5

In our corporate environment long ago some wiz decided to put the user "mysql" into LDAP.

The account is disabled:

$ sudo su - mysql
This account is currently not available.

...but it's id still exists:

$ id mysql
uid=2050913(mysql) gid=867(ENG) groups=867(ENG)

This makes mariadb installations fail on CentOS7 because /var/run/mariadb is created by a tmpfile rule which tries to assign the directory to be owned by mysql. But mysql doesn't exist until LDAP/networking is up and running, and the mariadb install doesn't create the mysql user because the user already exists in ldap.

Is there a way to locally force PAM (or something?) to ignore the user mysql in LDAP? Or rename the ldap mysql user to mysql_ldap?

Is my only workaround to manually add the entry in /etc/passwd? (Or change the mariadb config to use different username.) I'd rather have minimal changes to the config and systemd files that come from the rpm.

(And I don't have high hopes of removing mysql from LDAP as that could break a lot of legacy infrastructure.)

I'll be using ansible, btw, to implement the change.

Additional:

I've changed the title of the question:

I have found that if I do add the local "mysql" user that it works ok, unless I have files owned by the userid of the LDAP "mysql" user. If I ls -la the files, it then pollutes the nscd (or sssd) cache and "mysql" again resolves to the LDAP user. It seems what I really want is to somehow construct a PAM filter for accounts to make this LDAP "mysql" user disappear.

rrauenza
  • 555
  • 3
  • 16

5 Answers5

2

Here's my final solution, coded in ansible:

- name: Disable ldap users                                                  
  ini_file: dest=/etc/sssd/sssd.conf section='nss' 
            option=filter_users value={{ filter_ldap_users | join(",") }}
  register: sssd_conf_users                                                   

- name: Disable ldap groups                                                 
  ini_file: dest=/etc/sssd/sssd.conf section='nss' 
            option=filter_groups value={{ filter_ldap_groups | join(",") }}
  register: sssd_conf_groups                                                  

- name: Restart SSSD                                                        
  when: sssd_conf_users.changed or sssd_conf_groups.changed                   
  service: name=sssd state=restarted                                          

- name: Flush NSCD cache                                                    
  when: sssd_conf_users.changed or sssd_conf_groups.changed                   
  shell: "for db in /var/db/nscd/*; do nscd -i $(basename $db); done"         

- name: Flush SSSD cache                                                     
  when: sssd_conf_users.changed or sssd_conf_groups.changed                   
  command: /usr/sbin/sss_cache -E        
rrauenza
  • 555
  • 3
  • 16
  • 1
    No reason to use `ldap_user_search_base = dc=example,dc=com?subtree?(!(uid=mysql))` -- sssd.conf has a `filter_users` and `filter_groups` option. Will fix tomorrow. – rrauenza Sep 30 '15 at 23:06
  • I would strongly suggest not to use NSCD along with SSSD. The two different caching mechanisms just step on one another and in recent (1.9+) versions there should be no reason to use NSCD anyway as SSSD uses its own fast memory cache. As a matter of fact, SSSD should warn you if you use NSCD along with SSSD... – jhrozek Oct 02 '15 at 07:15
  • Thanks @jhrozek. For reference, https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/usingnscd-sssd.html which suggests `enable-cache hosts yes`, `enable-cache passwd no`, `enable-cache group no`, `enable-cache netgroup no`, – rrauenza Oct 02 '15 at 16:17
  • Ah, then it's correct, because what RHAT documentation suggests is to enable nscd cache for hosts map only but disale for passwd, group and netgroup which are handled by SSSD. What I thought is that your config also enabled nscd for sssd-handled maps which might conflict. Sorry about the confusion! – jhrozek Oct 03 '15 at 16:49
  • Oh, no confusion, I was just supporting your statement with the docs href. I've now modified my nscd.conf accordingly per your and redhat's recommendation. – rrauenza Oct 03 '15 at 21:02
1

On PAM level:
All you need is to ignore a user in LDAP. So, set up the particular LDAP client you're using, In CentOS it would be sssd, to use a custom LDAP UID/GID lookup fileters which will ignore the "mysql" record. On an existing system you will have to then clean sssd cache and restart it and the user will be gone. Reinstallation of mariadb will then create a local mysql user.

On package level:
Set up a custom Yum repo somewhere on the network that will include a package that contains a post-install script, fixing the mysql user problem. You'll also have to put the mariadb package in that repo. Then, define a package group which will include that package and mariadb and install it.
Alternatively, you could rebuild the mariaDB package with an updated, more intelligent post-install script that will take care of the mysql user creation.

I'd go with A - B is somewhat obfuscated :)

  • I did see pam_filter references, but haven't figured out how to use it yet -- either to map to another username (mysql_ldap) or to filter it out completely. I think, though, that even if the account shows up as disabled (which it actually currently is), it still shows up as a valid userid, so useradd fails to add it locally. Now that I think about it, I think PAM wouldn't affect that? – rrauenza Sep 29 '15 at 22:35
  • It's basically all in the man page for sssd: http://linux.die.net/man/5/sssd-ldap Look at the ldap_search_base option. It is absolutely possible to define a search filter that would filter out a specific record based on it's uid value. BTW, if you aren't using sssd I wholeheartedly recommend you switch to it - it's much more flexible. –  Sep 30 '15 at 05:46
  • Aha -- I'm zeroing in. It looks like I need to add `ldap_user_search_base = dc=example,dc=com?subtree?(!(uid=mysql))` to /etc/sssd/sssd.conf – rrauenza Sep 30 '15 at 16:37
  • No, that doesn't seem to be working. – rrauenza Sep 30 '15 at 18:03
  • `ldap_search_base` seems to be working, though. – rrauenza Sep 30 '15 at 18:17
  • Aha -- no, the problem is sss has its own cache. sss_cache -E clears it. – rrauenza Sep 30 '15 at 19:06
  • Make sure you also intercept the mysql group, if there is one in LDAP. –  Sep 30 '15 at 21:22
1

Here's something I'm using currently as a workaround. I've added this to my kickstart file to run at %post -- before I enable/setup LDAP:

# Install and de-install mariadb-server to create mysql
# user before LDAP is enabled.
yum -d1 -e1 -y install yum-plugin-remove-with-leaves mariadb-server
yum -d1 -e1 -y erase mariadb-server --remove-leaves

I was going to run the useradd manually from having read the mariadb-server spec file: http://pkgs.fedoraproject.org/cgit/mariadb.git/tree/mariadb.spec

%pre server
/usr/sbin/groupadd -g 27 -o -r mysql >/dev/null 2>&1 || :
/usr/sbin/useradd -M -N -g mysql -o -r -d %{mysqluserhome} -s /sbin/nologin \
  -c "MySQL Server" -u 27 mysql >/dev/null 2>&1 || :

...but I'm more comfortable taking it straight from installing the rpm.

I'm not completely satisfied with this as well because if I happen to find a file with the ldap "mysql" userid, the reverse lookup on the user id pollutes nscd or sssd with the wrong "mysql" user.

rrauenza
  • 555
  • 3
  • 16
1

I would actually suggest to add:

filter_users = mysql
filter_groups = mysql

To the [nss] section of sssd.conf instead of customizing the LDAP filter. It should do the same thing, except that when you use the LDAP filter way, the searches still hit the LDAP server, just don't match.

In contrast, the filter_users/filter_groups would enter the mysql user into the negative cache of SSSD, which would return "Not found" directly from the NSS responder, without going to the sssd_be process and the LDAP server.

rrauenza
  • 555
  • 3
  • 16
jhrozek
  • 1,370
  • 6
  • 5
0

If all you want to do is not resolve ldap users. Edit /etc/nsswitch.conf and for the user & group entries remove sssd (or ldap) entries. Then flush the nscd cache

Barry
  • 23
  • 6
  • I don't want to remove *all* ldap users. Just specific ones. A coleague also suggested making sure local was before ldap in ordering, but that doesn't help with the reverse lookup of the id polluting the cache. Another option would be to add the user locally with the same id as its ldap id. – rrauenza Oct 01 '15 at 15:53