[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