Line data Source code
1 : /*
2 : Authors:
3 : Jakub Hrozek <jhrozek@redhat.com>
4 :
5 : Copyright (C) 2011 Red Hat
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <Python.h>
22 : #include <structmember.h>
23 :
24 : #include "util/util.h"
25 : #include "util/sss_python.h"
26 : #include "providers/ipa/ipa_hbac.h"
27 :
28 : #define PYTHON_MODULE_NAME "pyhbac"
29 :
30 : #ifndef PYHBAC_ENCODING
31 : #define PYHBAC_ENCODING "UTF-8"
32 : #endif
33 :
34 : #define PYHBAC_ENCODING_ERRORS "strict"
35 :
36 : #define CHECK_ATTRIBUTE_DELETE(attr, attrname) do { \
37 : if (attr == NULL) { \
38 : PyErr_Format(PyExc_TypeError, \
39 : "Cannot delete the %s attribute", \
40 : attrname); \
41 : return -1; \
42 : } \
43 : } while(0)
44 :
45 : static PyObject *PyExc_HbacError;
46 :
47 : /* ==================== Utility functions ========================*/
48 : static char *
49 174 : py_strdup(const char *string)
50 : {
51 : char *copy;
52 :
53 174 : copy = PyMem_New(char, strlen(string)+1);
54 174 : if (copy == NULL) {
55 0 : PyErr_NoMemory();
56 0 : return NULL;
57 : }
58 :
59 174 : return strcpy(copy, string);
60 : }
61 :
62 : static char *
63 4 : py_strcat_realloc(char *first, const char *second)
64 : {
65 : char *new_first;
66 4 : new_first = PyMem_Realloc(first, strlen(first) + strlen(second) + 1);
67 4 : if (new_first == NULL) {
68 0 : PyErr_NoMemory();
69 0 : return NULL;
70 : }
71 :
72 4 : return strcat(new_first, second);
73 : }
74 :
75 : static PyObject *
76 128 : get_utf8_string(PyObject *obj, const char *attrname)
77 : {
78 128 : const char *a = attrname ? attrname : "attribute";
79 128 : PyObject *obj_utf8 = NULL;
80 :
81 128 : if (PyBytes_Check(obj)) {
82 64 : obj_utf8 = obj;
83 64 : Py_INCREF(obj_utf8); /* Make sure we can DECREF later */
84 64 : } else if (PyUnicode_Check(obj)) {
85 64 : if ((obj_utf8 = PyUnicode_AsUTF8String(obj)) == NULL) {
86 0 : return NULL;
87 : }
88 : } else {
89 0 : PyErr_Format(PyExc_TypeError, "%s must be a string", a);
90 0 : return NULL;
91 : }
92 :
93 128 : return obj_utf8;
94 : }
95 :
96 : static void
97 182 : free_string_list(const char **list)
98 : {
99 : int i;
100 :
101 182 : if (!list) return;
102 :
103 246 : for (i=0; list[i]; i++) {
104 64 : PyMem_Free(discard_const_p(char, list[i]));
105 : }
106 182 : PyMem_Free(list);
107 : }
108 :
109 : static const char **
110 182 : sequence_as_string_list(PyObject *seq, const char *paramname)
111 : {
112 182 : const char *p = paramname ? paramname : "attribute values";
113 : const char **ret;
114 : PyObject *utf_item;
115 : int i;
116 : Py_ssize_t len;
117 : PyObject *item;
118 :
119 182 : if (!PySequence_Check(seq)) {
120 0 : PyErr_Format(PyExc_TypeError,
121 : "The object must be a sequence\n");
122 0 : return NULL;
123 : }
124 :
125 182 : len = PySequence_Size(seq);
126 182 : if (len == -1) return NULL;
127 :
128 182 : ret = PyMem_New(const char *, (len+1));
129 182 : if (!ret) {
130 0 : PyErr_NoMemory();
131 0 : return NULL;
132 : }
133 :
134 246 : for (i = 0; i < len; i++) {
135 64 : item = PySequence_GetItem(seq, i);
136 64 : if (item == NULL) {
137 0 : break;
138 : }
139 :
140 64 : utf_item = get_utf8_string(item, p);
141 64 : if (utf_item == NULL) {
142 0 : Py_DECREF(item);
143 0 : return NULL;
144 : }
145 :
146 64 : ret[i] = py_strdup(PyBytes_AsString(utf_item));
147 64 : Py_DECREF(utf_item);
148 64 : if (!ret[i]) {
149 0 : Py_DECREF(item);
150 0 : return NULL;
151 : }
152 64 : Py_DECREF(item);
153 : }
154 :
155 182 : ret[i] = NULL;
156 182 : return ret;
157 : }
158 :
159 : static bool
160 82 : verify_sequence(PyObject *seq, const char *attrname)
161 : {
162 82 : const char *a = attrname ? attrname : "attribute";
163 :
164 82 : if (!PySequence_Check(seq)) {
165 8 : PyErr_Format(PyExc_TypeError, "%s must be a sequence", a);
166 8 : return false;
167 : }
168 :
169 74 : return true;
170 : }
171 :
172 : static int
173 106 : pyobject_to_category(PyObject *o)
174 : {
175 : long c;
176 :
177 106 : c = PYNUMBER_ASLONG(o);
178 106 : if (c == -1 && PyErr_Occurred()) {
179 0 : PyErr_Format(PyExc_TypeError,
180 : "Invalid type for category element - must be an int\n");
181 0 : return -1;
182 : }
183 :
184 106 : switch (c) {
185 : case HBAC_CATEGORY_NULL:
186 : case HBAC_CATEGORY_ALL:
187 104 : return c;
188 : }
189 :
190 2 : PyErr_Format(PyExc_ValueError, "Invalid value %ld for category\n", c);
191 2 : return -1;
192 : }
193 :
194 : static uint32_t
195 96 : native_category(PyObject *pycat)
196 : {
197 : PyObject *iterator;
198 : PyObject *item;
199 : uint32_t cat;
200 : int ret;
201 :
202 96 : iterator = PyObject_GetIter(pycat);
203 96 : if (iterator == NULL) {
204 0 : PyErr_Format(PyExc_RuntimeError, "Cannot iterate category\n");
205 0 : return -1;
206 : }
207 :
208 96 : cat = 0;
209 292 : while ((item = PyIter_Next(iterator))) {
210 102 : ret = pyobject_to_category(item);
211 102 : Py_DECREF(item);
212 102 : if (ret == -1) {
213 2 : Py_DECREF(iterator);
214 2 : return -1;
215 : }
216 :
217 100 : cat |= ret;
218 : }
219 :
220 94 : Py_DECREF(iterator);
221 94 : return cat;
222 : }
223 :
224 : static char *
225 60 : str_concat_sequence(PyObject *seq, const char *delim)
226 : {
227 : Py_ssize_t size;
228 : Py_ssize_t i;
229 : PyObject *item;
230 60 : char *s = NULL;
231 : char *part;
232 :
233 60 : size = PySequence_Size(seq);
234 :
235 60 : if (size == 0) {
236 46 : s = py_strdup("");
237 46 : if (s == NULL) {
238 0 : return NULL;
239 : }
240 46 : return s;
241 : }
242 :
243 30 : for (i=0; i < size; i++) {
244 16 : item = PySequence_GetItem(seq, i);
245 16 : if (item == NULL) goto fail;
246 :
247 : #ifdef IS_PY3K
248 8 : part = PyUnicode_AsUTF8(item);
249 : #else
250 8 : part = PyString_AsString(item);
251 : #endif
252 :
253 16 : if (s) {
254 2 : s = py_strcat_realloc(s, delim);
255 2 : if (s == NULL) goto fail;
256 2 : s = py_strcat_realloc(s, part);
257 2 : if (s == NULL) goto fail;
258 : } else {
259 14 : s = py_strdup(part);
260 14 : if (s == NULL) goto fail;
261 : }
262 16 : Py_DECREF(item);
263 : }
264 :
265 14 : return s;
266 :
267 : fail:
268 0 : Py_XDECREF(item);
269 0 : PyMem_Free(s);
270 0 : return NULL;
271 : }
272 :
273 : /* ================= HBAC Exception handling =====================*/
274 : static void
275 0 : set_hbac_exception(PyObject *exc, struct hbac_info *error)
276 : {
277 : PyObject *obj;
278 :
279 0 : obj = Py_BuildValue(sss_py_const_p(char, "(i,s)"), error->code,
280 0 : error->rule_name ? error->rule_name : "no rule");
281 :
282 0 : PyErr_SetObject(exc, obj);
283 0 : Py_XDECREF(obj);
284 0 : }
285 :
286 : /* ==================== HBAC Rule Element ========================*/
287 : typedef struct {
288 : PyObject_HEAD
289 :
290 : PyObject *category;
291 : PyObject *names;
292 : PyObject *groups;
293 : } HbacRuleElement;
294 :
295 : static PyObject *
296 106 : HbacRuleElement_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
297 : {
298 : HbacRuleElement *self;
299 :
300 106 : self = (HbacRuleElement *) type->tp_alloc(type, 0);
301 106 : if (self == NULL) {
302 0 : PyErr_NoMemory();
303 0 : return NULL;
304 : }
305 :
306 106 : self->category = PySet_New(NULL);
307 106 : self->names = PyList_New(0);
308 106 : self->groups = PyList_New(0);
309 106 : if (!self->names || !self->groups || !self->category) {
310 0 : Py_DECREF(self);
311 0 : PyErr_NoMemory();
312 0 : return NULL;
313 : }
314 :
315 106 : return (PyObject *) self;
316 : }
317 :
318 : static int
319 92 : HbacRuleElement_clear(HbacRuleElement *self)
320 : {
321 92 : Py_CLEAR(self->names);
322 92 : Py_CLEAR(self->groups);
323 92 : Py_CLEAR(self->category);
324 92 : return 0;
325 : }
326 :
327 : static void
328 92 : HbacRuleElement_dealloc(HbacRuleElement *self)
329 : {
330 92 : HbacRuleElement_clear(self);
331 92 : Py_TYPE(self)->tp_free((PyObject*) self);
332 92 : }
333 :
334 : static int
335 56 : HbacRuleElement_traverse(HbacRuleElement *self, visitproc visit, void *arg)
336 : {
337 56 : Py_VISIT(self->groups);
338 56 : Py_VISIT(self->names);
339 56 : Py_VISIT(self->category);
340 56 : return 0;
341 : }
342 :
343 : static int
344 : hbac_rule_element_set_names(HbacRuleElement *self, PyObject *names,
345 : void *closure);
346 : static int
347 : hbac_rule_element_set_groups(HbacRuleElement *self, PyObject *groups,
348 : void *closure);
349 : static int
350 : hbac_rule_element_set_category(HbacRuleElement *self, PyObject *category,
351 : void *closure);
352 :
353 : static int
354 106 : HbacRuleElement_init(HbacRuleElement *self, PyObject *args, PyObject *kwargs)
355 : {
356 106 : const char * const kwlist[] = { "names", "groups", "category", NULL };
357 106 : PyObject *names = NULL;
358 106 : PyObject *groups = NULL;
359 106 : PyObject *category = NULL;
360 106 : PyObject *tmp = NULL;
361 :
362 106 : if (!PyArg_ParseTupleAndKeywords(args, kwargs,
363 : sss_py_const_p(char, "|OOO"),
364 : discard_const_p(char *, kwlist),
365 : &names, &groups, &category)) {
366 106 : return -1;
367 : }
368 :
369 106 : if (names) {
370 12 : if (hbac_rule_element_set_names(self, names, NULL) != 0) {
371 4 : return -1;
372 : }
373 : }
374 :
375 102 : if (groups) {
376 8 : if (hbac_rule_element_set_groups(self, groups, NULL) != 0) {
377 0 : return -1;
378 : }
379 : }
380 :
381 102 : if (category) {
382 0 : if (hbac_rule_element_set_category(self, category, NULL) != 0) {
383 0 : return -1;
384 : }
385 : } else {
386 102 : tmp = PYNUMBER_FROMLONG(HBAC_CATEGORY_NULL);
387 102 : if (!tmp) {
388 0 : return -1;
389 : }
390 :
391 102 : if (PySet_Add(self->category, tmp) != 0) {
392 0 : Py_DECREF(tmp);
393 0 : return -1;
394 : }
395 : }
396 :
397 102 : return 0;
398 : }
399 :
400 : static int
401 50 : hbac_rule_element_set_names(HbacRuleElement *self,
402 : PyObject *names,
403 : void *closure)
404 : {
405 50 : CHECK_ATTRIBUTE_DELETE(names, "names");
406 :
407 50 : if (!verify_sequence(names, "names")) {
408 4 : return -1;
409 : }
410 :
411 46 : SAFE_SET(self->names, names);
412 46 : return 0;
413 : }
414 :
415 : static PyObject *
416 20 : hbac_rule_element_get_names(HbacRuleElement *self, void *closure)
417 : {
418 20 : Py_INCREF(self->names);
419 20 : return self->names;
420 : }
421 :
422 : static int
423 16 : hbac_rule_element_set_groups(HbacRuleElement *self,
424 : PyObject *groups,
425 : void *closure)
426 : {
427 16 : CHECK_ATTRIBUTE_DELETE(groups, "groups");
428 :
429 16 : if (!verify_sequence(groups, "groups")) {
430 0 : return -1;
431 : }
432 :
433 16 : SAFE_SET(self->groups, groups);
434 16 : return 0;
435 : }
436 :
437 : static PyObject *
438 24 : hbac_rule_element_get_groups(HbacRuleElement *self, void *closure)
439 : {
440 24 : Py_INCREF(self->groups);
441 24 : return self->groups;
442 : }
443 :
444 : static int
445 10 : hbac_rule_element_set_category(HbacRuleElement *self,
446 : PyObject *category,
447 : void *closure)
448 : {
449 : PyObject *iterator;
450 : PyObject *item;
451 : int ret;
452 :
453 10 : CHECK_ATTRIBUTE_DELETE(category, "category");
454 :
455 10 : if (!PySet_Check(category)) {
456 6 : PyErr_Format(PyExc_TypeError, "The category must be a set type\n");
457 6 : return -1;
458 : }
459 :
460 : /* Check the values, too */
461 4 : iterator = PyObject_GetIter(category);
462 4 : if (iterator == NULL) {
463 0 : PyErr_Format(PyExc_RuntimeError, "Cannot iterate a set?\n");
464 0 : return -1;
465 : }
466 :
467 12 : while ((item = PyIter_Next(iterator))) {
468 4 : ret = pyobject_to_category(item);
469 4 : Py_DECREF(item);
470 4 : if (ret == -1) {
471 0 : Py_DECREF(iterator);
472 0 : return -1;
473 : }
474 : }
475 :
476 4 : SAFE_SET(self->category, category);
477 4 : Py_DECREF(iterator);
478 4 : return 0;
479 : }
480 :
481 : static PyObject *
482 20 : hbac_rule_element_get_category(HbacRuleElement *self, void *closure)
483 : {
484 20 : Py_INCREF(self->category);
485 20 : return self->category;
486 : }
487 :
488 : static PyObject *
489 20 : HbacRuleElement_repr(HbacRuleElement *self)
490 : {
491 20 : char *strnames = NULL;
492 20 : char *strgroups = NULL;
493 : uint32_t category;
494 : PyObject *o, *format, *args;
495 :
496 20 : format = PyUnicode_FromString("<category %lu names [%s] groups [%s]>");
497 20 : if (format == NULL) {
498 0 : return NULL;
499 : }
500 :
501 20 : strnames = str_concat_sequence(self->names,
502 : discard_const_p(char, ","));
503 20 : strgroups = str_concat_sequence(self->groups,
504 : discard_const_p(char, ","));
505 20 : category = native_category(self->category);
506 20 : if (strnames == NULL || strgroups == NULL || category == -1) {
507 0 : PyMem_Free(strnames);
508 0 : PyMem_Free(strgroups);
509 0 : Py_DECREF(format);
510 0 : return NULL;
511 : }
512 :
513 20 : args = Py_BuildValue(sss_py_const_p(char, "Kss"),
514 : (unsigned long long ) category,
515 : strnames, strgroups);
516 20 : if (args == NULL) {
517 0 : PyMem_Free(strnames);
518 0 : PyMem_Free(strgroups);
519 0 : Py_DECREF(format);
520 0 : return NULL;
521 : }
522 :
523 20 : o = PyUnicode_Format(format, args);
524 20 : PyMem_Free(strnames);
525 20 : PyMem_Free(strgroups);
526 20 : Py_DECREF(format);
527 20 : Py_DECREF(args);
528 20 : return o;
529 : }
530 :
531 : PyDoc_STRVAR(HbacRuleElement_names__doc__,
532 : "(sequence of strings) A list of object names this element applies to");
533 : PyDoc_STRVAR(HbacRuleElement_groups__doc__,
534 : "(sequence of strings) A list of group names this element applies to");
535 : PyDoc_STRVAR(HbacRuleElement_category__doc__,
536 : "(set) A set of categories this rule falls into");
537 :
538 : static PyGetSetDef py_hbac_rule_element_getset[] = {
539 : { discard_const_p(char, "names"),
540 : (getter) hbac_rule_element_get_names,
541 : (setter) hbac_rule_element_set_names,
542 : HbacRuleElement_names__doc__,
543 : NULL },
544 :
545 : { discard_const_p(char, "groups"),
546 : (getter) hbac_rule_element_get_groups,
547 : (setter) hbac_rule_element_set_groups,
548 : HbacRuleElement_groups__doc__,
549 : NULL },
550 :
551 : { discard_const_p(char, "category"),
552 : (getter) hbac_rule_element_get_category,
553 : (setter) hbac_rule_element_set_category,
554 : HbacRuleElement_category__doc__,
555 : NULL },
556 :
557 : { NULL, 0, 0, 0, NULL } /* Sentinel */
558 : };
559 :
560 : PyDoc_STRVAR(HbacRuleElement__doc__,
561 : "IPA HBAC Rule Element\n\n"
562 : "HbacRuleElement() -> new empty rule element\n"
563 : "HbacRuleElement([names], [groups], [category]) -> optionally, provide\n"
564 : "names and/or groups and/or category\n");
565 :
566 : static PyTypeObject pyhbac_hbacrule_element_type = {
567 : PyVarObject_HEAD_INIT(NULL, 0)
568 : .tp_name = sss_py_const_p(char, "pyhbac.HbacRuleElement"),
569 : .tp_basicsize = sizeof(HbacRuleElement),
570 : .tp_new = HbacRuleElement_new,
571 : .tp_dealloc = (destructor) HbacRuleElement_dealloc,
572 : .tp_traverse = (traverseproc) HbacRuleElement_traverse,
573 : .tp_clear = (inquiry) HbacRuleElement_clear,
574 : .tp_init = (initproc) HbacRuleElement_init,
575 : .tp_repr = (reprfunc) HbacRuleElement_repr,
576 : .tp_getset = py_hbac_rule_element_getset,
577 : .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
578 : .tp_doc = HbacRuleElement__doc__
579 : };
580 :
581 : static void
582 86 : free_hbac_rule_element(struct hbac_rule_element *el)
583 : {
584 86 : if (!el) return;
585 :
586 76 : free_string_list(el->names);
587 76 : free_string_list(el->groups);
588 76 : PyMem_Free(el);
589 : }
590 :
591 : struct hbac_rule_element *
592 80 : HbacRuleElement_to_native(HbacRuleElement *pyel)
593 : {
594 80 : struct hbac_rule_element *el = NULL;
595 :
596 : /* check the type, None would wreak havoc here because for some reason
597 : * it would pass the sequence check */
598 80 : if (!PyObject_IsInstance((PyObject *) pyel,
599 : (PyObject *) &pyhbac_hbacrule_element_type)) {
600 4 : PyErr_Format(PyExc_TypeError,
601 : "The element must be of type HbacRuleElement\n");
602 4 : goto fail;
603 : }
604 :
605 76 : el = PyMem_Malloc(sizeof(struct hbac_rule_element));
606 76 : if (!el) {
607 0 : PyErr_NoMemory();
608 0 : goto fail;
609 : }
610 :
611 76 : el->category = native_category(pyel->category);
612 76 : el->names = sequence_as_string_list(pyel->names, "names");
613 76 : el->groups = sequence_as_string_list(pyel->groups, "groups");
614 76 : if (!el->names || !el->groups || el->category == -1) {
615 : goto fail;
616 : }
617 :
618 74 : return el;
619 :
620 : fail:
621 6 : free_hbac_rule_element(el);
622 6 : return NULL;
623 : }
624 :
625 : /* ==================== HBAC Rule ========================*/
626 : typedef struct {
627 : PyObject_HEAD
628 :
629 : PyObject *name;
630 : bool enabled;
631 :
632 : HbacRuleElement *users;
633 : HbacRuleElement *services;
634 : HbacRuleElement *targethosts;
635 : HbacRuleElement *srchosts;
636 : } HbacRuleObject;
637 :
638 : static void
639 : free_hbac_rule(struct hbac_rule *rule);
640 : static struct hbac_rule *
641 : HbacRule_to_native(HbacRuleObject *pyrule);
642 :
643 : static PyObject *
644 20 : HbacRule_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
645 : {
646 : HbacRuleObject *self;
647 :
648 20 : self = (HbacRuleObject *) type->tp_alloc(type, 0);
649 20 : if (self == NULL) {
650 0 : PyErr_NoMemory();
651 0 : return NULL;
652 : }
653 :
654 20 : self->name = PyUnicode_FromString("");
655 20 : if (self->name == NULL) {
656 0 : Py_DECREF(self);
657 0 : PyErr_NoMemory();
658 0 : return NULL;
659 : }
660 :
661 20 : self->enabled = false;
662 :
663 20 : self->services = (HbacRuleElement *) HbacRuleElement_new(
664 : &pyhbac_hbacrule_element_type,
665 : NULL, NULL);
666 20 : self->users = (HbacRuleElement *) HbacRuleElement_new(
667 : &pyhbac_hbacrule_element_type,
668 : NULL, NULL);
669 20 : self->targethosts = (HbacRuleElement *) HbacRuleElement_new(
670 : &pyhbac_hbacrule_element_type,
671 : NULL, NULL);
672 20 : self->srchosts = (HbacRuleElement *) HbacRuleElement_new(
673 : &pyhbac_hbacrule_element_type,
674 : NULL, NULL);
675 40 : if (self->services == NULL || self->users == NULL ||
676 40 : self->targethosts == NULL || self->srchosts == NULL) {
677 0 : Py_XDECREF(self->services);
678 0 : Py_XDECREF(self->users);
679 0 : Py_XDECREF(self->targethosts);
680 0 : Py_XDECREF(self->srchosts);
681 0 : Py_DECREF(self->name);
682 0 : Py_DECREF(self);
683 0 : PyErr_NoMemory();
684 0 : return NULL;
685 : }
686 :
687 20 : return (PyObject *) self;
688 : }
689 :
690 : static int
691 16 : HbacRule_clear(HbacRuleObject *self)
692 : {
693 16 : Py_CLEAR(self->name);
694 16 : Py_CLEAR(self->services);
695 16 : Py_CLEAR(self->users);
696 16 : Py_CLEAR(self->targethosts);
697 16 : Py_CLEAR(self->srchosts);
698 16 : return 0;
699 : }
700 :
701 : static void
702 16 : HbacRule_dealloc(HbacRuleObject *self)
703 : {
704 16 : HbacRule_clear(self);
705 16 : Py_TYPE(self)->tp_free((PyObject*) self);
706 16 : }
707 :
708 : static int
709 16 : HbacRule_traverse(HbacRuleObject *self, visitproc visit, void *arg)
710 : {
711 16 : Py_VISIT((PyObject *) self->name);
712 16 : Py_VISIT((PyObject *) self->services);
713 16 : Py_VISIT((PyObject *) self->users);
714 16 : Py_VISIT((PyObject *) self->targethosts);
715 16 : Py_VISIT((PyObject *) self->srchosts);
716 16 : return 0;
717 : }
718 :
719 : static int
720 : hbac_rule_set_enabled(HbacRuleObject *self, PyObject *enabled, void *closure);
721 : static int
722 : hbac_rule_set_name(HbacRuleObject *self, PyObject *name, void *closure);
723 :
724 : static int
725 20 : HbacRule_init(HbacRuleObject *self, PyObject *args, PyObject *kwargs)
726 : {
727 20 : const char * const kwlist[] = { "name", "enabled", NULL };
728 20 : PyObject *name = NULL;
729 20 : PyObject *empty_tuple = NULL;
730 20 : PyObject *enabled=NULL;
731 :
732 20 : if (!PyArg_ParseTupleAndKeywords(args, kwargs,
733 : sss_py_const_p(char, "O|O"),
734 : discard_const_p(char *, kwlist),
735 : &name, &enabled)) {
736 20 : return -1;
737 : }
738 :
739 20 : if (enabled) {
740 4 : if (hbac_rule_set_enabled(self, enabled, NULL) == -1) {
741 0 : return -1;
742 : }
743 : }
744 :
745 20 : if (hbac_rule_set_name(self, name, NULL) == -1) {
746 0 : return -1;
747 : }
748 :
749 20 : empty_tuple = PyTuple_New(0);
750 20 : if (!empty_tuple) {
751 0 : return -1;
752 : }
753 :
754 40 : if (HbacRuleElement_init(self->users, empty_tuple, NULL) == -1 ||
755 40 : HbacRuleElement_init(self->services, empty_tuple, NULL) == -1 ||
756 40 : HbacRuleElement_init(self->targethosts, empty_tuple, NULL) == -1 ||
757 20 : HbacRuleElement_init(self->srchosts, empty_tuple, NULL) == -1) {
758 0 : Py_DECREF(empty_tuple);
759 0 : return -1;
760 : }
761 :
762 20 : Py_DECREF(empty_tuple);
763 20 : return 0;
764 : }
765 :
766 : static int
767 32 : hbac_rule_set_enabled(HbacRuleObject *self, PyObject *enabled, void *closure)
768 : {
769 32 : CHECK_ATTRIBUTE_DELETE(enabled, "enabled");
770 :
771 32 : if (PyBytes_Check(enabled) || PyUnicode_Check(enabled)) {
772 : PyObject *utf8_str;
773 : char *str;
774 :
775 14 : utf8_str = get_utf8_string(enabled, "enabled");
776 14 : if (!utf8_str) return -1;
777 14 : str = PyBytes_AsString(utf8_str);
778 14 : if (!str) {
779 0 : Py_DECREF(utf8_str);
780 0 : return -1;
781 : }
782 :
783 14 : if (strcasecmp(str, "true") == 0) {
784 6 : self->enabled = true;
785 8 : } else if (strcasecmp(str, "false") == 0) {
786 6 : self->enabled = false;
787 : } else {
788 2 : PyErr_Format(PyExc_ValueError,
789 : "enabled only accepts 'true' of 'false' "
790 : "string literals");
791 2 : Py_DECREF(utf8_str);
792 2 : return -1;
793 : }
794 :
795 12 : Py_DECREF(utf8_str);
796 12 : return 0;
797 18 : } else if (PyBool_Check(enabled) == true) {
798 8 : self->enabled = (enabled == Py_True);
799 8 : return 0;
800 10 : } else if (PYNUMBER_CHECK(enabled)) {
801 6 : switch(PYNUMBER_ASLONG(enabled)) {
802 : case 0:
803 2 : self->enabled = false;
804 2 : break;
805 : case 1:
806 2 : self->enabled = true;
807 2 : break;
808 : default:
809 2 : PyErr_Format(PyExc_ValueError,
810 : "enabled only accepts '0' of '1' "
811 : "integer constants");
812 2 : return -1;
813 : }
814 4 : return 0;
815 : }
816 :
817 4 : PyErr_Format(PyExc_TypeError, "enabled must be a boolean, an integer "
818 : "1 or 0 or a string constant true/false");
819 4 : return -1;
820 :
821 : }
822 :
823 : static PyObject *
824 20 : hbac_rule_get_enabled(HbacRuleObject *self, void *closure)
825 : {
826 20 : if (self->enabled) {
827 10 : Py_RETURN_TRUE;
828 : }
829 :
830 10 : Py_RETURN_FALSE;
831 : }
832 :
833 : static int
834 22 : hbac_rule_set_name(HbacRuleObject *self, PyObject *name, void *closure)
835 : {
836 22 : CHECK_ATTRIBUTE_DELETE(name, "name");
837 :
838 22 : if (!PyBytes_Check(name) && !PyUnicode_Check(name)) {
839 0 : PyErr_Format(PyExc_TypeError, "name must be a string or Unicode");
840 0 : return -1;
841 : }
842 :
843 22 : SAFE_SET(self->name, name);
844 22 : return 0;
845 : }
846 :
847 : static PyObject *
848 4 : hbac_rule_get_name(HbacRuleObject *self, void *closure)
849 : {
850 4 : if (PyUnicode_Check(self->name)) {
851 2 : Py_INCREF(self->name);
852 2 : return self->name;
853 2 : } else if (PyBytes_Check(self->name)) {
854 2 : return PyUnicode_FromEncodedObject(self->name,
855 : PYHBAC_ENCODING, PYHBAC_ENCODING_ERRORS);
856 : }
857 :
858 : /* setter does typechecking but let us be paranoid */
859 0 : PyErr_Format(PyExc_TypeError, "name must be a string or Unicode");
860 0 : return NULL;
861 : }
862 :
863 : static PyObject *
864 4 : HbacRule_repr(HbacRuleObject *self)
865 : {
866 : PyObject *users_repr;
867 : PyObject *services_repr;
868 : PyObject *targethosts_repr;
869 : PyObject *srchosts_repr;
870 : PyObject *o, *format, *args;
871 :
872 4 : format = PyUnicode_FromString("<name %s enabled %d "
873 : "users %s services %s "
874 : "targethosts %s srchosts %s>");
875 4 : if (format == NULL) {
876 0 : return NULL;
877 : }
878 :
879 4 : users_repr = HbacRuleElement_repr(self->users);
880 4 : services_repr = HbacRuleElement_repr(self->services);
881 4 : targethosts_repr = HbacRuleElement_repr(self->targethosts);
882 4 : srchosts_repr = HbacRuleElement_repr(self->srchosts);
883 4 : if (users_repr == NULL || services_repr == NULL ||
884 4 : targethosts_repr == NULL || srchosts_repr == NULL) {
885 0 : Py_XDECREF(users_repr);
886 0 : Py_XDECREF(services_repr);
887 0 : Py_XDECREF(targethosts_repr);
888 0 : Py_XDECREF(srchosts_repr);
889 0 : Py_DECREF(format);
890 0 : return NULL;
891 : }
892 :
893 4 : args = Py_BuildValue(sss_py_const_p(char, "OiOOOO"),
894 4 : self->name, self->enabled,
895 : users_repr, services_repr,
896 : targethosts_repr, srchosts_repr);
897 4 : if (args == NULL) {
898 0 : Py_DECREF(users_repr);
899 0 : Py_DECREF(services_repr);
900 0 : Py_DECREF(targethosts_repr);
901 0 : Py_DECREF(srchosts_repr);
902 0 : Py_DECREF(format);
903 0 : return NULL;
904 : }
905 :
906 4 : o = PyUnicode_Format(format, args);
907 4 : Py_DECREF(users_repr);
908 4 : Py_DECREF(services_repr);
909 4 : Py_DECREF(targethosts_repr);
910 4 : Py_DECREF(srchosts_repr);
911 4 : Py_DECREF(format);
912 4 : Py_DECREF(args);
913 4 : return o;
914 : }
915 :
916 : static PyObject *
917 6 : py_hbac_rule_validate(HbacRuleObject *self, PyObject *args)
918 : {
919 : struct hbac_rule *rule;
920 : bool is_valid;
921 : uint32_t missing;
922 : uint32_t attr;
923 6 : PyObject *ret = NULL;
924 6 : PyObject *py_is_valid = NULL;
925 6 : PyObject *py_missing = NULL;
926 6 : PyObject *py_attr = NULL;
927 :
928 6 : rule = HbacRule_to_native(self);
929 6 : if (!rule) {
930 : /* Make sure there is at least a generic exception */
931 0 : if (!PyErr_Occurred()) {
932 0 : PyErr_Format(PyExc_IOError,
933 : "Could not convert HbacRule to native type\n");
934 : }
935 0 : goto fail;
936 : }
937 :
938 6 : is_valid = hbac_rule_is_complete(rule, &missing);
939 6 : free_hbac_rule(rule);
940 :
941 6 : ret = PyTuple_New(2);
942 6 : if (!ret) {
943 0 : PyErr_NoMemory();
944 0 : goto fail;
945 : }
946 :
947 6 : py_is_valid = PyBool_FromLong(is_valid);
948 6 : py_missing = PySet_New(NULL);
949 6 : if (!py_missing || !py_is_valid) {
950 0 : PyErr_NoMemory();
951 0 : goto fail;
952 : }
953 :
954 36 : for (attr = HBAC_RULE_ELEMENT_USERS;
955 : attr <= HBAC_RULE_ELEMENT_SOURCEHOSTS;
956 24 : attr <<= 1) {
957 24 : if (!(missing & attr)) continue;
958 :
959 12 : py_attr = PYNUMBER_FROMLONG(attr);
960 12 : if (!py_attr) {
961 0 : PyErr_NoMemory();
962 0 : goto fail;
963 : }
964 :
965 12 : if (PySet_Add(py_missing, py_attr) != 0) {
966 : /* If the set-add succeeded, it would steal the reference */
967 0 : Py_DECREF(py_attr);
968 0 : goto fail;
969 : }
970 : }
971 :
972 6 : PyTuple_SET_ITEM(ret, 0, py_is_valid);
973 6 : PyTuple_SET_ITEM(ret, 1, py_missing);
974 12 : return ret;
975 :
976 : fail:
977 0 : Py_XDECREF(ret);
978 0 : Py_XDECREF(py_missing);
979 0 : Py_XDECREF(py_is_valid);
980 0 : return NULL;
981 : }
982 :
983 : PyDoc_STRVAR(py_hbac_rule_validate__doc__,
984 : "validate() -> (valid, missing)\n\n"
985 : "Validate an HBAC rule\n"
986 : "Returns a tuple of (bool, set). The boolean value describes whether\n"
987 : "the rule is valid. If it is False, then the set lists all the missing "
988 : "rule elements as HBAC_RULE_ELEMENT_* constants\n");
989 :
990 : static PyMethodDef py_hbac_rule_methods[] = {
991 : { sss_py_const_p(char, "validate"),
992 : (PyCFunction) py_hbac_rule_validate,
993 : METH_VARARGS, py_hbac_rule_validate__doc__,
994 : },
995 : { NULL, NULL, 0, NULL } /* Sentinel */
996 : };
997 :
998 : PyDoc_STRVAR(HbacRuleObject_users__doc__,
999 : "(HbacRuleElement) Users and user groups for which this rule applies");
1000 : PyDoc_STRVAR(HbacRuleObject_services__doc__,
1001 : "(HbacRuleElement) Services and service groups for which this rule applies");
1002 : PyDoc_STRVAR(HbacRuleObject_targethosts__doc__,
1003 : "(HbacRuleElement) Target hosts for which this rule applies");
1004 : PyDoc_STRVAR(HbacRuleObject_srchosts__doc__,
1005 : "(HbacRuleElement) Source hosts for which this rule applies");
1006 :
1007 : static PyMemberDef py_hbac_rule_members[] = {
1008 : { discard_const_p(char, "users"), T_OBJECT_EX,
1009 : offsetof(HbacRuleObject, users), 0,
1010 : HbacRuleObject_users__doc__ },
1011 :
1012 : { discard_const_p(char, "services"), T_OBJECT_EX,
1013 : offsetof(HbacRuleObject, services), 0,
1014 : HbacRuleObject_services__doc__ },
1015 :
1016 : { discard_const_p(char, "targethosts"), T_OBJECT_EX,
1017 : offsetof(HbacRuleObject, targethosts), 0,
1018 : HbacRuleObject_targethosts__doc__},
1019 :
1020 : { discard_const_p(char, "srchosts"), T_OBJECT_EX,
1021 : offsetof(HbacRuleObject, srchosts), 0,
1022 : HbacRuleObject_srchosts__doc__},
1023 :
1024 : { NULL, 0, 0, 0, NULL } /* Sentinel */
1025 : };
1026 :
1027 : PyDoc_STRVAR(HbacRuleObject_enabled__doc__,
1028 : "(bool) Is the rule enabled");
1029 : PyDoc_STRVAR(HbacRuleObject_name__doc__,
1030 : "(string) The name of the rule");
1031 :
1032 : static PyGetSetDef py_hbac_rule_getset[] = {
1033 : { discard_const_p(char, "enabled"),
1034 : (getter) hbac_rule_get_enabled,
1035 : (setter) hbac_rule_set_enabled,
1036 : HbacRuleObject_enabled__doc__,
1037 : NULL },
1038 :
1039 : { discard_const_p(char, "name"),
1040 : (getter) hbac_rule_get_name,
1041 : (setter) hbac_rule_set_name,
1042 : HbacRuleObject_name__doc__,
1043 : NULL },
1044 :
1045 : {NULL, 0, 0, 0, NULL} /* Sentinel */
1046 : };
1047 :
1048 : PyDoc_STRVAR(HbacRuleObject__doc__,
1049 : "IPA HBAC Rule\n\n"
1050 : "HbacRule(name, [enabled]) -> instantiate an empty rule, optionally\n"
1051 : "specify whether it is enabled. Rules are created disabled by default and\n"
1052 : "contain empty HbacRuleElement instances in services, users, targethosts\n"
1053 : "and srchosts attributes.\n");
1054 :
1055 : static PyTypeObject pyhbac_hbacrule_type = {
1056 : PyVarObject_HEAD_INIT(NULL, 0)
1057 : .tp_name = sss_py_const_p(char, "pyhbac.HbacRule"),
1058 : .tp_basicsize = sizeof(HbacRuleObject),
1059 : .tp_new = HbacRule_new,
1060 : .tp_dealloc = (destructor) HbacRule_dealloc,
1061 : .tp_traverse = (traverseproc) HbacRule_traverse,
1062 : .tp_clear = (inquiry) HbacRule_clear,
1063 : .tp_init = (initproc) HbacRule_init,
1064 : .tp_repr = (reprfunc) HbacRule_repr,
1065 : .tp_members = py_hbac_rule_members,
1066 : .tp_methods = py_hbac_rule_methods,
1067 : .tp_getset = py_hbac_rule_getset,
1068 : .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1069 : .tp_doc = HbacRuleObject__doc__
1070 : };
1071 :
1072 : static void
1073 20 : free_hbac_rule(struct hbac_rule *rule)
1074 : {
1075 20 : if (!rule) return;
1076 :
1077 20 : free_hbac_rule_element(rule->services);
1078 20 : free_hbac_rule_element(rule->users);
1079 20 : free_hbac_rule_element(rule->targethosts);
1080 20 : free_hbac_rule_element(rule->srchosts);
1081 :
1082 20 : PyMem_Free(discard_const_p(char, rule->name));
1083 20 : PyMem_Free(rule);
1084 : }
1085 :
1086 : static struct hbac_rule *
1087 20 : HbacRule_to_native(HbacRuleObject *pyrule)
1088 : {
1089 20 : struct hbac_rule *rule = NULL;
1090 : PyObject *utf_name;
1091 :
1092 20 : rule = PyMem_Malloc(sizeof(struct hbac_rule));
1093 20 : if (!rule) {
1094 0 : PyErr_NoMemory();
1095 0 : goto fail;
1096 : }
1097 :
1098 20 : if (!PyObject_IsInstance((PyObject *) pyrule,
1099 : (PyObject *) &pyhbac_hbacrule_type)) {
1100 0 : PyErr_Format(PyExc_TypeError,
1101 : "The rule must be of type HbacRule\n");
1102 0 : goto fail;
1103 : }
1104 :
1105 20 : utf_name = get_utf8_string(pyrule->name, "name");
1106 20 : if (utf_name == NULL) {
1107 0 : return NULL;
1108 : }
1109 :
1110 20 : rule->name = py_strdup(PyBytes_AsString(utf_name));
1111 20 : Py_DECREF(utf_name);
1112 20 : if (rule->name == NULL) {
1113 0 : goto fail;
1114 : }
1115 :
1116 20 : rule->services = HbacRuleElement_to_native(pyrule->services);
1117 20 : rule->users = HbacRuleElement_to_native(pyrule->users);
1118 20 : rule->targethosts = HbacRuleElement_to_native(pyrule->targethosts);
1119 20 : rule->srchosts = HbacRuleElement_to_native(pyrule->srchosts);
1120 34 : if (!rule->services || !rule->users ||
1121 28 : !rule->targethosts || !rule->srchosts) {
1122 : goto fail;
1123 : }
1124 :
1125 14 : rule->enabled = pyrule->enabled;
1126 14 : return rule;
1127 :
1128 : fail:
1129 6 : free_hbac_rule(rule);
1130 6 : return NULL;
1131 : }
1132 :
1133 : /* ==================== HBAC Request Element ========================*/
1134 : typedef struct {
1135 : PyObject_HEAD
1136 :
1137 : PyObject *name;
1138 : PyObject *groups;
1139 : } HbacRequestElement;
1140 :
1141 : static PyObject *
1142 76 : HbacRequestElement_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1143 : {
1144 : HbacRequestElement *self;
1145 :
1146 76 : self = (HbacRequestElement *) type->tp_alloc(type, 0);
1147 76 : if (self == NULL) {
1148 0 : PyErr_NoMemory();
1149 0 : return NULL;
1150 : }
1151 :
1152 76 : self->name = PyUnicode_FromString("");
1153 76 : if (self->name == NULL) {
1154 0 : PyErr_NoMemory();
1155 0 : Py_DECREF(self);
1156 0 : return NULL;
1157 : }
1158 :
1159 76 : self->groups = PyList_New(0);
1160 76 : if (self->groups == NULL) {
1161 0 : Py_DECREF(self->name);
1162 0 : Py_DECREF(self);
1163 0 : PyErr_NoMemory();
1164 0 : return NULL;
1165 : }
1166 :
1167 76 : return (PyObject *) self;
1168 : }
1169 :
1170 : static int
1171 76 : HbacRequestElement_clear(HbacRequestElement *self)
1172 : {
1173 76 : Py_CLEAR(self->name);
1174 76 : Py_CLEAR(self->groups);
1175 76 : return 0;
1176 : }
1177 :
1178 : static void
1179 76 : HbacRequestElement_dealloc(HbacRequestElement *self)
1180 : {
1181 76 : HbacRequestElement_clear(self);
1182 76 : Py_TYPE(self)->tp_free((PyObject*) self);
1183 76 : }
1184 :
1185 : static int
1186 0 : HbacRequestElement_traverse(HbacRequestElement *self,
1187 : visitproc visit, void *arg)
1188 : {
1189 0 : Py_VISIT(self->name);
1190 0 : Py_VISIT(self->groups);
1191 0 : return 0;
1192 : }
1193 :
1194 : static int
1195 : hbac_request_element_set_groups(HbacRequestElement *self,
1196 : PyObject *groups,
1197 : void *closure);
1198 : static int
1199 : hbac_request_element_set_name(HbacRequestElement *self,
1200 : PyObject *name,
1201 : void *closure);
1202 :
1203 : static int
1204 76 : HbacRequestElement_init(HbacRequestElement *self,
1205 : PyObject *args,
1206 : PyObject *kwargs)
1207 : {
1208 76 : const char * const kwlist[] = { "name", "groups", NULL };
1209 76 : PyObject *name = NULL;
1210 76 : PyObject *groups = NULL;
1211 :
1212 76 : if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1213 : sss_py_const_p(char, "|OO"),
1214 : discard_const_p(char *, kwlist),
1215 : &name, &groups)) {
1216 76 : return -1;
1217 : }
1218 :
1219 76 : if (name) {
1220 4 : if (hbac_request_element_set_name(self, name, NULL) != 0) {
1221 0 : return -1;
1222 : }
1223 : }
1224 :
1225 76 : if (groups) {
1226 8 : if (hbac_request_element_set_groups(self, groups, NULL) != 0) {
1227 4 : return -1;
1228 : }
1229 : }
1230 :
1231 72 : return 0;
1232 : }
1233 :
1234 : static int
1235 36 : hbac_request_element_set_name(HbacRequestElement *self,
1236 : PyObject *name,
1237 : void *closure)
1238 : {
1239 36 : CHECK_ATTRIBUTE_DELETE(name, "name");
1240 :
1241 36 : if (!PyBytes_Check(name) && !PyUnicode_Check(name)) {
1242 0 : PyErr_Format(PyExc_TypeError, "name must be a string or Unicode");
1243 0 : return -1;
1244 : }
1245 :
1246 36 : SAFE_SET(self->name, name);
1247 36 : return 0;
1248 : }
1249 :
1250 : static PyObject *
1251 16 : hbac_request_element_get_name(HbacRequestElement *self, void *closure)
1252 : {
1253 16 : if (PyUnicode_Check(self->name)) {
1254 11 : Py_INCREF(self->name);
1255 11 : return self->name;
1256 5 : } else if (PyBytes_Check(self->name)) {
1257 5 : return PyUnicode_FromEncodedObject(self->name,
1258 : PYHBAC_ENCODING, PYHBAC_ENCODING_ERRORS);
1259 : }
1260 :
1261 : /* setter does typechecking but let us be paranoid */
1262 0 : PyErr_Format(PyExc_TypeError, "name must be a string or Unicode");
1263 0 : return NULL;
1264 : }
1265 :
1266 : static int
1267 16 : hbac_request_element_set_groups(HbacRequestElement *self,
1268 : PyObject *groups,
1269 : void *closure)
1270 : {
1271 16 : CHECK_ATTRIBUTE_DELETE(groups, "groups");
1272 :
1273 16 : if (!verify_sequence(groups, "groups")) {
1274 4 : return -1;
1275 : }
1276 :
1277 12 : SAFE_SET(self->groups, groups);
1278 12 : return 0;
1279 : }
1280 :
1281 : static PyObject *
1282 20 : hbac_request_element_get_groups(HbacRequestElement *self, void *closure)
1283 : {
1284 20 : Py_INCREF(self->groups);
1285 20 : return self->groups;
1286 : }
1287 :
1288 : static PyObject *
1289 20 : HbacRequestElement_repr(HbacRequestElement *self)
1290 : {
1291 : char *strgroups;
1292 : PyObject *o, *format, *args;
1293 :
1294 20 : format = PyUnicode_FromString("<name %s groups [%s]>");
1295 20 : if (format == NULL) {
1296 0 : return NULL;
1297 : }
1298 :
1299 20 : strgroups = str_concat_sequence(self->groups, discard_const_p(char, ","));
1300 20 : if (strgroups == NULL) {
1301 0 : Py_DECREF(format);
1302 0 : return NULL;
1303 : }
1304 :
1305 20 : args = Py_BuildValue(sss_py_const_p(char, "Os"), self->name, strgroups);
1306 20 : if (args == NULL) {
1307 0 : PyMem_Free(strgroups);
1308 0 : Py_DECREF(format);
1309 0 : return NULL;
1310 : }
1311 :
1312 20 : o = PyUnicode_Format(format, args);
1313 20 : PyMem_Free(strgroups);
1314 20 : Py_DECREF(format);
1315 20 : Py_DECREF(args);
1316 20 : return o;
1317 : }
1318 :
1319 : PyDoc_STRVAR(HbacRequestElement_name__doc__,
1320 : "(string) An object name this element applies to");
1321 : PyDoc_STRVAR(HbacRequestElement_groups__doc__,
1322 : "(list of strings) A list of group names this element applies to");
1323 :
1324 : static PyGetSetDef py_hbac_request_element_getset[] = {
1325 : { discard_const_p(char, "name"),
1326 : (getter) hbac_request_element_get_name,
1327 : (setter) hbac_request_element_set_name,
1328 : HbacRequestElement_name__doc__,
1329 : NULL },
1330 :
1331 : { discard_const_p(char, "groups"),
1332 : (getter) hbac_request_element_get_groups,
1333 : (setter) hbac_request_element_set_groups,
1334 : HbacRequestElement_groups__doc__,
1335 : NULL },
1336 :
1337 : { NULL, 0, 0, 0, NULL } /* Sentinel */
1338 : };
1339 :
1340 : PyDoc_STRVAR(HbacRequestElement__doc__,
1341 : "IPA HBAC Request Element\n\n"
1342 : "HbacRequestElement() -> new empty request element\n"
1343 : "HbacRequestElement([name], [groups]) -> optionally, provide name and/or "
1344 : "groups\n");
1345 :
1346 : static PyTypeObject pyhbac_hbacrequest_element_type = {
1347 : PyVarObject_HEAD_INIT(NULL, 0)
1348 : .tp_name = sss_py_const_p(char, "pyhbac.HbacRequestElement"),
1349 : .tp_basicsize = sizeof(HbacRequestElement),
1350 : .tp_new = HbacRequestElement_new,
1351 : .tp_dealloc = (destructor) HbacRequestElement_dealloc,
1352 : .tp_traverse = (traverseproc) HbacRequestElement_traverse,
1353 : .tp_clear = (inquiry) HbacRequestElement_clear,
1354 : .tp_init = (initproc) HbacRequestElement_init,
1355 : .tp_repr = (reprfunc) HbacRequestElement_repr,
1356 : .tp_getset = py_hbac_request_element_getset,
1357 : .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1358 : .tp_doc = HbacRequestElement__doc__
1359 : };
1360 :
1361 : static void
1362 34 : free_hbac_request_element(struct hbac_request_element *el)
1363 : {
1364 34 : if (!el) return;
1365 :
1366 30 : PyMem_Free(discard_const_p(char, el->name));
1367 30 : free_string_list(el->groups);
1368 30 : PyMem_Free(el);
1369 : }
1370 :
1371 : static struct hbac_request_element *
1372 32 : HbacRequestElement_to_native(HbacRequestElement *pyel)
1373 : {
1374 32 : struct hbac_request_element *el = NULL;
1375 : PyObject *utf_name;
1376 :
1377 32 : if (!PyObject_IsInstance((PyObject *) pyel,
1378 : (PyObject *) &pyhbac_hbacrequest_element_type)) {
1379 2 : PyErr_Format(PyExc_TypeError,
1380 : "The element must be of type HbacRequestElement\n");
1381 2 : goto fail;
1382 : }
1383 :
1384 30 : el = PyMem_Malloc(sizeof(struct hbac_request_element));
1385 30 : if (!el) {
1386 0 : PyErr_NoMemory();
1387 0 : goto fail;
1388 : }
1389 :
1390 30 : utf_name = get_utf8_string(pyel->name, "name");
1391 30 : if (utf_name == NULL) {
1392 0 : return NULL;
1393 : }
1394 :
1395 30 : el->name = py_strdup(PyBytes_AsString(utf_name));
1396 30 : Py_DECREF(utf_name);
1397 30 : if (!el->name) {
1398 0 : goto fail;
1399 : }
1400 :
1401 30 : el->groups = sequence_as_string_list(pyel->groups, "groups");
1402 30 : if (!el->groups) {
1403 0 : goto fail;
1404 : }
1405 :
1406 30 : return el;
1407 :
1408 : fail:
1409 2 : free_hbac_request_element(el);
1410 2 : return NULL;
1411 : }
1412 :
1413 : /* ==================== HBAC Request ========================*/
1414 : typedef struct {
1415 : PyObject_HEAD
1416 :
1417 : HbacRequestElement *service;
1418 : HbacRequestElement *user;
1419 : HbacRequestElement *targethost;
1420 : HbacRequestElement *srchost;
1421 :
1422 : PyObject *rule_name;
1423 : } HbacRequest;
1424 :
1425 : static PyObject *
1426 14 : HbacRequest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1427 : {
1428 : HbacRequest *self;
1429 :
1430 14 : self = (HbacRequest *) type->tp_alloc(type, 0);
1431 14 : if (self == NULL) {
1432 0 : PyErr_NoMemory();
1433 0 : return NULL;
1434 : }
1435 :
1436 14 : self->service = (HbacRequestElement *) HbacRequestElement_new(
1437 : &pyhbac_hbacrequest_element_type,
1438 : NULL, NULL);
1439 14 : self->user = (HbacRequestElement *) HbacRequestElement_new(
1440 : &pyhbac_hbacrequest_element_type,
1441 : NULL, NULL);
1442 14 : self->targethost = (HbacRequestElement *) HbacRequestElement_new(
1443 : &pyhbac_hbacrequest_element_type,
1444 : NULL, NULL);
1445 14 : self->srchost = (HbacRequestElement *) HbacRequestElement_new(
1446 : &pyhbac_hbacrequest_element_type,
1447 : NULL, NULL);
1448 28 : if (self->service == NULL || self->user == NULL ||
1449 28 : self->targethost == NULL || self->srchost == NULL) {
1450 0 : Py_XDECREF(self->service);
1451 0 : Py_XDECREF(self->user);
1452 0 : Py_XDECREF(self->targethost);
1453 0 : Py_XDECREF(self->srchost);
1454 0 : Py_DECREF(self);
1455 0 : PyErr_NoMemory();
1456 0 : return NULL;
1457 : }
1458 :
1459 14 : return (PyObject *) self;
1460 : }
1461 :
1462 : static int
1463 14 : HbacRequest_clear(HbacRequest *self)
1464 : {
1465 14 : Py_CLEAR(self->service);
1466 14 : Py_CLEAR(self->user);
1467 14 : Py_CLEAR(self->targethost);
1468 14 : Py_CLEAR(self->srchost);
1469 14 : Py_CLEAR(self->rule_name);
1470 14 : return 0;
1471 : }
1472 :
1473 : static void
1474 14 : HbacRequest_dealloc(HbacRequest *self)
1475 : {
1476 14 : HbacRequest_clear(self);
1477 14 : Py_TYPE(self)->tp_free((PyObject*) self);
1478 14 : }
1479 :
1480 : static int
1481 0 : HbacRequest_traverse(HbacRequest *self, visitproc visit, void *arg)
1482 : {
1483 0 : Py_VISIT((PyObject *) self->service);
1484 0 : Py_VISIT((PyObject *) self->user);
1485 0 : Py_VISIT((PyObject *) self->targethost);
1486 0 : Py_VISIT((PyObject *) self->srchost);
1487 0 : return 0;
1488 : }
1489 :
1490 : static int
1491 14 : HbacRequest_init(HbacRequest *self, PyObject *args, PyObject *kwargs)
1492 : {
1493 14 : PyObject *empty_tuple = NULL;
1494 :
1495 14 : empty_tuple = PyTuple_New(0);
1496 14 : if (!empty_tuple) {
1497 0 : PyErr_NoMemory();
1498 0 : return -1;
1499 : }
1500 :
1501 14 : self->rule_name = NULL;
1502 :
1503 28 : if (HbacRequestElement_init(self->user, empty_tuple, NULL) == -1 ||
1504 28 : HbacRequestElement_init(self->service, empty_tuple, NULL) == -1 ||
1505 28 : HbacRequestElement_init(self->targethost, empty_tuple, NULL) == -1 ||
1506 14 : HbacRequestElement_init(self->srchost, empty_tuple, NULL) == -1) {
1507 0 : Py_DECREF(empty_tuple);
1508 0 : return -1;
1509 : }
1510 :
1511 14 : Py_DECREF(empty_tuple);
1512 14 : return 0;
1513 : }
1514 :
1515 : PyDoc_STRVAR(py_hbac_evaluate__doc__,
1516 : "evaluate(rules) -> int\n\n"
1517 : "Evaluate a set of HBAC rules.\n"
1518 : "rules is a sequence of HbacRule objects. The returned value describes\n"
1519 : "the result of evaluation and will have one of HBAC_EVAL_* values.\n"
1520 : "Use hbac_result_string() to get textual representation of the result\n"
1521 : "On error, HbacError exception is raised.\n"
1522 : "If HBAC_EVAL_ALLOW is returned, the class attribute rule_name would\n"
1523 : "contain the name of the rule that matched. Otherwise, the attribute\n"
1524 : "contains None\n");
1525 :
1526 : static struct hbac_eval_req *
1527 : HbacRequest_to_native(HbacRequest *pyreq);
1528 :
1529 : static void
1530 14 : free_hbac_rule_list(struct hbac_rule **rules)
1531 : {
1532 : int i;
1533 :
1534 14 : if (!rules) return;
1535 :
1536 22 : for(i=0; rules[i]; i++) {
1537 8 : free_hbac_rule(rules[i]);
1538 : }
1539 14 : PyMem_Free(rules);
1540 : }
1541 :
1542 : static void
1543 : free_hbac_eval_req(struct hbac_eval_req *req);
1544 :
1545 : static PyObject *
1546 14 : py_hbac_evaluate(HbacRequest *self, PyObject *args)
1547 : {
1548 14 : PyObject *py_rules_list = NULL;
1549 14 : PyObject *py_rule = NULL;
1550 : Py_ssize_t num_rules;
1551 14 : struct hbac_rule **rules = NULL;
1552 14 : struct hbac_eval_req *hbac_req = NULL;
1553 : enum hbac_eval_result eres;
1554 14 : struct hbac_info *info = NULL;
1555 14 : PyObject *ret = NULL;
1556 : long i;
1557 :
1558 14 : if (!PyArg_ParseTuple(args, sss_py_const_p(char, "O"), &py_rules_list)) {
1559 0 : goto fail;
1560 : }
1561 :
1562 14 : if (!PySequence_Check(py_rules_list)) {
1563 0 : PyErr_Format(PyExc_TypeError,
1564 : "The parameter rules must be a sequence\n");
1565 0 : goto fail;
1566 : }
1567 :
1568 14 : num_rules = PySequence_Size(py_rules_list);
1569 14 : rules = PyMem_New(struct hbac_rule *, num_rules+1);
1570 14 : if (!rules) {
1571 0 : PyErr_NoMemory();
1572 0 : goto fail;
1573 : }
1574 :
1575 22 : for (i=0; i < num_rules; i++) {
1576 14 : py_rule = PySequence_GetItem(py_rules_list, i);
1577 :
1578 14 : if (!PyObject_IsInstance(py_rule,
1579 : (PyObject *) &pyhbac_hbacrule_type)) {
1580 0 : PyErr_Format(PyExc_TypeError,
1581 : "A rule must be of type HbacRule\n");
1582 0 : goto fail;
1583 : }
1584 :
1585 14 : rules[i] = HbacRule_to_native((HbacRuleObject *) py_rule);
1586 14 : if (!rules[i]) {
1587 : /* Make sure there is at least a generic exception */
1588 6 : if (!PyErr_Occurred()) {
1589 0 : PyErr_Format(PyExc_IOError,
1590 : "Could not convert HbacRule to native type\n");
1591 : }
1592 6 : goto fail;
1593 : }
1594 : }
1595 8 : rules[num_rules] = NULL;
1596 :
1597 8 : hbac_req = HbacRequest_to_native(self);
1598 8 : if (!hbac_req) {
1599 2 : if (!PyErr_Occurred()) {
1600 0 : PyErr_Format(PyExc_IOError,
1601 : "Could not convert HbacRequest to native type\n");
1602 : }
1603 2 : goto fail;
1604 : }
1605 :
1606 6 : Py_XDECREF(self->rule_name);
1607 6 : self->rule_name = NULL;
1608 :
1609 6 : eres = hbac_evaluate(rules, hbac_req, &info);
1610 6 : switch (eres) {
1611 : case HBAC_EVAL_ALLOW:
1612 4 : self->rule_name = PyUnicode_FromString(info->rule_name);
1613 4 : if (!self->rule_name) {
1614 0 : PyErr_NoMemory();
1615 0 : goto fail;
1616 : }
1617 : /* FALLTHROUGH */
1618 : case HBAC_EVAL_DENY:
1619 6 : ret = PYNUMBER_FROMLONG(eres);
1620 6 : break;
1621 : case HBAC_EVAL_ERROR:
1622 0 : set_hbac_exception(PyExc_HbacError, info);
1623 0 : goto fail;
1624 : case HBAC_EVAL_OOM:
1625 0 : PyErr_NoMemory();
1626 0 : goto fail;
1627 : }
1628 :
1629 6 : free_hbac_eval_req(hbac_req);
1630 6 : free_hbac_rule_list(rules);
1631 6 : hbac_free_info(info);
1632 20 : return ret;
1633 :
1634 : fail:
1635 8 : hbac_free_info(info);
1636 8 : free_hbac_eval_req(hbac_req);
1637 8 : free_hbac_rule_list(rules);
1638 8 : return NULL;
1639 : }
1640 :
1641 : static PyObject *
1642 6 : hbac_request_element_get_rule_name(HbacRequest *self, void *closure)
1643 : {
1644 6 : if (self->rule_name == NULL) {
1645 4 : Py_INCREF(Py_None);
1646 4 : return Py_None;
1647 2 : } else if (PyUnicode_Check(self->rule_name)) {
1648 2 : Py_INCREF(self->rule_name);
1649 2 : return self->rule_name;
1650 : }
1651 :
1652 0 : PyErr_Format(PyExc_TypeError, "rule_name is not Unicode");
1653 0 : return NULL;
1654 : }
1655 :
1656 : static PyObject *
1657 4 : HbacRequest_repr(HbacRequest *self)
1658 : {
1659 : PyObject *user_repr;
1660 : PyObject *service_repr;
1661 : PyObject *targethost_repr;
1662 : PyObject *srchost_repr;
1663 : PyObject *o, *format, *args;
1664 :
1665 4 : format = PyUnicode_FromString("<user %s service %s "
1666 : "targethost %s srchost %s>");
1667 4 : if (format == NULL) {
1668 0 : return NULL;
1669 : }
1670 :
1671 4 : user_repr = HbacRequestElement_repr(self->user);
1672 4 : service_repr = HbacRequestElement_repr(self->service);
1673 4 : targethost_repr = HbacRequestElement_repr(self->targethost);
1674 4 : srchost_repr = HbacRequestElement_repr(self->srchost);
1675 4 : if (user_repr == NULL || service_repr == NULL ||
1676 4 : targethost_repr == NULL || srchost_repr == NULL) {
1677 0 : Py_XDECREF(user_repr);
1678 0 : Py_XDECREF(service_repr);
1679 0 : Py_XDECREF(targethost_repr);
1680 0 : Py_XDECREF(srchost_repr);
1681 0 : Py_DECREF(format);
1682 0 : return NULL;
1683 : }
1684 :
1685 4 : args = Py_BuildValue(sss_py_const_p(char, "OOOO"),
1686 : user_repr, service_repr,
1687 : targethost_repr, srchost_repr);
1688 4 : if (args == NULL) {
1689 0 : Py_DECREF(user_repr);
1690 0 : Py_DECREF(service_repr);
1691 0 : Py_DECREF(targethost_repr);
1692 0 : Py_DECREF(srchost_repr);
1693 0 : Py_DECREF(format);
1694 0 : return NULL;
1695 : }
1696 :
1697 4 : o = PyUnicode_Format(format, args);
1698 4 : Py_DECREF(user_repr);
1699 4 : Py_DECREF(service_repr);
1700 4 : Py_DECREF(targethost_repr);
1701 4 : Py_DECREF(srchost_repr);
1702 4 : Py_DECREF(format);
1703 4 : Py_DECREF(args);
1704 4 : return o;
1705 : }
1706 :
1707 : static PyMethodDef py_hbac_request_methods[] = {
1708 : { sss_py_const_p(char, "evaluate"),
1709 : (PyCFunction) py_hbac_evaluate,
1710 : METH_VARARGS, py_hbac_evaluate__doc__
1711 : },
1712 : { NULL, NULL, 0, NULL } /* Sentinel */
1713 : };
1714 :
1715 : PyDoc_STRVAR(HbacRequest_service__doc__,
1716 : "(HbacRequestElement) This is a list of service DNs to check, it must\n"
1717 : "consist of the actual service requested, as well as all parent groups\n"
1718 : "containing that service");
1719 : PyDoc_STRVAR(HbacRequest_user__doc__,
1720 : "(HbacRequestElement) This is a list of user DNs to check, it must consist\n"
1721 : "of the actual user requested, as well as all parent groups containing\n"
1722 : "that user.");
1723 : PyDoc_STRVAR(HbacRequest_targethost__doc__,
1724 : "(HbacRequestElement) This is a list of target hosts to check, it must\n"
1725 : "consist of the actual target host requested, as well as all parent groups\n"
1726 : "containing that target host.");
1727 : PyDoc_STRVAR(HbacRequest_srchost__doc__,
1728 : "(HbacRequestElement) This is a list of source hosts to check, it must\n"
1729 : "consist of the actual source host requested, as well as all parent groups\n"
1730 : "containing that source host.");
1731 :
1732 : static PyMemberDef py_hbac_request_members[] = {
1733 : { discard_const_p(char, "service"), T_OBJECT_EX,
1734 : offsetof(HbacRequest, service), 0,
1735 : HbacRequest_service__doc__ },
1736 :
1737 : { discard_const_p(char, "user"), T_OBJECT_EX,
1738 : offsetof(HbacRequest, user), 0,
1739 : HbacRequest_user__doc__ },
1740 :
1741 : { discard_const_p(char, "targethost"), T_OBJECT_EX,
1742 : offsetof(HbacRequest, targethost), 0,
1743 : HbacRequest_targethost__doc__ },
1744 :
1745 : { discard_const_p(char, "srchost"), T_OBJECT_EX,
1746 : offsetof(HbacRequest, srchost), 0,
1747 : HbacRequest_srchost__doc__ },
1748 :
1749 : { NULL, 0, 0, 0, NULL } /* Sentinel */
1750 : };
1751 :
1752 : PyDoc_STRVAR(HbacRequest_rule_name__doc__,
1753 : "(string) If result of evaluation was to allow access, this member contains\n"
1754 : "the name of the rule that allowed it. Otherwise, this attribute contains \n"
1755 : "None. This attribute is read-only.\n");
1756 :
1757 : static PyGetSetDef py_hbac_request_getset[] = {
1758 : { discard_const_p(char, "rule_name"),
1759 : (getter) hbac_request_element_get_rule_name,
1760 : NULL, /* read only */
1761 : HbacRequest_rule_name__doc__,
1762 : NULL },
1763 :
1764 : { NULL, 0, 0, 0, NULL } /* Sentinel */
1765 : };
1766 :
1767 : PyDoc_STRVAR(HbacRequest__doc__,
1768 : "IPA HBAC Request\n\n"
1769 : "HbacRequest() -> new empty HBAC request");
1770 :
1771 : static PyTypeObject pyhbac_hbacrequest_type = {
1772 : PyVarObject_HEAD_INIT(NULL, 0)
1773 : .tp_name = sss_py_const_p(char, "pyhbac.HbacRequest"),
1774 : .tp_basicsize = sizeof(HbacRequest),
1775 : .tp_new = HbacRequest_new,
1776 : .tp_dealloc = (destructor) HbacRequest_dealloc,
1777 : .tp_traverse = (traverseproc) HbacRequest_traverse,
1778 : .tp_clear = (inquiry) HbacRequest_clear,
1779 : .tp_init = (initproc) HbacRequest_init,
1780 : .tp_repr = (reprfunc) HbacRequest_repr,
1781 : .tp_methods = py_hbac_request_methods,
1782 : .tp_members = py_hbac_request_members,
1783 : .tp_getset = py_hbac_request_getset,
1784 : .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
1785 : .tp_doc = HbacRequest__doc__
1786 : };
1787 :
1788 : static void
1789 16 : free_hbac_eval_req(struct hbac_eval_req *req)
1790 : {
1791 16 : if (!req) return;
1792 :
1793 8 : free_hbac_request_element(req->service);
1794 8 : free_hbac_request_element(req->user);
1795 8 : free_hbac_request_element(req->targethost);
1796 8 : free_hbac_request_element(req->srchost);
1797 :
1798 8 : PyMem_Free(req);
1799 : }
1800 :
1801 : static struct hbac_eval_req *
1802 8 : HbacRequest_to_native(HbacRequest *pyreq)
1803 : {
1804 8 : struct hbac_eval_req *req = NULL;
1805 :
1806 8 : req = PyMem_Malloc(sizeof(struct hbac_eval_req));
1807 8 : if (!req) {
1808 0 : PyErr_NoMemory();
1809 0 : goto fail;
1810 : }
1811 :
1812 8 : if (!PyObject_IsInstance((PyObject *) pyreq,
1813 : (PyObject *) &pyhbac_hbacrequest_type)) {
1814 0 : PyErr_Format(PyExc_TypeError,
1815 : "The request must be of type HbacRequest\n");
1816 0 : goto fail;
1817 : }
1818 :
1819 8 : req->service = HbacRequestElement_to_native(pyreq->service);
1820 8 : req->user = HbacRequestElement_to_native(pyreq->user);
1821 8 : req->targethost = HbacRequestElement_to_native(pyreq->targethost);
1822 8 : req->srchost = HbacRequestElement_to_native(pyreq->srchost);
1823 14 : if (!req->service || !req->user ||
1824 12 : !req->targethost || !req->srchost) {
1825 : goto fail;
1826 : }
1827 6 : return req;
1828 :
1829 : fail:
1830 2 : free_hbac_eval_req(req);
1831 2 : return NULL;
1832 : }
1833 :
1834 : /* =================== the pyhbac module initialization =====================*/
1835 : PyDoc_STRVAR(py_hbac_result_string__doc__,
1836 : "hbac_result_string(code) -> string\n"
1837 : "Returns a string representation of the HBAC result code");
1838 :
1839 : static PyObject *
1840 6 : py_hbac_result_string(PyObject *module, PyObject *args)
1841 : {
1842 : enum hbac_eval_result result;
1843 : const char *str;
1844 :
1845 6 : if (!PyArg_ParseTuple(args, sss_py_const_p(char, "i"), &result)) {
1846 6 : return NULL;
1847 : }
1848 :
1849 6 : str = hbac_result_string(result);
1850 6 : if (str == NULL) {
1851 : /* None needs to be referenced, too */
1852 0 : Py_INCREF(Py_None);
1853 0 : return Py_None;
1854 : }
1855 :
1856 6 : return PyUnicode_FromString(str);
1857 : }
1858 :
1859 : PyDoc_STRVAR(py_hbac_error_string__doc__,
1860 : "hbac_error_string(code) -> string\n"
1861 : "Returns a string representation of the HBAC error code");
1862 :
1863 : static PyObject *
1864 10 : py_hbac_error_string(PyObject *module, PyObject *args)
1865 : {
1866 : enum hbac_error_code code;
1867 : const char *str;
1868 :
1869 10 : if (!PyArg_ParseTuple(args, sss_py_const_p(char, "i"), &code)) {
1870 10 : return NULL;
1871 : }
1872 :
1873 10 : str = hbac_error_string(code);
1874 10 : if (str == NULL) {
1875 : /* None needs to be referenced, too */
1876 0 : Py_INCREF(Py_None);
1877 0 : return Py_None;
1878 : }
1879 :
1880 10 : return PyUnicode_FromString(str);
1881 : }
1882 :
1883 : static PyMethodDef pyhbac_module_methods[] = {
1884 : { sss_py_const_p(char, "hbac_result_string"),
1885 : (PyCFunction) py_hbac_result_string,
1886 : METH_VARARGS,
1887 : py_hbac_result_string__doc__,
1888 : },
1889 :
1890 : { sss_py_const_p(char, "hbac_error_string"),
1891 : (PyCFunction) py_hbac_error_string,
1892 : METH_VARARGS,
1893 : py_hbac_error_string__doc__,
1894 : },
1895 :
1896 : {NULL, NULL, 0, NULL} /* Sentinel */
1897 : };
1898 :
1899 : PyDoc_STRVAR(HbacError__doc__,
1900 : "An HBAC processing exception\n\n"
1901 : "This exception is raised when there is an internal error during the\n"
1902 : "HBAC processing, such as an Out-Of-Memory situation or unparseable\n"
1903 : "rule. HbacError.args argument is a tuple that contains error code and\n"
1904 : "the name of the rule that was being processed. Use hbac_error_string()\n"
1905 : "to get the text representation of the HBAC error");
1906 :
1907 : #ifdef IS_PY3K
1908 : static struct PyModuleDef pyhbacdef = {
1909 : PyModuleDef_HEAD_INIT,
1910 : PYTHON_MODULE_NAME,
1911 : NULL,
1912 : -1,
1913 : pyhbac_module_methods,
1914 : NULL,
1915 : NULL,
1916 : NULL,
1917 : NULL
1918 : };
1919 :
1920 : PyMODINIT_FUNC
1921 1 : PyInit_pyhbac(void)
1922 : #else
1923 : PyMODINIT_FUNC
1924 1 : initpyhbac(void)
1925 : #endif
1926 : {
1927 : PyObject *m;
1928 : int ret;
1929 :
1930 : #ifdef IS_PY3K
1931 1 : m = PyModule_Create(&pyhbacdef);
1932 : #else
1933 1 : m = Py_InitModule(sss_py_const_p(char, PYTHON_MODULE_NAME),
1934 : pyhbac_module_methods);
1935 : #endif
1936 2 : if (m == NULL) MODINITERROR;
1937 :
1938 : /* The HBAC module exception */
1939 2 : PyExc_HbacError = sss_exception_with_doc(
1940 : discard_const_p(char, "hbac.HbacError"),
1941 : HbacError__doc__,
1942 : PyExc_EnvironmentError, NULL);
1943 2 : Py_INCREF(PyExc_HbacError);
1944 2 : ret = PyModule_AddObject(m, sss_py_const_p(char, "HbacError"), PyExc_HbacError);
1945 2 : if (ret == -1) MODINITERROR;
1946 :
1947 : /* HBAC rule categories */
1948 2 : ret = PyModule_AddIntMacro(m, HBAC_CATEGORY_NULL);
1949 2 : if (ret == -1) MODINITERROR;
1950 2 : ret = PyModule_AddIntMacro(m, HBAC_CATEGORY_ALL);
1951 2 : if (ret == -1) MODINITERROR;
1952 :
1953 : /* HBAC rule elements */
1954 2 : ret = PyModule_AddIntMacro(m, HBAC_RULE_ELEMENT_USERS);
1955 2 : if (ret == -1) MODINITERROR;
1956 2 : ret = PyModule_AddIntMacro(m, HBAC_RULE_ELEMENT_SERVICES);
1957 2 : if (ret == -1) MODINITERROR;
1958 2 : ret = PyModule_AddIntMacro(m, HBAC_RULE_ELEMENT_TARGETHOSTS);
1959 2 : if (ret == -1) MODINITERROR;
1960 2 : ret = PyModule_AddIntMacro(m, HBAC_RULE_ELEMENT_SOURCEHOSTS);
1961 2 : if (ret == -1) MODINITERROR;
1962 :
1963 : /* enum hbac_eval_result */
1964 2 : ret = PyModule_AddIntMacro(m, HBAC_EVAL_ALLOW);
1965 2 : if (ret == -1) MODINITERROR;
1966 2 : ret = PyModule_AddIntMacro(m, HBAC_EVAL_DENY);
1967 2 : if (ret == -1) MODINITERROR;
1968 2 : ret = PyModule_AddIntMacro(m, HBAC_EVAL_ERROR);
1969 2 : if (ret == -1) MODINITERROR;
1970 :
1971 : /* enum hbac_error_code */
1972 2 : ret = PyModule_AddIntMacro(m, HBAC_ERROR_UNKNOWN);
1973 2 : if (ret == -1) MODINITERROR;
1974 2 : ret = PyModule_AddIntMacro(m, HBAC_SUCCESS);
1975 2 : if (ret == -1) MODINITERROR;
1976 2 : ret = PyModule_AddIntMacro(m, HBAC_ERROR_NOT_IMPLEMENTED);
1977 2 : if (ret == -1) MODINITERROR;
1978 2 : ret = PyModule_AddIntMacro(m, HBAC_ERROR_OUT_OF_MEMORY);
1979 2 : if (ret == -1) MODINITERROR;
1980 2 : ret = PyModule_AddIntMacro(m, HBAC_ERROR_UNPARSEABLE_RULE);
1981 2 : if (ret == -1) MODINITERROR;
1982 :
1983 2 : TYPE_READY(m, pyhbac_hbacrule_type, "HbacRule");
1984 2 : TYPE_READY(m, pyhbac_hbacrule_element_type, "HbacRuleElement");
1985 2 : TYPE_READY(m, pyhbac_hbacrequest_element_type, "HbacRequestElement");
1986 2 : TYPE_READY(m, pyhbac_hbacrequest_type, "HbacRequest");
1987 :
1988 : #ifdef IS_PY3K
1989 1 : return m;
1990 : #endif
1991 : }
|