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