summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2013-02-12 07:24:16 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2013-02-12 07:24:16 (GMT)
commite4ad8aacd1b10ef14d2a6d44c4c1ebd283ede6bb (patch)
tree20c481fa5c66cc430bf8032668dec776330c630a /Modules
parent008deb7f0409808485fe1338e5b840cf62068a82 (diff)
downloadcpython-e4ad8aacd1b10ef14d2a6d44c4c1ebd283ede6bb.zip
cpython-e4ad8aacd1b10ef14d2a6d44c4c1ebd283ede6bb.tar.gz
cpython-e4ad8aacd1b10ef14d2a6d44c4c1ebd283ede6bb.tar.bz2
Issue #4591: Uid and gid values larger than 2**31 are supported now.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/grpmodule.c17
-rw-r--r--Modules/posixmodule.c313
-rw-r--r--Modules/posixmodule.h25
-rw-r--r--Modules/pwdmodule.c20
4 files changed, 254 insertions, 121 deletions
diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c
index 7dfda28..f85cdd4 100644
--- a/Modules/grpmodule.c
+++ b/Modules/grpmodule.c
@@ -2,8 +2,8 @@
/* UNIX group file access module */
#include "Python.h"
+#include "posixmodule.h"
-#include <sys/types.h>
#include <grp.h>
static PyStructSequence_Field struct_group_type_fields[] = {
@@ -69,7 +69,7 @@ mkgrent(struct group *p)
Py_INCREF(Py_None);
}
#endif
- SET(setIndex++, PyLong_FromLong((long) p->gr_gid));
+ SET(setIndex++, _PyLong_FromGid(p->gr_gid));
SET(setIndex++, w);
#undef SET
@@ -85,17 +85,24 @@ 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_Long(pyo_id);
if (!py_int_id)
return NULL;
- gid = PyLong_AS_LONG(py_int_id);
+ 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);
+ PyObject *gid_obj = _PyLong_FromGid(gid);
+ if (gid_obj == NULL)
+ return NULL;
+ PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj);
+ Py_DECREF(gid_obj);
return NULL;
}
return mkgrent(p);
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 67bff25..34dff11 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -26,6 +26,9 @@
#define PY_SSIZE_T_CLEAN
#include "Python.h"
+#ifndef MS_WINDOWS
+#include "posixmodule.h"
+#endif
#if defined(__VMS)
# include <unixio.h>
@@ -347,6 +350,134 @@ static int win32_can_symlink = 0;
#endif
#endif
+
+#ifndef MS_WINDOWS
+PyObject *
+_PyLong_FromUid(uid_t uid)
+{
+ if (uid == (uid_t)-1)
+ return PyLong_FromLong(-1);
+ return PyLong_FromUnsignedLong(uid);
+}
+
+PyObject *
+_PyLong_FromGid(gid_t gid)
+{
+ if (gid == (gid_t)-1)
+ return PyLong_FromLong(-1);
+ 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.
@@ -1643,8 +1774,13 @@ _pystat_fromstructstat(STRUCT_STAT *st)
PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
#endif
PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
- PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
- PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
+#if defined(MS_WINDOWS)
+ PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
+#else
+ PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
+ PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
+#endif
#ifdef HAVE_LARGEFILE_SUPPORT
PyStructSequence_SET_ITEM(v, 6,
PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
@@ -2173,15 +2309,17 @@ posix_chown(PyObject *self, PyObject *args)
{
PyObject *opath;
char *path;
- long uid, gid;
+ uid_t uid;
+ gid_t gid;
int res;
- if (!PyArg_ParseTuple(args, "O&ll:chown",
+ if (!PyArg_ParseTuple(args, "O&O&O&:chown",
PyUnicode_FSConverter, &opath,
- &uid, &gid))
+ _Py_Uid_Converter, &uid,
+ _Py_Gid_Converter, &gid))
return NULL;
path = PyBytes_AsString(opath);
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(opath);
@@ -2201,12 +2339,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:fchown", &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();
@@ -2225,15 +2366,17 @@ posix_lchown(PyObject *self, PyObject *args)
{
PyObject *opath;
char *path;
- long uid, gid;
+ uid_t uid;
+ gid_t gid;
int res;
- if (!PyArg_ParseTuple(args, "O&ll:lchown",
+ if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
PyUnicode_FSConverter, &opath,
- &uid, &gid))
+ _Py_Uid_Converter, &uid,
+ _Py_Gid_Converter, &gid))
return NULL;
path = PyBytes_AsString(opath);
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(opath);
@@ -4288,7 +4431,7 @@ Return the current process's effective group id.");
static PyObject *
posix_getegid(PyObject *self, PyObject *noargs)
{
- return PyLong_FromLong((long)getegid());
+ return _PyLong_FromGid(getegid());
}
#endif
@@ -4301,7 +4444,7 @@ Return the current process's effective user id.");
static PyObject *
posix_geteuid(PyObject *self, PyObject *noargs)
{
- return PyLong_FromLong((long)geteuid());
+ return _PyLong_FromUid(geteuid());
}
#endif
@@ -4314,7 +4457,7 @@ Return the current process's group id.");
static PyObject *
posix_getgid(PyObject *self, PyObject *noargs)
{
- return PyLong_FromLong((long)getgid());
+ return _PyLong_FromGid(getgid());
}
#endif
@@ -4389,7 +4532,7 @@ posix_getgroups(PyObject *self, PyObject *noargs)
if (result != NULL) {
int i;
for (i = 0; i < n; ++i) {
- PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
+ PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
if (o == NULL) {
Py_DECREF(result);
result = NULL;
@@ -4420,14 +4563,25 @@ posix_initgroups(PyObject *self, PyObject *args)
PyObject *oname;
char *username;
int res;
- long gid;
+#ifdef __APPLE__
+ int gid;
+#else
+ gid_t gid;
+#endif
- if (!PyArg_ParseTuple(args, "O&l:initgroups",
- PyUnicode_FSConverter, &oname, &gid))
+#ifdef __APPLE__
+ if (!PyArg_ParseTuple(args, "O&i:initgroups",
+ PyUnicode_FSConverter, &oname,
+ &gid))
+#else
+ if (!PyArg_ParseTuple(args, "O&O&:initgroups",
+ PyUnicode_FSConverter, &oname,
+ _Py_Gid_Converter, &gid))
+#endif
return NULL;
username = PyBytes_AS_STRING(oname);
- res = initgroups(username, (gid_t) gid);
+ res = initgroups(username, gid);
Py_DECREF(oname);
if (res == -1)
return PyErr_SetFromErrno(PyExc_OSError);
@@ -4602,7 +4756,7 @@ Return the current process's user id.");
static PyObject *
posix_getuid(PyObject *self, PyObject *noargs)
{
- return PyLong_FromLong((long)getuid());
+ return _PyLong_FromUid(getuid());
}
#endif
@@ -4742,15 +4896,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))
- return NULL;
- uid = uid_arg;
- if (uid != uid_arg) {
- PyErr_SetString(PyExc_OverflowError, "user id too big");
+ if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
return NULL;
- }
if (setuid(uid) < 0)
return posix_error();
Py_INCREF(Py_None);
@@ -4767,15 +4915,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 {
@@ -4793,15 +4935,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))
- return NULL;
- egid = egid_arg;
- if (egid != egid_arg) {
- PyErr_SetString(PyExc_OverflowError, "group id too big");
+ if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
return NULL;
- }
if (setegid(egid) < 0) {
return posix_error();
} else {
@@ -4819,23 +4955,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 {
@@ -4853,23 +4977,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 {
@@ -4887,15 +4999,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))
- return NULL;
- gid = gid_arg;
- if (gid != gid_arg) {
- PyErr_SetString(PyExc_OverflowError, "group id too big");
+ if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
return NULL;
- }
if (setgid(gid) < 0)
return posix_error();
Py_INCREF(Py_None);
@@ -4934,18 +5040,7 @@ posix_setgroups(PyObject *self, PyObject *groups)
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 the value to see if it fitted in gid_t */
- if (grouplist[i] != x) {
- PyErr_SetString(PyExc_TypeError,
- "group id too big");
+ if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Py_DECREF(elem);
return NULL;
}
@@ -7694,9 +7789,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();
@@ -7712,9 +7809,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();
@@ -7731,14 +7830,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)", _PyLong_FromUid(ruid),
+ _PyLong_FromUid(euid),
+ _PyLong_FromUid(suid));
}
#endif
@@ -7751,14 +7847,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)", _PyLong_FromGid(rgid),
+ _PyLong_FromGid(egid),
+ _PyLong_FromGid(sgid));
}
#endif
diff --git a/Modules/posixmodule.h b/Modules/posixmodule.h
new file mode 100644
index 0000000..1ec1833
--- /dev/null
+++ b/Modules/posixmodule.h
@@ -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 *) _PyLong_FromUid(uid_t);
+PyAPI_FUNC(PyObject *) _PyLong_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 */
diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c
index 1e0903a..285fd9c 100644
--- a/Modules/pwdmodule.c
+++ b/Modules/pwdmodule.c
@@ -2,8 +2,8 @@
/* UNIX password file access module */
#include "Python.h"
+#include "posixmodule.h"
-#include <sys/types.h>
#include <pwd.h>
static PyStructSequence_Field struct_pwd_type_fields[] = {
@@ -74,8 +74,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++, _PyLong_FromUid(p->pw_uid));
+ PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid));
#ifdef __VMS
SETS(setIndex++, "");
#else
@@ -104,13 +104,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) {
+ PyObject *uid_obj = _PyLong_FromUid(uid);
+ if (uid_obj == NULL)
+ return NULL;
PyErr_Format(PyExc_KeyError,
- "getpwuid(): uid not found: %d", uid);
+ "getpwuid(): uid not found: %S", uid_obj);
+ Py_DECREF(uid_obj);
return NULL;
}
return mkpwent(p);