rust/cargo-c: update to 0.10.7+cargo-0.84.0
[oi-userland.git] / components / python / python37 / patches / 06-rbac.patch
blob98dd10389594fcf095be168863e6d52c3b6782aa
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.7.4/Modules/authattr.c
7 +++ Python-3.7.4/Modules/authattr.c
8 @@ -0,0 +1,261 @@
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 +static char pyrbac_authattr__doc__[];
168 +PyDoc_STRVAR(pyrbac_authattr__doc__, """provides interfaces to the auth_attr \
169 +database. may be iterated over to return all auth_attr entries\n\n\
170 +Methods provided:\n\
171 +setauthattr\n\
172 +endauthattr\n\
173 +getauthattr\n\
174 +chkauthattr\n\
175 +getauthnam""");
177 +static char pyrbac_setauthattr__doc__[];
178 +static char pyrbac_endauthattr__doc__[];
179 +static char pyrbac_getauthattr__doc__[];
180 +static char pyrbac_chkauthattr__doc__[];
182 +PyDoc_STRVAR(pyrbac_setauthattr__doc__,
183 +"\"rewinds\" the auth_attr functions to the first entry in the db. Called \
184 +automatically by the constructor\n\tArguments: None\n\tReturns: None");
186 +PyDoc_STRVAR(pyrbac_endauthattr__doc__,
187 +"closes the auth_attr database, cleans up storage. called automatically by \
188 +the destructor\n\tArguments: None\n\tReturns: None");
190 +PyDoc_STRVAR(pyrbac_chkauthattr__doc__, "verifies if a user has a given \
191 +authorization.\n\tArguments: 2 Python strings, 'authname' and 'username'\n\
192 +\tReturns: True if the user is authorized, False otherwise");
194 +PyDoc_STRVAR(pyrbac_getauthattr__doc__,
195 +"return one entry from the auth_attr database\n\
196 +\tArguments: None\n\
197 +\tReturns: a dict representing the authattr_t struct:\n\
198 +\t\t\"name\": Authorization Name\n\
199 +\t\t\"res1\": reserved\n\
200 +\t\t\"res2\": reserved\n\
201 +\t\t\"short\": Short Description\n\
202 +\t\t\"long\": Long Description\n\
203 +\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
204 +or a string depending on value");
206 +PyDoc_STRVAR(pyrbac_getauthnam__doc__,
207 +"searches the auth_attr database for a given authorization name\n\
208 +\tArguments: a Python string containing the auth name\n\
209 +\tReturns: a dict representing the authattr_t struct:\n\
210 +\t\t\"name\": Authorization Name\n\
211 +\t\t\"res1\": reserved\n\
212 +\t\t\"res2\": reserved\n\
213 +\t\t\"short\": Short Description\n\
214 +\t\t\"long\": Long Description\n\
215 +\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
216 +or a string depending on value");
218 +static PyMethodDef Authattr_methods[] = {
219 + {"setauthattr", pyrbac_setauthattr, METH_NOARGS, pyrbac_setauthattr__doc__},
220 + {"endauthattr", pyrbac_endauthattr, METH_NOARGS, pyrbac_endauthattr__doc__},
221 + {"chkauthattr", pyrbac_chkauthattr, METH_VARARGS, pyrbac_chkauthattr__doc__},
222 + {"getauthattr", pyrbac_getauthattr, METH_NOARGS, pyrbac_getauthattr__doc__},
223 + {"getauthnam", pyrbac_getauthnam, METH_VARARGS, pyrbac_getauthnam__doc__},
224 + {NULL, NULL}
227 +PyTypeObject AuthattrType = {
228 + PyVarObject_HEAD_INIT(NULL, 0)
229 + "rbac.authattr", /*tp_name*/
230 + sizeof(Authattr), /*tp_basicsize*/
231 + 0, /*tp_itemsize*/
232 + (destructor)Authattr_dealloc, /*tp_dealloc*/
233 + 0, /*tp_print*/
234 + 0, /*tp_getattr*/
235 + 0, /*tp_setattr*/
236 + 0, /*tp_reserved*/
237 + 0, /*tp_repr*/
238 + 0, /*tp_as_number*/
239 + 0, /*tp_as_sequence*/
240 + 0, /*tp_as_mapping*/
241 + 0, /*tp_hash */
242 + 0, /*tp_call*/
243 + 0, /*tp_str*/
244 + 0, /*tp_getattro*/
245 + 0, /*tp_setattro*/
246 + 0, /*tp_as_buffer*/
247 + Py_TPFLAGS_DEFAULT |
248 + Py_TPFLAGS_BASETYPE, /*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 + 0, /* tp_free */
268 + 0, /* tp_is_gc */
270 --- Python-3.7.4/Modules/execattr.c
271 +++ Python-3.7.4/Modules/execattr.c
272 @@ -0,0 +1,313 @@
274 + * CDDL HEADER START
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.
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.
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]
291 + * CDDL HEADER END
292 + */
295 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
296 + */
299 + * RBAC Bindings for Python - exec_attr functions
300 + */
302 +#include <exec_attr.h>
303 +#include "Python.h"
304 +#include "pyrbac.h"
306 +static PyObject *
307 +pyrbac_setexecattr(PyObject* self, PyObject* args) {
308 + setexecattr();
309 + return Py_None;
312 +static PyObject *
313 +pyrbac_endexecattr(PyObject* self, PyObject* args) {
314 + endexecattr();
315 + return Py_None;
318 +PyObject *
319 +pyrbac_getexecuserprofattr(PyObject* self, char* userprofname, char* type, char* id, int mode) {
321 + PyObject* ep_data = (mode == PYRBAC_ATTR_MODE) ? NULL : PyList_New(0);
323 + if (ep_data == NULL && mode != PYRBAC_ATTR_MODE )
324 + return NULL;
326 + execattr_t *execprof;
327 + if (mode == PYRBAC_USER_MODE)
328 + execprof = getexecuser(userprofname, type, id, GET_ALL);
329 + else if (mode == PYRBAC_PROF_MODE)
330 + execprof = getexecprof(userprofname, type, id, GET_ALL);
331 + else if (mode == PYRBAC_ATTR_MODE)
332 + execprof = getexecattr();
333 + else
334 + return NULL;
336 + if (execprof == NULL)
337 + return Py_None;
339 + execattr_t *execprof_head = execprof;
341 + while(execprof != NULL) {
343 + PyObject* kv_data = PyDict_New();
345 + if(execprof->attr != NULL) {
346 + int len;
347 + for(len = 0; len < execprof->attr->length; len++) {
348 + kv_t current = execprof->attr->data[len];
350 + PyObject* set = PyList_New(NULL);
351 + char* saveptr;
352 + char* item = strtok_r(current.value, ",", &saveptr);
353 + PyList_Append(set, PyBytes_FromString(item));
355 + while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
356 + if(PyList_Append(set, PyBytes_FromString(item)) != 0) {
357 + Py_XDECREF(set);
358 + Py_XDECREF(kv_data);
359 + free_execattr(execprof_head);
360 + return NULL;
363 + if(PyDict_SetItemString(kv_data, current.key, set)) {
364 + free_execattr(execprof_head);
365 + return NULL;
369 + PyObject* entry = Py_BuildValue("{s:s,s:s,s:s,s:s,s:s,s:s,s:O}",
370 + "name", execprof->name,
371 + "type", execprof->type,
372 + "policy", execprof->policy,
373 + "res1", execprof->res1,
374 + "res2", execprof->res2,
375 + "id", execprof->id,
376 + "attributes", kv_data);
378 + if (entry == NULL) {
379 + Py_XDECREF(kv_data);
380 + free_execattr(execprof_head);
381 + return NULL;
384 + if (mode == PYRBAC_ATTR_MODE) {
385 + free_execattr(execprof_head);
386 + return(entry);
388 + PyList_Append(ep_data, entry);
389 + execprof = execprof->next;
392 + free_execattr(execprof_head);
393 + return(ep_data);
397 +static PyObject *
398 +pyrbac_getexecuser(PyObject* self, PyObject* args) {
399 + char* username = NULL;
400 + char* type = NULL;
401 + char* id = NULL;
403 + if(!PyArg_ParseTuple(args, "sss:getexecuser", &username, &type, &id))
404 + return NULL;
406 + return (pyrbac_getexecuserprofattr(self, username, type, id, PYRBAC_USER_MODE));
409 +static PyObject *
410 +pyrbac_getexecprof(PyObject* self, PyObject* args) {
412 + char* profname = NULL;
413 + char* type = NULL;
414 + char* id = NULL;
416 + if(!PyArg_ParseTuple(args, "sss:getexecprof", &profname, &type, &id))
417 + return NULL;
419 + return (pyrbac_getexecuserprofattr(self, profname, type, id, PYRBAC_PROF_MODE));
422 +static PyObject*
423 +pyrbac_getexecattr(PyObject* self, PyObject* args) {
424 + return pyrbac_getexecuserprofattr(self, NULL, NULL, NULL, PYRBAC_ATTR_MODE);
427 +static PyObject*
428 +pyrbac_execattr_next(PyObject* self, PyObject* args) {
429 + PyObject* retval = pyrbac_getexecattr(self, args);
430 + if( retval == Py_None ) {
431 + setexecattr();
432 + return NULL;
434 + return retval;
436 +static PyObject*
437 +pyrbac_execattr__iter__(PyObject* self, PyObject* args) {
438 + return self;
441 +typedef struct {
442 + PyObject_HEAD
443 +} Execattr;
445 +static void
446 +Execattr_dealloc(Execattr* self) {
447 + endexecattr();
448 + Py_TYPE(self)->tp_free((PyObject*) self);
451 +static PyObject*
452 +Execattr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
453 + Execattr *self;
454 + self = (Execattr*)type->tp_alloc(type, 0);
456 + return ((PyObject *) self);
459 +static int
460 +Execattr_init(Execattr* self, PyObject *args, PyObject *kwargs) {
461 + setexecattr();
462 + return 0;
465 +static char pyrbac_execattr__doc__[];
467 +PyDoc_STRVAR(pyrbac_execattr__doc__, "provides functions for \
468 +interacting with the execution profiles database. May be iterated over to \
469 +enumerate exec_attr(4) entries\n\n\
470 +Methods provided:\n\
471 +setexecattr\n\
472 +endexecattr\n\
473 +getexecattr\n\
474 +getexecprof\n\
475 +getexecuser");
478 +static char pyrbac_getexecuser__doc__[];
479 +static char pyrbac_getexecprof__doc__[];
480 +static char pyrbac_getexecattr__doc__[];
481 +static char pyrbac_setexecattr__doc__[];
482 +static char pyrbac_endexecattr__doc__[];
484 +PyDoc_STRVAR(pyrbac_setexecattr__doc__,
485 +"\"rewinds\" the exec_attr functions to the first entry in the db. Called \
486 +automatically by the constructor.\n\
487 +\tArguments: None\
488 +\tReturns: None");
490 +PyDoc_STRVAR(pyrbac_endexecattr__doc__,
491 +"closes the exec_attr database, cleans up storage. called automatically by \
492 +the destructor.\n\
493 +\tArguments: None\
494 +\tReturns: None");
496 +PyDoc_STRVAR(pyrbac_getexecuser__doc__, "corresponds with getexecuser(3SECDB)\
497 +\nTakes: \'username\', \'type\', \'id\'\n\
498 +Return: a single exec_attr entry\n\
499 +\tArguments: None\n\
500 +\tReturns: a dict representation of an execattr_t struct:\n\
501 +\t\t\"name\": Authorization Name\n\
502 +\t\t\"type\": Profile Type\n\
503 +\t\t\"policy\": Policy attributes are relevant in\n\
504 +\t\t\"res1\": reserved\n\
505 +\t\t\"res2\": reserved\n\
506 +\t\t\"id\": unique identifier\n\
507 +\t\t\"attributes\": A Python dict keyed by attribute & valued as\
508 +either a list or a string depending on value");
510 +PyDoc_STRVAR(pyrbac_getexecprof__doc__, "corresponds with getexecprof(3SECDB)\
511 +\nTakes: \'profile name\', \'type\', \'id\'\n\
512 +\tReturns: a dict representation of an execattr_t struct:\n\
513 +\t\t\"name\": Authorization Name\n\
514 +\t\t\"type\": Profile Type\n\
515 +\t\t\"policy\": Policy attributes are relevant in\n\
516 +\t\t\"res1\": reserved\n\
517 +\t\t\"res2\": reserved\n\
518 +\t\t\"id\": unique identifier\n\
519 +\t\t\"attributes\": A Python dict keyed by attribute & valued as\
520 +either a list or a string depending on value");
522 +PyDoc_STRVAR(pyrbac_getexecattr__doc__, "corresponds with getexecattr(3SECDB)\
523 +\nTakes 0 arguments\n\
524 +\tReturns: a dict representation of an execattr_t struct:\n\
525 +\t\t\"name\": Authorization Name\n\
526 +\t\t\"type\": Profile Type\n\
527 +\t\t\"policy\": Policy attributes are relevant in\n\
528 +\t\t\"res1\": reserved\n\
529 +\t\t\"res2\": reserved\n\
530 +\t\t\"id\": unique identifier\n\
531 +\t\t\"attributes\": A Python dict keyed by attribute & valued as\
532 +either a list or a string depending on value");
534 +static PyMethodDef Execattr_methods[] = {
535 + {"setexecattr", pyrbac_setexecattr, METH_NOARGS, pyrbac_setexecattr__doc__},
536 + {"endexecattr", pyrbac_endexecattr, METH_NOARGS, pyrbac_endexecattr__doc__},
537 + {"getexecprof", pyrbac_getexecprof, METH_VARARGS, pyrbac_getexecprof__doc__},
538 + {"getexecuser", pyrbac_getexecuser, METH_VARARGS, pyrbac_getexecuser__doc__},
539 + {"getexecattr", pyrbac_getexecattr, METH_NOARGS, pyrbac_getexecattr__doc__},
540 + {NULL, NULL}
543 +PyTypeObject ExecattrType = {
544 + PyVarObject_HEAD_INIT(NULL, 0)
545 + "rbac.execattr", /*tp_name*/
546 + sizeof(Execattr), /*tp_basicsize*/
547 + 0, /*tp_itemsize*/
548 + (destructor)Execattr_dealloc, /*tp_dealloc*/
549 + 0, /*tp_print*/
550 + 0, /*tp_getattr*/
551 + 0, /*tp_setattr*/
552 + 0, /*tp_reserved*/
553 + 0, /*tp_repr*/
554 + 0, /*tp_as_number*/
555 + 0, /*tp_as_sequence*/
556 + 0, /*tp_as_mapping*/
557 + 0, /*tp_hash */
558 + 0, /*tp_call*/
559 + 0, /*tp_str*/
560 + 0, /*tp_getattro*/
561 + 0, /*tp_setattro*/
562 + 0, /*tp_as_buffer*/
563 + Py_TPFLAGS_DEFAULT |
564 + Py_TPFLAGS_BASETYPE, /*tp_flags*/
565 + pyrbac_execattr__doc__, /* tp_doc */
566 + 0, /* tp_traverse */
567 + 0, /* tp_clear */
568 + 0, /* tp_richcompare */
569 + 0, /* tp_weaklistoffset */
570 + pyrbac_execattr__iter__, /* tp_iter */
571 + pyrbac_execattr_next, /* tp_iternext */
572 + Execattr_methods, /* tp_methods */
573 + 0, /* tp_members */
574 + 0, /* tp_getset */
575 + 0, /* tp_base */
576 + 0, /* tp_dict */
577 + 0, /* tp_descr_get */
578 + 0, /* tp_descr_set */
579 + 0, /* tp_dictoffset */
580 + (initproc)Execattr_init, /* tp_init */
581 + 0, /* tp_alloc */
582 + Execattr_new, /* tp_new */
583 + 0, /* tp_free */
584 + 0, /* tp_is_gc */
586 --- Python-3.7.4/Modules/privileges.c
587 +++ Python-3.7.4/Modules/privileges.c
588 @@ -0,0 +1,243 @@
590 + * CDDL HEADER START
592 + * The contents of this file are subject to the terms of the
593 + * Common Development and Distribution License (the "License").
594 + * You may not use this file except in compliance with the License.
596 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
597 + * or http://www.opensolaris.org/os/licensing.
598 + * See the License for the specific language governing permissions
599 + * and limitations under the License.
601 + * When distributing Covered Code, include this CDDL HEADER in each
602 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
603 + * If applicable, add the following below this CDDL HEADER, with the
604 + * fields enclosed by brackets "[]" replaced with your own identifying
605 + * information: Portions Copyright [yyyy] [name of copyright owner]
607 + * CDDL HEADER END
608 + */
611 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
612 + */
615 + * privileges(5) bindings for Python
616 + */
618 +#include <priv.h>
619 +#include "Python.h"
621 +static PyObject *
622 +pyprivileges_setppriv( PyObject *self, PyObject *args) {
623 + priv_op_t op = -1 ;
624 + priv_ptype_t which = NULL;
626 + PyObject* set_list = NULL;
628 + priv_set_t * set = NULL;
630 + if(!PyArg_ParseTuple(args, "iiO:setppriv", &op, &which, &set_list))
631 + return NULL;
633 + if((op != PRIV_ON && op != PRIV_OFF && op != PRIV_SET) ||
634 + (which != PRIV_PERMITTED && which != PRIV_EFFECTIVE &&
635 + which != PRIV_INHERITABLE && which != PRIV_LIMIT))
636 + return NULL;
638 + PyObject* set_string = PyList_GetItem(set_list, 0);
639 + int i;
640 + for (i = 1; i < PyList_Size(set_list); ++i) {
641 + PyBytes_Concat(&set_string, PyBytes_FromString(","));
642 + PyBytes_Concat(&set_string, PyList_GetItem(set_list, i));
645 + set = priv_str_to_set(PyBytes_AsString(set_string), ",", NULL );
647 + if ( set == NULL )
648 + return NULL;
650 + long ret = (long) setppriv(op, which, set);
651 + priv_freeset(set);
652 + // Python inverts true & false
653 + if(ret)
654 + Py_RETURN_FALSE;
656 + Py_RETURN_TRUE;
659 +static PyObject *
660 +pyprivileges_getppriv( PyObject *self, PyObject *args) {
662 + char* set_str = NULL;
663 + priv_ptype_t which = NULL;
664 + priv_set_t * set = priv_allocset();
665 + if (set == NULL)
666 + return NULL;
668 + if(!PyArg_ParseTuple(args, "i:getppriv", &which))
669 + return NULL;
671 + if (which != PRIV_PERMITTED && which != PRIV_EFFECTIVE &&
672 + which != PRIV_INHERITABLE && which != PRIV_LIMIT)
673 + return NULL;
675 + if (getppriv(which, set) != 0)
676 + return NULL;
678 + set_str = priv_set_to_str(set, ',', PRIV_STR_LIT);
679 + priv_freeset(set);
681 + PyObject* set_list = PyList_New(NULL);
682 + char* saveptr;
683 + char* item = strtok_r(set_str, ",", &saveptr);
684 + PyList_Append(set_list, PyBytes_FromString(item));
686 + while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
687 + if(PyList_Append(set_list, PyBytes_FromString(item)) != 0) {
688 + Py_XDECREF(set_list);
689 + return NULL;
693 + return(set_list);
696 +static PyObject *
697 +pyprivileges_priv_inverse( PyObject *self, PyObject *args ) {
699 + PyObject* set_list_in = NULL;
700 + if(!PyArg_ParseTuple(args, "O:priv_inverse", &set_list_in))
701 + return NULL;
703 + PyObject* set_string = PyList_GetItem(set_list_in, 0);
704 + int i;
705 + for (i = 1; i < PyList_Size(set_list_in); ++i) {
706 + PyBytes_Concat(set_string, PyBytes_FromString(","));
707 + PyBytes_Concat(set_string, PyList_GetItem(set_list_in, i));
710 + priv_set_t * set = priv_str_to_set(PyBytes_AsString(set_string), ",", NULL);
711 + if (set == NULL)
712 + return NULL;
713 + priv_inverse(set);
714 + char * ret_str = priv_set_to_str(set, ',', PRIV_STR_LIT);
715 + priv_freeset(set);
717 + PyObject* set_list_out = PyList_New(NULL);
718 + char* saveptr;
719 + char* item = strtok_r(ret_str, ",", &saveptr);
720 + PyList_Append(set_list_out, PyBytes_FromString(item));
722 + while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
723 + if(PyList_Append(set_list_out, PyBytes_FromString(item)) != 0) {
724 + Py_XDECREF(set_list_out);
725 + return NULL;
729 + Py_XDECREF(set_list_in);
731 + return(set_list_out);
734 +/* priv_ineffect is a convienient wrapper to priv_get
735 + * however priv_set is, in the context of python, not
736 + * much of a convienience, so it's omitted
737 + */
738 +static PyObject *
739 +pyprivileges_priv_ineffect(PyObject* self, PyObject* args) {
740 + char* privstring=NULL;
741 + if (!PyArg_ParseTuple(args, "s:priv_ineffect", &privstring))
742 + return NULL;
743 + return PyBool_FromLong(priv_ineffect(privstring));
747 +static char pyprivileges__doc__[];
748 +PyDoc_STRVAR(pyprivileges__doc__,
749 +"Provides functions for interacting with the Solaris privileges(5) framework\n\
750 +Functions provided:\n\
751 +setppriv\n\
752 +getppriv\n\
753 +priv_ineffect\n\
754 +priv_inverse");
756 +static char pyprivileges_setppriv__doc__[];
757 +static char pyprivileges_getppriv__doc__[];
758 +static char pyprivileges_priv_ineffect__doc__[];
759 +static char pyprivileges_priv_inverse__doc__[];
761 +PyDoc_STRVAR(pyprivileges_setppriv__doc__,
762 +"Facilitates setting the permitted/inheritable/limit/effective privileges set\n\
763 +\tArguments:\n\
764 +\t\tone of (PRIV_ON|PRIV_OFF|PRIV_SET)\n\
765 +\t\tone of (PRIV_PERMITTED|PRIV_INHERITABLE|PRIV_LIMIT|PRIV_EFFECTIVE)\n\
766 +\t\tset of privileges: a list of strings\n\
767 +\tReturns: True on success, False on failure\
768 +");
770 +PyDoc_STRVAR(pyprivileges_getppriv__doc__,
771 +"Return the process privilege set\n\
772 +\tArguments:\n\
773 +\t\tone of (PRIV_PERMITTED|PRIV_INHERITABLE|PRIV_LIMIT|PRIV_EFFECTIVE)\n\
774 +\tReturns: a Python list of strings");
776 +PyDoc_STRVAR(pyprivileges_priv_ineffect__doc__,
777 +"Checks for a privileges presence in the effective set\n\
778 +\tArguments: a String\n\
779 +\tReturns: True if the privilege is in effect, False otherwise");
781 +PyDoc_STRVAR(pyprivileges_priv_inverse__doc__,
782 +"The complement of the set of privileges\n\
783 +\tArguments: a list of strings\n\tReturns: a list of strings");
785 +static PyMethodDef module_methods[] = {
786 + {"setppriv", pyprivileges_setppriv, METH_VARARGS, pyprivileges_setppriv__doc__},
787 + {"getppriv", pyprivileges_getppriv, METH_VARARGS, pyprivileges_getppriv__doc__},
788 + {"priv_ineffect", pyprivileges_priv_ineffect, METH_VARARGS, pyprivileges_priv_ineffect__doc__},
789 + {"priv_inverse", pyprivileges_priv_inverse, METH_VARARGS, pyprivileges_priv_inverse__doc__},
790 + {NULL, NULL}
794 +#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
795 +#define PyMODINIT_FUNC void
796 +#endif
797 +PyMODINIT_FUNC
798 +PyInit_privileges (void) {
799 + PyObject* m;
801 + static struct PyModuleDef moduledef = {
802 + PyModuleDef_HEAD_INIT,
803 + "privileges",
804 + pyprivileges__doc__,
805 + -1,
806 + module_methods,
807 + NULL,
808 + NULL,
809 + NULL,
810 + NULL,
811 + };
813 + m = PyModule_Create(&moduledef);
814 + if ( m == NULL )
815 + return m;
817 + PyObject* d = PyModule_GetDict(m);
818 + if (d == NULL)
819 + return m;
821 + PyDict_SetItemString(d, "PRIV_ON", PyLong_FromLong((long)PRIV_ON));
822 + PyDict_SetItemString(d, "PRIV_OFF", PyLong_FromLong((long)PRIV_OFF));
823 + PyDict_SetItemString(d, "PRIV_SET", PyLong_FromLong((long)PRIV_SET));
825 + PyDict_SetItemString(d, "PRIV_PERMITTED", PyLong_FromLong((long)PRIV_PERMITTED));
826 + PyDict_SetItemString(d, "PRIV_INHERITABLE", PyLong_FromLong((long)PRIV_INHERITABLE));
827 + PyDict_SetItemString(d, "PRIV_LIMIT", PyLong_FromLong((long)PRIV_LIMIT));
828 + PyDict_SetItemString(d, "PRIV_EFFECTIVE", PyLong_FromLong((long)PRIV_EFFECTIVE));
830 + return m;
832 --- Python-3.7.9/Modules/pyrbac.c 2021-02-19 10:07:48.503350965 +0000
833 +++ Python-3.7.9/Modules/pyrbac.c 2021-02-19 10:06:44.738020940 +0000
834 @@ -0,0 +1,86 @@
836 + * CDDL HEADER START
838 + * The contents of this file are subject to the terms of the
839 + * Common Development and Distribution License (the "License").
840 + * You may not use this file except in compliance with the License.
842 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
843 + * or http://www.opensolaris.org/os/licensing.
844 + * See the License for the specific language governing permissions
845 + * and limitations under the License.
847 + * When distributing Covered Code, include this CDDL HEADER in each
848 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
849 + * If applicable, add the following below this CDDL HEADER, with the
850 + * fields enclosed by brackets "[]" replaced with your own identifying
851 + * information: Portions Copyright [yyyy] [name of copyright owner]
853 + * CDDL HEADER END
854 + */
857 + * Copyright (c) 2011, 2021, Oracle and/or its affiliates.
858 + */
861 + * RBAC Bindings for Python
862 + */
864 +#include <Python.h>
865 +#include "pyrbac.h"
867 +extern PyTypeObject AuthattrType;
868 +extern PyTypeObject ExecattrType;
869 +extern PyTypeObject UserattrType;
871 +static PyMethodDef module_methods[] = {NULL};
872 +static char pyrbac__doc__[];
874 +PyDoc_STRVAR(pyrbac__doc__, "provides access to some objects \
875 +for interaction with the Solaris Role-Based Access Control \
876 +framework.\n\nDynamic objects:\n\
877 +userattr -- for interacting with user_attr(4)\n\
878 +authattr -- for interacting with auth_attr(4)\n\
879 +execattr -- for interacting with exec_attr(4)\n");
881 +#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
882 +#define PyMODINIT_FUNC void
883 +#endif
884 +PyMODINIT_FUNC
885 +PyInit_rbac (void) {
886 + PyObject* m;
888 + if (PyType_Ready(&AuthattrType) < 0 ||
889 + PyType_Ready(&ExecattrType) < 0 ||
890 + PyType_Ready(&UserattrType) < 0 )
891 + return NULL;
893 + static struct PyModuleDef moduledef = {
894 + PyModuleDef_HEAD_INIT,
895 + "rbac",
896 + pyrbac__doc__,
897 + -1,
898 + module_methods,
899 + NULL,
900 + NULL,
901 + NULL,
902 + NULL,
903 + };
905 + m = PyModule_Create(&moduledef);
906 + if ( m == NULL )
907 + return NULL;
909 + Py_INCREF(&AuthattrType);
910 + PyModule_AddObject(m, "authattr", (PyObject*)&AuthattrType);
912 + Py_INCREF(&ExecattrType);
913 + PyModule_AddObject(m, "execattr", (PyObject*)&ExecattrType);
915 + Py_INCREF(&UserattrType);
916 + PyModule_AddObject(m, "userattr", (PyObject*)&UserattrType);
918 + return m;
921 --- Python-3.7.9/Modules/pyrbac.h 2021-02-19 10:07:33.834751750 +0000
922 +++ Python-3.7.9/Modules/pyrbac.h 2021-02-19 09:58:59.367899290 +0000
923 @@ -0,0 +1,41 @@
925 + * CDDL HEADER START
927 + * The contents of this file are subject to the terms of the
928 + * Common Development and Distribution License (the "License").
929 + * You may not use this file except in compliance with the License.
931 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
932 + * or http://www.opensolaris.org/os/licensing.
933 + * See the License for the specific language governing permissions
934 + * and limitations under the License.
936 + * When distributing Covered Code, include this CDDL HEADER in each
937 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
938 + * If applicable, add the following below this CDDL HEADER, with the
939 + * fields enclosed by brackets "[]" replaced with your own identifying
940 + * information: Portions Copyright [yyyy] [name of copyright owner]
942 + * CDDL HEADER END
943 + */
946 + * Copyright (c) 2011, 2021, Oracle and/or its affiliates.
947 + */
949 +/*
950 + * RBAC bindings for python
951 + */
952 +#ifndef PYRBAC_H
953 +#define PYRBAC_H
955 +#include <secdb.h>
958 +#define PYRBAC_USER_MODE 1
959 +#define PYRBAC_PROF_MODE 2
960 +#define PYRBAC_ATTR_MODE 3
961 +#define PYRBAC_NAM_MODE 4
962 +#define PYRBAC_UID_MODE 5
964 +#endif
965 --- Python-3.7.4/Modules/userattr.c
966 +++ Python-3.7.4/Modules/userattr.c
967 @@ -0,0 +1,308 @@
969 + * CDDL HEADER START
971 + * The contents of this file are subject to the terms of the
972 + * Common Development and Distribution License (the "License").
973 + * You may not use this file except in compliance with the License.
975 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
976 + * or http://www.opensolaris.org/os/licensing.
977 + * See the License for the specific language governing permissions
978 + * and limitations under the License.
980 + * When distributing Covered Code, include this CDDL HEADER in each
981 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
982 + * If applicable, add the following below this CDDL HEADER, with the
983 + * fields enclosed by brackets "[]" replaced with your own identifying
984 + * information: Portions Copyright [yyyy] [name of copyright owner]
986 + * CDDL HEADER END
987 + */
990 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
991 + */
994 + * RBAC Bindings for Python - user_attr functions
995 + */
997 +#include <stdio.h>
998 +#include <user_attr.h>
999 +#include "Python.h"
1000 +#include "pyrbac.h"
1002 +static PyObject*
1003 +pyrbac_setuserattr(PyObject* self, PyObject* args) {
1004 + setuserattr();
1005 + return Py_None;
1008 +static PyObject*
1009 +pyrbac_enduserattr(PyObject* self, PyObject* args) {
1010 + enduserattr();
1011 + return Py_None;
1014 +PyObject*
1015 +pyrbac_getuseruidnamattr(PyObject* self, void* arg, int mode, char* filename) {
1017 + userattr_t *ret_userattr;
1019 + if (mode == PYRBAC_ATTR_MODE) {
1020 + if (filename != NULL) {
1021 + FILE* file = fopen(filename, "r");
1022 + if (file == NULL)
1023 + return NULL;
1024 + ret_userattr = fgetuserattr(file);
1025 + if (fclose(file))
1026 + return NULL;
1028 + else
1029 + ret_userattr = getuserattr();
1031 + else if (mode == PYRBAC_NAM_MODE)
1032 + ret_userattr = getusernam((char*) arg);
1033 + else if (mode == PYRBAC_UID_MODE)
1034 + ret_userattr = getuseruid(*((uid_t*) arg));
1036 + if (ret_userattr == NULL)
1037 + return Py_None;
1039 + PyObject* entry = PyTuple_New(5);
1040 + if (entry == NULL) {
1041 + free_userattr(ret_userattr);
1042 + return NULL;
1045 + PyObject* kv_data = PyDict_New();
1047 + if(ret_userattr->attr != NULL) {
1048 + int len;
1049 + for(len = 0; len < ret_userattr->attr->length; len++) {
1050 + kv_t current = ret_userattr->attr->data[len];
1052 + PyObject* set = PyList_New(NULL);
1053 + char* saveptr;
1054 + char* item = strtok_r(current.value, ",", &saveptr);
1055 + PyList_Append(set, PyBytes_FromString(item));
1057 + while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
1058 + if(PyList_Append(set, PyBytes_FromString(item)) != 0) {
1059 + Py_XDECREF(set);
1060 + Py_XDECREF(kv_data);
1061 + free_userattr(ret_userattr);
1062 + return NULL;
1065 + if(PyDict_SetItemString(kv_data, current.key, set)) {
1066 + free_userattr(ret_userattr);
1067 + return NULL;
1071 + entry = Py_BuildValue("{s:s,s:s,s:s,s:s,s:O}",
1072 + "name", ret_userattr->name,
1073 + "qualifier", ret_userattr->qualifier,
1074 + "res1", ret_userattr->res1,
1075 + "res2", ret_userattr->res2,
1076 + "attributes", kv_data);
1078 + free_userattr(ret_userattr);
1080 + return entry;
1084 +static PyObject*
1085 +pyrbac_getuserattr(PyObject* self, PyObject* args) {
1086 + return(pyrbac_getuseruidnamattr(self, (void*) NULL, PYRBAC_ATTR_MODE, NULL));
1089 +static PyObject*
1090 +pyrbac_fgetuserattr(PyObject* self, PyObject* args) {
1091 + char* filename = NULL;
1092 + if(!PyArg_ParseTuple(args, "s:fgetuserattr", &filename))
1093 + return NULL;
1094 + return(pyrbac_getuseruidnamattr(self, NULL, PYRBAC_ATTR_MODE, filename));
1097 +static PyObject*
1098 +pyrbac_getusernam(PyObject* self, PyObject* args) {
1099 + char* name = NULL;
1100 + if(!PyArg_ParseTuple(args, "s:getusernam", &name))
1101 + return NULL;
1102 + return(pyrbac_getuseruidnamattr(self, (void*) name, PYRBAC_NAM_MODE, NULL));
1105 +static PyObject*
1106 +pyrbac_getuseruid(PyObject* self, PyObject* args) {
1107 + uid_t uid;
1108 + if(!PyArg_ParseTuple(args, "i:getuseruid", &uid))
1109 + return NULL;
1110 + return(pyrbac_getuseruidnamattr(self, (void*) &uid, PYRBAC_UID_MODE, NULL));
1113 +static PyObject*
1114 +pyrbac_userattr_next(PyObject* self, PyObject* args) {
1115 + PyObject* retval = pyrbac_getuserattr(self, args);
1116 + if( retval == Py_None ) {
1117 + setuserattr();
1118 + return NULL;
1120 + return retval;
1122 +static PyObject*
1123 +pyrbac_userattr__iter__(PyObject* self, PyObject* args) {
1124 + return self;
1127 +typedef struct {
1128 + PyObject_HEAD
1129 +} Userattr;
1131 +static void
1132 +Userattr_dealloc(Userattr* self) {
1133 + enduserattr();
1134 + Py_TYPE(self)->tp_free((PyObject*) self);
1137 +static PyObject*
1138 +Userattr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1139 + Userattr *self;
1140 + self = (Userattr*)type->tp_alloc(type, 0);
1142 + return ((PyObject *) self);
1145 +static int
1146 +Userattr_init(Userattr* self, PyObject *args, PyObject *kwargs) {
1147 + setuserattr();
1148 + return 0;
1151 +static char pyrbac_userattr__doc__[];
1152 +PyDoc_STRVAR(pyrbac_userattr__doc__, "provides functions for \
1153 +interacting with the extended user attributes database. May be iterated over \
1154 +to enumerate user_attr(4) entries\n\n\
1155 +Methods provided:\n\
1156 +setuserattr\n\
1157 +enduserattr\n\
1158 +getuserattr\n\
1159 +fgetuserattr\n\
1160 +getusernam\n\
1161 +getuseruid");
1163 +static char pyrbac_setuserattr__doc__[];
1164 +static char pyrbac_enduserattr__doc__[];
1165 +static char pyrbac_getuserattr__doc__[];
1166 +static char pyrbac_getusernam__doc__[];
1167 +static char pyrbac_getuseruid__doc__[];
1169 +PyDoc_STRVAR(pyrbac_setuserattr__doc__, "\"rewinds\" the user_attr functions \
1170 +to the first entry in the db. Called automatically by the constructor.\n\
1171 +\tArguments: None\n\
1172 +\tReturns: None");
1174 +PyDoc_STRVAR(pyrbac_enduserattr__doc__, "closes the user_attr database, \
1175 +cleans up storage. called automatically by the destructor\n\
1176 +\tArguments: None\n\
1177 +\tReturns: None");
1179 +PyDoc_STRVAR(pyrbac_getuserattr__doc__, "Return a single user_attr entry\n \
1180 +\tArguments: None\n\
1181 +\tReturns: a dict representation of a userattr_t struct:\n\
1182 +\t\t\"name\": username\n\
1183 +\t\t\"qualifier\": reserved\n\
1184 +\t\t\"res1\": reserved\n\
1185 +\t\t\"res2\": reserved\n\
1186 +\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
1187 +or a string depending on value"
1190 +PyDoc_STRVAR(pyrbac_fgetuserattr__doc__, "Return a single user_attr entry \
1191 +from a file, bypassing nsswitch.conf\n\
1192 +\tArguments: \'filename\'\n\
1193 +\tReturns: a dict representation of a userattr_t struct:\n\
1194 +\t\t\"name\": username\n\
1195 +\t\t\"qualifier\": reserved\n\
1196 +\t\t\"res1\": reserved\n\
1197 +\t\t\"res2\": reserved\n\
1198 +\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
1199 +or a string depending on value");
1201 +PyDoc_STRVAR(pyrbac_getusernam__doc__, "Searches for a user_attr entry with a \
1202 +given user name\n\
1203 +\tArgument: \'username\'\n\
1204 +\tReturns: a dict representation of a userattr_t struct:\n\
1205 +\t\t\"name\": username\n\
1206 +\t\t\"qualifier\": reserved\n\
1207 +\t\t\"res1\": reserved\n\
1208 +\t\t\"res2\": reserved\n\
1209 +\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
1210 +or a string depending on value");
1212 +PyDoc_STRVAR(pyrbac_getuseruid__doc__, "Searches for a user_attr entry with a \
1213 +given uid\n\
1214 +\tArgument: uid\n\
1215 +\tReturns: a dict representation of a userattr_t struct:\n\
1216 +\t\t\"name\": username\n\
1217 +\t\t\"qualifier\": reserved\n\
1218 +\t\t\"res1\": reserved\n\
1219 +\t\t\"res2\": reserved\n\
1220 +\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
1221 +or a string depending on value");
1223 +static PyMethodDef Userattr_methods[] = {
1224 + {"setuserattr", pyrbac_setuserattr, METH_NOARGS, pyrbac_setuserattr__doc__},
1225 + {"enduserattr", pyrbac_enduserattr, METH_NOARGS, pyrbac_enduserattr__doc__},
1226 + {"getuserattr", pyrbac_getuserattr, METH_NOARGS, pyrbac_getuserattr__doc__},
1227 + {"fgetuserattr", pyrbac_fgetuserattr, METH_VARARGS, pyrbac_fgetuserattr__doc__},
1228 + {"getusernam", pyrbac_getusernam, METH_VARARGS, pyrbac_getusernam__doc__},
1229 + {"getuseruid", pyrbac_getuseruid, METH_VARARGS, pyrbac_getuseruid__doc__},
1230 + {NULL, NULL}
1233 +PyTypeObject UserattrType = {
1234 + PyVarObject_HEAD_INIT(NULL, 0)
1235 + "rbac.userattr", /*tp_name*/
1236 + sizeof(Userattr), /*tp_basicsize*/
1237 + 0, /*tp_itemsize*/
1238 + (destructor)Userattr_dealloc, /*tp_dealloc*/
1239 + 0, /*tp_print*/
1240 + 0, /*tp_getattr*/
1241 + 0, /*tp_setattr*/
1242 + 0, /*tp_reserved*/
1243 + 0, /*tp_repr*/
1244 + 0, /*tp_as_number*/
1245 + 0, /*tp_as_sequence*/
1246 + 0, /*tp_as_mapping*/
1247 + 0, /*tp_hash */
1248 + 0, /*tp_call*/
1249 + 0, /*tp_str*/
1250 + 0, /*tp_getattro*/
1251 + 0, /*tp_setattro*/
1252 + 0, /*tp_as_buffer*/
1253 + Py_TPFLAGS_DEFAULT |
1254 + Py_TPFLAGS_BASETYPE, /*tp_flags*/
1255 + pyrbac_userattr__doc__, /* tp_doc */
1256 + 0, /* tp_traverse */
1257 + 0, /* tp_clear */
1258 + 0, /* tp_richcompare */
1259 + 0, /* tp_weaklistoffset */
1260 + pyrbac_userattr__iter__, /* tp_iter */
1261 + pyrbac_userattr_next, /* tp_iternext */
1262 + Userattr_methods, /* tp_methods */
1263 + 0, /* tp_members */
1264 + 0, /* tp_getset */
1265 + 0, /* tp_base */
1266 + 0, /* tp_dict */
1267 + 0, /* tp_descr_get */
1268 + 0, /* tp_descr_set */
1269 + 0, /* tp_dictoffset */
1270 + (initproc)Userattr_init, /* tp_init */
1271 + 0, /* tp_alloc */
1272 + Userattr_new, /* tp_new */
1273 + 0, /* tp_free */
1274 + 0, /* tp_is_gc */
1276 --- Python-3.7.4/setup.py
1277 +++ Python-3.7.4/setup.py
1278 @@ -1651,6 +1651,22 @@ class PyBuildExt(build_ext):
1279 exts.append( Extension('dlpi', ['dlpimodule.c'],
1280 libraries = ['dlpi']) )
1282 + # privileges module (Solaris)
1283 + priv_inc = find_file('priv.h', [], inc_dirs)
1284 + if priv_inc is not None:
1285 + exts.append( Extension('privileges', ['privileges.c']))
1287 + # rbac module (Solaris)
1288 + secdb_inc = find_file('secdb.h', [], inc_dirs)
1289 + aa_inc = find_file('auth_attr.h', [], inc_dirs)
1290 + ea_inc = find_file('exec_attr.h', [], inc_dirs)
1291 + ua_inc = find_file('user_attr.h', [], inc_dirs)
1292 + if secdb_inc is not None and aa_inc is not None and \
1293 + ea_inc is not None and ua_inc is not None:
1294 + exts.append( Extension('rbac', ['pyrbac.c', 'authattr.c', \
1295 + 'execattr.c', 'userattr.c'],
1296 + libraries = ['nsl', 'socket', 'secdb']) )
1298 # Thomas Heller's _ctypes module
1299 self.detect_ctypes(inc_dirs, lib_dirs)
1301 --- Python-3.7.4/Lib/test/privrbactest.py
1302 +++ Python-3.7.4/Lib/test/privrbactest.py
1303 @@ -0,0 +1,289 @@
1304 +#!/usr/bin/python3.7
1306 +# CDDL HEADER START
1308 +# The contents of this file are subject to the terms of the
1309 +# Common Development and Distribution License (the "License").
1310 +# You may not use this file except in compliance with the License.
1312 +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1313 +# or http://www.opensolaris.org/os/licensing.
1314 +# See the License for the specific language governing permissions
1315 +# and limitations under the License.
1317 +# When distributing Covered Code, include this CDDL HEADER in each
1318 +# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1319 +# If applicable, add the following below this CDDL HEADER, with the
1320 +# fields enclosed by brackets "[]" replaced with your own identifying
1321 +# information: Portions Copyright [yyyy] [name of copyright owner]
1323 +# CDDL HEADER END
1326 +# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
1328 +import privileges
1329 +import rbac
1330 +import os
1331 +import sys
1332 +import tempfile
1334 +# privileges tests
1336 +def test_setppriv():
1337 + amchild = os.fork()
1338 + if amchild == 0:
1339 + if privileges.setppriv(privileges.PRIV_OFF, privileges.PRIV_EFFECTIVE,
1340 + ['proc_fork']):
1341 + try:
1342 + os.fork()
1343 + sys.exit(1)
1344 + except OSError as e:
1345 + sys.exit(0)
1347 + child = os.wait()
1348 + if child[1] is not 0:
1349 + print("setppriv. Bad exit status from pid %i\n" % child[0])
1350 + return False
1351 + return True
1353 +def test_getppriv():
1354 + if 'proc_fork' in privileges.getppriv(privileges.PRIV_LIMIT):
1355 + return True
1356 + print("getppriv or PRIV_PROC_FORK not in PRIV_LIMIT.\n")
1357 + return False
1359 +def test_priv_ineffect():
1360 + if privileges.priv_ineffect('proc_fork'):
1361 + return True
1362 + print("priv_ineffect or PRIV_PROC_FORK not in effect\n")
1363 + return False
1365 +# authattr tests
1367 +def test_chkauthattr():
1368 + try:
1369 + a = rbac.authattr()
1370 + except Exception as e:
1371 + print("Could not instantiate authattr object: %s\n" % e)
1372 + return False
1373 + try:
1374 + res = a.chkauthattr('solaris.*', 'root')
1375 + except Exception as e:
1376 + print("chkauthattr failed: %s\n" % e)
1377 + return False
1378 + if not res:
1379 + print("chkauthattr failed or \'root\' lacks \'solaris.*\'\n")
1380 + return False
1381 + return True
1383 +def test_getauthattr():
1384 + try:
1385 + a = rbac.authattr()
1386 + except Exception as e:
1387 + print("Could not instantiate authattr object: %s\n" % e)
1388 + return False
1389 + try:
1390 + res = a.getauthattr()
1391 + except Exception as e:
1392 + print("getauthattr failed: %s\n" % e)
1393 + return False
1394 + if not 'name' in list(res.keys()):
1395 + print("getauthattr failed\n")
1396 + return False
1397 + return True
1399 +def test_getauthnam():
1400 + try:
1401 + a = rbac.authattr()
1402 + except Exception as e:
1403 + print("Could not instantiate authattr object: %s\n" % e)
1404 + return False
1405 + try:
1406 + res = a.getauthnam('solaris.')
1407 + except Exception as e:
1408 + print("getauthnam failed: %s\n" % e)
1409 + return False
1410 + if not res:
1411 + print("getauthnam failed or \'solaris.\' not in auth_attr(4)\n")
1412 + return False
1413 + return True
1415 +def test_authattr_iter():
1416 + try:
1417 + a = rbac.authattr()
1418 + except Exception as e:
1419 + print("Could not instantiate authattr object: %s\n" % e)
1420 + return False
1421 + res = next(a)
1422 + if not 'name' in list(res.keys()) or type(a) != type(a.__iter__()):
1423 + print("authattr object is not an iterable\n")
1424 + return False
1425 + return True
1427 +# execattr tests
1429 +def test_getexecattr():
1430 + try:
1431 + a = rbac.execattr()
1432 + except Exception as e:
1433 + print("Could not instantiate execattr object: %s\n" % e)
1434 + return False
1435 + try:
1436 + res = a.getexecattr()
1437 + except Exception as e:
1438 + print("getexecattr failed: %s\n" % e)
1439 + return False
1440 + if not 'name' in list(res.keys()):
1441 + print("getexecattr failed\n")
1442 + return False
1443 + return True
1445 +def test_getexecuser():
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.getexecuser("root", "act", "*;*;*;*;*")
1453 + except Exception as e:
1454 + print("getexecuser failed: %s\n" % e)
1455 + return False
1456 + if not res:
1457 + print("getexecuser failed or \'root\' not assigned to \'act\', " \
1458 + "\'*;*;*;*;*\' \n")
1459 + return False
1460 + return True
1463 +def test_getexecprof():
1464 + try:
1465 + a = rbac.execattr()
1466 + except Exception as e:
1467 + print("Could not instantiate execattr object: %s\n" % e)
1468 + return False
1469 + try:
1470 + res = a.getexecprof("All", "cmd", "*")
1471 + except Exception as e:
1472 + print("getexecprof failed: %s\n" % e)
1473 + return False
1474 + if not res:
1475 + print("getexecprof failed or \'All\' not granted \'cmd\' : \'*\'\n")
1476 + return False
1477 + return True
1479 +def test_execattr_iter():
1480 + try:
1481 + a = rbac.execattr()
1482 + except Exception as e:
1483 + print("Could not instantiate execattr object: %s\n" % e)
1484 + return False
1485 + res = next(a)
1486 + if not 'name' in list(res.keys()) or type(a) != type(a.__iter__()):
1487 + print("execattr object is not an iterable\n")
1488 + return False
1489 + return True
1491 +# userattr tests
1493 +def test_getuserattr():
1494 + try:
1495 + a = rbac.userattr()
1496 + except Exception as e:
1497 + print("Could not instantiate userattr object: %s\n" % e)
1498 + return False
1499 + try:
1500 + res = a.getuserattr()
1501 + except Exception as e:
1502 + print("getuserattr failed: %s\n" % e)
1503 + return False
1504 + if not 'name' in list(res.keys()):
1505 + print("getuserattr failed\n")
1506 + return False
1507 + return True
1509 +def test_fgetuserattr():
1510 + temp = tempfile.NamedTemporaryFile()
1511 + temp.write("user::::profiles=Software Installation;roles=foo;"\
1512 + "auths=solaris.foo.bar")
1513 + temp.seek(0)
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.fgetuserattr(temp.name)
1521 + temp.close()
1522 + except Exception as e:
1523 + print("fgetuserattr failed: %s\n" % e)
1524 + temp.close()
1525 + return False
1526 + if not 'name' in list(res.keys()):
1527 + print("fgetuserattr failed\n")
1528 + return False
1529 + return True
1531 +def test_getuseruid():
1532 + try:
1533 + a = rbac.userattr()
1534 + except Exception as e:
1535 + print("Could not instantiate userattr object: %s\n" % e)
1536 + return False
1537 + try:
1538 + res = a.getuseruid(0)
1539 + except Exception as e:
1540 + print("getusernam failed: %s\n" % e)
1541 + return False
1542 + if not 'name' in res:
1543 + print("getusernam failed or no uid 0\n")
1544 + return False
1545 + return True
1547 +def test_getusernam():
1548 + try:
1549 + a = rbac.userattr()
1550 + except Exception as e:
1551 + print("Could not instantiate userattr object: %s\n" % e)
1552 + return False
1553 + try:
1554 + res = a.getusernam('root')
1555 + except Exception as e:
1556 + print("getusernam failed: %s\n" % e)
1557 + return False
1558 + if not 'name' in res:
1559 + print("getusernam failed or no \'root\' user\n")
1560 + return False
1561 + return True
1563 +def test_userattr_iter():
1564 + try:
1565 + a = rbac.userattr()
1566 + except Exception as e:
1567 + print("Could not instantiate userattr object: %s\n" % e)
1568 + return False
1569 + res = next(a)
1570 + if not 'name' in list(res.keys()) or type(a) != type(a.__iter__()):
1571 + print("userattr object is not an iterable\n")
1572 + return False
1573 + return True
1575 +if not test_setppriv() or not test_getppriv() or not test_priv_ineffect():
1576 + print("*** Failures detected in privileges module\n")
1577 + sys.exit(1)
1579 +if not test_getauthattr() or not test_chkauthattr() or not test_getauthnam() \
1580 + or not test_authattr_iter:
1581 + print("*** Failures detected in rbac.authattr\n")
1582 + sys.exit(1)
1584 +if not test_getexecattr() or not test_getexecuser() or not test_getexecprof() \
1585 + or not test_execattr_iter():
1586 + print("*** Failures detected in rbac.execattr\n")
1587 + sys.exit(1)
1589 +if not test_getuserattr() or not test_fgetuserattr() or not test_getusernam()\
1590 + or not test_getuseruid() or not test_userattr_iter():
1591 + print("*** Failures detected in rbac.userattr\n")
1592 + sys.exit(1)