Discussion:
how to check uniqueness of uidNumber ?
W***@seac.pf
2003-01-13 17:25:44 UTC
Permalink
Hi,

I'm thinking about to use openldap for users authentication. For that, I
use person, posixAccount and shadowAccount objects to store user data
(password, uid, ...). Now I want that no user have the same uidNumber (I
know Unix allows multiple users to have the same uidNumber, but this is
not compliant with my policy).

So how can I check uniqueness of uidNumber ?

Jeffrey
Hallvard B Furuseth
2003-01-13 18:00:56 UTC
Permalink
Post by W***@seac.pf
So how can I check uniqueness of uidNumber ?
LDAP doesn't support such constraints in the way some databases do.

Either search a new entry's uidNumber before adding it to check that it
does not already exist, or use uidNumber as RDN (in which case you'll
have to search for uid to verify that that is unique, instead.)
--
Hallvard
Markus Storm
2003-01-14 07:30:00 UTC
Permalink
Post by Hallvard B Furuseth
Post by W***@seac.pf
So how can I check uniqueness of uidNumber ?
LDAP doesn't support such constraints in the way some databases do.
But quite some LDAP servers do (like iplanet).

It greatly eases maintaining a 'proper' directory.
The alternative is to restrict LDAP write access to certain interfaces
(i.e. proxies) only and implement the uniqueness checks therein.
This is what we currently do, but it severely limits flexibility
and requires maintaining the proxies.
IMHO such a uniqueness check feature would be more useful than most of the
additional schema checking stuff introduced in 2.1.

Would it be hard to implement this?
I vaguely recall someone of the IBM guys that are regularly contributing to
OpenLDAP intended to work on this, but this may be an outdated information.
Post by Hallvard B Furuseth
Either search a new entry's uidNumber before adding it to check that it
does not already exist, or use uidNumber as RDN (in which case you'll
have to search for uid to verify that that is unique, instead.)
Designing all of the tree for this "application" is often not possible,
especially with meta-type directories that contain all sorts of different
subtrees, each of which contains DNs that are dictated by a particular
application.

Markus
--
Markus Storm, Telefonica Deutschland GmbH
storm @ mediaways.net
Lon Tierney
2003-01-13 17:53:46 UTC
Permalink
Post by W***@seac.pf
Hi,
I'm thinking about to use openldap for users authentication. For that,
I use person, posixAccount and shadowAccount objects to store user data
(password, uid, ...). Now I want that no user have the same uidNumber
(I know Unix allows multiple users to have the same uidNumber, but this
is not compliant with my policy).
So how can I check uniqueness of uidNumber ?
You could do a simple little trick - make uidNumber part of the DN for the
users in your directory. It will ensure that no two users can be added
that have the same value for uidNumber (as DN must be unique). This of
course assumes that the users are all in the same location in the tree.

-lon
W***@seac.pf
2003-01-13 22:05:28 UTC
Permalink
I will use uidNumber for rdn.

Thank you for your answers,

Jeffrey
Leonid Mamtchenkov
2003-01-15 00:24:01 UTC
Permalink
***@seac.pf wrote:
WJsp> I'm thinking about to use openldap for users authentication. For that, I
WJsp> use person, posixAccount and shadowAccount objects to store user data
WJsp> (password, uid, ...). Now I want that no user have the same uidNumber (I
WJsp> know Unix allows multiple users to have the same uidNumber, but this is
WJsp> not compliant with my policy).
WJsp>
WJsp> So how can I check uniqueness of uidNumber ?

I don't think it is possible to do. I am used to think of it as a
feature though. Consider that having multiple userPassword attributes
for the same object in posixAccount will allow your users to use
different passwords to login! ;)
--
Best regards,
Leonid Mamtchenkov, RHCE
System Administrator
Francoudi & Stephanou Ltd.
Tony Earnshaw
2003-01-15 06:30:15 UTC
Permalink
Post by Leonid Mamtchenkov
WJsp> I'm thinking about to use openldap for users authentication. For that, I
WJsp> use person, posixAccount and shadowAccount objects to store user data
WJsp> (password, uid, ...). Now I want that no user have the same uidNumber (I
WJsp> know Unix allows multiple users to have the same uidNumber, but this is
WJsp> not compliant with my policy).
WJsp>
WJsp> So how can I check uniqueness of uidNumber ?
I don't think it is possible to do. I am used to think of it as a
feature though. Consider that having multiple userPassword attributes
for the same object in posixAccount will allow your users to use
different passwords to login! ;)
In fact, both are multi-value attributes. As far as userPassword is
concerned, I'd tried that before (Openldap 2.1.8, I think) and pam_ldap
authentication allowed either password. Strange.

