pynet: Create a net class.
authorJelmer Vernooij <jelmer@samba.org>
Mon, 1 Mar 2010 21:23:45 +0000 (22:23 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Thu, 8 Apr 2010 21:22:55 +0000 (23:22 +0200)
source4/auth/credentials/pycredentials.c
source4/auth/gensec/pygensec.c
source4/auth/pyauth.c
source4/lib/registry/pyregistry.c
source4/libnet/py_net.c
source4/librpc/rpc/pyrpc.c
source4/param/provision.c
source4/param/pyparam.h
source4/param/pyparam_util.c
source4/scripting/python/pyglue.c

index cd578a5c116d29d857dc04bf9c66a9cae9142503..c5cca4fb327aa8318bbe8e74cf690fea9ff96174 100644 (file)
@@ -197,14 +197,18 @@ static PyObject *py_creds_guess(py_talloc_Object *self, PyObject *args)
 {
        PyObject *py_lp_ctx = Py_None;
        struct loadparm_context *lp_ctx;
+       struct cli_credentials *creds;
+
+       creds = PyCredentials_AsCliCredentials(self);
+
        if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
                return NULL;
 
-       lp_ctx = lp_from_py_object(py_lp_ctx);
+       lp_ctx = lp_from_py_object(NULL, py_lp_ctx); /* FIXME: leaky */
        if (lp_ctx == NULL) 
                return NULL;
 
-       cli_credentials_guess(PyCredentials_AsCliCredentials(self), lp_ctx);
+       cli_credentials_guess(creds, lp_ctx);
 
        Py_RETURN_NONE;
 }
@@ -214,14 +218,18 @@ static PyObject *py_creds_set_machine_account(py_talloc_Object *self, PyObject *
        PyObject *py_lp_ctx = Py_None;
        struct loadparm_context *lp_ctx;
        NTSTATUS status;
+       struct cli_credentials *creds;
+
+       creds = PyCredentials_AsCliCredentials(self);
+
        if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
                return NULL;
 
-       lp_ctx = lp_from_py_object(py_lp_ctx);
+       lp_ctx = lp_from_py_object(NULL, py_lp_ctx); /* FIXME: leaky */
        if (lp_ctx == NULL) 
                return NULL;
 
-       status = cli_credentials_set_machine_account(PyCredentials_AsCliCredentials(self), lp_ctx);
+       status = cli_credentials_set_machine_account(creds, lp_ctx);
        PyErr_NTSTATUS_IS_ERR_RAISE(status);
 
        Py_RETURN_NONE;
@@ -255,17 +263,20 @@ static PyObject *py_creds_get_named_ccache(py_talloc_Object *self, PyObject *arg
        struct tevent_context *event_ctx;
        int ret;
        const char *error_string;
+       struct cli_credentials *creds;
+
+       creds = PyCredentials_AsCliCredentials(self);
 
        if (!PyArg_ParseTuple(args, "|Os", &py_lp_ctx, &ccache_name))
                return NULL;
 
-       lp_ctx = lp_from_py_object(py_lp_ctx);
+       lp_ctx = lp_from_py_object(NULL, py_lp_ctx); /* FIXME: leaky */
        if (lp_ctx == NULL) 
                return NULL;
 
        event_ctx = tevent_context_init(NULL);
 
-       ret = cli_credentials_get_named_ccache(PyCredentials_AsCliCredentials(self), event_ctx, lp_ctx,
+       ret = cli_credentials_get_named_ccache(creds, event_ctx, lp_ctx,
                                               ccache_name, &ccc, &error_string);
        if (ret == 0) {
                talloc_steal(ccc, event_ctx);
index 381938c25a63124ecd8d74b8cdb949a49f34b79c..2b4963c843157c46c7bd3893c2c7e6d88bcf2edc 100644 (file)
@@ -69,7 +69,7 @@ static struct gensec_settings *settings_from_object(TALLOC_CTX *mem_ctx, PyObjec
        }
        
        s->target_hostname = PyString_AsString(py_hostname);
-       s->lp_ctx = lp_from_py_object(py_lp_ctx);
+       s->lp_ctx = lp_from_py_object(s, py_lp_ctx);
        s->iconv_convenience = py_iconv_convenience(s);
        return s;
 }
index f81b449540113908c17507216d75c71f492018f4..2563b85570b4ec50b9f0753dc3c3deb80a159230 100644 (file)
@@ -46,7 +46,7 @@ static PyObject *py_system_session(PyObject *module, PyObject *args)
        if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
                return NULL;
 
-       lp_ctx = lp_from_py_object(py_lp_ctx);
+       lp_ctx = lp_from_py_object(NULL, py_lp_ctx); /* FIXME: Leaks memory */
        if (lp_ctx == NULL)
                return NULL;
 
@@ -61,10 +61,11 @@ static PyObject *py_system_session_anon(PyObject *module, PyObject *args)
        PyObject *py_lp_ctx = Py_None;
        struct loadparm_context *lp_ctx;
        struct auth_session_info *session;
+
        if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
                return NULL;
 
-       lp_ctx = lp_from_py_object(py_lp_ctx);
+       lp_ctx = lp_from_py_object(NULL, py_lp_ctx); /* FIXME: leaks memory */
        if (lp_ctx == NULL)
                return NULL;
 
@@ -83,7 +84,7 @@ static PyObject *py_admin_session(PyObject *module, PyObject *args)
        if (!PyArg_ParseTuple(args, "OO", &py_lp_ctx, &py_sid))
                return NULL;
 
-       lp_ctx = lp_from_py_object(py_lp_ctx);
+       lp_ctx = lp_from_py_object(NULL, py_lp_ctx); /* FIXME: leaky */
        if (lp_ctx == NULL)
                return NULL;
 
index b043594042a701d0ae28563dd8be7041ad2ffb27..d4cdd895af90d1b3ddf359b9a6b1711ad56327aa 100644 (file)
@@ -276,7 +276,7 @@ static PyObject *py_open_samba(PyObject *self, PyObject *args, PyObject *kwargs)
                                         &py_credentials))
                return NULL;
 
-       lp_ctx = lp_from_py_object(py_lp_ctx);
+       lp_ctx = lp_from_py_object(NULL, py_lp_ctx); /* FIXME: leaky */
        if (lp_ctx == NULL) {
                PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
                return NULL;
@@ -347,7 +347,7 @@ static PyObject *py_open_ldb_file(PyObject *self, PyObject *args, PyObject *kwar
                                         &py_credentials, &py_lp_ctx))
                return NULL;
 
-       lp_ctx = lp_from_py_object(py_lp_ctx);
+       lp_ctx = lp_from_py_object(NULL, py_lp_ctx); /* FIXME: leaky */
        if (lp_ctx == NULL) {
                PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
                return NULL;
index 7f799db5ab2f72ae2808a3a75dd060d3acf106ca..71e7cd87d684b35cea2c0e27999da7b666875f58 100644 (file)
 #include "libcli/security/security.h"
 #include "lib/events/events.h"
 #include "param/param.h"
+#include "param/pyparam.h"
 
-/* FIXME: This prototype should be in param/pyparam.h */
-struct loadparm_context *py_default_loadparm_context(TALLOC_CTX *mem_ctx);
-
-static struct libnet_context *py_net_ctx(PyObject *obj, struct tevent_context *ev, struct cli_credentials *creds)
-{
-/* FIXME: Use obj */
-       struct libnet_context *libnet;
-       libnet = libnet_context_init(ev, py_default_loadparm_context(NULL));
-       if (!libnet) {
-               return NULL;
-       }
-       libnet->cred = creds;
-       return libnet;
-}
+typedef struct {
+       PyObject_HEAD
+       struct libnet_context *libnet_ctx;
+       TALLOC_CTX *mem_ctx;
+       struct tevent_context *ev;
+} py_net_Object;
 
-static PyObject *py_net_join(PyObject *cls, PyObject *args, PyObject *kwargs)
+static PyObject *py_net_join(py_net_Object *self, PyObject *args, PyObject *kwargs)
 {
        struct libnet_Join r;
        NTSTATUS status;
        PyObject *result;
        TALLOC_CTX *mem_ctx;
-       struct tevent_context *ev;
-       struct libnet_context *libnet_ctx;
-       struct cli_credentials *creds;
        PyObject *py_creds;     
        const char *kwnames[] = { "domain_name", "netbios_name", "join_type", "level", "credentials", NULL };
 
@@ -58,26 +48,9 @@ static PyObject *py_net_join(PyObject *cls, PyObject *args, PyObject *kwargs)
                                         &r.in.join_type, &r.in.level, &py_creds))
                return NULL;
 
-       /* FIXME: we really need to get a context from the caller or we may end
-        * up with 2 event contexts */
-       ev = s4_event_context_init(NULL);
-       mem_ctx = talloc_new(ev);
+       mem_ctx = talloc_new(self->mem_ctx);
 
-       creds = cli_credentials_from_py_object(py_creds);
-       if (creds == NULL) {
-               PyErr_SetString(PyExc_TypeError, "Expected credentials object");
-               talloc_free(mem_ctx);
-               return NULL;
-       }
-
-       libnet_ctx = py_net_ctx(cls, ev, creds);
-       if (libnet_ctx == NULL) {
-               PyErr_SetString(PyExc_RuntimeError, "Unable to initialize libnet");
-               talloc_free(mem_ctx);
-               return NULL;
-       }
-
-       status = libnet_Join(libnet_ctx, mem_ctx, &r);
+       status = libnet_Join(self->libnet_ctx, mem_ctx, &r);
        if (NT_STATUS_IS_ERR(status)) {
                PyErr_SetString(PyExc_RuntimeError, r.out.error_string);
                talloc_free(mem_ctx);
@@ -96,15 +69,13 @@ static PyObject *py_net_join(PyObject *cls, PyObject *args, PyObject *kwargs)
 static const char py_net_join_doc[] = "join(domain_name, netbios_name, join_type, level) -> (join_password, domain_sid, domain_name)\n\n" \
 "Join the domain with the specified name.";
 
-static PyObject *py_net_set_password(PyObject *cls, PyObject *args, PyObject *kwargs)
+static PyObject *py_net_set_password(py_net_Object *self, PyObject *args, PyObject *kwargs)
 {
        union libnet_SetPassword r;
        NTSTATUS status;
        PyObject *py_creds;
        TALLOC_CTX *mem_ctx;
        struct tevent_context *ev;
-       struct libnet_context *libnet_ctx;
-       struct cli_credentials *creds;
        const char *kwnames[] = { "account_name", "domain_name", "newpassword", "credentials", NULL };
 
        r.generic.level = LIBNET_SET_PASSWORD_GENERIC;
@@ -120,15 +91,7 @@ static PyObject *py_net_set_password(PyObject *cls, PyObject *args, PyObject *kw
        ev = s4_event_context_init(NULL);
        mem_ctx = talloc_new(ev);
 
-       creds = cli_credentials_from_py_object(py_creds);
-       if (creds == NULL) {
-               PyErr_SetString(PyExc_TypeError, "Expected credentials object");
-               return NULL;
-       }
-
-       libnet_ctx = py_net_ctx(cls, ev, creds);
-
-       status = libnet_SetPassword(libnet_ctx, mem_ctx, &r);
+       status = libnet_SetPassword(self->libnet_ctx, mem_ctx, &r);
        if (NT_STATUS_IS_ERR(status)) {
                PyErr_SetString(PyExc_RuntimeError, r.generic.out.error_string);
                talloc_free(mem_ctx);
@@ -153,15 +116,12 @@ static const char py_net_set_password_doc[] = "set_password(account_name, domain
 "                credentials=creds)\n";
 
 
-static PyObject *py_net_export_keytab(PyObject *cls, PyObject *args, PyObject *kwargs)
+static PyObject *py_net_export_keytab(py_net_Object *self, PyObject *args, PyObject *kwargs)
 {
        struct libnet_export_keytab r;
-       struct tevent_context *ev;
        TALLOC_CTX *mem_ctx;
        const char *kwnames[] = { "keytab", "creds", NULL };
-       struct libnet_context *libnet_ctx;
        PyObject *py_creds;
-       struct cli_credentials *creds;
        NTSTATUS status;
 
        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO:export_keytab", discard_const_p(char *, kwnames),
@@ -169,20 +129,9 @@ static PyObject *py_net_export_keytab(PyObject *cls, PyObject *args, PyObject *k
                return NULL;
        }
 
-       creds = cli_credentials_from_py_object(py_creds);
-       if (creds == NULL) {
-               PyErr_SetString(PyExc_TypeError, "Expected credentials object");
-               return NULL;
-       }
+       mem_ctx = talloc_new(self->mem_ctx);
 
-       /* FIXME: we really need to get a context from the caller or we may end
-        * up with 2 event contexts */
-       ev = s4_event_context_init(NULL);
-       mem_ctx = talloc_new(ev);
-
-       libnet_ctx = py_net_ctx(cls, ev, creds);
-
-       status = libnet_export_keytab(libnet_ctx, mem_ctx, &r);
+       status = libnet_export_keytab(self->libnet_ctx, mem_ctx, &r);
        if (NT_STATUS_IS_ERR(status)) {
                PyErr_SetString(PyExc_RuntimeError, r.out.error_string);
                talloc_free(mem_ctx);
@@ -197,14 +146,79 @@ static PyObject *py_net_export_keytab(PyObject *cls, PyObject *args, PyObject *k
 static const char py_net_export_keytab_doc[] = "export_keytab(keytab, name)\n\n"
 "Export the DC keytab to a keytab file.";
 
-static struct PyMethodDef net_methods[] = {
+static PyMethodDef net_obj_methods[] = {
        {"join", (PyCFunction)py_net_join, METH_VARARGS|METH_KEYWORDS, py_net_join_doc},
        {"set_password", (PyCFunction)py_net_set_password, METH_VARARGS|METH_KEYWORDS, py_net_set_password_doc},
        {"export_keytab", (PyCFunction)py_net_export_keytab, METH_VARARGS|METH_KEYWORDS, py_net_export_keytab_doc},
-       {NULL }
+       { NULL }
+};
+
+static void py_net_dealloc(py_net_Object *self)
+{
+       talloc_free(self->mem_ctx);
+}
+
+static PyObject *net_obj_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+       PyObject *py_creds, *py_lp = Py_None;
+       const char *kwnames[] = { "creds", "lp", NULL };
+       py_net_Object *ret;
+       struct loadparm_context *lp;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", 
+                       discard_const_p(char *, kwnames), &py_creds, &py_lp))
+               return NULL;
+
+       ret = PyObject_New(py_net_Object, type);
+       if (ret == NULL) {
+               return NULL;
+       }
+
+       /* FIXME: we really need to get a context from the caller or we may end
+        * up with 2 event contexts */
+       ret->ev = s4_event_context_init(NULL);
+       ret->mem_ctx = talloc_new(ret->ev);
+
+       lp = lp_from_py_object(ret->mem_ctx, py_lp);
+       if (lp == NULL) {
+               Py_DECREF(ret);
+               return NULL;
+       }
+
+       ret->libnet_ctx = libnet_context_init(ret->ev, lp);
+       if (ret->libnet_ctx == NULL) {
+               PyErr_SetString(PyExc_RuntimeError, "Unable to initialize net");
+               Py_DECREF(ret);
+               return NULL;
+       }
+
+       ret->libnet_ctx->cred = cli_credentials_from_py_object(py_creds);
+       if (ret->libnet_ctx->cred == NULL) {
+               PyErr_SetString(PyExc_TypeError, "Expected credentials object");
+               Py_DECREF(ret);
+               return NULL;
+       }
+
+       return (PyObject *)ret;
+}
+
+
+PyTypeObject py_net_Type = {
+       PyObject_HEAD_INIT(NULL) 0,
+       .tp_name = "net.Net",
+       .tp_basicsize = sizeof(py_net_Object),
+       .tp_dealloc = (destructor)py_net_dealloc,
+       .tp_methods = net_obj_methods,
+       .tp_new = net_obj_new,
 };
 
 void initnet(void)
 {
-       Py_InitModule3("net", net_methods, NULL);
+       PyObject *m;
+       m = Py_InitModule3("net", NULL, NULL);
+       if (m == NULL)
+               return;
+
+       Py_INCREF(&py_net_Type);
+       PyModule_AddObject(m, "Net", (PyObject *)&py_net_Type);
 }
index 2398f27d4ac683699ed689cf8f66478c33129f07..9a6aa0d45af8da3cc79ef49bb6aebf659b5c0bcf 100644 (file)
@@ -313,7 +313,7 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
                return NULL;
        }
 
-       lp_ctx = lp_from_py_object(py_lp_ctx);
+       lp_ctx = lp_from_py_object(NULL, py_lp_ctx); /* FIXME: leaky */
        if (lp_ctx == NULL) {
                PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
                return NULL;
@@ -395,7 +395,7 @@ static PyObject *dcerpc_interface_new(PyTypeObject *self, PyObject *args, PyObje
                return NULL;
        }
 
-       lp_ctx = lp_from_py_object(py_lp_ctx);
+       lp_ctx = lp_from_py_object(NULL, py_lp_ctx); /* FIXME: leaky */
        if (lp_ctx == NULL) {
                PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
                return NULL;
index 9191400f59a0232edbb77cb9437f583d8c90ede3..1e518ffe1f5a0c4931864bfa50335ae575065a00 100644 (file)
@@ -189,7 +189,7 @@ NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
        result->domaindn = talloc_strdup(mem_ctx, PyString_AsString(PyObject_GetAttrString(py_result, "domaindn")));
 
        /* FIXME paths */
-       result->lp_ctx = lp_from_py_object(PyObject_GetAttrString(py_result, "lp"));
+       result->lp_ctx = lp_from_py_object(result, PyObject_GetAttrString(py_result, "lp"));
        result->samdb = PyLdb_AsLdbContext(PyObject_GetAttrString(py_result, "samdb"));
 
        return NT_STATUS_OK;
index 1a06730f387fd16584e92f4108859e9984fdde00..4657dbafdff32dcd081528278938408ef4d73172 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "param/param.h"
 
-_PUBLIC_ struct loadparm_context *lp_from_py_object(PyObject *py_obj);
+_PUBLIC_ struct loadparm_context *lp_from_py_object(TALLOC_CTX *mem_ctx, PyObject *py_obj);
 _PUBLIC_ struct loadparm_context *py_default_loadparm_context(TALLOC_CTX *mem_ctx);
 
 #endif /* _PYPARAM_H_ */
index cc84395ea016d94b44bc1343e64e0b8082214a52..8136746f52e3bcf67fcc0c3e54b18854472e5111 100644 (file)
 
 #define PyLoadparmContext_AsLoadparmContext(obj) py_talloc_get_type(obj, struct loadparm_context)
 
-_PUBLIC_ struct loadparm_context *lp_from_py_object(PyObject *py_obj)
+_PUBLIC_ struct loadparm_context *lp_from_py_object(TALLOC_CTX *mem_ctx, PyObject *py_obj)
 {
     struct loadparm_context *lp_ctx;
 
     if (PyString_Check(py_obj)) {
-        lp_ctx = loadparm_init(NULL);
+        lp_ctx = loadparm_init(mem_ctx);
         if (!lp_load(lp_ctx, PyString_AsString(py_obj))) {
             talloc_free(lp_ctx);
                        PyErr_Format(PyExc_RuntimeError, "Unable to load %s", 
@@ -41,7 +41,7 @@ _PUBLIC_ struct loadparm_context *lp_from_py_object(PyObject *py_obj)
     }
 
     if (py_obj == Py_None) {
-        lp_ctx = loadparm_init(NULL);
+        lp_ctx = loadparm_init(mem_ctx);
                /* We're not checking that loading the file succeeded *on purpose */
         lp_load_default(lp_ctx);
         return lp_ctx;
index 629c9b11e22a11a735d92a70db8eab4457a11e40..f08571463526950402f6212a40ddd776c7610c5f 100644 (file)
@@ -206,14 +206,15 @@ static PyObject *py_interface_ips(PyObject *self, PyObject *args)
        if (!PyArg_ParseTuple(args, "Oi", &py_lp_ctx, &all_interfaces))
                return NULL;
 
-       lp_ctx = lp_from_py_object(py_lp_ctx);
+       tmp_ctx = talloc_new(NULL);
+
+       lp_ctx = lp_from_py_object(NULL, py_lp_ctx); /* FIXME: leaky */
        if (lp_ctx == NULL) {
                PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
+               talloc_free(tmp_ctx);
                return NULL;
        }
 
-       tmp_ctx = talloc_new(NULL);
-
        load_interfaces(tmp_ctx, lp_interfaces(lp_ctx), &ifaces);
 
        count = iface_count(ifaces);