Simplify customization of pidl-generated Python modules.
authorJelmer Vernooij <jelmer@samba.org>
Sun, 21 Dec 2008 20:10:40 +0000 (21:10 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Sun, 21 Dec 2008 20:10:40 +0000 (21:10 +0100)
pidl/lib/Parse/Pidl/Samba4/Python.pm
source4/libcli/security/dom_sid.c
source4/librpc/ndr/py_security.c
source4/scripting/python/samba/provision.py

index 69365416a5e52f9bd04ca304844414a121b8136c..73ae8350b1daae85371449f4715d843dbb775118 100644 (file)
@@ -24,7 +24,7 @@ sub new($) {
        my ($class) = @_;
        my $self = { res => "", res_hdr => "", tabs => "", constants => {},
                     module_methods => [], module_objects => [], ready_types => [],
-                                readycode => [] };
+                                patch_type_calls => [], readycode => [] };
        bless($self, $class);
 }
 
@@ -38,7 +38,9 @@ sub pidl($$)
 {
        my ($self, $d) = @_;
        if ($d) {
-               $self->{res} .= $self->{tabs};
+               if ((!($d =~ /^#/))) {
+                       $self->{res} .= $self->{tabs};
+               }
                $self->{res} .= $d;
        }
        $self->{res} .= "\n";
@@ -279,11 +281,6 @@ sub PythonStruct($$$$$$)
                $self->indent;
                $self->pidl("{ \"__ndr_pack__\", (PyCFunction)py_$name\_ndr_pack, METH_NOARGS, \"S.pack() -> blob\\nNDR pack\" },");
                $self->pidl("{ \"__ndr_unpack__\", (PyCFunction)py_$name\_ndr_unpack, METH_VARARGS, \"S.unpack(blob) -> None\\nNDR unpack\" },");
-               $self->deindent;
-               $self->pidl("#ifdef ".uc("py_$name\_extra_methods"));
-               $self->pidl("\t" .uc("py_$name\_extra_methods"));
-               $self->pidl("#endif");
-               $self->indent;
                $self->pidl("{ NULL, NULL, 0, NULL }");
                $self->deindent;
                $self->pidl("};");
@@ -294,11 +291,8 @@ sub PythonStruct($$$$$$)
        $self->pidl_hdr("#define $name\_Check(op) PyObject_TypeCheck(op, &$name\_Type)\n");
        $self->pidl_hdr("#define $name\_CheckExact(op) ((op)->ob_type == &$name\_Type)\n");
        $self->pidl_hdr("\n");
-       $self->pidl("#ifndef ".uc("py_$name\_repr"));
-       $self->pidl("#define ".uc("py_$name\_repr") . " py_talloc_default_repr");
-       $self->pidl("#endif");
        $self->pidl("");
-       my $docstring = ($self->DocString($d, $name) or "NULL");
+       my $docstring = $self->DocString($d, $name);
        my $typeobject = "$name\_Type";
        $self->pidl("PyTypeObject $typeobject = {");
        $self->indent;
@@ -307,8 +301,10 @@ sub PythonStruct($$$$$$)
        $self->pidl(".tp_basicsize = sizeof(py_talloc_Object),");
        $self->pidl(".tp_dealloc = py_talloc_dealloc,");
        $self->pidl(".tp_getset = $getsetters,");
-       $self->pidl(".tp_repr = ".uc("py_$name\_repr").",");
-       $self->pidl(".tp_doc = $docstring,");
+       $self->pidl(".tp_repr = py_talloc_default_repr,");
+       if ($docstring) {
+               $self->pidl(".tp_doc = $docstring,");
+       }
        $self->pidl(".tp_methods = $py_methods,");
        $self->pidl(".tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,");
        $self->pidl(".tp_new = py_$name\_new,");
@@ -815,6 +811,8 @@ sub register_module_typeobject($$$)
        $self->register_module_object($name, "(PyObject *)$py_name");
 
        $self->check_ready_type($py_name);
+
+       $self->register_patch_type_call($name, $py_name);
 }
 
 sub check_ready_type($$)
@@ -823,6 +821,14 @@ sub check_ready_type($$)
        push (@{$self->{ready_types}}, $py_name) unless (grep(/^$py_name$/,@{$self->{ready_types}}));
 }
 
+sub register_patch_type_call($$$)
+{
+       my ($self, $typename, $cvar) = @_;
+
+       push(@{$self->{patch_type_calls}}, [$typename, $cvar]);
+
+}
+
 sub register_module_readycode($$)
 {
        my ($self, $code) = @_;
@@ -1184,12 +1190,6 @@ sub Parse($$$$$)
                $self->pidl("{ \"$fn_name\", (PyCFunction)$pyfn_name, $flags, $doc },");
        }
 
-       $self->deindent;
-       $self->pidl("#ifdef ".uc("py_mod_$basename\_extra_methods"));
-       $self->pidl("\t" .uc("py_mod_$basename\_extra_methods"));
-       $self->pidl("#endif");
-       $self->indent;
-       
        $self->pidl("{ NULL, NULL, 0, NULL }");
        $self->deindent;
        $self->pidl("};");
@@ -1209,6 +1209,13 @@ sub Parse($$$$$)
 
        $self->pidl($_) foreach (@{$self->{readycode}});
 
+       foreach (@{$self->{patch_type_calls}}) {
+               my ($typename, $cvar) = @$_;
+               $self->pidl("#ifdef PY_".uc($typename)."_PATCH");
+               $self->pidl("PY_".uc($typename)."_PATCH($cvar);");
+               $self->pidl("#endif");
+       }
+
        $self->pidl("");
 
        $self->pidl("m = Py_InitModule3(\"$basename\", $basename\_methods, \"$basename DCE/RPC\");");
@@ -1235,6 +1242,10 @@ sub Parse($$$$$)
                $self->pidl("PyModule_AddObject(m, \"$object_name\", $c_name);");
        }
 