Best,

Tony
--
Tony Earnshaw

When all's said and done ...
there's nothing left to say or do.

e-post: ***@billy.demon.nl
www: http://www.billy.demon.nl
Sameh Attia
2003-01-15 08:50:05 UTC
Permalink
Post by Leonid Mamtchenkov
WJsp> I'm thinking about to use openldap for users authentication. For that, I
WJsp> use person, posixAccount and shadowAccount objects to store user data
WJsp> (password, uid, ...). Now I want that no user have the same uidNumber (I
WJsp> know Unix allows multiple users to have the same uidNumber, but this is
WJsp> not compliant with my policy).
WJsp>
WJsp> So how can I check uniqueness of uidNumber ?
I don't think it is possible to do. I am used to think of it as a
feature though. Consider that having multiple userPassword attributes
for the same object in posixAccount will allow your users to use
different passwords to login! ;)
the uidNumber attribute of the posixAccount objectClass is single
valued; i.e. u cannot add more than one attribute of uidNumber to a dn
that has a posixAccount. So the only solution I think to guarantee the
uniqueness of ur customers' uidNumber is on ur client side.
1 - search for this uidNumber in ur tree
2 - if found then do not add
3 - if not found then add
I hope this helps
--
Sameh Attia
Senior System Engineer
T.E. Data
--
__ __ _
_________ _/ /_/ /_(_)___ _
/ ___/ __ `/ __/ __/ / __ `/
(__ ) /_/ / /_/ /_/ / /_/ /
/____/\__,_/\__/\__/_/\__,_/

"She who is in my mind and mouth, I love her with all my heart and blood"
We'll restore OUR Palestine
Jim C
2003-01-15 11:19:54 UTC
Permalink
I'm trying to write scripts for this right now.

The algorithm I am using works like this:

1. Retrieve / sort uids for a given ou.
2. Grab the biggest one.
3. Add 1.
4. Create a new record with the new uid.
5. Add it to the ldap server.

Problem is that on a multi-user system, this should be an atomic action
with locking. Otherwise someone else who is also adding users might
beat you to the next number causeing two users with the same number.
Of course you can fix this also by makeing uidNumber part of the dn.
I just don't get why this is not the default however, and doing this
probably breaks a number of things such as directory_administrator.

Man, there just really ought to be more server-side tools / schema
adjustments /standards for copeing with uids/rids.
...
Post by Sameh Attia
the uidNumber attribute of the posixAccount objectClass is single
valued; i.e. u cannot add more than one attribute of uidNumber to a dn
that has a posixAccount. So the only solution I think to guarantee the
uniqueness of ur customers' uidNumber is on ur client side.
1 - search for this uidNumber in ur tree
2 - if found then do not add
3 - if not found then add
I hope this helps
Tony Earnshaw
2003-01-15 12:24:52 UTC
Permalink
Post by Jim C
Problem is that on a multi-user system, this should be an atomic action
with locking. Otherwise someone else who is also adding users might
beat you to the next number causeing two users with the same number.
Of course you can fix this also by makeing uidNumber part of the dn.
I just don't get why this is not the default however, and doing this
probably breaks a number of things such as directory_administrator.
Man, there just really ought to be more server-side tools / schema
adjustments /standards for copeing with uids/rids.
I reckon that David Smith's SQL solution is pretty good, especially if
you're using something like PHP or Perl. That'd cater for your locking.

If you don't want to learn both PHP and Perl at the same time, a PHP CGI
binary can be made and installed in /usr/local/bin and called from the
command line. Others might advise you to go the whole hog and learn C
:-) but not me.

Best,

Tony
--
Tony Earnshaw

When all's said and done ...
there's nothing left to say or do.

e-post: ***@billy.demon.nl
www: http://www.billy.demon.nl
Jim C
2003-01-15 15:58:49 UTC
Permalink
As a matter of fact I know C but I'm a little rusty.
That's a great idea but I'm not sure if I have the time to develop it
this quarter and unfortunately this quarter is my last before
graduation. I suppose I might pick it up afterwards but it is more
likely that I will be in panic mode trying to get work sos I don't loose
my apt. :-/

I'm working on a php script and a bash script for the purpose... any
reason I cannot just touch off a lock file and then check for it?
Hmmm... for speed/scaleability I could check a shell variable instead of
a file... assumeing that there are shell variables that users cannot
mess with i.e. that ownership *is* an issue with shell variables.


