In order to get off NIS, I did an upgradeable ldap->master.passwd build script system. It's not instantly obvious what is happening when you look at it, but:
One worked example might be in order.
admin# crontab -l -u root MAILTOemail@example.com */10 * * * * /usr/sbin/daemon -cf /usr/bin/lockf -s -t 0 /var/run/ldap-client.lock /etc/ldap-client/update-admin-cron.sh admin# cat /etc/ldap-client/update-admin-cron.sh #! /bin/sh # */10 * * * * /usr/sbin/daemon -cf /usr/bin/lockf -s -t 0 /var/run/ldap-client.lock /etc/ldap-client/update-admin-cron.sh /etc/ldap-client/randwait.pl 180 /etc/ldap-client/update-admin.sh 2>&1 | /etc/ldap-client/maybemail.pl -d freebsd.org -s "`/bin/hostname` - $0" firstname.lastname@example.org admin# cat /etc/ldap-client/update-admin.sh #! /bin/sh cd /etc/ldap-client && /usr/bin/cvs -Rq up -d -P -C /etc/ldap-client/make_masterpasswd.pl -o adminAccount -s adminShell -q /etc/ldap-client/make_sshkeys.pl -o adminAccount -k adminPublicKey -q /etc/ldap-client/make_group.pl -q /etc/ldap-client/make_k5login.pl -o adminAccount -q
The general flow:
- update-admin-cron runs every 10 minutes. It sleeps for a random time (range 1 second through 3 minutes).
runs the backend script which mails the output to email@example.com (extremely spammy!):
- cvs update, erasing local changes
- generates /etc/master.passwd
- updates ssh keys
- generates /etc/group
- updates /root/.k5login
The scripts do their best to merge with local changes. Except for things that are in ldap. eg: if there is a local user called "peter", and one in ldap, it will remove the local user and install the ldap one instead. This means you CAN just build/install ports that install local ports users.
The scripts DO interact correctly with useradd/vipw/etc. All locking conventions are maintained. You can still vipw.
So far, this should be easy enough. Where it gets complex is deciding what accounts to put on a machine, and which ssh keys to use.
There are three filtering / access control systems.
ldap accounts are tagged with "objectClass".
- an "objectClass: freebsdAccount" is a general purpose account.
- "adminAccount" is an admin account. "pkgbldAccount" for package builders. etc. There are a few.
- In general the scripts default to searching for and installing things tagged with "objectClass: freebsdAccount".
- In general, the scripts take an argument, "-o", which MERGES sets of objectclasses. "-o adminAccount" means ONLY get admin accounts. "-o adminAccount+postmasterAccount" means install admins and ALSO postmaster tagged accounts.
- This -o objectclass filter controls which lines appear in master.passwd, or which ssh keys get installed, or who gets listed in /root/.k5login.
ldap accounts have a "loginShell".
- Some have "adminShell" as well. This allows us to have a "bash" on regular user machines, but "sh" or "tcsh" on minimal lightweight admin machines without a full port suite.
- There are multiple fallback shell options. eg: if a shell attribute is requested "adminShell" but your ldap record doesn't have an adminShell, then you'll get /sbin/nologin. This fallback shell can be changed. Another option is to test to see if the executable exists, and fallback if not.
- A third option is to force everything to the same shell (eg: /usr/local/bin/cvssh). Read the code, this is what you're looking at.
The third access filter is ssh shell selection.
- By default, accounts that match the objectclass filters get the keys from sshPublicKey attribute.
- We can specify "-k adminPublicKey" which means a different set will be used. They may have the same contents, or we may have different keys for regular machines vs admin machines.
- The merge syntax here is different. "+" means merge (like above), while "," means ordered. "-k adminPublicKey,postmasterPublicKey" means "use the admin keyset if one is set, else use the postmaster keyset if it is set, else put no keys on at all".
- On the other hand, we could merge key sets: "-k adminPublicKey+postmasterPublicKey" means that /etc/ssh-keys/%u will have both sets if an account has both.
- There is an example of this in the /etc/ssh-ldap/* files.
With these basic rules I was able to implement all the one-off hacks we had done with NIS. Its not pretty, but it works so far.
- update-foundation: we put adminAccount+foundationAccount on the machines. adminAccount gets ksu, but we preserve any local ksu folks because make_k5login only selects adminAccount. We admin accounts get admin ssh keys, foundation folks get regular keys.
- update-ftpadm: we put ALL accounts in /etc/passwd (unrestricted objectClass), but everybody who doesn't have an adminShell or ftpadmShell attribute gets /sbin/nologin.
- update-pointyhat: this is used on pluto2 and pointyhat. This mixes in the ports-* accounts. Note they have local ssh keys for ports-* and a custom sshd_config.
- update-postmaster: limited account list, but postmasterAccount folks get their regular freebsd.org shell and keys.
- update-repoman and update-svn: regular dev accounts EXCEPT shells are FORCED to cvssh or svnssh
- update-wwwadm: think of red. Admin accounts plus wwwadmAccount tagged, like -postmaster.
I expect this will need refining. I want to add signature checking for updates, etc. Lots todo, but we are off NIS.