1 diff --git Python-2.6.4/Modules/authattr.c Python-2.6.4/Modules/authattr.c
   2 new file mode 100644
   3 --- /dev/null
   4 +++ Python-2.6.4/Modules/authattr.c
   5 @@ -0,0 +1,262 @@
   6 +/*
   7 + * CDDL HEADER START
   8 + *
   9 + * The contents of this file are subject to the terms of the
  10 + * Common Development and Distribution License (the "License").
  11 + * You may not use this file except in compliance with the License.
  12 + *
  13 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  14 + * or http://www.opensolaris.org/os/licensing.
  15 + * See the License for the specific language governing permissions
  16 + * and limitations under the License.
  17 + *
  18 + * When distributing Covered Code, include this CDDL HEADER in each
  19 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  20 + * If applicable, add the following below this CDDL HEADER, with the
  21 + * fields enclosed by brackets "[]" replaced with your own identifying
  22 + * information: Portions Copyright [yyyy] [name of copyright owner]
  23 + *
  24 + * CDDL HEADER END
  25 + */
  26 +
  27 +/*
  28 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  29 + * Use is subject to license terms.
  30 + */
  31 +
  32 +/*
  33 + * RBAC Bindings for Python - auth_attr functions
  34 + */
  35 +
  36 +#include <auth_attr.h>
  37 +#include "Python.h"
  38 +#include "pyrbac.h"
  39 +
  40 +static PyObject*
  41 +pyrbac_setauthattr(PyObject* self, PyObject* args) {
  42 +       setauthattr();
  43 +       return Py_None;
  44 +}
  45 +
  46 +static PyObject*
  47 +pyrbac_endauthattr(PyObject* self, PyObject* args) {
  48 +       endauthattr();
  49 +       return Py_None;
  50 +}
  51 +
  52 +PyObject*
  53 +pyrbac_getauthnamattr(PyObject* self, char* authname, int mode) {
  54 +       
  55 +
  56 +       
  57 +       authattr_t * ret_authattr = (mode == PYRBAC_NAM_MODE) ? getauthnam(authname) : getauthattr();
  58 +       if (ret_authattr == NULL)
  59 +               return Py_None;
  60 +               
  61 +       PyObject* kv_data = PyDict_New();
  62 +       if (kv_data == NULL) {
  63 +               free_authattr(ret_authattr);
  64 +               return NULL;
  65 +       }
  66 +
  67 +       if(ret_authattr->attr != NULL) {
  68 +               int len;
  69 +               for(len = 0; len < ret_authattr->attr->length; len++) {
  70 +                       kv_t current = ret_authattr->attr->data[len];
  71 +
  72 +                       PyObject* set = PyList_New(NULL);
  73 +                       char* saveptr;
  74 +                       char* item = strtok_r(current.value, ",", &saveptr);
  75 +                       PyList_Append(set, PyString_FromString(item));
  76 +
  77 +                       while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
  78 +                               if(PyList_Append(set, PyString_FromString(item)) != 0) {
  79 +                                       Py_XDECREF(set);
  80 +                                       Py_XDECREF(kv_data);
  81 +                                       free_authattr(ret_authattr);
  82 +                                       return NULL;
  83 +                               }
  84 +                       }
  85 +                       if(PyDict_SetItemString(kv_data, current.key, set)) {
  86 +                                       free_authattr(ret_authattr);
  87 +                                       return NULL;
  88 +                       }
  89 +               }
  90 +       }
  91 +       PyObject * retval = Py_BuildValue("{s:s,s:s,s:s,s:s,s:s,s:O}",
  92 +               "name",ret_authattr->name,
  93 +               "res1",ret_authattr->res1,
  94 +               "res2",ret_authattr->res2,
  95 +               "short",ret_authattr->short_desc,
  96 +               "long",ret_authattr->long_desc,
  97 +               "attributes",kv_data);
  98 +
  99 +       free_authattr(ret_authattr);
 100 +       return retval;
 101 +
 102 +}
 103 +
 104 +static PyObject*
 105 +pyrbac_getauthattr(PyObject* self, PyObject* args) {
 106 +       return(pyrbac_getauthnamattr(self, NULL, PYRBAC_ATTR_MODE));
 107 +}
 108 +
 109 +static PyObject*
 110 +pyrbac_getauthnam(PyObject* self, PyObject* args) {
 111 +       char* name = NULL;
 112 +       if(!PyArg_ParseTuple(args, "s:getauthnam", &name))
 113 +               return NULL;
 114 +       return(pyrbac_getauthnamattr(self, name, PYRBAC_NAM_MODE));
 115 +}
 116 +
 117 +static PyObject *
 118 +pyrbac_chkauthattr(PyObject* self, PyObject* args) {
 119 +       char* authstring = NULL;
 120 +       char* username = NULL;
 121 +       if(!PyArg_ParseTuple(args, "ss:chkauthattr", &authstring, &username))
 122 +               return NULL;
 123 +       return PyBool_FromLong((long)chkauthattr(authstring, username));
 124 +}
 125 +
 126 +static PyObject*
 127 +pyrbac_authattr_next(PyObject* self, PyObject* args) {
 128 +       PyObject* retval = pyrbac_getauthattr(self, args);
 129 +       if( retval == Py_None ) {
 130 +               setauthattr();
 131 +               return NULL;
 132 +       }
 133 +       return retval;
 134 +}
 135 +static PyObject*
 136 +pyrbac_authattr__iter__(PyObject* self, PyObject* args) {
 137 +       return self;
 138 +}
 139 +
 140 +typedef struct {
 141 +       PyObject_HEAD
 142 +} Authattr;
 143 +
 144 +static void
 145 +Authattr_dealloc(Authattr* self) {
 146 +       endauthattr();
 147 +       self->ob_type->tp_free((PyObject*) self);
 148 +}
 149 +
 150 +static PyObject*
 151 +Authattr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
 152 +       Authattr *self;
 153 +       self = (Authattr*)type->tp_alloc(type, 0);
 154 +
 155 +       return ((PyObject *) self);
 156 +}
 157 +
 158 +static int
 159 +Authattr_init(Authattr* self, PyObject *args, PyObject *kwargs) {
 160 +       setauthattr();
 161 +       return 0;
 162 +}
 163 +
 164 +static char pyrbac_authattr__doc__[];
 165 +
 166 +PyDoc_STRVAR(pyrbac_authattr__doc__, """provides interfaces to the auth_attr \
 167 +database. may be iterated over to return all auth_attr entries\n\n\
 168 +Methods provided:\n\
 169 +setauthattr\n\
 170 +endauthattr\n\
 171 +getauthattr\n\
 172 +chkauthattr\n\
 173 +getauthnam""");
 174 +
 175 +static char pyrbac_setauthattr__doc__[];
 176 +static char pyrbac_endauthattr__doc__[];
 177 +static char pyrbac_getauthattr__doc__[];
 178 +static char pyrbac_chkauthattr__doc__[];
 179 +
 180 +PyDoc_STRVAR(pyrbac_setauthattr__doc__, 
 181 +"\"rewinds\" the auth_attr functions to the first entry in the db. Called \
 182 +automatically by the constructor\n\tArguments: None\n\tReturns: None");
 183 +
 184 +PyDoc_STRVAR(pyrbac_endauthattr__doc__, 
 185 +"closes the auth_attr database, cleans up storage. called automatically by \
 186 +the destructor\n\tArguments: None\n\tReturns: None");
 187 +
 188 +PyDoc_STRVAR(pyrbac_chkauthattr__doc__, "verifies if a user has a given \
 189 +authorization.\n\tArguments: 2 Python strings, 'authname' and 'username'\n\
 190 +\tReturns: True if the user is authorized, False otherwise");
 191 +
 192 +PyDoc_STRVAR(pyrbac_getauthattr__doc__, 
 193 +"return one entry from the auth_attr database\n\
 194 +\tArguments: None\n\
 195 +\tReturns: a dict representing the authattr_t struct:\n\
 196 +\t\t\"name\": Authorization Name\n\
 197 +\t\t\"res1\": reserved\n\
 198 +\t\t\"res2\": reserved\n\
 199 +\t\t\"short\": Short Description\n\
 200 +\t\t\"long\": Long Description\n\
 201 +\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
 202 +or a string depending on value");
 203 +
 204 +PyDoc_STRVAR(pyrbac_getauthnam__doc__, 
 205 +"searches the auth_attr database for a given authorization name\n\
 206 +\tArguments: a Python string containing the auth name\n\
 207 +\tReturns: a dict representing the authattr_t struct:\n\
 208 +\t\t\"name\": Authorization Name\n\
 209 +\t\t\"res1\": reserved\n\
 210 +\t\t\"res2\": reserved\n\
 211 +\t\t\"short\": Short Description\n\
 212 +\t\t\"long\": Long Description\n\
 213 +\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
 214 +or a string depending on value");
 215 +
 216 +static PyMethodDef Authattr_methods[] = {
 217 +       {"setauthattr", pyrbac_setauthattr, METH_NOARGS, pyrbac_setauthattr__doc__},
 218 +       {"endauthattr", pyrbac_endauthattr, METH_NOARGS, pyrbac_endauthattr__doc__},
 219 +       {"chkauthattr", pyrbac_chkauthattr, METH_VARARGS, pyrbac_chkauthattr__doc__},
 220 +       {"getauthattr", pyrbac_getauthattr, METH_NOARGS, pyrbac_getauthattr__doc__},
 221 +       {"getauthnam", pyrbac_getauthnam, METH_VARARGS, pyrbac_getauthnam__doc__},
 222 +       {NULL}
 223 +};
 224 +
 225 +PyTypeObject AuthattrType = {
 226 +       PyObject_HEAD_INIT(NULL)
 227 +       0,                         /*ob_size*/
 228 +       "rbac.authattr",             /*tp_name*/
 229 +       sizeof(Authattr),             /*tp_basicsize*/
 230 +       0,                         /*tp_itemsize*/
 231 +       (destructor)Authattr_dealloc, /*tp_dealloc*/
 232 +       0,                         /*tp_print*/
 233 +       0,                         /*tp_getattr*/
 234 +       0,                         /*tp_setattr*/
 235 +       0,                         /*tp_compare*/
 236 +       0,                         /*tp_repr*/
 237 +       0,                         /*tp_as_number*/
 238 +       0,                         /*tp_as_sequence*/
 239 +       0,                         /*tp_as_mapping*/
 240 +       0,                         /*tp_hash */
 241 +       0,                         /*tp_call*/
 242 +       0,                         /*tp_str*/
 243 +       0,                         /*tp_getattro*/
 244 +       0,                         /*tp_setattro*/
 245 +       0,                         /*tp_as_buffer*/
 246 +       Py_TPFLAGS_DEFAULT |
 247 +       Py_TPFLAGS_BASETYPE |
 248 +       Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
 249 +       pyrbac_authattr__doc__,           /* tp_doc */
 250 +       0,                             /* tp_traverse */
 251 +       0,                             /* tp_clear */
 252 +       0,                             /* tp_richcompare */
 253 +       0,                             /* tp_weaklistoffset */
 254 +       pyrbac_authattr__iter__,                               /* tp_iter */
 255 +       pyrbac_authattr_next,         /* tp_iternext */
 256 +       Authattr_methods,             /* tp_methods */
 257 +       0,             /* tp_members */
 258 +       0,                         /* tp_getset */
 259 +       0,                         /* tp_base */
 260 +       0,                         /* tp_dict */
 261 +       0,                         /* tp_descr_get */
 262 +       0,                         /* tp_descr_set */
 263 +       0,                         /* tp_dictoffset */
 264 +       (initproc)Authattr_init,      /* tp_init */
 265 +       0,                         /* tp_alloc */
 266 +       Authattr_new,                 /* tp_new */
 267 +};
 268 diff --git Python-2.6.4/Modules/execattr.c Python-2.6.4/Modules/execattr.c
 269 new file mode 100644
 270 --- /dev/null
 271 +++ Python-2.6.4/Modules/execattr.c
 272 @@ -0,0 +1,314 @@
 273 +/*
 274 + * CDDL HEADER START
 275 + *
 276 + * The contents of this file are subject to the terms of the
 277 + * Common Development and Distribution License (the "License").
 278 + * You may not use this file except in compliance with the License.
 279 + *
 280 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 281 + * or http://www.opensolaris.org/os/licensing.
 282 + * See the License for the specific language governing permissions
 283 + * and limitations under the License.
 284 + *
 285 + * When distributing Covered Code, include this CDDL HEADER in each
 286 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 287 + * If applicable, add the following below this CDDL HEADER, with the
 288 + * fields enclosed by brackets "[]" replaced with your own identifying
 289 + * information: Portions Copyright [yyyy] [name of copyright owner]
 290 + *
 291 + * CDDL HEADER END
 292 + */
 293 +
 294 +/*
 295 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 296 + * Use is subject to license terms.
 297 + */
 298 +
 299 +/*
 300 + * RBAC Bindings for Python - exec_attr functions
 301 + */
 302 +
 303 +#include <exec_attr.h>
 304 +#include "Python.h"
 305 +#include "pyrbac.h"
 306 +
 307 +static PyObject *
 308 +pyrbac_setexecattr(PyObject* self, PyObject* args) {
 309 +       setexecattr();
 310 +       return Py_None;
 311 +}
 312 +
 313 +static PyObject *
 314 +pyrbac_endexecattr(PyObject* self, PyObject* args) {
 315 +       endexecattr();
 316 +       return Py_None;
 317 +}
 318 +
 319 +PyObject *
 320 +pyrbac_getexecuserprofattr(PyObject* self, char* userprofname, char* type, char* id, int mode) {
 321 +
 322 +       PyObject* ep_data = (mode == PYRBAC_ATTR_MODE) ? NULL : PyList_New(0);
 323 +       
 324 +       if (ep_data == NULL && mode != PYRBAC_ATTR_MODE )
 325 +               return NULL;
 326 +       
 327 +       execattr_t *execprof;
 328 +       if (mode == PYRBAC_USER_MODE)
 329 +               execprof = getexecuser(userprofname, type, id, GET_ALL);
 330 +       else if (mode == PYRBAC_PROF_MODE)
 331 +               execprof = getexecprof(userprofname, type, id, GET_ALL);
 332 +       else if (mode == PYRBAC_ATTR_MODE)
 333 +               execprof = getexecattr();
 334 +       else
 335 +               return NULL;
 336 +
 337 +       if (execprof == NULL)
 338 +               return Py_None;
 339 +       
 340 +       execattr_t *execprof_head = execprof;
 341 +
 342 +       while(execprof != NULL) {
 343 +               
 344 +               PyObject* kv_data = PyDict_New();
 345 +
 346 +               if(execprof->attr != NULL) {
 347 +                       int len;
 348 +                       for(len = 0; len < execprof->attr->length; len++) {
 349 +                               kv_t current = execprof->attr->data[len];
 350 +
 351 +                               PyObject* set = PyList_New(NULL);
 352 +                               char* saveptr;
 353 +                               char* item = strtok_r(current.value, ",", &saveptr);
 354 +                               PyList_Append(set, PyString_FromString(item));
 355 +
 356 +                               while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
 357 +                                       if(PyList_Append(set, PyString_FromString(item)) != 0) {
 358 +                                               Py_XDECREF(set);
 359 +                                               Py_XDECREF(kv_data);
 360 +                                               free_execattr(execprof_head);
 361 +                                               return NULL;
 362 +                                       }
 363 +                               }
 364 +                               if(PyDict_SetItemString(kv_data, current.key, set)) {
 365 +                                               free_execattr(execprof_head);
 366 +                                               return NULL;
 367 +                               }
 368 +                       }
 369 +               }
 370 +               PyObject* entry = Py_BuildValue("{s:s,s:s,s:s,s:s,s:s,s:s,s:O}",
 371 +                       "name", execprof->name,
 372 +                       "type", execprof->type,
 373 +                       "policy", execprof->policy,
 374 +                       "res1", execprof->res1,
 375 +                       "res2", execprof->res2,
 376 +                       "id", execprof->id,
 377 +                       "attributes", kv_data);
 378 +               
 379 +               if (entry == NULL) {
 380 +                       Py_XDECREF(kv_data);
 381 +                       free_execattr(execprof_head);
 382 +                       return NULL;
 383 +               }
 384 +               
 385 +               if (mode == PYRBAC_ATTR_MODE) {
 386 +                       free_execattr(execprof_head);
 387 +                       return(entry);
 388 +               }
 389 +               PyList_Append(ep_data, entry);
 390 +               execprof = execprof->next;
 391 +       }
 392 +
 393 +       free_execattr(execprof_head);
 394 +       return(ep_data);
 395 + 
 396 +}
 397 +
 398 +static PyObject *
 399 +pyrbac_getexecuser(PyObject* self, PyObject* args) {
 400 +       char* username = NULL;
 401 +       char* type = NULL;
 402 +       char* id = NULL;
 403 +       
 404 +       if(!PyArg_ParseTuple(args, "sss:getexecuser", &username, &type, &id))
 405 +               return NULL;
 406 +
 407 +       return (pyrbac_getexecuserprofattr(self, username, type, id, PYRBAC_USER_MODE));
 408 +}
 409 +
 410 +static PyObject *
 411 +pyrbac_getexecprof(PyObject* self, PyObject* args) {
 412 +
 413 +       char* profname = NULL;
 414 +       char* type = NULL;
 415 +       char* id = NULL;
 416 +       
 417 +       if(!PyArg_ParseTuple(args, "sss:getexecprof", &profname, &type, &id))
 418 +               return NULL;
 419 +
 420 +       return (pyrbac_getexecuserprofattr(self, profname, type, id, PYRBAC_PROF_MODE));
 421 +}
 422 +
 423 +static PyObject*
 424 +pyrbac_getexecattr(PyObject* self, PyObject* args) {
 425 +       return pyrbac_getexecuserprofattr(self, NULL, NULL, NULL, PYRBAC_ATTR_MODE);
 426 +}
 427 +
 428 +static PyObject*
 429 +pyrbac_execattr_next(PyObject* self, PyObject* args) {
 430 +       PyObject* retval = pyrbac_getexecattr(self, args);
 431 +       if( retval == Py_None ) {
 432 +               setexecattr();
 433 +               return NULL;
 434 +       }
 435 +       return retval;
 436 +}
 437 +static PyObject*
 438 +pyrbac_execattr__iter__(PyObject* self, PyObject* args) {
 439 +       return self;
 440 +}
 441 +
 442 +typedef struct {
 443 +       PyObject_HEAD
 444 +} Execattr;
 445 +
 446 +static void
 447 +Execattr_dealloc(Execattr* self) {
 448 +       endexecattr();
 449 +       self->ob_type->tp_free((PyObject*) self);
 450 +}
 451 +
 452 +static PyObject*
 453 +Execattr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
 454 +       Execattr *self;
 455 +       self = (Execattr*)type->tp_alloc(type, 0);
 456 +
 457 +       return ((PyObject *) self);
 458 +}
 459 +
 460 +static int
 461 +Execattr_init(Execattr* self, PyObject *args, PyObject *kwargs) {
 462 +       setexecattr();
 463 +       return 0;
 464 +}
 465 +
 466 +static char pyrbac_execattr__doc__[];
 467 +
 468 +PyDoc_STRVAR(pyrbac_execattr__doc__, "provides functions for \
 469 +interacting with the execution profiles database. May be iterated over to \
 470 +enumerate exec_attr(4) entries\n\n\
 471 +Methods provided:\n\
 472 +setexecattr\n\
 473 +endexecattr\n\
 474 +getexecattr\n\
 475 +getexecprof\n\
 476 +getexecuser");
 477 +
 478 +
 479 +static char pyrbac_getexecuser__doc__[];
 480 +static char pyrbac_getexecprof__doc__[];
 481 +static char pyrbac_getexecattr__doc__[];
 482 +static char pyrbac_setexecattr__doc__[];
 483 +static char pyrbac_endexecattr__doc__[];
 484 +
 485 +PyDoc_STRVAR(pyrbac_setexecattr__doc__,
 486 +"\"rewinds\" the exec_attr functions to the first entry in the db. Called \
 487 +automatically by the constructor.\n\
 488 +\tArguments: None\
 489 +\tReturns: None");
 490 +
 491 +PyDoc_STRVAR(pyrbac_endexecattr__doc__, 
 492 +"closes the exec_attr database, cleans up storage. called automatically by \
 493 +the destructor.\n\
 494 +\tArguments: None\
 495 +\tReturns: None");
 496 +
 497 +PyDoc_STRVAR(pyrbac_getexecuser__doc__, "corresponds with getexecuser(3SECDB)\
 498 +\nTakes: \'username\', \'type\', \'id\'\n\
 499 +Return: a single exec_attr entry\n\
 500 +\tArguments: None\n\
 501 +\tReturns: a dict representation of an execattr_t struct:\n\
 502 +\t\t\"name\": Authorization Name\n\
 503 +\t\t\"type\": Profile Type\n\
 504 +\t\t\"policy\": Policy attributes are relevant in\n\
 505 +\t\t\"res1\": reserved\n\
 506 +\t\t\"res2\": reserved\n\
 507 +\t\t\"id\": unique identifier\n\
 508 +\t\t\"attributes\": A Python dict keyed by attribute & valued as\
 509 +either a list or a string depending on value");
 510 +
 511 +PyDoc_STRVAR(pyrbac_getexecprof__doc__, "corresponds with getexecprof(3SECDB)\
 512 +\nTakes: \'profile name\', \'type\', \'id\'\n\
 513 +\tReturns: a dict representation of an execattr_t struct:\n\
 514 +\t\t\"name\": Authorization Name\n\
 515 +\t\t\"type\": Profile Type\n\
 516 +\t\t\"policy\": Policy attributes are relevant in\n\
 517 +\t\t\"res1\": reserved\n\
 518 +\t\t\"res2\": reserved\n\
 519 +\t\t\"id\": unique identifier\n\
 520 +\t\t\"attributes\": A Python dict keyed by attribute & valued as\
 521 +either a list or a string depending on value");
 522 +
 523 +PyDoc_STRVAR(pyrbac_getexecattr__doc__, "corresponds with getexecattr(3SECDB)\
 524 +\nTakes 0 arguments\n\
 525 +\tReturns: a dict representation of an execattr_t struct:\n\
 526 +\t\t\"name\": Authorization Name\n\
 527 +\t\t\"type\": Profile Type\n\
 528 +\t\t\"policy\": Policy attributes are relevant in\n\
 529 +\t\t\"res1\": reserved\n\
 530 +\t\t\"res2\": reserved\n\
 531 +\t\t\"id\": unique identifier\n\
 532 +\t\t\"attributes\": A Python dict keyed by attribute & valued as\
 533 +either a list or a string depending on value");
 534 +
 535 +static PyMethodDef Execattr_methods[] = {
 536 +       {"setexecattr", pyrbac_setexecattr, METH_NOARGS, pyrbac_setexecattr__doc__},
 537 +       {"endexecattr", pyrbac_endexecattr, METH_NOARGS, pyrbac_endexecattr__doc__},
 538 +       {"getexecprof", pyrbac_getexecprof, METH_VARARGS, pyrbac_getexecprof__doc__},   
 539 +       {"getexecuser", pyrbac_getexecuser, METH_VARARGS, pyrbac_getexecuser__doc__},
 540 +       {"getexecattr", pyrbac_getexecattr, METH_NOARGS, pyrbac_getexecattr__doc__},
 541 +       {NULL}
 542 +};
 543 +
 544 +PyTypeObject ExecattrType = {
 545 +       PyObject_HEAD_INIT(NULL)
 546 +       0,                         /*ob_size*/
 547 +       "rbac.execattr",             /*tp_name*/
 548 +       sizeof(Execattr),             /*tp_basicsize*/
 549 +       0,                         /*tp_itemsize*/
 550 +       (destructor)Execattr_dealloc, /*tp_dealloc*/
 551 +       0,                         /*tp_print*/
 552 +       0,                         /*tp_getattr*/
 553 +       0,                         /*tp_setattr*/
 554 +       0,                         /*tp_compare*/
 555 +       0,                         /*tp_repr*/
 556 +       0,                         /*tp_as_number*/
 557 +       0,                         /*tp_as_sequence*/
 558 +       0,                         /*tp_as_mapping*/
 559 +       0,                         /*tp_hash */
 560 +       0,                         /*tp_call*/
 561 +       0,                         /*tp_str*/
 562 +       0,                         /*tp_getattro*/
 563 +       0,                         /*tp_setattro*/
 564 +       0,                         /*tp_as_buffer*/
 565 +       Py_TPFLAGS_DEFAULT |
 566 +       Py_TPFLAGS_BASETYPE |
 567 +       Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
 568 +       pyrbac_execattr__doc__,           /* tp_doc */
 569 +       0,                             /* tp_traverse */
 570 +       0,                             /* tp_clear */
 571 +       0,                             /* tp_richcompare */
 572 +       0,                             /* tp_weaklistoffset */
 573 +       pyrbac_execattr__iter__,                               /* tp_iter */
 574 +       pyrbac_execattr_next,         /* tp_iternext */
 575 +       Execattr_methods,             /* tp_methods */
 576 +       0,             /* tp_members */
 577 +       0,                         /* tp_getset */
 578 +       0,                         /* tp_base */
 579 +       0,                         /* tp_dict */
 580 +       0,                         /* tp_descr_get */
 581 +       0,                         /* tp_descr_set */
 582 +       0,                         /* tp_dictoffset */
 583 +       (initproc)Execattr_init,      /* tp_init */
 584 +       0,                         /* tp_alloc */
 585 +       Execattr_new,                 /* tp_new */
 586 +};
 587 diff --git Python-2.6.4/Modules/privileges.c Python-2.6.4/Modules/privileges.c
 588 new file mode 100644
 589 --- /dev/null
 590 +++ Python-2.6.4/Modules/privileges.c
 591 @@ -0,0 +1,230 @@
 592 +/*
 593 + * CDDL HEADER START
 594 + *
 595 + * The contents of this file are subject to the terms of the
 596 + * Common Development and Distribution License (the "License").
 597 + * You may not use this file except in compliance with the License.
 598 + *
 599 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 600 + * or http://www.opensolaris.org/os/licensing.
 601 + * See the License for the specific language governing permissions
 602 + * and limitations under the License.
 603 + *
 604 + * When distributing Covered Code, include this CDDL HEADER in each
 605 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 606 + * If applicable, add the following below this CDDL HEADER, with the
 607 + * fields enclosed by brackets "[]" replaced with your own identifying
 608 + * information: Portions Copyright [yyyy] [name of copyright owner]
 609 + *
 610 + * CDDL HEADER END
 611 + */
 612 +
 613 +/*
 614 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 615 + * Use is subject to license terms.
 616 + */
 617 +
 618 +/*
 619 + * privileges(5) bindings for Python
 620 + */
 621 +
 622 +#include <priv.h>
 623 +#include "Python.h"
 624 +
 625 +static PyObject *
 626 +pyprivileges_setppriv( PyObject *self, PyObject *args) {
 627 +       priv_op_t op = -1 ; 
 628 +       priv_ptype_t which = NULL;
 629 +
 630 +       PyObject* set_list = NULL;
 631 +
 632 +       priv_set_t * set = NULL;
 633 +
 634 +       if(!PyArg_ParseTuple(args, "iiO:setppriv", &op, &which, &set_list))
 635 +               return NULL;
 636 +       
 637 +       if((op != PRIV_ON && op != PRIV_OFF && op != PRIV_SET) ||
 638 +               (which != PRIV_PERMITTED && which != PRIV_EFFECTIVE &&
 639 +               which != PRIV_INHERITABLE && which != PRIV_LIMIT))
 640 +               return NULL;
 641 +       
 642 +       PyObject* set_string = PyList_GetItem(set_list, 0);
 643 +       int i;
 644 +       for (i = 1; i < PyList_Size(set_list); ++i) {
 645 +               PyString_Concat(&set_string, PyString_FromString(","));
 646 +               PyString_Concat(&set_string, PyList_GetItem(set_list, i));
 647 +       }
 648 +
 649 +       set = priv_str_to_set(PyString_AsString(set_string), ",", NULL );
 650 +
 651 +       if ( set == NULL )
 652 +               return NULL;
 653 +
 654 +       long ret = (long) setppriv(op, which, set);
 655 +       priv_freeset(set);      
 656 +       // Python inverts true & false
 657 +       if(ret)
 658 +               Py_RETURN_FALSE;
 659 +       
 660 +       Py_RETURN_TRUE;
 661 +}
 662 +
 663 +static PyObject *
 664 +pyprivileges_getppriv( PyObject *self, PyObject *args) {
 665 +
 666 +       char* set_str = NULL;
 667 +       priv_ptype_t which = NULL;
 668 +       priv_set_t * set = priv_allocset();
 669 +       if (set == NULL)
 670 +               return NULL;
 671 +
 672 +       if(!PyArg_ParseTuple(args, "i:getppriv", &which))
 673 +               return NULL;
 674 +
 675 +       if (which != PRIV_PERMITTED && which != PRIV_EFFECTIVE &&
 676 +       which != PRIV_INHERITABLE && which != PRIV_LIMIT)
 677 +               return NULL;
 678 +
 679 +       if (getppriv(which, set) != 0)
 680 +               return NULL;
 681 +       
 682 +       set_str = priv_set_to_str(set, ',', PRIV_STR_LIT);
 683 +       priv_freeset(set);
 684 +       
 685 +       PyObject* set_list = PyList_New(NULL);
 686 +       char* saveptr;
 687 +       char* item = strtok_r(set_str, ",", &saveptr);
 688 +       PyList_Append(set_list, PyString_FromString(item));
 689 +
 690 +       while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
 691 +               if(PyList_Append(set_list, PyString_FromString(item)) != 0) {
 692 +                       Py_XDECREF(set_list);
 693 +                       return NULL;
 694 +               }
 695 +       }
 696 +
 697 +       return(set_list);
 698 +}
 699 +
 700 +static PyObject *
 701 +pyprivileges_priv_inverse( PyObject *self, PyObject *args ) {
 702 +
 703 +       PyObject* set_list_in = NULL;
 704 +       if(!PyArg_ParseTuple(args, "O:priv_inverse", &set_list_in))
 705 +               return NULL;
 706 +
 707 +       PyObject* set_string = PyList_GetItem(set_list_in, 0);
 708 +       int i;
 709 +       for (i = 1; i < PyList_Size(set_list_in); ++i) {
 710 +               PyString_Concat(set_string, PyString_FromString(","));
 711 +               PyString_Concat(set_string, PyList_GetItem(set_list_in, i));
 712 +       }
 713 +
 714 +       priv_set_t * set = priv_str_to_set(PyString_AsString(set_string), ",", NULL);
 715 +       if (set == NULL)
 716 +               return NULL;
 717 +       priv_inverse(set);
 718 +       char * ret_str = priv_set_to_str(set, ',', PRIV_STR_LIT);
 719 +       priv_freeset(set);
 720 +       
 721 +       PyObject* set_list_out = PyList_New(NULL);
 722 +       char* saveptr;
 723 +       char* item = strtok_r(ret_str, ",", &saveptr);
 724 +       PyList_Append(set_list_out, PyString_FromString(item));
 725 +
 726 +       while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
 727 +               if(PyList_Append(set_list_out, PyString_FromString(item)) != 0) {
 728 +                       Py_XDECREF(set_list_out);
 729 +                       return NULL;
 730 +               }
 731 +       }
 732 +       
 733 +       Py_XDECREF(set_list_in);
 734 +       
 735 +       return(set_list_out);
 736 +}
 737 +
 738 +/* priv_ineffect is a convienient wrapper to priv_get
 739 + * however priv_set is, in the context of python, not
 740 + * much of a convienience, so it's omitted
 741 + */
 742 +static PyObject * 
 743 +pyprivileges_priv_ineffect(PyObject* self, PyObject* args) {
 744 +       char* privstring=NULL;
 745 +       if (!PyArg_ParseTuple(args, "s:priv_ineffect", &privstring))
 746 +               return NULL;
 747 +       return PyBool_FromLong(priv_ineffect(privstring));
 748 +}
 749 +
 750 +
 751 +static char pyprivileges__doc__[];
 752 +PyDoc_STRVAR(pyprivileges__doc__, 
 753 +"Provides functions for interacting with the Solaris privileges(5) framework\n\
 754 +Functions provided:\n\
 755 +setppriv\n\
 756 +getppriv\n\
 757 +priv_ineffect\n\
 758 +priv_inverse");
 759 +
 760 +static char pyprivileges_setppriv__doc__[];
 761 +static char pyprivileges_getppriv__doc__[];
 762 +static char pyprivileges_priv_ineffect__doc__[];
 763 +static char pyprivileges_priv_inverse__doc__[];
 764 +
 765 +PyDoc_STRVAR(pyprivileges_setppriv__doc__, 
 766 +"Facilitates setting the permitted/inheritable/limit/effective privileges set\n\
 767 +\tArguments:\n\
 768 +\t\tone of (PRIV_ON|PRIV_OFF|PRIV_SET)\n\
 769 +\t\tone of (PRIV_PERMITTED|PRIV_INHERITABLE|PRIV_LIMIT|PRIV_EFFECTIVE)\n\
 770 +\t\tset of privileges: a list of strings\n\
 771 +\tReturns: True on success, False on failure\
 772 +");
 773 +
 774 +PyDoc_STRVAR(pyprivileges_getppriv__doc__, 
 775 +"Return the process privilege set\n\
 776 +\tArguments:\n\
 777 +\t\tone of (PRIV_PERMITTED|PRIV_INHERITABLE|PRIV_LIMIT|PRIV_EFFECTIVE)\n\
 778 +\tReturns: a Python list of strings");
 779 +       
 780 +PyDoc_STRVAR(pyprivileges_priv_ineffect__doc__, 
 781 +"Checks for a privileges presence in the effective set\n\
 782 +\tArguments: a String\n\
 783 +\tReturns: True if the privilege is in effect, False otherwise");
 784 +
 785 +PyDoc_STRVAR(pyprivileges_priv_inverse__doc__, 
 786 +"The complement of the set of privileges\n\
 787 +\tArguments: a list of strings\n\tReturns: a list of strings");
 788 +
 789 +static PyMethodDef module_methods[] = {
 790 +       {"setppriv", pyprivileges_setppriv, METH_VARARGS, pyprivileges_setppriv__doc__}, 
 791 +       {"getppriv", pyprivileges_getppriv, METH_VARARGS, pyprivileges_getppriv__doc__}, 
 792 +       {"priv_ineffect", pyprivileges_priv_ineffect, METH_VARARGS, pyprivileges_priv_ineffect__doc__},
 793 +       {"priv_inverse", pyprivileges_priv_inverse, METH_VARARGS, pyprivileges_priv_inverse__doc__},
 794 +       {NULL}
 795 +};
 796 +
 797 +
 798 +#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
 799 +#define PyMODINIT_FUNC void
 800 +#endif
 801 +PyMODINIT_FUNC
 802 +initprivileges(void) {
 803 +       PyObject* m;
 804 +
 805 +       m = Py_InitModule3("privileges", module_methods, pyprivileges__doc__);
 806 +               if ( m == NULL )
 807 +               return;
 808 +               
 809 +       PyObject* d = PyModule_GetDict(m);
 810 +       if (d == NULL)
 811 +               return;
 812 +
 813 +       PyDict_SetItemString(d, "PRIV_ON", PyInt_FromLong((long)PRIV_ON));
 814 +       PyDict_SetItemString(d, "PRIV_OFF", PyInt_FromLong((long)PRIV_OFF));
 815 +       PyDict_SetItemString(d, "PRIV_SET", PyInt_FromLong((long)PRIV_SET));
 816 +
 817 +       PyDict_SetItemString(d, "PRIV_PERMITTED", PyInt_FromLong((long)PRIV_PERMITTED));
 818 +       PyDict_SetItemString(d, "PRIV_INHERITABLE", PyInt_FromLong((long)PRIV_INHERITABLE));
 819 +       PyDict_SetItemString(d, "PRIV_LIMIT", PyInt_FromLong((long)PRIV_LIMIT));
 820 +       PyDict_SetItemString(d, "PRIV_EFFECTIVE", PyInt_FromLong((long)PRIV_EFFECTIVE));
 821 +}
 822 diff --git Python-2.6.4/Modules/pyrbac.c Python-2.6.4/Modules/pyrbac.c
 823 new file mode 100644
 824 --- /dev/null
 825 +++ Python-2.6.4/Modules/pyrbac.c
 826 @@ -0,0 +1,69 @@
 827 +/*
 828 + * CDDL HEADER START
 829 + *
 830 + * The contents of this file are subject to the terms of the
 831 + * Common Development and Distribution License (the "License").
 832 + * You may not use this file except in compliance with the License.
 833 + *
 834 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 835 + * or http://www.opensolaris.org/os/licensing.
 836 + * See the License for the specific language governing permissions
 837 + * and limitations under the License.
 838 + *
 839 + * When distributing Covered Code, include this CDDL HEADER in each
 840 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 841 + * If applicable, add the following below this CDDL HEADER, with the
 842 + * fields enclosed by brackets "[]" replaced with your own identifying
 843 + * information: Portions Copyright [yyyy] [name of copyright owner]
 844 + *
 845 + * CDDL HEADER END
 846 + */
 847 +
 848 +/*
 849 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 850 + * Use is subject to license terms.
 851 + */
 852 +
 853 +/*
 854 + * RBAC Bindings for Python
 855 + */
 856 +
 857 +#include <Python.h>
 858 +#include "pyrbac.h"
 859 +
 860 +static PyMethodDef module_methods[] = {NULL};
 861 +static char pyrbac__doc__[];
 862 +
 863 +PyDoc_STRVAR(pyrbac__doc__, "provides access to some objects \
 864 +for interaction with the Solaris Role-Based Access Control \
 865 +framework.\n\nDynamic objects:\n\
 866 +userattr -- for interacting with user_attr(4)\n\
 867 +authattr -- for interacting with auth_attr(4)\n\
 868 +execattr -- for interacting with exec_attr(4)\n");
 869 +
 870 +#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
 871 +#define PyMODINIT_FUNC void
 872 +#endif
 873 +PyMODINIT_FUNC
 874 +initrbac(void) {
 875 +       PyObject* m;
 876 +       if (PyType_Ready(&AuthattrType) < 0 || 
 877 +               PyType_Ready(&ExecattrType) < 0 ||
 878 +               PyType_Ready(&UserattrType) < 0 )
 879 +               return;
 880 +
 881 +       m = Py_InitModule3("rbac", module_methods, pyrbac__doc__);
 882 +       if ( m == NULL )
 883 +               return;
 884 +       
 885 +       Py_INCREF(&AuthattrType);
 886 +       PyModule_AddObject(m, "authattr", (PyObject*)&AuthattrType);
 887 +
 888 +       Py_INCREF(&ExecattrType);
 889 +       PyModule_AddObject(m, "execattr", (PyObject*)&ExecattrType);
 890 +
 891 +       Py_INCREF(&UserattrType);
 892 +       PyModule_AddObject(m, "userattr", (PyObject*)&UserattrType);
 893 +
 894 +}
 895 +
 896 diff --git Python-2.6.4/Modules/pyrbac.h Python-2.6.4/Modules/pyrbac.h
 897 new file mode 100644
 898 --- /dev/null
 899 +++ Python-2.6.4/Modules/pyrbac.h
 900 @@ -0,0 +1,46 @@
 901 +/*
 902 + * CDDL HEADER START
 903 + *
 904 + * The contents of this file are subject to the terms of the
 905 + * Common Development and Distribution License (the "License").
 906 + * You may not use this file except in compliance with the License.
 907 + *
 908 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 909 + * or http://www.opensolaris.org/os/licensing.
 910 + * See the License for the specific language governing permissions
 911 + * and limitations under the License.
 912 + *
 913 + * When distributing Covered Code, include this CDDL HEADER in each
 914 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 915 + * If applicable, add the following below this CDDL HEADER, with the
 916 + * fields enclosed by brackets "[]" replaced with your own identifying
 917 + * information: Portions Copyright [yyyy] [name of copyright owner]
 918 + *
 919 + * CDDL HEADER END
 920 + */
 921 +
 922 +/*
 923 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 924 + * Use is subject to license terms.
 925 + */
 926 +
 927 +/* 
 928 + * RBAC bindings for python
 929 + */
 930 +#ifndef PYRBAC_H
 931 +#define PYRBAC_H
 932 +
 933 +#include <secdb.h>
 934 +
 935 +
 936 +#define PYRBAC_USER_MODE 1
 937 +#define PYRBAC_PROF_MODE 2
 938 +#define PYRBAC_ATTR_MODE 3
 939 +#define PYRBAC_NAM_MODE 4
 940 +#define PYRBAC_UID_MODE 5
 941 +
 942 +PyTypeObject AuthattrType;
 943 +PyTypeObject ExecattrType;
 944 +PyTypeObject UserattrType;
 945 +
 946 +#endif
 947 diff --git Python-2.6.4/Modules/userattr.c Python-2.6.4/Modules/userattr.c
 948 new file mode 100644
 949 --- /dev/null
 950 +++ Python-2.6.4/Modules/userattr.c
 951 @@ -0,0 +1,309 @@
 952 +/*
 953 + * CDDL HEADER START
 954 + *
 955 + * The contents of this file are subject to the terms of the
 956 + * Common Development and Distribution License (the "License").
 957 + * You may not use this file except in compliance with the License.
 958 + *
 959 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 960 + * or http://www.opensolaris.org/os/licensing.
 961 + * See the License for the specific language governing permissions
 962 + * and limitations under the License.
 963 + *
 964 + * When distributing Covered Code, include this CDDL HEADER in each
 965 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 966 + * If applicable, add the following below this CDDL HEADER, with the
 967 + * fields enclosed by brackets "[]" replaced with your own identifying
 968 + * information: Portions Copyright [yyyy] [name of copyright owner]
 969 + *
 970 + * CDDL HEADER END
 971 + */
 972 +
 973 +/*
 974 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 975 + * Use is subject to license terms.
 976 + */
 977 +
 978 +/*
 979 + * RBAC Bindings for Python - user_attr functions
 980 + */
 981 +
 982 +#include <stdio.h>
 983 +#include <user_attr.h>
 984 +#include "Python.h"
 985 +#include "pyrbac.h"
 986 +
 987 +static PyObject*
 988 +pyrbac_setuserattr(PyObject* self, PyObject* args) {
 989 +       setuserattr();
 990 +       return Py_None;
 991 +}
 992 +
 993 +static PyObject*
 994 +pyrbac_enduserattr(PyObject* self, PyObject* args) {
 995 +       enduserattr();
 996 +       return Py_None;
 997 +}
 998 +
 999 +PyObject*
