From 814e20e7da60f0ec33dfea1d4d6dda1b653b818d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 Mar 2010 22:23:45 +0100 Subject: pynet: Create a net class. --- source4/auth/credentials/pycredentials.c | 23 +++-- source4/auth/gensec/pygensec.c | 2 +- source4/auth/pyauth.c | 7 +- source4/lib/registry/pyregistry.c | 4 +- source4/libnet/py_net.c | 152 +++++++++++++++++-------------- source4/librpc/rpc/pyrpc.c | 4 +- source4/param/provision.c | 2 +- source4/param/pyparam.h | 2 +- source4/param/pyparam_util.c | 6 +- source4/scripting/python/pyglue.c | 7 +- 10 files changed, 118 insertions(+), 91 deletions(-) diff --git a/source4/auth/credentials/pycredentials.c b/source4/auth/credentials/pycredentials.c index cd578a5c116..c5cca4fb327 100644 --- a/source4/auth/credentials/pycredentials.c +++ b/source4/auth/credentials/pycredentials.c @@ -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); diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c index 381938c25a6..2b4963c8431 100644 --- a/source4/auth/gensec/pygensec.c +++ b/source4/auth/gensec/pygensec.c @@ -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; } diff --git a/source4/auth/pyauth.c b/source4/auth/pyauth.c index f81b4495401..2563b85570b 100644 --- a/source4/auth/pyauth.c +++ b/source4/auth/pyauth.c @@ -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; diff --git a/source4/lib/registry/pyregistry.c b/source4/lib/registry/pyregistry.c index b043594042a..d4cdd895af9 100644 --- a/source4/lib/registry/pyregistry.c +++ b/source4/lib/registry/pyregistry.c @@ -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; diff --git a/source4/libnet/py_net.c b/source4/libnet/py_net.c index 7f799db5ab2..71e7cd87d68 100644 --- a/source4/libnet/py_net.c +++ b/source4/libnet/py_net.c @@ -25,31 +25,21 @@ #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); } diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c index 2398f27d4ac..9a6aa0d45af 100644 --- a/source4/librpc/rpc/pyrpc.c +++ b/source4/librpc/rpc/pyrpc.c @@ -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; diff --git a/source4/param/provision.c b/source4/param/provision.c index 9191400f59a..1e518ffe1f5 100644 --- a/source4/param/provision.c +++ b/source4/param/provision.c @@ -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; diff --git a/source4/param/pyparam.h b/source4/param/pyparam.h index 1a06730f387..4657dbafdff 100644 --- a/source4/param/pyparam.h +++ b/source4/param/pyparam.h @@ -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_ */ diff --git a/source4/param/pyparam_util.c b/source4/param/pyparam_util.c index cc84395ea01..8136746f52e 100644 --- a/source4/param/pyparam_util.c +++ b/source4/param/pyparam_util.c @@ -25,12 +25,12 @@ #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; diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c index 629c9b11e22..f0857146352 100644 --- a/source4/scripting/python/pyglue.c +++ b/source4/scripting/python/pyglue.c @@ -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); -- cgit