From 3b16c532f21202696d54ef87f8fa74d066812898 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 05:16:51 +0100 Subject: pidl/python: Pass credentials and loadparm context when connecting using DCE/RPC. (This used to be commit 4c87af95310e4aaee3f2e2da02d0ea70ed1ec25b) --- source4/auth/credentials/credentials.i | 17 +++++++ source4/auth/credentials/credentials_wrap.c | 16 ++++++ source4/foo.py | 7 ++- source4/param/param.i | 12 +++++ source4/param/param_wrap.c | 11 ++++ source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 59 ++++++++++++++++++---- .../scripting/python/samba/tests/dcerpc/rpcecho.py | 13 +++-- 7 files changed, 118 insertions(+), 17 deletions(-) diff --git a/source4/auth/credentials/credentials.i b/source4/auth/credentials/credentials.i index 8f09ff4b18..ee09b43a75 100644 --- a/source4/auth/credentials/credentials.i +++ b/source4/auth/credentials/credentials.i @@ -95,3 +95,20 @@ typedef struct cli_credentials { bool wrong_password(void); } } cli_credentials; + +%{ +struct cli_credentials *cli_credentials_from_py_object(PyObject *py_obj) +{ + struct cli_credentials *ret; + + if (py_obj == Py_None) { + return cli_credentials_init_anon(NULL); + } + + if (SWIG_ConvertPtr(py_obj, (void *)&ret, SWIGTYPE_p_cli_credentials, 0 | 0 ) < 0) { + return NULL; + } + return ret; +} + +%} diff --git a/source4/auth/credentials/credentials_wrap.c b/source4/auth/credentials/credentials_wrap.c index ebf7162c5b..146a81abaf 100644 --- a/source4/auth/credentials/credentials_wrap.c +++ b/source4/auth/credentials/credentials_wrap.c @@ -2774,6 +2774,22 @@ SWIGINTERNINLINE PyObject* } SWIGINTERN void delete_cli_credentials(cli_credentials *self){ talloc_free(self); } + +struct cli_credentials *cli_credentials_from_py_object(PyObject *py_obj) +{ + struct cli_credentials *ret; + + if (py_obj == Py_None) { + return cli_credentials_init_anon(NULL); + } + + if (SWIG_ConvertPtr(py_obj, (void *)&ret, SWIGTYPE_p_cli_credentials, 0 | 0 ) < 0) { + return NULL; + } + return ret; +} + + #ifdef __cplusplus extern "C" { #endif diff --git a/source4/foo.py b/source4/foo.py index 0e2d35f080..21a422ce01 100644 --- a/source4/foo.py +++ b/source4/foo.py @@ -18,5 +18,10 @@ # from echo import rpcecho +from param import LoadParm -x = rpcecho("ncalrpc:") +lp = LoadParm() +lp.load("st/client/client.conf") + +x = rpcecho("ncalrpc:", lp) +print x.AddOne(41) diff --git a/source4/param/param.i b/source4/param/param.i index 353fa3ced6..fdc9de233f 100644 --- a/source4/param/param.i +++ b/source4/param/param.i @@ -290,3 +290,15 @@ typedef struct param_section { %rename(default_config) global_loadparm; struct loadparm_context *global_loadparm; + +%{ + +struct loadparm_context *lp_from_py_object(PyObject *py_obj) +{ + struct loadparm_context *lp_ctx; + if (SWIG_ConvertPtr(py_obj, &lp_ctx, SWIGTYPE_p_loadparm_context, 0 | 0 ) < 0) + return NULL; + return lp_ctx; +} + +%} diff --git a/source4/param/param_wrap.c b/source4/param/param_wrap.c index ca9fbb77b8..e9fe8a3df5 100644 --- a/source4/param/param_wrap.c +++ b/source4/param/param_wrap.c @@ -2760,6 +2760,17 @@ SWIGINTERN char const *param_opt___str__(param_opt *self){ return self->value; } SWIGINTERN void delete_param_opt(param_opt *self){ talloc_free(self); } SWIGINTERN struct param_opt *param_section_first_parameter(param_section *self){ return self->parameters; } SWIGINTERN struct param_opt *param_section_next_parameter(param_section *self,struct param_opt *s){ return s->next; } + + +struct loadparm_context *lp_from_py_object(PyObject *py_obj) +{ + struct loadparm_context *lp_ctx; + if (SWIG_ConvertPtr(py_obj, &lp_ctx, SWIGTYPE_p_loadparm_context, 0 | 0 ) < 0) + return NULL; + return lp_ctx; +} + + #ifdef __cplusplus extern "C" { #endif diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 266a092788..04649d3668 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -264,7 +264,7 @@ sub PythonFunction($$$) $self->pidl("NTSTATUS status;"); $self->pidl("TALLOC_CTX *mem_ctx = talloc_new(NULL);"); $self->pidl("struct $fn->{NAME} r;"); - $self->pidl("PyObject *result;"); + $self->pidl("PyObject *result = Py_None;"); my $env = GenerateFunctionInEnv($fn, "r."); my $result_size = 0; @@ -313,21 +313,33 @@ sub PythonFunction($$$) $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);"); $self->handle_ntstatus("status", "NULL", "mem_ctx"); - $self->pidl("result = PyTuple_New($result_size);"); - $env = GenerateFunctionOutEnv($fn, "r."); my $i = 0; + if ($result_size > 1) { + $self->pidl("result = PyTuple_New($result_size);"); + } + foreach my $e (@{$fn->{ELEMENTS}}) { + my $py_name = "py_$e->{NAME}"; if (grep(/out/,@{$e->{DIRECTION}})) { - $self->ConvertObjectToPython($env, $e, "r.out.$e->{NAME}", "py_$e->{NAME}"); - $self->pidl("PyTuple_SetItem(result, $i, py_$e->{NAME});"); - $i++; + $self->ConvertObjectToPython($env, $e, "r.out.$e->{NAME}", $py_name); + if ($result_size > 1) { + $self->pidl("PyTuple_SetItem(result, $i, $py_name);"); + $i++; + } else { + $self->pidl("result = $py_name;"); + } } } if (defined($fn->{RETURN_TYPE})) { - $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPythonData($fn->{RETURN_TYPE}, "r.out.result") . ");"); + my $conv = $self->ConvertObjectToPythonData($fn->{RETURN_TYPE}, "r.out.result"); + if ($result_size > 1) { + $self->pidl("PyTuple_SetItem(result, $i, $conv);"); + } else { + $self->pidl("result = $conv;"); + } } $self->pidl("talloc_free(mem_ctx);"); @@ -446,6 +458,7 @@ sub Interface($$$) my $fn_name = $d->{NAME}; $fn_name =~ s/^$interface->{NAME}_//; + $fn_name =~ s/^$basename\_//; $self->pidl("{ \"$fn_name\", (PyCFunction)py_$d->{NAME}, METH_VARARGS|METH_KEYWORDS, NULL },"); } @@ -491,25 +504,47 @@ sub Interface($$$) $self->indent; $self->pidl("$interface->{NAME}_InterfaceObject *ret;"); $self->pidl("const char *binding_string;"); - $self->pidl("struct cli_credentials *credentials = NULL;"); + $self->pidl("struct cli_credentials *credentials;"); $self->pidl("struct loadparm_context *lp_ctx = NULL;"); + $self->pidl("PyObject *py_lp_ctx = NULL, *py_credentials = Py_None;"); $self->pidl("TALLOC_CTX *mem_ctx = NULL;"); $self->pidl("NTSTATUS status;"); $self->pidl(""); $self->pidl("const char *kwnames[] = {"); $self->indent; - $self->pidl("\"binding\", NULL"); + $self->pidl("\"binding\", \"lp_ctx\", \"credentials\", NULL"); $self->deindent; $self->pidl("};"); + $self->pidl("extern struct loadparm_context *lp_from_py_object(PyObject *py_obj);"); + $self->pidl("extern struct cli_credentials *cli_credentials_from_py_object(PyObject *py_obj);"); + $self->pidl(""); + $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"sO|O:$interface->{NAME}\", discard_const_p(char *, kwnames), &binding_string, &py_lp_ctx, &py_credentials)) {"); + $self->indent; + $self->pidl("return NULL;"); + $self->deindent; + $self->pidl("}"); $self->pidl(""); - $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"s:$interface->{NAME}\", discard_const_p(char *, kwnames), &binding_string)) {"); + $self->pidl("if (py_lp_ctx != NULL) {"); + $self->indent; + $self->pidl("lp_ctx = lp_from_py_object(py_lp_ctx);"); + $self->pidl("if (lp_ctx == NULL) {"); $self->indent; + $self->pidl("PyErr_SetString(PyExc_TypeError, \"Expected loadparm context\");"); $self->pidl("return NULL;"); $self->deindent; $self->pidl("}"); + $self->deindent; + $self->pidl("}"); $self->pidl(""); - # FIXME: Arguments: binding string, credentials, loadparm context + $self->pidl("credentials = cli_credentials_from_py_object(py_credentials);"); + $self->pidl("if (credentials == NULL) {"); + $self->indent; + $self->pidl("PyErr_SetString(PyExc_TypeError, \"Expected credentials\");"); + $self->pidl("return NULL;"); + $self->deindent; + $self->pidl("}"); + $self->pidl("ret = PyObject_New($interface->{NAME}_InterfaceObject, &$interface->{NAME}_InterfaceType);"); $self->pidl(""); @@ -517,6 +552,8 @@ sub Interface($$$) $self->pidl(" &ndr_table_$interface->{NAME}, credentials, NULL, lp_ctx);"); $self->handle_ntstatus("status", "NULL", "mem_ctx"); + $self->pidl("ret->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;"); + $self->pidl("return (PyObject *)ret;"); $self->deindent; $self->pidl("}"); diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index cedd0cc2fe..52a4f49bb4 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -18,22 +18,25 @@ # import echo +from param import LoadParm import unittest class RpcEchoTests(unittest.TestCase): def setUp(self): - self.conn = echo.rpcecho("ncalrpc:") + lp_ctx = LoadParm() + lp_ctx.load("st/client/client.conf") + self.conn = echo.rpcecho("ncalrpc:", lp_ctx) def test_addone(self): - self.assertEquals(2, conn.AddOne(1)) + self.assertEquals(2, self.conn.AddOne(1)) def test_echodata(self): - self.assertEquals("bla", conn.EchoData(3, "bla")) + self.assertEquals("bla", self.conn.EchoData(3, "bla")) def test_call(self): - self.assertEquals("foobar", conn.TestCall("foobar")) + self.assertEquals("foobar", self.conn.TestCall("foobar")) def test_surrounding(self): somearray = [1,2,3,4] - (y,) = conn.TestSurrounding(echo.Surrounding(4, somearray)) + (y,) = self.conn.TestSurrounding(echo.Surrounding(4, somearray)) self.assertEquals(8 * [0], y.surrounding) -- cgit