Issue #9344: Add os.getgrouplist().
This commit is contained in:
parent
10c30d6764
commit
b0ae53d8a0
|
@ -219,6 +219,17 @@ process and user.
|
||||||
Availability: Unix.
|
Availability: Unix.
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: getgrouplist(user, group)
|
||||||
|
|
||||||
|
Return list of group ids that *user* belongs to. If *group* is not in the
|
||||||
|
list, it is included; typically, *group* is specified as the group ID
|
||||||
|
field from the password record for *user*.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: getgroups()
|
.. function:: getgroups()
|
||||||
|
|
||||||
Return list of supplemental group ids associated with the current process.
|
Return list of supplemental group ids associated with the current process.
|
||||||
|
|
|
@ -569,6 +569,21 @@ class PosixTester(unittest.TestCase):
|
||||||
os.chdir(curdir)
|
os.chdir(curdir)
|
||||||
support.rmtree(base_path)
|
support.rmtree(base_path)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
|
||||||
|
@unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
|
||||||
|
@unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
|
||||||
|
def test_getgrouplist(self):
|
||||||
|
with os.popen('id -G') as idg:
|
||||||
|
groups = idg.read().strip()
|
||||||
|
|
||||||
|
if not groups:
|
||||||
|
raise unittest.SkipTest("need working 'id -G'")
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
set([int(x) for x in groups.split()]),
|
||||||
|
set(posix.getgrouplist(pwd.getpwuid(os.getuid())[0],
|
||||||
|
pwd.getpwuid(os.getuid())[3])))
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
|
@unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
|
||||||
def test_getgroups(self):
|
def test_getgroups(self):
|
||||||
with os.popen('id -G') as idg:
|
with os.popen('id -G') as idg:
|
||||||
|
|
|
@ -4672,6 +4672,70 @@ posix_getpid(PyObject *self, PyObject *noargs)
|
||||||
return PyLong_FromPid(getpid());
|
return PyLong_FromPid(getpid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_GETGROUPLIST
|
||||||
|
PyDoc_STRVAR(posix_getgrouplist__doc__,
|
||||||
|
"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
|
||||||
|
Returns a list of groups to which a user belongs.\n\n\
|
||||||
|
user: username to lookup\n\
|
||||||
|
group: base group id of the user");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_getgrouplist(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
#ifdef NGROUPS_MAX
|
||||||
|
#define MAX_GROUPS NGROUPS_MAX
|
||||||
|
#else
|
||||||
|
/* defined to be 16 on Solaris7, so this should be a small number */
|
||||||
|
#define MAX_GROUPS 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char *user;
|
||||||
|
int i, ngroups;
|
||||||
|
PyObject *list;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
int *groups, basegid;
|
||||||
|
#else
|
||||||
|
gid_t *groups, basegid;
|
||||||
|
#endif
|
||||||
|
ngroups = MAX_GROUPS;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "si", &user, &basegid))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
groups = PyMem_Malloc(ngroups * sizeof(int));
|
||||||
|
#else
|
||||||
|
groups = PyMem_Malloc(ngroups * sizeof(gid_t));
|
||||||
|
#endif
|
||||||
|
if (groups == NULL)
|
||||||
|
return PyErr_NoMemory();
|
||||||
|
|
||||||
|
if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
|
||||||
|
PyMem_Del(groups);
|
||||||
|
return posix_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
list = PyList_New(ngroups);
|
||||||
|
if (list == NULL) {
|
||||||
|
PyMem_Del(groups);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ngroups; i++) {
|
||||||
|
PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
|
||||||
|
if (o == NULL) {
|
||||||
|
Py_DECREF(list);
|
||||||
|
PyMem_Del(groups);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyList_SET_ITEM(list, i, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyMem_Del(groups);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_GETGROUPS
|
#ifdef HAVE_GETGROUPS
|
||||||
PyDoc_STRVAR(posix_getgroups__doc__,
|
PyDoc_STRVAR(posix_getgroups__doc__,
|
||||||
|
@ -9383,6 +9447,9 @@ static PyMethodDef posix_methods[] = {
|
||||||
#ifdef HAVE_GETGID
|
#ifdef HAVE_GETGID
|
||||||
{"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
|
{"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
|
||||||
#endif /* HAVE_GETGID */
|
#endif /* HAVE_GETGID */
|
||||||
|
#ifdef HAVE_GETGROUPLIST
|
||||||
|
{"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
|
||||||
|
#endif
|
||||||
#ifdef HAVE_GETGROUPS
|
#ifdef HAVE_GETGROUPS
|
||||||
{"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
|
{"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2541,8 +2541,8 @@ AC_MSG_RESULT(MACHDEP_OBJS)
|
||||||
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
||||||
clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat \
|
clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat \
|
||||||
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
|
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
|
||||||
futimens futimes \
|
futimens futimes gai_strerror \
|
||||||
gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
|
getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
|
||||||
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
|
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
|
||||||
if_nameindex \
|
if_nameindex \
|
||||||
initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mbrtowc mkdirat mkfifo \
|
initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mbrtowc mkdirat mkfifo \
|
||||||
|
|
|
@ -305,6 +305,9 @@
|
||||||
/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
|
/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
|
||||||
#undef HAVE_GETC_UNLOCKED
|
#undef HAVE_GETC_UNLOCKED
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getgrouplist' function. */
|
||||||
|
#undef HAVE_GETGROUPLIST
|
||||||
|
|
||||||
/* Define to 1 if you have the `getgroups' function. */
|
/* Define to 1 if you have the `getgroups' function. */
|
||||||
#undef HAVE_GETGROUPS
|
#undef HAVE_GETGROUPS
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue