components/python/python27/patches/06-ucred.patch
changeset 458 2edc011b559e
child 985 57467415833a
child 3367 ed5024e47b53
equal deleted inserted replaced
457:aa27b836c528 458:2edc011b559e
       
     1 diff --git Python-2.6.4/Modules/ucred.c Python-2.6.4/Modules/ucred.c
       
     2 new file mode 100644
       
     3 --- /dev/null
       
     4 +++ Python-2.6.4/Modules/ucred.c
       
     5 @@ -0,0 +1,390 @@
       
     6 +/*
       
     7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     8 + * of this software and associated documentation files (the "Software"), to
       
     9 + * deal in the Software without restriction, including without limitation the
       
    10 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
       
    11 + * sell copies of the Software, and to permit persons to whom the Software is
       
    12 + * furnished to do so, subject to the following conditions:
       
    13 + *
       
    14 + * The above copyright notice and this permission notice shall be included in
       
    15 + * all copies or substantial portions of the Software.
       
    16 + *
       
    17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
       
    20 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       
    21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
       
    22 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
       
    23 + * DEALINGS IN THE SOFTWARE.
       
    24 + *
       
    25 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
       
    26 + */
       
    27 +
       
    28 +#include <Python.h>
       
    29 +
       
    30 +#include <stdio.h>
       
    31 +#include <priv.h>
       
    32 +#include <ucred.h>
       
    33 +#include <ctype.h>
       
    34 +#include <tsol/label.h>
       
    35 +
       
    36 +typedef struct {
       
    37 +	PyObject_HEAD
       
    38 +	ucred_t *ucred;
       
    39 +} pyucred_t;
       
    40 +
       
    41 +#define pyucred_getlongid(name, type)				\
       
    42 +	static PyObject *					\
       
    43 +	pyucred_get##name(pyucred_t *uc)			\
       
    44 +	{ 							\
       
    45 +		type val;					\
       
    46 +								\
       
    47 +		if (uc->ucred == NULL) {			\
       
    48 +			errno = EINVAL;				\
       
    49 +			PyErr_SetFromErrno(PyExc_OSError);	\
       
    50 +			return (NULL);				\
       
    51 +		}						\
       
    52 +								\
       
    53 +		if ((val = ucred_get##name(uc->ucred)) == -1) {	\
       
    54 +			PyErr_SetFromErrno(PyExc_OSError);	\
       
    55 +			return (NULL);				\
       
    56 +		}						\
       
    57 +								\
       
    58 +		return (Py_BuildValue("l", (long)val));		\
       
    59 +	}
       
    60 +
       
    61 +pyucred_getlongid(euid, uid_t)
       
    62 +pyucred_getlongid(ruid, uid_t)
       
    63 +pyucred_getlongid(suid, uid_t)
       
    64 +pyucred_getlongid(egid, gid_t)
       
    65 +pyucred_getlongid(rgid, gid_t)
       
    66 +pyucred_getlongid(sgid, gid_t)
       
    67 +pyucred_getlongid(pid, pid_t)
       
    68 +pyucred_getlongid(projid, projid_t)
       
    69 +pyucred_getlongid(zoneid, zoneid_t)
       
    70 +
       
    71 +static PyObject *
       
    72 +pyucred_getgroups(pyucred_t *uc)
       
    73 +{
       
    74 +	const gid_t *groups;
       
    75 +	PyObject *list;
       
    76 +	int len;
       
    77 +	int i;
       
    78 +
       
    79 +	if (uc->ucred == NULL) {
       
    80 +		errno = EINVAL;
       
    81 +		PyErr_SetFromErrno(PyExc_OSError);
       
    82 +		return (NULL);
       
    83 +	}
       
    84 +
       
    85 +	if ((len = ucred_getgroups(uc->ucred, &groups)) == -1) {
       
    86 +		PyErr_SetFromErrno(PyExc_OSError);
       
    87 +		return (NULL);
       
    88 +	}
       
    89 +
       
    90 +	if ((list = PyList_New(len)) == NULL)
       
    91 +		return (NULL);
       
    92 +
       
    93 +	for (i = 0; i < len; i++) {
       
    94 +		PyObject *gid = Py_BuildValue("l", (long)groups[i]);
       
    95 +		if (PyList_SetItem(list, i, gid) == -1)
       
    96 +			return (NULL);
       
    97 +	}
       
    98 +
       
    99 +	return (list);
       
   100 +}
       
   101 +
       
   102 +static PyObject *
       
   103 +pyucred_getlabel(pyucred_t *uc)
       
   104 +{
       
   105 +	m_label_t *label;
       
   106 +	PyObject *ret;
       
   107 +	char *str;
       
   108 +
       
   109 +	if (uc->ucred == NULL) {
       
   110 +		errno = EINVAL;
       
   111 +		PyErr_SetFromErrno(PyExc_OSError);
       
   112 +		return (NULL);
       
   113 +	}
       
   114 +
       
   115 +	label = ucred_getlabel(uc->ucred);
       
   116 +	if (label == NULL)
       
   117 +		return (Py_BuildValue("s", ""));
       
   118 +
       
   119 +	if (label_to_str(label, &str, M_LABEL, DEF_NAMES) == -1) {
       
   120 +		PyErr_SetFromErrno(PyExc_OSError);
       
   121 +		return (NULL);
       
   122 +	}
       
   123 +
       
   124 +	ret = Py_BuildValue("s", str);
       
   125 +	free(str);
       
   126 +	return (ret);
       
   127 +}
       
   128 +
       
   129 +static PyObject *
       
   130 +pyucred_getpflags(pyucred_t *uc, PyObject *args, PyObject *kwargs)
       
   131 +{
       
   132 +	static char *kwlist[] = { "flags", NULL };
       
   133 +	uint_t flags;
       
   134 +
       
   135 +	if (uc->ucred == NULL) {
       
   136 +		errno = EINVAL;
       
   137 +		PyErr_SetFromErrno(PyExc_OSError);
       
   138 +		return (NULL);
       
   139 +	}
       
   140 +
       
   141 +	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist,
       
   142 +	    &flags))
       
   143 +		return (NULL);
       
   144 +
       
   145 +	if ((flags = ucred_getpflags(uc->ucred, flags)) == (uint_t)-1) {
       
   146 +		PyErr_SetFromErrno(PyExc_OSError);
       
   147 +		return (NULL);
       
   148 +	}
       
   149 +
       
   150 +	return (Py_BuildValue("i", flags));
       
   151 +}
       
   152 +
       
   153 +static PyObject *
       
   154 +pyucred_has_priv(pyucred_t *uc, PyObject *args, PyObject *kwargs)
       
   155 +{
       
   156 +	static char *kwlist[] = { "set", "priv", NULL };
       
   157 +	const priv_set_t *privs;
       
   158 +	const char *set;
       
   159 +	const char *priv;
       
   160 +
       
   161 +	if (uc->ucred == NULL) {
       
   162 +		errno = EINVAL;
       
   163 +		PyErr_SetFromErrno(PyExc_OSError);
       
   164 +		return (NULL);
       
   165 +	}
       
   166 +
       
   167 +	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist,
       
   168 +	    &set, &priv))
       
   169 +		return (NULL);
       
   170 +
       
   171 +	if ((privs = ucred_getprivset(uc->ucred, set)) == NULL) {
       
   172 +		PyErr_SetFromErrno(PyExc_OSError);
       
   173 +		return (NULL);
       
   174 +	}
       
   175 +
       
   176 +	if (priv_ismember(privs, priv)) {
       
   177 +		Py_INCREF(Py_True);
       
   178 +		return Py_True;
       
   179 +	}
       
   180 +
       
   181 +	Py_INCREF(Py_False);
       
   182 +	return Py_False;
       
   183 +}
       
   184 +
       
   185 +PyDoc_STRVAR(pyucred_getlabel_doc,
       
   186 +    "getlabel() -> string\n"
       
   187 +    "\n"
       
   188 +    "Return the Trusted Extensions label string, or an "
       
   189 +    "empty string if not available. The label string is "
       
   190 +    "converted using the default name and M_LABEL (human-readable). "
       
   191 +    "Raises OSError. See label_to_str(3TSOL).");
       
   192 +PyDoc_STRVAR(pyucred_getpflags_doc,
       
   193 +    "getpflags(flags) -> int\n"
       
   194 +    "\n"
       
   195 +    "Return the values of the specified privilege flags.");
       
   196 +PyDoc_STRVAR(pyucred_has_priv_doc,
       
   197 +    "has_priv(set, priv) -> bool\n"
       
   198 +    "\n"
       
   199 +    "Return true if the given privilege is set in the "
       
   200 +    "specified set. Raises OSError if the set or privilege is "
       
   201 +    "invalid, or a problem occurs.\n"
       
   202 +    "\n"
       
   203 +    "Currently, the following privilege sets are defined, as "
       
   204 +    "described in privileges(5):\n"
       
   205 +    "\n"
       
   206 +    "Effective\n"
       
   207 +    "Permitted\n"
       
   208 +    "Inheritable\n"
       
   209 +    "Limit\n");
       
   210 +
       
   211 +static PyMethodDef pyucred_methods[] = {
       
   212 +	{ "geteuid", (PyCFunction)pyucred_geteuid, METH_NOARGS,
       
   213 +	    "Return the effective user ID." },
       
   214 +	{ "getruid", (PyCFunction)pyucred_getruid, METH_NOARGS,
       
   215 +	    "Return the real user ID." },
       
   216 +	{ "getsuid", (PyCFunction)pyucred_getsuid, METH_NOARGS,
       
   217 +	    "Return the saved user ID." },
       
   218 +	{ "getegid", (PyCFunction)pyucred_getegid, METH_NOARGS,
       
   219 +	    "Return the effective group ID." },
       
   220 +	{ "getrgid", (PyCFunction)pyucred_getrgid, METH_NOARGS,
       
   221 +	    "Return the real group ID." },
       
   222 +	{ "getsgid", (PyCFunction)pyucred_getsgid, METH_NOARGS,
       
   223 +	    "Return the saved group ID." },
       
   224 +	{ "getpid", (PyCFunction)pyucred_getpid, METH_NOARGS,
       
   225 +	    "Return the effective user ID." },
       
   226 +	{ "getprojid", (PyCFunction)pyucred_getprojid, METH_NOARGS,
       
   227 +	    "Return the project ID." },
       
   228 +	{ "getzoneid", (PyCFunction)pyucred_getzoneid, METH_NOARGS,
       
   229 +	    "Return the zone ID." },
       
   230 +	{ "getgroups", (PyCFunction)pyucred_getgroups, METH_NOARGS,
       
   231 +	    "Return a list of group IDs." },
       
   232 +	{ "getlabel", (PyCFunction)pyucred_getlabel, METH_NOARGS,
       
   233 +	    pyucred_getlabel_doc },
       
   234 +	{ "getpflags", (PyCFunction)pyucred_getpflags,
       
   235 +	    METH_VARARGS|METH_KEYWORDS, pyucred_getpflags_doc },
       
   236 +	{ "has_priv", (PyCFunction)pyucred_has_priv,
       
   237 +	    METH_VARARGS|METH_KEYWORDS, pyucred_has_priv_doc },
       
   238 +	{ NULL }
       
   239 +};
       
   240 +
       
   241 +static int
       
   242 +pyucred_init(PyObject *self, PyObject *args, PyObject *kwargs)
       
   243 +{
       
   244 +	pyucred_t *uc = (pyucred_t *)self;
       
   245 +	uc->ucred = NULL;
       
   246 +	return (0);
       
   247 +}
       
   248 +
       
   249 +static void
       
   250 +pyucred_dealloc(PyObject *self)
       
   251 +{
       
   252 +	pyucred_t *uc = (pyucred_t *)self;
       
   253 +	if (uc->ucred != NULL)
       
   254 +		ucred_free(uc->ucred);
       
   255 +	self->ob_type->tp_free(self);
       
   256 +}
       
   257 +
       
   258 +static PyTypeObject pyucred_type = {
       
   259 +	PyObject_HEAD_INIT(NULL)
       
   260 +	0,                         /*ob_size*/
       
   261 +	"ucred.ucred",             /*tp_name*/
       
   262 +	sizeof (pyucred_t),        /*tp_basicsize*/
       
   263 +	0,                         /*tp_itemsize*/
       
   264 +	pyucred_dealloc,           /*tp_dealloc*/
       
   265 +	0,                         /*tp_print*/
       
   266 +	0,                         /*tp_getattr*/
       
   267 +	0,                         /*tp_setattr*/
       
   268 +	0,                         /*tp_compare*/
       
   269 +	0,                         /*tp_repr*/
       
   270 +	0,                         /*tp_as_number*/
       
   271 +	0,                         /*tp_as_sequence*/
       
   272 +	0,                         /*tp_as_mapping*/
       
   273 +	0,                         /*tp_hash */
       
   274 +	0,                         /*tp_call*/
       
   275 +	0,                         /*tp_str*/
       
   276 +	0,                         /*tp_getattro*/
       
   277 +	0,                         /*tp_setattro*/
       
   278 +	0,                         /*tp_as_buffer*/
       
   279 +	Py_TPFLAGS_DEFAULT,        /*tp_flags*/
       
   280 +	"user credentials",        /*tp_doc */
       
   281 +	0,		           /* tp_traverse */
       
   282 +	0,		           /* tp_clear */
       
   283 +	0,		           /* tp_richcompare */
       
   284 +	0,		           /* tp_weaklistoffset */
       
   285 +	0,		           /* tp_iter */
       
   286 +	0,		           /* tp_iternext */
       
   287 +	pyucred_methods,           /* tp_methods */
       
   288 +	0,                         /* tp_members */
       
   289 +	0,                         /* tp_getset */
       
   290 +	0,                         /* tp_base */
       
   291 +	0,                         /* tp_dict */
       
   292 +	0,                         /* tp_descr_get */
       
   293 +	0,                         /* tp_descr_set */
       
   294 +	0,                         /* tp_dictoffset */
       
   295 +	(initproc)pyucred_init,    /* tp_init */
       
   296 +	0,                         /* tp_alloc */
       
   297 +	0,                         /* tp_new */
       
   298 +};
       
   299 +
       
   300 +static PyObject *
       
   301 +pyucred_new(const ucred_t *uc)
       
   302 +{
       
   303 +	pyucred_t *self;
       
   304 +
       
   305 +	self = (pyucred_t *)PyObject_CallObject((PyObject *)&pyucred_type, NULL);
       
   306 +
       
   307 +	if (self == NULL)
       
   308 +		return (NULL);
       
   309 +
       
   310 +	self->ucred = (ucred_t *)uc;
       
   311 +
       
   312 +	return ((PyObject *)self);
       
   313 +}
       
   314 +
       
   315 +static PyObject *
       
   316 +pyucred_get(PyObject *o, PyObject *args, PyObject *kwargs)
       
   317 +{
       
   318 +	static char *kwlist[] = { "pid", NULL };
       
   319 +	ucred_t *ucred = NULL;
       
   320 +	int pid;
       
   321 +
       
   322 +	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist,
       
   323 +	    &pid))
       
   324 +		return (NULL);
       
   325 +
       
   326 +	ucred = ucred_get(pid);
       
   327 +
       
   328 +	if (ucred == NULL) {
       
   329 +		PyErr_SetFromErrno(PyExc_OSError);
       
   330 +		return (NULL);
       
   331 +	}
       
   332 +
       
   333 +	return (pyucred_new(ucred));
       
   334 +}
       
   335 +
       
   336 +static PyObject *
       
   337 +pyucred_getpeer(PyObject *o, PyObject *args, PyObject *kwargs)
       
   338 +{
       
   339 +	static char *kwlist[] = { "fd", NULL };
       
   340 +	ucred_t *ucred = NULL;
       
   341 +	int fd;
       
   342 +
       
   343 +	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist,
       
   344 +	    &fd))
       
   345 +		return (NULL);
       
   346 +
       
   347 +	if (getpeerucred(fd, &ucred) == -1) {
       
   348 +		PyErr_SetFromErrno(PyExc_OSError);
       
   349 +		return (NULL);
       
   350 +	}
       
   351 +
       
   352 +	return (pyucred_new(ucred));
       
   353 +}
       
   354 +
       
   355 +PyDoc_STRVAR(pyucred_get_doc,
       
   356 +    "get(pid) -> ucred\n"
       
   357 +    "\n"
       
   358 +    "Return the credentials of the specified process ID. "
       
   359 +    "Raises OSError. See ucred_get(3C).");
       
   360 +PyDoc_STRVAR(pyucred_getpeer_doc,
       
   361 +    "getpeer(fd) -> ucred\n"
       
   362 +    "\n"
       
   363 +    "Return the credentials of the peer endpoint of a "
       
   364 +    "connection-oriented socket (SOCK_STREAM) or STREAM fd "
       
   365 +    "at the time the endpoint was created or the connection "
       
   366 +    "was established. Raises OSError. See getpeerucred(3C).");
       
   367 +
       
   368 +static struct PyMethodDef pyucred_module_methods[] = {
       
   369 +	{ "get", (PyCFunction) pyucred_get,
       
   370 +	  METH_VARARGS|METH_KEYWORDS, pyucred_get_doc },
       
   371 +	{ "getpeer", (PyCFunction) pyucred_getpeer,
       
   372 +	  METH_VARARGS|METH_KEYWORDS, pyucred_getpeer_doc },
       
   373 +	{ NULL, NULL, 0, NULL }
       
   374 +};
       
   375 +
       
   376 +PyDoc_STRVAR(pyucred_module_doc,
       
   377 +    "This module provides an interface to the user credential access "
       
   378 +    "methods, obtainable either by process ID or file descriptor.");
       
   379 +   
       
   380 +PyMODINIT_FUNC
       
   381 +initucred(void)
       
   382 +{
       
   383 +	PyObject *m;
       
   384 +
       
   385 +	m = Py_InitModule3("ucred", pyucred_module_methods,
       
   386 +	    pyucred_module_doc);
       
   387 +
       
   388 +	pyucred_type.tp_new = PyType_GenericNew;
       
   389 +	if (PyType_Ready(&pyucred_type) < 0)
       
   390 +		return;
       
   391 +
       
   392 +	Py_INCREF(&pyucred_type);
       
   393 +
       
   394 +	PyModule_AddObject(m, "ucred", (PyObject *)&pyucred_type);
       
   395 +}
       
   396 diff --git Python-2.6.4/setup.py Python-2.6.4/setup.py
       
   397 --- Python-2.6.4/setup.py
       
   398 +++ Python-2.6.4/setup.py
       
   399 @@ -1277,6 +1277,13 @@
       
   400          else:
       
   401              missing.append('dl')
       
   402  
       
   403 +        # ucred module (Solaris)
       
   404 +        ucred_inc = find_file('ucred.h', [], inc_dirs)
       
   405 +        tsol_inc = find_file('tsol/label.h', [], inc_dirs)
       
   406 +        if ucred_inc is not None and tsol_inc is not None:
       
   407 +            exts.append( Extension('ucred', ['ucred.c'],
       
   408 +                                   libraries = ['tsol']) )
       
   409 +
       
   410          # Thomas Heller's _ctypes module
       
   411          self.detect_ctypes(inc_dirs, lib_dirs)
       
   412  
       
   413 diff --git Python-2.6.4/Lib/test/ucredtext.py Python-2.6.4/Lib/test/ucredtext.py
       
   414 new file mode 100644
       
   415 --- /dev/null	2011-02-12 03:14:16.000000000 -0600
       
   416 +++ Python-2.6.4/Lib/test/ucredtest.py	2011-01-20 13:52:42.945657919 -0600
       
   417 @@ -0,0 +1,45 @@
       
   418 +#!/usr/bin/python2.6
       
   419 +
       
   420 +import ucred
       
   421 +import os
       
   422 +
       
   423 +uc = ucred.get(os.getpid())
       
   424 +
       
   425 +print "pid = %d" % uc.getpid()
       
   426 +print "euid = %d" % uc.geteuid()
       
   427 +print "ruid = %d" % uc.getruid()
       
   428 +print "suid = %d" % uc.getsuid()
       
   429 +print "egid = %d" % uc.getegid()
       
   430 +print "rgid = %d" % uc.getrgid()
       
   431 +print "sgid = %d" % uc.getsgid()
       
   432 +print "zoneid = %d" % uc.getzoneid()
       
   433 +print "projid = %d" % uc.getprojid()
       
   434 +print "groups = %s" % uc.getgroups()
       
   435 +print "label = %s" % uc.getlabel()
       
   436 +
       
   437 +print "getpflags(0x1) = %d" % uc.getpflags(0x1)
       
   438 +print "getpflags(0x2) = %d" % uc.getpflags(0x2)
       
   439 +print "has_priv(Effective, proc_fork) = %d" % uc.has_priv("Effective", "proc_fork")
       
   440 +print "has_priv(Permitted, proc_fork) = %d" % uc.has_priv("Permitted", "proc_fork")
       
   441 +print "has_priv(Inheritable, proc_fork) = %d" % uc.has_priv("Inheritable", "proc_fork")
       
   442 +print "has_priv(Limit, file_setid) = %d" % uc.has_priv("Limit", "file_setid")
       
   443 +print "has_priv(Effective, file_setid) = %d" % uc.has_priv("Effective", "file_setid")
       
   444 +try:
       
   445 +    uc.has_priv("Effective", "proc_bork")
       
   446 +except OSError, e:
       
   447 +    print e
       
   448 +try:
       
   449 +    uc.has_priv("Defective", "proc_fork")
       
   450 +except OSError, e:
       
   451 +    print e
       
   452 +try:
       
   453 +    uc.has_priv("Defective", "proc_bork")
       
   454 +except OSError, e:
       
   455 +    print e
       
   456 +
       
   457 +del uc
       
   458 +uc = ucred.ucred()
       
   459 +try:
       
   460 +    uc.getpid()
       
   461 +except OSError, e:
       
   462 +    print e