+       $self->pidl("#ifdef PY_MOD_".uc($basename)."_PATCH");
+       $self->pidl("PY_MOD_".uc($basename)."_PATCH(m);");
+       $self->pidl("#endif");
+
        $self->pidl("");
        $self->deindent;
        $self->pidl("}");
index 36e39679104909eaa87d8ba9f383299c386c6363..a83ebb0aa1542819f26fff3802a62be944d14813 100644 (file)
@@ -84,31 +84,26 @@ bool dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2)
        return dom_sid_compare(sid1, sid2) == 0;
 }
 
-
-/*
-  convert a string to a dom_sid, returning a talloc'd dom_sid
-*/
-struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
+bool dom_sid_parse(const char *sidstr, struct dom_sid *ret)
 {
-       struct dom_sid *ret;
        uint_t rev, ia, num_sub_auths, i;
        char *p;
   
        if (strncasecmp(sidstr, "S-", 2)) {
-               return NULL;
+               return false;
        }
 
        sidstr += 2;
 
        rev = strtol(sidstr, &p, 10);
        if (*p != '-') {
-               return NULL;
+               return false;
        }
        sidstr = p+1;
 
        ia = strtol(sidstr, &p, 10);
        if (p == sidstr) {
-               return NULL;
+               return false;
        }
        sidstr = p;
 
@@ -117,11 +112,6 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
                if (sidstr[i] == '-') num_sub_auths++;
        }
 
-       ret = talloc(mem_ctx, struct dom_sid);
-       if (!ret) {
-               return NULL;
-       }
-
        ret->sid_rev_num = rev;
        ret->id_auth[0] = 0;
        ret->id_auth[1] = 0;
@@ -133,16 +123,34 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
 
        for (i=0;i<num_sub_auths;i++) {
                if (sidstr[0] != '-') {
-                       return NULL;
+                       return false;
                }
                sidstr++;
                ret->sub_auths[i] = strtoul(sidstr, &p, 10);
                if (p == sidstr) {
-                       return NULL;
+                       return false;
                }
                sidstr = p;
        }
 
+       return true;
+}
+
+/*
+  convert a string to a dom_sid, returning a talloc'd dom_sid
+*/
+struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
+{
+       struct dom_sid *ret;
+       ret = talloc(mem_ctx, struct dom_sid);
+       if (!ret) {
+               return NULL;
+       }
+       if (!dom_sid_parse(sidstr, ret)) {
+               talloc_free(ret);
+               return NULL;
+       }
+
        return ret;
 }
 
index d79ad58f7dca518f57b69bbf3c53f96829561a57..2d01dedaecc084b8bcb3cd20c164a63e5b94fcc8 100644 (file)
 */
 #include "libcli/security/security.h"
 
