(Illustration by Gaich Muramatsu)
On Wed, Mar 07, 2007 at 07:19:41PM +0100, S. Cance wrote: > I'm working on a network where every services use LDAP to authenticate > users. > That's why I am working on a LDAP based clog utility. Ok, pause here for a second LDAP is a directory service, the list of users, groups and membership information. Clog/auth2 perform authentication which is quite different. In the Active Directory environment LDAP handles membership and such, but kerberos is used for authentication. However... Since LDAP has the mechanism that allows a user to authenticate with the LDAP servers (possibly based on their kerberos identity), it is possible to have the ldap directory provide authentication tokens for Coda. (i.e. user proves his identity to kerberos which gives him a ticket that proves the identity to ldap which then could return a Coda token which is used to prove our identity to the Coda servers). So the whole authentication/authorization/ACL system consists of several parts, 1 - Coda tokens, the user somehow proves his identity to Coda's auth2 server, maybe through a shared secret (Coda password) or in the form of a valid kerberos ticket. 2- This token is then used whenever the client connects to the servers. If the token is valid the server associates the Coda user identity with any request that is sent over this encrypted connection from the client. 3- When a client creates a new connection, the server does a lookup in the protection database (pdb) and obtains a list of all groups that the authenticated user is a member of. The user identity + all numeric group identifiers are stored in a per-user (per-connection?) list. 4- Whenever an action is performed on any object, the server takes the ACL and checks if the user is a member of any of the groups that would allow the operation to complete. So really LDAP wouldn't really be involved much in the token part of this, but really would replace step 4 where we check if the current users is a member of any of the groups listed in the ACL. However this is probably too expensive, a single reintegration may touch several hundred objects each of which may have a couple of groups listed in their ACLs. To keep the number of LDAP queries within reason, it is probably valuable to keep the existing model where we obtain the full list of groups a user belongs to only when a new connection is set up. Since the server stores ACLs as a (uid/gid, rights) tuple, the user and group names when when an ACL is updated have to be mapped to numeric group identifiers, but ACLs are not updated all that frequently. However, nothing in LDAP actually is based on numeric ids, assigns them or enforces their constistency. Another problem is that the last time I looked at the openldap library, which would have to be linked with the Coda server for most of the described functionality, is using pthreads which have some issues when mixed with Coda's userspace threading. It also was randomly using blocking operations (I guess assuming that the calling application uses kernel threads?) during which the Coda server is unable to send any responses back to clients. And failure handling was problematic. If a backend LDAP server fell over all queries would fail until the ldap handle was closed and reopened. So this meant that we had to keep track of all outstanding queries and resubmit them after failover happens. Things may have improved though, most of this was with early openldap releases probably about 6 years ago. Anything that has survived from these early attempts should be at, /coda/coda.cs.cmu.edu/usr/pam/development/ldap-coda/ Not so long ago I revisited some bits, but approaching it more from the user/management side. I imported a snapshot of our pdbtool user/group databases into an LDAP repository and tried to see how we could move pdbtool like functionality to an LDAP server. /coda/coda.cs.cmu.edu/usr/jaharkes/ldap/ The main program is 'codapts' which may seem familiar to anyone who has worked with AFS as it implements a similar set of operations as the AFS 'pts' tool, some operations require system:administrator membership, but users are allowed to create/manage their own groups and such. $ codapts help codapts: Commands are: adduser add a user to a group chown change ownership of a group chfn change user name and information chsh change login shell creategroup create a new group createuser create a new user delete delete a user or group from database examine examine an entry help get help on commands listentries list users/groups in the protection database listmax list max id listowned list groups owned by an entry membership list membership of a user or group passwd change user password removeuser remove a user from a group rename rename user or group setfields set fields for an entry setmax (re)set max id There is also some code (tokens.py) that was intended to be used as an LDAP server plugin to allow the ldap server to return a valid Coda token. I guess I never figured out how to get the authenticated user identity from the ldap server and ended up using it mostly as a testing tool while I was implementing the new Coda token format that was introduced around the same time as rpc2-2.0. > Still, the source code is quite complicated and I could use a hand on > some of my questions : > - are ACLs checker(s) only based on tokens, or do they make > references to the user database ? > what I mean here is : do I have to create a new user in pdbtool for each > of the users in the LDAP database ? > If I do, is it possible to check if a user exists in the server database > without using any password ? The server doesn't need passwords or anything to validate membership (i.e. ACL rights) of a user that presented a valid token against the pdbtool database. But it does need to know such information. So this would either involve having the Coda server use LDAP to query for group membership information, which may be somewhat complicated as I described earlier. Or have a way to synchronize the LDAP and pdbtool database contents, (periodically) export all users and groups from LDAP and import them into pdbtool. > - I see in U_BindToServer (line 325 of coda/coda-src/auth2/auser.c) > a loop on each of the auth servers. while using LDAP there is only one > LDAP server, do the tokens have to be registered to each servers or is > it that the tokens are stored on the client and sent to the servers at > each requests if needed ? Tokens are generated by the auth2 daemon, but anyone who has access to the shared authentication secret can in principle generate a valid token (this is a secret that is shared between auth2 and codasrv, that way codasrv can tell if the token came from auth2 and has not been tampered with, etc.) > - I am not sure where the token is generated, I don't really get the > whole token system in fact, if it is generated by the client wouldn't > that be a security issue ? So if it generated by the server, LDAP auth > doesn't seems that easy :( > > do you think it is usefull to create a whole new way to authenticate > users, or should I create a tool to synchronize coda user database with > the ldap ? Synchronizing LDAP with the pdbtool database may be useful, because it will allow the server to correctly test ACL/group membership. But it won't solve your authentication issues. ldap uses hash+salt based password authentication, while clog and auth2 depend on both sides proving to each other that they know the same shared secret without actually revealing the secret, so auth2 can't use the passwords as they are stored in ldap. And LDAP probably can't be trusted to store the (cleartext) passwords that auth2 would like to use. JanReceived on 2007-03-07 15:40:56