pidl/python: Pass credentials and loadparm context when connecting using DCE/RPC.
authorJelmer Vernooij <jelmer@samba.org>
Mon, 14 Jan 2008 04:16:51 +0000 (05:16 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Mon, 14 Jan 2008 18:53:06 +0000 (19:53 +0100)
source/auth/credentials/credentials.i
source/auth/credentials/credentials_wrap.c
source/foo.py
source/param/param.i
source/param/param_wrap.c
source/pidl/lib/Parse/Pidl/Samba4/Python.pm
source/scripting/python/samba/tests/dcerpc/rpcecho.py

index 8f09ff4b185903e1e9ec7ce4b5e8e5fabc711683..ee09b43a753d46eedc929c8f5242a21681f27227 100644 (file)
@@ -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;
+}
+
+%}
index ebf7162c5bb178c55fc4cef74892d3aa2030aaf1..146a81abafaa71894bc81a53744b4641a84d68cd 100644 (file)
@@ -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
index 0e2d35f080ae743b4ebd28583b2d496fa4863aec..21a422ce012104840dafb50da5bed76c8ec6f761 100644 (file)
 #
 
 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)
index 353fa3ced62da553326b27526976fd85cf58ccc3..fdc9de233ff502adec7e3c90aba9b5705cc8972a 100644 (file)
@@ -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;
+}
+
+%}
index ca9fbb77b83412cf896af03756b276c929bc7f7e..e9fe8a3df57a05063cc62789180ace1e76047244 100644 (file)
@@ -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
index 266a092788e820465dd39f2049841cf95a876f1e..04649d3668f6abff18a87bba87891fc7aeb83e2e 100644 (file)
@@ -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("}");
index cedd0cc2fee538aa4b04e6155b61639e2d1ac9f2..52a4f49bb49f5d899a98eca5bcc921b39036a7b7 100644 (file)
 #
 
 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)