[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