def initgroups(uid, primaryGid): """ Initializes the group access list. If the C extension is present, we're calling it, which in turn calls initgroups(3). If not, this is done by reading the group database /etc/group and using all groups of which C{uid} is a member. The additional group C{primaryGid} is also added to the list. If the given user is a member of more than C{NGROUPS}, arbitrary groups will be silently discarded to bring the number below that limit. @type uid: C{int} @param uid: The UID for which to look up group information. @type primaryGid: C{int} or C{NoneType} @param primaryGid: If provided, an additional GID to include when setting the groups. """ if _c_initgroups is not None: return _c_initgroups(pwd.getpwuid(uid)[0], primaryGid) try: # Try to get the maximum number of groups max_groups = os.sysconf("SC_NGROUPS_MAX") except: # No predefined limit max_groups = 0 username = pwd.getpwuid(uid)[0] l = [] if primaryGid is not None: l.append(primaryGid) for groupname, password, gid, userlist in grp.getgrall(): if username in userlist: l.append(gid) if len(l) == max_groups: break # No more groups, ignore any more try: _setgroups_until_success(l) except OSError as e: # We might be able to remove this code now that we # don't try to setgid/setuid even when not asked to. if e.errno == errno.EPERM: for g in getgroups(): if g not in l: raise else: raise