+static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods)
+{
+       PyObject *dict;
+       int i;
+       if (type->tp_dict == NULL)
+               type->tp_dict = PyDict_New();
+       dict = type->tp_dict;
+       for (i = 0; methods[i].ml_name; i++) {
+               PyObject *descr = PyDescr_NewMethod(type, &methods[i]);
+               PyDict_SetItemString(dict, methods[i].ml_name, 
+                                    descr);
+       }
+}
+
 static PyObject *py_dom_sid_eq(PyObject *self, PyObject *args)
 {
        struct dom_sid *this = py_talloc_get_ptr(self), *other;
@@ -51,27 +65,37 @@ static PyObject *py_dom_sid_repr(PyObject *self)
        return ret;
 }
 
-#define PY_DOM_SID_REPR py_dom_sid_repr
-
-static PyObject *py_dom_sid_init(PyObject *self, PyObject *args)
+static int py_dom_sid_init(PyObject *self, PyObject *args, PyObject *kwargs)
 {
-       struct dom_sid *this = py_talloc_get_ptr(self);
-       char *str;
-       struct dom_sid *new_this;
+       char *str = NULL;
+       struct dom_sid *sid = py_talloc_get_ptr(self);
+       const char *kwnames[] = { "str", NULL };
 
-       if (!PyArg_ParseTuple(args, "|s", &str))
-               return NULL;
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &str))
+               return -1;
 
-       new_this = dom_sid_parse_talloc(NULL, str);
-       memcpy(this, new_this, sizeof(*new_this));
-       talloc_free(new_this);
-       return Py_None;
+       if (str != NULL && !dom_sid_parse(str, sid)) {
+               PyErr_SetString(PyExc_TypeError, "Unable to parse string");
+               return -1;
+       }
+
+       return 0;
 }
 
-#define PY_DOM_SID_EXTRA_METHODS \
+static PyMethodDef py_dom_sid_extra_methods[] = {
        { "__eq__", (PyCFunction)py_dom_sid_eq, METH_VARARGS, "S.__eq__(x) -> S == x" }, \
-       { "__str__", (PyCFunction)py_dom_sid_str, METH_NOARGS, "S.__str__() -> str(S)" }, \
-       { "__init__", (PyCFunction)py_dom_sid_init, METH_VARARGS, "S.__init__(str=None)" },
+       { NULL }
+};
+
+static void py_dom_sid_patch(PyTypeObject *type)
+{
+       type->tp_init = py_dom_sid_init;
+       type->tp_str = py_dom_sid_str;
+       type->tp_repr = py_dom_sid_repr;
+       PyType_AddMethods(type, py_dom_sid_extra_methods);
+}
+
+#define PY_DOM_SID_PATCH py_dom_sid_patch
 
 static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args)
 {
@@ -156,18 +180,28 @@ static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject
        return py_talloc_import(self, security_descriptor_initialise(NULL));
 }      
 
