Re: Looking for highest uidNumber in ldap
by jhourcle (Prior) on May 14, 2005 at 20:25 UTC
|
I've had to do this once before, and never could find a good way to handle it. So I cheated, and kept a nextUID() function, that connected to an Oracle database, and use a sequence that I had set up there.
But I already had the Oracle database, and my LDAP routines already opened LDAP connections (as all new users authenticated out of an Oracle database that tracked staff and students)
Of course, this is more an LDAP than Perl question, so I checked the OpenLDAP mailing list, and they had a solution for doing something similar, but storing the number in your LDAP directory:
| [reply] |
Re: Looking for highest uidNumber in ldap
by davidrw (Prior) on May 14, 2005 at 18:30 UTC
|
What do you need it for? Just letting Net::LDAP->add() deal w/it automatically isn't sufficient? I don't see anything specific in Net::LDAP that does it, so your approach (find all & sort & pop) seems like the way to go. Just two comments:
| [reply] [d/l] |
|
|
Do you add the objects to the ldap directory? Have you got total control about this process? If yes, perhaps you could create an object which contains just the last used uidNumber, and read it at the beginning of each import or sync, and if new objects are to be created, just increase it and write it back. With this solution, you can also create more-than-life-long-unique uidNumbers for each person
Best regards,
perl -e "s>>*F>e=>y)\*martinF)stronat)=>print,print v8.8.8.32.11.32"
| [reply] |
|
|
| [reply] |
|
|
Hmm. I'm actually not familiar w/the internals of LDAP -- i just assumed that uidNumber was a LDAP primary key (thus unique and auto-incrementing), so that it would be necessary for add() (really whatever "ADD" command it sends to the ldap server) to result in the sequence (internal to the ldap server) being incremented .. So if the only need for trying to find the highest uidNumber was just to feed it back into add(), it didn't seem necessary, but I assume there's a broader need for it that i'm just missing...
| [reply] |
|
|
$ldap->add() doesn't increment the uidNumber. If the uidNumber attribute is supposed to be unique in the directory, and you attempt to write one that exists, the directory will return a constraint violation.
If the uidNumber attribute does not have a uniqueness constraint, the directory will accept it and write it in.
LDAP does not have the concept of 'primary keys' as such. Each entry in LDAP is 'keyed' by it's distinguished name, which is made up of the distinguished name of its parent container, and its own naming attribute (often cn). So within container "ou=container,o=company" the cn must be unique (assuming cn is the naming attribute), but in "ou=container1,o=company" you can duplicate a cn that is already used in ou=container. Unless you define a constraint against an attribute, the only thing that must be unique is the distinguished name (dn).
By default, iPlanet used to (and possibly still does - I work on a heavily customised iPlanet environment) have a uniqueness constraint on the uid attribute across the whole directory tree. If thats the case with the OP's directory environment on uidNumber, then attempting to write a uidNumber attribute that's already been used will result in a constraint violation. I would not recommend catching that error and incrementing until the error doesn't occur as an approach BTW, because LDAP is optimised for reads, not writes.
strat's approach or a SSS (see my post below) would be the most LDAP'ish. Of the two strat's is the better method.
Update: Hmm. I'm actually not familiar w/the internals of LDAP -- i just assumed that uidNumber was a LDAP primary key (thus unique and auto-incrementing)
As per above, LDAP doesn't have the concept of primary keys, and most databases don't create numeric auto incrementing primary keys unless you tell them to. They generally have a ROWID or similar which is numeric and auto incrementing, but thats not the same thing as a primary key.
--------------------------------------------------------------
g0n, backpropagated monk
| [reply] [d/l] |
Re: Looking for highest uidNumber in ldap
by jdalbec (Deacon) on May 14, 2005 at 23:02 UTC
|
Depending on the number of users you have, this could become very expensive. It's more efficient to pick a random number in a fixed range and try again if it's already in use. | [reply] |
Re: Looking for highest uidNumber in ldap
by ghenry (Vicar) on May 15, 2005 at 11:56 UTC
|
Hi,
This has been spoken about before on the OpenLDAP lists, and the following is the method adopted by most of the commercial support companies, including my own (But your circumstance may defer).
The best way to handle this, is to handle it in OpenLDAP directly.
See:
Basically, you create an entry like so:
dn: cn=maxUid,dc=example,dc=com
objectClass: extensibleObject
objectClass: top
uidNumber: 500
And then do the following ldapmodify with every new entry added:
dn: cn=maxUid,dc=example,dc=com
changetype: modify
delete: uidNumber
uidNumber: 500
-
add: uidNumber
uidNumber: 501
Then you can just do a search to see the latest number.
HTH,
Gavin.
Walking the road to enlightenment... I found a penguin and a camel on the way.....
Fancy a yourname@perl.me.uk? Just ask!!!
| [reply] [d/l] [select] |
Re: Looking for highest uidNumber in ldap
by g0n (Priest) on May 15, 2005 at 18:05 UTC
|
Although it's expensive in server processing, you could do a server side sort (if your LDAP server supports the control):
LDAP::Control::Sort
to get the highest uid, then ++ it.
--------------------------------------------------------------
g0n, backpropagated monk
| [reply] |