[TriLUG] LDAP provisioning/update best practices

Aaron S. Joyner aaron at joyner.ws
Sat Jul 15 23:59:13 EDT 2006


Kevin Otte wrote:

>Tanner Lovelace wrote:
>  
>
>>It is possible to do it with ldap, although it might be easier to just
>>keep everything in a database and instead of using pam_ldap
>>to do accounts, just use pam_mysql and don't worry about ldap at
>>all!  That would probably be the easiest thing to do.
>>    
>>
>
>pam_mysql addresses the auth side of things, but is there an NSS library
>for doing MySQL lookups?
>
>-- Kevin
>  
>
Gah, don't go there.  Stick with ldap, as the modules are stable and 
used a lot, thus likely to encounter quirky corner case bugs that may 
affect the ability of the entire machine to function.  I'm not sure if 
there is an nsswitch library for mysql, but it would make at least me 
highly nervous with out some serious testing.

First, the traditional way to fight this problem is with a lock file.  
Don't allow more than one copy of the thing which performs the updates 
to run at once.  Or more simply, make it a cron job which reads LDIFs* 
to add to LDAP from a directory only writable by an appropriate user 
(suexec on apache will help out here), and have the cron job 
automagically figure out the UID.  Run it once a min even and you've got 
reasonably fast updates, no traditional lock files to worry about, and 
it solves the concurrency issues.  This also separates your web app from 
being able to needing the permissions to directly modify ldap, thus 
being marginally more secure (it can still write to the directory, which 
is a potential problem).

If you don't want to go the cron route for what ever reason, another way 
of thinking about it, temporary collisions in UID aren't the end of the 
world, so have your script simply perform the add, then enter a loop 
which checks back to see if there is now a collision.  If there is, have 
it wait a random time interval at least twice as long as it will take to 
fix it**, and then check again, and if there is still a collision, 
increment the UID.

In short, there are a thousand ways to fix this problem with LDAP, none 
of which require all that much scripting, and none of which is entirely 
perfect.  Another idea that someone might suggest, which is also fraught 
with problems, would be to backend LDAP with MySQL.  Then you can setup 
the schema, and add a unique index to the username column as well as the 
dn (uid) column, and you've avoided collisions.  The problem I mentioned 
is that now you've added another potential 100% point of failure to your 
system 100% of the time, to work around a potential problem for a very 
fractional portion of the userbase in what for your setup will be 
extremely rare circumstances.

Aaron S. Joyner

* - You could use some custom config file that isn't quite so capable, 
if you'd prefer to be slightly more secure at the expense of more work.
** - This idea attempts to avoid both scripts continuously trying to 
"fix" it by incrementing the UID of the user they're working on, and 
colliding with each other.  This situation wouldn't likely last very 
long, unless the update takes significantly longer than the check code, 
but it's worth protecting against.  Something in the range of 1 seconds 
plus 3 to 5 seconds of random is probably plenty long.  These values 
would need tuning for this to really scale into hundreds of user adds 
per minute, and probably in the best case breaks down there.  You'd need 
to fall back to something like the cron'd adds I mentioned before to 
scale much beyond somewhere between 1 and 10 adds per second.



More information about the TriLUG mailing list