[SCM] Samba Shared Repository - branch master updated

Jelmer Vernooij jelmer at samba.org
Thu Apr 8 15:42:23 MDT 2010


The branch, master has been updated
       via  26d928e... s4-net: Convert 'net time' to python.
       via  0c6f434... net: Convert time command to python.
       via  6510b2c... s4-net: Use new Net() object in net export keytab.
       via  814e20e... pynet: Create a net class.
      from  7a6f1c7... s4-python: Fix formatting, use standard convention to call instance methods.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 26d928e9482725fe66db05f23af573fdea61a291
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Thu Apr 8 23:41:08 2010 +0200

    s4-net: Convert 'net time' to python.

commit 0c6f434b7bc0d9d4a8819a03815200966c92736e
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Mar 1 22:33:01 2010 +0100

    net: Convert time command to python.

commit 6510b2cdd21c473bd146b7630d69d06342801cb1
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Thu Apr 8 22:59:16 2010 +0200

    s4-net: Use new Net() object in net export keytab.

commit 814e20e7da60f0ec33dfea1d4d6dda1b653b818d
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Mar 1 22:23:45 2010 +0100

    pynet: Create a net class.

-----------------------------------------------------------------------

Summary of changes:
 source4/auth/credentials/pycredentials.c           |   23 ++-
 source4/auth/gensec/pygensec.c                     |    2 +-
 source4/auth/pyauth.c                              |    7 +-
 source4/lib/ldb-samba/pyldb.c                      |    6 +-
 source4/lib/registry/pyregistry.c                  |    4 +-
 source4/libnet/py_net.c                            |  218 ++++++++++++--------
 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 +-
 source4/scripting/python/samba/netcmd/__init__.py  |    2 +
 source4/scripting/python/samba/netcmd/export.py    |    6 +-
 .../python/samba/netcmd/{export.py => time.py}     |   30 +--
 source4/utils/net/config.mk                        |    1 -
 source4/utils/net/net.c                            |    1 -
 source4/utils/net/net_time.c                       |   78 -------
 source4/utils/net/wscript_build                    |    2 +-
 source4/utils/tests/test_net.sh                    |   10 +-
 19 files changed, 196 insertions(+), 215 deletions(-)
 copy source4/scripting/python/samba/netcmd/{export.py => time.py} (64%)
 delete mode 100644 source4/utils/net/net_time.c


Changeset truncated at 500 lines:

diff --git a/source4/auth/credentials/pycredentials.c b/source4/auth/credentials/pycredentials.c
index cd578a5..c5cca4f 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 381938c..2b4963c 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 f81b449..2563b85 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/ldb-samba/pyldb.c b/source4/lib/ldb-samba/pyldb.c
index 084afb7..2b7b237 100644
--- a/source4/lib/ldb-samba/pyldb.c
+++ b/source4/lib/ldb-samba/pyldb.c
@@ -54,14 +54,14 @@ static PyObject *py_ldb_set_loadparm(PyObject *self, PyObject *args)
 	if (!PyArg_ParseTuple(args, "O", &py_lp_ctx))
 		return NULL;
 
-	lp_ctx = lp_from_py_object(py_lp_ctx);
+	ldb = PyLdb_AsLdbContext(self);
+
+	lp_ctx = lp_from_py_object(ldb, py_lp_ctx);
 	if (lp_ctx == NULL) {
 		PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
 		return NULL;
 	}
 
-	ldb = PyLdb_AsLdbContext(self);
-
 	ldb_set_opaque(ldb, "loadparm", lp_ctx);
 
 	Py_RETURN_NONE;
diff --git a/source4/lib/registry/pyregistry.c b/source4/lib/registry/pyregistry.c
index b043594..d4cdd89 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 7f799db..d6bd134 100644
--- a/source4/libnet/py_net.c
+++ b/source4/libnet/py_net.c
@@ -1,7 +1,7 @@
 /*
    Unix SMB/CIFS implementation.
    Samba utility functions
-   Copyright (C) Jelmer Vernooij <jelmer at samba.org> 2008
+   Copyright (C) Jelmer Vernooij <jelmer at samba.org> 2008-2010
    Copyright (C) Kamen Mazdrashki <kamen.mazdrashki at postpath.com> 2009
 
    This program is free software; you can redistribute it and/or modify
@@ -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);
-
-	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;
-	}
+	mem_ctx = talloc_new(self->mem_ctx);
 
-	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);
@@ -143,46 +106,26 @@ static PyObject *py_net_set_password(PyObject *cls, PyObject *args, PyObject *kw
 static const char py_net_set_password_doc[] = "set_password(account_name, domain_name, newpassword) -> True\n\n" \
 "Set password for a user. You must supply credential with enough rights to do this.\n\n" \
 "Sample usage is:\n" \
-"creds = samba.credentials.Credentials()\n" \
-"creds.set_username('admin_user')\n" \
-"creds.set_domain('domain_name')\n" \
-"creds.set_password('pass')\n\n" \
 "net.set_password(account_name=<account_name>,\n" \
-"                domain_name=creds.get_domain(),\n" \
-"                newpassword=new_pass,\n" \
-"                credentials=creds)\n";
+"                domain_name=domain_name,\n" \
+"                newpassword=new_pass)\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;
+	const char *kwnames[] = { "keytab", NULL };
 	NTSTATUS status;
 
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO:export_keytab", discard_const_p(char *, kwnames),
-					 &r.in.keytab_name, &py_creds)) {
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:export_keytab", discard_const_p(char *, kwnames),
+					 &r.in.keytab_name)) {
 		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 +140,127 @@ 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 PyObject *py_net_time(py_net_Object *self, PyObject *args, PyObject *kwargs)
+{
+	const char *kwnames[] = { "server_name", NULL };
+	union libnet_RemoteTOD r;
+	NTSTATUS status;
+	TALLOC_CTX *mem_ctx;
+	char timestr[64];
+	PyObject *ret;
+	struct tm *tm;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s",
+		discard_const_p(char *, kwnames), &r.generic.in.server_name))
+		return NULL;
+
+	r.generic.level			= LIBNET_REMOTE_TOD_GENERIC;
+
+	mem_ctx = talloc_new(NULL);
+	if (mem_ctx == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	status = libnet_RemoteTOD(self->libnet_ctx, mem_ctx, &r);
+	if (!NT_STATUS_IS_OK(status)) {
+		PyErr_SetString(PyExc_RuntimeError, r.generic.out.error_string);
+		talloc_free(mem_ctx);
+		return NULL;
+	}
+
+	ZERO_STRUCT(timestr);
+	tm = localtime(&r.generic.out.time);
+	strftime(timestr, sizeof(timestr)-1, "%c %Z",tm);
+	
+	ret = PyString_FromString(timestr);
+
+	talloc_free(mem_ctx);
+
+	return ret;
+}
+
+static const char py_net_time_doc[] = "time(server_name) -> timestr\n"
+"Retrieve the remote time on a server";
+
+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 }
+	{"time", (PyCFunction)py_net_time, METH_VARARGS|METH_KEYWORDS, py_net_time_doc},
+	{ 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;
+
+	if (PyType_Ready(&py_net_Type) < 0)
+		return;
+
+	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 2398f27..9a6aa0d 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 9191400..1e518ff 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 1a06730..4657dba 100644


-- 
Samba Shared Repository


More information about the samba-cvs mailing list