Jim C.
Post by Tony Earnshaw
I reckon that David Smith's SQL solution is pretty good, especially if
How would that work without a SQL type backend that will work with it?
Post by Tony Earnshaw
you're using something like PHP or Perl. That'd cater for your locking.
If you don't want to learn both PHP and Perl at the same time, a PHP CGI
binary can be made and installed in /usr/local/bin and called from the
command line. Others might advise you to go the whole hog and learn C
:-) but not me.
Sameh Attia
2003-01-15 12:47:48 UTC
Permalink
David Smith solution can be modified to just a single value or entry; instead of many values and removing
the used one; which is incremented on each new subscription after being locked
1 - Lock the table
2 - Increment the value
3 - Get the new value
4 - Unlock the table
This way u can add additional info like machine name......etc and it is only just one record
--
Sameh Attia
Senior System Engineer
T.E. Data
--
__ __ _
_________ _/ /_/ /_(_)___ _
/ ___/ __ `/ __/ __/ / __ `/
(__ ) /_/ / /_/ /_/ / /_/ /
/____/\__,_/\__/\__/_/\__,_/

"She who is in my mind and mouth, I love her with all my heart and blood"
We'll restore OUR Palestine
Frank Swasey
2003-01-15 14:19:43 UTC
Permalink
Sheesh! Every two or three months we go through this all over again....

http://www.openldap.org/lists/openldap-software/200210/msg00584.html

To the best of my knowledge there is nothing in the openldap server that
will prevent the duplication of a value for any attribute (other than
dn) in the database. Therefore, you are required to police your
clients. The best practices that have been developed after hashing this
same topic repeatedly is summarized in the link above.

The process is easily extended to have a specific DN for each branch you
want to "protect" ....
Post by Jim C
I'm trying to write scripts for this right now.
1. Retrieve / sort uids for a given ou.
2. Grab the biggest one.
3. Add 1.
4. Create a new record with the new uid.
5. Add it to the ldap server.
Problem is that on a multi-user system, this should be an atomic action
with locking. Otherwise someone else who is also adding users might
beat you to the next number causeing two users with the same number.
Of course you can fix this also by makeing uidNumber part of the dn.
I just don't get why this is not the default however, and doing this
probably breaks a number of things such as directory_administrator.
Man, there just really ought to be more server-side tools / schema
adjustments /standards for copeing with uids/rids.
...
Post by Sameh Attia
the uidNumber attribute of the posixAccount objectClass is single
valued; i.e. u cannot add more than one attribute of uidNumber to a dn
that has a posixAccount. So the only solution I think to guarantee the
uniqueness of ur customers' uidNumber is on ur client side.
1 - search for this uidNumber in ur tree
2 - if found then do not add
3 - if not found then add
I hope this helps
--
Frank Swasey | http://www.uvm.edu/~fcs
Systems Programmer | Always remember: You are UNIQUE,
University of Vermont | just like everyone else.
=== God Bless Us All ===
Sameh Attia
2003-01-15 14:31:37 UTC
Permalink
Post by Frank Swasey
Sheesh! Every two or three months we go through this all over again....
http://www.openldap.org/lists/openldap-software/200210/msg00584.html
Frank,
ur solution does not help the racing problem that happen on the max number in multiuser env.
It seems u did not get the point cuz wer discussing here either locking solutions thru sql databases, or simply an
algorithm generating unique numbers like the one I suggested to David Smith. Kindly read it and comment.
--
Sameh Attia
Senior System Engineer
T.E. Data
--
__ __ _
_________ _/ /_/ /_(_)___ _
/ ___/ __ `/ __/ __/ / __ `/
(__ ) /_/ / /_/ /_/ / /_/ /
/____/\__,_/\__/\__/_/\__,_/

"She who is in my mind and mouth, I love her with all my heart and blood"
We'll restore OUR Palestine
Howard Chu
2003-01-15 15:08:00 UTC
Permalink
-----Original Message-----
Post by Frank Swasey
Sheesh! Every two or three months we go through this all
over again....
Sheesh, you can say that again...
Post by Frank Swasey
http://www.openldap.org/lists/openldap-software/200210/msg00584.html
Frank,
ur solution does not help the racing problem that
happen on the max number in multiuser env.
There is no race problem. Read the above-referenced thread fully. This
message
summarizes as well:
http://www.openldap.org/lists/openldap-software/200210/msg00617.html
It seems u did not get the point cuz wer discussing here
either locking solutions thru sql databases,
LDAP is not an SQL database. If your mind can only imagine a
database-oriented solution to this problem, then you shouldn't be using LDAP,
you should stick to your database exclusively. On the other hand, if you're
willing to contemplate an LDAP-oriented solution to the problem, then the
above-referenced messages will work for you.