1000 +pyrbac_getuseruidnamattr(PyObject* self, void* arg, int mode, char* filename) {
1001 +       
1002 +       userattr_t *ret_userattr;
1003 +
1004 +       if (mode == PYRBAC_ATTR_MODE) {
1005 +           if (filename != NULL) {
1006 +            FILE* file = fopen(filename, "r");
1007 +            if (file == NULL)
1008 +                return NULL;
1009 +               ret_userattr = fgetuserattr(file);
1010 +               if (fclose(file))
1011 +                return NULL;
1012 +           }
1013 +           else
1014 +               ret_userattr = getuserattr();
1015 +       }
1016 +       else if (mode == PYRBAC_NAM_MODE)
1017 +               ret_userattr = getusernam((char*) arg);
1018 +       else if (mode == PYRBAC_UID_MODE)
1019 +               ret_userattr = getuseruid(*((uid_t*) arg));
1020 +       
1021 +       if (ret_userattr == NULL)
1022 +               return Py_None;
1023 +       
1024 +       PyObject* entry = PyTuple_New(5);
1025 +       if (entry == NULL) {
1026 +               free_userattr(ret_userattr);
1027 +               return NULL;
1028 +       }
1029 +       
1030 +       PyObject* kv_data = PyDict_New();
1031 +
1032 +       if(ret_userattr->attr != NULL) {
1033 +               int len;
1034 +               for(len = 0; len < ret_userattr->attr->length; len++) {
1035 +                       kv_t current = ret_userattr->attr->data[len];
1036 +
1037 +                       PyObject* set = PyList_New(NULL);
1038 +                       char* saveptr;
1039 +                       char* item = strtok_r(current.value, ",", &saveptr);
1040 +                       PyList_Append(set, PyString_FromString(item));
1041 +
1042 +                       while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
1043 +                               if(PyList_Append(set, PyString_FromString(item)) != 0) {
1044 +                                       Py_XDECREF(set);
1045 +                                       Py_XDECREF(kv_data);
1046 +                                       free_userattr(ret_userattr);
1047 +                                       return NULL;
1048 +                               }
1049 +                       }
1050 +                       if(PyDict_SetItemString(kv_data, current.key, set)) {
1051 +                                       free_userattr(ret_userattr);
1052 +                                       return NULL;
1053 +                       }
1054 +               }
1055 +       }
1056 +       entry = Py_BuildValue("{s:s,s:s,s:s,s:s,s:O}", 
1057 +               "name", ret_userattr->name,
1058 +               "qualifier", ret_userattr->qualifier,
1059 +               "res1", ret_userattr->res1,
1060 +               "res2", ret_userattr->res2,
1061 +               "attributes", kv_data);
1062 +
1063 +       free_userattr(ret_userattr);
1064 +       
1065 +       return entry;
1066 +}
1067 +
1068 +
1069 +static PyObject*
1070 +pyrbac_getuserattr(PyObject* self, PyObject* args) {
1071 +       return(pyrbac_getuseruidnamattr(self, (void*) NULL, PYRBAC_ATTR_MODE, NULL));
1072 +}
1073 +
1074 +static PyObject*
1075 +pyrbac_fgetuserattr(PyObject* self, PyObject* args) {
1076 +       char* filename = NULL;
1077 +       if(!PyArg_ParseTuple(args, "s:fgetuserattr", &filename))
1078 +               return NULL;
1079 +       return(pyrbac_getuseruidnamattr(self, NULL, PYRBAC_ATTR_MODE, filename));
1080 +}
1081 +
1082 +static PyObject*
1083 +pyrbac_getusernam(PyObject* self, PyObject* args) {
1084 +       char* name = NULL;
1085 +       if(!PyArg_ParseTuple(args, "s:getusernam", &name))
1086 +               return NULL;
1087 +       return(pyrbac_getuseruidnamattr(self, (void*) name, PYRBAC_NAM_MODE, NULL));
1088 +}
1089 +
1090 +static PyObject*
1091 +pyrbac_getuseruid(PyObject* self, PyObject* args) {
1092 +       uid_t uid;
1093 +       if(!PyArg_ParseTuple(args, "i:getuseruid", &uid))
1094 +               return NULL;
1095 +       return(pyrbac_getuseruidnamattr(self, (void*) &uid, PYRBAC_UID_MODE, NULL));
1096 +}
1097 +
1098 +static PyObject*
1099 +pyrbac_userattr_next(PyObject* self, PyObject* args) {
1100 +       PyObject* retval = pyrbac_getuserattr(self, args);
1101 +       if( retval == Py_None ) {
1102 +               setuserattr();
1103 +               return NULL;
1104 +       }
1105 +       return retval;
1106 +}
1107 +static PyObject*
1108 +pyrbac_userattr__iter__(PyObject* self, PyObject* args) {
1109 +       return self;
1110 +}
1111 +
1112 +typedef struct {
1113 +       PyObject_HEAD
1114 +} Userattr;
1115 +
1116 +static void
1117 +Userattr_dealloc(Userattr* self) {
1118 +       enduserattr();
1119 +       self->ob_type->tp_free((PyObject*) self);
1120 +}
1121 +
1122 +static PyObject*
1123 +Userattr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1124 +       Userattr *self;
1125 +       self = (Userattr*)type->tp_alloc(type, 0);
1126 +
1127 +       return ((PyObject *) self);
1128 +}
1129 +
1130 +static int
1131 +Userattr_init(Userattr* self, PyObject *args, PyObject *kwargs) {
1132 +       setuserattr();
1133 +       return 0;
1134 +}
1135 +
1136 +static char pyrbac_userattr__doc__[];
1137 +PyDoc_STRVAR(pyrbac_userattr__doc__, "provides functions for \
1138 +interacting with the extended user attributes database. May be iterated over \
1139 +to enumerate user_attr(4) entries\n\n\
1140 +Methods provided:\n\
1141 +setuserattr\n\
1142 +enduserattr\n\
1143 +getuserattr\n\
1144 +fgetuserattr\n\
1145 +getusernam\n\
1146 +getuseruid");
1147 +
1148 +static char pyrbac_setuserattr__doc__[];
1149 +static char pyrbac_enduserattr__doc__[];
1150 +static char pyrbac_getuserattr__doc__[];
1151 +static char pyrbac_getusernam__doc__[];
1152 +static char pyrbac_getuseruid__doc__[];
1153 +
1154 +PyDoc_STRVAR(pyrbac_setuserattr__doc__, "\"rewinds\" the user_attr functions \
1155 +to the first entry in the db. Called automatically by the constructor.\n\
1156 +\tArguments: None\n\
1157 +\tReturns: None");
1158 +
1159 +PyDoc_STRVAR(pyrbac_enduserattr__doc__, "closes the user_attr database, \
1160 +cleans up storage. called automatically by the destructor\n\
1161 +\tArguments: None\n\
1162 +\tReturns: None");
1163 +
1164 +PyDoc_STRVAR(pyrbac_getuserattr__doc__, "Return a single user_attr entry\n \
1165 +\tArguments: None\n\
1166 +\tReturns: a dict representation of a userattr_t struct:\n\
1167 +\t\t\"name\": username\n\
1168 +\t\t\"qualifier\": reserved\n\
1169 +\t\t\"res1\": reserved\n\
1170 +\t\t\"res2\": reserved\n\
1171 +\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
1172 +or a string depending on value"
1173 +);
1174 +
1175 +PyDoc_STRVAR(pyrbac_fgetuserattr__doc__, "Return a single user_attr entry \
1176 +from a file, bypassing nsswitch.conf\n\
1177 +\tArguments: \'filename\'\n\
1178 +\tReturns: a dict representation of a userattr_t struct:\n\
1179 +\t\t\"name\": username\n\
1180 +\t\t\"qualifier\": reserved\n\
1181 +\t\t\"res1\": reserved\n\
1182 +\t\t\"res2\": reserved\n\
1183 +\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
1184 +or a string depending on value");
1185 +
1186 +PyDoc_STRVAR(pyrbac_getusernam__doc__, "Searches for a user_attr entry with a \
1187 +given user name\n\
1188 +\tArgument: \'username\'\n\
1189 +\tReturns: a dict representation of a userattr_t struct:\n\
1190 +\t\t\"name\": username\n\
1191 +\t\t\"qualifier\": reserved\n\
1192 +\t\t\"res1\": reserved\n\
1193 +\t\t\"res2\": reserved\n\
1194 +\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
1195 +or a string depending on value");
1196 +
1197 +PyDoc_STRVAR(pyrbac_getuseruid__doc__, "Searches for a user_attr entry with a \
1198 +given uid\n\
1199 +\tArgument: uid\n\
1200 +\tReturns: a dict representation of a userattr_t struct:\n\
1201 +\t\t\"name\": username\n\
1202 +\t\t\"qualifier\": reserved\n\
1203 +\t\t\"res1\": reserved\n\
1204 +\t\t\"res2\": reserved\n\
1205 +\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
1206 +or a string depending on value");
1207 +
1208 +static PyMethodDef Userattr_methods[] = {
1209 +       {"setuserattr", pyrbac_setuserattr, METH_NOARGS, pyrbac_setuserattr__doc__},
1210 +       {"enduserattr", pyrbac_enduserattr, METH_NOARGS, pyrbac_enduserattr__doc__},
1211 +       {"getuserattr", pyrbac_getuserattr, METH_NOARGS, pyrbac_getuserattr__doc__},
1212 +       {"fgetuserattr", pyrbac_fgetuserattr, METH_VARARGS, pyrbac_fgetuserattr__doc__},
1213 +       {"getusernam", pyrbac_getusernam, METH_VARARGS, pyrbac_getusernam__doc__},
1214 +       {"getuseruid", pyrbac_getuseruid, METH_VARARGS, pyrbac_getuseruid__doc__},
1215 +       {NULL}
1216 +};
1217 +
1218 +PyTypeObject UserattrType = {
1219 +       PyObject_HEAD_INIT(NULL)
1220 +       0,                         /*ob_size*/
1221 +       "rbac.userattr",             /*tp_name*/
1222 +       sizeof(Userattr),             /*tp_basicsize*/
1223 +       0,                         /*tp_itemsize*/
1224 +       (destructor)Userattr_dealloc, /*tp_dealloc*/
1225 +       0,                         /*tp_print*/
1226 +       0,                         /*tp_getattr*/
1227 +       0,                         /*tp_setattr*/
1228 +       0,                         /*tp_compare*/
1229 +       0,                         /*tp_repr*/
1230 +       0,                         /*tp_as_number*/
1231 +       0,                         /*tp_as_sequence*/
1232 +       0,                         /*tp_as_mapping*/
1233 +       0,                         /*tp_hash */
1234 +       0,                         /*tp_call*/
1235 +       0,                         /*tp_str*/
1236 +       0,                         /*tp_getattro*/
1237 +       0,                         /*tp_setattro*/
1238 +       0,                         /*tp_as_buffer*/
1239 +       Py_TPFLAGS_DEFAULT |
1240 +       Py_TPFLAGS_BASETYPE |
1241 +       Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
1242 +       pyrbac_userattr__doc__,    /* tp_doc */
1243 +       0,                             /* tp_traverse */
1244 +       0,                             /* tp_clear */
1245 +       0,                             /* tp_richcompare */
1246 +       0,                             /* tp_weaklistoffset */
1247 +       pyrbac_userattr__iter__,                               /* tp_iter */
1248 +       pyrbac_userattr_next,         /* tp_iternext */
1249 +       Userattr_methods,             /* tp_methods */
1250 +       0,             /* tp_members */
1251 +       0,                         /* tp_getset */
1252 +       0,                         /* tp_base */
1253 +       0,                         /* tp_dict */
1254 +       0,                         /* tp_descr_get */
1255 +       0,                         /* tp_descr_set */
1256 +       0,                         /* tp_dictoffset */
1257 +       (initproc)Userattr_init,      /* tp_init */
1258 +       0,                         /* tp_alloc */
1259 +       Userattr_new,                 /* tp_new */
1260 +};
1261 diff --git Python-2.6.4/setup.py Python-2.6.4/setup.py
1262 --- Python-2.6.4/setup.py
1263 +++ Python-2.6.4/setup.py
1264 @@ -1290,6 +1290,22 @@
1265              exts.append( Extension('dlpi', ['dlpimodule.c'],
1266                                     libraries = ['dlpi']) )
1267  
1268 +        # privileges module (Solaris)
1269 +        priv_inc = find_file('priv.h', [], inc_dirs)
1270 +        if priv_inc is not None:
1271 +            exts.append( Extension('privileges', ['privileges.c']))
1272 +
1273 +        # rbac module (Solaris)
1274 +        secdb_inc = find_file('secdb.h', [], inc_dirs)
1275 +        aa_inc = find_file('auth_attr.h', [], inc_dirs)
1276 +        ea_inc = find_file('exec_attr.h', [], inc_dirs)
1277 +        ua_inc = find_file('user_attr.h', [], inc_dirs)
1278 +        if secdb_inc is not None and aa_inc is not None and \
1279 +            ea_inc is not None and ua_inc is not None:
1280 +            exts.append( Extension('rbac', ['pyrbac.c', 'authattr.c', \
1281 +                                   'execattr.c', 'userattr.c'],
1282 +                                   libraries = ['nsl', 'socket', 'secdb']) )
1283 +
1284          # Thomas Heller's _ctypes module
1285          self.detect_ctypes(inc_dirs, lib_dirs)
1286  
1287 diff --git Python-2.6.4/Lib/test/privrbac.py Python-2.6.4/Lib/test/privrbac.py
1288 new file mode 100644
1289 --- /dev/null   2011-02-12 03:13:57.000000000 -0600
1290 +++ Python-2.6.4/Lib/test/privrbactest.py       2011-01-20 13:52:42.862305331 -0600
1291 @@ -0,0 +1,290 @@
1292 +#!/usr/bin/python2.6
1293 +#
1294 +# CDDL HEADER START
1295 +#
1296 +# The contents of this file are subject to the terms of the
1297 +# Common Development and Distribution License (the "License").
1298 +# You may not use this file except in compliance with the License.
1299 +#
1300 +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1301 +# or http://www.opensolaris.org/os/licensing.
1302 +# See the License for the specific language governing permissions
1303 +# and limitations under the License.
1304 +#
1305 +# When distributing Covered Code, include this CDDL HEADER in each
1306 +# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1307 +# If applicable, add the following below this CDDL HEADER, with the
1308 +# fields enclosed by brackets "[]" replaced with your own identifying
1309 +# information: Portions Copyright [yyyy] [name of copyright owner]
1310 +#
1311 +# CDDL HEADER END
1312 +#
1313 +
1314 +# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
1315 +# Use is subject to license terms.
1316 +
1317 +import privileges
1318 +import rbac
1319 +import os
1320 +import sys
1321 +import tempfile
1322 +
1323 +# privileges tests
1324 +
1325 +def test_setppriv():
1326 +    amchild = os.fork()
1327 +    if amchild == 0:
1328 +        if privileges.setppriv(privileges.PRIV_OFF, privileges.PRIV_EFFECTIVE, 
1329 +            ['proc_fork']):
1330 +            try:
1331 +                os.fork()
1332 +                sys.exit(1)
1333 +            except OSError, e:
1334 +                sys.exit(0)
1335 +
1336 +    child = os.wait()
1337 +    if child[1] is not 0:
1338 +        print "setppriv. Bad exit status from pid %i\n" % child[0]
1339 +        return False
1340 +    return True
1341 +
1342 +def test_getppriv():
1343 +    if 'proc_fork' in privileges.getppriv(privileges.PRIV_LIMIT):
1344 +        return True
1345 +    print "getppriv or PRIV_PROC_FORK not in PRIV_LIMIT.\n"
1346 +    return False
1347 +
1348 +def test_priv_ineffect():
1349 +    if privileges.priv_ineffect('proc_fork'):
1350 +        return True
1351 +    print "priv_ineffect or PRIV_PROC_FORK not in effect\n"
1352 +    return False
1353 +
1354 +# authattr tests
1355 +
1356 +def test_chkauthattr():
1357 +    try:
1358 +        a = rbac.authattr()
1359 +    except Exception, e:
1360 +        print "Could not instantiate authattr object: %s\n" % e
1361 +        return False
1362 +    try:
1363 +        res = a.chkauthattr('solaris.*', 'root')
1364 +    except Exception, e:
1365 +        print "chkauthattr failed: %s\n" % e
1366 +        return False
1367 +    if not res:
1368 +        print "chkauthattr failed or \'root\' lacks \'solaris.*\'\n"
1369 +        return False
1370 +    return True
1371 +
1372 +def test_getauthattr():
1373 +    try:
1374 +        a = rbac.authattr()
1375 +    except Exception, e:
1376 +        print "Could not instantiate authattr object: %s\n" % e
1377 +        return False
1378 +    try:
1379 +        res = a.getauthattr()
1380 +    except Exception, e:
1381 +        print "getauthattr failed: %s\n" % e
1382 +        return False
1383 +    if not 'name' in res.keys():
1384 +        print "getauthattr failed\n"
1385 +        return False
1386 +    return True
1387 +
1388 +def test_getauthnam():
1389 +    try:
1390 +        a = rbac.authattr()
1391 +    except Exception, e:
1392 +        print "Could not instantiate authattr object: %s\n" % e
1393 +        return False
1394 +    try:
1395 +        res = a.getauthnam('solaris.')
1396 +    except Exception, e:
1397 +        print "getauthnam failed: %s\n" % e
1398 +        return False
1399 +    if not res:
1400 +        print "getauthnam failed or \'solaris.\' not in auth_attr(4)\n"
1401 +        return False
1402 +    return True
1403 +
1404 +def test_authattr_iter():
1405 +    try:
1406 +        a = rbac.authattr()
1407 +    except Exception, e:
1408 +        print "Could not instantiate authattr object: %s\n" % e
1409 +        return False
1410 +    res = a.next()
1411 +    if not 'name' in res.keys() or type(a) != type(a.__iter__()):
1412 +        print "authattr object is not an iterable\n"
1413 +        return False
1414 +    return True
1415 +
1416 +# execattr tests
1417 +
1418 +def test_getexecattr():
1419 +    try:
1420 +        a = rbac.execattr()
1421 +    except Exception, e:
1422 +        print "Could not instantiate execattr object: %s\n" % e
1423 +        return False
1424 +    try:
1425 +        res = a.getexecattr()
1426 +    except Exception, e:
1427 +        print "getexecattr failed: %s\n" % e
1428 +        return False
1429 +    if not 'name' in res.keys():
1430 +        print "getexecattr failed\n"
1431 +        return False
1432 +    return True
1433 +
1434 +def test_getexecuser():
1435 +    try:
1436 +        a = rbac.execattr()
1437 +    except Exception, e:
1438 +        print "Could not instantiate execattr object: %s\n" % e
1439 +        return False
1440 +    try:
1441 +        res = a.getexecuser("root", "act", "*;*;*;*;*")
1442 +    except Exception, e:
1443 +        print "getexecuser failed: %s\n" % e
1444 +        return False
1445 +    if not res:
1446 +        print "getexecuser failed or \'root\' not assigned to \'act\', " \
1447 +            "\'*;*;*;*;*\' \n"
1448 +        return False
1449 +    return True
1450 +
1451 +
1452 +def test_getexecprof():
1453 +    try:
1454 +        a = rbac.execattr()
1455 +    except Exception, e:
1456 +        print "Could not instantiate execattr object: %s\n" % e
1457 +        return False
1458 +    try:
1459 +        res = a.getexecprof("All", "cmd", "*")
1460 +    except Exception, e:
1461 +        print "getexecprof failed: %s\n" % e
1462 +        return False
1463 +    if not res:
1464 +        print "getexecprof failed or \'All\' not granted \'cmd\' : \'*\'\n"
1465 +        return False
1466 +    return True
1467 +
1468 +def test_execattr_iter():
1469 +    try:
1470 +        a = rbac.execattr()
1471 +    except Exception, e:
1472 +        print "Could not instantiate execattr object: %s\n" % e
1473 +        return False
1474 +    res = a.next()
1475 +    if not 'name' in res.keys() or type(a) != type(a.__iter__()):
1476 +        print "execattr object is not an iterable\n"
1477 +        return False
1478 +    return True
1479 +
1480 +# userattr tests
1481 +
1482 +def test_getuserattr():
1483 +    try:
1484 +        a = rbac.userattr()
1485 +    except Exception, e:
1486 +        print "Could not instantiate userattr object: %s\n" % e
1487 +        return False
1488 +    try:
1489 +        res = a.getuserattr()
1490 +    except Exception, e:
1491 +        print "getuserattr failed: %s\n" % e
1492 +        return False
1493 +    if not 'name' in res.keys():
1494 +        print "getuserattr failed\n"
1495 +        return False
1496 +    return True
1497 +
1498 +def test_fgetuserattr():
1499 +    temp = tempfile.NamedTemporaryFile()
1500 +    temp.write("user::::profiles=Software Installation;roles=foo;"\
1501 +        "auths=solaris.foo.bar")
1502 +    temp.seek(0)
1503 +    try:
1504 +        a = rbac.userattr()
1505 +    except Exception, e:
1506 +        print "Could not instantiate userattr object: %s\n" % e
1507 +        return False
1508 +    try:
1509 +        res = a.fgetuserattr(temp.name)
1510 +        temp.close()    
1511 +    except Exception, e:
1512 +        print "fgetuserattr failed: %s\n" % e
1513 +        temp.close()
1514 +        return False
1515 +    if not 'name' in res.keys():
1516 +        print "fgetuserattr failed\n"
1517 +        return False
1518 +    return True
1519 +
1520 +def test_getuseruid():
1521 +    try:
1522 +        a = rbac.userattr()
1523 +    except Exception, e:
1524 +        print "Could not instantiate userattr object: %s\n" % e
1525 +        return False
1526 +    try:
1527 +        res = a.getuseruid(0)
1528 +    except Exception, e:
1529 +        print "getusernam failed: %s\n" % e
1530 +        return False
1531 +    if not 'name' in res:
1532 +        print "getusernam failed or no uid 0\n"
1533 +        return False
1534 +    return True
1535 +
1536 +def test_getusernam():
1537 +    try:
1538 +        a = rbac.userattr()
1539 +    except Exception, e:
1540 +        print "Could not instantiate userattr object: %s\n" % e
1541 +        return False
1542 +    try:
1543 +        res = a.getusernam('root')
1544 +    except Exception, e:
1545 +        print "getusernam failed: %s\n" % e
1546 +        return False
1547 +    if not 'name' in res:
1548 +        print "getusernam failed or no \'root\' user\n"
1549 +        return False
1550 +    return True
1551 +
1552 +def test_userattr_iter():
1553 +    try:
1554 +        a = rbac.userattr()
1555 +    except Exception, e:
1556 +        print "Could not instantiate userattr object: %s\n" % e
1557 +        return False
1558 +    res = a.next()
1559 +    if not 'name' in res.keys() or type(a) != type(a.__iter__()):
1560 +        print "userattr object is not an iterable\n"
1561 +        return False
1562 +    return True
1563 +
1564 +if not test_setppriv() or not test_getppriv() or not test_priv_ineffect():
1565 +    print "*** Failures detected in privileges module\n"    
1566 +    sys.exit(1)
1567 +
1568 +if not test_getauthattr() or not test_chkauthattr() or not test_getauthnam() \
1569 +    or not test_authattr_iter:
1570 +    print "*** Failures detected in rbac.authattr\n"
1571 +    sys.exit(1)
1572 +
1573 +if not test_getexecattr() or not test_getexecuser() or not test_getexecprof() \
1574 +    or not test_execattr_iter():
1575 +    print "*** Failures detected in rbac.execattr\n"
1576 +    sys.exit(1)
1577 +
1578 +if not test_getuserattr() or not test_fgetuserattr() or not test_getusernam()\
1579 +    or not test_getuseruid() or not test_userattr_iter():
1580 +    print "*** Failures detected in rbac.userattr\n"
1581 +    sys.exit(1)