mirror of
https://github.com/python/cpython.git
synced 2025-01-19 06:54:52 +08:00
Issue #4591: Uid and gid values larger than 2**31 are supported now.
This commit is contained in:
parent
083c0aac32
commit
da5c2a0646
@ -222,10 +222,20 @@ class PosixTester(unittest.TestCase):
|
||||
if hasattr(posix, 'stat'):
|
||||
self.assertTrue(posix.stat(test_support.TESTFN))
|
||||
|
||||
def _test_all_chown_common(self, chown_func, first_param):
|
||||
def _test_all_chown_common(self, chown_func, first_param, stat_func):
|
||||
"""Common code for chown, fchown and lchown tests."""
|
||||
def check_stat():
|
||||
if stat_func is not None:
|
||||
stat = stat_func(first_param)
|
||||
self.assertEqual(stat.st_uid, os.getuid())
|
||||
self.assertEqual(stat.st_gid, os.getgid())
|
||||
# test a successful chown call
|
||||
chown_func(first_param, os.getuid(), os.getgid())
|
||||
check_stat()
|
||||
chown_func(first_param, -1, os.getgid())
|
||||
check_stat()
|
||||
chown_func(first_param, os.getuid(), -1)
|
||||
check_stat()
|
||||
|
||||
if os.getuid() == 0:
|
||||
try:
|
||||
@ -245,8 +255,12 @@ class PosixTester(unittest.TestCase):
|
||||
"behavior")
|
||||
else:
|
||||
# non-root cannot chown to root, raises OSError
|
||||
self.assertRaises(OSError, chown_func,
|
||||
first_param, 0, 0)
|
||||
self.assertRaises(OSError, chown_func, first_param, 0, 0)
|
||||
check_stat()
|
||||
self.assertRaises(OSError, chown_func, first_param, -1, 0)
|
||||
check_stat()
|
||||
self.assertRaises(OSError, chown_func, first_param, 0, -1)
|
||||
check_stat()
|
||||
|
||||
@unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
|
||||
def test_chown(self):
|
||||
@ -256,7 +270,8 @@ class PosixTester(unittest.TestCase):
|
||||
|
||||
# re-create the file
|
||||
open(test_support.TESTFN, 'w').close()
|
||||
self._test_all_chown_common(posix.chown, test_support.TESTFN)
|
||||
self._test_all_chown_common(posix.chown, test_support.TESTFN,
|
||||
getattr(posix, 'stat', None))
|
||||
|
||||
@unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
|
||||
def test_fchown(self):
|
||||
@ -266,7 +281,8 @@ class PosixTester(unittest.TestCase):
|
||||
test_file = open(test_support.TESTFN, 'w')
|
||||
try:
|
||||
fd = test_file.fileno()
|
||||
self._test_all_chown_common(posix.fchown, fd)
|
||||
self._test_all_chown_common(posix.fchown, fd,
|
||||
getattr(posix, 'fstat', None))
|
||||
finally:
|
||||
test_file.close()
|
||||
|
||||
@ -275,7 +291,8 @@ class PosixTester(unittest.TestCase):
|
||||
os.unlink(test_support.TESTFN)
|
||||
# create a symlink
|
||||
os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
|
||||
self._test_all_chown_common(posix.lchown, test_support.TESTFN)
|
||||
self._test_all_chown_common(posix.lchown, test_support.TESTFN,
|
||||
getattr(posix, 'lstat', None))
|
||||
|
||||
def test_chdir(self):
|
||||
if hasattr(posix, 'chdir'):
|
||||
|
@ -49,7 +49,9 @@ class PwdTest(unittest.TestCase):
|
||||
|
||||
def test_errors(self):
|
||||
self.assertRaises(TypeError, pwd.getpwuid)
|
||||
self.assertRaises(TypeError, pwd.getpwuid, 3.14)
|
||||
self.assertRaises(TypeError, pwd.getpwnam)
|
||||
self.assertRaises(TypeError, pwd.getpwnam, 42)
|
||||
self.assertRaises(TypeError, pwd.getpwall, 42)
|
||||
|
||||
# try to get some errors
|
||||
@ -93,6 +95,13 @@ class PwdTest(unittest.TestCase):
|
||||
self.assertNotIn(fakeuid, byuids)
|
||||
self.assertRaises(KeyError, pwd.getpwuid, fakeuid)
|
||||
|
||||
# -1 shouldn't be a valid uid because it has a special meaning in many
|
||||
# uid-related functions
|
||||
self.assertRaises(KeyError, pwd.getpwuid, -1)
|
||||
# should be out of uid_t range
|
||||
self.assertRaises(KeyError, pwd.getpwuid, 2**128)
|
||||
self.assertRaises(KeyError, pwd.getpwuid, -2**128)
|
||||
|
||||
def test_main():
|
||||
test_support.run_unittest(PwdTest)
|
||||
|
||||
|
@ -579,6 +579,11 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile
|
||||
Modules/python.o: $(srcdir)/Modules/python.c
|
||||
$(MAINCC) -c $(PY_CFLAGS) -o $@ $(srcdir)/Modules/python.c
|
||||
|
||||
Modules/posixmodule.o: $(srcdir)/Modules/posixmodule.c $(srcdir)/Modules/posixmodule.h
|
||||
|
||||
Modules/grpmodule.o: $(srcdir)/Modules/grpmodule.c $(srcdir)/Modules/posixmodule.h
|
||||
|
||||
Modules/pwdmodule.o: $(srcdir)/Modules/pwdmodule.c $(srcdir)/Modules/posixmodule.h
|
||||
|
||||
$(GRAMMAR_H): $(GRAMMAR_INPUT) $(PGENSRCS)
|
||||
@$(MKDIR_P) Include
|
||||
|
@ -204,6 +204,8 @@ Library
|
||||
|
||||
- Issue #17052: unittest discovery should use self.testLoader.
|
||||
|
||||
- Issue #4591: Uid and gid values larger than 2**31 are supported now.
|
||||
|
||||
- Issue #17141: random.vonmisesvariate() no more hangs for large kappas.
|
||||
|
||||
- Issue #17149: Fix random.vonmisesvariate to always return results in
|
||||
|
@ -3,8 +3,8 @@
|
||||
|
||||
#include "Python.h"
|
||||
#include "structseq.h"
|
||||
#include "posixmodule.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <grp.h>
|
||||
|
||||
static PyStructSequence_Field struct_group_type_fields[] = {
|
||||
@ -70,7 +70,7 @@ mkgrent(struct group *p)
|
||||
Py_INCREF(Py_None);
|
||||
}
|
||||
#endif
|
||||
SET(setIndex++, PyInt_FromLong((long) p->gr_gid));
|
||||
SET(setIndex++, _PyInt_FromGid(p->gr_gid));
|
||||
SET(setIndex++, w);
|
||||
#undef SET
|
||||
|
||||
@ -86,17 +86,25 @@ static PyObject *
|
||||
grp_getgrgid(PyObject *self, PyObject *pyo_id)
|
||||
{
|
||||
PyObject *py_int_id;
|
||||
unsigned int gid;
|
||||
gid_t gid;
|
||||
struct group *p;
|
||||
|
||||
py_int_id = PyNumber_Int(pyo_id);
|
||||
if (!py_int_id)
|
||||
return NULL;
|
||||
gid = PyInt_AS_LONG(py_int_id);
|
||||
return NULL;
|
||||
if (!_Py_Gid_Converter(py_int_id, &gid)) {
|
||||
Py_DECREF(py_int_id);
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(py_int_id);
|
||||
|
||||
if ((p = getgrgid(gid)) == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
|
||||
if (gid < 0)
|
||||
PyErr_Format(PyExc_KeyError,
|
||||
"getgrgid(): gid not found: %ld", (long)gid);
|
||||
else
|
||||
PyErr_Format(PyExc_KeyError,
|
||||
"getgrgid(): gid not found: %lu", (unsigned long)gid);
|
||||
return NULL;
|
||||
}
|
||||
return mkgrent(p);
|
||||
|
@ -27,6 +27,9 @@
|
||||
|
||||
#include "Python.h"
|
||||
#include "structseq.h"
|
||||
#ifndef MS_WINDOWS
|
||||
#include "posixmodule.h"
|
||||
#endif
|
||||
|
||||
#if defined(__VMS)
|
||||
# include <unixio.h>
|
||||
@ -347,6 +350,134 @@ extern int lstat(const char *, struct stat *);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef MS_WINDOWS
|
||||
PyObject *
|
||||
_PyInt_FromUid(uid_t uid)
|
||||
{
|
||||
if (uid <= LONG_MAX)
|
||||
return PyInt_FromLong(uid);
|
||||
return PyLong_FromUnsignedLong(uid);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
_PyInt_FromGid(gid_t gid)
|
||||
{
|
||||
if (gid <= LONG_MAX)
|
||||
return PyInt_FromLong(gid);
|
||||
return PyLong_FromUnsignedLong(gid);
|
||||
}
|
||||
|
||||
int
|
||||
_Py_Uid_Converter(PyObject *obj, void *p)
|
||||
{
|
||||
int overflow;
|
||||
long result;
|
||||
if (PyFloat_Check(obj)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"integer argument expected, got float");
|
||||
return 0;
|
||||
}
|
||||
result = PyLong_AsLongAndOverflow(obj, &overflow);
|
||||
if (overflow < 0)
|
||||
goto OverflowDown;
|
||||
if (!overflow && result == -1) {
|
||||
/* error or -1 */
|
||||
if (PyErr_Occurred())
|
||||
return 0;
|
||||
*(uid_t *)p = (uid_t)-1;
|
||||
}
|
||||
else {
|
||||
/* unsigned uid_t */
|
||||
unsigned long uresult;
|
||||
if (overflow > 0) {
|
||||
uresult = PyLong_AsUnsignedLong(obj);
|
||||
if (PyErr_Occurred()) {
|
||||
if (PyErr_ExceptionMatches(PyExc_OverflowError))
|
||||
goto OverflowUp;
|
||||
return 0;
|
||||
}
|
||||
if ((uid_t)uresult == (uid_t)-1)
|
||||
goto OverflowUp;
|
||||
} else {
|
||||
if (result < 0)
|
||||
goto OverflowDown;
|
||||
uresult = result;
|
||||
}
|
||||
if (sizeof(uid_t) < sizeof(long) &&
|
||||
(unsigned long)(uid_t)uresult != uresult)
|
||||
goto OverflowUp;
|
||||
*(uid_t *)p = (uid_t)uresult;
|
||||
}
|
||||
return 1;
|
||||
|
||||
OverflowDown:
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
"user id is less than minimum");
|
||||
return 0;
|
||||
|
||||
OverflowUp:
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
"user id is greater than maximum");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_Py_Gid_Converter(PyObject *obj, void *p)
|
||||
{
|
||||
int overflow;
|
||||
long result;
|
||||
if (PyFloat_Check(obj)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"integer argument expected, got float");
|
||||
return 0;
|
||||
}
|
||||
result = PyLong_AsLongAndOverflow(obj, &overflow);
|
||||
if (overflow < 0)
|
||||
goto OverflowDown;
|
||||
if (!overflow && result == -1) {
|
||||
/* error or -1 */
|
||||
if (PyErr_Occurred())
|
||||
return 0;
|
||||
*(gid_t *)p = (gid_t)-1;
|
||||
}
|
||||
else {
|
||||
/* unsigned gid_t */
|
||||
unsigned long uresult;
|
||||
if (overflow > 0) {
|
||||
uresult = PyLong_AsUnsignedLong(obj);
|
||||
if (PyErr_Occurred()) {
|
||||
if (PyErr_ExceptionMatches(PyExc_OverflowError))
|
||||
goto OverflowUp;
|
||||
return 0;
|
||||
}
|
||||
if ((gid_t)uresult == (gid_t)-1)
|
||||
goto OverflowUp;
|
||||
} else {
|
||||
if (result < 0)
|
||||
goto OverflowDown;
|
||||
uresult = result;
|
||||
}
|
||||
if (sizeof(gid_t) < sizeof(long) &&
|
||||
(unsigned long)(gid_t)uresult != uresult)
|
||||
goto OverflowUp;
|
||||
*(gid_t *)p = (gid_t)uresult;
|
||||
}
|
||||
return 1;
|
||||
|
||||
OverflowDown:
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
"group id is less than minimum");
|
||||
return 0;
|
||||
|
||||
OverflowUp:
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
"group id is greater than maximum");
|
||||
return 0;
|
||||
}
|
||||
#endif /* MS_WINDOWS */
|
||||
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1400
|
||||
/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
|
||||
* valid and raise an assertion if it isn't.
|
||||
@ -1306,8 +1437,13 @@ _pystat_fromstructstat(STRUCT_STAT *st)
|
||||
PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
|
||||
#endif
|
||||
PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
|
||||
PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
|
||||
PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
|
||||
#if defined(MS_WINDOWS)
|
||||
PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong(0));
|
||||
PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong(0));
|
||||
#else
|
||||
PyStructSequence_SET_ITEM(v, 4, _PyInt_FromUid(st->st_uid));
|
||||
PyStructSequence_SET_ITEM(v, 5, _PyInt_FromGid(st->st_gid));
|
||||
#endif
|
||||
#ifdef HAVE_LARGEFILE_SUPPORT
|
||||
PyStructSequence_SET_ITEM(v, 6,
|
||||
PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
|
||||
@ -1884,14 +2020,16 @@ static PyObject *
|
||||
posix_chown(PyObject *self, PyObject *args)
|
||||
{
|
||||
char *path = NULL;
|
||||
long uid, gid;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int res;
|
||||
if (!PyArg_ParseTuple(args, "etll:chown",
|
||||
if (!PyArg_ParseTuple(args, "etO&O&:chown",
|
||||
Py_FileSystemDefaultEncoding, &path,
|
||||
&uid, &gid))
|
||||
_Py_Uid_Converter, &uid,
|
||||
_Py_Gid_Converter, &gid))
|
||||
return NULL;
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
res = chown(path, (uid_t) uid, (gid_t) gid);
|
||||
res = chown(path, uid, gid);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (res < 0)
|
||||
return posix_error_with_allocated_filename(path);
|
||||
@ -1911,12 +2049,15 @@ static PyObject *
|
||||
posix_fchown(PyObject *self, PyObject *args)
|
||||
{
|
||||
int fd;
|
||||
long uid, gid;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int res;
|
||||
if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
|
||||
if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
|
||||
_Py_Uid_Converter, &uid,
|
||||
_Py_Gid_Converter, &gid))
|
||||
return NULL;
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
res = fchown(fd, (uid_t) uid, (gid_t) gid);
|
||||
res = fchown(fd, uid, gid);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (res < 0)
|
||||
return posix_error();
|
||||
@ -1934,14 +2075,16 @@ static PyObject *
|
||||
posix_lchown(PyObject *self, PyObject *args)
|
||||
{
|
||||
char *path = NULL;
|
||||
long uid, gid;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int res;
|
||||
if (!PyArg_ParseTuple(args, "etll:lchown",
|
||||
if (!PyArg_ParseTuple(args, "etO&O&:lchown",
|
||||
Py_FileSystemDefaultEncoding, &path,
|
||||
&uid, &gid))
|
||||
_Py_Uid_Converter, &uid,
|
||||
_Py_Gid_Converter, &gid))
|
||||
return NULL;
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
res = lchown(path, (uid_t) uid, (gid_t) gid);
|
||||
res = lchown(path, uid, gid);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (res < 0)
|
||||
return posix_error_with_allocated_filename(path);
|
||||
@ -3844,7 +3987,7 @@ Return the current process's effective group id.");
|
||||
static PyObject *
|
||||
posix_getegid(PyObject *self, PyObject *noargs)
|
||||
{
|
||||
return PyInt_FromLong((long)getegid());
|
||||
return _PyInt_FromGid(getegid());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3857,7 +4000,7 @@ Return the current process's effective user id.");
|
||||
static PyObject *
|
||||
posix_geteuid(PyObject *self, PyObject *noargs)
|
||||
{
|
||||
return PyInt_FromLong((long)geteuid());
|
||||
return _PyInt_FromUid(geteuid());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3870,7 +4013,7 @@ Return the current process's group id.");
|
||||
static PyObject *
|
||||
posix_getgid(PyObject *self, PyObject *noargs)
|
||||
{
|
||||
return PyInt_FromLong((long)getgid());
|
||||
return _PyInt_FromGid(getgid());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3945,7 +4088,7 @@ posix_getgroups(PyObject *self, PyObject *noargs)
|
||||
if (result != NULL) {
|
||||
int i;
|
||||
for (i = 0; i < n; ++i) {
|
||||
PyObject *o = PyInt_FromLong((long)alt_grouplist[i]);
|
||||
PyObject *o = _PyInt_FromGid(alt_grouplist[i]);
|
||||
if (o == NULL) {
|
||||
Py_DECREF(result);
|
||||
result = NULL;
|
||||
@ -3974,12 +4117,22 @@ static PyObject *
|
||||
posix_initgroups(PyObject *self, PyObject *args)
|
||||
{
|
||||
char *username;
|
||||
long gid;
|
||||
#ifdef __APPLE__
|
||||
int gid;
|
||||
#else
|
||||
gid_t gid;
|
||||
#endif
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))
|
||||
#ifdef __APPLE__
|
||||
if (!PyArg_ParseTuple(args, "si:initgroups", &username,
|
||||
&gid))
|
||||
#else
|
||||
if (!PyArg_ParseTuple(args, "sO&:initgroups", &username,
|
||||
_Py_Gid_Converter, &gid))
|
||||
#endif
|
||||
return NULL;
|
||||
|
||||
if (initgroups(username, (gid_t) gid) == -1)
|
||||
if (initgroups(username, gid) == -1)
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
@ -4093,7 +4246,7 @@ Return the current process's user id.");
|
||||
static PyObject *
|
||||
posix_getuid(PyObject *self, PyObject *noargs)
|
||||
{
|
||||
return PyInt_FromLong((long)getuid());
|
||||
return _PyInt_FromUid(getuid());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -5740,15 +5893,9 @@ Set the current process's user id.");
|
||||
static PyObject *
|
||||
posix_setuid(PyObject *self, PyObject *args)
|
||||
{
|
||||
long uid_arg;
|
||||
uid_t uid;
|
||||
if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
|
||||
if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
|
||||
return NULL;
|
||||
uid = uid_arg;
|
||||
if (uid != uid_arg) {
|
||||
PyErr_SetString(PyExc_OverflowError, "user id too big");
|
||||
return NULL;
|
||||
}
|
||||
if (setuid(uid) < 0)
|
||||
return posix_error();
|
||||
Py_INCREF(Py_None);
|
||||
@ -5765,15 +5912,9 @@ Set the current process's effective user id.");
|
||||
static PyObject *
|
||||
posix_seteuid (PyObject *self, PyObject *args)
|
||||
{
|
||||
long euid_arg;
|
||||
uid_t euid;
|
||||
if (!PyArg_ParseTuple(args, "l", &euid_arg))
|
||||
if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
|
||||
return NULL;
|
||||
euid = euid_arg;
|
||||
if (euid != euid_arg) {
|
||||
PyErr_SetString(PyExc_OverflowError, "user id too big");
|
||||
return NULL;
|
||||
}
|
||||
if (seteuid(euid) < 0) {
|
||||
return posix_error();
|
||||
} else {
|
||||
@ -5791,15 +5932,9 @@ Set the current process's effective group id.");
|
||||
static PyObject *
|
||||
posix_setegid (PyObject *self, PyObject *args)
|
||||
{
|
||||
long egid_arg;
|
||||
gid_t egid;
|
||||
if (!PyArg_ParseTuple(args, "l", &egid_arg))
|
||||
if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
|
||||
return NULL;
|
||||
egid = egid_arg;
|
||||
if (egid != egid_arg) {
|
||||
PyErr_SetString(PyExc_OverflowError, "group id too big");
|
||||
return NULL;
|
||||
}
|
||||
if (setegid(egid) < 0) {
|
||||
return posix_error();
|
||||
} else {
|
||||
@ -5817,23 +5952,11 @@ Set the current process's real and effective user ids.");
|
||||
static PyObject *
|
||||
posix_setreuid (PyObject *self, PyObject *args)
|
||||
{
|
||||
long ruid_arg, euid_arg;
|
||||
uid_t ruid, euid;
|
||||
if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
|
||||
if (!PyArg_ParseTuple(args, "O&O&:setreuid",
|
||||
_Py_Uid_Converter, &ruid,
|
||||
_Py_Uid_Converter, &euid))
|
||||
return NULL;
|
||||
if (ruid_arg == -1)
|
||||
ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
|
||||
else
|
||||
ruid = ruid_arg; /* otherwise, assign from our long */
|
||||
if (euid_arg == -1)
|
||||
euid = (uid_t)-1;
|
||||
else
|
||||
euid = euid_arg;
|
||||
if ((euid_arg != -1 && euid != euid_arg) ||
|
||||
(ruid_arg != -1 && ruid != ruid_arg)) {
|
||||
PyErr_SetString(PyExc_OverflowError, "user id too big");
|
||||
return NULL;
|
||||
}
|
||||
if (setreuid(ruid, euid) < 0) {
|
||||
return posix_error();
|
||||
} else {
|
||||
@ -5851,23 +5974,11 @@ Set the current process's real and effective group ids.");
|
||||
static PyObject *
|
||||
posix_setregid (PyObject *self, PyObject *args)
|
||||
{
|
||||
long rgid_arg, egid_arg;
|
||||
gid_t rgid, egid;
|
||||
if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
|
||||
if (!PyArg_ParseTuple(args, "O&O&:setregid",
|
||||
_Py_Gid_Converter, &rgid,
|
||||
_Py_Gid_Converter, &egid))
|
||||
return NULL;
|
||||
if (rgid_arg == -1)
|
||||
rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
|
||||
else
|
||||
rgid = rgid_arg; /* otherwise, assign from our long */
|
||||
if (egid_arg == -1)
|
||||
egid = (gid_t)-1;
|
||||
else
|
||||
egid = egid_arg;
|
||||
if ((egid_arg != -1 && egid != egid_arg) ||
|
||||
(rgid_arg != -1 && rgid != rgid_arg)) {
|
||||
PyErr_SetString(PyExc_OverflowError, "group id too big");
|
||||
return NULL;
|
||||
}
|
||||
if (setregid(rgid, egid) < 0) {
|
||||
return posix_error();
|
||||
} else {
|
||||
@ -5885,15 +5996,9 @@ Set the current process's group id.");
|
||||
static PyObject *
|
||||
posix_setgid(PyObject *self, PyObject *args)
|
||||
{
|
||||
long gid_arg;
|
||||
gid_t gid;
|
||||
if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
|
||||
if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
|
||||
return NULL;
|
||||
gid = gid_arg;
|
||||
if (gid != gid_arg) {
|
||||
PyErr_SetString(PyExc_OverflowError, "group id too big");
|
||||
return NULL;
|
||||
}
|
||||
if (setgid(gid) < 0)
|
||||
return posix_error();
|
||||
Py_INCREF(Py_None);
|
||||
@ -5926,35 +6031,13 @@ posix_setgroups(PyObject *self, PyObject *groups)
|
||||
elem = PySequence_GetItem(groups, i);
|
||||
if (!elem)
|
||||
return NULL;
|
||||
if (!PyInt_Check(elem)) {
|
||||
if (!PyLong_Check(elem)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"groups must be integers");
|
||||
Py_DECREF(elem);
|
||||
return NULL;
|
||||
} else {
|
||||
unsigned long x = PyLong_AsUnsignedLong(elem);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"group id too big");
|
||||
Py_DECREF(elem);
|
||||
return NULL;
|
||||
}
|
||||
grouplist[i] = x;
|
||||
/* read back to see if it fits in gid_t */
|
||||
if (grouplist[i] != x) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"group id too big");
|
||||
Py_DECREF(elem);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!PyInt_Check(elem) && !PyLong_Check(elem)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"groups must be integers");
|
||||
Py_DECREF(elem);
|
||||
return NULL;
|
||||
} else {
|
||||
long x = PyInt_AsLong(elem);
|
||||
grouplist[i] = x;
|
||||
if (grouplist[i] != x) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"group id too big");
|
||||
if (!_Py_Gid_Converter(elem, &grouplist[i])) {
|
||||
Py_DECREF(elem);
|
||||
return NULL;
|
||||
}
|
||||
@ -8580,9 +8663,11 @@ Set the current process's real, effective, and saved user ids.");
|
||||
static PyObject*
|
||||
posix_setresuid (PyObject *self, PyObject *args)
|
||||
{
|
||||
/* We assume uid_t is no larger than a long. */
|
||||
long ruid, euid, suid;
|
||||
if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
|
||||
uid_t ruid, euid, suid;
|
||||
if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
|
||||
_Py_Uid_Converter, &ruid,
|
||||
_Py_Uid_Converter, &euid,
|
||||
_Py_Uid_Converter, &suid))
|
||||
return NULL;
|
||||
if (setresuid(ruid, euid, suid) < 0)
|
||||
return posix_error();
|
||||
@ -8598,9 +8683,11 @@ Set the current process's real, effective, and saved group ids.");
|
||||
static PyObject*
|
||||
posix_setresgid (PyObject *self, PyObject *args)
|
||||
{
|
||||
/* We assume uid_t is no larger than a long. */
|
||||
long rgid, egid, sgid;
|
||||
if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
|
||||
gid_t rgid, egid, sgid;
|
||||
if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
|
||||
_Py_Gid_Converter, &rgid,
|
||||
_Py_Gid_Converter, &egid,
|
||||
_Py_Gid_Converter, &sgid))
|
||||
return NULL;
|
||||
if (setresgid(rgid, egid, sgid) < 0)
|
||||
return posix_error();
|
||||
@ -8617,14 +8704,11 @@ static PyObject*
|
||||
posix_getresuid (PyObject *self, PyObject *noargs)
|
||||
{
|
||||
uid_t ruid, euid, suid;
|
||||
long l_ruid, l_euid, l_suid;
|
||||
if (getresuid(&ruid, &euid, &suid) < 0)
|
||||
return posix_error();
|
||||
/* Force the values into long's as we don't know the size of uid_t. */
|
||||
l_ruid = ruid;
|
||||
l_euid = euid;
|
||||
l_suid = suid;
|
||||
return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
|
||||
return Py_BuildValue("(NNN)", _PyInt_FromUid(ruid),
|
||||
_PyInt_FromUid(euid),
|
||||
_PyInt_FromUid(suid));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -8637,14 +8721,11 @@ static PyObject*
|
||||
posix_getresgid (PyObject *self, PyObject *noargs)
|
||||
{
|
||||
uid_t rgid, egid, sgid;
|
||||
long l_rgid, l_egid, l_sgid;
|
||||
if (getresgid(&rgid, &egid, &sgid) < 0)
|
||||
return posix_error();
|
||||
/* Force the values into long's as we don't know the size of uid_t. */
|
||||
l_rgid = rgid;
|
||||
l_egid = egid;
|
||||
l_sgid = sgid;
|
||||
return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
|
||||
return Py_BuildValue("(NNN)", _PyInt_FromGid(rgid),
|
||||
_PyInt_FromGid(egid),
|
||||
_PyInt_FromGid(sgid));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
25
Modules/posixmodule.h
Normal file
25
Modules/posixmodule.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* Declarations shared between the different POSIX-related modules */
|
||||
|
||||
#ifndef Py_POSIXMODULE_H
|
||||
#define Py_POSIXMODULE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifndef MS_WINDOWS
|
||||
PyAPI_FUNC(PyObject *) _PyInt_FromUid(uid_t);
|
||||
PyAPI_FUNC(PyObject *) _PyInt_FromGid(gid_t);
|
||||
PyAPI_FUNC(int) _Py_Uid_Converter(PyObject *, void *);
|
||||
PyAPI_FUNC(int) _Py_Gid_Converter(PyObject *, void *);
|
||||
#endif /* MS_WINDOWS */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_POSIXMODULE_H */
|
@ -3,8 +3,8 @@
|
||||
|
||||
#include "Python.h"
|
||||
#include "structseq.h"
|
||||
#include "posixmodule.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
|
||||
static PyStructSequence_Field struct_pwd_type_fields[] = {
|
||||
@ -73,8 +73,8 @@ mkpwent(struct passwd *p)
|
||||
#else
|
||||
SETS(setIndex++, p->pw_passwd);
|
||||
#endif
|
||||
SETI(setIndex++, p->pw_uid);
|
||||
SETI(setIndex++, p->pw_gid);
|
||||
PyStructSequence_SET_ITEM(v, setIndex++, _PyInt_FromUid(p->pw_uid));
|
||||
PyStructSequence_SET_ITEM(v, setIndex++, _PyInt_FromGid(p->pw_gid));
|
||||
#ifdef __VMS
|
||||
SETS(setIndex++, "");
|
||||
#else
|
||||
@ -103,13 +103,21 @@ See help(pwd) for more on password database entries.");
|
||||
static PyObject *
|
||||
pwd_getpwuid(PyObject *self, PyObject *args)
|
||||
{
|
||||
unsigned int uid;
|
||||
uid_t uid;
|
||||
struct passwd *p;
|
||||
if (!PyArg_ParseTuple(args, "I:getpwuid", &uid))
|
||||
if (!PyArg_ParseTuple(args, "O&:getpwuid", _Py_Uid_Converter, &uid)) {
|
||||
if (PyErr_ExceptionMatches(PyExc_OverflowError))
|
||||
PyErr_Format(PyExc_KeyError,
|
||||
"getpwuid(): uid not found");
|
||||
return NULL;
|
||||
}
|
||||
if ((p = getpwuid(uid)) == NULL) {
|
||||
PyErr_Format(PyExc_KeyError,
|
||||
"getpwuid(): uid not found: %d", uid);
|
||||
if (uid < 0)
|
||||
PyErr_Format(PyExc_KeyError,
|
||||
"getpwuid(): uid not found: %ld", (long)uid);
|
||||
else
|
||||
PyErr_Format(PyExc_KeyError,
|
||||
"getpwuid(): uid not found: %lu", (unsigned long)uid);
|
||||
return NULL;
|
||||
}
|
||||
return mkpwent(p);
|
||||
|
Loading…
Reference in New Issue
Block a user