sattvik: 15:29 Oct 08, 2008
If a particular system has multiple instances of a given group, group authentication doesn't work.
For example on my Linux system using nss_ldap-258, I have two 'lp' groups. The first group is retrieved from the /etc/group file, and the second is retrieved from my LDAP server. Using getgrnam() only retrieves entry from the first instance of the group.
In order to fix this problem, I propose using getgrent() instead of of getgrnam(). This requires a more tedious verification since it requires CUPS to iterate through each group.
My patch functions as follows:
1. Add a new local variable 'foundit' in order to flag if group membership is confirmed.
2. Reinitialise the group database by calling setgrent() and set foundit to 0.
3. Iterate through each group using getgrent(): a. If the name of the group does not match groupname, continue to the next loop. b. I first check to see if the user's gid matches the groups id. If the two values match, I set foundit and break out of the loop. In the original code, this is done later, but I do it sooner since it is a theoretically quicker check. c. Next, check to see if the username matches any group member's name. If so, set foundit and break out of the loop.
4. Once the program leaves the loop, reset the group database by calling endgrent().
5. Finally, if foundit has been set, exit the function signalling success. |
mike: 16:48 Oct 08, 2008
Reassigning as a feature request for CUPS 1.4. This is *not* a bug, but rather a limitation of the current implementation and the underlying Linux name services.
Having multiple groups with the same name is a REALLY bad idea in general, and if they do have the same name they should be joined (as is usually the case for NIS, for example...) |
mike: 20:14 Oct 09, 2008
I'm pushing this to CUPS 1.5; there are performance and security considerations that need to be thought out before we incorporate any changes. |
sattvik: 07:50 Oct 10, 2008
While I agree that this is a limitation of the current implementation and underlying name system, at the very least it needs to be better documented.
Gentoo adds the 'lpadmin' group with gid 106 automatically to the '/etc/group' file when installing CUPS. On my network, I use LDAP to manage my users. If I wish to include a user in lpadmin, LDAP itself needs to have a copy of the group. So, I have added 'lpadmin' with gid 106 into the LDAP database.
As a result, if I use the 'getent' command, the lpadmin group shows up twice in the list, first from the file and then from LDAP. However, other commands, such as shadow's 'groups' command use the iterative getgrent() method for getting a user's groups.
In the end, although this may be a somewhat obscure limitation, it is quite confounding to an administrator who doesn't understand why CUPS is not authorising users despite successful authentication. I do not know how rare it is, but I imagine it is likely to occur in a number of scenarios:
1. When converting a system from one type of database, e.g. NIS, to another
2. With mobile systems that move from one network to another
3. In a situation like Gentoo, if system is not configured to use LDAP at the time of CUPS installation, it will create the local group. Once the system is configured to look up entries in LDAP, the local group effectively clobbers the remote group.
An alternative fix is to use 'getgrouplist()'. This function correctly retrieves a list of all of the user's groups, including the user's primary group. As such, this function can replace iterative getgrent() calls (and may be better performance since, but I am not certain). However, patching CUPS to use this function will require some additional configuration checks.
If desired, I can attempt to make a patch that uses getgrouplist() instead of iterative getgrent() calls. |