From 48106435eb8246f1a73f59cc7a97631b7c477818 Mon Sep 17 00:00:00 2001 From: "antoine.pitrou" Date: Wed, 2 Dec 2009 20:37:54 +0000 Subject: [PATCH] Issue #7333: The `posix` module gains an `initgroups()` function providing access to the initgroups(3) C library call on Unix systems which implement it. Patch by Jean-Paul Calderone. git-svn-id: http://svn.python.org/projects/python/trunk@76636 6015fed2-1504-0410-9fe1-9d1591cc4771 --- Doc/library/os.rst | 9 +++++++++ Lib/test/test_posix.py | 22 ++++++++++++++++++++++ Misc/NEWS | 4 ++++ Modules/posixmodule.c | 27 +++++++++++++++++++++++++++ configure | 5 +++-- configure.in | 2 +- pyconfig.h.in | 3 +++ 7 files changed, 69 insertions(+), 3 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 0036845560..fac37b0e07 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -136,6 +136,15 @@ process and user. Availability: Unix. +.. function:: initgroups(username, gid) + + Call the system initgroups() to initialize the group access list with all of + the groups of which the specified username is a member, plus the specified + group id. Availability: Unix. + + .. versionadded:: 2.7 + + .. function:: getlogin() Return the name of the user logged in on the controlling terminal of the diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index aaa384124c..c6da157446 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -5,6 +5,7 @@ from test import test_support # Skip these tests if there is no posix module. posix = test_support.import_module('posix') +import errno import time import os import pwd @@ -83,6 +84,27 @@ class PosixTester(unittest.TestCase): new_group_ids = (current_group_ids[0]+1, -1, -1) self.assertRaises(OSError, posix.setresgid, *new_group_ids) + @unittest.skipUnless(hasattr(posix, 'initgroups'), + "test needs os.initgroups()") + def test_initgroups(self): + # It takes a string and an integer; check that it raises a TypeError + # for other argument lists. + self.assertRaises(TypeError, posix.initgroups) + self.assertRaises(TypeError, posix.initgroups, None) + self.assertRaises(TypeError, posix.initgroups, 3, "foo") + self.assertRaises(TypeError, posix.initgroups, "foo", 3, object()) + + # If a non-privileged user invokes it, it should fail with OSError + # EPERM. + if os.getuid() != 0: + name = pwd.getpwuid(posix.getuid()).pw_name + try: + posix.initgroups(name, 13) + except OSError as e: + self.assertEquals(e.errno, errno.EPERM) + else: + self.fail("Expected OSError to be raised by initgroups") + def test_statvfs(self): if hasattr(posix, 'statvfs'): self.assertTrue(posix.statvfs(os.curdir)) diff --git a/Misc/NEWS b/Misc/NEWS index a8b56e275c..92f9026204 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -490,6 +490,10 @@ Core and Builtins Library ------- +- Issue #7333: The `posix` module gains an `initgroups()` function providing + access to the initgroups(3) C library call on Unix systems which implement + it. Patch by Jean-Paul Calderone. + - Issue #7408: Fixed distutils.tests.sdist so it doesn't check for group ownership when the group is not forced, because the group may be different from the user's group and inherit from its container when the test is run. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 68e7286efc..8956e939c2 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -3861,6 +3861,30 @@ posix_getgroups(PyObject *self, PyObject *noargs) } #endif +#ifdef HAVE_INITGROUPS +PyDoc_STRVAR(posix_initgroups__doc__, +"initgroups(username, gid) -> None\n\n\ +Call the system initgroups() to initialize the group access list with all of\n\ +the groups of which the specified username is a member, plus the specified\n\ +group id."); + +static PyObject * +posix_initgroups(PyObject *self, PyObject *args) +{ + char *username; + long gid; + + if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid)) + return NULL; + + if (initgroups(username, (gid_t) gid) == -1) + return PyErr_SetFromErrno(PyExc_OSError); + + Py_INCREF(Py_None); + return Py_None; +} +#endif + #ifdef HAVE_GETPGID PyDoc_STRVAR(posix_getpgid__doc__, "getpgid(pid) -> pgid\n\n\ @@ -8629,6 +8653,9 @@ static PyMethodDef posix_methods[] = { #ifdef HAVE_SETGROUPS {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__}, #endif /* HAVE_SETGROUPS */ +#ifdef HAVE_INITGROUPS + {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__}, +#endif /* HAVE_INITGROUPS */ #ifdef HAVE_GETPGID {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__}, #endif /* HAVE_GETPGID */ diff --git a/configure b/configure index 55e95347f4..8391a17e99 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76558 . +# From configure.in Revision: 76568 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -17895,11 +17895,12 @@ echo "${ECHO_T}MACHDEP_OBJS" >&6; } + for ac_func in alarm setitimer getitimer bind_textdomain_codeset chown \ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ - kill killpg lchmod lchown lstat mkfifo mknod mktime \ + initgroups kill killpg lchmod lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ diff --git a/configure.in b/configure.in index 95d100a4cd..e7e6b9173f 100644 --- a/configure.in +++ b/configure.in @@ -2547,7 +2547,7 @@ AC_CHECK_FUNCS(alarm setitimer getitimer bind_textdomain_codeset chown \ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ - kill killpg lchmod lchown lstat mkfifo mknod mktime \ + initgroups kill killpg lchmod lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ diff --git a/pyconfig.h.in b/pyconfig.h.in index 7541213d8e..fd58443b71 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -301,6 +301,9 @@ /* Define to 1 if you have the `getpeername' function. */ #undef HAVE_GETPEERNAME +/* Define to 1 if you have the `initgroups' function. */ +#undef HAVE_INITGROUPS + /* Define to 1 if you have the `getpgid' function. */ #undef HAVE_GETPGID -- 2.11.4.GIT