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