-#define PY_SECURITY_DESCRIPTOR_EXTRA_METHODS \
-       { "sacl_add", (PyCFunction)py_descriptor_sacl_add, METH_VARARGS, \
-               "S.sacl_add(ace) -> None\n" \
-               "Add a security ace to this security descriptor" },\
-       { "dacl_add", (PyCFunction)py_descriptor_dacl_add, METH_VARARGS, \
-               NULL }, \
-       { "dacl_del", (PyCFunction)py_descriptor_dacl_del, METH_VARARGS, \
-               NULL }, \
-       { "sacl_del", (PyCFunction)py_descriptor_sacl_del, METH_VARARGS, \
-               NULL }, \
-       { "__eq__", (PyCFunction)py_descriptor_eq, METH_VARARGS, \
+static PyMethodDef py_descriptor_extra_methods[] = {
+       { "sacl_add", (PyCFunction)py_descriptor_sacl_add, METH_VARARGS,
+               "S.sacl_add(ace) -> None\n"
+               "Add a security ace to this security descriptor" },
+       { "dacl_add", (PyCFunction)py_descriptor_dacl_add, METH_VARARGS,
                NULL },
+       { "dacl_del", (PyCFunction)py_descriptor_dacl_del, METH_VARARGS,
+               NULL },
+       { "sacl_del", (PyCFunction)py_descriptor_sacl_del, METH_VARARGS,
+               NULL },
+       { "__eq__", (PyCFunction)py_descriptor_eq, METH_VARARGS,
+               NULL },
+       { NULL }
+};
+
+static void py_descriptor_patch(PyTypeObject *type)
+{
+       type->tp_new = py_descriptor_new;
+       PyType_AddMethods(type, py_descriptor_extra_methods);
+}
+
+#define PY_DESCRIPTOR_PATCH py_descriptor_patch
 
 static PyObject *py_token_is_sid(PyObject *self, PyObject *args)
 {
@@ -251,25 +285,34 @@ static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwar
        return py_talloc_import(self, security_token_initialise(NULL));
 }      
 
-#define PY_SECURITY_TOKEN_EXTRA_METHODS \
-       { "is_sid", (PyCFunction)py_token_is_sid, METH_VARARGS, \
-               "S.is_sid(sid) -> bool\n" \
-               "Check whether this token is of the specified SID." }, \
-       { "has_sid", (PyCFunction)py_token_has_sid, METH_VARARGS, \
-               NULL }, \
-       { "is_anonymous", (PyCFunction)py_token_is_anonymous, METH_NOARGS, \
-               "S.is_anonymus() -> bool\n" \
-               "Check whether this is an anonymous token." }, \
-       { "is_system", (PyCFunction)py_token_is_system, METH_NOARGS, \
-               NULL }, \
-       { "has_builtin_administrators", (PyCFunction)py_token_has_builtin_administrators, METH_NOARGS, \
-               NULL }, \
-       { "has_nt_authenticated_users", (PyCFunction)py_token_has_nt_authenticated_users, METH_NOARGS, \
-               NULL }, \
-       { "has_privilege", (PyCFunction)py_token_has_privilege, METH_VARARGS, \
-               NULL }, \
-       { "set_privilege", (PyCFunction)py_token_set_privilege, METH_VARARGS, \
+static PyMethodDef py_token_extra_methods[] = {
+       { "is_sid", (PyCFunction)py_token_is_sid, METH_VARARGS,
+               "S.is_sid(sid) -> bool\n"
+               "Check whether this token is of the specified SID." },
+       { "has_sid", (PyCFunction)py_token_has_sid, METH_VARARGS,
+               NULL },
+       { "is_anonymous", (PyCFunction)py_token_is_anonymous, METH_NOARGS,
+               "S.is_anonymus() -> bool\n"
+               "Check whether this is an anonymous token." },
+       { "is_system", (PyCFunction)py_token_is_system, METH_NOARGS,
+               NULL },
+       { "has_builtin_administrators", (PyCFunction)py_token_has_builtin_administrators, METH_NOARGS,
+               NULL },
+       { "has_nt_authenticated_users", (PyCFunction)py_token_has_nt_authenticated_users, METH_NOARGS,
+               NULL },
+       { "has_privilege", (PyCFunction)py_token_has_privilege, METH_VARARGS,
+               NULL },
+       { "set_privilege", (PyCFunction)py_token_set_privilege, METH_VARARGS,
                NULL },
+       { NULL }
+};
+
+#define PY_TOKEN_PATCH py_token_patch
+static void py_token_patch(PyTypeObject *type)
+{
+       type->tp_new = py_token_new;
+       PyType_AddMethods(type, py_token_extra_methods);
+}
 
 static PyObject *py_privilege_name(PyObject *self, PyObject *args)
 {
@@ -306,7 +349,21 @@ static PyObject *py_random_sid(PyObject *self)
        return ret;
 }
 
-#define PY_MOD_SECURITY_EXTRA_METHODS \
-       { "random_sid", (PyCFunction)py_random_sid, METH_NOARGS, NULL }, \
-       { "privilege_id", (PyCFunction)py_privilege_id, METH_VARARGS, NULL }, \
+static PyMethodDef py_mod_security_extra_methods[] = {
+       { "random_sid", (PyCFunction)py_random_sid, METH_NOARGS, NULL },
+       { "privilege_id", (PyCFunction)py_privilege_id, METH_VARARGS, NULL },
        { "privilege_name", (PyCFunction)py_privilege_name, METH_VARARGS, NULL },
+       { NULL }
+};
+
+static void py_mod_security_patch(PyObject *m)
+{
+       int i;
+       for (i = 0; py_mod_security_extra_methods[i].ml_name; i++) {
+               PyObject *descr = PyCFunction_New(&py_mod_security_extra_methods[i], NULL);
+               PyModule_AddObject(m, py_mod_security_extra_methods[i].ml_name,
+                                  descr);
+       }
+}
+
+#define PY_MOD_SECURITY_PATCH py_mod_security_patch
index 6b3c26a11a07ad70d9b7a7c9ea07f6a5c79915a0..9cd5c0e162cf815842d639e82f1e1b40908adfdb 100644 (file)
@@ -38,7 +38,7 @@ from auth import system_session
 from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted
 from samba.samdb import SamDB
 from samba.idmap import IDmapDB
-import security
+from samba.dcerpc import security
 import urllib
 from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \
         timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE