]> granicus.if.org Git - python/commitdiff
Issue #7333: The `posix` module gains an `initgroups()` function providing
authorAntoine Pitrou <solipsis@pitrou.net>
Wed, 2 Dec 2009 20:37:54 +0000 (20:37 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Wed, 2 Dec 2009 20:37:54 +0000 (20:37 +0000)
access to the initgroups(3) C library call on Unix systems which implement
it.  Patch by Jean-Paul Calderone.

Doc/library/os.rst
Lib/test/test_posix.py
Misc/NEWS
Modules/posixmodule.c
configure
configure.in
pyconfig.h.in

index 0036845560b0c6c32fd1b140b45d24bd1428f34e..fac37b0e07a8488b6a46636b1fe8edf78edc0dbd 100644 (file)
@@ -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
index aaa384124c990181b056cee67daf6595dbc188a0..c6da1574463f164409516e8564b98188ba5a44af 100644 (file)
@@ -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))
index a8b56e275ce9b68260f9c5235c53f8cf5a8537ef..92f9026204be862b3a064f5a3fd3cdf8d6141b27 100644 (file)
--- 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.
index 68e7286efcb5e66bb293076a9422dd2e500291b0..8956e939c2be24c553463ebafc889bbd790cf9d2 100644 (file)
@@ -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 */
index 55e95347f4e9f692533f73288025ad0de68701bb..8391a17e99f07087ffb4678add179ea212ccdd09 100755 (executable)
--- 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.
 #
@@ -17893,13 +17893,14 @@ 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 \
index 95d100a4cd7c9d17b66ce9a6ef0ea38381f14e2b..e7e6b9173f62d31e428ae3c5887b4e16920a1845 100644 (file)
@@ -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 \
index 7541213d8e2b642dfecd6b494e17673a4f5a0758..fd58443b7160bffbcc2f53194fd0a16b19784de3 100644 (file)
 /* 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