[SSSD] [PATCH] HBAC rule validation Python bindings

Jakub Hrozek jhrozek at redhat.com
Sun Jul 31 08:24:07 UTC 2011


Second part of https://fedorahosted.org/sssd/ticket/943

Must be applied on top of Stephen's validation patch for the library
-------------- next part --------------
>From b1e4541a052562aac0e5a082f576536f8ad7da37 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Sat, 30 Jul 2011 12:57:24 +0200
Subject: [PATCH] HBAC rule validation Python bindings

https://fedorahosted.org/sssd/ticket/943
---
 src/python/pyhbac.c      |  114 ++++++++++++++++++++++++++++++++++++++++++++++
 src/tests/pyhbac-test.py |   21 ++++++++
 2 files changed, 135 insertions(+), 0 deletions(-)

diff --git a/src/python/pyhbac.c b/src/python/pyhbac.c
index 38df27e..f87ffdc 100644
--- a/src/python/pyhbac.c
+++ b/src/python/pyhbac.c
@@ -382,6 +382,7 @@ HbacRuleElement_init(HbacRuleElement *self, PyObject *args, PyObject *kwargs)
         }
 
         if (sss_python_set_add(self->category, tmp) != 0) {
+            Py_DECREF(tmp);
             return -1;
         }
     }
@@ -627,6 +628,11 @@ typedef struct {
     HbacRuleElement *srchosts;
 } HbacRuleObject;
 
+static void
+free_hbac_rule(struct hbac_rule *rule);
+static struct hbac_rule *
+HbacRule_to_native(HbacRuleObject *pyrule);
+
 static PyObject *
 HbacRule_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
@@ -891,6 +897,113 @@ HbacRule_repr(HbacRuleObject *self)
     return o;
 }
 
+static PyObject *
+str_missing_attribute(uint32_t attr)
+{
+    const char *str_attr;
+
+    switch (attr) {
+        case HBAC_RULE_ELEMENT_USERS:
+            str_attr = "users";
+            break;
+        case HBAC_RULE_ELEMENT_SERVICES:
+            str_attr = "services";
+            break;
+        case HBAC_RULE_ELEMENT_TARGETHOSTS:
+            str_attr = "targethosts";
+            break;
+        case HBAC_RULE_ELEMENT_SOURCEHOSTS:
+            str_attr = "sourcehosts";
+            break;
+        default:
+            return NULL;
+    }
+
+    return sss_python_unicode_from_string(str_attr);
+}
+
+static PyObject *
+py_hbac_rule_validate(HbacRuleObject *self, PyObject *args)
+{
+    struct hbac_rule *rule;
+    bool is_valid;
+    uint32_t missing;
+    uint32_t attr;
+    PyObject *ret = NULL;
+    PyObject *py_is_valid = NULL;
+    PyObject *py_missing = NULL;
+    PyObject *py_attr = NULL;
+
+    rule = HbacRule_to_native(self);
+    if (!rule) {
+        /* Make sure there is at least a generic exception */
+        if (!PyErr_Occurred()) {
+            PyErr_Format(PyExc_IOError,
+                         "Could not convert HbacRule to native type\n");
+        }
+        goto fail;
+    }
+
+    is_valid = hbac_rule_is_complete(rule, &missing);
+    free_hbac_rule(rule);
+
+    ret = PyTuple_New(2);
+    if (!ret) {
+        PyErr_NoMemory();
+        goto fail;
+    }
+
+    py_is_valid = PyBool_FromLong(is_valid);
+    py_missing = sss_python_set_new();
+    if (!py_missing || !py_is_valid) {
+        PyErr_NoMemory();
+        goto fail;
+    }
+
+    for (attr = HBAC_RULE_ELEMENT_USERS;
+         attr <= HBAC_RULE_ELEMENT_SOURCEHOSTS;
+         attr <<= 1) {
+        if (!(missing & attr)) continue;
+
+        py_attr = str_missing_attribute(attr);
+        if (!py_attr) {
+            PyErr_NoMemory();
+            goto fail;
+        }
+
+        if (sss_python_set_add(py_missing, py_attr) != 0) {
+            /* If the set-add succeeded, it would steal the reference */
+            Py_DECREF(py_attr);
+            goto fail;
+        }
+    }
+
+    PyTuple_SET_ITEM(ret, 0, py_is_valid);
+    PyTuple_SET_ITEM(ret, 1, py_missing);
+    return ret;
+
+fail:
+    Py_XDECREF(ret);
+    Py_XDECREF(py_missing);
+    Py_XDECREF(py_is_valid);
+    return NULL;
+}
+
+PyDoc_STRVAR(py_hbac_rule_validate__doc__,
+"validate() -> (valid, missing)\n\n"
+"Validate an HBAC rule\n"
+"Returns a tuple of (bool, set). The boolean value describes whether\n"
+"the rule is valid. If it is False, then the set contains the names of\n"
+"missing attributes\n");
+
+static PyMethodDef py_hbac_rule_methods[] = {
+    { sss_py_const_p(char, "validate"),
+      (PyCFunction) py_hbac_rule_validate,
+      METH_VARARGS, py_hbac_rule_validate__doc__,
+    },
+    { NULL, NULL, 0, NULL }        /* Sentinel */
+};
+
 PyDoc_STRVAR(HbacRuleObject_users__doc__,
 "(HbacRuleElement) Users and user groups for which this rule applies");
 PyDoc_STRVAR(HbacRuleObject_services__doc__,
@@ -959,6 +1072,7 @@ static PyTypeObject pyhbac_hbacrule_type = {
     .tp_init = (initproc) HbacRule_init,
     .tp_repr = (reprfunc) HbacRule_repr,
     .tp_members = py_hbac_rule_members,
+    .tp_methods = py_hbac_rule_methods,
     .tp_getset = py_hbac_rule_getset,
     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
     .tp_doc   = HbacRuleObject__doc__
diff --git a/src/tests/pyhbac-test.py b/src/tests/pyhbac-test.py
index b19fe58..b86de87 100755
--- a/src/tests/pyhbac-test.py
+++ b/src/tests/pyhbac-test.py
@@ -232,6 +232,27 @@ class PyHbacRuleTest(unittest.TestCase):
                                         "srchosts <category 0 names [%s] groups []>>" %
                                         (name, service, targethost, srchost))
 
+    def testValidate(self):
+        r = pyhbac.HbacRule('valid_rule')
+
+        valid, missing = r.validate()
+        self.assertEqual(valid, False)
+        self.assertItemsEqual(missing, [ u"users", u"services",
+                                         u"targethosts", u"sourcehosts" ])
+
+        r.users.names = [ "someuser" ]
+        r.services.names = [ "ssh" ]
+
+        valid, missing = r.validate()
+        self.assertEqual(valid, False)
+        self.assertItemsEqual(missing, [ u"targethosts", u"sourcehosts" ])
+
+        r.srchosts.names = [ "host1" ]
+        r.targethosts.names = [ "host2" ]
+
+        valid, missing = r.validate()
+        self.assertEqual(valid, True)
+
 class PyHbacRequestElementTest(unittest.TestCase):
     def testInstantiateEmpty(self):
         el = pyhbac.HbacRequestElement()
-- 
1.7.6



More information about the sssd-devel mailing list