-- Howard Chu
Chief Architect, Symas Corp. Director, Highland Sun
http://www.symas.com http://highlandsun.com/hyc
Symas: Premier OpenSource Development and Support
Frank Swasey
2003-01-15 16:17:10 UTC
Permalink
Post by Sameh Attia
Post by Frank Swasey
Sheesh! Every two or three months we go through this all over again....
http://www.openldap.org/lists/openldap-software/200210/msg00584.html
Frank,
ur solution does not help the racing problem that happen on the
max number in multiuser env.
Sorry. No race problem. Read the link.... if the value is not what
you specify on the delete the modify fails... and the add of the new
value doesn't happen.... where's the race condition in that?
--
Frank Swasey | http://www.uvm.edu/~fcs
Systems Programmer | Always remember: You are UNIQUE,
University of Vermont | just like everyone else.
=== God Bless Us All ===
Howard Chu
2003-01-15 13:46:01 UTC
Permalink
You don't need locks, LDAP already provides atomic actions. There's more than
one approach to solve a generic problem, you just have to understand the
approach that LDAP supports.
http://www.openldap.org/lists/openldap-software/200208/msg00358.html

-- Howard Chu
Chief Architect, Symas Corp. Director, Highland Sun
http://www.symas.com http://highlandsun.com/hyc
Symas: Premier OpenSource Development and Support
-----Original Message-----
I'm trying to write scripts for this right now.
1. Retrieve / sort uids for a given ou.
2. Grab the biggest one.
3. Add 1.
4. Create a new record with the new uid.
5. Add it to the ldap server.
Problem is that on a multi-user system, this should be an
atomic action
with locking. Otherwise someone else who is also adding users might
beat you to the next number causeing two users with the same number.
Of course you can fix this also by makeing uidNumber part of the dn.
I just don't get why this is not the default however, and doing this
probably breaks a number of things such as directory_administrator.
Man, there just really ought to be more server-side tools / schema
adjustments /standards for copeing with uids/rids.
...
Post by Sameh Attia
the uidNumber attribute of the posixAccount objectClass is single
valued; i.e. u cannot add more than one attribute of
uidNumber to a dn
Post by Sameh Attia
that has a posixAccount. So the only solution I think to
guarantee the
Post by Sameh Attia
uniqueness of ur customers' uidNumber is on ur client side.
1 - search for this uidNumber in ur tree
2 - if found then do not add
3 - if not found then add
I hope this helps
Sameh Attia
2003-01-15 16:12:10 UTC
Permalink
Post by Howard Chu
You don't need locks, LDAP already provides atomic actions. There's more than
You are right Howard but I was discussing David's solution and not
suggesting a sql one from scratch.
--
Sameh Attia
Senior System Engineer
T.E. Data
--
__ __ _
_________ _/ /_/ /_(_)___ _
/ ___/ __ `/ __/ __/ / __ `/
(__ ) /_/ / /_/ /_/ / /_/ /
/____/\__,_/\__/\__/_/\__,_/

"She who is in my mind and mouth, I love her with all my heart and blood"
We'll restore OUR Palestine
Jim C
2003-01-16 07:16:00 UTC
Permalink
The problem does not occur at the db level. It occurs at the script
level because one must first retrieve the uidNumber and then do the
modify. Between the two lines of code a race condition can possibly
occur between scripts. Here is an example function written in php:

function getnewuid ($ds)
{

$booleantest=FALSE;

//We get a number of retries equal to NUMRETRIES
for($idx=0; $idx < NUMRETRIES && !$booleantest ;$idx=$idx+1 )
{

$entries=ldap_get_entries($ds, ldap_search($ds, PROXYDN ,"cn=*"));

/*
If another such script starts AND finishes it's ldap_mod_replace
before we get ours started below, then we have a
race condition at the script level.
*/

if($entries[0]["uidnumber"][0] < MINUID )
$change_entry["uidnumber"] = MINUID;
else
$change_entry["uidnumber"] = $entries[0]["uidnumber"][0] + 1;

//This, at least, is atomic.
$booleantest=ldap_mod_replace($ds, PROXYDN, $change_entry);

}//end of for loop

if($booleantest)
return $change_entry["uidnumber"];
else
die("Timeout error! Unable to set uidNumber in PROXYDN. To many
users being added from other sources?\n");

}//end of function getnewuid ($ds)

So lets say that we have more than one person adding users using the
script in question. What if script A ends a search just as script B
starts a modify? If B somehow finishes the modify before A begins it's
modify, which could concievably happen despite the odds, then you wind
up with two users with the same uid. Problem is that we would rather
there be no chance at all. <grins and hikes up suspenders> After all,
we are not writin' Windoze code, here. ;-)
Post by Howard Chu
You don't need locks, LDAP already provides atomic actions. There's more than
one approach to solve a generic problem, you just have to understand the
approach that LDAP supports.
http://www.openldap.org/lists/openldap-software/200208/msg00358.html
Howard Chu
2003-01-16 15:27:09 UTC
Permalink
-----Original Message-----
The problem does not occur at the db level. It occurs at the script
level because one must first retrieve the uidNumber and then do the
modify. Between the two lines of code a race condition can possibly
No. You aren't reading carefully enough, and your script does not implement
the method that has been discussed in the original threads. There's a
difference between LDAPModify/Replace and LDAPModify/Delete. The correct
update, already described in detail in the previous threads, uses
LDAPModify/Delete and /Add. Your script uses Replace, which provides no
locking assurances. Read RFC2251 and don't come back until you've fully read
and understand the description of the LDAP Modify operation.
There's more than one approach to solve a generic problem, you just have to
understand the approach that LDAP supports.
Post by Howard Chu
http://www.openldap.org/lists/openldap-software/200208/msg00358.html
-- Howard Chu
Chief Architect, Symas Corp. Director, Highland Sun
http://www.symas.com http://highlandsun.com/hyc
Symas: Premier OpenSource Development and Support
Tony Earnshaw
2003-01-16 16:54:05 UTC
Permalink
Post by Jim C
function getnewuid ($ds)
{
I realize that what you quote is just a snippet, but does it run for
you? I don't think it would run for me ;)

Best,

Tony
--
Tony Earnshaw

When all's said and done ...
there's nothing left to say or do.

e-post: ***@billy.demon.nl
www: http://www.billy.demon.nl
David Smith
2003-01-15 09:34:53 UTC
Permalink
Post by Leonid Mamtchenkov
WJsp> I'm thinking about to use openldap for users authentication. For that, I
WJsp> use person, posixAccount and shadowAccount objects to store user data
WJsp> (password, uid, ...). Now I want that no user have the same uidNumber (I
WJsp> know Unix allows multiple users to have the same uidNumber, but this is
WJsp> not compliant with my policy).
WJsp>
WJsp> So how can I check uniqueness of uidNumber ?
I am administering a system similar to yours. We built a Postgres
database just to maintain a list of available uidNumbers, and it has
worked quite well thus far. Every time we create a new user, we select a
uidNumber for the Postgres DB and remove it from the list.

--Dave
Sameh Attia
2003-01-15 12:50:41 UTC
Permalink
Post by David Smith
I am administering a system similar to yours. We built a Postgres
database just to maintain a list of available uidNumbers, and it has
worked quite well thus far. Every time we create a new user, we select a
uidNumber for the Postgres DB and remove it from the list.
--Dave
what if we use a timestamp, pid, ..etc any combination of numbers we r
sure that they r unique? and also take into consideration the multiuser env.
--
Sameh Attia
Senior System Engineer
T.E. Data
--
__ __ _
_________ _/ /_/ /_(_)___ _
/ ___/ __ `/ __/ __/ / __ `/
(__ ) /_/ / /_/ /_/ / /_/ /
/____/\__,_/\__/\__/_/\__,_/

"She who is in my mind and mouth, I love her with all my heart and blood"
We'll restore OUR Palestine
David Smith
2003-01-15 23:40:04 UTC
Permalink
Post by Sameh Attia
Post by David Smith
I am administering a system similar to yours. We built a Postgres
database just to maintain a list of available uidNumbers, and it has
worked quite well thus far. Every time we create a new user, we select a
uidNumber for the Postgres DB and remove it from the list.
--Dave
what if we use a timestamp, pid, ..etc any combination of numbers we r
sure that they r unique? and also take into consideration the multiuser env.
Here's how we solve the locking problems:

We serialize all LDAP account creations through a single cron script (in PHP)
that is responsible for building each account. This may be considered an
over-complication, but it has worked very well, and a single point-of-entry
has proved very stable and reliable. Since OpenLDAP is optimized for reading,
not writing, we had some major problems allowing ad-hoc account creation.

When a a new user requests an account:

We add an entry to a Postgres table for pending account creations. Our cron
script (mentioned above) runs through that table and extracts outstanding
account creations. It then creates the user in LDAP and performs some
quota and housekeeping functions. The result: linear account creation,
no locking necessary, easy logs, easy maintenance.

--Dave
Loading...