[issue7900] posix.getgroups() failure on Mac OS X

Ronald Oussoren report at bugs.python.org
Thu Jul 8 22:30:27 CEST 2010

Ronald Oussoren <ronaldoussoren at mac.com> added the comment:

I got some time and did an experiment to deduce how multiple groups behave. This comment is rather long, a very short summary of the results is that OSX behaves oddly.

What I did:

* This is on OSX 10.6
* Create 18 groups named group1 to group18
* Create a user testuser that is a member of those groups:

$ id testuser
uid=504(testuser) gid=20(staff) groups=20(staff),514(group10),512(group8),513(group9),511(group7),515(group11),520(group16),516(group12),507(group3),517(group13),61(localaccounts),12(everyone),509(group5),505(group1),518(group14),510(group6),508(group4),521(group17),506(group2),402(com.apple.sharepoint.group.1),519(group15),522(group18)

  The user is actually a member of over 18 groups, it is a member of
  a number of system groups as well (but note: not the admin group)

* Create 18 files named 1 to 18, echo is owned by the group with
  the same number, contains its sequence number ('1' in 'group1')
  and has mode '0060':

$ ls -l
total 144
----rw----  1 ronald  group1   2 Jul  8 21:56 1
----rw----  1 ronald  group10  3 Jul  8 21:56 10
----rw----  1 ronald  group11  3 Jul  8 21:56 11
----rw----  1 ronald  group12  3 Jul  8 21:56 12
----rw----  1 ronald  group13  3 Jul  8 21:56 13
----rw----  1 ronald  group14  3 Jul  8 21:56 14
----rw----  1 ronald  group15  3 Jul  8 21:56 15
----rw----  1 ronald  group16  3 Jul  8 21:56 16
----rw----  1 ronald  group17  3 Jul  8 21:56 17
----rw----  1 ronald  group18  3 Jul  8 21:56 18
----rw----  1 ronald  group2   2 Jul  8 21:56 2
----rw----  1 ronald  group3   2 Jul  8 21:56 3
----rw----  1 ronald  group4   2 Jul  8 21:56 4
----rw----  1 ronald  group5   2 Jul  8 21:56 5
----rw----  1 ronald  group6   2 Jul  8 21:56 6
----rw----  1 ronald  group7   2 Jul  8 21:56 7
----rw----  1 ronald  group8   2 Jul  8 21:56 8
----rw----  1 ronald  group9   2 Jul  8 21:56 9

* Log in as that user, I used fast  user switching for that

* The user can read all files, that which means that the user is
  a member of all 18 groups as far as filesystem access is concerned

* My own account is not a member of the 18 groups and can not read
  the files (tested just in case access control is totally broken)

* Removing testuser from a group has no effect for running processes,
  but does affect new Terminal windows.

  This is different than what I had expected, I expected that the
  new window would have the same permissions as the already opened

* I also added a new group (group19) and made testuser a member of that
  group. Using the same technique as before I observed that a shell
  in a new Terminal window had group19 in its effective group list.

According to an engineer I had an e-mail conversation with this behaviour is intentional, which is why they patched /usr/bin/python in OSX 10.6 to use the new getgroups implementation.

IMO for most users the new getgroups (the one you get when _DARWIN_C_SOURCE is defined) more closely matches system behavior (that is, it returns the effective group list for regular processes). 

The only users that will see the odd behavior w.r.t. os.setgroups are those running scripts as root that use both os.setgroups and os.getgroups.  

Note that explicitly setting the effective uid and gid of processes is somewhat frowned upon by Apple, they'd prefer if all daemon processes where started using launchd and used launchd to start them using the correct permissions. A tool like ssh should use initgroup to initialize the effective group list, and that will do the right thing (which appearently is the odd behaviour I saw in new Terminal sessions).

I therefore propose to both keep _DARWIN_C_SOURCE and enhance the posix.getgroups implementation to deal with the fact that getgroups(3) may return more groups than we'd expect.

An earlier comment noted that such code might even be useful on Linux where MAX_GROUPS is 2**16 and the current implementation therefore uses a mostly unnecessarily large buffer on the stack, which may cause stack overflows.


Python tracker <report at bugs.python.org>

More information about the Python-bugs-list mailing list