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