From 88f2ca7fb5619b5121184d4ee55a7ce202e2b8d3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 14 Jan 2008 17:10:31 +0100 Subject: Fill in IDL for lsa_SetInfoPolicy and lsa_SetInfoPolicy2. Guenther (This used to be commit 54458c46249e07176e2a5b37279a3c95d21df0ab) --- source4/librpc/idl/lsa.idl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/librpc/idl/lsa.idl b/source4/librpc/idl/lsa.idl index ea94458936..5ac6d55229 100644 --- a/source4/librpc/idl/lsa.idl +++ b/source4/librpc/idl/lsa.idl @@ -239,7 +239,11 @@ import "security.idl"; /******************/ /* Function: 0x08 */ - NTSTATUS lsa_SetInfoPolicy (); + NTSTATUS lsa_SetInfoPolicy ( + [in] policy_handle *handle, + [in] uint16 level, + [in,switch_is(level)] lsa_PolicyInformation *info + ); /******************/ /* Function: 0x09 */ @@ -727,7 +731,11 @@ import "security.idl"; ); /* Function 0x2f */ - NTSTATUS lsa_SetInfoPolicy2(); + NTSTATUS lsa_SetInfoPolicy2( + [in] policy_handle *handle, + [in] uint16 level, + [in,switch_is(level)] lsa_PolicyInformation *info + ); /**********************/ /* Function 0x30 */ -- cgit From b7d5a760dc2c64374b065b35a412875d06ae423c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 14 Jan 2008 17:37:35 +0100 Subject: Use lsa_PolicyInfo enum in lsa policy info calls. Guenther (This used to be commit 068697706652373d28091cd7594e0276da27dbc4) --- source4/librpc/idl/lsa.idl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4') diff --git a/source4/librpc/idl/lsa.idl b/source4/librpc/idl/lsa.idl index 5ac6d55229..705c86e39b 100644 --- a/source4/librpc/idl/lsa.idl +++ b/source4/librpc/idl/lsa.idl @@ -214,7 +214,7 @@ import "security.idl"; LSA_POLICY_INFO_AUDIT_FULL_SET=10, LSA_POLICY_INFO_AUDIT_FULL_QUERY=11, LSA_POLICY_INFO_DNS=12 - } lsaPolicyInfo; + } lsa_PolicyInfo; typedef [switch_type(uint16)] union { [case(LSA_POLICY_INFO_AUDIT_LOG)] lsa_AuditLogInfo audit_log; @@ -233,7 +233,7 @@ import "security.idl"; NTSTATUS lsa_QueryInfoPolicy ( [in] policy_handle *handle, - [in] uint16 level, + [in] lsa_PolicyInfo level, [out,unique,switch_is(level)] lsa_PolicyInformation *info ); @@ -241,7 +241,7 @@ import "security.idl"; /* Function: 0x08 */ NTSTATUS lsa_SetInfoPolicy ( [in] policy_handle *handle, - [in] uint16 level, + [in] lsa_PolicyInfo level, [in,switch_is(level)] lsa_PolicyInformation *info ); @@ -726,14 +726,14 @@ import "security.idl"; NTSTATUS lsa_QueryInfoPolicy2( [in] policy_handle *handle, - [in] uint16 level, + [in] lsa_PolicyInfo level, [out,unique,switch_is(level)] lsa_PolicyInformation *info ); /* Function 0x2f */ NTSTATUS lsa_SetInfoPolicy2( [in] policy_handle *handle, - [in] uint16 level, + [in] lsa_PolicyInfo level, [in,switch_is(level)] lsa_PolicyInformation *info ); -- cgit From 83c56f2118393e142021e232f7731e4622d2dfb3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 11 Jan 2008 18:11:45 +0100 Subject: python/pidl: More work on wrapping enums, bitmaps and structs. (This used to be commit 732c3453f0784d5052705b00735b750809afce61) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 102 ++++++++++++++++++++------- 1 file changed, 76 insertions(+), 26 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 8effff9d5e..7c379548ed 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -9,7 +9,7 @@ use Exporter; @ISA = qw(Exporter); use strict; -use Parse::Pidl::Typelist; +use Parse::Pidl::Typelist qw(hasType getType mapTypeName); use Parse::Pidl::Util qw(has_property ParseExpr); use vars qw($VERSION); @@ -17,7 +17,8 @@ $VERSION = '0.01'; sub new($) { my ($class) = @_; - my $self = { res => "", res_hdr => "", tabs => "", constants => {}}; + my $self = { res => "", res_hdr => "", tabs => "", constants => {}, + module_methods => []}; bless($self, $class); } @@ -63,7 +64,26 @@ sub Import sub Const($$) { my ($self, $const) = @_; - $self->{constants}->{$const->{NAME}} = [$const->{DATA}->{TYPE}, $const->{VALUE}]; + $self->register_constant($const->{NAME}, $const->{DATA}->{TYPE}, $const->{VALUE}); +} + +sub register_constant($$$$) +{ + my ($self, $name, $type, $value) = @_; + + $self->{constants}->{$name} = [$type, $value]; +} + +sub EnumAndBitmapConsts($$$) +{ + my ($self, $name, $d) = @_; + + foreach my $e (@{$d->{ELEMENTS}}) { + $e =~ /^([A-Za-z0-9_]+)=(.*)$/; + my $cname = $1; + + $self->register_constant($cname, $d, $cname); + } } sub FromTypeToPythonFunction($$) @@ -97,6 +117,8 @@ sub TypeConstructor($$) $self->pidl("static PyObject *py_$type->{NAME}_getattr(PyTypeObject *obj, char *name)"); $self->pidl("{"); $self->indent; + $self->pidl("$type->{NAME}_Object *py_object = ($type->{NAME}_Object *)obj;"); + $self->pidl(mapTypeName($type) . " *object = talloc_get_type(py_object->object, ".mapTypeName($type).");"); $self->pidl("return Py_None;"); $self->deindent; $self->pidl("}"); @@ -115,6 +137,8 @@ sub TypeConstructor($$) $self->pidl("static PyObject *py_$type->{NAME}_setattr(PyTypeObject *obj, char *name, PyObject *value)"); $self->pidl("{"); $self->indent; + $self->pidl("$type->{NAME}_Object *py_object = ($type->{NAME}_Object *)obj;"); + $self->pidl(mapTypeName($type) . " *object = talloc_get_type(py_object->object, ".mapTypeName($type).");"); $self->pidl("return Py_None;"); $self->deindent; $self->pidl("}"); @@ -133,7 +157,8 @@ sub TypeConstructor($$) $self->pidl(""); - $self->pidl("static PyObject *py_$type->{NAME}(PyObject *self, PyObject *args)"); + my $py_fnname = "py_$type->{NAME}"; + $self->pidl("static PyObject *$py_fnname(PyObject *self, PyObject *args)"); $self->pidl("{"); $self->indent; $self->pidl("$type->{NAME}\_Object *ret;"); @@ -142,6 +167,8 @@ sub TypeConstructor($$) $self->deindent; $self->pidl("}"); $self->pidl(""); + + return $py_fnname; } sub PythonFunction($$$) @@ -175,9 +202,36 @@ sub handle_ntstatus($$$) $self->pidl(""); } -sub Interface($$) +sub PythonType($$$) { - my($self,$interface) = @_; + my ($self, $d, $interface, $basename) = @_; + + if ($d->{TYPE} eq "STRUCT" or $d->{TYPE} eq "TYPEDEF" and + $d->{DATA}->{TYPE} eq "STRUCT") { + $self->FromTypeToPythonFunction($d); + $self->FromPythonToTypeFunction($d); + my $py_fnname = $self->TypeConstructor($d); + + my $fn_name = $d->{NAME}; + + $fn_name =~ s/^$interface->{NAME}_//; + $fn_name =~ s/^$basename\_//; + + $self->register_module_method($fn_name, $py_fnname, "METH_VARARGS|METH_KEYWORDS", "NULL"); + } + + if ($d->{TYPE} eq "ENUM" or $d->{TYPE} eq "BITMAP") { + $self->EnumAndBitmapConsts($d->{NAME}, $d); + } + + if ($d->{TYPE} eq "TYPEDEF" and ($d->{DATA}->{TYPE} eq "ENUM" or $d->{DATA}->{TYPE} eq "BITMAP")) { + $self->EnumAndBitmapConsts($d->{NAME}, $d->{DATA}); + } +} + +sub Interface($$$) +{ + my($self,$interface,$basename) = @_; $self->pidl_hdr("#ifndef _HEADER_PYTHON_$interface->{NAME}\n"); $self->pidl_hdr("#define _HEADER_PYTHON_$interface->{NAME}\n\n"); @@ -186,10 +240,10 @@ sub Interface($$) $self->Const($_) foreach (@{$interface->{CONSTS}}); - foreach (@{$interface->{TYPES}}) { - $self->FromTypeToPythonFunction($_); - $self->FromPythonToTypeFunction($_); - $self->TypeConstructor($_); + foreach my $d (@{$interface->{TYPES}}) { + next if has_property($d, "nopython"); + + $self->PythonType($d, $interface, $basename); } $self->pidl("staticforward PyTypeObject $interface->{NAME}_InterfaceType;"); @@ -257,6 +311,7 @@ sub Interface($$) $self->pidl(""); + $self->register_module_method($interface->{NAME}, "interface_$interface->{NAME}", "METH_VARARGS|METH_KEYWORDS", "NULL"); $self->pidl("static PyObject *interface_$interface->{NAME}(PyObject *self, PyObject *args)"); $self->pidl("{"); $self->indent; @@ -285,6 +340,13 @@ sub Interface($$) $self->pidl_hdr("#endif /* _HEADER_NDR_$interface->{NAME} */\n"); } +sub register_module_method($$$$$) +{ + my ($self, $fn_name, $pyfn_name, $flags, $doc) = @_; + + push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc]) +} + sub Parse($$$$) { my($self,$basename,$ndr,$hdr) = @_; @@ -305,27 +367,15 @@ sub Parse($$$$) "); foreach my $x (@$ndr) { - ($x->{TYPE} eq "INTERFACE") && $self->Interface($x); + ($x->{TYPE} eq "INTERFACE") && $self->Interface($x, $basename); ($x->{TYPE} eq "IMPORT") && $self->Import(@{$x->{PATHS}}); } $self->pidl("static PyMethodDef $basename\_methods[] = {"); $self->indent; - foreach my $x (@$ndr) { - next if ($x->{TYPE} ne "INTERFACE"); - $self->pidl("{ \"$x->{NAME}\", (PyCFunction)interface_$x->{NAME}, METH_VARARGS|METH_KEYWORDS, NULL },"); - - foreach my $d (@{$x->{TYPES}}) { - next if has_property($d, "nopython"); - next if ($d->{TYPE} eq "ENUM" or $d->{TYPE} eq "BITMAP"); - - my $fn_name = $d->{NAME}; - - $fn_name =~ s/^$x->{NAME}_//; - $fn_name =~ s/^$basename\_//; - - $self->pidl("{ \"$fn_name\", (PyCFunction)py_$d->{NAME}, METH_VARARGS|METH_KEYWORDS, NULL },"); - } + foreach (@{$self->{module_methods}}) { + my ($fn_name, $pyfn_name, $flags, $doc) = @$_; + $self->pidl("{ \"$fn_name\", (PyCFunction)$pyfn_name, $flags, $doc },"); } $self->pidl("{ NULL, NULL, 0, NULL }"); -- cgit From 7aa0f25d7f0a8a1eac19c886477b13ab00bd76fe Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 11 Jan 2008 18:27:47 +0100 Subject: python/pidl: Handle non-string types. (This used to be commit 02dd02c529d578ad7fa4a6b825097685555604fe) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 7c379548ed..5077102fc7 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -347,6 +347,24 @@ sub register_module_method($$$$$) push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc]) } +sub ConvertObjectToPython($$$) +{ + my ($self, $ctype, $cvar) = @_; + + if ($cvar =~ /^".*"$/) { + return "PyString_FromString($cvar)"; + } + + if ($cvar =~ /^[0-9]+$/ or + $ctype->{TYPE} eq "ENUM" or $ctype->{TYPE} eq "BITMAP" or + $ctype->{TYPE} eq "TYPEDEF" and + ($ctype->{TYPE} eq "ENUM" or $ctype->{TYPE} eq "BITMAP")) { + return "PyInt_FromLong($cvar)"; + } + + die("Unknown type for ".mapTypeName($ctype).": $cvar"); +} + sub Parse($$$$) { my($self,$basename,$ndr,$hdr) = @_; @@ -391,7 +409,7 @@ sub Parse($$$$) $self->pidl("m = Py_InitModule(\"$basename\", $basename\_methods);"); foreach (keys %{$self->{constants}}) { # FIXME: Handle non-string constants - $self->pidl("PyModule_AddObject(m, \"$_\", PyString_FromString(" . $self->{constants}->{$_}->[1] . "));"); + $self->pidl("PyModule_AddObject(m, \"$_\", " . $self->ConvertObjectToPython($self->{constants}->{$_}->[0], $self->{constants}->{$_}->[1]) . ");"); } $self->deindent; $self->pidl("}"); -- cgit From f71df735556947f70c6a14bf9588988d0f6adfe3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 11 Jan 2008 20:00:46 +0100 Subject: python/pidl: Start wrapping function arguments. (This used to be commit c2595d3754db4d03bafd53b6f62158516493657e) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 198 ++++++++++++++++++++++----- 1 file changed, 160 insertions(+), 38 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 5077102fc7..6b4b41f74f 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -86,83 +86,121 @@ sub EnumAndBitmapConsts($$$) } } -sub FromTypeToPythonFunction($$) +sub FromUnionToPythonFunction($$) { my ($self, $type) = @_; #FIXME + + $self->pidl("return NULL;"); } -sub FromPythonToTypeFunction($$) +sub FromStructToPythonFunction($$) { my ($self, $type) = @_; #FIXME + $self->pidl("return NULL;"); } -sub TypeConstructor($$) +sub FromPythonToUnionFunction($$) { my ($self, $type) = @_; - $self->pidl("staticforward PyTypeObject $type->{NAME}_ObjectType;"); + #FIXME + $self->pidl("return NULL;"); +} + +sub FromPythonToStructFunction($$) +{ + my ($self, $type) = @_; + + #FIXME + $self->pidl("return NULL;"); +} + +sub PythonStruct($$$$) +{ + my ($self, $name, $cname, $d) = @_; + + $self->pidl("staticforward PyTypeObject $name\_ObjectType;"); $self->pidl("typedef struct {"); $self->indent; $self->pidl("PyObject_HEAD"); - $self->pidl("void *object;"); # FIXME: Use real type rather than void + $self->pidl("$cname *object;"); $self->deindent; - $self->pidl("} $type->{NAME}_Object;"); + $self->pidl("} $name\_Object;"); $self->pidl(""); - $self->pidl("static PyObject *py_$type->{NAME}_getattr(PyTypeObject *obj, char *name)"); + $self->pidl("static PyObject *py_$name\_getattr(PyTypeObject *obj, char *name)"); $self->pidl("{"); $self->indent; - $self->pidl("$type->{NAME}_Object *py_object = ($type->{NAME}_Object *)obj;"); - $self->pidl(mapTypeName($type) . " *object = talloc_get_type(py_object->object, ".mapTypeName($type).");"); - $self->pidl("return Py_None;"); + $self->pidl("$name\_Object *py_object = ($name\_Object *)obj;"); + $self->pidl("$cname *object = talloc_get_type(py_object->object, $cname);"); + foreach my $e (@{$d->{ELEMENTS}}) { + $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); + my $varname = "object->$e->{NAME}"; + $self->indent; + $self->pidl("return ".$self->ConvertObjectToPython($e->{TYPE}, $varname) . ";"); + $self->deindent; + $self->pidl("}"); + } + $self->pidl("PyErr_SetString(PyExc_AttributeError, \"no such attribute\");"); + $self->pidl("return NULL;"); $self->deindent; $self->pidl("}"); $self->pidl(""); - $self->pidl("static void py_$type->{NAME}_dealloc(PyObject* self)"); + $self->pidl("static void py_$name\_dealloc(PyObject* self)"); $self->pidl("{"); $self->indent; - $self->pidl("$type->{NAME}_Object *obj = ($type->{NAME}_Object *)self;"); + $self->pidl("$name\_Object *obj = ($name\_Object *)self;"); $self->pidl("talloc_free(obj->object);"); $self->pidl("PyObject_Del(self);"); $self->deindent; $self->pidl("}"); $self->pidl(""); - $self->pidl("static PyObject *py_$type->{NAME}_setattr(PyTypeObject *obj, char *name, PyObject *value)"); + $self->pidl("static PyObject *py_$name\_setattr(PyTypeObject *obj, char *name, PyObject *value)"); $self->pidl("{"); $self->indent; - $self->pidl("$type->{NAME}_Object *py_object = ($type->{NAME}_Object *)obj;"); - $self->pidl(mapTypeName($type) . " *object = talloc_get_type(py_object->object, ".mapTypeName($type).");"); - $self->pidl("return Py_None;"); + $self->pidl("$name\_Object *py_object = ($name\_Object *)obj;"); + $self->pidl("$cname *object = talloc_get_type(py_object->object, $cname);"); + foreach my $e (@{$d->{ELEMENTS}}) { + $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); + my $varname = "object->$e->{NAME}"; + $self->indent; + $self->pidl("/* FIXME: talloc_free($varname) if necessary */"); + $self->pidl("$varname = " . $self->ConvertObjectFromPython($e->{TYPE}, "value") . ";"); + $self->deindent; + $self->pidl("}"); + } + $self->pidl("PyErr_SetString(PyExc_AttributeError, \"no such attribute\");"); + $self->pidl("return NULL;"); $self->deindent; $self->pidl("}"); $self->pidl(""); - $self->pidl("static PyTypeObject $type->{NAME}_ObjectType = {"); + $self->pidl("static PyTypeObject $name\_ObjectType = {"); $self->indent; $self->pidl("PyObject_HEAD_INIT(NULL) 0,"); - $self->pidl(".tp_name = \"$type->{NAME}\","); - $self->pidl(".tp_basicsize = sizeof($type->{NAME}_Object),"); - $self->pidl(".tp_dealloc = (destructor)py_$type->{NAME}_dealloc,"); - $self->pidl(".tp_getattr = (getattrfunc)py_$type->{NAME}_getattr,"); - $self->pidl(".tp_setattr = (setattrfunc)py_$type->{NAME}_setattr,"); + $self->pidl(".tp_name = \"$name\","); + $self->pidl(".tp_basicsize = sizeof($name\_Object),"); + $self->pidl(".tp_dealloc = (destructor)py_$name\_dealloc,"); + $self->pidl(".tp_getattr = (getattrfunc)py_$name\_getattr,"); + $self->pidl(".tp_setattr = (setattrfunc)py_$name\_setattr,"); $self->deindent; $self->pidl("};"); $self->pidl(""); - my $py_fnname = "py_$type->{NAME}"; + my $py_fnname = "py_$name"; $self->pidl("static PyObject *$py_fnname(PyObject *self, PyObject *args)"); $self->pidl("{"); $self->indent; - $self->pidl("$type->{NAME}\_Object *ret;"); - $self->pidl("ret = PyObject_New($type->{NAME}_Object, &$type->{NAME}_ObjectType);"); + $self->pidl("$name\_Object *ret;"); + $self->pidl("ret = PyObject_New($name\_Object, &$name\_ObjectType);"); $self->pidl("return (PyObject *) ret;"); $self->deindent; $self->pidl("}"); @@ -180,22 +218,51 @@ sub PythonFunction($$$) $self->indent; $self->pidl("$iface\_InterfaceObject *iface = ($iface\_InterfaceObject *)self;"); $self->pidl("NTSTATUS status;"); + $self->pidl("TALLOC_CTX *mem_ctx = talloc_new(NULL);"); + $self->pidl("struct dcerpc_$fn->{NAME} r;"); + $self->pidl("PyObject *result = Py_None;"); + foreach my $e (@{$fn->{ELEMENTS}}) { + $self->pidl("PyObject *py_$e->{NAME};"); + } + if ($fn->{RETURN_TYPE}) { + $self->pidl("PyObject *py_result;"); + } $self->pidl(""); - # FIXME - $self->handle_ntstatus("status", "NULL"); - $self->pidl("return Py_None;"); + $self->pidl("ZERO_STRUCT(r.out);"); + + foreach my $e (@{$fn->{ELEMENTS}}) { + if (grep(/in/,@{$e->{DIRECTION}})) { + $self->pidl("r.in.$e->{NAME} = " . $self->ConvertObjectFromPython($e->{TYPE}, "py_$e->{NAME}") . ";"); + } + } + $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);"); + $self->handle_ntstatus("status", "NULL", "mem_ctx"); + + foreach my $e (@{$fn->{ELEMENTS}}) { + if (grep(/out/,@{$e->{DIRECTION}})) { + $self->pidl("py_$e->{NAME} = " . $self->ConvertObjectToPython($e->{TYPE}, "r.out.$e->{NAME}") . ";"); + } + } + + if ($fn->{RETURN_TYPE}) { + $self->pidl("py_result = " . $self->ConvertObjectToPython($fn->{RETURN_TYPE}, "r.out.result") . ";"); + } + + $self->pidl("talloc_free(mem_ctx);"); + $self->pidl("return result;"); $self->deindent; $self->pidl("}"); $self->pidl(""); } -sub handle_ntstatus($$$) +sub handle_ntstatus($$$$) { - my ($self, $var, $retval) = @_; + my ($self, $var, $retval, $mem_ctx) = @_; $self->pidl("if (NT_STATUS_IS_ERR($var)) {"); $self->indent; $self->pidl("PyErr_SetString(PyExc_RuntimeError, nt_errstr($var));"); + $self->pidl("talloc_free($mem_ctx);") if ($mem_ctx); $self->pidl("return $retval;"); $self->deindent; $self->pidl("}"); @@ -206,11 +273,19 @@ sub PythonType($$$) { my ($self, $d, $interface, $basename) = @_; + my $actual_ctype = $d; + if ($actual_ctype->{TYPE} eq "TYPEDEF") { + $actual_ctype = $actual_ctype->{DATA}; + } + if ($d->{TYPE} eq "STRUCT" or $d->{TYPE} eq "TYPEDEF" and $d->{DATA}->{TYPE} eq "STRUCT") { - $self->FromTypeToPythonFunction($d); - $self->FromPythonToTypeFunction($d); - my $py_fnname = $self->TypeConstructor($d); + my $py_fnname; + if ($d->{TYPE} eq "STRUCT") { + $py_fnname = $self->PythonStruct($d->{NAME}, mapTypeName($d), $d); + } else { + $py_fnname = $self->PythonStruct($d->{NAME}, mapTypeName($d), $d->{DATA}); + } my $fn_name = $d->{NAME}; @@ -227,6 +302,26 @@ sub PythonType($$$) if ($d->{TYPE} eq "TYPEDEF" and ($d->{DATA}->{TYPE} eq "ENUM" or $d->{DATA}->{TYPE} eq "BITMAP")) { $self->EnumAndBitmapConsts($d->{NAME}, $d->{DATA}); } + + if ($actual_ctype->{TYPE} eq "UNION" or $actual_ctype->{TYPE} eq "STRUCT") { + $self->pidl("PyObject *py_import_$d->{NAME}(" .mapTypeName($d) . "*in)"); + $self->pidl("{"); + $self->indent; + $self->FromStructToPythonFunction($d) if ($actual_ctype->{TYPE} eq "STRUCT"); + $self->FromUnionToPythonFunction($d) if ($actual_ctype->{TYPE} eq "UNION"); + $self->deindent; + $self->pidl("}"); + $self->pidl(""); + + $self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, PyObject *in)"); + $self->pidl("{"); + $self->indent; + $self->FromPythonToStructFunction($d) if ($actual_ctype->{TYPE} eq "STRUCT"); + $self->FromPythonToUnionFunction($d) if ($actual_ctype->{TYPE} eq "UNION"); + $self->deindent; + $self->pidl("}"); + $self->pidl(""); + } } sub Interface($$$) @@ -319,6 +414,7 @@ sub Interface($$$) $self->pidl("const char *binding_string;"); $self->pidl("struct cli_credentials *credentials;"); $self->pidl("struct loadparm_context *lp_ctx;"); + $self->pidl("TALLOC_CTX *mem_ctx = NULL;"); $self->pidl("NTSTATUS status;"); $self->pidl(""); @@ -328,7 +424,7 @@ sub Interface($$$) $self->pidl("status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string, "); $self->pidl(" &ndr_table_$interface->{NAME}, credentials, NULL, lp_ctx);"); - $self->handle_ntstatus("status", "NULL"); + $self->handle_ntstatus("status", "NULL", "mem_ctx"); $self->pidl("return (PyObject *)ret;"); $self->deindent; @@ -347,6 +443,13 @@ sub register_module_method($$$$$) push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc]) } +sub ConvertObjectFromPython($$$) +{ + my ($self, $ctype, $cvar) = @_; + + return "FIXME($cvar)"; +} + sub ConvertObjectToPython($$$) { my ($self, $ctype, $cvar) = @_; @@ -355,14 +458,33 @@ sub ConvertObjectToPython($$$) return "PyString_FromString($cvar)"; } + if (ref($ctype) ne "HASH") { + $ctype = getType($ctype); + } + + my $actual_ctype = $ctype; + if ($ctype->{TYPE} eq "TYPEDEF") { + $actual_ctype = $ctype->{DATA}; + } + if ($cvar =~ /^[0-9]+$/ or - $ctype->{TYPE} eq "ENUM" or $ctype->{TYPE} eq "BITMAP" or - $ctype->{TYPE} eq "TYPEDEF" and - ($ctype->{TYPE} eq "ENUM" or $ctype->{TYPE} eq "BITMAP")) { + $actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or + $actual_ctype->{TYPE} eq "SCALAR" and ( + $actual_ctype->{NAME} =~ /^(uint[0-9]+|hyper)$/)) { return "PyInt_FromLong($cvar)"; } - die("Unknown type for ".mapTypeName($ctype).": $cvar"); + if ($ctype->{TYPE} eq "TYPEDEF" and ( + $actual_ctype->{TYPE} eq "STRUCT" or + $actual_ctype->{TYPE} eq "UNION")) { + return "py_import_$ctype->{NAME}($cvar)"; + } + + if ($ctype->{TYPE} eq "STRUCT" or $ctype->{TYPE} eq "UNION") { + return "py_import_$ctype->{TYPE}_$ctype->{NAME}($cvar)"; + } + + die("unknown type ".mapTypeName($ctype) . ": $cvar"); } sub Parse($$$$) -- cgit From 8986f3ee6f46c354fed2cce5e434dda060e6318b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 11 Jan 2008 20:37:08 +0100 Subject: pidl/python: Convert some Python objects back to C, return proper tuples in client calls. (This used to be commit 1ab617296943dc1d270cbf999dedcfb3073d3d20) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 47 +++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 7 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 6b4b41f74f..4454eeefd7 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -1,6 +1,6 @@ ################################################### # Python function wrapper generator -# Copyright jelmer@samba.org 2007 +# Copyright jelmer@samba.org 2007-2008 # released under the GNU GPL package Parse::Pidl::Samba4::Python; @@ -11,6 +11,7 @@ use Exporter; use strict; use Parse::Pidl::Typelist qw(hasType getType mapTypeName); use Parse::Pidl::Util qw(has_property ParseExpr); +use Parse::Pidl::CUtil qw(get_value_of get_pointer_of); use vars qw($VERSION); $VERSION = '0.01'; @@ -220,12 +221,19 @@ sub PythonFunction($$$) $self->pidl("NTSTATUS status;"); $self->pidl("TALLOC_CTX *mem_ctx = talloc_new(NULL);"); $self->pidl("struct dcerpc_$fn->{NAME} r;"); - $self->pidl("PyObject *result = Py_None;"); + $self->pidl("PyObject *result;"); + my $result_size = 0; + foreach my $e (@{$fn->{ELEMENTS}}) { - $self->pidl("PyObject *py_$e->{NAME};"); + if (grep(/in/,@{$e->{DIRECTION}})) { + $self->pidl("PyObject *py_$e->{NAME};"); + } + if (grep(/out/,@{$e->{DIRECTION}})) { + $result_size++; + } } if ($fn->{RETURN_TYPE}) { - $self->pidl("PyObject *py_result;"); + $result_size++; } $self->pidl(""); $self->pidl("ZERO_STRUCT(r.out);"); @@ -238,14 +246,20 @@ 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);"); + + my $i = 0; + foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/out/,@{$e->{DIRECTION}})) { - $self->pidl("py_$e->{NAME} = " . $self->ConvertObjectToPython($e->{TYPE}, "r.out.$e->{NAME}") . ";"); + $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($e->{TYPE}, "r.out.$e->{NAME}") . ");"); + + $i++; } } if ($fn->{RETURN_TYPE}) { - $self->pidl("py_result = " . $self->ConvertObjectToPython($fn->{RETURN_TYPE}, "r.out.result") . ";"); + $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($fn->{RETURN_TYPE}, "r.out.result") . ");"); } $self->pidl("talloc_free(mem_ctx);"); @@ -304,7 +318,7 @@ sub PythonType($$$) } if ($actual_ctype->{TYPE} eq "UNION" or $actual_ctype->{TYPE} eq "STRUCT") { - $self->pidl("PyObject *py_import_$d->{NAME}(" .mapTypeName($d) . "*in)"); + $self->pidl("PyObject *py_import_$d->{NAME}(" .mapTypeName($d) . " *in)"); $self->pidl("{"); $self->indent; $self->FromStructToPythonFunction($d) if ($actual_ctype->{TYPE} eq "STRUCT"); @@ -447,6 +461,21 @@ sub ConvertObjectFromPython($$$) { my ($self, $ctype, $cvar) = @_; + if (ref($ctype) ne "HASH") { + $ctype = getType($ctype); + } + + my $actual_ctype = $ctype; + if ($ctype->{TYPE} eq "TYPEDEF") { + $actual_ctype = $ctype->{DATA}; + } + + if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or + $actual_ctype->{TYPE} eq "SCALAR" and ( + $actual_ctype->{NAME} =~ /^(uint[0-9]+|hyper)$/)) { + return "PyInt_AsLong($cvar)"; + } + return "FIXME($cvar)"; } @@ -484,6 +513,10 @@ sub ConvertObjectToPython($$$) return "py_import_$ctype->{TYPE}_$ctype->{NAME}($cvar)"; } + if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") { + return "PyInt_FromLong($cvar->v)"; + } + die("unknown type ".mapTypeName($ctype) . ": $cvar"); } -- cgit From 375624ecf95a0aac6e29ce0c7dca35f239c9dd12 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 12 Jan 2008 01:09:28 +0100 Subject: pidl/python: Some more support for special case types. (This used to be commit 991aa950a377bbc07e0bf05758574f850a6d0ff7) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 48 ++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 9 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 4454eeefd7..2bf5f1528a 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -11,7 +11,7 @@ use Exporter; use strict; use Parse::Pidl::Typelist qw(hasType getType mapTypeName); use Parse::Pidl::Util qw(has_property ParseExpr); -use Parse::Pidl::CUtil qw(get_value_of get_pointer_of); +use Parse::Pidl::CUtil qw(get_value_of get_pointer_to); use vars qw($VERSION); $VERSION = '0.01'; @@ -288,12 +288,11 @@ sub PythonType($$$) my ($self, $d, $interface, $basename) = @_; my $actual_ctype = $d; - if ($actual_ctype->{TYPE} eq "TYPEDEF") { + if ($actual_ctype->{TYPE} eq "TYPEDEF" or $actual_ctype->{TYPE} eq "DECLARE") { $actual_ctype = $actual_ctype->{DATA}; } - if ($d->{TYPE} eq "STRUCT" or $d->{TYPE} eq "TYPEDEF" and - $d->{DATA}->{TYPE} eq "STRUCT") { + if ($actual_ctype->{TYPE} eq "STRUCT") { my $py_fnname; if ($d->{TYPE} eq "STRUCT") { $py_fnname = $self->PythonStruct($d->{NAME}, mapTypeName($d), $d); @@ -466,13 +465,13 @@ sub ConvertObjectFromPython($$$) } my $actual_ctype = $ctype; - if ($ctype->{TYPE} eq "TYPEDEF") { + if ($ctype->{TYPE} eq "TYPEDEF" or $ctype->{TYPE} eq "DECLARE") { $actual_ctype = $ctype->{DATA}; } if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or $actual_ctype->{TYPE} eq "SCALAR" and ( - $actual_ctype->{NAME} =~ /^(uint[0-9]+|hyper)$/)) { + $actual_ctype->{NAME} =~ /^(uint[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong)$/)) { return "PyInt_AsLong($cvar)"; } @@ -488,18 +487,22 @@ sub ConvertObjectToPython($$$) } if (ref($ctype) ne "HASH") { + if (not hasType($ctype)) { + return "py_import_$ctype($cvar)"; # best bet + } + $ctype = getType($ctype); } my $actual_ctype = $ctype; - if ($ctype->{TYPE} eq "TYPEDEF") { + if ($ctype->{TYPE} eq "TYPEDEF" or $ctype->{TYPE} eq "DECLARE") { $actual_ctype = $ctype->{DATA}; } if ($cvar =~ /^[0-9]+$/ or $actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or - $actual_ctype->{TYPE} eq "SCALAR" and ( - $actual_ctype->{NAME} =~ /^(uint[0-9]+|hyper)$/)) { + ($actual_ctype->{TYPE} eq "SCALAR" and + $actual_ctype->{NAME} =~ /^(int|long|char|u?int[0-9]+|hyper|dlong|udlong|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/)) { return "PyInt_FromLong($cvar)"; } @@ -509,6 +512,11 @@ sub ConvertObjectToPython($$$) return "py_import_$ctype->{NAME}($cvar)"; } + if ($actual_ctype->{TYPE} eq "SCALAR" and + $actual_ctype->{NAME} eq "DATA_BLOB") { + return "PyString_FromStringAndSize($cvar->data, $cvar->length)"; + } + if ($ctype->{TYPE} eq "STRUCT" or $ctype->{TYPE} eq "UNION") { return "py_import_$ctype->{TYPE}_$ctype->{NAME}($cvar)"; } @@ -517,6 +525,28 @@ sub ConvertObjectToPython($$$) return "PyInt_FromLong($cvar->v)"; } + if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") { + return "PyInt_FromLong($cvar->v)"; + } + + if ($actual_ctype->{TYPE} eq "SCALAR" and + ($actual_ctype->{NAME} eq "string" or $actual_ctype->{NAME} eq "nbt_string")) { + return "PyString_FromString($cvar)"; + } + + if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") { + return "FIXME($cvar)"; + } + + if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv4address") { + return "FIXME($cvar)"; + } + + if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "pointer") { + return "PyCObject_FromVoidPtr($cvar, talloc_free)"; + } + + die("unknown type ".mapTypeName($ctype) . ": $cvar"); } -- cgit From f0916ef230b48e3140a4fca68f96ab33350bee93 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 01:35:06 +0100 Subject: pidl/python: Remove references to DECLARE, which has been removed. (This used to be commit 9a907567c8e0836b731e0ef01f8d097a33de21b0) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 2bf5f1528a..98e9ee9ec2 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -288,7 +288,7 @@ sub PythonType($$$) my ($self, $d, $interface, $basename) = @_; my $actual_ctype = $d; - if ($actual_ctype->{TYPE} eq "TYPEDEF" or $actual_ctype->{TYPE} eq "DECLARE") { + if ($actual_ctype->{TYPE} eq "TYPEDEF") { $actual_ctype = $actual_ctype->{DATA}; } @@ -465,7 +465,7 @@ sub ConvertObjectFromPython($$$) } my $actual_ctype = $ctype; - if ($ctype->{TYPE} eq "TYPEDEF" or $ctype->{TYPE} eq "DECLARE") { + if ($ctype->{TYPE} eq "TYPEDEF") { $actual_ctype = $ctype->{DATA}; } @@ -495,7 +495,7 @@ sub ConvertObjectToPython($$$) } my $actual_ctype = $ctype; - if ($ctype->{TYPE} eq "TYPEDEF" or $ctype->{TYPE} eq "DECLARE") { + if ($ctype->{TYPE} eq "TYPEDEF") { $actual_ctype = $ctype->{DATA}; } -- cgit From 4ba71079272b1231c457112ac2d90f1f920cf5c8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 01:50:31 +0100 Subject: pidl/python: Fix conversion of last few non-standard types. (This used to be commit b8bdbc38c15598e34c55fb9e3ee1f6894964d2c6) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 98e9ee9ec2..4ae647aa0a 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -9,7 +9,7 @@ use Exporter; @ISA = qw(Exporter); use strict; -use Parse::Pidl::Typelist qw(hasType getType mapTypeName); +use Parse::Pidl::Typelist qw(hasType getType mapTypeName expandAlias); use Parse::Pidl::Util qw(has_property ParseExpr); use Parse::Pidl::CUtil qw(get_value_of get_pointer_to); @@ -471,7 +471,7 @@ sub ConvertObjectFromPython($$$) if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or $actual_ctype->{TYPE} eq "SCALAR" and ( - $actual_ctype->{NAME} =~ /^(uint[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong)$/)) { + expandAlias($actual_ctype->{NAME}) =~ /^(uint[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong)$/)) { return "PyInt_AsLong($cvar)"; } @@ -502,7 +502,7 @@ sub ConvertObjectToPython($$$) if ($cvar =~ /^[0-9]+$/ or $actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or ($actual_ctype->{TYPE} eq "SCALAR" and - $actual_ctype->{NAME} =~ /^(int|long|char|u?int[0-9]+|hyper|dlong|udlong|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/)) { + expandAlias($actual_ctype->{NAME}) =~ /^(int|long|char|u?int[0-9]+|hyper|dlong|udlong|udlongr|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/)) { return "PyInt_FromLong($cvar)"; } @@ -513,7 +513,7 @@ sub ConvertObjectToPython($$$) } if ($actual_ctype->{TYPE} eq "SCALAR" and - $actual_ctype->{NAME} eq "DATA_BLOB") { + expandAlias($actual_ctype->{NAME}) eq "DATA_BLOB") { return "PyString_FromStringAndSize($cvar->data, $cvar->length)"; } @@ -530,7 +530,7 @@ sub ConvertObjectToPython($$$) } if ($actual_ctype->{TYPE} eq "SCALAR" and - ($actual_ctype->{NAME} eq "string" or $actual_ctype->{NAME} eq "nbt_string")) { + ($actual_ctype->{NAME} eq "string" or $actual_ctype->{NAME} eq "nbt_string" or $actual_ctype->{NAME} eq "nbt_name" or $actual_ctype->{NAME} eq "wrepl_nbt_name")) { return "PyString_FromString($cvar)"; } -- cgit From d814f3ce1c58be53886deab31a815e444ca6c5d5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 03:15:55 +0100 Subject: pidl/python: Fix const type wrapping. (This used to be commit 35a4843f9c75a59ab98e785520114809903575cf) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 4ae647aa0a..ae4931571a 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -65,7 +65,7 @@ sub Import sub Const($$) { my ($self, $const) = @_; - $self->register_constant($const->{NAME}, $const->{DATA}->{TYPE}, $const->{VALUE}); + $self->register_constant($const->{NAME}, $const->{DTYPE}, $const->{VALUE}); } sub register_constant($$$$) @@ -258,7 +258,7 @@ sub PythonFunction($$$) } } - if ($fn->{RETURN_TYPE}) { + if (defined($fn->{RETURN_TYPE})) { $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($fn->{RETURN_TYPE}, "r.out.result") . ");"); } @@ -460,10 +460,16 @@ sub ConvertObjectFromPython($$$) { my ($self, $ctype, $cvar) = @_; + die("undef type for $cvar") unless(defined($ctype)); + if (ref($ctype) ne "HASH") { $ctype = getType($ctype); } + if (ref($ctype) ne "HASH") { + return "FIXME($cvar)"; + } + my $actual_ctype = $ctype; if ($ctype->{TYPE} eq "TYPEDEF") { $actual_ctype = $ctype->{DATA}; @@ -482,13 +488,23 @@ sub ConvertObjectToPython($$$) { my ($self, $ctype, $cvar) = @_; + if ($cvar =~ /^[0-9]+$/ or $cvar =~ /^0x[0-9a-fA-F]+$/) { + return "PyInt_FromLong($cvar)"; + } + + die("undef type for $cvar") unless(defined($ctype)); + if ($cvar =~ /^".*"$/) { return "PyString_FromString($cvar)"; } if (ref($ctype) ne "HASH") { if (not hasType($ctype)) { - return "py_import_$ctype($cvar)"; # best bet + if (ref($ctype) eq "HASH") { + return "py_import_$ctype->{TYPE}_$ctype->{NAME}($cvar)"; + } else { + return "py_import_$ctype($cvar)"; # best bet + } } $ctype = getType($ctype); @@ -499,8 +515,7 @@ sub ConvertObjectToPython($$$) $actual_ctype = $ctype->{DATA}; } - if ($cvar =~ /^[0-9]+$/ or - $actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or + if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or ($actual_ctype->{TYPE} eq "SCALAR" and expandAlias($actual_ctype->{NAME}) =~ /^(int|long|char|u?int[0-9]+|hyper|dlong|udlong|udlongr|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/)) { return "PyInt_FromLong($cvar)"; -- cgit From 4a8ceb8c56c66059791e4ef74ef3cbef4259f961 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 15:11:28 +0100 Subject: pidl/python: Fix bug accidently filling in the body of enums/bitmaps without body. (This used to be commit 97971f0d8080f3934ea5940cc0f230004afb94a1) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index ae4931571a..d0a5bbd7e3 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -79,6 +79,8 @@ sub EnumAndBitmapConsts($$$) { my ($self, $name, $d) = @_; + return unless (defined($d->{ELEMENTS})); + foreach my $e (@{$d->{ELEMENTS}}) { $e =~ /^([A-Za-z0-9_]+)=(.*)$/; my $cname = $1; -- cgit From c660845737f454713f60f01d015125b053435b2c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 15:29:56 +0100 Subject: pidl/python: Fix more warnings in the generated code. (This used to be commit 23add37b729aaa85b83cbf6ba98e7042c01f6472) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 51 +++++++++++++++------------- source4/pidl/pidl | 3 +- 2 files changed, 30 insertions(+), 24 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index d0a5bbd7e3..fc5480b661 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -89,37 +89,39 @@ sub EnumAndBitmapConsts($$$) } } -sub FromUnionToPythonFunction($$) +sub FromUnionToPythonFunction($$$) { - my ($self, $type) = @_; + my ($self, $type, $name) = @_; #FIXME $self->pidl("return NULL;"); } -sub FromStructToPythonFunction($$) +sub FromStructToPythonFunction($$$) { - my ($self, $type) = @_; + my ($self, $type, $name) = @_; - #FIXME - $self->pidl("return NULL;"); + $self->pidl("$type->{NAME}\_Object *ret;"); + $self->pidl("ret = PyObject_New($type->{NAME}\_Object, &$type->{NAME}\_ObjectType);"); + $self->pidl("ret->object = talloc_reference(NULL, $name);"); + $self->pidl("return (PyObject *) ret;"); } -sub FromPythonToUnionFunction($$) +sub FromPythonToUnionFunction($$$$) { - my ($self, $type) = @_; + my ($self, $type, $mem_ctx, $name) = @_; #FIXME $self->pidl("return NULL;"); } -sub FromPythonToStructFunction($$) +sub FromPythonToStructFunction($$$$) { - my ($self, $type) = @_; + my ($self, $type, $mem_ctx, $name) = @_; - #FIXME - $self->pidl("return NULL;"); + $self->pidl("$type->{NAME}\_Object *py_object = ($type->{NAME}_Object *)$name;"); + $self->pidl("return talloc_reference($mem_ctx, py_object->object);"); } sub PythonStruct($$$$) @@ -222,7 +224,7 @@ sub PythonFunction($$$) $self->pidl("$iface\_InterfaceObject *iface = ($iface\_InterfaceObject *)self;"); $self->pidl("NTSTATUS status;"); $self->pidl("TALLOC_CTX *mem_ctx = talloc_new(NULL);"); - $self->pidl("struct dcerpc_$fn->{NAME} r;"); + $self->pidl("struct $fn->{NAME} r;"); $self->pidl("PyObject *result;"); my $result_size = 0; @@ -234,11 +236,13 @@ sub PythonFunction($$$) $result_size++; } } + if ($result_size > 0) { + $self->pidl(""); + $self->pidl("ZERO_STRUCT(r.out);"); + } if ($fn->{RETURN_TYPE}) { $result_size++; } - $self->pidl(""); - $self->pidl("ZERO_STRUCT(r.out);"); foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { @@ -322,8 +326,8 @@ sub PythonType($$$) $self->pidl("PyObject *py_import_$d->{NAME}(" .mapTypeName($d) . " *in)"); $self->pidl("{"); $self->indent; - $self->FromStructToPythonFunction($d) if ($actual_ctype->{TYPE} eq "STRUCT"); - $self->FromUnionToPythonFunction($d) if ($actual_ctype->{TYPE} eq "UNION"); + $self->FromStructToPythonFunction($d, "in") if ($actual_ctype->{TYPE} eq "STRUCT"); + $self->FromUnionToPythonFunction($d, "in") if ($actual_ctype->{TYPE} eq "UNION"); $self->deindent; $self->pidl("}"); $self->pidl(""); @@ -331,8 +335,8 @@ sub PythonType($$$) $self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, PyObject *in)"); $self->pidl("{"); $self->indent; - $self->FromPythonToStructFunction($d) if ($actual_ctype->{TYPE} eq "STRUCT"); - $self->FromPythonToUnionFunction($d) if ($actual_ctype->{TYPE} eq "UNION"); + $self->FromPythonToStructFunction($d, "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "STRUCT"); + $self->FromPythonToUnionFunction($d, "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION"); $self->deindent; $self->pidl("}"); $self->pidl(""); @@ -414,8 +418,8 @@ sub Interface($$$) $self->pidl("PyObject_HEAD_INIT(NULL) 0,"); $self->pidl(".tp_name = \"$interface->{NAME}\","); $self->pidl(".tp_basicsize = sizeof($interface->{NAME}_InterfaceObject),"); - $self->pidl(".tp_dealloc = interface_$interface->{NAME}_dealloc,"); - $self->pidl(".tp_getattr = interface_$interface->{NAME}_getattr,"); + $self->pidl(".tp_dealloc = (destructor)interface_$interface->{NAME}_dealloc,"); + $self->pidl(".tp_getattr = (getattrfunc)interface_$interface->{NAME}_getattr,"); $self->deindent; $self->pidl("};"); @@ -567,9 +571,9 @@ sub ConvertObjectToPython($$$) die("unknown type ".mapTypeName($ctype) . ": $cvar"); } -sub Parse($$$$) +sub Parse($$$$$) { - my($self,$basename,$ndr,$hdr) = @_; + my($self,$basename,$ndr,$ndr_hdr,$hdr) = @_; my $py_hdr = $hdr; $py_hdr =~ s/ndr_([^\/]+)$/py_$1/g; @@ -582,6 +586,7 @@ sub Parse($$$$) #include #include \"librpc/rpc/dcerpc.h\" #include \"$hdr\" +#include \"$ndr_hdr\" #include \"$py_hdr\" "); diff --git a/source4/pidl/pidl b/source4/pidl/pidl index 500b4dcbfc..4dfd57dc20 100755 --- a/source4/pidl/pidl +++ b/source4/pidl/pidl @@ -671,7 +671,8 @@ sub process_file($) if (defined($opt_python)) { require Parse::Pidl::Samba4::Python; my $generator = new Parse::Pidl::Samba4::Python(); - my ($hdr,$prsr) = $generator->Parse($basename, $ndr, $h_filename); + my ($hdr,$prsr) = $generator->Parse($basename, $ndr, + "$outputdir/ndr_$basename\_c.h", $h_filename); FileSave("$outputdir/py_$basename.c", $prsr); FileSave("$outputdir/py_$basename.h", $hdr); } -- cgit From ce874c0b898eee3dfa8439424350579bf974e98f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 15:51:15 +0100 Subject: pidl/python: Convert unions. (This used to be commit e9037d0f5d222efd4ca04a0f8ce5c39cb3bb6997) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 57 +++++++++++++++++++++------- 1 file changed, 43 insertions(+), 14 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index fc5480b661..8720421088 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -91,36 +91,65 @@ sub EnumAndBitmapConsts($$$) sub FromUnionToPythonFunction($$$) { - my ($self, $type, $name) = @_; + my ($self, $type, $switch, $name) = @_; - #FIXME + $self->pidl("switch ($switch) {"); + $self->indent; + + foreach my $e (@{$type->{ELEMENTS}}) { + my $conv = $self->ConvertObjectToPython($e->{TYPE}, "$name->$e->{NAME}"); + if (defined($e->{CASE})) { + $self->pidl("$e->{CASE}: return $conv;"); + } else { + $self->pidl("default: return $conv;"); + } + } + $self->deindent; + $self->pidl("}"); + + $self->pidl("PyErr_SetString(PyExc_TypeError, \"unknown union level\");"); $self->pidl("return NULL;"); } sub FromStructToPythonFunction($$$) { - my ($self, $type, $name) = @_; + my ($self, $type, $typename, $name) = @_; - $self->pidl("$type->{NAME}\_Object *ret;"); - $self->pidl("ret = PyObject_New($type->{NAME}\_Object, &$type->{NAME}\_ObjectType);"); + $self->pidl("$typename\_Object *ret;"); + $self->pidl("ret = PyObject_New($typename\_Object, &$typename\_ObjectType);"); $self->pidl("ret->object = talloc_reference(NULL, $name);"); $self->pidl("return (PyObject *) ret;"); } sub FromPythonToUnionFunction($$$$) { - my ($self, $type, $mem_ctx, $name) = @_; + my ($self, $type, $switch, $mem_ctx, $name) = @_; - #FIXME + $self->pidl("switch ($switch) {"); + $self->indent; + + foreach my $e (@{$type->{ELEMENTS}}) { + my $conv = $self->ConvertObjectFromPython($e->{TYPE}, "$name"); + if (defined($e->{CASE})) { + $self->pidl("$e->{CASE}: return $conv;"); + } else { + $self->pidl("default: return $conv;"); + } + } + + $self->deindent; + $self->pidl("}"); + $self->pidl(""); + $self->pidl("PyErr_SetString(PyExc_TypeError, \"invalid union level value\");"); $self->pidl("return NULL;"); } -sub FromPythonToStructFunction($$$$) +sub FromPythonToStructFunction($$$$$) { - my ($self, $type, $mem_ctx, $name) = @_; + my ($self, $type, $typename, $mem_ctx, $name) = @_; - $self->pidl("$type->{NAME}\_Object *py_object = ($type->{NAME}_Object *)$name;"); + $self->pidl("$typename\_Object *py_object = ($typename\_Object *)$name;"); $self->pidl("return talloc_reference($mem_ctx, py_object->object);"); } @@ -326,8 +355,8 @@ sub PythonType($$$) $self->pidl("PyObject *py_import_$d->{NAME}(" .mapTypeName($d) . " *in)"); $self->pidl("{"); $self->indent; - $self->FromStructToPythonFunction($d, "in") if ($actual_ctype->{TYPE} eq "STRUCT"); - $self->FromUnionToPythonFunction($d, "in") if ($actual_ctype->{TYPE} eq "UNION"); + $self->FromStructToPythonFunction($actual_ctype, $d->{NAME}, "in") if ($actual_ctype->{TYPE} eq "STRUCT"); + $self->FromUnionToPythonFunction($actual_ctype, "level", "in") if ($actual_ctype->{TYPE} eq "UNION"); $self->deindent; $self->pidl("}"); $self->pidl(""); @@ -335,8 +364,8 @@ sub PythonType($$$) $self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, PyObject *in)"); $self->pidl("{"); $self->indent; - $self->FromPythonToStructFunction($d, "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "STRUCT"); - $self->FromPythonToUnionFunction($d, "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION"); + $self->FromPythonToStructFunction($actual_ctype, $d->{NAME}, "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "STRUCT"); + $self->FromPythonToUnionFunction($actual_ctype, "level", "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION"); $self->deindent; $self->pidl("}"); $self->pidl(""); -- cgit From 252675a5788059dbcc49b175b56fa6c6a35ef74a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 16:44:42 +0100 Subject: python: Add some utility functions for working with Python objects based on talloc pointers. (This used to be commit 9366ddba92e192cd88e12eafba4a90af8c266f1c) --- source4/scripting/python/pytalloc.c | 34 +++++++++++++++++++++++++++++ source4/scripting/python/pytalloc.h | 43 +++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 source4/scripting/python/pytalloc.c create mode 100644 source4/scripting/python/pytalloc.h (limited to 'source4') diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c new file mode 100644 index 0000000000..55ed56a627 --- /dev/null +++ b/source4/scripting/python/pytalloc.c @@ -0,0 +1,34 @@ +/* + Unix SMB/CIFS implementation. + Python/Talloc glue + Copyright (C) Jelmer Vernooij 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" + +void py_talloc_dealloc(PyObject* self) +{ + py_talloc_Object *obj = (py_talloc_Object *)self; + talloc_free(obj->object); + PyObject_Del(self); +} + +PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr) +{ + PyObject *ret = PyObject_New(py_talloc_Object, &py_type); + ret->talloc_ptr = talloc_reference(NULL, ptr); + return ret; +} diff --git a/source4/scripting/python/pytalloc.h b/source4/scripting/python/pytalloc.h new file mode 100644 index 0000000000..93f6b48d82 --- /dev/null +++ b/source4/scripting/python/pytalloc.h @@ -0,0 +1,43 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _PY_TALLOC_H_ +#define _PY_TALLOC_H_ + +#include + +typedef struct { + PyObject_HEAD + void *talloc_ptr; +} py_talloc_Object; + +/* Deallocate a py_talloc_Object */ +void py_talloc_dealloc(PyObject* self); + +/* Retrieve the pointer for a py_talloc_object. Like talloc_get_type() + * but for py_talloc_Objects. */ + +/* FIXME: Call PyErr_SetString(PyExc_TypeError, "expected " __STR(type) ") + * when talloc_get_type() returns NULL. */ +#define py_talloc_get_type(py_obj, type) \ + talloc_get_type(((py_talloc_Object *)py_obj)->talloc_ptr, type) + +PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr); + +#endif /* _PY_TALLOC_H_ */ -- cgit From d06c990dbe89cb3b5996b3470a36de1b821bcdfc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 16:59:15 +0100 Subject: pidl/python: Use new talloc utility functions. (This used to be commit 48cfd44dc088717c0282436148888e45b2632946) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 73 +++++++++------------------- 1 file changed, 24 insertions(+), 49 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 8720421088..4b552a9ba9 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -112,16 +112,6 @@ sub FromUnionToPythonFunction($$$) $self->pidl("return NULL;"); } -sub FromStructToPythonFunction($$$) -{ - my ($self, $type, $typename, $name) = @_; - - $self->pidl("$typename\_Object *ret;"); - $self->pidl("ret = PyObject_New($typename\_Object, &$typename\_ObjectType);"); - $self->pidl("ret->object = talloc_reference(NULL, $name);"); - $self->pidl("return (PyObject *) ret;"); -} - sub FromPythonToUnionFunction($$$$) { my ($self, $type, $switch, $mem_ctx, $name) = @_; @@ -145,33 +135,19 @@ sub FromPythonToUnionFunction($$$$) $self->pidl("return NULL;"); } -sub FromPythonToStructFunction($$$$$) -{ - my ($self, $type, $typename, $mem_ctx, $name) = @_; - - $self->pidl("$typename\_Object *py_object = ($typename\_Object *)$name;"); - $self->pidl("return talloc_reference($mem_ctx, py_object->object);"); -} - sub PythonStruct($$$$) { my ($self, $name, $cname, $d) = @_; $self->pidl("staticforward PyTypeObject $name\_ObjectType;"); - $self->pidl("typedef struct {"); - $self->indent; - $self->pidl("PyObject_HEAD"); - $self->pidl("$cname *object;"); - $self->deindent; - $self->pidl("} $name\_Object;"); $self->pidl(""); $self->pidl("static PyObject *py_$name\_getattr(PyTypeObject *obj, char *name)"); $self->pidl("{"); $self->indent; - $self->pidl("$name\_Object *py_object = ($name\_Object *)obj;"); - $self->pidl("$cname *object = talloc_get_type(py_object->object, $cname);"); + $self->pidl("py_talloc_Object *py_object = (py_talloc_Object *)obj;"); + $self->pidl("$cname *object = py_talloc_get_type(py_object, $cname);"); foreach my $e (@{$d->{ELEMENTS}}) { $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); my $varname = "object->$e->{NAME}"; @@ -186,21 +162,11 @@ sub PythonStruct($$$$) $self->pidl("}"); $self->pidl(""); - $self->pidl("static void py_$name\_dealloc(PyObject* self)"); - $self->pidl("{"); - $self->indent; - $self->pidl("$name\_Object *obj = ($name\_Object *)self;"); - $self->pidl("talloc_free(obj->object);"); - $self->pidl("PyObject_Del(self);"); - $self->deindent; - $self->pidl("}"); - $self->pidl(""); - $self->pidl("static PyObject *py_$name\_setattr(PyTypeObject *obj, char *name, PyObject *value)"); $self->pidl("{"); $self->indent; - $self->pidl("$name\_Object *py_object = ($name\_Object *)obj;"); - $self->pidl("$cname *object = talloc_get_type(py_object->object, $cname);"); + $self->pidl("py_talloc_Object *py_object = (py_talloc_Object *)obj;"); + $self->pidl("$cname *object = py_talloc_get_type(py_object, $cname);"); foreach my $e (@{$d->{ELEMENTS}}) { $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); my $varname = "object->$e->{NAME}"; @@ -220,8 +186,8 @@ sub PythonStruct($$$$) $self->indent; $self->pidl("PyObject_HEAD_INIT(NULL) 0,"); $self->pidl(".tp_name = \"$name\","); - $self->pidl(".tp_basicsize = sizeof($name\_Object),"); - $self->pidl(".tp_dealloc = (destructor)py_$name\_dealloc,"); + $self->pidl(".tp_basicsize = sizeof(py_talloc_Object),"); + $self->pidl(".tp_dealloc = (destructor)py_talloc_dealloc,"); $self->pidl(".tp_getattr = (getattrfunc)py_$name\_getattr,"); $self->pidl(".tp_setattr = (setattrfunc)py_$name\_setattr,"); $self->deindent; @@ -233,9 +199,8 @@ sub PythonStruct($$$$) $self->pidl("static PyObject *$py_fnname(PyObject *self, PyObject *args)"); $self->pidl("{"); $self->indent; - $self->pidl("$name\_Object *ret;"); - $self->pidl("ret = PyObject_New($name\_Object, &$name\_ObjectType);"); - $self->pidl("return (PyObject *) ret;"); + $self->pidl("$cname *ret = talloc_zero(NULL, $cname);"); + $self->pidl("return py_talloc_import(&$name\_ObjectType, ret);"); $self->deindent; $self->pidl("}"); $self->pidl(""); @@ -351,11 +316,10 @@ sub PythonType($$$) $self->EnumAndBitmapConsts($d->{NAME}, $d->{DATA}); } - if ($actual_ctype->{TYPE} eq "UNION" or $actual_ctype->{TYPE} eq "STRUCT") { + if ($actual_ctype->{TYPE} eq "UNION") { $self->pidl("PyObject *py_import_$d->{NAME}(" .mapTypeName($d) . " *in)"); $self->pidl("{"); $self->indent; - $self->FromStructToPythonFunction($actual_ctype, $d->{NAME}, "in") if ($actual_ctype->{TYPE} eq "STRUCT"); $self->FromUnionToPythonFunction($actual_ctype, "level", "in") if ($actual_ctype->{TYPE} eq "UNION"); $self->deindent; $self->pidl("}"); @@ -364,7 +328,6 @@ sub PythonType($$$) $self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, PyObject *in)"); $self->pidl("{"); $self->indent; - $self->FromPythonToStructFunction($actual_ctype, $d->{NAME}, "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "STRUCT"); $self->FromPythonToUnionFunction($actual_ctype, "level", "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION"); $self->deindent; $self->pidl("}"); @@ -516,6 +479,14 @@ sub ConvertObjectFromPython($$$) return "PyInt_AsLong($cvar)"; } + if ($actual_ctype->{TYPE} eq "STRUCT") { + return "py_talloc_get_type($cvar, " . mapTypeName($ctype) . ")"; + } + + if ($actual_ctype->{TYPE} eq "UNION") { + return "py_export_$ctype->{NAME}($cvar)"; + } + return "FIXME($cvar)"; } @@ -556,12 +527,15 @@ sub ConvertObjectToPython($$$) return "PyInt_FromLong($cvar)"; } - if ($ctype->{TYPE} eq "TYPEDEF" and ( - $actual_ctype->{TYPE} eq "STRUCT" or - $actual_ctype->{TYPE} eq "UNION")) { + if ($ctype->{TYPE} eq "TYPEDEF" and $actual_ctype->{TYPE} eq "UNION") { return "py_import_$ctype->{NAME}($cvar)"; } + if ($ctype->{TYPE} eq "TYPEDEF" and $actual_ctype->{TYPE} eq "STRUCT") { + # FIXME: if $cvar is not a pointer, do a talloc_dup() + return "py_talloc_import(&$ctype->{NAME}_ObjectType, $cvar)"; + } + if ($actual_ctype->{TYPE} eq "SCALAR" and expandAlias($actual_ctype->{NAME}) eq "DATA_BLOB") { return "PyString_FromStringAndSize($cvar->data, $cvar->length)"; @@ -614,6 +588,7 @@ sub Parse($$$$$) #include \"includes.h\" #include #include \"librpc/rpc/dcerpc.h\" +#include \"scripting/python/pytalloc.h\" #include \"$hdr\" #include \"$ndr_hdr\" #include \"$py_hdr\" -- cgit From 915f1589252be8cb9fb86eed479e328371e355e1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 17:15:56 +0100 Subject: pidl/python: Support more scalar types when converting from Python. (This used to be commit 1f3bbb65e5a46715c49225eecc760faaf5dbb9d7) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 67 +++++++++++++++++++--------- 1 file changed, 47 insertions(+), 20 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 4b552a9ba9..1c0cafc050 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -120,7 +120,7 @@ sub FromPythonToUnionFunction($$$$) $self->indent; foreach my $e (@{$type->{ELEMENTS}}) { - my $conv = $self->ConvertObjectFromPython($e->{TYPE}, "$name"); + my $conv = $self->ConvertObjectFromPython($mem_ctx, $e->{TYPE}, "$name"); if (defined($e->{CASE})) { $self->pidl("$e->{CASE}: return $conv;"); } else { @@ -143,11 +143,10 @@ sub PythonStruct($$$$) $self->pidl(""); - $self->pidl("static PyObject *py_$name\_getattr(PyTypeObject *obj, char *name)"); + $self->pidl("static PyObject *py_$name\_getattr(PyObject *obj, char *name)"); $self->pidl("{"); $self->indent; - $self->pidl("py_talloc_Object *py_object = (py_talloc_Object *)obj;"); - $self->pidl("$cname *object = py_talloc_get_type(py_object, $cname);"); + $self->pidl("$cname *object = py_talloc_get_type(obj, $cname);"); foreach my $e (@{$d->{ELEMENTS}}) { $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); my $varname = "object->$e->{NAME}"; @@ -162,17 +161,16 @@ sub PythonStruct($$$$) $self->pidl("}"); $self->pidl(""); - $self->pidl("static PyObject *py_$name\_setattr(PyTypeObject *obj, char *name, PyObject *value)"); + $self->pidl("static PyObject *py_$name\_setattr(PyObject *obj, char *name, PyObject *value)"); $self->pidl("{"); $self->indent; - $self->pidl("py_talloc_Object *py_object = (py_talloc_Object *)obj;"); $self->pidl("$cname *object = py_talloc_get_type(py_object, $cname);"); foreach my $e (@{$d->{ELEMENTS}}) { $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); my $varname = "object->$e->{NAME}"; $self->indent; $self->pidl("/* FIXME: talloc_free($varname) if necessary */"); - $self->pidl("$varname = " . $self->ConvertObjectFromPython($e->{TYPE}, "value") . ";"); + $self->pidl("$varname = " . $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value") . ";"); $self->deindent; $self->pidl("}"); } @@ -187,9 +185,9 @@ sub PythonStruct($$$$) $self->pidl("PyObject_HEAD_INIT(NULL) 0,"); $self->pidl(".tp_name = \"$name\","); $self->pidl(".tp_basicsize = sizeof(py_talloc_Object),"); - $self->pidl(".tp_dealloc = (destructor)py_talloc_dealloc,"); - $self->pidl(".tp_getattr = (getattrfunc)py_$name\_getattr,"); - $self->pidl(".tp_setattr = (setattrfunc)py_$name\_setattr,"); + $self->pidl(".tp_dealloc = py_talloc_dealloc,"); + $self->pidl(".tp_getattr = py_$name\_getattr,"); + $self->pidl(".tp_setattr = py_$name\_setattr,"); $self->deindent; $self->pidl("};"); @@ -240,7 +238,7 @@ sub PythonFunction($$$) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - $self->pidl("r.in.$e->{NAME} = " . $self->ConvertObjectFromPython($e->{TYPE}, "py_$e->{NAME}") . ";"); + $self->pidl("r.in.$e->{NAME} = " . $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "py_$e->{NAME}") . ";"); } } $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);"); @@ -396,10 +394,10 @@ sub Interface($$$) $self->pidl("}"); $self->pidl(""); - $self->pidl("static PyObject *interface_$interface->{NAME}_getattr(PyTypeObject *obj, char *name)"); + $self->pidl("static PyObject *interface_$interface->{NAME}_getattr(PyObject *obj, char *name)"); $self->pidl("{"); $self->indent; - $self->pidl("return Py_FindMethod(interface_$interface->{NAME}\_methods, (PyObject *)obj, name);"); + $self->pidl("return Py_FindMethod(interface_$interface->{NAME}\_methods, obj, name);"); $self->deindent; $self->pidl("}"); @@ -454,9 +452,9 @@ sub register_module_method($$$$$) push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc]) } -sub ConvertObjectFromPython($$$) +sub ConvertObjectFromPython($$$$) { - my ($self, $ctype, $cvar) = @_; + my ($self, $mem_ctx, $ctype, $cvar) = @_; die("undef type for $cvar") unless(defined($ctype)); @@ -475,7 +473,7 @@ sub ConvertObjectFromPython($$$) if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or $actual_ctype->{TYPE} eq "SCALAR" and ( - expandAlias($actual_ctype->{NAME}) =~ /^(uint[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong)$/)) { + expandAlias($actual_ctype->{NAME}) =~ /^(u?int[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong|udlongr)$/)) { return "PyInt_AsLong($cvar)"; } @@ -487,7 +485,37 @@ sub ConvertObjectFromPython($$$) return "py_export_$ctype->{NAME}($cvar)"; } - return "FIXME($cvar)"; + if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "DATA_BLOB") { + return "data_blob_talloc($mem_ctx, PyString_AsString($cvar), PyString_Size($cvar))"; + } + + if ($actual_ctype->{TYPE} eq "SCALAR" and + ($actual_ctype->{NAME} eq "string" or $actual_ctype->{NAME} eq "nbt_string" or $actual_ctype->{NAME} eq "nbt_name" or $actual_ctype->{NAME} eq "wrepl_nbt_name")) { + return "talloc_strdup($mem_ctx, PyString_AsString($cvar))"; + } + + if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv4address") { + return "FIXME($cvar)"; + } + + + if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") { + return "PyInt_AsLong($cvar)"; + } + + if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") { + return "PyInt_AsLong($cvar)"; + } + + if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") { + return "FIXME($cvar)"; + } + + if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "pointer") { + return "PyCObject_AsVoidPtr($cvar)"; + } + + die("unknown type ".mapTypeName($ctype) . ": $cvar"); } sub ConvertObjectToPython($$$) @@ -546,11 +574,11 @@ sub ConvertObjectToPython($$$) } if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") { - return "PyInt_FromLong($cvar->v)"; + return "PyInt_FromLong(NT_STATUS_V($cvar))"; } if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") { - return "PyInt_FromLong($cvar->v)"; + return "PyInt_FromLong(W_ERROR_V($cvar))"; } if ($actual_ctype->{TYPE} eq "SCALAR" and @@ -570,7 +598,6 @@ sub ConvertObjectToPython($$$) return "PyCObject_FromVoidPtr($cvar, talloc_free)"; } - die("unknown type ".mapTypeName($ctype) . ": $cvar"); } -- cgit From be01d080247c70ec260763adc7711976c8ee19fc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 18:05:43 +0100 Subject: pidl/python: Work towards supporting more complex types (arrays, etc). (This used to be commit 49d91a1a92e226c015db86ddc9ef772030415d76) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 191 ++++++++++++++++----------- 1 file changed, 115 insertions(+), 76 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 1c0cafc050..545d233d08 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -97,7 +97,13 @@ sub FromUnionToPythonFunction($$$) $self->indent; foreach my $e (@{$type->{ELEMENTS}}) { - my $conv = $self->ConvertObjectToPython($e->{TYPE}, "$name->$e->{NAME}"); + my $conv; + + if ($e->{NAME}) { + $conv = $self->ConvertObjectToPython($e->{TYPE}, "$name->$e->{NAME}"); + } else { + $conv = "Py_None"; + } if (defined($e->{CASE})) { $self->pidl("$e->{CASE}: return $conv;"); } else { @@ -112,27 +118,46 @@ sub FromUnionToPythonFunction($$$) $self->pidl("return NULL;"); } -sub FromPythonToUnionFunction($$$$) +sub FromPythonToUnionFunction($$$$$) { - my ($self, $type, $switch, $mem_ctx, $name) = @_; + my ($self, $type, $typename, $switch, $mem_ctx, $name) = @_; + + my $has_default = 0; + + $self->pidl("$typename *ret = talloc_zero($mem_ctx, $typename);"); $self->pidl("switch ($switch) {"); $self->indent; foreach my $e (@{$type->{ELEMENTS}}) { - my $conv = $self->ConvertObjectFromPython($mem_ctx, $e->{TYPE}, "$name"); if (defined($e->{CASE})) { - $self->pidl("$e->{CASE}: return $conv;"); + $self->pidl("$e->{CASE}:"); } else { - $self->pidl("default: return $conv;"); + $has_default = 1; + $self->pidl("default:"); } + $self->indent; + if ($e->{NAME}) { + $self->ConvertObjectFromPython($mem_ctx, $e->{TYPE}, $name, "ret->$e->{NAME}"); + } + $self->pidl("break;"); + $self->deindent; + $self->pidl(""); + } + + if (!$has_default) { + $self->pidl("default:"); + $self->indent; + $self->pidl("PyErr_SetString(PyExc_TypeError, \"invalid union level value\");"); + $self->pidl("talloc_free(ret);"); + $self->pidl("ret = NULL;"); + $self->deindent; } $self->deindent; $self->pidl("}"); $self->pidl(""); - $self->pidl("PyErr_SetString(PyExc_TypeError, \"invalid union level value\");"); - $self->pidl("return NULL;"); + $self->pidl("return ret;"); } sub PythonStruct($$$$) @@ -161,21 +186,22 @@ sub PythonStruct($$$$) $self->pidl("}"); $self->pidl(""); - $self->pidl("static PyObject *py_$name\_setattr(PyObject *obj, char *name, PyObject *value)"); + $self->pidl("static int py_$name\_setattr(PyObject *py_obj, char *name, PyObject *value)"); $self->pidl("{"); $self->indent; - $self->pidl("$cname *object = py_talloc_get_type(py_object, $cname);"); + $self->pidl("$cname *object = py_talloc_get_type(py_obj, $cname);"); foreach my $e (@{$d->{ELEMENTS}}) { $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); my $varname = "object->$e->{NAME}"; $self->indent; $self->pidl("/* FIXME: talloc_free($varname) if necessary */"); - $self->pidl("$varname = " . $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value") . ";"); + $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value", $varname); + $self->pidl("return 0;"); $self->deindent; $self->pidl("}"); } $self->pidl("PyErr_SetString(PyExc_AttributeError, \"no such attribute\");"); - $self->pidl("return NULL;"); + $self->pidl("return -1;"); $self->deindent; $self->pidl("}"); $self->pidl(""); @@ -238,7 +264,7 @@ sub PythonFunction($$$) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - $self->pidl("r.in.$e->{NAME} = " . $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "py_$e->{NAME}") . ";"); + $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "py_$e->{NAME}", "r.in.$e->{NAME}"); } } $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);"); @@ -303,7 +329,7 @@ sub PythonType($$$) $fn_name =~ s/^$interface->{NAME}_//; $fn_name =~ s/^$basename\_//; - $self->register_module_method($fn_name, $py_fnname, "METH_VARARGS|METH_KEYWORDS", "NULL"); + $self->register_module_method($fn_name, $py_fnname, "METH_NOARGS", "NULL"); } if ($d->{TYPE} eq "ENUM" or $d->{TYPE} eq "BITMAP") { @@ -315,7 +341,7 @@ sub PythonType($$$) } if ($actual_ctype->{TYPE} eq "UNION") { - $self->pidl("PyObject *py_import_$d->{NAME}(" .mapTypeName($d) . " *in)"); + $self->pidl("PyObject *py_import_$d->{NAME}(int level, " .mapTypeName($d) . " *in)"); $self->pidl("{"); $self->indent; $self->FromUnionToPythonFunction($actual_ctype, "level", "in") if ($actual_ctype->{TYPE} eq "UNION"); @@ -323,10 +349,10 @@ sub PythonType($$$) $self->pidl("}"); $self->pidl(""); - $self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, PyObject *in)"); + $self->pidl(mapTypeName($d) . " *py_export_$d->{NAME}(TALLOC_CTX *mem_ctx, int level, PyObject *in)"); $self->pidl("{"); $self->indent; - $self->FromPythonToUnionFunction($actual_ctype, "level", "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION"); + $self->FromPythonToUnionFunction($actual_ctype, mapTypeName($d), "level", "mem_ctx", "in") if ($actual_ctype->{TYPE} eq "UNION"); $self->deindent; $self->pidl("}"); $self->pidl(""); @@ -452,9 +478,9 @@ sub register_module_method($$$$$) push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc]) } -sub ConvertObjectFromPython($$$$) +sub ConvertObjectFromPython($$$$$) { - my ($self, $mem_ctx, $ctype, $cvar) = @_; + my ($self, $mem_ctx, $ctype, $cvar, $target) = @_; die("undef type for $cvar") unless(defined($ctype)); @@ -463,7 +489,8 @@ sub ConvertObjectFromPython($$$$) } if (ref($ctype) ne "HASH") { - return "FIXME($cvar)"; + $self->pidl("$target = FIXME($cvar);"); + return; } my $actual_ctype = $ctype; @@ -474,64 +501,102 @@ sub ConvertObjectFromPython($$$$) if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or $actual_ctype->{TYPE} eq "SCALAR" and ( expandAlias($actual_ctype->{NAME}) =~ /^(u?int[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong|udlongr)$/)) { - return "PyInt_AsLong($cvar)"; + $self->pidl("$target = PyInt_AsLong($cvar);"); + return; } if ($actual_ctype->{TYPE} eq "STRUCT") { - return "py_talloc_get_type($cvar, " . mapTypeName($ctype) . ")"; + $self->pidl("$target = py_talloc_get_type($cvar, " . mapTypeName($ctype) . ");"); + return; } if ($actual_ctype->{TYPE} eq "UNION") { - return "py_export_$ctype->{NAME}($cvar)"; + $self->pidl("$target = py_export_$ctype->{NAME}($cvar);"); + return; } if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "DATA_BLOB") { - return "data_blob_talloc($mem_ctx, PyString_AsString($cvar), PyString_Size($cvar))"; + $self->pidl("$target = data_blob_talloc($mem_ctx, PyString_AsString($cvar), PyString_Size($cvar));"); + return; } if ($actual_ctype->{TYPE} eq "SCALAR" and ($actual_ctype->{NAME} eq "string" or $actual_ctype->{NAME} eq "nbt_string" or $actual_ctype->{NAME} eq "nbt_name" or $actual_ctype->{NAME} eq "wrepl_nbt_name")) { - return "talloc_strdup($mem_ctx, PyString_AsString($cvar))"; + $self->pidl("$target = talloc_strdup($mem_ctx, PyString_AsString($cvar));"); + return; } if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv4address") { - return "FIXME($cvar)"; + $self->pidl("$target = FIXME($cvar);"); + return; } if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") { - return "PyInt_AsLong($cvar)"; + $self->pidl("$target = PyInt_AsLong($cvar);"); + return; } if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") { - return "PyInt_AsLong($cvar)"; + $self->pidl("$target = PyInt_AsLong($cvar);"); + return; } if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") { - return "FIXME($cvar)"; + $self->pidl("$target = FIXME($cvar);"); + return; } if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "pointer") { - return "PyCObject_AsVoidPtr($cvar)"; + $self->pidl("$target = PyCObject_AsVoidPtr($cvar);"); + return; } die("unknown type ".mapTypeName($ctype) . ": $cvar"); } -sub ConvertObjectToPython($$$) +sub ConvertScalarToPython($$$) { - my ($self, $ctype, $cvar) = @_; + my ($self, $ctypename, $cvar) = @_; - if ($cvar =~ /^[0-9]+$/ or $cvar =~ /^0x[0-9a-fA-F]+$/) { + $ctypename = expandAlias($ctypename); + + if ($ctypename =~ /^(int|long|char|u?int[0-9]+|hyper|dlong|udlong|udlongr|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/) { return "PyInt_FromLong($cvar)"; } - die("undef type for $cvar") unless(defined($ctype)); + if ($ctypename eq "DATA_BLOB") { + return "PyString_FromStringAndSize($cvar->data, $cvar->length)"; + } + + if ($ctypename eq "NTSTATUS") { + return "PyInt_FromLong(NT_STATUS_V($cvar))"; + } + + if ($ctypename eq "WERROR") { + return "PyInt_FromLong(W_ERROR_V($cvar))"; + } - if ($cvar =~ /^".*"$/) { + if (($ctypename eq "string" or $ctypename eq "nbt_string" or $ctypename eq "nbt_name" or $ctypename eq "wrepl_nbt_name")) { return "PyString_FromString($cvar)"; } + if ($ctypename eq "string_array") { return "FIXME($cvar)"; } + + if ($$ctypename eq "ipv4address") { return "FIXME($cvar)"; } + if ($ctypename eq "pointer") { + return "PyCObject_FromVoidPtr($cvar, talloc_free)"; + } + + die("Unknown scalar type $ctypename"); +} + +sub ConvertObjectToPython($$$) +{ + my ($self, $ctype, $cvar) = @_; + + die("undef type for $cvar") unless(defined($ctype)); + if (ref($ctype) ne "HASH") { if (not hasType($ctype)) { if (ref($ctype) eq "HASH") { @@ -550,54 +615,19 @@ sub ConvertObjectToPython($$$) } if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or - ($actual_ctype->{TYPE} eq "SCALAR" and - expandAlias($actual_ctype->{NAME}) =~ /^(int|long|char|u?int[0-9]+|hyper|dlong|udlong|udlongr|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/)) { - return "PyInt_FromLong($cvar)"; + ($actual_ctype->{TYPE} eq "SCALAR") { + return $self->ConvertScalarToPython($actual_ctype->{NAME}, $cvar); } - if ($ctype->{TYPE} eq "TYPEDEF" and $actual_ctype->{TYPE} eq "UNION") { + if ($actual_ctype->{TYPE} eq "UNION") { return "py_import_$ctype->{NAME}($cvar)"; } - if ($ctype->{TYPE} eq "TYPEDEF" and $actual_ctype->{TYPE} eq "STRUCT") { + if ($actual_ctype->{TYPE} eq "STRUCT") { # FIXME: if $cvar is not a pointer, do a talloc_dup() return "py_talloc_import(&$ctype->{NAME}_ObjectType, $cvar)"; } - if ($actual_ctype->{TYPE} eq "SCALAR" and - expandAlias($actual_ctype->{NAME}) eq "DATA_BLOB") { - return "PyString_FromStringAndSize($cvar->data, $cvar->length)"; - } - - if ($ctype->{TYPE} eq "STRUCT" or $ctype->{TYPE} eq "UNION") { - return "py_import_$ctype->{TYPE}_$ctype->{NAME}($cvar)"; - } - - if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") { - return "PyInt_FromLong(NT_STATUS_V($cvar))"; - } - - if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") { - return "PyInt_FromLong(W_ERROR_V($cvar))"; - } - - if ($actual_ctype->{TYPE} eq "SCALAR" and - ($actual_ctype->{NAME} eq "string" or $actual_ctype->{NAME} eq "nbt_string" or $actual_ctype->{NAME} eq "nbt_name" or $actual_ctype->{NAME} eq "wrepl_nbt_name")) { - return "PyString_FromString($cvar)"; - } - - if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") { - return "FIXME($cvar)"; - } - - if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv4address") { - return "FIXME($cvar)"; - } - - if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "pointer") { - return "PyCObject_FromVoidPtr($cvar, talloc_free)"; - } - die("unknown type ".mapTypeName($ctype) . ": $cvar"); } @@ -646,8 +676,17 @@ sub Parse($$$$$) $self->pidl("PyObject *m;"); $self->pidl("m = Py_InitModule(\"$basename\", $basename\_methods);"); foreach (keys %{$self->{constants}}) { - # FIXME: Handle non-string constants - $self->pidl("PyModule_AddObject(m, \"$_\", " . $self->ConvertObjectToPython($self->{constants}->{$_}->[0], $self->{constants}->{$_}->[1]) . ");"); + my $py_obj; + my ($ctype, $cvar) = @{$self->{constants}->{$_}}; + if ($cvar =~ /^[0-9]+$/ or $cvar =~ /^0x[0-9a-fA-F]+$/) { + $py_obj = "PyInt_FromLong($cvar)"; + } elsif ($cvar =~ /^".*"$/) { + $py_obj = "PyString_FromString($cvar)"; + } else { + $py_obj = $self->ConvertScalarToPython($ctype, $cvar); + } + + $self->pidl("PyModule_AddObject(m, \"$_\", $py_obj);"); } $self->deindent; $self->pidl("}"); -- cgit From a99dff8660ca2d168523b7264d9208a8a12ca5cc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 18:15:12 +0100 Subject: pidl: Move Generate*Env functions to Parse::Pidl::Samba4::Header because they only work with the structures generated by that file. (This used to be commit 9aeb7f31b0fc3b9679e5af07e65e79bc8073c4e1) --- source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm | 4 +- source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm | 2 +- source4/pidl/lib/Parse/Pidl/Samba4/Header.pm | 71 +++++++++++++++++++++++- source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 65 +--------------------- source4/pidl/tests/header.pl | 54 +++++++++++++++++- source4/pidl/tests/samba-ndr.pl | 51 +---------------- source4/pidl/tests/samba3-cli.pl | 2 +- 7 files changed, 130 insertions(+), 119 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm index b7372a802a..86b8951026 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm @@ -9,7 +9,7 @@ package Parse::Pidl::Samba3::ClientNDR; use Exporter; @ISA = qw(Exporter); -@EXPORT_OK = qw(GenerateFunctionInEnv ParseFunction $res $res_hdr); +@EXPORT_OK = qw(ParseFunction $res $res_hdr); use strict; use Parse::Pidl qw(fatal warning); @@ -17,7 +17,7 @@ use Parse::Pidl::Typelist qw(hasType getType mapTypeName scalar_is_reference); use Parse::Pidl::Util qw(has_property is_constant ParseExpr); use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred); use Parse::Pidl::Samba4 qw(DeclLong); -use Parse::Pidl::Samba4::NDR::Parser qw(GenerateFunctionInEnv); +use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv); use vars qw($VERSION); $VERSION = '0.01'; diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm b/source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm index 24270340b9..efb3f2858d 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/EJS.pm @@ -15,7 +15,7 @@ use Parse::Pidl::Typelist qw(typeHasBody); use Parse::Pidl::CUtil qw(get_pointer_to get_value_of); use Parse::Pidl::Util qw(has_property ParseExpr); use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel); -use Parse::Pidl::Samba4::NDR::Parser qw(GenerateStructEnv GenerateFunctionInEnv +use Parse::Pidl::Samba4::Header qw(GenerateStructEnv GenerateFunctionInEnv GenerateFunctionOutEnv); use vars qw($VERSION); diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm index b96a58783c..06e9ec4b9f 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm @@ -6,10 +6,15 @@ package Parse::Pidl::Samba4::Header; +require Exporter; + +@ISA = qw(Exporter); +@EXPORT_OK = qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv); + use strict; use Parse::Pidl qw(fatal); use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference); -use Parse::Pidl::Util qw(has_property is_constant unmake_str); +use Parse::Pidl::Util qw(has_property is_constant unmake_str ParseExpr); use Parse::Pidl::Samba4 qw(is_intree ElementStars ArrayBrackets choose_header); use vars qw($VERSION); @@ -406,4 +411,68 @@ sub Parse($) return $res; } +sub GenerateStructEnv($$) +{ + my ($x, $v) = @_; + my %env; + + foreach my $e (@{$x->{ELEMENTS}}) { + $env{$e->{NAME}} = "$v->$e->{NAME}"; + } + + $env{"this"} = $v; + + return \%env; +} + +sub EnvSubstituteValue($$) +{ + my ($env,$s) = @_; + + # Substitute the value() values in the env + foreach my $e (@{$s->{ELEMENTS}}) { + next unless (defined(my $v = has_property($e, "value"))); + + $env->{$e->{NAME}} = ParseExpr($v, $env, $e); + } + + return $env; +} + +sub GenerateFunctionInEnv($;$) +{ + my ($fn, $base) = @_; + my %env; + + $base = "r->" unless defined($base); + + foreach my $e (@{$fn->{ELEMENTS}}) { + if (grep (/in/, @{$e->{DIRECTION}})) { + $env{$e->{NAME}} = $base."in.$e->{NAME}"; + } + } + + return \%env; +} + +sub GenerateFunctionOutEnv($;$) +{ + my ($fn, $base) = @_; + my %env; + + $base = "r->" unless defined($base); + + foreach my $e (@{$fn->{ELEMENTS}}) { + if (grep (/out/, @{$e->{DIRECTION}})) { + $env{$e->{NAME}} = $base."out.$e->{NAME}"; + } elsif (grep (/in/, @{$e->{DIRECTION}})) { + $env{$e->{NAME}} = $base."in.$e->{NAME}"; + } + } + + return \%env; +} + + + 1; diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm index 8eb2f9ad15..0800a19fab 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm @@ -9,7 +9,7 @@ package Parse::Pidl::Samba4::NDR::Parser; require Exporter; @ISA = qw(Exporter); -@EXPORT_OK = qw(check_null_pointer GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv NeededFunction NeededElement NeededType $res NeededInterface TypeFunctionName ParseElementPrint); +@EXPORT_OK = qw(check_null_pointer NeededFunction NeededElement NeededType $res NeededInterface TypeFunctionName ParseElementPrint); use strict; use Parse::Pidl::Typelist qw(hasType getType mapTypeName typeHasBody); @@ -17,6 +17,7 @@ use Parse::Pidl::Util qw(has_property ParseExpr ParseExprExt print_uuid); use Parse::Pidl::CUtil qw(get_pointer_to get_value_of); use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred); use Parse::Pidl::Samba4 qw(is_intree choose_header); +use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv); use Parse::Pidl qw(warning); use vars qw($VERSION); @@ -193,68 +194,6 @@ sub end_flags($$) } } -sub GenerateStructEnv($$) -{ - my ($x, $v) = @_; - my %env; - - foreach my $e (@{$x->{ELEMENTS}}) { - $env{$e->{NAME}} = "$v->$e->{NAME}"; - } - - $env{"this"} = $v; - - return \%env; -} - -sub EnvSubstituteValue($$) -{ - my ($env,$s) = @_; - - # Substitute the value() values in the env - foreach my $e (@{$s->{ELEMENTS}}) { - next unless (defined(my $v = has_property($e, "value"))); - - $env->{$e->{NAME}} = ParseExpr($v, $env, $e); - } - - return $env; -} - -sub GenerateFunctionInEnv($;$) -{ - my ($fn, $base) = @_; - my %env; - - $base = "r->" unless defined($base); - - foreach my $e (@{$fn->{ELEMENTS}}) { - if (grep (/in/, @{$e->{DIRECTION}})) { - $env{$e->{NAME}} = $base."in.$e->{NAME}"; - } - } - - return \%env; -} - -sub GenerateFunctionOutEnv($;$) -{ - my ($fn, $base) = @_; - my %env; - - $base = "r->" unless defined($base); - - foreach my $e (@{$fn->{ELEMENTS}}) { - if (grep (/out/, @{$e->{DIRECTION}})) { - $env{$e->{NAME}} = $base."out.$e->{NAME}"; - } elsif (grep (/in/, @{$e->{DIRECTION}})) { - $env{$e->{NAME}} = $base."in.$e->{NAME}"; - } - } - - return \%env; -} - ##################################################################### # parse the data of an array - push side sub ParseArrayPushHeader($$$$$$) diff --git a/source4/pidl/tests/header.pl b/source4/pidl/tests/header.pl index 8d0dccf507..db59484444 100755 --- a/source4/pidl/tests/header.pl +++ b/source4/pidl/tests/header.pl @@ -4,12 +4,14 @@ use strict; use warnings; -use Test::More tests => 16; +use Test::More tests => 27; use FindBin qw($RealBin); use lib "$RealBin"; use Util; use Parse::Pidl::Util qw(MyDumper); -use Parse::Pidl::Samba4::Header; +use Parse::Pidl::Samba4::Header qw( + GenerateFunctionInEnv GenerateFunctionOutEnv GenerateStructEnv + EnvSubstituteValue); use Parse::Pidl::IDL qw(parse_string); use Parse::Pidl::NDR; @@ -56,3 +58,51 @@ like(parse_idl("interface p { typedef struct x { int p; } x; };"), like(parse_idl("cpp_quote(\"some-foo\")"), qr/some-foo/sm, "cpp quote"); + +# Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work +my $fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] }; +is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionInEnv($fn)); + +$fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] }; +is_deeply({ "foo" => "r->out.foo" }, GenerateFunctionOutEnv($fn)); + +$fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] }; +is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionInEnv($fn)); + +$fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] }; +is_deeply({ "foo" => "r->out.foo" }, GenerateFunctionOutEnv($fn)); + +$fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] }; +is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionOutEnv($fn)); + +$fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] }; +is_deeply({ }, GenerateFunctionInEnv($fn)); + +$fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] }; +is_deeply({ foo => "r->foo", bar => "r->bar", this => "r" }, + GenerateStructEnv($fn, "r")); + +$fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] }; +is_deeply({ foo => "some->complex.variable->foo", + bar => "some->complex.variable->bar", + this => "some->complex.variable" }, + GenerateStructEnv($fn, "some->complex.variable")); + +$fn = { ELEMENTS => [ { NAME => "foo", PROPERTIES => { value => 3 }} ] }; + +my $env = GenerateStructEnv($fn, "r"); +EnvSubstituteValue($env, $fn); +is_deeply($env, { foo => 3, this => "r" }); + +$fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] }; +$env = GenerateStructEnv($fn, "r"); +EnvSubstituteValue($env, $fn); +is_deeply($env, { foo => 'r->foo', bar => 'r->bar', this => "r" }); + +$fn = { ELEMENTS => [ { NAME => "foo", PROPERTIES => { value => 0 }} ] }; + +$env = GenerateStructEnv($fn, "r"); +EnvSubstituteValue($env, $fn); +is_deeply($env, { foo => 0, this => "r" }); + + diff --git a/source4/pidl/tests/samba-ndr.pl b/source4/pidl/tests/samba-ndr.pl index 05c3c1c0df..a14111961f 100755 --- a/source4/pidl/tests/samba-ndr.pl +++ b/source4/pidl/tests/samba-ndr.pl @@ -4,15 +4,14 @@ use strict; use warnings; -use Test::More tests => 41; +use Test::More tests => 30; use FindBin qw($RealBin); use lib "$RealBin"; use Util; use strict; use Parse::Pidl::Util qw(MyDumper); use Parse::Pidl::Samba4::NDR::Parser qw(check_null_pointer - GenerateFunctionInEnv GenerateFunctionOutEnv GenerateStructEnv - EnvSubstituteValue NeededFunction NeededElement NeededType + NeededFunction NeededElement NeededType NeededInterface TypeFunctionName ParseElementPrint); my $output; @@ -138,52 +137,6 @@ test_warnings("nofile:2: unknown dereferenced expression `r->in.bla'\n", is($output, "if (r->in.bla == NULL) return;"); -# Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work -$fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] }; -is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionInEnv($fn)); - -$fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] }; -is_deeply({ "foo" => "r->out.foo" }, GenerateFunctionOutEnv($fn)); - -$fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] }; -is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionInEnv($fn)); - -$fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] }; -is_deeply({ "foo" => "r->out.foo" }, GenerateFunctionOutEnv($fn)); - -$fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] }; -is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionOutEnv($fn)); - -$fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] }; -is_deeply({ }, GenerateFunctionInEnv($fn)); - -$fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] }; -is_deeply({ foo => "r->foo", bar => "r->bar", this => "r" }, - GenerateStructEnv($fn, "r")); - -$fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] }; -is_deeply({ foo => "some->complex.variable->foo", - bar => "some->complex.variable->bar", - this => "some->complex.variable" }, - GenerateStructEnv($fn, "some->complex.variable")); - -$fn = { ELEMENTS => [ { NAME => "foo", PROPERTIES => { value => 3 }} ] }; - -my $env = GenerateStructEnv($fn, "r"); -EnvSubstituteValue($env, $fn); -is_deeply($env, { foo => 3, this => "r" }); - -$fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] }; -$env = GenerateStructEnv($fn, "r"); -EnvSubstituteValue($env, $fn); -is_deeply($env, { foo => 'r->foo', bar => 'r->bar', this => "r" }); - -$fn = { ELEMENTS => [ { NAME => "foo", PROPERTIES => { value => 0 }} ] }; - -$env = GenerateStructEnv($fn, "r"); -EnvSubstituteValue($env, $fn); -is_deeply($env, { foo => 0, this => "r" }); - my $needed = {}; NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "pull", $needed); is_deeply($needed, { ndr_pull_foo => 1 }); diff --git a/source4/pidl/tests/samba3-cli.pl b/source4/pidl/tests/samba3-cli.pl index 1b2a3c9785..f5b51b7d34 100755 --- a/source4/pidl/tests/samba3-cli.pl +++ b/source4/pidl/tests/samba3-cli.pl @@ -10,7 +10,7 @@ use lib "$RealBin"; use Util; use Parse::Pidl::Util qw(MyDumper); use Parse::Pidl::Samba3::ClientNDR qw(ParseFunction); -use Parse::Pidl::Samba4::NDR::Parser qw(GenerateFunctionInEnv GenerateFunctionOutEnv); +use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv); # Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work my $fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] }; -- cgit From f7a0ef04f00cd44845bcee0a171e4cc05a545350 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 18:38:12 +0100 Subject: pidl/python: Support repr() for python types. (This used to be commit cf3664594d3540db20d32bc844f18e20abfa0d96) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 24 +- source4/py_echo.c | 818 +++++++++++++++++++++++++++ source4/py_echo.h | 8 + source4/scripting/python/pytalloc.c | 10 +- source4/scripting/python/pytalloc.h | 3 + 5 files changed, 855 insertions(+), 8 deletions(-) create mode 100644 source4/py_echo.c create mode 100644 source4/py_echo.h (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 545d233d08..a5f8053834 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -214,6 +214,7 @@ sub PythonStruct($$$$) $self->pidl(".tp_dealloc = py_talloc_dealloc,"); $self->pidl(".tp_getattr = py_$name\_getattr,"); $self->pidl(".tp_setattr = py_$name\_setattr,"); + $self->pidl(".tp_repr = py_talloc_default_repr,"); $self->deindent; $self->pidl("};"); @@ -559,6 +560,8 @@ sub ConvertScalarToPython($$$) { my ($self, $ctypename, $cvar) = @_; + die("expected string for $cvar, not $ctypename") if (ref($ctypename) eq "HASH"); + $ctypename = expandAlias($ctypename); if ($ctypename =~ /^(int|long|char|u?int[0-9]+|hyper|dlong|udlong|udlongr|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/) { @@ -583,7 +586,7 @@ sub ConvertScalarToPython($$$) if ($ctypename eq "string_array") { return "FIXME($cvar)"; } - if ($$ctypename eq "ipv4address") { return "FIXME($cvar)"; } + if ($ctypename eq "ipv4address") { return "FIXME($cvar)"; } if ($ctypename eq "pointer") { return "PyCObject_FromVoidPtr($cvar, talloc_free)"; } @@ -614,8 +617,15 @@ sub ConvertObjectToPython($$$) $actual_ctype = $ctype->{DATA}; } - if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or - ($actual_ctype->{TYPE} eq "SCALAR") { + if ($actual_ctype->{TYPE} eq "ENUM") { + return $self->ConvertScalarToPython(Parse::Pidl::Typelist::enum_type_fn($actual_ctype), $cvar); + } + + if ($actual_ctype->{TYPE} eq "BITMAP") { + return $self->ConvertScalarToPython(Parse::Pidl::Typelist::bitmap_type_fn($actual_ctype), $cvar); + } + + if ($actual_ctype->{TYPE} eq "SCALAR") { return $self->ConvertScalarToPython($actual_ctype->{NAME}, $cvar); } @@ -675,18 +685,18 @@ sub Parse($$$$$) $self->indent; $self->pidl("PyObject *m;"); $self->pidl("m = Py_InitModule(\"$basename\", $basename\_methods);"); - foreach (keys %{$self->{constants}}) { + foreach my $name (keys %{$self->{constants}}) { my $py_obj; - my ($ctype, $cvar) = @{$self->{constants}->{$_}}; + my ($ctype, $cvar) = @{$self->{constants}->{$name}}; if ($cvar =~ /^[0-9]+$/ or $cvar =~ /^0x[0-9a-fA-F]+$/) { $py_obj = "PyInt_FromLong($cvar)"; } elsif ($cvar =~ /^".*"$/) { $py_obj = "PyString_FromString($cvar)"; } else { - $py_obj = $self->ConvertScalarToPython($ctype, $cvar); + $py_obj = $self->ConvertObjectToPython($ctype, $cvar); } - $self->pidl("PyModule_AddObject(m, \"$_\", $py_obj);"); + $self->pidl("PyModule_AddObject(m, \"$name\", $py_obj);"); } $self->deindent; $self->pidl("}"); diff --git a/source4/py_echo.c b/source4/py_echo.c new file mode 100644 index 0000000000..f9cf77deac --- /dev/null +++ b/source4/py_echo.c @@ -0,0 +1,818 @@ + +/* Python wrapper functions auto-generated by pidl */ +#include "includes.h" +#include +#include "librpc/rpc/dcerpc.h" +#include "scripting/python/pytalloc.h" +#include "./ndr_echo.h" +#include "./ndr_echo_c.h" +#include "./py_echo.h" + + +staticforward PyTypeObject echo_info1_ObjectType; + +static PyObject *py_echo_info1_getattr(PyObject *obj, char *name) +{ + struct echo_info1 *object = py_talloc_get_type(obj, struct echo_info1); + if (!strcmp(name, "v")) { + return PyInt_FromLong(object->v); + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return NULL; +} + +static int py_echo_info1_setattr(PyObject *py_obj, char *name, PyObject *value) +{ + struct echo_info1 *object = py_talloc_get_type(py_obj, struct echo_info1); + if (!strcmp(name, "v")) { + /* FIXME: talloc_free(object->v) if necessary */ + object->v = PyInt_AsLong(value); + return 0; + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return -1; +} + +static PyTypeObject echo_info1_ObjectType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "echo_info1", + .tp_basicsize = sizeof(py_talloc_Object), + .tp_dealloc = py_talloc_dealloc, + .tp_getattr = py_echo_info1_getattr, + .tp_setattr = py_echo_info1_setattr, +}; + +static PyObject *py_echo_info1(PyObject *self, PyObject *args) +{ + struct echo_info1 *ret = talloc_zero(NULL, struct echo_info1); + return py_talloc_import(&echo_info1_ObjectType, ret); +} + +staticforward PyTypeObject echo_info2_ObjectType; + +static PyObject *py_echo_info2_getattr(PyObject *obj, char *name) +{ + struct echo_info2 *object = py_talloc_get_type(obj, struct echo_info2); + if (!strcmp(name, "v")) { + return PyInt_FromLong(object->v); + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return NULL; +} + +static int py_echo_info2_setattr(PyObject *py_obj, char *name, PyObject *value) +{ + struct echo_info2 *object = py_talloc_get_type(py_obj, struct echo_info2); + if (!strcmp(name, "v")) { + /* FIXME: talloc_free(object->v) if necessary */ + object->v = PyInt_AsLong(value); + return 0; + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return -1; +} + +static PyTypeObject echo_info2_ObjectType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "echo_info2", + .tp_basicsize = sizeof(py_talloc_Object), + .tp_dealloc = py_talloc_dealloc, + .tp_getattr = py_echo_info2_getattr, + .tp_setattr = py_echo_info2_setattr, +}; + +static PyObject *py_echo_info2(PyObject *self, PyObject *args) +{ + struct echo_info2 *ret = talloc_zero(NULL, struct echo_info2); + return py_talloc_import(&echo_info2_ObjectType, ret); +} + +staticforward PyTypeObject echo_info3_ObjectType; + +static PyObject *py_echo_info3_getattr(PyObject *obj, char *name) +{ + struct echo_info3 *object = py_talloc_get_type(obj, struct echo_info3); + if (!strcmp(name, "v")) { + return PyInt_FromLong(object->v); + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return NULL; +} + +static int py_echo_info3_setattr(PyObject *py_obj, char *name, PyObject *value) +{ + struct echo_info3 *object = py_talloc_get_type(py_obj, struct echo_info3); + if (!strcmp(name, "v")) { + /* FIXME: talloc_free(object->v) if necessary */ + object->v = PyInt_AsLong(value); + return 0; + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return -1; +} + +static PyTypeObject echo_info3_ObjectType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "echo_info3", + .tp_basicsize = sizeof(py_talloc_Object), + .tp_dealloc = py_talloc_dealloc, + .tp_getattr = py_echo_info3_getattr, + .tp_setattr = py_echo_info3_setattr, +}; + +static PyObject *py_echo_info3(PyObject *self, PyObject *args) +{ + struct echo_info3 *ret = talloc_zero(NULL, struct echo_info3); + return py_talloc_import(&echo_info3_ObjectType, ret); +} + +staticforward PyTypeObject echo_info4_ObjectType; + +static PyObject *py_echo_info4_getattr(PyObject *obj, char *name) +{ + struct echo_info4 *object = py_talloc_get_type(obj, struct echo_info4); + if (!strcmp(name, "v")) { + return PyInt_FromLong(object->v); + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return NULL; +} + +static int py_echo_info4_setattr(PyObject *py_obj, char *name, PyObject *value) +{ + struct echo_info4 *object = py_talloc_get_type(py_obj, struct echo_info4); + if (!strcmp(name, "v")) { + /* FIXME: talloc_free(object->v) if necessary */ + object->v = PyInt_AsLong(value); + return 0; + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return -1; +} + +static PyTypeObject echo_info4_ObjectType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "echo_info4", + .tp_basicsize = sizeof(py_talloc_Object), + .tp_dealloc = py_talloc_dealloc, + .tp_getattr = py_echo_info4_getattr, + .tp_setattr = py_echo_info4_setattr, +}; + +static PyObject *py_echo_info4(PyObject *self, PyObject *args) +{ + struct echo_info4 *ret = talloc_zero(NULL, struct echo_info4); + return py_talloc_import(&echo_info4_ObjectType, ret); +} + +staticforward PyTypeObject echo_info5_ObjectType; + +static PyObject *py_echo_info5_getattr(PyObject *obj, char *name) +{ + struct echo_info5 *object = py_talloc_get_type(obj, struct echo_info5); + if (!strcmp(name, "v1")) { + return PyInt_FromLong(object->v1); + } + if (!strcmp(name, "v2")) { + return PyInt_FromLong(object->v2); + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return NULL; +} + +static int py_echo_info5_setattr(PyObject *py_obj, char *name, PyObject *value) +{ + struct echo_info5 *object = py_talloc_get_type(py_obj, struct echo_info5); + if (!strcmp(name, "v1")) { + /* FIXME: talloc_free(object->v1) if necessary */ + object->v1 = PyInt_AsLong(value); + return 0; + } + if (!strcmp(name, "v2")) { + /* FIXME: talloc_free(object->v2) if necessary */ + object->v2 = PyInt_AsLong(value); + return 0; + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return -1; +} + +static PyTypeObject echo_info5_ObjectType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "echo_info5", + .tp_basicsize = sizeof(py_talloc_Object), + .tp_dealloc = py_talloc_dealloc, + .tp_getattr = py_echo_info5_getattr, + .tp_setattr = py_echo_info5_setattr, +}; + +static PyObject *py_echo_info5(PyObject *self, PyObject *args) +{ + struct echo_info5 *ret = talloc_zero(NULL, struct echo_info5); + return py_talloc_import(&echo_info5_ObjectType, ret); +} + +staticforward PyTypeObject echo_info6_ObjectType; + +static PyObject *py_echo_info6_getattr(PyObject *obj, char *name) +{ + struct echo_info6 *object = py_talloc_get_type(obj, struct echo_info6); + if (!strcmp(name, "v1")) { + return PyInt_FromLong(object->v1); + } + if (!strcmp(name, "info1")) { + return py_talloc_import(&echo_info1_ObjectType, object->info1); + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return NULL; +} + +static int py_echo_info6_setattr(PyObject *py_obj, char *name, PyObject *value) +{ + struct echo_info6 *object = py_talloc_get_type(py_obj, struct echo_info6); + if (!strcmp(name, "v1")) { + /* FIXME: talloc_free(object->v1) if necessary */ + object->v1 = PyInt_AsLong(value); + return 0; + } + if (!strcmp(name, "info1")) { + /* FIXME: talloc_free(object->info1) if necessary */ + object->info1 = py_talloc_get_type(value, struct echo_info1); + return 0; + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return -1; +} + +static PyTypeObject echo_info6_ObjectType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "echo_info6", + .tp_basicsize = sizeof(py_talloc_Object), + .tp_dealloc = py_talloc_dealloc, + .tp_getattr = py_echo_info6_getattr, + .tp_setattr = py_echo_info6_setattr, +}; + +static PyObject *py_echo_info6(PyObject *self, PyObject *args) +{ + struct echo_info6 *ret = talloc_zero(NULL, struct echo_info6); + return py_talloc_import(&echo_info6_ObjectType, ret); +} + +staticforward PyTypeObject echo_info7_ObjectType; + +static PyObject *py_echo_info7_getattr(PyObject *obj, char *name) +{ + struct echo_info7 *object = py_talloc_get_type(obj, struct echo_info7); + if (!strcmp(name, "v1")) { + return PyInt_FromLong(object->v1); + } + if (!strcmp(name, "info4")) { + return py_talloc_import(&echo_info4_ObjectType, object->info4); + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return NULL; +} + +static int py_echo_info7_setattr(PyObject *py_obj, char *name, PyObject *value) +{ + struct echo_info7 *object = py_talloc_get_type(py_obj, struct echo_info7); + if (!strcmp(name, "v1")) { + /* FIXME: talloc_free(object->v1) if necessary */ + object->v1 = PyInt_AsLong(value); + return 0; + } + if (!strcmp(name, "info4")) { + /* FIXME: talloc_free(object->info4) if necessary */ + object->info4 = py_talloc_get_type(value, struct echo_info4); + return 0; + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return -1; +} + +static PyTypeObject echo_info7_ObjectType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "echo_info7", + .tp_basicsize = sizeof(py_talloc_Object), + .tp_dealloc = py_talloc_dealloc, + .tp_getattr = py_echo_info7_getattr, + .tp_setattr = py_echo_info7_setattr, +}; + +static PyObject *py_echo_info7(PyObject *self, PyObject *args) +{ + struct echo_info7 *ret = talloc_zero(NULL, struct echo_info7); + return py_talloc_import(&echo_info7_ObjectType, ret); +} + +PyObject *py_import_echo_Info(int level, union echo_Info *in) +{ + switch (level) { + case 1: return py_talloc_import(&echo_info1_ObjectType, in->info1); + case 2: return py_talloc_import(&echo_info2_ObjectType, in->info2); + case 3: return py_talloc_import(&echo_info3_ObjectType, in->info3); + case 4: return py_talloc_import(&echo_info4_ObjectType, in->info4); + case 5: return py_talloc_import(&echo_info5_ObjectType, in->info5); + case 6: return py_talloc_import(&echo_info6_ObjectType, in->info6); + case 7: return py_talloc_import(&echo_info7_ObjectType, in->info7); + } + PyErr_SetString(PyExc_TypeError, "unknown union level"); + return NULL; +} + +union echo_Info *py_export_echo_Info(TALLOC_CTX *mem_ctx, int level, PyObject *in) +{ + union echo_Info *ret = talloc_zero(mem_ctx, union echo_Info); + switch (level) { + case 1: + ret->info1 = py_talloc_get_type(in, struct echo_info1); + break; + + case 2: + ret->info2 = py_talloc_get_type(in, struct echo_info2); + break; + + case 3: + ret->info3 = py_talloc_get_type(in, struct echo_info3); + break; + + case 4: + ret->info4 = py_talloc_get_type(in, struct echo_info4); + break; + + case 5: + ret->info5 = py_talloc_get_type(in, struct echo_info5); + break; + + case 6: + ret->info6 = py_talloc_get_type(in, struct echo_info6); + break; + + case 7: + ret->info7 = py_talloc_get_type(in, struct echo_info7); + break; + + default: + PyErr_SetString(PyExc_TypeError, "invalid union level value"); + talloc_free(ret); + ret = NULL; + } + + return ret; +} + +staticforward PyTypeObject echo_Enum2_ObjectType; + +static PyObject *py_echo_Enum2_getattr(PyObject *obj, char *name) +{ + struct echo_Enum2 *object = py_talloc_get_type(obj, struct echo_Enum2); + if (!strcmp(name, "e1")) { + return PyInt_FromLong(object->e1); + } + if (!strcmp(name, "e2")) { + return PyInt_FromLong(object->e2); + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return NULL; +} + +static int py_echo_Enum2_setattr(PyObject *py_obj, char *name, PyObject *value) +{ + struct echo_Enum2 *object = py_talloc_get_type(py_obj, struct echo_Enum2); + if (!strcmp(name, "e1")) { + /* FIXME: talloc_free(object->e1) if necessary */ + object->e1 = PyInt_AsLong(value); + return 0; + } + if (!strcmp(name, "e2")) { + /* FIXME: talloc_free(object->e2) if necessary */ + object->e2 = PyInt_AsLong(value); + return 0; + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return -1; +} + +static PyTypeObject echo_Enum2_ObjectType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "echo_Enum2", + .tp_basicsize = sizeof(py_talloc_Object), + .tp_dealloc = py_talloc_dealloc, + .tp_getattr = py_echo_Enum2_getattr, + .tp_setattr = py_echo_Enum2_setattr, +}; + +static PyObject *py_echo_Enum2(PyObject *self, PyObject *args) +{ + struct echo_Enum2 *ret = talloc_zero(NULL, struct echo_Enum2); + return py_talloc_import(&echo_Enum2_ObjectType, ret); +} + +PyObject *py_import_echo_Enum3(int level, union echo_Enum3 *in) +{ + switch (level) { + case ECHO_ENUM1: return PyInt_FromLong(in->e1); + case ECHO_ENUM2: return py_talloc_import(&echo_Enum2_ObjectType, in->e2); + } + PyErr_SetString(PyExc_TypeError, "unknown union level"); + return NULL; +} + +union echo_Enum3 *py_export_echo_Enum3(TALLOC_CTX *mem_ctx, int level, PyObject *in) +{ + union echo_Enum3 *ret = talloc_zero(mem_ctx, union echo_Enum3); + switch (level) { + case ECHO_ENUM1: + ret->e1 = PyInt_AsLong(in); + break; + + case ECHO_ENUM2: + ret->e2 = py_talloc_get_type(in, struct echo_Enum2); + break; + + default: + PyErr_SetString(PyExc_TypeError, "invalid union level value"); + talloc_free(ret); + ret = NULL; + } + + return ret; +} + +staticforward PyTypeObject echo_Surrounding_ObjectType; + +static PyObject *py_echo_Surrounding_getattr(PyObject *obj, char *name) +{ + struct echo_Surrounding *object = py_talloc_get_type(obj, struct echo_Surrounding); + if (!strcmp(name, "x")) { + return PyInt_FromLong(object->x); + } + if (!strcmp(name, "surrounding")) { + return PyInt_FromLong(object->surrounding); + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return NULL; +} + +static int py_echo_Surrounding_setattr(PyObject *py_obj, char *name, PyObject *value) +{ + struct echo_Surrounding *object = py_talloc_get_type(py_obj, struct echo_Surrounding); + if (!strcmp(name, "x")) { + /* FIXME: talloc_free(object->x) if necessary */ + object->x = PyInt_AsLong(value); + return 0; + } + if (!strcmp(name, "surrounding")) { + /* FIXME: talloc_free(object->surrounding) if necessary */ + object->surrounding = PyInt_AsLong(value); + return 0; + } + PyErr_SetString(PyExc_AttributeError, "no such attribute"); + return -1; +} + +static PyTypeObject echo_Surrounding_ObjectType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "echo_Surrounding", + .tp_basicsize = sizeof(py_talloc_Object), + .tp_dealloc = py_talloc_dealloc, + .tp_getattr = py_echo_Surrounding_getattr, + .tp_setattr = py_echo_Surrounding_setattr, +}; + +static PyObject *py_echo_Surrounding(PyObject *self, PyObject *args) +{ + struct echo_Surrounding *ret = talloc_zero(NULL, struct echo_Surrounding); + return py_talloc_import(&echo_Surrounding_ObjectType, ret); +} + +staticforward PyTypeObject rpcecho_InterfaceType; +typedef struct { + PyObject_HEAD + struct dcerpc_pipe *pipe; +} rpcecho_InterfaceObject; + +static PyObject *py_echo_AddOne(PyObject *self, PyObject *args) +{ + rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct echo_AddOne r; + PyObject *result; + PyObject *py_in_data; + + ZERO_STRUCT(r.out); + r.in.in_data = PyInt_AsLong(py_in_data); + status = dcerpc_echo_AddOne(iface->pipe, mem_ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); + talloc_free(mem_ctx); + return NULL; + } + + result = PyTuple_New(1); + PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.out_data)); + talloc_free(mem_ctx); + return result; +} + +static PyObject *py_echo_EchoData(PyObject *self, PyObject *args) +{ + rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct echo_EchoData r; + PyObject *result; + PyObject *py_len; + PyObject *py_in_data; + + ZERO_STRUCT(r.out); + r.in.len = PyInt_AsLong(py_len); + r.in.in_data = PyInt_AsLong(py_in_data); + status = dcerpc_echo_EchoData(iface->pipe, mem_ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); + talloc_free(mem_ctx); + return NULL; + } + + result = PyTuple_New(1); + PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.out_data)); + talloc_free(mem_ctx); + return result; +} + +static PyObject *py_echo_SinkData(PyObject *self, PyObject *args) +{ + rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct echo_SinkData r; + PyObject *result; + PyObject *py_len; + PyObject *py_data; + r.in.len = PyInt_AsLong(py_len); + r.in.data = PyInt_AsLong(py_data); + status = dcerpc_echo_SinkData(iface->pipe, mem_ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); + talloc_free(mem_ctx); + return NULL; + } + + result = PyTuple_New(0); + talloc_free(mem_ctx); + return result; +} + +static PyObject *py_echo_SourceData(PyObject *self, PyObject *args) +{ + rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct echo_SourceData r; + PyObject *result; + PyObject *py_len; + + ZERO_STRUCT(r.out); + r.in.len = PyInt_AsLong(py_len); + status = dcerpc_echo_SourceData(iface->pipe, mem_ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); + talloc_free(mem_ctx); + return NULL; + } + + result = PyTuple_New(1); + PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.data)); + talloc_free(mem_ctx); + return result; +} + +static PyObject *py_echo_TestCall(PyObject *self, PyObject *args) +{ + rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct echo_TestCall r; + PyObject *result; + PyObject *py_s1; + + ZERO_STRUCT(r.out); + r.in.s1 = PyInt_AsLong(py_s1); + status = dcerpc_echo_TestCall(iface->pipe, mem_ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); + talloc_free(mem_ctx); + return NULL; + } + + result = PyTuple_New(1); + PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.s2)); + talloc_free(mem_ctx); + return result; +} + +static PyObject *py_echo_TestCall2(PyObject *self, PyObject *args) +{ + rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct echo_TestCall2 r; + PyObject *result; + PyObject *py_level; + + ZERO_STRUCT(r.out); + r.in.level = PyInt_AsLong(py_level); + status = dcerpc_echo_TestCall2(iface->pipe, mem_ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); + talloc_free(mem_ctx); + return NULL; + } + + result = PyTuple_New(2); + PyTuple_SetItem(result, 0, py_import_echo_Info(r.out.info)); + PyTuple_SetItem(result, 1, PyInt_FromLong(NT_STATUS_V(r.out.result))); + talloc_free(mem_ctx); + return result; +} + +static PyObject *py_echo_TestSleep(PyObject *self, PyObject *args) +{ + rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct echo_TestSleep r; + PyObject *result; + PyObject *py_seconds; + r.in.seconds = PyInt_AsLong(py_seconds); + status = dcerpc_echo_TestSleep(iface->pipe, mem_ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); + talloc_free(mem_ctx); + return NULL; + } + + result = PyTuple_New(1); + PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.result)); + talloc_free(mem_ctx); + return result; +} + +static PyObject *py_echo_TestEnum(PyObject *self, PyObject *args) +{ + rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct echo_TestEnum r; + PyObject *result; + PyObject *py_foo1; + PyObject *py_foo2; + PyObject *py_foo3; + + ZERO_STRUCT(r.out); + r.in.foo1 = PyInt_AsLong(py_foo1); + r.in.foo2 = py_talloc_get_type(py_foo2, struct echo_Enum2); + r.in.foo3 = py_export_echo_Enum3(py_foo3); + status = dcerpc_echo_TestEnum(iface->pipe, mem_ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); + talloc_free(mem_ctx); + return NULL; + } + + result = PyTuple_New(3); + PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.foo1)); + PyTuple_SetItem(result, 1, py_talloc_import(&echo_Enum2_ObjectType, r.out.foo2)); + PyTuple_SetItem(result, 2, py_import_echo_Enum3(r.out.foo3)); + talloc_free(mem_ctx); + return result; +} + +static PyObject *py_echo_TestSurrounding(PyObject *self, PyObject *args) +{ + rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct echo_TestSurrounding r; + PyObject *result; + PyObject *py_data; + + ZERO_STRUCT(r.out); + r.in.data = py_talloc_get_type(py_data, struct echo_Surrounding); + status = dcerpc_echo_TestSurrounding(iface->pipe, mem_ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); + talloc_free(mem_ctx); + return NULL; + } + + result = PyTuple_New(1); + PyTuple_SetItem(result, 0, py_talloc_import(&echo_Surrounding_ObjectType, r.out.data)); + talloc_free(mem_ctx); + return result; +} + +static PyObject *py_echo_TestDoublePointer(PyObject *self, PyObject *args) +{ + rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct echo_TestDoublePointer r; + PyObject *result; + PyObject *py_data; + r.in.data = PyInt_AsLong(py_data); + status = dcerpc_echo_TestDoublePointer(iface->pipe, mem_ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); + talloc_free(mem_ctx); + return NULL; + } + + result = PyTuple_New(1); + PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.result)); + talloc_free(mem_ctx); + return result; +} + +static PyMethodDef interface_rpcecho_methods[] = { + { "echo_AddOne", (PyCFunction)py_echo_AddOne, METH_VARARGS|METH_KEYWORDS, NULL }, + { "echo_EchoData", (PyCFunction)py_echo_EchoData, METH_VARARGS|METH_KEYWORDS, NULL }, + { "echo_SinkData", (PyCFunction)py_echo_SinkData, METH_VARARGS|METH_KEYWORDS, NULL }, + { "echo_SourceData", (PyCFunction)py_echo_SourceData, METH_VARARGS|METH_KEYWORDS, NULL }, + { "echo_TestCall", (PyCFunction)py_echo_TestCall, METH_VARARGS|METH_KEYWORDS, NULL }, + { "echo_TestCall2", (PyCFunction)py_echo_TestCall2, METH_VARARGS|METH_KEYWORDS, NULL }, + { "echo_TestSleep", (PyCFunction)py_echo_TestSleep, METH_VARARGS|METH_KEYWORDS, NULL }, + { "echo_TestEnum", (PyCFunction)py_echo_TestEnum, METH_VARARGS|METH_KEYWORDS, NULL }, + { "echo_TestSurrounding", (PyCFunction)py_echo_TestSurrounding, METH_VARARGS|METH_KEYWORDS, NULL }, + { "echo_TestDoublePointer", (PyCFunction)py_echo_TestDoublePointer, METH_VARARGS|METH_KEYWORDS, NULL }, + { NULL, NULL, 0, NULL } +}; + +static void interface_rpcecho_dealloc(PyObject* self) +{ + rpcecho_InterfaceObject *interface = (rpcecho_InterfaceObject *)self; + talloc_free(interface->pipe); + PyObject_Del(self); +} + +static PyObject *interface_rpcecho_getattr(PyObject *obj, char *name) +{ + return Py_FindMethod(interface_rpcecho_methods, obj, name); +} + +static PyTypeObject rpcecho_InterfaceType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "rpcecho", + .tp_basicsize = sizeof(rpcecho_InterfaceObject), + .tp_dealloc = (destructor)interface_rpcecho_dealloc, + .tp_getattr = (getattrfunc)interface_rpcecho_getattr, +}; + +static PyObject *interface_rpcecho(PyObject *self, PyObject *args) +{ + rpcecho_InterfaceObject *ret; + const char *binding_string; + struct cli_credentials *credentials; + struct loadparm_context *lp_ctx; + TALLOC_CTX *mem_ctx = NULL; + NTSTATUS status; + + ret = PyObject_New(rpcecho_InterfaceObject, &rpcecho_InterfaceType); + + status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string, + &ndr_table_rpcecho, credentials, NULL, lp_ctx); + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); + talloc_free(mem_ctx); + return NULL; + } + + return (PyObject *)ret; +} + +static PyMethodDef echo_methods[] = { + { "info1", (PyCFunction)py_echo_info1, METH_NOARGS, NULL }, + { "info2", (PyCFunction)py_echo_info2, METH_NOARGS, NULL }, + { "info3", (PyCFunction)py_echo_info3, METH_NOARGS, NULL }, + { "info4", (PyCFunction)py_echo_info4, METH_NOARGS, NULL }, + { "info5", (PyCFunction)py_echo_info5, METH_NOARGS, NULL }, + { "info6", (PyCFunction)py_echo_info6, METH_NOARGS, NULL }, + { "info7", (PyCFunction)py_echo_info7, METH_NOARGS, NULL }, + { "Enum2", (PyCFunction)py_echo_Enum2, METH_NOARGS, NULL }, + { "Surrounding", (PyCFunction)py_echo_Surrounding, METH_NOARGS, NULL }, + { "rpcecho", (PyCFunction)interface_rpcecho, METH_VARARGS|METH_KEYWORDS, NULL }, + { NULL, NULL, 0, NULL } +}; + +void initecho(void) +{ + PyObject *m; + m = Py_InitModule("echo", echo_methods); + PyModule_AddObject(m, "ECHO_ENUM1", PyInt_FromLong(ECHO_ENUM1)); + PyModule_AddObject(m, "ECHO_ENUM2_32", PyInt_FromLong(ECHO_ENUM2_32)); + PyModule_AddObject(m, "ECHO_ENUM2", PyInt_FromLong(ECHO_ENUM2)); + PyModule_AddObject(m, "ECHO_ENUM1_32", PyInt_FromLong(ECHO_ENUM1_32)); +} diff --git a/source4/py_echo.h b/source4/py_echo.h new file mode 100644 index 0000000000..426bce3b3d --- /dev/null +++ b/source4/py_echo.h @@ -0,0 +1,8 @@ +/* header auto-generated by pidl */ + +#ifndef _HEADER_PYTHON_rpcecho +#define _HEADER_PYTHON_rpcecho + + + +#endif /* _HEADER_NDR_rpcecho */ diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index 55ed56a627..4032ff75a4 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -22,7 +22,7 @@ void py_talloc_dealloc(PyObject* self) { py_talloc_Object *obj = (py_talloc_Object *)self; - talloc_free(obj->object); + talloc_free(obj->talloc_ptr); PyObject_Del(self); } @@ -32,3 +32,11 @@ PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr) ret->talloc_ptr = talloc_reference(NULL, ptr); return ret; } + +PyObject *py_talloc_default_repr(PyObject *py_obj) +{ + py_talloc_Object *obj = (py_talloc_Object *)py_obj; + + return PyString_FromFormat("", + talloc_get_name(obj->talloc_ptr)); +} diff --git a/source4/scripting/python/pytalloc.h b/source4/scripting/python/pytalloc.h index 93f6b48d82..735829bfcb 100644 --- a/source4/scripting/python/pytalloc.h +++ b/source4/scripting/python/pytalloc.h @@ -40,4 +40,7 @@ void py_talloc_dealloc(PyObject* self); PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr); +/* Sane default implementation of reprfunc. */ +PyObject *py_talloc_default_repr(PyObject *py_obj); + #endif /* _PY_TALLOC_H_ */ -- cgit From bfab9862fcdd657a1bddafde49cdd182f89fcf8b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 20:41:34 +0100 Subject: python: Allow wrapping pointers within talloc'ed memory that are not talloc contexts. (This used to be commit 9c038a74113fb55ed5eb12a7d0ae4a46bad9050c) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 44 ++++++++++++++++++---------- source4/scripting/python/pytalloc.c | 10 ++++--- source4/scripting/python/pytalloc.h | 11 +++++-- 3 files changed, 42 insertions(+), 23 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index a5f8053834..cea3889938 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -138,7 +138,7 @@ sub FromPythonToUnionFunction($$$$$) } $self->indent; if ($e->{NAME}) { - $self->ConvertObjectFromPython($mem_ctx, $e->{TYPE}, $name, "ret->$e->{NAME}"); + $self->ConvertObjectFromPython($mem_ctx, $e->{TYPE}, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;"); } $self->pidl("break;"); $self->deindent; @@ -164,8 +164,6 @@ sub PythonStruct($$$$) { my ($self, $name, $cname, $d) = @_; - $self->pidl("staticforward PyTypeObject $name\_ObjectType;"); - $self->pidl(""); $self->pidl("static PyObject *py_$name\_getattr(PyObject *obj, char *name)"); @@ -190,12 +188,15 @@ sub PythonStruct($$$$) $self->pidl("{"); $self->indent; $self->pidl("$cname *object = py_talloc_get_type(py_obj, $cname);"); + $self->pidl("TALLOC_CTX *mem_ctx = py_talloc_get_mem_ctx(py_obj);"); foreach my $e (@{$d->{ELEMENTS}}) { $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); my $varname = "object->$e->{NAME}"; $self->indent; - $self->pidl("/* FIXME: talloc_free($varname) if necessary */"); - $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value", $varname); + if ($e->{ORIGINAL}->{POINTERS} > 0) { + $self->pidl("talloc_free($varname);"); + } + $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value", $varname, "talloc_free(mem_ctx); return -1;"); $self->pidl("return 0;"); $self->deindent; $self->pidl("}"); @@ -206,7 +207,11 @@ sub PythonStruct($$$$) $self->pidl("}"); $self->pidl(""); - $self->pidl("static PyTypeObject $name\_ObjectType = {"); + $self->pidl_hdr("PyAPI_DATA(PyTypeObject) $name\_Type;\n"); + $self->pidl_hdr("#define $name\_Check(op) PyObject_TypeCheck(op, &$name\_Type)\n"); + $self->pidl_hdr("#define $name\_CheckExact(op) ((op)->ob_type == &$name\_Type)\n"); + $self->pidl_hdr("\n"); + $self->pidl("PyTypeObject $name\_Type = {"); $self->indent; $self->pidl("PyObject_HEAD_INIT(NULL) 0,"); $self->pidl(".tp_name = \"$name\","); @@ -225,7 +230,7 @@ sub PythonStruct($$$$) $self->pidl("{"); $self->indent; $self->pidl("$cname *ret = talloc_zero(NULL, $cname);"); - $self->pidl("return py_talloc_import(&$name\_ObjectType, ret);"); + $self->pidl("return py_talloc_import(&$name\_Type, ret);"); $self->deindent; $self->pidl("}"); $self->pidl(""); @@ -265,7 +270,7 @@ sub PythonFunction($$$) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "py_$e->{NAME}", "r.in.$e->{NAME}"); + $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "py_$e->{NAME}", "r.in.$e->{NAME}", "talloc_free(mem_ctx); return NULL;"); } } $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);"); @@ -377,7 +382,7 @@ sub Interface($$$) $self->PythonType($d, $interface, $basename); } - $self->pidl("staticforward PyTypeObject $interface->{NAME}_InterfaceType;"); + $self->pidl_hdr("PyAPI_DATA(PyTypeObject) $interface->{NAME}_InterfaceType;\n"); $self->pidl("typedef struct {"); $self->indent; $self->pidl("PyObject_HEAD"); @@ -430,13 +435,13 @@ sub Interface($$$) $self->pidl(""); - $self->pidl("static PyTypeObject $interface->{NAME}_InterfaceType = {"); + $self->pidl("PyTypeObject $interface->{NAME}_InterfaceType = {"); $self->indent; $self->pidl("PyObject_HEAD_INIT(NULL) 0,"); $self->pidl(".tp_name = \"$interface->{NAME}\","); $self->pidl(".tp_basicsize = sizeof($interface->{NAME}_InterfaceObject),"); - $self->pidl(".tp_dealloc = (destructor)interface_$interface->{NAME}_dealloc,"); - $self->pidl(".tp_getattr = (getattrfunc)interface_$interface->{NAME}_getattr,"); + $self->pidl(".tp_dealloc = interface_$interface->{NAME}_dealloc,"); + $self->pidl(".tp_getattr = interface_$interface->{NAME}_getattr,"); $self->deindent; $self->pidl("};"); @@ -479,9 +484,9 @@ sub register_module_method($$$$$) push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc]) } -sub ConvertObjectFromPython($$$$$) +sub ConvertObjectFromPython($$$$$$) { - my ($self, $mem_ctx, $ctype, $cvar, $target) = @_; + my ($self, $mem_ctx, $ctype, $cvar, $target, $fail) = @_; die("undef type for $cvar") unless(defined($ctype)); @@ -502,12 +507,14 @@ sub ConvertObjectFromPython($$$$$) if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or $actual_ctype->{TYPE} eq "SCALAR" and ( expandAlias($actual_ctype->{NAME}) =~ /^(u?int[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong|udlongr)$/)) { + $self->pidl("PY_CHECK_TYPE(PyInt, $cvar, $fail);"); $self->pidl("$target = PyInt_AsLong($cvar);"); return; } if ($actual_ctype->{TYPE} eq "STRUCT") { - $self->pidl("$target = py_talloc_get_type($cvar, " . mapTypeName($ctype) . ");"); + $self->pidl("PY_CHECK_TYPE($ctype->{NAME}, $cvar, $fail);"); + $self->pidl("$target = py_talloc_get_ptr($cvar);"); return; } @@ -635,7 +642,7 @@ sub ConvertObjectToPython($$$) if ($actual_ctype->{TYPE} eq "STRUCT") { # FIXME: if $cvar is not a pointer, do a talloc_dup() - return "py_talloc_import(&$ctype->{NAME}_ObjectType, $cvar)"; + return "py_talloc_import(&$ctype->{NAME}_Type, $cvar)"; } die("unknown type ".mapTypeName($ctype) . ": $cvar"); @@ -660,6 +667,11 @@ sub Parse($$$$$) #include \"$ndr_hdr\" #include \"$py_hdr\" +#define PY_CHECK_TYPE(type, var, fail) \\ + if (!type ## _Check(var)) {\\ + PyErr_Format(PyExc_TypeError, \"Expected type %s\", type ## _Type.tp_name); \\ + fail; \\ + } "); foreach my $x (@$ndr) { diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index 4032ff75a4..d0b8cb83f2 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -22,14 +22,16 @@ void py_talloc_dealloc(PyObject* self) { py_talloc_Object *obj = (py_talloc_Object *)self; - talloc_free(obj->talloc_ptr); + talloc_free(obj->talloc_ctx); PyObject_Del(self); } -PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr) +PyObject *py_talloc_import(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, + void *ptr) { PyObject *ret = PyObject_New(py_talloc_Object, &py_type); - ret->talloc_ptr = talloc_reference(NULL, ptr); + ret->talloc_ctx = talloc_reference(mem_ctx, ptr); + ret->ptr = ptr; return ret; } @@ -38,5 +40,5 @@ PyObject *py_talloc_default_repr(PyObject *py_obj) py_talloc_Object *obj = (py_talloc_Object *)py_obj; return PyString_FromFormat("", - talloc_get_name(obj->talloc_ptr)); + talloc_get_name(obj->talloc_ctx)); } diff --git a/source4/scripting/python/pytalloc.h b/source4/scripting/python/pytalloc.h index 735829bfcb..aad5840a67 100644 --- a/source4/scripting/python/pytalloc.h +++ b/source4/scripting/python/pytalloc.h @@ -24,7 +24,8 @@ typedef struct { PyObject_HEAD - void *talloc_ptr; + TALLOC_CTX *talloc_ctx; + void *ptr; } py_talloc_Object; /* Deallocate a py_talloc_Object */ @@ -36,9 +37,13 @@ void py_talloc_dealloc(PyObject* self); /* FIXME: Call PyErr_SetString(PyExc_TypeError, "expected " __STR(type) ") * when talloc_get_type() returns NULL. */ #define py_talloc_get_type(py_obj, type) \ - talloc_get_type(((py_talloc_Object *)py_obj)->talloc_ptr, type) + talloc_get_type(py_talloc_get_ptr(py_obj), type) -PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr); +#define py_talloc_get_ptr(py_obj) ((py_talloc_Object *)py_obj)->ptr +#define py_talloc_get_mem_ctx(py_obj) ((py_talloc_Object *)py_obj)->talloc_ctx + +PyObject *py_talloc_import_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr); +#define py_talloc_import(py_type, talloc_ptr) py_talloc_import_ex(py_type, talloc_ptr, talloc_ptr) /* Sane default implementation of reprfunc. */ PyObject *py_talloc_default_repr(PyObject *py_obj); -- cgit From 23c2facc8203c005b603163fc0ac67eda4240b4e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 20:43:10 +0100 Subject: Remove accidently committed files. (This used to be commit 45e7d230385dc8f636157e45f3df4a8cb4e9d587) --- source4/py_echo.c | 818 ------------------------------------------------------ source4/py_echo.h | 8 - 2 files changed, 826 deletions(-) delete mode 100644 source4/py_echo.c delete mode 100644 source4/py_echo.h (limited to 'source4') diff --git a/source4/py_echo.c b/source4/py_echo.c deleted file mode 100644 index f9cf77deac..0000000000 --- a/source4/py_echo.c +++ /dev/null @@ -1,818 +0,0 @@ - -/* Python wrapper functions auto-generated by pidl */ -#include "includes.h" -#include -#include "librpc/rpc/dcerpc.h" -#include "scripting/python/pytalloc.h" -#include "./ndr_echo.h" -#include "./ndr_echo_c.h" -#include "./py_echo.h" - - -staticforward PyTypeObject echo_info1_ObjectType; - -static PyObject *py_echo_info1_getattr(PyObject *obj, char *name) -{ - struct echo_info1 *object = py_talloc_get_type(obj, struct echo_info1); - if (!strcmp(name, "v")) { - return PyInt_FromLong(object->v); - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return NULL; -} - -static int py_echo_info1_setattr(PyObject *py_obj, char *name, PyObject *value) -{ - struct echo_info1 *object = py_talloc_get_type(py_obj, struct echo_info1); - if (!strcmp(name, "v")) { - /* FIXME: talloc_free(object->v) if necessary */ - object->v = PyInt_AsLong(value); - return 0; - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return -1; -} - -static PyTypeObject echo_info1_ObjectType = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "echo_info1", - .tp_basicsize = sizeof(py_talloc_Object), - .tp_dealloc = py_talloc_dealloc, - .tp_getattr = py_echo_info1_getattr, - .tp_setattr = py_echo_info1_setattr, -}; - -static PyObject *py_echo_info1(PyObject *self, PyObject *args) -{ - struct echo_info1 *ret = talloc_zero(NULL, struct echo_info1); - return py_talloc_import(&echo_info1_ObjectType, ret); -} - -staticforward PyTypeObject echo_info2_ObjectType; - -static PyObject *py_echo_info2_getattr(PyObject *obj, char *name) -{ - struct echo_info2 *object = py_talloc_get_type(obj, struct echo_info2); - if (!strcmp(name, "v")) { - return PyInt_FromLong(object->v); - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return NULL; -} - -static int py_echo_info2_setattr(PyObject *py_obj, char *name, PyObject *value) -{ - struct echo_info2 *object = py_talloc_get_type(py_obj, struct echo_info2); - if (!strcmp(name, "v")) { - /* FIXME: talloc_free(object->v) if necessary */ - object->v = PyInt_AsLong(value); - return 0; - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return -1; -} - -static PyTypeObject echo_info2_ObjectType = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "echo_info2", - .tp_basicsize = sizeof(py_talloc_Object), - .tp_dealloc = py_talloc_dealloc, - .tp_getattr = py_echo_info2_getattr, - .tp_setattr = py_echo_info2_setattr, -}; - -static PyObject *py_echo_info2(PyObject *self, PyObject *args) -{ - struct echo_info2 *ret = talloc_zero(NULL, struct echo_info2); - return py_talloc_import(&echo_info2_ObjectType, ret); -} - -staticforward PyTypeObject echo_info3_ObjectType; - -static PyObject *py_echo_info3_getattr(PyObject *obj, char *name) -{ - struct echo_info3 *object = py_talloc_get_type(obj, struct echo_info3); - if (!strcmp(name, "v")) { - return PyInt_FromLong(object->v); - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return NULL; -} - -static int py_echo_info3_setattr(PyObject *py_obj, char *name, PyObject *value) -{ - struct echo_info3 *object = py_talloc_get_type(py_obj, struct echo_info3); - if (!strcmp(name, "v")) { - /* FIXME: talloc_free(object->v) if necessary */ - object->v = PyInt_AsLong(value); - return 0; - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return -1; -} - -static PyTypeObject echo_info3_ObjectType = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "echo_info3", - .tp_basicsize = sizeof(py_talloc_Object), - .tp_dealloc = py_talloc_dealloc, - .tp_getattr = py_echo_info3_getattr, - .tp_setattr = py_echo_info3_setattr, -}; - -static PyObject *py_echo_info3(PyObject *self, PyObject *args) -{ - struct echo_info3 *ret = talloc_zero(NULL, struct echo_info3); - return py_talloc_import(&echo_info3_ObjectType, ret); -} - -staticforward PyTypeObject echo_info4_ObjectType; - -static PyObject *py_echo_info4_getattr(PyObject *obj, char *name) -{ - struct echo_info4 *object = py_talloc_get_type(obj, struct echo_info4); - if (!strcmp(name, "v")) { - return PyInt_FromLong(object->v); - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return NULL; -} - -static int py_echo_info4_setattr(PyObject *py_obj, char *name, PyObject *value) -{ - struct echo_info4 *object = py_talloc_get_type(py_obj, struct echo_info4); - if (!strcmp(name, "v")) { - /* FIXME: talloc_free(object->v) if necessary */ - object->v = PyInt_AsLong(value); - return 0; - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return -1; -} - -static PyTypeObject echo_info4_ObjectType = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "echo_info4", - .tp_basicsize = sizeof(py_talloc_Object), - .tp_dealloc = py_talloc_dealloc, - .tp_getattr = py_echo_info4_getattr, - .tp_setattr = py_echo_info4_setattr, -}; - -static PyObject *py_echo_info4(PyObject *self, PyObject *args) -{ - struct echo_info4 *ret = talloc_zero(NULL, struct echo_info4); - return py_talloc_import(&echo_info4_ObjectType, ret); -} - -staticforward PyTypeObject echo_info5_ObjectType; - -static PyObject *py_echo_info5_getattr(PyObject *obj, char *name) -{ - struct echo_info5 *object = py_talloc_get_type(obj, struct echo_info5); - if (!strcmp(name, "v1")) { - return PyInt_FromLong(object->v1); - } - if (!strcmp(name, "v2")) { - return PyInt_FromLong(object->v2); - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return NULL; -} - -static int py_echo_info5_setattr(PyObject *py_obj, char *name, PyObject *value) -{ - struct echo_info5 *object = py_talloc_get_type(py_obj, struct echo_info5); - if (!strcmp(name, "v1")) { - /* FIXME: talloc_free(object->v1) if necessary */ - object->v1 = PyInt_AsLong(value); - return 0; - } - if (!strcmp(name, "v2")) { - /* FIXME: talloc_free(object->v2) if necessary */ - object->v2 = PyInt_AsLong(value); - return 0; - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return -1; -} - -static PyTypeObject echo_info5_ObjectType = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "echo_info5", - .tp_basicsize = sizeof(py_talloc_Object), - .tp_dealloc = py_talloc_dealloc, - .tp_getattr = py_echo_info5_getattr, - .tp_setattr = py_echo_info5_setattr, -}; - -static PyObject *py_echo_info5(PyObject *self, PyObject *args) -{ - struct echo_info5 *ret = talloc_zero(NULL, struct echo_info5); - return py_talloc_import(&echo_info5_ObjectType, ret); -} - -staticforward PyTypeObject echo_info6_ObjectType; - -static PyObject *py_echo_info6_getattr(PyObject *obj, char *name) -{ - struct echo_info6 *object = py_talloc_get_type(obj, struct echo_info6); - if (!strcmp(name, "v1")) { - return PyInt_FromLong(object->v1); - } - if (!strcmp(name, "info1")) { - return py_talloc_import(&echo_info1_ObjectType, object->info1); - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return NULL; -} - -static int py_echo_info6_setattr(PyObject *py_obj, char *name, PyObject *value) -{ - struct echo_info6 *object = py_talloc_get_type(py_obj, struct echo_info6); - if (!strcmp(name, "v1")) { - /* FIXME: talloc_free(object->v1) if necessary */ - object->v1 = PyInt_AsLong(value); - return 0; - } - if (!strcmp(name, "info1")) { - /* FIXME: talloc_free(object->info1) if necessary */ - object->info1 = py_talloc_get_type(value, struct echo_info1); - return 0; - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return -1; -} - -static PyTypeObject echo_info6_ObjectType = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "echo_info6", - .tp_basicsize = sizeof(py_talloc_Object), - .tp_dealloc = py_talloc_dealloc, - .tp_getattr = py_echo_info6_getattr, - .tp_setattr = py_echo_info6_setattr, -}; - -static PyObject *py_echo_info6(PyObject *self, PyObject *args) -{ - struct echo_info6 *ret = talloc_zero(NULL, struct echo_info6); - return py_talloc_import(&echo_info6_ObjectType, ret); -} - -staticforward PyTypeObject echo_info7_ObjectType; - -static PyObject *py_echo_info7_getattr(PyObject *obj, char *name) -{ - struct echo_info7 *object = py_talloc_get_type(obj, struct echo_info7); - if (!strcmp(name, "v1")) { - return PyInt_FromLong(object->v1); - } - if (!strcmp(name, "info4")) { - return py_talloc_import(&echo_info4_ObjectType, object->info4); - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return NULL; -} - -static int py_echo_info7_setattr(PyObject *py_obj, char *name, PyObject *value) -{ - struct echo_info7 *object = py_talloc_get_type(py_obj, struct echo_info7); - if (!strcmp(name, "v1")) { - /* FIXME: talloc_free(object->v1) if necessary */ - object->v1 = PyInt_AsLong(value); - return 0; - } - if (!strcmp(name, "info4")) { - /* FIXME: talloc_free(object->info4) if necessary */ - object->info4 = py_talloc_get_type(value, struct echo_info4); - return 0; - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return -1; -} - -static PyTypeObject echo_info7_ObjectType = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "echo_info7", - .tp_basicsize = sizeof(py_talloc_Object), - .tp_dealloc = py_talloc_dealloc, - .tp_getattr = py_echo_info7_getattr, - .tp_setattr = py_echo_info7_setattr, -}; - -static PyObject *py_echo_info7(PyObject *self, PyObject *args) -{ - struct echo_info7 *ret = talloc_zero(NULL, struct echo_info7); - return py_talloc_import(&echo_info7_ObjectType, ret); -} - -PyObject *py_import_echo_Info(int level, union echo_Info *in) -{ - switch (level) { - case 1: return py_talloc_import(&echo_info1_ObjectType, in->info1); - case 2: return py_talloc_import(&echo_info2_ObjectType, in->info2); - case 3: return py_talloc_import(&echo_info3_ObjectType, in->info3); - case 4: return py_talloc_import(&echo_info4_ObjectType, in->info4); - case 5: return py_talloc_import(&echo_info5_ObjectType, in->info5); - case 6: return py_talloc_import(&echo_info6_ObjectType, in->info6); - case 7: return py_talloc_import(&echo_info7_ObjectType, in->info7); - } - PyErr_SetString(PyExc_TypeError, "unknown union level"); - return NULL; -} - -union echo_Info *py_export_echo_Info(TALLOC_CTX *mem_ctx, int level, PyObject *in) -{ - union echo_Info *ret = talloc_zero(mem_ctx, union echo_Info); - switch (level) { - case 1: - ret->info1 = py_talloc_get_type(in, struct echo_info1); - break; - - case 2: - ret->info2 = py_talloc_get_type(in, struct echo_info2); - break; - - case 3: - ret->info3 = py_talloc_get_type(in, struct echo_info3); - break; - - case 4: - ret->info4 = py_talloc_get_type(in, struct echo_info4); - break; - - case 5: - ret->info5 = py_talloc_get_type(in, struct echo_info5); - break; - - case 6: - ret->info6 = py_talloc_get_type(in, struct echo_info6); - break; - - case 7: - ret->info7 = py_talloc_get_type(in, struct echo_info7); - break; - - default: - PyErr_SetString(PyExc_TypeError, "invalid union level value"); - talloc_free(ret); - ret = NULL; - } - - return ret; -} - -staticforward PyTypeObject echo_Enum2_ObjectType; - -static PyObject *py_echo_Enum2_getattr(PyObject *obj, char *name) -{ - struct echo_Enum2 *object = py_talloc_get_type(obj, struct echo_Enum2); - if (!strcmp(name, "e1")) { - return PyInt_FromLong(object->e1); - } - if (!strcmp(name, "e2")) { - return PyInt_FromLong(object->e2); - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return NULL; -} - -static int py_echo_Enum2_setattr(PyObject *py_obj, char *name, PyObject *value) -{ - struct echo_Enum2 *object = py_talloc_get_type(py_obj, struct echo_Enum2); - if (!strcmp(name, "e1")) { - /* FIXME: talloc_free(object->e1) if necessary */ - object->e1 = PyInt_AsLong(value); - return 0; - } - if (!strcmp(name, "e2")) { - /* FIXME: talloc_free(object->e2) if necessary */ - object->e2 = PyInt_AsLong(value); - return 0; - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return -1; -} - -static PyTypeObject echo_Enum2_ObjectType = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "echo_Enum2", - .tp_basicsize = sizeof(py_talloc_Object), - .tp_dealloc = py_talloc_dealloc, - .tp_getattr = py_echo_Enum2_getattr, - .tp_setattr = py_echo_Enum2_setattr, -}; - -static PyObject *py_echo_Enum2(PyObject *self, PyObject *args) -{ - struct echo_Enum2 *ret = talloc_zero(NULL, struct echo_Enum2); - return py_talloc_import(&echo_Enum2_ObjectType, ret); -} - -PyObject *py_import_echo_Enum3(int level, union echo_Enum3 *in) -{ - switch (level) { - case ECHO_ENUM1: return PyInt_FromLong(in->e1); - case ECHO_ENUM2: return py_talloc_import(&echo_Enum2_ObjectType, in->e2); - } - PyErr_SetString(PyExc_TypeError, "unknown union level"); - return NULL; -} - -union echo_Enum3 *py_export_echo_Enum3(TALLOC_CTX *mem_ctx, int level, PyObject *in) -{ - union echo_Enum3 *ret = talloc_zero(mem_ctx, union echo_Enum3); - switch (level) { - case ECHO_ENUM1: - ret->e1 = PyInt_AsLong(in); - break; - - case ECHO_ENUM2: - ret->e2 = py_talloc_get_type(in, struct echo_Enum2); - break; - - default: - PyErr_SetString(PyExc_TypeError, "invalid union level value"); - talloc_free(ret); - ret = NULL; - } - - return ret; -} - -staticforward PyTypeObject echo_Surrounding_ObjectType; - -static PyObject *py_echo_Surrounding_getattr(PyObject *obj, char *name) -{ - struct echo_Surrounding *object = py_talloc_get_type(obj, struct echo_Surrounding); - if (!strcmp(name, "x")) { - return PyInt_FromLong(object->x); - } - if (!strcmp(name, "surrounding")) { - return PyInt_FromLong(object->surrounding); - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return NULL; -} - -static int py_echo_Surrounding_setattr(PyObject *py_obj, char *name, PyObject *value) -{ - struct echo_Surrounding *object = py_talloc_get_type(py_obj, struct echo_Surrounding); - if (!strcmp(name, "x")) { - /* FIXME: talloc_free(object->x) if necessary */ - object->x = PyInt_AsLong(value); - return 0; - } - if (!strcmp(name, "surrounding")) { - /* FIXME: talloc_free(object->surrounding) if necessary */ - object->surrounding = PyInt_AsLong(value); - return 0; - } - PyErr_SetString(PyExc_AttributeError, "no such attribute"); - return -1; -} - -static PyTypeObject echo_Surrounding_ObjectType = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "echo_Surrounding", - .tp_basicsize = sizeof(py_talloc_Object), - .tp_dealloc = py_talloc_dealloc, - .tp_getattr = py_echo_Surrounding_getattr, - .tp_setattr = py_echo_Surrounding_setattr, -}; - -static PyObject *py_echo_Surrounding(PyObject *self, PyObject *args) -{ - struct echo_Surrounding *ret = talloc_zero(NULL, struct echo_Surrounding); - return py_talloc_import(&echo_Surrounding_ObjectType, ret); -} - -staticforward PyTypeObject rpcecho_InterfaceType; -typedef struct { - PyObject_HEAD - struct dcerpc_pipe *pipe; -} rpcecho_InterfaceObject; - -static PyObject *py_echo_AddOne(PyObject *self, PyObject *args) -{ - rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct echo_AddOne r; - PyObject *result; - PyObject *py_in_data; - - ZERO_STRUCT(r.out); - r.in.in_data = PyInt_AsLong(py_in_data); - status = dcerpc_echo_AddOne(iface->pipe, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); - talloc_free(mem_ctx); - return NULL; - } - - result = PyTuple_New(1); - PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.out_data)); - talloc_free(mem_ctx); - return result; -} - -static PyObject *py_echo_EchoData(PyObject *self, PyObject *args) -{ - rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct echo_EchoData r; - PyObject *result; - PyObject *py_len; - PyObject *py_in_data; - - ZERO_STRUCT(r.out); - r.in.len = PyInt_AsLong(py_len); - r.in.in_data = PyInt_AsLong(py_in_data); - status = dcerpc_echo_EchoData(iface->pipe, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); - talloc_free(mem_ctx); - return NULL; - } - - result = PyTuple_New(1); - PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.out_data)); - talloc_free(mem_ctx); - return result; -} - -static PyObject *py_echo_SinkData(PyObject *self, PyObject *args) -{ - rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct echo_SinkData r; - PyObject *result; - PyObject *py_len; - PyObject *py_data; - r.in.len = PyInt_AsLong(py_len); - r.in.data = PyInt_AsLong(py_data); - status = dcerpc_echo_SinkData(iface->pipe, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); - talloc_free(mem_ctx); - return NULL; - } - - result = PyTuple_New(0); - talloc_free(mem_ctx); - return result; -} - -static PyObject *py_echo_SourceData(PyObject *self, PyObject *args) -{ - rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct echo_SourceData r; - PyObject *result; - PyObject *py_len; - - ZERO_STRUCT(r.out); - r.in.len = PyInt_AsLong(py_len); - status = dcerpc_echo_SourceData(iface->pipe, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); - talloc_free(mem_ctx); - return NULL; - } - - result = PyTuple_New(1); - PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.data)); - talloc_free(mem_ctx); - return result; -} - -static PyObject *py_echo_TestCall(PyObject *self, PyObject *args) -{ - rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct echo_TestCall r; - PyObject *result; - PyObject *py_s1; - - ZERO_STRUCT(r.out); - r.in.s1 = PyInt_AsLong(py_s1); - status = dcerpc_echo_TestCall(iface->pipe, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); - talloc_free(mem_ctx); - return NULL; - } - - result = PyTuple_New(1); - PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.s2)); - talloc_free(mem_ctx); - return result; -} - -static PyObject *py_echo_TestCall2(PyObject *self, PyObject *args) -{ - rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct echo_TestCall2 r; - PyObject *result; - PyObject *py_level; - - ZERO_STRUCT(r.out); - r.in.level = PyInt_AsLong(py_level); - status = dcerpc_echo_TestCall2(iface->pipe, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); - talloc_free(mem_ctx); - return NULL; - } - - result = PyTuple_New(2); - PyTuple_SetItem(result, 0, py_import_echo_Info(r.out.info)); - PyTuple_SetItem(result, 1, PyInt_FromLong(NT_STATUS_V(r.out.result))); - talloc_free(mem_ctx); - return result; -} - -static PyObject *py_echo_TestSleep(PyObject *self, PyObject *args) -{ - rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct echo_TestSleep r; - PyObject *result; - PyObject *py_seconds; - r.in.seconds = PyInt_AsLong(py_seconds); - status = dcerpc_echo_TestSleep(iface->pipe, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); - talloc_free(mem_ctx); - return NULL; - } - - result = PyTuple_New(1); - PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.result)); - talloc_free(mem_ctx); - return result; -} - -static PyObject *py_echo_TestEnum(PyObject *self, PyObject *args) -{ - rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct echo_TestEnum r; - PyObject *result; - PyObject *py_foo1; - PyObject *py_foo2; - PyObject *py_foo3; - - ZERO_STRUCT(r.out); - r.in.foo1 = PyInt_AsLong(py_foo1); - r.in.foo2 = py_talloc_get_type(py_foo2, struct echo_Enum2); - r.in.foo3 = py_export_echo_Enum3(py_foo3); - status = dcerpc_echo_TestEnum(iface->pipe, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); - talloc_free(mem_ctx); - return NULL; - } - - result = PyTuple_New(3); - PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.foo1)); - PyTuple_SetItem(result, 1, py_talloc_import(&echo_Enum2_ObjectType, r.out.foo2)); - PyTuple_SetItem(result, 2, py_import_echo_Enum3(r.out.foo3)); - talloc_free(mem_ctx); - return result; -} - -static PyObject *py_echo_TestSurrounding(PyObject *self, PyObject *args) -{ - rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct echo_TestSurrounding r; - PyObject *result; - PyObject *py_data; - - ZERO_STRUCT(r.out); - r.in.data = py_talloc_get_type(py_data, struct echo_Surrounding); - status = dcerpc_echo_TestSurrounding(iface->pipe, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); - talloc_free(mem_ctx); - return NULL; - } - - result = PyTuple_New(1); - PyTuple_SetItem(result, 0, py_talloc_import(&echo_Surrounding_ObjectType, r.out.data)); - talloc_free(mem_ctx); - return result; -} - -static PyObject *py_echo_TestDoublePointer(PyObject *self, PyObject *args) -{ - rpcecho_InterfaceObject *iface = (rpcecho_InterfaceObject *)self; - NTSTATUS status; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct echo_TestDoublePointer r; - PyObject *result; - PyObject *py_data; - r.in.data = PyInt_AsLong(py_data); - status = dcerpc_echo_TestDoublePointer(iface->pipe, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); - talloc_free(mem_ctx); - return NULL; - } - - result = PyTuple_New(1); - PyTuple_SetItem(result, 0, PyInt_FromLong(r.out.result)); - talloc_free(mem_ctx); - return result; -} - -static PyMethodDef interface_rpcecho_methods[] = { - { "echo_AddOne", (PyCFunction)py_echo_AddOne, METH_VARARGS|METH_KEYWORDS, NULL }, - { "echo_EchoData", (PyCFunction)py_echo_EchoData, METH_VARARGS|METH_KEYWORDS, NULL }, - { "echo_SinkData", (PyCFunction)py_echo_SinkData, METH_VARARGS|METH_KEYWORDS, NULL }, - { "echo_SourceData", (PyCFunction)py_echo_SourceData, METH_VARARGS|METH_KEYWORDS, NULL }, - { "echo_TestCall", (PyCFunction)py_echo_TestCall, METH_VARARGS|METH_KEYWORDS, NULL }, - { "echo_TestCall2", (PyCFunction)py_echo_TestCall2, METH_VARARGS|METH_KEYWORDS, NULL }, - { "echo_TestSleep", (PyCFunction)py_echo_TestSleep, METH_VARARGS|METH_KEYWORDS, NULL }, - { "echo_TestEnum", (PyCFunction)py_echo_TestEnum, METH_VARARGS|METH_KEYWORDS, NULL }, - { "echo_TestSurrounding", (PyCFunction)py_echo_TestSurrounding, METH_VARARGS|METH_KEYWORDS, NULL }, - { "echo_TestDoublePointer", (PyCFunction)py_echo_TestDoublePointer, METH_VARARGS|METH_KEYWORDS, NULL }, - { NULL, NULL, 0, NULL } -}; - -static void interface_rpcecho_dealloc(PyObject* self) -{ - rpcecho_InterfaceObject *interface = (rpcecho_InterfaceObject *)self; - talloc_free(interface->pipe); - PyObject_Del(self); -} - -static PyObject *interface_rpcecho_getattr(PyObject *obj, char *name) -{ - return Py_FindMethod(interface_rpcecho_methods, obj, name); -} - -static PyTypeObject rpcecho_InterfaceType = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "rpcecho", - .tp_basicsize = sizeof(rpcecho_InterfaceObject), - .tp_dealloc = (destructor)interface_rpcecho_dealloc, - .tp_getattr = (getattrfunc)interface_rpcecho_getattr, -}; - -static PyObject *interface_rpcecho(PyObject *self, PyObject *args) -{ - rpcecho_InterfaceObject *ret; - const char *binding_string; - struct cli_credentials *credentials; - struct loadparm_context *lp_ctx; - TALLOC_CTX *mem_ctx = NULL; - NTSTATUS status; - - ret = PyObject_New(rpcecho_InterfaceObject, &rpcecho_InterfaceType); - - status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string, - &ndr_table_rpcecho, credentials, NULL, lp_ctx); - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetString(PyExc_RuntimeError, nt_errstr(status)); - talloc_free(mem_ctx); - return NULL; - } - - return (PyObject *)ret; -} - -static PyMethodDef echo_methods[] = { - { "info1", (PyCFunction)py_echo_info1, METH_NOARGS, NULL }, - { "info2", (PyCFunction)py_echo_info2, METH_NOARGS, NULL }, - { "info3", (PyCFunction)py_echo_info3, METH_NOARGS, NULL }, - { "info4", (PyCFunction)py_echo_info4, METH_NOARGS, NULL }, - { "info5", (PyCFunction)py_echo_info5, METH_NOARGS, NULL }, - { "info6", (PyCFunction)py_echo_info6, METH_NOARGS, NULL }, - { "info7", (PyCFunction)py_echo_info7, METH_NOARGS, NULL }, - { "Enum2", (PyCFunction)py_echo_Enum2, METH_NOARGS, NULL }, - { "Surrounding", (PyCFunction)py_echo_Surrounding, METH_NOARGS, NULL }, - { "rpcecho", (PyCFunction)interface_rpcecho, METH_VARARGS|METH_KEYWORDS, NULL }, - { NULL, NULL, 0, NULL } -}; - -void initecho(void) -{ - PyObject *m; - m = Py_InitModule("echo", echo_methods); - PyModule_AddObject(m, "ECHO_ENUM1", PyInt_FromLong(ECHO_ENUM1)); - PyModule_AddObject(m, "ECHO_ENUM2_32", PyInt_FromLong(ECHO_ENUM2_32)); - PyModule_AddObject(m, "ECHO_ENUM2", PyInt_FromLong(ECHO_ENUM2)); - PyModule_AddObject(m, "ECHO_ENUM1_32", PyInt_FromLong(ECHO_ENUM1_32)); -} diff --git a/source4/py_echo.h b/source4/py_echo.h deleted file mode 100644 index 426bce3b3d..0000000000 --- a/source4/py_echo.h +++ /dev/null @@ -1,8 +0,0 @@ -/* header auto-generated by pidl */ - -#ifndef _HEADER_PYTHON_rpcecho -#define _HEADER_PYTHON_rpcecho - - - -#endif /* _HEADER_NDR_rpcecho */ -- cgit From 41057618f890b9053dce9cd671d11db7af7d3612 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 21:23:12 +0100 Subject: pidl/python: Remove unnecessary talloc_free(). (This used to be commit a099d30067a4d965a283f52e56ffd1897137bf1a) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index cea3889938..93a6161ce4 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -196,7 +196,7 @@ sub PythonStruct($$$$) if ($e->{ORIGINAL}->{POINTERS} > 0) { $self->pidl("talloc_free($varname);"); } - $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value", $varname, "talloc_free(mem_ctx); return -1;"); + $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value", $varname, "return -1;"); $self->pidl("return 0;"); $self->deindent; $self->pidl("}"); -- cgit From 1f54cb1af997f993ebd130f08813028f7e1f3f51 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 21:33:35 +0100 Subject: python: Add simple tests for the DCE/RPC echo interface. (This used to be commit 8523740796f3cd739bdc338b5e2855a01bafa540) --- source4/selftest/samba4_tests.sh | 1 + source4/torture/rpc/echo.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 source4/torture/rpc/echo.py (limited to 'source4') diff --git a/source4/selftest/samba4_tests.sh b/source4/selftest/samba4_tests.sh index 11daa4bd59..14b51c6054 100755 --- a/source4/selftest/samba4_tests.sh +++ b/source4/selftest/samba4_tests.sh @@ -322,6 +322,7 @@ then plantest "samba3.python" none $SUBUNITRUN samba.tests.samba3 plantest "events.python" none PYTHONPATH="$PYTHONPATH:lib/events" $SUBUNITRUN tests plantest "samba3sam.python" none PYTHONPATH="$PYTHONPATH:dsdb/samdb/ldb_modules/tests" $SUBUNITRUN samba3sam + plantest "rpcecho.python" dc PYTHONPATH="$PYTHONPATH:torture/rpc" $SUBUNITRUN echo plantest "ldap.python" dc $PYTHON $samba4srcdir/lib/ldb/tests/python/ldap.py $CONFIGURATION \$SERVER -U\$USERNAME%\$PASSWORD -W \$DOMAIN plantest "blackbox.samba3dump" none $PYTHON scripting/bin/samba3dump $samba4srcdir/../testdata/samba3 rm -rf $PREFIX/upgrade diff --git a/source4/torture/rpc/echo.py b/source4/torture/rpc/echo.py new file mode 100644 index 0000000000..d11a3ea66a --- /dev/null +++ b/source4/torture/rpc/echo.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +from echo import rpcecho +import unittest + +class RpcEchoTests(unittest.TestCase): + def setUp(self): + self.conn = rpcecho("ncalrpc:") + + def test_addone(self): + self.assertEquals(2, conn.AddOne(1)) -- cgit From 0d39a205bf227851028aea11744e6a60ff9a2cb9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 21:42:42 +0100 Subject: python: Add some more rpc/echo tests. (This used to be commit b4840d1ae283a3853d041f3a9a848aec991e81a6) --- source4/torture/rpc/echo.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source4') diff --git a/source4/torture/rpc/echo.py b/source4/torture/rpc/echo.py index d11a3ea66a..7a0a54a1a1 100644 --- a/source4/torture/rpc/echo.py +++ b/source4/torture/rpc/echo.py @@ -26,3 +26,14 @@ class RpcEchoTests(unittest.TestCase): def test_addone(self): self.assertEquals(2, conn.AddOne(1)) + + def test_echodata(self): + self.assertEquals("bla", conn.EchoData(3, "bla")) + + def test_call(self): + self.assertEquals("foobar", conn.TestCall("foobar")) + + def test_surrounding(self): + somearray = [1,2,3,4] + conn.TestSurrounding(echo.Surrounding(4, somearray)) + self.assertEquals(8 * [0], somearray) -- cgit From d8b21ae2534d5b51c1dc5a4c50b3de5ddb32af80 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 23:13:30 +0100 Subject: pidl/python: Fix use of pointers. (This used to be commit 13f2b0380f310b101975d709361a29d4032c3689) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 81 ++++++++++++++++++++++++---- source4/torture/rpc/echo.py | 4 +- 2 files changed, 72 insertions(+), 13 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 93a6161ce4..2d6ec50d39 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -11,6 +11,7 @@ use Exporter; use strict; use Parse::Pidl::Typelist qw(hasType getType mapTypeName expandAlias); use Parse::Pidl::Util qw(has_property ParseExpr); +use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred); use Parse::Pidl::CUtil qw(get_value_of get_pointer_to); use vars qw($VERSION); @@ -100,7 +101,7 @@ sub FromUnionToPythonFunction($$$) my $conv; if ($e->{NAME}) { - $conv = $self->ConvertObjectToPython($e->{TYPE}, "$name->$e->{NAME}"); + $conv = $self->ConvertObjectToPython($e, "$name->$e->{NAME}"); } else { $conv = "Py_None"; } @@ -138,7 +139,7 @@ sub FromPythonToUnionFunction($$$$$) } $self->indent; if ($e->{NAME}) { - $self->ConvertObjectFromPython($mem_ctx, $e->{TYPE}, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;"); + $self->ConvertObjectFromPython($mem_ctx, $e, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;"); } $self->pidl("break;"); $self->deindent; @@ -174,7 +175,7 @@ sub PythonStruct($$$$) $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); my $varname = "object->$e->{NAME}"; $self->indent; - $self->pidl("return ".$self->ConvertObjectToPython($e->{TYPE}, $varname) . ";"); + $self->pidl("return ".$self->ConvertObjectToPython($e, $varname) . ";"); $self->deindent; $self->pidl("}"); } @@ -188,7 +189,7 @@ sub PythonStruct($$$$) $self->pidl("{"); $self->indent; $self->pidl("$cname *object = py_talloc_get_type(py_obj, $cname);"); - $self->pidl("TALLOC_CTX *mem_ctx = py_talloc_get_mem_ctx(py_obj);"); + my $mem_ctx = "py_talloc_get_mem_ctx(py_obj)"; foreach my $e (@{$d->{ELEMENTS}}) { $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); my $varname = "object->$e->{NAME}"; @@ -196,7 +197,7 @@ sub PythonStruct($$$$) if ($e->{ORIGINAL}->{POINTERS} > 0) { $self->pidl("talloc_free($varname);"); } - $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "value", $varname, "return -1;"); + $self->ConvertObjectFromPython($mem_ctx, $e, "value", $varname, "return -1;"); $self->pidl("return 0;"); $self->deindent; $self->pidl("}"); @@ -270,7 +271,7 @@ sub PythonFunction($$$) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - $self->ConvertObjectFromPython("mem_ctx", $e->{TYPE}, "py_$e->{NAME}", "r.in.$e->{NAME}", "talloc_free(mem_ctx); return NULL;"); + $self->ConvertObjectFromPython("mem_ctx", $e, "py_$e->{NAME}", "r.in.$e->{NAME}", "talloc_free(mem_ctx); return NULL;"); } } $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);"); @@ -282,14 +283,14 @@ sub PythonFunction($$$) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/out/,@{$e->{DIRECTION}})) { - $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($e->{TYPE}, "r.out.$e->{NAME}") . ");"); + $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($e, "r.out.$e->{NAME}") . ");"); $i++; } } if (defined($fn->{RETURN_TYPE})) { - $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($fn->{RETURN_TYPE}, "r.out.result") . ");"); + $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPythonData($fn->{RETURN_TYPE}, "r.out.result") . ");"); } $self->pidl("talloc_free(mem_ctx);"); @@ -484,7 +485,7 @@ sub register_module_method($$$$$) push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc]) } -sub ConvertObjectFromPython($$$$$$) +sub convertObjectFromPythonData($$$$$$) { my ($self, $mem_ctx, $ctype, $cvar, $target, $fail) = @_; @@ -561,6 +562,36 @@ sub ConvertObjectFromPython($$$$$$) } die("unknown type ".mapTypeName($ctype) . ": $cvar"); + +} + +sub ConvertObjectFromPythonLevel($$$$$$$) +{ + my ($self, $mem_ctx, $e, $l, $var_name, $target, $fail) = @_; + + if ($l->{TYPE} eq "POINTER") { + $self->ConvertObjectFromPythonLevel($mem_ctx, $e, GetNextLevel($e, $l), get_value_of($var_name), $target, $fail); + } elsif ($l->{TYPE} eq "ARRAY") { + $self->ConvertObjectFromPythonLevel($mem_ctx, $e, GetNextLevel($e, $l), $var_name."[i]", $target, $fail); + } elsif ($l->{TYPE} eq "DATA") { + if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or + Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { + $var_name = get_pointer_to($var_name); + } + $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name, $target, $fail); + } elsif ($l->{TYPE} eq "SWITCH") { + $self->ConvertObjectFromPythonLevel($mem_ctx, $e, GetNextLevel($e, $l), get_value_of($var_name), $target, $fail); + } else { + die("unknown level type $l->{TYPE}"); + } +} + +sub ConvertObjectFromPython($$$$$$) +{ + my ($self, $mem_ctx, $ctype, $cvar, $target, $fail) = @_; + + $self->ConvertObjectFromPythonLevel($mem_ctx, $ctype, $ctype->{LEVELS}[0], + $cvar, $target, $fail); } sub ConvertScalarToPython($$$) @@ -601,7 +632,7 @@ sub ConvertScalarToPython($$$) die("Unknown scalar type $ctypename"); } -sub ConvertObjectToPython($$$) +sub ConvertObjectToPythonData($$$) { my ($self, $ctype, $cvar) = @_; @@ -648,6 +679,34 @@ sub ConvertObjectToPython($$$) die("unknown type ".mapTypeName($ctype) . ": $cvar"); } +sub ConvertObjectToPythonLevel($$$$) +{ + my ($self, $e, $l, $var_name) = @_; + + if ($l->{TYPE} eq "POINTER") { + $self->ConvertObjectToPythonLevel($e, GetNextLevel($e, $l), get_value_of($var_name)); + } elsif ($l->{TYPE} eq "ARRAY") { + $self->ConvertObjectToPythonLevel($e, GetNextLevel($e, $l), $var_name."[i]"); + } elsif ($l->{TYPE} eq "SWITCH") { + $self->ConvertObjectToPythonLevel($e, GetNextLevel($e, $l), $var_name); + } elsif ($l->{TYPE} eq "DATA") { + if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or + Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { + $var_name = get_pointer_to($var_name); + } + $self->ConvertObjectToPythonData($l->{DATA_TYPE}, $var_name); + } else { + die("Unknown level type $l->{TYPE} $var_name"); + } +} + +sub ConvertObjectToPython($$$) +{ + my ($self, $ctype, $cvar) = @_; + + $self->ConvertObjectToPythonLevel($ctype, $ctype->{LEVELS}[0], $cvar); +} + sub Parse($$$$$) { my($self,$basename,$ndr,$ndr_hdr,$hdr) = @_; @@ -705,7 +764,7 @@ sub Parse($$$$$) } elsif ($cvar =~ /^".*"$/) { $py_obj = "PyString_FromString($cvar)"; } else { - $py_obj = $self->ConvertObjectToPython($ctype, $cvar); + $py_obj = $self->ConvertObjectToPythonData($ctype, $cvar); } $self->pidl("PyModule_AddObject(m, \"$name\", $py_obj);"); diff --git a/source4/torture/rpc/echo.py b/source4/torture/rpc/echo.py index 7a0a54a1a1..47b71c9e15 100644 --- a/source4/torture/rpc/echo.py +++ b/source4/torture/rpc/echo.py @@ -35,5 +35,5 @@ class RpcEchoTests(unittest.TestCase): def test_surrounding(self): somearray = [1,2,3,4] - conn.TestSurrounding(echo.Surrounding(4, somearray)) - self.assertEquals(8 * [0], somearray) + (y) = conn.TestSurrounding(echo.Surrounding(4, somearray))) + self.assertEquals(8 * [0], y.surrounding) -- cgit From 5d60cb6ef1c63ce771ab44b6831147568061aa50 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 01:30:44 +0100 Subject: pidl/python: Fix parsing arguments, fix more pointer issues. (This used to be commit b00c1a072457e5083ffc24a8b74b3793d0b44eee) --- source4/pidl/lib/Parse/Pidl/NDR.pm | 17 ++- source4/pidl/lib/Parse/Pidl/Samba4/Header.pm | 2 - source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 15 +-- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 162 ++++++++++++++++++----- 4 files changed, 146 insertions(+), 50 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/NDR.pm b/source4/pidl/lib/Parse/Pidl/NDR.pm index 1d059ebdf7..fc6bfe4c96 100644 --- a/source4/pidl/lib/Parse/Pidl/NDR.pm +++ b/source4/pidl/lib/Parse/Pidl/NDR.pm @@ -35,7 +35,7 @@ use vars qw($VERSION); $VERSION = '0.01'; @ISA = qw(Exporter); @EXPORT = qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsString); -@EXPORT_OK = qw(GetElementLevelTable ParseElement ValidElement align_type mapToScalar ParseType can_contain_deferred); +@EXPORT_OK = qw(GetElementLevelTable ParseElement ValidElement align_type mapToScalar ParseType can_contain_deferred is_charset_array); use strict; use Parse::Pidl qw(warning fatal); @@ -1181,4 +1181,19 @@ sub Validate($) } } +sub is_charset_array($$) +{ + my ($e,$l) = @_; + + return 0 if ($l->{TYPE} ne "ARRAY"); + + my $nl = GetNextLevel($e,$l); + + return 0 unless ($nl->{TYPE} eq "DATA"); + + return has_property($e, "charset"); +} + + + 1; diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm index 06e9ec4b9f..2b3a9df80f 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm @@ -473,6 +473,4 @@ sub GenerateFunctionOutEnv($;$) return \%env; } - - 1; diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm index 0800a19fab..02d3a80992 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm @@ -15,7 +15,7 @@ use strict; use Parse::Pidl::Typelist qw(hasType getType mapTypeName typeHasBody); use Parse::Pidl::Util qw(has_property ParseExpr ParseExprExt print_uuid); use Parse::Pidl::CUtil qw(get_pointer_to get_value_of); -use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred); +use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array); use Parse::Pidl::Samba4 qw(is_intree choose_header); use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv); use Parse::Pidl qw(warning); @@ -78,19 +78,6 @@ sub has_fast_array($$) return ($t->{NAME} eq "uint8") or ($t->{NAME} eq "string"); } -sub is_charset_array($$) -{ - my ($e,$l) = @_; - - return 0 if ($l->{TYPE} ne "ARRAY"); - - my $nl = GetNextLevel($e,$l); - - return 0 unless ($nl->{TYPE} eq "DATA"); - - return has_property($e, "charset"); -} - #################################### # pidl() is our basic output routine diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 2d6ec50d39..9a3e82a94b 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -11,8 +11,9 @@ use Exporter; use strict; use Parse::Pidl::Typelist qw(hasType getType mapTypeName expandAlias); use Parse::Pidl::Util qw(has_property ParseExpr); -use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred); +use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array); use Parse::Pidl::CUtil qw(get_value_of get_pointer_to); +use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv); use vars qw($VERSION); $VERSION = '0.01'; @@ -94,22 +95,31 @@ sub FromUnionToPythonFunction($$$) { my ($self, $type, $switch, $name) = @_; + $self->pidl("PyObject *ret;"); + $self->pidl(""); + $self->pidl("switch ($switch) {"); $self->indent; foreach my $e (@{$type->{ELEMENTS}}) { - my $conv; - - if ($e->{NAME}) { - $conv = $self->ConvertObjectToPython($e, "$name->$e->{NAME}"); + if (defined($e->{CASE})) { + $self->pidl("$e->{CASE}:"); } else { - $conv = "Py_None"; + $self->pidl("default:"); } - if (defined($e->{CASE})) { - $self->pidl("$e->{CASE}: return $conv;"); + + $self->indent; + + if ($e->{NAME}) { + $self->ConvertObjectToPython({}, $e, "$name->$e->{NAME}", "ret"); } else { - $self->pidl("default: return $conv;"); + $self->pidl("ret = Py_None;"); } + + $self->pidl("return ret;"); + $self->pidl(""); + + $self->deindent; } $self->deindent; @@ -165,6 +175,8 @@ sub PythonStruct($$$$) { my ($self, $name, $cname, $d) = @_; + my $env = GenerateStructEnv($d, "object"); + $self->pidl(""); $self->pidl("static PyObject *py_$name\_getattr(PyObject *obj, char *name)"); @@ -175,7 +187,9 @@ sub PythonStruct($$$$) $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); my $varname = "object->$e->{NAME}"; $self->indent; - $self->pidl("return ".$self->ConvertObjectToPython($e, $varname) . ";"); + $self->pidl("PyObject *py_$e->{NAME};"); + $self->ConvertObjectToPython($env, $e, $varname, "py_$e->{NAME}"); + $self->pidl("return py_$e->{NAME};"); $self->deindent; $self->pidl("}"); } @@ -243,7 +257,7 @@ sub PythonFunction($$$) { my ($self, $fn, $iface) = @_; - $self->pidl("static PyObject *py_$fn->{NAME}(PyObject *self, PyObject *args)"); + $self->pidl("static PyObject *py_$fn->{NAME}(PyObject *self, PyObject *args, PyObject *kwargs)"); $self->pidl("{"); $self->indent; $self->pidl("$iface\_InterfaceObject *iface = ($iface\_InterfaceObject *)self;"); @@ -251,16 +265,38 @@ sub PythonFunction($$$) $self->pidl("TALLOC_CTX *mem_ctx = talloc_new(NULL);"); $self->pidl("struct $fn->{NAME} r;"); $self->pidl("PyObject *result;"); + + my $env = GenerateFunctionInEnv($fn, "r."); my $result_size = 0; + my $args_format = ""; + my $args_string = ""; + my $args_names = ""; + foreach my $e (@{$fn->{ELEMENTS}}) { - if (grep(/in/,@{$e->{DIRECTION}})) { - $self->pidl("PyObject *py_$e->{NAME};"); - } + $self->pidl("PyObject *py_$e->{NAME};"); if (grep(/out/,@{$e->{DIRECTION}})) { $result_size++; } + if (grep(/in/,@{$e->{DIRECTION}})) { + $args_format .= "O"; + $args_string .= ", &py_$e->{NAME}"; + $args_names .= "\"$e->{NAME}\", "; + } } + $self->pidl("const char *kwnames[] = {"); + $self->indent; + $self->pidl($args_names . "NULL"); + $self->deindent; + $self->pidl("};"); + + $self->pidl(""); + $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"$args_format:$fn->{NAME}\", discard_const_p(char *, kwnames)$args_string)) {"); + $self->indent; + $self->pidl("return NULL;"); + $self->deindent; + $self->pidl("}"); + if ($result_size > 0) { $self->pidl(""); $self->pidl("ZERO_STRUCT(r.out);"); @@ -279,11 +315,13 @@ sub PythonFunction($$$) $self->pidl("result = PyTuple_New($result_size);"); + $env = GenerateFunctionOutEnv($fn, "r."); my $i = 0; foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/out/,@{$e->{DIRECTION}})) { - $self->pidl("PyTuple_SetItem(result, $i, " . $self->ConvertObjectToPython($e, "r.out.$e->{NAME}") . ");"); + $self->ConvertObjectToPython($env, $e, "r.out.$e->{NAME}", "py_$e->{NAME}"); + $self->pidl("PyTuple_SetItem(result, $i, py_$e->{NAME});"); $i++; } @@ -485,9 +523,9 @@ sub register_module_method($$$$$) push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc]) } -sub convertObjectFromPythonData($$$$$$) +sub ConvertObjectFromPythonData($$$$$$) { - my ($self, $mem_ctx, $ctype, $cvar, $target, $fail) = @_; + my ($self, $mem_ctx, $cvar, $ctype, $target, $fail) = @_; die("undef type for $cvar") unless(defined($ctype)); @@ -567,20 +605,45 @@ sub convertObjectFromPythonData($$$$$$) sub ConvertObjectFromPythonLevel($$$$$$$) { - my ($self, $mem_ctx, $e, $l, $var_name, $target, $fail) = @_; + my ($self, $mem_ctx, $py_var, $e, $l, $var_name, $fail) = @_; if ($l->{TYPE} eq "POINTER") { - $self->ConvertObjectFromPythonLevel($mem_ctx, $e, GetNextLevel($e, $l), get_value_of($var_name), $target, $fail); + if ($l->{POINTER_TYPE} ne "ref") { + $self->pidl("if ($py_var == Py_None) {"); + $self->indent; + $self->pidl("$var_name = NULL;"); + $self->deindent; + $self->pidl("} else {"); + $self->indent; + } + $self->ConvertObjectFromPythonLevel($mem_ctx, $py_var, $e, GetNextLevel($e, $l), get_value_of($var_name), $fail); + if ($l->{POINTER_TYPE} ne "ref") { + $self->deindent; + $self->pidl("}"); + } } elsif ($l->{TYPE} eq "ARRAY") { - $self->ConvertObjectFromPythonLevel($mem_ctx, $e, GetNextLevel($e, $l), $var_name."[i]", $target, $fail); + if (is_charset_array($e, $l)) { + $self->pidl("$var_name = PyString_AsString(PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\"));"); + } else { + my $counter = "i"; + $self->pidl("$var_name = talloc_array($mem_ctx, FIXME, PyList_Length($py_var));"); + $self->pidl("for ($counter = 0; $counter < PyList_Length($py_var); $counter++) {"); + $self->indent; + $self->ConvertObjectFromPythonLevel($var_name, "PyList_GetItem($py_var, $counter)", $e, GetNextLevel($e, $l), $var_name."[$counter]", $fail); + $self->deindent; + $self->pidl("}"); + } } elsif ($l->{TYPE} eq "DATA") { + if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { $var_name = get_pointer_to($var_name); } - $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name, $target, $fail); + $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $l->{DATA_TYPE}, $var_name, $fail); } elsif ($l->{TYPE} eq "SWITCH") { - $self->ConvertObjectFromPythonLevel($mem_ctx, $e, GetNextLevel($e, $l), get_value_of($var_name), $target, $fail); + $self->ConvertObjectFromPythonLevel($mem_ctx, $py_var, $e, GetNextLevel($e, $l), get_value_of($var_name), $fail); + } elsif ($l->{TYPE} eq "SUBCONTEXT") { + $self->pidl("FIXME"); } else { die("unknown level type $l->{TYPE}"); } @@ -590,8 +653,7 @@ sub ConvertObjectFromPython($$$$$$) { my ($self, $mem_ctx, $ctype, $cvar, $target, $fail) = @_; - $self->ConvertObjectFromPythonLevel($mem_ctx, $ctype, $ctype->{LEVELS}[0], - $cvar, $target, $fail); + $self->ConvertObjectFromPythonLevel($mem_ctx, $cvar, $ctype, $ctype->{LEVELS}[0], $target, $fail); } sub ConvertScalarToPython($$$) @@ -632,7 +694,7 @@ sub ConvertScalarToPython($$$) die("Unknown scalar type $ctypename"); } -sub ConvertObjectToPythonData($$$) +sub ConvertObjectToPythonData($$$$) { my ($self, $ctype, $cvar) = @_; @@ -681,30 +743,64 @@ sub ConvertObjectToPythonData($$$) sub ConvertObjectToPythonLevel($$$$) { - my ($self, $e, $l, $var_name) = @_; + my ($self, $env, $e, $l, $var_name, $py_var) = @_; if ($l->{TYPE} eq "POINTER") { - $self->ConvertObjectToPythonLevel($e, GetNextLevel($e, $l), get_value_of($var_name)); + if ($l->{POINTER_TYPE} ne "ref") { + $self->pidl("if ($var_name == NULL) {"); + $self->indent; + $self->pidl("$py_var = Py_None;"); + $self->deindent; + $self->pidl("} else {"); + $self->indent; + } + $self->ConvertObjectToPythonLevel($env, $e, GetNextLevel($e, $l), get_value_of($var_name), $py_var); + if ($l->{POINTER_TYPE} ne "ref") { + $self->deindent; + $self->pidl("}"); + } } elsif ($l->{TYPE} eq "ARRAY") { - $self->ConvertObjectToPythonLevel($e, GetNextLevel($e, $l), $var_name."[i]"); + if (is_charset_array($e, $l)) { + $self->pidl("$py_var = PyUnicode_Decode($var_name, strlen($var_name), \"utf-8\", \"ignore\");"); + } else { + die("No SIZE_IS for array $var_name") unless (defined($l->{SIZE_IS})); + my $length = $l->{SIZE_IS}; + if (defined($l->{LENGTH_IS})) { + $length = $l->{LENGTH_IS}; + } + + $length = ParseExpr($length, $env, $e); + $self->pidl("$py_var = PyList_New($length);"); + my $counter = "i"; + $self->pidl("for ($counter = 0; $counter < $length; $counter++) {"); + $self->indent; + my $member_var = "py_$e->{NAME}_$l->{LEVEL_INDEX}"; + $self->pidl("PyObject *$member_var;"); + $self->ConvertObjectToPythonLevel($env, $e, GetNextLevel($e, $l), $var_name."[$counter]", $member_var); + $self->pidl("PyList_SetItem($py_var, $counter, $member_var);"); + $self->deindent; + $self->pidl("}"); + } } elsif ($l->{TYPE} eq "SWITCH") { - $self->ConvertObjectToPythonLevel($e, GetNextLevel($e, $l), $var_name); + $self->ConvertObjectToPythonLevel($env, $e, GetNextLevel($e, $l), $var_name, $py_var); } elsif ($l->{TYPE} eq "DATA") { if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { $var_name = get_pointer_to($var_name); } - $self->ConvertObjectToPythonData($l->{DATA_TYPE}, $var_name); + $self->pidl("$py_var = ".$self->ConvertObjectToPythonData($l->{DATA_TYPE}, $var_name) . ";"); + } elsif ($l->{TYPE} eq "SUBCONTEXT") { + $self->pidl("FIXME"); } else { die("Unknown level type $l->{TYPE} $var_name"); } } -sub ConvertObjectToPython($$$) +sub ConvertObjectToPython($$$$$) { - my ($self, $ctype, $cvar) = @_; + my ($self, $env, $ctype, $cvar, $py_var) = @_; - $self->ConvertObjectToPythonLevel($ctype, $ctype->{LEVELS}[0], $cvar); + $self->ConvertObjectToPythonLevel($env, $ctype, $ctype->{LEVELS}[0], $cvar, $py_var); } sub Parse($$$$$) -- cgit From 657e0cc4d09a89944445b17fd3fdc56e777917d0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 02:04:06 +0100 Subject: pidl/python: Fix more compile errors. (This used to be commit 2eb4526599ec6d3c604dd9b1f258496c82288284) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 58 +++++++++++++++------------- 1 file changed, 32 insertions(+), 26 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 9a3e82a94b..a2ad3c6508 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -149,7 +149,7 @@ sub FromPythonToUnionFunction($$$$$) } $self->indent; if ($e->{NAME}) { - $self->ConvertObjectFromPython($mem_ctx, $e, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;"); + $self->ConvertObjectFromPython({}, $mem_ctx, $e, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;"); } $self->pidl("break;"); $self->deindent; @@ -211,7 +211,7 @@ sub PythonStruct($$$$) if ($e->{ORIGINAL}->{POINTERS} > 0) { $self->pidl("talloc_free($varname);"); } - $self->ConvertObjectFromPython($mem_ctx, $e, "value", $varname, "return -1;"); + $self->ConvertObjectFromPython($env, $mem_ctx, $e, "value", $varname, "return -1;"); $self->pidl("return 0;"); $self->deindent; $self->pidl("}"); @@ -307,7 +307,7 @@ sub PythonFunction($$$) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - $self->ConvertObjectFromPython("mem_ctx", $e, "py_$e->{NAME}", "r.in.$e->{NAME}", "talloc_free(mem_ctx); return NULL;"); + $self->ConvertObjectFromPython($env, "mem_ctx", $e, "py_$e->{NAME}", "r.in.$e->{NAME}", "talloc_free(mem_ctx); return NULL;"); } } $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);"); @@ -557,11 +557,6 @@ sub ConvertObjectFromPythonData($$$$$$) return; } - if ($actual_ctype->{TYPE} eq "UNION") { - $self->pidl("$target = py_export_$ctype->{NAME}($cvar);"); - return; - } - if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "DATA_BLOB") { $self->pidl("$target = data_blob_talloc($mem_ctx, PyString_AsString($cvar), PyString_Size($cvar));"); return; @@ -603,9 +598,9 @@ sub ConvertObjectFromPythonData($$$$$$) } -sub ConvertObjectFromPythonLevel($$$$$$$) +sub ConvertObjectFromPythonLevel($$$$$$$$) { - my ($self, $mem_ctx, $py_var, $e, $l, $var_name, $fail) = @_; + my ($self, $env, $mem_ctx, $py_var, $e, $l, $var_name, $fail) = @_; if ($l->{TYPE} eq "POINTER") { if ($l->{POINTER_TYPE} ne "ref") { @@ -616,20 +611,25 @@ sub ConvertObjectFromPythonLevel($$$$$$$) $self->pidl("} else {"); $self->indent; } - $self->ConvertObjectFromPythonLevel($mem_ctx, $py_var, $e, GetNextLevel($e, $l), get_value_of($var_name), $fail); + $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, GetNextLevel($e, $l), get_value_of($var_name), $fail); if ($l->{POINTER_TYPE} ne "ref") { $self->deindent; $self->pidl("}"); } } elsif ($l->{TYPE} eq "ARRAY") { if (is_charset_array($e, $l)) { - $self->pidl("$var_name = PyString_AsString(PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\"));"); + $self->pidl(get_pointer_to($var_name) . " = PyString_AsString(PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\"));"); } else { - my $counter = "i"; - $self->pidl("$var_name = talloc_array($mem_ctx, FIXME, PyList_Length($py_var));"); - $self->pidl("for ($counter = 0; $counter < PyList_Length($py_var); $counter++) {"); + my $counter = "$e->{NAME}_cntr_$l->{LEVEL_INDEX}"; + $self->pidl("{"); $self->indent; - $self->ConvertObjectFromPythonLevel($var_name, "PyList_GetItem($py_var, $counter)", $e, GetNextLevel($e, $l), $var_name."[$counter]", $fail); + $self->pidl("int $counter;"); + $self->pidl("$var_name = talloc_array($mem_ctx, FIXME, PyList_Size($py_var));"); + $self->pidl("for ($counter = 0; $counter < PyList_Size($py_var); $counter++) {"); + $self->indent; + $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GetItem($py_var, $counter)", $e, GetNextLevel($e, $l), $var_name."[$counter]", $fail); + $self->deindent; + $self->pidl("}"); $self->deindent; $self->pidl("}"); } @@ -641,7 +641,9 @@ sub ConvertObjectFromPythonLevel($$$$$$$) } $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $l->{DATA_TYPE}, $var_name, $fail); } elsif ($l->{TYPE} eq "SWITCH") { - $self->ConvertObjectFromPythonLevel($mem_ctx, $py_var, $e, GetNextLevel($e, $l), get_value_of($var_name), $fail); + $var_name = get_pointer_to($var_name); + my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e); + $self->pidl("$var_name = py_export_" . GetNextLevel($e, $l)->{DATA_TYPE} . "($mem_ctx, $switch, $py_var);"); } elsif ($l->{TYPE} eq "SUBCONTEXT") { $self->pidl("FIXME"); } else { @@ -649,11 +651,11 @@ sub ConvertObjectFromPythonLevel($$$$$$$) } } -sub ConvertObjectFromPython($$$$$$) +sub ConvertObjectFromPython($$$$$$$) { - my ($self, $mem_ctx, $ctype, $cvar, $target, $fail) = @_; + my ($self, $env, $mem_ctx, $ctype, $cvar, $target, $fail) = @_; - $self->ConvertObjectFromPythonLevel($mem_ctx, $cvar, $ctype, $ctype->{LEVELS}[0], $target, $fail); + $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $cvar, $ctype, $ctype->{LEVELS}[0], $target, $fail); } sub ConvertScalarToPython($$$) @@ -729,10 +731,6 @@ sub ConvertObjectToPythonData($$$$) return $self->ConvertScalarToPython($actual_ctype->{NAME}, $cvar); } - if ($actual_ctype->{TYPE} eq "UNION") { - return "py_import_$ctype->{NAME}($cvar)"; - } - if ($actual_ctype->{TYPE} eq "STRUCT") { # FIXME: if $cvar is not a pointer, do a talloc_dup() return "py_talloc_import(&$ctype->{NAME}_Type, $cvar)"; @@ -761,6 +759,7 @@ sub ConvertObjectToPythonLevel($$$$) } } elsif ($l->{TYPE} eq "ARRAY") { if (is_charset_array($e, $l)) { + $var_name = get_pointer_to($var_name); $self->pidl("$py_var = PyUnicode_Decode($var_name, strlen($var_name), \"utf-8\", \"ignore\");"); } else { die("No SIZE_IS for array $var_name") unless (defined($l->{SIZE_IS})); @@ -771,7 +770,10 @@ sub ConvertObjectToPythonLevel($$$$) $length = ParseExpr($length, $env, $e); $self->pidl("$py_var = PyList_New($length);"); - my $counter = "i"; + $self->pidl("{"); + $self->indent; + my $counter = "$e->{NAME}_cntr_$l->{LEVEL_INDEX}"; + $self->pidl("int $counter;"); $self->pidl("for ($counter = 0; $counter < $length; $counter++) {"); $self->indent; my $member_var = "py_$e->{NAME}_$l->{LEVEL_INDEX}"; @@ -780,9 +782,13 @@ sub ConvertObjectToPythonLevel($$$$) $self->pidl("PyList_SetItem($py_var, $counter, $member_var);"); $self->deindent; $self->pidl("}"); + $self->deindent; + $self->pidl("}"); } } elsif ($l->{TYPE} eq "SWITCH") { - $self->ConvertObjectToPythonLevel($env, $e, GetNextLevel($e, $l), $var_name, $py_var); + $var_name = get_pointer_to($var_name); + my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e); + $self->pidl("$py_var = py_import_" . GetNextLevel($e, $l)->{DATA_TYPE} . "($switch, $var_name);"); } elsif ($l->{TYPE} eq "DATA") { if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { -- cgit From 2afa1bee549ae119b1088c1e6affaec6f1997887 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 02:27:40 +0100 Subject: python/pidl: Fix assignment. (This used to be commit 2d2cb6486e6e1a31ae94223784e49fb4eea8bb26) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index a2ad3c6508..a7e1791793 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -322,7 +322,6 @@ sub PythonFunction($$$) 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++; } } @@ -523,6 +522,16 @@ sub register_module_method($$$$$) push (@{$self->{module_methods}}, [$fn_name, $pyfn_name, $flags, $doc]) } +sub assign($$$) +{ + my ($self, $dest, $src) = @_; + if ($dest =~ /^\&/) { + $self->pidl("memcpy($dest, $src, sizeof(*$dest));"); + } else { + $self->pidl("$dest = $src;"); + } +} + sub ConvertObjectFromPythonData($$$$$$) { my ($self, $mem_ctx, $cvar, $ctype, $target, $fail) = @_; @@ -553,7 +562,7 @@ sub ConvertObjectFromPythonData($$$$$$) if ($actual_ctype->{TYPE} eq "STRUCT") { $self->pidl("PY_CHECK_TYPE($ctype->{NAME}, $cvar, $fail);"); - $self->pidl("$target = py_talloc_get_ptr($cvar);"); + $self->assign($target, "py_talloc_get_ptr($cvar)"); return; } @@ -590,7 +599,7 @@ sub ConvertObjectFromPythonData($$$$$$) } if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "pointer") { - $self->pidl("$target = PyCObject_AsVoidPtr($cvar);"); + $self->assign($target, "PyCObject_AsVoidPtr($cvar)"); return; } @@ -624,7 +633,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$) $self->pidl("{"); $self->indent; $self->pidl("int $counter;"); - $self->pidl("$var_name = talloc_array($mem_ctx, FIXME, PyList_Size($py_var));"); + $self->pidl("$var_name = talloc_array_ptrtype($mem_ctx, $var_name, PyList_Size($py_var));"); $self->pidl("for ($counter = 0; $counter < PyList_Size($py_var); $counter++) {"); $self->indent; $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GetItem($py_var, $counter)", $e, GetNextLevel($e, $l), $var_name."[$counter]", $fail); @@ -645,7 +654,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$) my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e); $self->pidl("$var_name = py_export_" . GetNextLevel($e, $l)->{DATA_TYPE} . "($mem_ctx, $switch, $py_var);"); } elsif ($l->{TYPE} eq "SUBCONTEXT") { - $self->pidl("FIXME"); + $self->pidl("#error Subcontext not yet supported"); } else { die("unknown level type $l->{TYPE}"); } @@ -686,9 +695,9 @@ sub ConvertScalarToPython($$$) return "PyString_FromString($cvar)"; } - if ($ctypename eq "string_array") { return "FIXME($cvar)"; } - - if ($ctypename eq "ipv4address") { return "FIXME($cvar)"; } + # Not yet supported + if ($ctypename eq "string_array") { return "PyCObject_FromVoidPtr($cvar)"; } + if ($ctypename eq "ipv4address") { return "PyCObject_FromVoidPtr($cvar)"; } if ($ctypename eq "pointer") { return "PyCObject_FromVoidPtr($cvar, talloc_free)"; } @@ -794,7 +803,8 @@ sub ConvertObjectToPythonLevel($$$$) Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { $var_name = get_pointer_to($var_name); } - $self->pidl("$py_var = ".$self->ConvertObjectToPythonData($l->{DATA_TYPE}, $var_name) . ";"); + my $conv = $self->ConvertObjectToPythonData($l->{DATA_TYPE}, $var_name); + $self->pidl("$py_var = $conv;"); } elsif ($l->{TYPE} eq "SUBCONTEXT") { $self->pidl("FIXME"); } else { -- cgit From d5903fd75e9640831f0e78fc04d3ffa5ea3b1b4a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 02:48:50 +0100 Subject: pidl/python: Fix compilation of py_echo. (This used to be commit 5ee99ff31c80ece6861b2a0323d71170ef9346b9) --- source4/foo.py | 22 ++++++++++++++++++++++ source4/librpc/config.mk | 2 +- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 16 ++++++++++++++-- source4/scripting/python/config.mk | 2 +- source4/scripting/python/pytalloc.c | 7 ++++--- 5 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 source4/foo.py (limited to 'source4') diff --git a/source4/foo.py b/source4/foo.py new file mode 100644 index 0000000000..0e2d35f080 --- /dev/null +++ b/source4/foo.py @@ -0,0 +1,22 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +from echo import rpcecho + +x = rpcecho("ncalrpc:") diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index debfbb6869..e491f69b34 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -597,4 +597,4 @@ PUBLIC_DEPENDENCIES = LIBCLI_SMB NDR_MISC LIBSAMBA-UTIL LIBSAMBA-CONFIG dcerpc_s [PYTHON::python_echo] OBJ_FILES = gen_ndr/py_echo.o -PRIVATE_DEPENDENCIES = NDR_ECHO +PRIVATE_DEPENDENCIES = RPC_NDR_ECHO diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index a7e1791793..f569f013dc 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -384,7 +384,7 @@ sub PythonType($$$) $self->EnumAndBitmapConsts($d->{NAME}, $d->{DATA}); } - if ($actual_ctype->{TYPE} eq "UNION") { + if ($actual_ctype->{TYPE} eq "UNION" and defined($actual_ctype->{ELEMENTS})) { $self->pidl("PyObject *py_import_$d->{NAME}(int level, " .mapTypeName($d) . " *in)"); $self->pidl("{"); $self->indent; @@ -486,7 +486,7 @@ sub Interface($$$) $self->pidl(""); $self->register_module_method($interface->{NAME}, "interface_$interface->{NAME}", "METH_VARARGS|METH_KEYWORDS", "NULL"); - $self->pidl("static PyObject *interface_$interface->{NAME}(PyObject *self, PyObject *args)"); + $self->pidl("static PyObject *interface_$interface->{NAME}(PyObject *self, PyObject *args, PyObject *kwargs)"); $self->pidl("{"); $self->indent; $self->pidl("$interface->{NAME}_InterfaceObject *ret;"); @@ -496,6 +496,18 @@ sub Interface($$$) $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->deindent; + $self->pidl("};"); + $self->pidl(""); + $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"s:$interface->{NAME}\", discard_const_p(char *, kwnames), &binding_string)) {"); + $self->indent; + $self->pidl("return NULL;"); + $self->deindent; + $self->pidl("}"); + $self->pidl(""); # FIXME: Arguments: binding string, credentials, loadparm context $self->pidl("ret = PyObject_New($interface->{NAME}_InterfaceObject, &$interface->{NAME}_InterfaceType);"); diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index cfd179aff5..f00b477919 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -5,7 +5,7 @@ OBJ_FILES = smbpython.o [SUBSYSTEM::LIBPYTHON] PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON INIT_FUNCTION_SENTINEL = { NULL, NULL } -OBJ_FILES = modules.o +OBJ_FILES = modules.o pytalloc.o [PYTHON::python_uuid] PRIVATE_DEPENDENCIES = LIBNDR diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index d0b8cb83f2..dc61a0a13d 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "scripting/python/pytalloc.h" void py_talloc_dealloc(PyObject* self) { @@ -26,13 +27,13 @@ void py_talloc_dealloc(PyObject* self) PyObject_Del(self); } -PyObject *py_talloc_import(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, +PyObject *py_talloc_import_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) { - PyObject *ret = PyObject_New(py_talloc_Object, &py_type); + py_talloc_Object *ret = PyObject_New(py_talloc_Object, py_type); ret->talloc_ctx = talloc_reference(mem_ctx, ptr); ret->ptr = ptr; - return ret; + return (PyObject *)ret; } PyObject *py_talloc_default_repr(PyObject *py_obj) -- cgit From db4ee4cce5f1fd84f3f0a331e769a70394126ca5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 03:59:36 +0100 Subject: python: Fix rpcecho tests. (This used to be commit ebb78ea4232c1614755844849580e3697b0a53fa) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 4 +-- source4/scripting/python/STATUS | 5 --- .../python/samba/tests/dcerpc/__init__.py | 0 .../scripting/python/samba/tests/dcerpc/rpcecho.py | 39 ++++++++++++++++++++++ source4/selftest/samba4_tests.sh | 2 +- source4/torture/rpc/echo.py | 39 ---------------------- 6 files changed, 42 insertions(+), 47 deletions(-) create mode 100644 source4/scripting/python/samba/tests/dcerpc/__init__.py create mode 100644 source4/scripting/python/samba/tests/dcerpc/rpcecho.py delete mode 100644 source4/torture/rpc/echo.py (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index f569f013dc..266a092788 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -491,8 +491,8 @@ sub Interface($$$) $self->indent; $self->pidl("$interface->{NAME}_InterfaceObject *ret;"); $self->pidl("const char *binding_string;"); - $self->pidl("struct cli_credentials *credentials;"); - $self->pidl("struct loadparm_context *lp_ctx;"); + $self->pidl("struct cli_credentials *credentials = NULL;"); + $self->pidl("struct loadparm_context *lp_ctx = NULL;"); $self->pidl("TALLOC_CTX *mem_ctx = NULL;"); $self->pidl("NTSTATUS status;"); $self->pidl(""); diff --git a/source4/scripting/python/STATUS b/source4/scripting/python/STATUS index 5972027f59..9a1c5b1b64 100644 --- a/source4/scripting/python/STATUS +++ b/source4/scripting/python/STATUS @@ -9,11 +9,6 @@ DCE/RPC bindings Parse::Pidl::Samba::Python - wrap struct/bitmap/enum/union types - __ndr_pack__/__ndr_unpack__ members - Parse::Pidl::Samba::NDR::Python - - pidl generated client fns - - one class per interface - - AddOne() - - scripting/bin/smbstatus.py - scripting/bin/winreg.py diff --git a/source4/scripting/python/samba/tests/dcerpc/__init__.py b/source4/scripting/python/samba/tests/dcerpc/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py new file mode 100644 index 0000000000..cedd0cc2fe --- /dev/null +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -0,0 +1,39 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import echo +import unittest + +class RpcEchoTests(unittest.TestCase): + def setUp(self): + self.conn = echo.rpcecho("ncalrpc:") + + def test_addone(self): + self.assertEquals(2, conn.AddOne(1)) + + def test_echodata(self): + self.assertEquals("bla", conn.EchoData(3, "bla")) + + def test_call(self): + self.assertEquals("foobar", conn.TestCall("foobar")) + + def test_surrounding(self): + somearray = [1,2,3,4] + (y,) = conn.TestSurrounding(echo.Surrounding(4, somearray)) + self.assertEquals(8 * [0], y.surrounding) diff --git a/source4/selftest/samba4_tests.sh b/source4/selftest/samba4_tests.sh index 14b51c6054..c1dac21614 100755 --- a/source4/selftest/samba4_tests.sh +++ b/source4/selftest/samba4_tests.sh @@ -322,7 +322,7 @@ then plantest "samba3.python" none $SUBUNITRUN samba.tests.samba3 plantest "events.python" none PYTHONPATH="$PYTHONPATH:lib/events" $SUBUNITRUN tests plantest "samba3sam.python" none PYTHONPATH="$PYTHONPATH:dsdb/samdb/ldb_modules/tests" $SUBUNITRUN samba3sam - plantest "rpcecho.python" dc PYTHONPATH="$PYTHONPATH:torture/rpc" $SUBUNITRUN echo + plantest "rpcecho.python" dc $SUBUNITRUN samba.tests.dcerpc.rpcecho plantest "ldap.python" dc $PYTHON $samba4srcdir/lib/ldb/tests/python/ldap.py $CONFIGURATION \$SERVER -U\$USERNAME%\$PASSWORD -W \$DOMAIN plantest "blackbox.samba3dump" none $PYTHON scripting/bin/samba3dump $samba4srcdir/../testdata/samba3 rm -rf $PREFIX/upgrade diff --git a/source4/torture/rpc/echo.py b/source4/torture/rpc/echo.py deleted file mode 100644 index 47b71c9e15..0000000000 --- a/source4/torture/rpc/echo.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/python - -# Unix SMB/CIFS implementation. -# Copyright (C) Jelmer Vernooij 2008 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -from echo import rpcecho -import unittest - -class RpcEchoTests(unittest.TestCase): - def setUp(self): - self.conn = rpcecho("ncalrpc:") - - def test_addone(self): - self.assertEquals(2, conn.AddOne(1)) - - def test_echodata(self): - self.assertEquals("bla", conn.EchoData(3, "bla")) - - def test_call(self): - self.assertEquals("foobar", conn.TestCall("foobar")) - - def test_surrounding(self): - somearray = [1,2,3,4] - (y) = conn.TestSurrounding(echo.Surrounding(4, somearray))) - self.assertEquals(8 * [0], y.surrounding) -- cgit 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(-) (limited to 'source4') 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 From aca6bd5a2a2c5fe266509499be624bbab7b5c3c0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 06:03:33 +0100 Subject: python: Fix deallocation bug in pytalloc. (This used to be commit b849b4a6c4c9b03a9704449a69f00a59fc0df9c5) --- source4/scripting/python/pytalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index dc61a0a13d..d8d3efe69c 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -31,7 +31,7 @@ PyObject *py_talloc_import_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) { py_talloc_Object *ret = PyObject_New(py_talloc_Object, py_type); - ret->talloc_ctx = talloc_reference(mem_ctx, ptr); + ret->talloc_ctx = talloc_reference(NULL, mem_ctx); ret->ptr = ptr; return (PyObject *)ret; } -- cgit From 4cfd90308c4dffebf7cebdcd8c11a7aa836ce23e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 06:05:12 +0100 Subject: pidl/python: Specify memory context explicitly when returning Python objects. (This used to be commit 9c72f652e0d3f14d5db4d3930f0d1f9a1875e93f) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 62 ++++++++++++++-------------- 1 file changed, 30 insertions(+), 32 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 04649d3668..e0751d0c72 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -91,9 +91,9 @@ sub EnumAndBitmapConsts($$$) } } -sub FromUnionToPythonFunction($$$) +sub FromUnionToPythonFunction($$$$) { - my ($self, $type, $switch, $name) = @_; + my ($self, $mem_ctx, $type, $switch, $name) = @_; $self->pidl("PyObject *ret;"); $self->pidl(""); @@ -111,7 +111,7 @@ sub FromUnionToPythonFunction($$$) $self->indent; if ($e->{NAME}) { - $self->ConvertObjectToPython({}, $e, "$name->$e->{NAME}", "ret"); + $self->ConvertObjectToPython($mem_ctx, {}, $e, "$name->$e->{NAME}", "ret"); } else { $self->pidl("ret = Py_None;"); } @@ -182,13 +182,13 @@ sub PythonStruct($$$$) $self->pidl("static PyObject *py_$name\_getattr(PyObject *obj, char *name)"); $self->pidl("{"); $self->indent; - $self->pidl("$cname *object = py_talloc_get_type(obj, $cname);"); + $self->pidl("$cname *object = py_talloc_get_ptr(obj);"); foreach my $e (@{$d->{ELEMENTS}}) { $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); my $varname = "object->$e->{NAME}"; $self->indent; $self->pidl("PyObject *py_$e->{NAME};"); - $self->ConvertObjectToPython($env, $e, $varname, "py_$e->{NAME}"); + $self->ConvertObjectToPython("py_talloc_get_talloc_ctx(obj)", $env, $e, $varname, "py_$e->{NAME}"); $self->pidl("return py_$e->{NAME};"); $self->deindent; $self->pidl("}"); @@ -202,7 +202,7 @@ sub PythonStruct($$$$) $self->pidl("static int py_$name\_setattr(PyObject *py_obj, char *name, PyObject *value)"); $self->pidl("{"); $self->indent; - $self->pidl("$cname *object = py_talloc_get_type(py_obj, $cname);"); + $self->pidl("$cname *object = py_talloc_get_ptr(py_obj);"); my $mem_ctx = "py_talloc_get_mem_ctx(py_obj)"; foreach my $e (@{$d->{ELEMENTS}}) { $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); @@ -263,10 +263,10 @@ sub PythonFunction($$$) $self->pidl("$iface\_InterfaceObject *iface = ($iface\_InterfaceObject *)self;"); $self->pidl("NTSTATUS status;"); $self->pidl("TALLOC_CTX *mem_ctx = talloc_new(NULL);"); - $self->pidl("struct $fn->{NAME} r;"); + $self->pidl("struct $fn->{NAME} *r = talloc_zero(mem_ctx, struct $fn->{NAME});"); $self->pidl("PyObject *result = Py_None;"); - - my $env = GenerateFunctionInEnv($fn, "r."); + + my $env = GenerateFunctionInEnv($fn, "r->"); my $result_size = 0; my $args_format = ""; @@ -297,23 +297,19 @@ sub PythonFunction($$$) $self->deindent; $self->pidl("}"); - if ($result_size > 0) { - $self->pidl(""); - $self->pidl("ZERO_STRUCT(r.out);"); - } if ($fn->{RETURN_TYPE}) { $result_size++; } foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - $self->ConvertObjectFromPython($env, "mem_ctx", $e, "py_$e->{NAME}", "r.in.$e->{NAME}", "talloc_free(mem_ctx); return NULL;"); + $self->ConvertObjectFromPython($env, "mem_ctx", $e, "py_$e->{NAME}", "r->in.$e->{NAME}", "talloc_free(mem_ctx); return NULL;"); } } - $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, &r);"); + $self->pidl("status = dcerpc_$fn->{NAME}(iface->pipe, mem_ctx, r);"); $self->handle_ntstatus("status", "NULL", "mem_ctx"); - $env = GenerateFunctionOutEnv($fn, "r."); + $env = GenerateFunctionOutEnv($fn, "r->"); my $i = 0; if ($result_size > 1) { @@ -323,7 +319,7 @@ sub PythonFunction($$$) 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_name); + $self->ConvertObjectToPython("r", $env, $e, "r->out.$e->{NAME}", $py_name); if ($result_size > 1) { $self->pidl("PyTuple_SetItem(result, $i, $py_name);"); $i++; @@ -334,7 +330,7 @@ sub PythonFunction($$$) } if (defined($fn->{RETURN_TYPE})) { - my $conv = $self->ConvertObjectToPythonData($fn->{RETURN_TYPE}, "r.out.result"); + my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result"); if ($result_size > 1) { $self->pidl("PyTuple_SetItem(result, $i, $conv);"); } else { @@ -397,10 +393,10 @@ sub PythonType($$$) } if ($actual_ctype->{TYPE} eq "UNION" and defined($actual_ctype->{ELEMENTS})) { - $self->pidl("PyObject *py_import_$d->{NAME}(int level, " .mapTypeName($d) . " *in)"); + $self->pidl("PyObject *py_import_$d->{NAME}(TALLOC_CTX *mem_ctx, int level, " .mapTypeName($d) . " *in)"); $self->pidl("{"); $self->indent; - $self->FromUnionToPythonFunction($actual_ctype, "level", "in") if ($actual_ctype->{TYPE} eq "UNION"); + $self->FromUnionToPythonFunction("mem_ctx", $actual_ctype, "level", "in") if ($actual_ctype->{TYPE} eq "UNION"); $self->deindent; $self->pidl("}"); $self->pidl(""); @@ -676,9 +672,11 @@ sub ConvertObjectFromPythonLevel($$$$$$$$) } } elsif ($l->{TYPE} eq "ARRAY") { if (is_charset_array($e, $l)) { + $self->pidl("PY_CHECK_TYPE(PyUnicode, $py_var, $fail);"); $self->pidl(get_pointer_to($var_name) . " = PyString_AsString(PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\"));"); } else { my $counter = "$e->{NAME}_cntr_$l->{LEVEL_INDEX}"; + $self->pidl("PY_CHECK_TYPE(PyList, $py_var, $fail);"); $self->pidl("{"); $self->indent; $self->pidl("int $counter;"); @@ -754,9 +752,9 @@ sub ConvertScalarToPython($$$) die("Unknown scalar type $ctypename"); } -sub ConvertObjectToPythonData($$$$) +sub ConvertObjectToPythonData($$$$$) { - my ($self, $ctype, $cvar) = @_; + my ($self, $mem_ctx, $ctype, $cvar) = @_; die("undef type for $cvar") unless(defined($ctype)); @@ -797,9 +795,9 @@ sub ConvertObjectToPythonData($$$$) die("unknown type ".mapTypeName($ctype) . ": $cvar"); } -sub ConvertObjectToPythonLevel($$$$) +sub ConvertObjectToPythonLevel($$$$$) { - my ($self, $env, $e, $l, $var_name, $py_var) = @_; + my ($self, $mem_ctx, $env, $e, $l, $var_name, $py_var) = @_; if ($l->{TYPE} eq "POINTER") { if ($l->{POINTER_TYPE} ne "ref") { @@ -810,7 +808,7 @@ sub ConvertObjectToPythonLevel($$$$) $self->pidl("} else {"); $self->indent; } - $self->ConvertObjectToPythonLevel($env, $e, GetNextLevel($e, $l), get_value_of($var_name), $py_var); + $self->ConvertObjectToPythonLevel($var_name, $env, $e, GetNextLevel($e, $l), get_value_of($var_name), $py_var); if ($l->{POINTER_TYPE} ne "ref") { $self->deindent; $self->pidl("}"); @@ -836,7 +834,7 @@ sub ConvertObjectToPythonLevel($$$$) $self->indent; my $member_var = "py_$e->{NAME}_$l->{LEVEL_INDEX}"; $self->pidl("PyObject *$member_var;"); - $self->ConvertObjectToPythonLevel($env, $e, GetNextLevel($e, $l), $var_name."[$counter]", $member_var); + $self->ConvertObjectToPythonLevel($var_name, $env, $e, GetNextLevel($e, $l), $var_name."[$counter]", $member_var); $self->pidl("PyList_SetItem($py_var, $counter, $member_var);"); $self->deindent; $self->pidl("}"); @@ -846,13 +844,13 @@ sub ConvertObjectToPythonLevel($$$$) } elsif ($l->{TYPE} eq "SWITCH") { $var_name = get_pointer_to($var_name); my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e); - $self->pidl("$py_var = py_import_" . GetNextLevel($e, $l)->{DATA_TYPE} . "($switch, $var_name);"); + $self->pidl("$py_var = py_import_" . GetNextLevel($e, $l)->{DATA_TYPE} . "($mem_ctx, $switch, $var_name);"); } elsif ($l->{TYPE} eq "DATA") { if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { $var_name = get_pointer_to($var_name); } - my $conv = $self->ConvertObjectToPythonData($l->{DATA_TYPE}, $var_name); + my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name); $self->pidl("$py_var = $conv;"); } elsif ($l->{TYPE} eq "SUBCONTEXT") { $self->pidl("FIXME"); @@ -861,11 +859,11 @@ sub ConvertObjectToPythonLevel($$$$) } } -sub ConvertObjectToPython($$$$$) +sub ConvertObjectToPython($$$$$$) { - my ($self, $env, $ctype, $cvar, $py_var) = @_; + my ($self, $mem_ctx, $env, $ctype, $cvar, $py_var) = @_; - $self->ConvertObjectToPythonLevel($env, $ctype, $ctype->{LEVELS}[0], $cvar, $py_var); + $self->ConvertObjectToPythonLevel($mem_ctx, $env, $ctype, $ctype->{LEVELS}[0], $cvar, $py_var); } sub Parse($$$$$) @@ -925,7 +923,7 @@ sub Parse($$$$$) } elsif ($cvar =~ /^".*"$/) { $py_obj = "PyString_FromString($cvar)"; } else { - $py_obj = $self->ConvertObjectToPythonData($ctype, $cvar); + $py_obj = $self->ConvertObjectToPythonData("NULL", $ctype, $cvar); } $self->pidl("PyModule_AddObject(m, \"$name\", $py_obj);"); -- cgit From 271f5f18f2c871cfba256f7088839e4eb195e289 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 06:05:28 +0100 Subject: python: Fix last bugs in rpcecho test. It passes now! (This used to be commit 25a0cd091bb24e579ceb34472d9c213aae157ba9) --- source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4') diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 52a4f49bb4..52c2bb8c72 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -31,12 +31,14 @@ class RpcEchoTests(unittest.TestCase): self.assertEquals(2, self.conn.AddOne(1)) def test_echodata(self): - self.assertEquals("bla", self.conn.EchoData(3, "bla")) + self.assertEquals([1,2,3], self.conn.EchoData(3, [1, 2, 3])) def test_call(self): - self.assertEquals("foobar", self.conn.TestCall("foobar")) + self.assertEquals(u"foobar", self.conn.TestCall(u"foobar")) def test_surrounding(self): - somearray = [1,2,3,4] - (y,) = self.conn.TestSurrounding(echo.Surrounding(4, somearray)) + surrounding_struct = echo.Surrounding() + surrounding_struct.x = 4 + surrounding_struct.surrounding = [1,2,3,4] + y = self.conn.TestSurrounding(surrounding_struct) self.assertEquals(8 * [0], y.surrounding) -- cgit From e231e24d89dfe3faaf0f791dc5e0df5fa9c21590 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 06:23:13 +0100 Subject: pidl/python: Deal with arrays that are not pointers. (This used to be commit 7516af7c7262240df3b804dda962194a811d4e96) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index e0751d0c72..1483083e22 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -673,8 +673,14 @@ sub ConvertObjectFromPythonLevel($$$$$$$$) } elsif ($l->{TYPE} eq "ARRAY") { if (is_charset_array($e, $l)) { $self->pidl("PY_CHECK_TYPE(PyUnicode, $py_var, $fail);"); + # FIXME: Use Unix charset setting rather than utf-8 $self->pidl(get_pointer_to($var_name) . " = PyString_AsString(PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\"));"); } else { + my $pl = GetPrevLevel($e, $l); + if ($pl && $pl->{TYPE} eq "POINTER") { + $var_name = get_pointer_to($var_name); + } + my $counter = "$e->{NAME}_cntr_$l->{LEVEL_INDEX}"; $self->pidl("PY_CHECK_TYPE(PyList, $py_var, $fail);"); $self->pidl("{"); @@ -816,8 +822,14 @@ sub ConvertObjectToPythonLevel($$$$$) } elsif ($l->{TYPE} eq "ARRAY") { if (is_charset_array($e, $l)) { $var_name = get_pointer_to($var_name); + # FIXME: Use Unix charset setting rather than utf-8 $self->pidl("$py_var = PyUnicode_Decode($var_name, strlen($var_name), \"utf-8\", \"ignore\");"); } else { + my $pl = GetPrevLevel($e, $l); + if ($pl && $pl->{TYPE} eq "POINTER") { + $var_name = get_pointer_to($var_name); + } + die("No SIZE_IS for array $var_name") unless (defined($l->{SIZE_IS})); my $length = $l->{SIZE_IS}; if (defined($l->{LENGTH_IS})) { -- cgit From 30a2a43a7546b5336058559f5ffd74b1f799c05b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 13:26:01 +0100 Subject: pidl/python: Fix processing UUID-less interfaces, external typedefs and certain bitmap elements. (This used to be commit e65618fff3299193c27959e2cc5a3937837e1422) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 261 +++++++++++++-------------- source4/pidl/lib/Parse/Pidl/Typelist.pm | 16 +- 2 files changed, 137 insertions(+), 140 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 1483083e22..e538771624 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -9,7 +9,7 @@ use Exporter; @ISA = qw(Exporter); use strict; -use Parse::Pidl::Typelist qw(hasType getType mapTypeName expandAlias); +use Parse::Pidl::Typelist qw(hasType resolveType getType mapTypeName expandAlias); use Parse::Pidl::Util qw(has_property ParseExpr); use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array); use Parse::Pidl::CUtil qw(get_value_of get_pointer_to); @@ -84,7 +84,7 @@ sub EnumAndBitmapConsts($$$) return unless (defined($d->{ELEMENTS})); foreach my $e (@{$d->{ELEMENTS}}) { - $e =~ /^([A-Za-z0-9_]+)=(.*)$/; + $e =~ /^([A-Za-z0-9_]+)/; my $cname = $1; $self->register_constant($cname, $d, $cname); @@ -188,7 +188,7 @@ sub PythonStruct($$$$) my $varname = "object->$e->{NAME}"; $self->indent; $self->pidl("PyObject *py_$e->{NAME};"); - $self->ConvertObjectToPython("py_talloc_get_talloc_ctx(obj)", $env, $e, $varname, "py_$e->{NAME}"); + $self->ConvertObjectToPython("py_talloc_get_mem_ctx(obj)", $env, $e, $varname, "py_$e->{NAME}"); $self->pidl("return py_$e->{NAME};"); $self->deindent; $self->pidl("}"); @@ -428,133 +428,135 @@ sub Interface($$$) $self->PythonType($d, $interface, $basename); } - $self->pidl_hdr("PyAPI_DATA(PyTypeObject) $interface->{NAME}_InterfaceType;\n"); - $self->pidl("typedef struct {"); - $self->indent; - $self->pidl("PyObject_HEAD"); - $self->pidl("struct dcerpc_pipe *pipe;"); - $self->deindent; - $self->pidl("} $interface->{NAME}_InterfaceObject;"); + if (defined $interface->{PROPERTIES}->{uuid}) { + $self->pidl_hdr("PyAPI_DATA(PyTypeObject) $interface->{NAME}_InterfaceType;\n"); + $self->pidl("typedef struct {"); + $self->indent; + $self->pidl("PyObject_HEAD"); + $self->pidl("struct dcerpc_pipe *pipe;"); + $self->deindent; + $self->pidl("} $interface->{NAME}_InterfaceObject;"); - $self->pidl(""); + $self->pidl(""); - foreach my $d (@{$interface->{FUNCTIONS}}) { - next if not defined($d->{OPNUM}); - next if has_property($d, "nopython"); + foreach my $d (@{$interface->{FUNCTIONS}}) { + next if not defined($d->{OPNUM}); + next if has_property($d, "nopython"); - $self->PythonFunction($d, $interface->{NAME}); - } + $self->PythonFunction($d, $interface->{NAME}); + } - $self->pidl("static PyMethodDef interface_$interface->{NAME}\_methods[] = {"); - $self->indent; - foreach my $d (@{$interface->{FUNCTIONS}}) { - next if not defined($d->{OPNUM}); - next if has_property($d, "nopython"); + $self->pidl("static PyMethodDef interface_$interface->{NAME}\_methods[] = {"); + $self->indent; + foreach my $d (@{$interface->{FUNCTIONS}}) { + next if not defined($d->{OPNUM}); + next if has_property($d, "nopython"); - my $fn_name = $d->{NAME}; + my $fn_name = $d->{NAME}; - $fn_name =~ s/^$interface->{NAME}_//; - $fn_name =~ s/^$basename\_//; + $fn_name =~ s/^$interface->{NAME}_//; + $fn_name =~ s/^$basename\_//; - $self->pidl("{ \"$fn_name\", (PyCFunction)py_$d->{NAME}, METH_VARARGS|METH_KEYWORDS, NULL },"); - } - $self->pidl("{ NULL, NULL, 0, NULL }"); - $self->deindent; - $self->pidl("};"); - $self->pidl(""); + $self->pidl("{ \"$fn_name\", (PyCFunction)py_$d->{NAME}, METH_VARARGS|METH_KEYWORDS, NULL },"); + } + $self->pidl("{ NULL, NULL, 0, NULL }"); + $self->deindent; + $self->pidl("};"); + $self->pidl(""); - $self->pidl("static void interface_$interface->{NAME}_dealloc(PyObject* self)"); - $self->pidl("{"); - $self->indent; - $self->pidl("$interface->{NAME}_InterfaceObject *interface = ($interface->{NAME}_InterfaceObject *)self;"); - $self->pidl("talloc_free(interface->pipe);"); - $self->pidl("PyObject_Del(self);"); - $self->deindent; - $self->pidl("}"); - $self->pidl(""); + $self->pidl("static void interface_$interface->{NAME}_dealloc(PyObject* self)"); + $self->pidl("{"); + $self->indent; + $self->pidl("$interface->{NAME}_InterfaceObject *interface = ($interface->{NAME}_InterfaceObject *)self;"); + $self->pidl("talloc_free(interface->pipe);"); + $self->pidl("PyObject_Del(self);"); + $self->deindent; + $self->pidl("}"); + $self->pidl(""); - $self->pidl("static PyObject *interface_$interface->{NAME}_getattr(PyObject *obj, char *name)"); - $self->pidl("{"); - $self->indent; - $self->pidl("return Py_FindMethod(interface_$interface->{NAME}\_methods, obj, name);"); - $self->deindent; - $self->pidl("}"); + $self->pidl("static PyObject *interface_$interface->{NAME}_getattr(PyObject *obj, char *name)"); + $self->pidl("{"); + $self->indent; + $self->pidl("return Py_FindMethod(interface_$interface->{NAME}\_methods, obj, name);"); + $self->deindent; + $self->pidl("}"); - $self->pidl(""); + $self->pidl(""); - $self->pidl("PyTypeObject $interface->{NAME}_InterfaceType = {"); - $self->indent; - $self->pidl("PyObject_HEAD_INIT(NULL) 0,"); - $self->pidl(".tp_name = \"$interface->{NAME}\","); - $self->pidl(".tp_basicsize = sizeof($interface->{NAME}_InterfaceObject),"); - $self->pidl(".tp_dealloc = interface_$interface->{NAME}_dealloc,"); - $self->pidl(".tp_getattr = interface_$interface->{NAME}_getattr,"); - $self->deindent; - $self->pidl("};"); + $self->pidl("PyTypeObject $interface->{NAME}_InterfaceType = {"); + $self->indent; + $self->pidl("PyObject_HEAD_INIT(NULL) 0,"); + $self->pidl(".tp_name = \"$interface->{NAME}\","); + $self->pidl(".tp_basicsize = sizeof($interface->{NAME}_InterfaceObject),"); + $self->pidl(".tp_dealloc = interface_$interface->{NAME}_dealloc,"); + $self->pidl(".tp_getattr = interface_$interface->{NAME}_getattr,"); + $self->deindent; + $self->pidl("};"); - $self->pidl(""); + $self->pidl(""); - $self->register_module_method($interface->{NAME}, "interface_$interface->{NAME}", "METH_VARARGS|METH_KEYWORDS", "NULL"); - $self->pidl("static PyObject *interface_$interface->{NAME}(PyObject *self, PyObject *args, PyObject *kwargs)"); - $self->pidl("{"); - $self->indent; - $self->pidl("$interface->{NAME}_InterfaceObject *ret;"); - $self->pidl("const char *binding_string;"); - $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\", \"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 (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(""); + $self->register_module_method($interface->{NAME}, "interface_$interface->{NAME}", "METH_VARARGS|METH_KEYWORDS", "NULL"); + $self->pidl("static PyObject *interface_$interface->{NAME}(PyObject *self, PyObject *args, PyObject *kwargs)"); + $self->pidl("{"); + $self->indent; + $self->pidl("$interface->{NAME}_InterfaceObject *ret;"); + $self->pidl("const char *binding_string;"); + $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\", \"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 (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(""); - $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("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(""); + $self->pidl("ret = PyObject_New($interface->{NAME}_InterfaceObject, &$interface->{NAME}_InterfaceType);"); + $self->pidl(""); - $self->pidl("status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string, "); - $self->pidl(" &ndr_table_$interface->{NAME}, credentials, NULL, lp_ctx);"); - $self->handle_ntstatus("status", "NULL", "mem_ctx"); + $self->pidl("status = dcerpc_pipe_connect(NULL, &ret->pipe, binding_string, "); + $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("ret->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;"); - $self->pidl("return (PyObject *)ret;"); - $self->deindent; - $self->pidl("}"); - - $self->pidl(""); + $self->pidl("return (PyObject *)ret;"); + $self->deindent; + $self->pidl("}"); + + $self->pidl(""); + } $self->pidl_hdr("\n"); $self->pidl_hdr("#endif /* _HEADER_NDR_$interface->{NAME} */\n"); @@ -583,9 +585,7 @@ sub ConvertObjectFromPythonData($$$$$$) die("undef type for $cvar") unless(defined($ctype)); - if (ref($ctype) ne "HASH") { - $ctype = getType($ctype); - } + $ctype = resolveType($ctype); if (ref($ctype) ne "HASH") { $self->pidl("$target = FIXME($cvar);"); @@ -764,38 +764,21 @@ sub ConvertObjectToPythonData($$$$$) die("undef type for $cvar") unless(defined($ctype)); - if (ref($ctype) ne "HASH") { - if (not hasType($ctype)) { - if (ref($ctype) eq "HASH") { - return "py_import_$ctype->{TYPE}_$ctype->{NAME}($cvar)"; - } else { - return "py_import_$ctype($cvar)"; # best bet - } - } - - $ctype = getType($ctype); - } + $ctype = resolveType($ctype); my $actual_ctype = $ctype; if ($ctype->{TYPE} eq "TYPEDEF") { $actual_ctype = $ctype->{DATA}; - } - + } + if ($actual_ctype->{TYPE} eq "ENUM") { return $self->ConvertScalarToPython(Parse::Pidl::Typelist::enum_type_fn($actual_ctype), $cvar); - } - - if ($actual_ctype->{TYPE} eq "BITMAP") { + } elsif ($actual_ctype->{TYPE} eq "BITMAP") { return $self->ConvertScalarToPython(Parse::Pidl::Typelist::bitmap_type_fn($actual_ctype), $cvar); - } - - if ($actual_ctype->{TYPE} eq "SCALAR") { + } elsif ($actual_ctype->{TYPE} eq "SCALAR") { return $self->ConvertScalarToPython($actual_ctype->{NAME}, $cvar); - } - - if ($actual_ctype->{TYPE} eq "STRUCT") { - # FIXME: if $cvar is not a pointer, do a talloc_dup() - return "py_talloc_import(&$ctype->{NAME}_Type, $cvar)"; + } elsif ($actual_ctype->{TYPE} eq "STRUCT") { + return "py_talloc_import_ex(&$ctype->{NAME}_Type, $mem_ctx, $cvar)"; } die("unknown type ".mapTypeName($ctype) . ": $cvar"); diff --git a/source4/pidl/lib/Parse/Pidl/Typelist.pm b/source4/pidl/lib/Parse/Pidl/Typelist.pm index e54ef11b88..9e6c683f82 100644 --- a/source4/pidl/lib/Parse/Pidl/Typelist.pm +++ b/source4/pidl/lib/Parse/Pidl/Typelist.pm @@ -7,7 +7,7 @@ package Parse::Pidl::Typelist; require Exporter; @ISA = qw(Exporter); -@EXPORT_OK = qw(hasType getType mapTypeName scalar_is_reference expandAlias +@EXPORT_OK = qw(hasType getType resolveType mapTypeName scalar_is_reference expandAlias mapScalarType addType typeIs is_scalar enum_type_fn bitmap_type_fn mapType typeHasBody ); @@ -95,6 +95,20 @@ sub addType($) $types{$t->{NAME}} = $t; } +sub resolveType($) +{ + my ($ctype) = @_; + + if (not hasType($ctype)) { + # assume struct typedef + return { TYPE => "TYPEDEF", NAME => $ctype, DATA => { TYPE => "STRUCT" } }; + } else { + return getType($ctype); + } + + return $ctype; +} + sub getType($) { my $t = shift; -- cgit From e42322848b81a36528a0af88138acb3ec997bf01 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 13:26:21 +0100 Subject: python: Start building winreg module. (This used to be commit f1a9fad83cee7754304b3422aa273d5f64868e40) --- source4/librpc/config.mk | 7 +++++++ source4/scripting/python/modules.c | 1 + 2 files changed, 8 insertions(+) (limited to 'source4') diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index e491f69b34..55991f4953 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -598,3 +598,10 @@ PUBLIC_DEPENDENCIES = LIBCLI_SMB NDR_MISC LIBSAMBA-UTIL LIBSAMBA-CONFIG dcerpc_s [PYTHON::python_echo] OBJ_FILES = gen_ndr/py_echo.o PRIVATE_DEPENDENCIES = RPC_NDR_ECHO + +[PYTHON::python_winreg] +OBJ_FILES = gen_ndr/py_winreg.o +PRIVATE_DEPENDENCIES = RPC_NDR_WINREG python_misc + +[PYTHON::python_dcerpc_misc] +OBJ_FILES = gen_ndr/py_misc.o diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 55df51d881..5e53aadb94 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -35,6 +35,7 @@ extern void init_events(void); extern void inituuid(void); extern void init_net(void); extern void initecho(void); +extern void initwinreg(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From 7dd468ff2e5a4c4ce503e1b8e024bf91dcf7a412 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 14:48:59 +0100 Subject: python: Fix python code for winreg, add test. (This used to be commit bd3e6c41c42738fcfcc5cef4e65f0e219d358260) --- source4/foo.py | 27 ----------- source4/librpc/config.mk | 4 ++ source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 11 +++-- source4/scripting/python/STATUS | 1 - .../python/samba/tests/dcerpc/registry.py | 53 ++++++++++++++++++++++ source4/selftest/samba4_tests.sh | 1 + 6 files changed, 64 insertions(+), 33 deletions(-) delete mode 100644 source4/foo.py create mode 100644 source4/scripting/python/samba/tests/dcerpc/registry.py (limited to 'source4') diff --git a/source4/foo.py b/source4/foo.py deleted file mode 100644 index 21a422ce01..0000000000 --- a/source4/foo.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/python - -# Unix SMB/CIFS implementation. -# Copyright (C) Jelmer Vernooij 2008 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -from echo import rpcecho -from param import LoadParm - -lp = LoadParm() -lp.load("st/client/client.conf") - -x = rpcecho("ncalrpc:", lp) -print x.AddOne(41) diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 55991f4953..ab94770d46 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -605,3 +605,7 @@ PRIVATE_DEPENDENCIES = RPC_NDR_WINREG python_misc [PYTHON::python_dcerpc_misc] OBJ_FILES = gen_ndr/py_misc.o + +[PYTHON::python_dcerpc_initshutdown] +OBJ_FILES = gen_ndr/py_initshutdown.o +PRIVATE_DEPENDENCIES = RPC_NDR_INITSHUTDOWN diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index e538771624..c8505e9904 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -665,6 +665,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$) $self->pidl("} else {"); $self->indent; } + $self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);"); $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, GetNextLevel($e, $l), get_value_of($var_name), $fail); if ($l->{POINTER_TYPE} ne "ref") { $self->deindent; @@ -686,7 +687,9 @@ sub ConvertObjectFromPythonLevel($$$$$$$$) $self->pidl("{"); $self->indent; $self->pidl("int $counter;"); - $self->pidl("$var_name = talloc_array_ptrtype($mem_ctx, $var_name, PyList_Size($py_var));"); + if (!$l->{IS_FIXED}) { + $self->pidl("$var_name = talloc_array_ptrtype($mem_ctx, $var_name, PyList_Size($py_var));"); + } $self->pidl("for ($counter = 0; $counter < PyList_Size($py_var); $counter++) {"); $self->indent; $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GetItem($py_var, $counter)", $e, GetNextLevel($e, $l), $var_name."[$counter]", $fail); @@ -697,8 +700,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$) } } elsif ($l->{TYPE} eq "DATA") { - if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or - Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { + if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) { $var_name = get_pointer_to($var_name); } $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $l->{DATA_TYPE}, $var_name, $fail); @@ -841,8 +843,7 @@ sub ConvertObjectToPythonLevel($$$$$) my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e); $self->pidl("$py_var = py_import_" . GetNextLevel($e, $l)->{DATA_TYPE} . "($mem_ctx, $switch, $var_name);"); } elsif ($l->{TYPE} eq "DATA") { - if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE}) or - Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { + if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) { $var_name = get_pointer_to($var_name); } my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name); diff --git a/source4/scripting/python/STATUS b/source4/scripting/python/STATUS index 9a1c5b1b64..0e88b4041c 100644 --- a/source4/scripting/python/STATUS +++ b/source4/scripting/python/STATUS @@ -10,7 +10,6 @@ DCE/RPC bindings - wrap struct/bitmap/enum/union types - __ndr_pack__/__ndr_unpack__ members - scripting/bin/smbstatus.py - - scripting/bin/winreg.py not important before making Python the default: - scripting/python/samba/upgrade.py diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py new file mode 100644 index 0000000000..7979592a40 --- /dev/null +++ b/source4/scripting/python/samba/tests/dcerpc/registry.py @@ -0,0 +1,53 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + + +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import winreg +from param import LoadParm +import unittest + +class WinregTests(unittest.TestCase): + def setUp(self): + lp_ctx = LoadParm() + lp_ctx.load("st/client/client.conf") + self.conn = winreg.winreg("ncalrpc:", lp_ctx) + + def test_hklm(self): + (handle, _) = self.conn.OpenHKLM(None, + winreg.KEY_QUERY_VALUE | winreg.KEY_ENUMERATE_SUB_KEYS) + self.conn.CloseKey(handle) diff --git a/source4/selftest/samba4_tests.sh b/source4/selftest/samba4_tests.sh index c1dac21614..fdf535e003 100755 --- a/source4/selftest/samba4_tests.sh +++ b/source4/selftest/samba4_tests.sh @@ -323,6 +323,7 @@ then plantest "events.python" none PYTHONPATH="$PYTHONPATH:lib/events" $SUBUNITRUN tests plantest "samba3sam.python" none PYTHONPATH="$PYTHONPATH:dsdb/samdb/ldb_modules/tests" $SUBUNITRUN samba3sam plantest "rpcecho.python" dc $SUBUNITRUN samba.tests.dcerpc.rpcecho + plantest "winreg.python" dc $SUBUNITRUN samba.tests.dcerpc.registry plantest "ldap.python" dc $PYTHON $samba4srcdir/lib/ldb/tests/python/ldap.py $CONFIGURATION \$SERVER -U\$USERNAME%\$PASSWORD -W \$DOMAIN plantest "blackbox.samba3dump" none $PYTHON scripting/bin/samba3dump $samba4srcdir/../testdata/samba3 rm -rf $PREFIX/upgrade -- cgit From 035599fa651409502a6894179d5cd8a026110ba1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 15:25:09 +0100 Subject: python: Be more pythonic - turn WERROR and NTSTATUS return codes into exceptions. (This used to be commit 16fc69b843e92ae62b15caf927335cc117156499) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 22 ++++++++++-- .../python/samba/tests/dcerpc/registry.py | 39 ++++++++++------------ 2 files changed, 38 insertions(+), 23 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index c8505e9904..9f6a7847b1 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -298,7 +298,7 @@ sub PythonFunction($$$) $self->pidl("}"); if ($fn->{RETURN_TYPE}) { - $result_size++; + $result_size++ unless ($fn->{RETURN_TYPE} eq "WERROR" or $fn->{RETURN_TYPE} eq "NTSTATUS"); } foreach my $e (@{$fn->{ELEMENTS}}) { @@ -329,7 +329,11 @@ sub PythonFunction($$$) } } - if (defined($fn->{RETURN_TYPE})) { + if (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "NTSTATUS") { + $self->handle_ntstatus("r->out.result", "NULL", "mem_ctx"); + } elsif (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "WERROR") { + $self->handle_werror("r->out.result", "NULL", "mem_ctx"); + } elsif (defined($fn->{RETURN_TYPE})) { my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result"); if ($result_size > 1) { $self->pidl("PyTuple_SetItem(result, $i, $conv);"); @@ -345,6 +349,20 @@ sub PythonFunction($$$) $self->pidl(""); } +sub handle_werror($$$$) +{ + my ($self, $var, $retval, $mem_ctx) = @_; + + $self->pidl("if (!W_ERROR_IS_OK($var)) {"); + $self->indent; + $self->pidl("PyErr_SetString(PyExc_RuntimeError, win_errstr($var));"); + $self->pidl("talloc_free($mem_ctx);") if ($mem_ctx); + $self->pidl("return $retval;"); + $self->deindent; + $self->pidl("}"); + $self->pidl(""); +} + sub handle_ntstatus($$$$) { my ($self, $var, $retval, $mem_ctx) = @_; diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py index 7979592a40..f3f0b0fb1a 100644 --- a/source4/scripting/python/samba/tests/dcerpc/registry.py +++ b/source4/scripting/python/samba/tests/dcerpc/registry.py @@ -17,26 +17,6 @@ # along with this program. If not, see . # - -#!/usr/bin/python - -# Unix SMB/CIFS implementation. -# Copyright (C) Jelmer Vernooij 2008 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - import winreg from param import LoadParm import unittest @@ -47,7 +27,24 @@ class WinregTests(unittest.TestCase): lp_ctx.load("st/client/client.conf") self.conn = winreg.winreg("ncalrpc:", lp_ctx) + def get_hklm(self): + return self.conn.OpenHKLM(None, + winreg.KEY_QUERY_VALUE | winreg.KEY_ENUMERATE_SUB_KEYS) + def test_hklm(self): - (handle, _) = self.conn.OpenHKLM(None, + handle = self.conn.OpenHKLM(None, + winreg.KEY_QUERY_VALUE | winreg.KEY_ENUMERATE_SUB_KEYS) + self.conn.CloseKey(handle) + + def test_getversion(self): + handle = self.get_hklm() + version = self.conn.GetVersion(handle) + self.assertEquals(int, version.__class__) + self.conn.CloseKey(handle) + + def test_getkeyinfo(self): + handle = self.conn.OpenHKLM(None, winreg.KEY_QUERY_VALUE | winreg.KEY_ENUMERATE_SUB_KEYS) + x = self.conn.QueryInfoKey(handle, winreg.String()) + self.assertEquals(9, len(x)) # should return a 9-tuple self.conn.CloseKey(handle) -- cgit From 251457264bf862e3048414ef0d77c133be1bd3d0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 16:11:36 +0100 Subject: python: Accept loadparm filename rather than loadparm object, too. (This used to be commit 7e583a7ec4196982bd13cb679d741f37ef7decdb) --- source4/param/param.i | 11 ++++++++++- source4/param/param_wrap.c | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/param/param.i b/source4/param/param.i index fdc9de233f..eeecb0e5b9 100644 --- a/source4/param/param.i +++ b/source4/param/param.i @@ -296,7 +296,16 @@ 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) + if (PyString_Check(py_obj)) { + lp_ctx = loadparm_init(NULL); + if (!lp_load(lp_ctx, PyString_AsString(py_obj))) { + talloc_free(lp_ctx); + return NULL; + } + return lp_ctx; + } + + if (SWIG_ConvertPtr(py_obj, (void *)&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 e9fe8a3df5..d8be725c5e 100644 --- a/source4/param/param_wrap.c +++ b/source4/param/param_wrap.c @@ -2765,7 +2765,16 @@ SWIGINTERN struct param_opt *param_section_next_parameter(param_section *self,st 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) + if (PyString_Check(py_obj)) { + lp_ctx = loadparm_init(NULL); + if (!lp_load(lp_ctx, PyString_AsString(py_obj))) { + talloc_free(lp_ctx); + return NULL; + } + return lp_ctx; + } + + if (SWIG_ConvertPtr(py_obj, (void *)&lp_ctx, SWIGTYPE_p_loadparm_context, 0 | 0 ) < 0) return NULL; return lp_ctx; } -- cgit From fa5397fbeda759ac66fc5d0a6bdfb60a070a7962 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 16:11:58 +0100 Subject: python: Build epmapper module. (This used to be commit 6cb78c7634de0f9ab327583844d7860d384356eb) --- source4/librpc/config.mk | 5 +- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 83 +++++++++++++--------------- source4/scripting/python/modules.c | 3 + 3 files changed, 44 insertions(+), 47 deletions(-) (limited to 'source4') diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index ab94770d46..03977e8263 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -606,6 +606,9 @@ PRIVATE_DEPENDENCIES = RPC_NDR_WINREG python_misc [PYTHON::python_dcerpc_misc] OBJ_FILES = gen_ndr/py_misc.o -[PYTHON::python_dcerpc_initshutdown] +[PYTHON::python_initshutdown] OBJ_FILES = gen_ndr/py_initshutdown.o PRIVATE_DEPENDENCIES = RPC_NDR_INITSHUTDOWN + +[PYTHON::python_epmapper] +OBJ_FILES = gen_ndr/py_epmapper.o diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 9f6a7847b1..0d5237022a 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -102,11 +102,7 @@ sub FromUnionToPythonFunction($$$$) $self->indent; foreach my $e (@{$type->{ELEMENTS}}) { - if (defined($e->{CASE})) { - $self->pidl("$e->{CASE}:"); - } else { - $self->pidl("default:"); - } + $self->pidl("$e->{CASE}:"); $self->indent; @@ -141,12 +137,8 @@ sub FromPythonToUnionFunction($$$$$) $self->indent; foreach my $e (@{$type->{ELEMENTS}}) { - if (defined($e->{CASE})) { - $self->pidl("$e->{CASE}:"); - } else { - $has_default = 1; - $self->pidl("default:"); - } + $self->pidl("$e->{CASE}:"); + if ($e->{CASE} eq "default") { $has_default = 1; } $self->indent; if ($e->{NAME}) { $self->ConvertObjectFromPython({}, $mem_ctx, $e, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;"); @@ -182,16 +174,18 @@ sub PythonStruct($$$$) $self->pidl("static PyObject *py_$name\_getattr(PyObject *obj, char *name)"); $self->pidl("{"); $self->indent; - $self->pidl("$cname *object = py_talloc_get_ptr(obj);"); - foreach my $e (@{$d->{ELEMENTS}}) { - $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); - my $varname = "object->$e->{NAME}"; - $self->indent; - $self->pidl("PyObject *py_$e->{NAME};"); - $self->ConvertObjectToPython("py_talloc_get_mem_ctx(obj)", $env, $e, $varname, "py_$e->{NAME}"); - $self->pidl("return py_$e->{NAME};"); - $self->deindent; - $self->pidl("}"); + if ($#{$d->{ELEMENTS}} > -1) { + $self->pidl("$cname *object = py_talloc_get_ptr(obj);"); + foreach my $e (@{$d->{ELEMENTS}}) { + $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); + my $varname = "object->$e->{NAME}"; + $self->indent; + $self->pidl("PyObject *py_$e->{NAME};"); + $self->ConvertObjectToPython("py_talloc_get_mem_ctx(obj)", $env, $e, $varname, "py_$e->{NAME}"); + $self->pidl("return py_$e->{NAME};"); + $self->deindent; + $self->pidl("}"); + } } $self->pidl("PyErr_SetString(PyExc_AttributeError, \"no such attribute\");"); $self->pidl("return NULL;"); @@ -202,19 +196,21 @@ sub PythonStruct($$$$) $self->pidl("static int py_$name\_setattr(PyObject *py_obj, char *name, PyObject *value)"); $self->pidl("{"); $self->indent; - $self->pidl("$cname *object = py_talloc_get_ptr(py_obj);"); - my $mem_ctx = "py_talloc_get_mem_ctx(py_obj)"; - foreach my $e (@{$d->{ELEMENTS}}) { - $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); - my $varname = "object->$e->{NAME}"; - $self->indent; - if ($e->{ORIGINAL}->{POINTERS} > 0) { - $self->pidl("talloc_free($varname);"); + if ($#{$d->{ELEMENTS}} > -1) { + $self->pidl("$cname *object = py_talloc_get_ptr(py_obj);"); + my $mem_ctx = "py_talloc_get_mem_ctx(py_obj)"; + foreach my $e (@{$d->{ELEMENTS}}) { + $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); + my $varname = "object->$e->{NAME}"; + $self->indent; + if ($e->{ORIGINAL}->{POINTERS} > 0) { + $self->pidl("talloc_free($varname);"); + } + $self->ConvertObjectFromPython($env, $mem_ctx, $e, "value", $varname, "return -1;"); + $self->pidl("return 0;"); + $self->deindent; + $self->pidl("}"); } - $self->ConvertObjectFromPython($env, $mem_ctx, $e, "value", $varname, "return -1;"); - $self->pidl("return 0;"); - $self->deindent; - $self->pidl("}"); } $self->pidl("PyErr_SetString(PyExc_AttributeError, \"no such attribute\");"); $self->pidl("return -1;"); @@ -591,7 +587,7 @@ sub assign($$$) { my ($self, $dest, $src) = @_; if ($dest =~ /^\&/) { - $self->pidl("memcpy($dest, $src, sizeof(*$dest));"); + $self->pidl("memcpy($dest, $src, sizeof(" . get_value_of($dest) . "));"); } else { $self->pidl("$dest = $src;"); } @@ -605,11 +601,6 @@ sub ConvertObjectFromPythonData($$$$$$) $ctype = resolveType($ctype); - if (ref($ctype) ne "HASH") { - $self->pidl("$target = FIXME($cvar);"); - return; - } - my $actual_ctype = $ctype; if ($ctype->{TYPE} eq "TYPEDEF") { $actual_ctype = $ctype->{DATA}; @@ -641,7 +632,7 @@ sub ConvertObjectFromPythonData($$$$$$) } if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv4address") { - $self->pidl("$target = FIXME($cvar);"); + $self->pidl("$target = PyString_AsString($cvar);"); return; } @@ -657,7 +648,7 @@ sub ConvertObjectFromPythonData($$$$$$) } if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "string_array") { - $self->pidl("$target = FIXME($cvar);"); + $self->pidl("$target = PyCObject_AsVoidPtr($cvar);"); return; } @@ -725,9 +716,9 @@ sub ConvertObjectFromPythonLevel($$$$$$$$) } elsif ($l->{TYPE} eq "SWITCH") { $var_name = get_pointer_to($var_name); my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e); - $self->pidl("$var_name = py_export_" . GetNextLevel($e, $l)->{DATA_TYPE} . "($mem_ctx, $switch, $py_var);"); + $self->assign($var_name, "py_export_" . GetNextLevel($e, $l)->{DATA_TYPE} . "($mem_ctx, $switch, $py_var)"); } elsif ($l->{TYPE} eq "SUBCONTEXT") { - $self->pidl("#error Subcontext not yet supported"); + $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, GetNextLevel($e, $l), $var_name, $fail); } else { die("unknown level type $l->{TYPE}"); } @@ -753,7 +744,7 @@ sub ConvertScalarToPython($$$) } if ($ctypename eq "DATA_BLOB") { - return "PyString_FromStringAndSize($cvar->data, $cvar->length)"; + return "PyString_FromStringAndSize((char *)($cvar).data, ($cvar).length)"; } if ($ctypename eq "NTSTATUS") { @@ -770,7 +761,7 @@ sub ConvertScalarToPython($$$) # Not yet supported if ($ctypename eq "string_array") { return "PyCObject_FromVoidPtr($cvar)"; } - if ($ctypename eq "ipv4address") { return "PyCObject_FromVoidPtr($cvar)"; } + if ($ctypename eq "ipv4address") { return "PyString_FromString($cvar)"; } if ($ctypename eq "pointer") { return "PyCObject_FromVoidPtr($cvar, talloc_free)"; } @@ -867,7 +858,7 @@ sub ConvertObjectToPythonLevel($$$$$) my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name); $self->pidl("$py_var = $conv;"); } elsif ($l->{TYPE} eq "SUBCONTEXT") { - $self->pidl("FIXME"); + $self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, GetNextLevel($e, $l), $var_name, $py_var); } else { die("Unknown level type $l->{TYPE} $var_name"); } diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 5e53aadb94..d8a5fdeeae 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -36,6 +36,9 @@ extern void inituuid(void); extern void init_net(void); extern void initecho(void); extern void initwinreg(void); +extern void initepmapper(void); +extern void initinitshutdown(void); +static void initdcerpc_misc(void) {} static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From a896c8940ca372808c0725bc4f2725f6cb8467b8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 16:48:27 +0100 Subject: python: Enable python bindings for samr and lsa interfaces. (This used to be commit 3dfcefd8ac640ef1539185f19f7414fbcea9e741) --- source4/librpc/config.mk | 16 ++++++++++++++++ source4/librpc/idl/mgmt.idl | 2 ++ source4/scripting/python/modules.c | 3 +++ source4/scripting/python/pyrpc.h | 27 +++++++++++++++++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 source4/scripting/python/pyrpc.h (limited to 'source4') diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 03977e8263..31013289dd 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -612,3 +612,19 @@ PRIVATE_DEPENDENCIES = RPC_NDR_INITSHUTDOWN [PYTHON::python_epmapper] OBJ_FILES = gen_ndr/py_epmapper.o + +[PYTHON::python_mgmt] +OBJ_FILES = gen_ndr/py_mgmt.o +PRIVATE_DEPENDENCIES = dcerpc_mgmt + +[PYTHON::python_atsvc] +OBJ_FILES = gen_ndr/py_atsvc.o +PRIVATE_DEPENDENCIES = dcerpc_atsvc + +[PYTHON::python_samr] +OBJ_FILES = gen_ndr/py_samr.o +PRIVATE_DEPENDENCIES = dcerpc_samr + +[PYTHON::python_lsa] +OBJ_FILES = gen_ndr/py_lsa.o +PRIVATE_DEPENDENCIES = RPC_NDR_LSA diff --git a/source4/librpc/idl/mgmt.idl b/source4/librpc/idl/mgmt.idl index 60d1ebdc85..35857f26cd 100644 --- a/source4/librpc/idl/mgmt.idl +++ b/source4/librpc/idl/mgmt.idl @@ -2,6 +2,8 @@ dcerpc remote management interface */ +import "misc.idl"; + [ uuid("afa8bd80-7d8a-11c9-bef4-08002b102989"), version(1.0), diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index d8a5fdeeae..8c5115efca 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -39,6 +39,9 @@ extern void initwinreg(void); extern void initepmapper(void); extern void initinitshutdown(void); static void initdcerpc_misc(void) {} +extern void initmgmt(void); +extern void initatsvc(void); +extern void initsamr(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; diff --git a/source4/scripting/python/pyrpc.h b/source4/scripting/python/pyrpc.h new file mode 100644 index 0000000000..d7b64dbe93 --- /dev/null +++ b/source4/scripting/python/pyrpc.h @@ -0,0 +1,27 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#define PY_CHECK_TYPE(type, var, fail) \ + if (!type ## _Check(var)) {\ + PyErr_Format(PyExc_TypeError, "Expected type %s", type ## _Type.tp_name); \ + fail; \ + } + +#define dom_sid2_Type dom_sid_Type +#define dom_sid28_Type dom_sid_Type -- cgit From 860106b3f426a06eed6a681fa839dd89f339ba9a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 16:49:19 +0100 Subject: python: Move some convenience macros to a separate header rather than putting them in every generated py_* file. (This used to be commit 712274b9bdf524da125cbbe6e4bb475b21b1da66) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 8 ++------ source4/scripting/python/pyrpc.h | 2 ++ 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 0d5237022a..84b3405bb9 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -886,20 +886,16 @@ sub Parse($$$$$) #include #include \"librpc/rpc/dcerpc.h\" #include \"scripting/python/pytalloc.h\" +#include \"scripting/python/pyrpc.h\" #include \"$hdr\" #include \"$ndr_hdr\" #include \"$py_hdr\" -#define PY_CHECK_TYPE(type, var, fail) \\ - if (!type ## _Check(var)) {\\ - PyErr_Format(PyExc_TypeError, \"Expected type %s\", type ## _Type.tp_name); \\ - fail; \\ - } "); foreach my $x (@$ndr) { - ($x->{TYPE} eq "INTERFACE") && $self->Interface($x, $basename); ($x->{TYPE} eq "IMPORT") && $self->Import(@{$x->{PATHS}}); + ($x->{TYPE} eq "INTERFACE") && $self->Interface($x, $basename); } $self->pidl("static PyMethodDef $basename\_methods[] = {"); diff --git a/source4/scripting/python/pyrpc.h b/source4/scripting/python/pyrpc.h index d7b64dbe93..5390c6923d 100644 --- a/source4/scripting/python/pyrpc.h +++ b/source4/scripting/python/pyrpc.h @@ -25,3 +25,5 @@ #define dom_sid2_Type dom_sid_Type #define dom_sid28_Type dom_sid_Type +#define dom_sid2_Check dom_sid_Check +#define dom_sid28_Check dom_sid28_Check -- cgit From 994e43e9ebd3922f2c3378edf0e73e912815230a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 18:01:54 +0100 Subject: python: Don't try to free const pointers. (This used to be commit b4754f4683e67a940f18a88e45c0878259f45b97) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 84b3405bb9..73442be59d 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -203,7 +203,11 @@ sub PythonStruct($$$$) $self->pidl("if (!strcmp(name, \"$e->{NAME}\")) {"); my $varname = "object->$e->{NAME}"; $self->indent; - if ($e->{ORIGINAL}->{POINTERS} > 0) { + my $l = $e->{LEVELS}[0]; + my $nl = GetNextLevel($e, $l); + if ($l->{TYPE} eq "POINTER" and + not ($nl->{TYPE} eq "ARRAY" and ($nl->{IS_FIXED} or is_charset_array($e, $nl))) and + not ($nl->{TYPE} eq "SCALAR" and $nl->{TYPE} eq "string")) { $self->pidl("talloc_free($varname);"); } $self->ConvertObjectFromPython($env, $mem_ctx, $e, "value", $varname, "return -1;"); -- cgit From 134e38ac28b30b7fb3f4efcf9985c17ff2f070ad Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 18:24:10 +0100 Subject: python: Fix some corner cases handling scalars. (This used to be commit b662c98a9ad461a33a27a918c0d544a96433e48c) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 73442be59d..8ff909a455 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -207,7 +207,7 @@ sub PythonStruct($$$$) my $nl = GetNextLevel($e, $l); if ($l->{TYPE} eq "POINTER" and not ($nl->{TYPE} eq "ARRAY" and ($nl->{IS_FIXED} or is_charset_array($e, $nl))) and - not ($nl->{TYPE} eq "SCALAR" and $nl->{TYPE} eq "string")) { + not ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE}))) { $self->pidl("talloc_free($varname);"); } $self->ConvertObjectFromPython($env, $mem_ctx, $e, "value", $varname, "return -1;"); @@ -668,8 +668,13 @@ sub ConvertObjectFromPythonData($$$$$$) sub ConvertObjectFromPythonLevel($$$$$$$$) { my ($self, $env, $mem_ctx, $py_var, $e, $l, $var_name, $fail) = @_; + my $nl = GetNextLevel($e, $l); if ($l->{TYPE} eq "POINTER") { + if ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) { + $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail); + return; + } if ($l->{POINTER_TYPE} ne "ref") { $self->pidl("if ($py_var == Py_None) {"); $self->indent; @@ -679,7 +684,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$) $self->indent; } $self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);"); - $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, GetNextLevel($e, $l), get_value_of($var_name), $fail); + $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, get_value_of($var_name), $fail); if ($l->{POINTER_TYPE} ne "ref") { $self->deindent; $self->pidl("}"); @@ -802,8 +807,13 @@ sub ConvertObjectToPythonData($$$$$) sub ConvertObjectToPythonLevel($$$$$) { my ($self, $mem_ctx, $env, $e, $l, $var_name, $py_var) = @_; + my $nl = GetNextLevel($e, $l); if ($l->{TYPE} eq "POINTER") { + if ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) { + $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, $var_name, $py_var); + return; + } if ($l->{POINTER_TYPE} ne "ref") { $self->pidl("if ($var_name == NULL) {"); $self->indent; @@ -812,7 +822,7 @@ sub ConvertObjectToPythonLevel($$$$$) $self->pidl("} else {"); $self->indent; } - $self->ConvertObjectToPythonLevel($var_name, $env, $e, GetNextLevel($e, $l), get_value_of($var_name), $py_var); + $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, get_value_of($var_name), $py_var); if ($l->{POINTER_TYPE} ne "ref") { $self->deindent; $self->pidl("}"); -- cgit From d28eb21a984a733e8f1de51170e41ae7c879f7e9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 18:59:11 +0100 Subject: python: Compile security module, handle uint. (This used to be commit dee64344fb13aaed38a550ebb4048d0fa526d5b6) --- source4/librpc/config.mk | 3 +++ source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 6 +++--- source4/pidl/lib/Parse/Pidl/Typelist.pm | 1 + source4/scripting/python/modules.c | 2 ++ 4 files changed, 9 insertions(+), 3 deletions(-) (limited to 'source4') diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 31013289dd..cda57bedcf 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -628,3 +628,6 @@ PRIVATE_DEPENDENCIES = dcerpc_samr [PYTHON::python_lsa] OBJ_FILES = gen_ndr/py_lsa.o PRIVATE_DEPENDENCIES = RPC_NDR_LSA + +[PYTHON::python_security] +OBJ_FILES = gen_ndr/py_security.o diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 8ff909a455..31b06d16b8 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -612,7 +612,7 @@ sub ConvertObjectFromPythonData($$$$$$) if ($actual_ctype->{TYPE} eq "ENUM" or $actual_ctype->{TYPE} eq "BITMAP" or $actual_ctype->{TYPE} eq "SCALAR" and ( - expandAlias($actual_ctype->{NAME}) =~ /^(u?int[0-9]+|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong|udlongr)$/)) { + expandAlias($actual_ctype->{NAME}) =~ /^(u?int[0-9]*|hyper|NTTIME|time_t|NTTIME_hyper|NTTIME_1sec|dlong|udlong|udlongr)$/)) { $self->pidl("PY_CHECK_TYPE(PyInt, $cvar, $fail);"); $self->pidl("$target = PyInt_AsLong($cvar);"); return; @@ -748,7 +748,7 @@ sub ConvertScalarToPython($$$) $ctypename = expandAlias($ctypename); - if ($ctypename =~ /^(int|long|char|u?int[0-9]+|hyper|dlong|udlong|udlongr|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/) { + if ($ctypename =~ /^(char|u?int[0-9]*|hyper|dlong|udlong|udlongr|time_t|NTTIME_hyper|NTTIME|NTTIME_1sec)$/) { return "PyInt_FromLong($cvar)"; } @@ -938,7 +938,7 @@ sub Parse($$$$$) } elsif ($cvar =~ /^".*"$/) { $py_obj = "PyString_FromString($cvar)"; } else { - $py_obj = $self->ConvertObjectToPythonData("NULL", $ctype, $cvar); + $py_obj = $self->ConvertObjectToPythonData("NULL", expandAlias($ctype), $cvar); } $self->pidl("PyModule_AddObject(m, \"$name\", $py_obj);"); diff --git a/source4/pidl/lib/Parse/Pidl/Typelist.pm b/source4/pidl/lib/Parse/Pidl/Typelist.pm index 9e6c683f82..8ba1ae47af 100644 --- a/source4/pidl/lib/Parse/Pidl/Typelist.pm +++ b/source4/pidl/lib/Parse/Pidl/Typelist.pm @@ -59,6 +59,7 @@ my %aliases = ( "boolean8" => "uint8", "boolean32" => "uint32", "DWORD" => "uint32", + "uint" => "uint32", "int" => "int32", "WORD" => "uint16", "char" => "uint8", diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 8c5115efca..1728f166bd 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -42,6 +42,8 @@ static void initdcerpc_misc(void) {} extern void initmgmt(void); extern void initatsvc(void); extern void initsamr(void); +extern void initsecurity(void); +extern void initlsa(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From 001b2435f0a47f75f82a32f2ccead2759596a09d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 19:05:08 +0100 Subject: python: Add simple test for samr python code. (This used to be commit 0a039fabcba9510ab600b2e4becbf75a58d2134d) --- source4/scripting/python/samba/tests/dcerpc/sam.py | 28 ++++++++++++++++++++++ source4/selftest/samba4_tests.sh | 1 + 2 files changed, 29 insertions(+) create mode 100644 source4/scripting/python/samba/tests/dcerpc/sam.py (limited to 'source4') diff --git a/source4/scripting/python/samba/tests/dcerpc/sam.py b/source4/scripting/python/samba/tests/dcerpc/sam.py new file mode 100644 index 0000000000..50caaf2348 --- /dev/null +++ b/source4/scripting/python/samba/tests/dcerpc/sam.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import samr +import unittest + +class SamrTests(unittest.TestCase): + def setUp(self): + self.conn = samr.samr("ncalrpc:", "st/client/client.conf") + + def test_connect5(self): + (level, info, handle) = self.conn.Connect5(None, 0, 1, samr.ConnectInfo1()) diff --git a/source4/selftest/samba4_tests.sh b/source4/selftest/samba4_tests.sh index fdf535e003..2068a971ca 100755 --- a/source4/selftest/samba4_tests.sh +++ b/source4/selftest/samba4_tests.sh @@ -320,6 +320,7 @@ then plantest "samba.python" none $SUBUNITRUN samba.tests plantest "provision.python" none $SUBUNITRUN samba.tests.provision plantest "samba3.python" none $SUBUNITRUN samba.tests.samba3 + plantest "samr.python" dc $SUBUNITRUN samba.tests.dcerpc.sam plantest "events.python" none PYTHONPATH="$PYTHONPATH:lib/events" $SUBUNITRUN tests plantest "samba3sam.python" none PYTHONPATH="$PYTHONPATH:dsdb/samdb/ldb_modules/tests" $SUBUNITRUN samba3sam plantest "rpcecho.python" dc $SUBUNITRUN samba.tests.dcerpc.rpcecho -- cgit From 2aa8cbca8baf1159544c2f3c0ce316da03035d71 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 19:49:52 +0100 Subject: python: Work around the fact that there are two "security" modules now. This well demonstrates the fact we need hierarchy. (This used to be commit df7e3498824e27f8a6d61b8b6f52577eab248d2c) --- source4/librpc/config.mk | 2 +- source4/scripting/python/modules.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index cda57bedcf..ddb07dc6e2 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -629,5 +629,5 @@ PRIVATE_DEPENDENCIES = dcerpc_samr OBJ_FILES = gen_ndr/py_lsa.o PRIVATE_DEPENDENCIES = RPC_NDR_LSA -[PYTHON::python_security] +[PYTHON::python_dcerpc_security] OBJ_FILES = gen_ndr/py_security.o diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 1728f166bd..c953e9866c 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -42,7 +42,7 @@ static void initdcerpc_misc(void) {} extern void initmgmt(void); extern void initatsvc(void); extern void initsamr(void); -extern void initsecurity(void); +static void initdcerpc_security(void) {} extern void initlsa(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From 2ebe80c27c8cd39a0f40ef6de3a9f805cb7d6bed Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 19:51:08 +0100 Subject: python: Convert winreg.py completely to rpc, use new RPC Python bindings. (This used to be commit 9c21773737ea941b623105352b4625dcb8437706) --- source4/scripting/bin/winreg.py | 133 ++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 72 deletions(-) mode change 100644 => 100755 source4/scripting/bin/winreg.py (limited to 'source4') diff --git a/source4/scripting/bin/winreg.py b/source4/scripting/bin/winreg.py old mode 100644 new mode 100755 index 6cdc3a5898..f68f2d12f2 --- a/source4/scripting/bin/winreg.py +++ b/source4/scripting/bin/winreg.py @@ -7,87 +7,76 @@ # import sys +import winreg +import optparse +import samba.getopt as options -options = GetOptions(ARGV, - "POPT_AUTOHELP", - "POPT_COMMON_SAMBA", - "POPT_COMMON_CREDENTIALS", - "createkey=s") -if (options == undefined) { - print "Failed to parse options" - sys.exit(-1) +parser = optparse.OptionParser("%s [path]" % sys.argv[0]) +parser.add_option_group(options.SambaOptions(parser)) +parser.add_option("--createkey", type="string", metavar="KEYNAME", + help="create a key") -if len(sys.argv < 2: - print "Usage: %s [path]" % sys.argv[0] - sys.exit(-1) +opts, args = parser.parse_args() -binding = options.ARGV[0] -reg = winregObj() +if len(args) < 1: + parser.print_usage() + sys.exit(-1) + +binding = args[0] print "Connecting to " + binding -status = reg.connect(binding) -if (status.is_ok != true) { - print("Failed to connect to " + binding + " - " + status.errstr + "\n") - return -1 -} +conn = winreg.winreg(binding, opts.configfile) -def list_values(path): - list = reg.enum_values(path) - if (list == undefined) { - return - } - for (i=0;i 2: - root = sys.argv[2] +if len(args) > 1: + root = args[1] else: - root = '' + root = "HKLM" -if options.createkey: - try: - reg.create_key("HKLM\\SOFTWARE", options.createkey) - except: - print "Failed to create key" +if opts.createkey: + reg.create_key("HKLM\\SOFTWARE", opt.createkey) else: - printf("Listing registry tree '%s'\n", root) - count = list_path(root) + print "Listing registry tree '%s'" % root + try: + root_key = getattr(conn, "Open%s" % root)(None, winreg.KEY_QUERY_VALUE | winreg.KEY_ENUMERATE_SUB_KEYS) + except AttributeError: + print "Unknown root key name %s" % root + sys.exit(1) + count = list_path(root_key, root) if count == 0: - println("No entries found") - sys.exit(1) + print "No entries found" + sys.exit(1) -- cgit From 506f6432882804ed62fd3b8c1ddc2a4ac80fa08d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 20:08:04 +0100 Subject: python: Compile in svcctl Python bindings. (This used to be commit 567099b66d0369715f8e0a083a5ce160faaf4da2) --- source4/librpc/config.mk | 4 ++++ source4/librpc/idl/svcctl.idl | 1 + source4/scripting/python/modules.c | 1 + 3 files changed, 6 insertions(+) (limited to 'source4') diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index ddb07dc6e2..78e90b464d 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -625,6 +625,10 @@ PRIVATE_DEPENDENCIES = dcerpc_atsvc OBJ_FILES = gen_ndr/py_samr.o PRIVATE_DEPENDENCIES = dcerpc_samr +[PYTHON::python_svcctl] +OBJ_FILES = gen_ndr/py_svcctl.o +PRIVATE_DEPENDENCIES = RPC_NDR_SVCCTL + [PYTHON::python_lsa] OBJ_FILES = gen_ndr/py_lsa.o PRIVATE_DEPENDENCIES = RPC_NDR_LSA diff --git a/source4/librpc/idl/svcctl.idl b/source4/librpc/idl/svcctl.idl index 2fbdb71e74..d9f8233a0e 100644 --- a/source4/librpc/idl/svcctl.idl +++ b/source4/librpc/idl/svcctl.idl @@ -4,6 +4,7 @@ svcctl interface definitions */ +import "misc.idl"; [ uuid("367abb81-9844-35f1-ad32-98f038001003"), version(2.0), pointer_default(unique), diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index c953e9866c..dc6e79fe1a 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -44,6 +44,7 @@ extern void initatsvc(void); extern void initsamr(void); static void initdcerpc_security(void) {} extern void initlsa(void); +extern void initsvcctl(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From 1530d7c3b0d02a2b75c1ee393209f69473f3c4af Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 20:09:18 +0100 Subject: python: Fix handling of pointer-less strings in function arguments. (This used to be commit cb2700094fc1fc3887d5254e5d42e035deefa5b9) --- source4/pidl/lib/Parse/Pidl/Samba4/Python.pm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4') diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm index 31b06d16b8..2475925377 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -642,12 +642,12 @@ sub ConvertObjectFromPythonData($$$$$$) if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") { - $self->pidl("$target = PyInt_AsLong($cvar);"); + $self->pidl("$target = NT_STATUS(PyInt_AsLong($cvar));"); return; } if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") { - $self->pidl("$target = PyInt_AsLong($cvar);"); + $self->pidl("$target = W_ERROR(PyInt_AsLong($cvar));"); return; } @@ -690,16 +690,16 @@ sub ConvertObjectFromPythonLevel($$$$$$$$) $self->pidl("}"); } } elsif ($l->{TYPE} eq "ARRAY") { + my $pl = GetPrevLevel($e, $l); + if ($pl && $pl->{TYPE} eq "POINTER") { + $var_name = get_pointer_to($var_name); + } + if (is_charset_array($e, $l)) { $self->pidl("PY_CHECK_TYPE(PyUnicode, $py_var, $fail);"); # FIXME: Use Unix charset setting rather than utf-8 - $self->pidl(get_pointer_to($var_name) . " = PyString_AsString(PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\"));"); + $self->pidl($var_name . " = PyString_AsString(PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\"));"); } else { - my $pl = GetPrevLevel($e, $l); - if ($pl && $pl->{TYPE} eq "POINTER") { - $var_name = get_pointer_to($var_name); - } - my $counter = "$e->{NAME}_cntr_$l->{LEVEL_INDEX}"; $self->pidl("PY_CHECK_TYPE(PyList, $py_var, $fail);"); $self->pidl("{"); -- cgit From d869de531c9f6b81c7eca43c3bfaab294c14cab1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 20:14:53 +0100 Subject: python: Enable building of the wkssvc python bindings. (This used to be commit 7a00d48a478be84e9f38c5e6cb57739063d0d613) --- source4/librpc/config.mk | 4 ++++ source4/scripting/bin/epdump.py | 24 ++++++++++++++++++++++++ source4/scripting/python/modules.c | 1 + 3 files changed, 29 insertions(+) create mode 100644 source4/scripting/bin/epdump.py (limited to 'source4') diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 78e90b464d..8774f2fd17 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -633,5 +633,9 @@ PRIVATE_DEPENDENCIES = RPC_NDR_SVCCTL OBJ_FILES = gen_ndr/py_lsa.o PRIVATE_DEPENDENCIES = RPC_NDR_LSA +[PYTHON::python_wkssvc] +OBJ_FILES = gen_ndr/py_wkssvc.o +PRIVATE_DEPENDENCIES = RPC_NDR_WKSSVC + [PYTHON::python_dcerpc_security] OBJ_FILES = gen_ndr/py_security.o diff --git a/source4/scripting/bin/epdump.py b/source4/scripting/bin/epdump.py new file mode 100644 index 0000000000..15dee33774 --- /dev/null +++ b/source4/scripting/bin/epdump.py @@ -0,0 +1,24 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import sys + +if len(sys.argv) < 2: + print "Usage: %s " % sys.argv[0] + sys.exit(1) diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index dc6e79fe1a..b2dd50b507 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -45,6 +45,7 @@ extern void initsamr(void); static void initdcerpc_security(void) {} extern void initlsa(void); extern void initsvcctl(void); +extern void initwkssvc(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From 2e02bb5289b78aab2158d56fd187ef1addd0c8de Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 22:24:07 +0100 Subject: libreplace: Escape asterisk. (This used to be commit df36c78549b40ee5e47d5cc79de2eb79f58c567a) --- source4/lib/replace/libreplace_ld.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/lib/replace/libreplace_ld.m4 b/source4/lib/replace/libreplace_ld.m4 index 0ca6f7a34d..2aec698967 100644 --- a/source4/lib/replace/libreplace_ld.m4 +++ b/source4/lib/replace/libreplace_ld.m4 @@ -265,7 +265,7 @@ AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_ALLOW_UNDEF_FLAG], LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,--allow-shlib-undefined" ;; *osf*) - LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-expect_unresolved,*" + LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-expect_unresolved,\"*\"" ;; *darwin*) LD_SHLIB_ALLOW_UNDEF_FLAG="-undefined dynamic_lookup" -- cgit From 939edd0eb7c3952859afb802c8e542449a2c4031 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Jan 2008 01:04:38 +0100 Subject: util: Move asn1 to lib/util to trim down the number of subsystems. (This used to be commit 44e1cfd2d0ef62e4ee541cec00581a7151d951b3) --- source4/auth/gensec/spnego_parse.c | 2 +- source4/auth/kerberos/gssapi_parse.c | 2 +- source4/ldap_server/ldap_server.c | 2 +- source4/lib/util/asn1.c | 770 +++++++++++++++++++++++++++++++++++ source4/lib/util/asn1.h | 54 +++ source4/lib/util/config.mk | 5 + source4/libcli/cldap/cldap.h | 2 +- source4/libcli/config.mk | 5 - source4/libcli/ldap/ldap.c | 2 +- source4/libcli/ldap/ldap_client.c | 2 +- source4/libcli/ldap/ldap_controls.c | 2 +- source4/libcli/util/asn1.c | 770 ----------------------------------- source4/libcli/util/asn_1.h | 54 --- source4/librpc/ndr/ndr_drsuapi.c | 2 +- 14 files changed, 837 insertions(+), 837 deletions(-) create mode 100644 source4/lib/util/asn1.c create mode 100644 source4/lib/util/asn1.h delete mode 100644 source4/libcli/util/asn1.c delete mode 100644 source4/libcli/util/asn_1.h (limited to 'source4') diff --git a/source4/auth/gensec/spnego_parse.c b/source4/auth/gensec/spnego_parse.c index 37f4f12278..8012a83ba8 100644 --- a/source4/auth/gensec/spnego_parse.c +++ b/source4/auth/gensec/spnego_parse.c @@ -23,7 +23,7 @@ #include "includes.h" #include "auth/gensec/spnego.h" #include "auth/gensec/gensec.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, struct spnego_negTokenInit *token) diff --git a/source4/auth/kerberos/gssapi_parse.c b/source4/auth/kerberos/gssapi_parse.c index 4b1b178238..77e907d3fa 100644 --- a/source4/auth/kerberos/gssapi_parse.c +++ b/source4/auth/kerberos/gssapi_parse.c @@ -22,7 +22,7 @@ */ #include "includes.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "auth/gensec/gensec.h" /* diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index fcc9435ead..8380775c28 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -27,7 +27,7 @@ #include "auth/credentials/credentials.h" #include "librpc/gen_ndr/ndr_samr.h" #include "lib/util/dlinklist.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "ldap_server/ldap_server.h" #include "smbd/service_task.h" #include "smbd/service_stream.h" diff --git a/source4/lib/util/asn1.c b/source4/lib/util/asn1.c new file mode 100644 index 0000000000..4756c0640d --- /dev/null +++ b/source4/lib/util/asn1.c @@ -0,0 +1,770 @@ +/* + Unix SMB/CIFS implementation. + simple ASN1 routines + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "lib/util/asn1.h" + +/* allocate an asn1 structure */ +struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx) +{ + struct asn1_data *ret = talloc_zero(mem_ctx, struct asn1_data); + if (ret == NULL) { + DEBUG(0,("asn1_init failed! out of memory\n")); + } + return ret; +} + +/* free an asn1 structure */ +void asn1_free(struct asn1_data *data) +{ + talloc_free(data); +} + +/* write to the ASN1 buffer, advancing the buffer pointer */ +bool asn1_write(struct asn1_data *data, const void *p, int len) +{ + if (data->has_error) return false; + if (data->length < data->ofs+len) { + uint8_t *newp; + newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len); + if (!newp) { + asn1_free(data); + data->has_error = true; + return false; + } + data->data = newp; + data->length = data->ofs+len; + } + memcpy(data->data + data->ofs, p, len); + data->ofs += len; + return true; +} + +/* useful fn for writing a uint8_t */ +bool asn1_write_uint8(struct asn1_data *data, uint8_t v) +{ + return asn1_write(data, &v, 1); +} + +/* push a tag onto the asn1 data buffer. Used for nested structures */ +bool asn1_push_tag(struct asn1_data *data, uint8_t tag) +{ + struct nesting *nesting; + + asn1_write_uint8(data, tag); + nesting = talloc(data, struct nesting); + if (!nesting) { + data->has_error = true; + return false; + } + + nesting->start = data->ofs; + nesting->next = data->nesting; + data->nesting = nesting; + return asn1_write_uint8(data, 0xff); +} + +/* pop a tag */ +bool asn1_pop_tag(struct asn1_data *data) +{ + struct nesting *nesting; + size_t len; + + nesting = data->nesting; + + if (!nesting) { + data->has_error = true; + return false; + } + len = data->ofs - (nesting->start+1); + /* yes, this is ugly. We don't know in advance how many bytes the length + of a tag will take, so we assumed 1 byte. If we were wrong then we + need to correct our mistake */ + if (len > 0xFFFFFF) { + data->data[nesting->start] = 0x84; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; + memmove(data->data+nesting->start+5, data->data+nesting->start+1, len); + data->data[nesting->start+1] = (len>>24) & 0xFF; + data->data[nesting->start+2] = (len>>16) & 0xFF; + data->data[nesting->start+3] = (len>>8) & 0xFF; + data->data[nesting->start+4] = len&0xff; + } else if (len > 0xFFFF) { + data->data[nesting->start] = 0x83; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; + memmove(data->data+nesting->start+4, data->data+nesting->start+1, len); + data->data[nesting->start+1] = (len>>16) & 0xFF; + data->data[nesting->start+2] = (len>>8) & 0xFF; + data->data[nesting->start+3] = len&0xff; + } else if (len > 255) { + data->data[nesting->start] = 0x82; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; + memmove(data->data+nesting->start+3, data->data+nesting->start+1, len); + data->data[nesting->start+1] = len>>8; + data->data[nesting->start+2] = len&0xff; + } else if (len > 127) { + data->data[nesting->start] = 0x81; + if (!asn1_write_uint8(data, 0)) return false; + memmove(data->data+nesting->start+2, data->data+nesting->start+1, len); + data->data[nesting->start+1] = len; + } else { + data->data[nesting->start] = len; + } + + data->nesting = nesting->next; + talloc_free(nesting); + return true; +} + +/* "i" is the one's complement representation, as is the normal result of an + * implicit signed->unsigned conversion */ + +static bool push_int_bigendian(struct asn1_data *data, unsigned int i, bool negative) +{ + uint8_t lowest = i & 0xFF; + + i = i >> 8; + if (i != 0) + if (!push_int_bigendian(data, i, negative)) + return false; + + if (data->nesting->start+1 == data->ofs) { + + /* We did not write anything yet, looking at the highest + * valued byte */ + + if (negative) { + /* Don't write leading 0xff's */ + if (lowest == 0xFF) + return true; + + if ((lowest & 0x80) == 0) { + /* The only exception for a leading 0xff is if + * the highest bit is 0, which would indicate + * a positive value */ + if (!asn1_write_uint8(data, 0xff)) + return false; + } + } else { + if (lowest & 0x80) { + /* The highest bit of a positive integer is 1, + * this would indicate a negative number. Push + * a 0 to indicate a positive one */ + if (!asn1_write_uint8(data, 0)) + return false; + } + } + } + + return asn1_write_uint8(data, lowest); +} + +/* write an Integer without the tag framing. Needed for example for the LDAP + * Abandon Operation */ + +bool asn1_write_implicit_Integer(struct asn1_data *data, int i) +{ + if (i == -1) { + /* -1 is special as it consists of all-0xff bytes. In + push_int_bigendian this is the only case that is not + properly handled, as all 0xff bytes would be handled as + leading ones to be ignored. */ + return asn1_write_uint8(data, 0xff); + } else { + return push_int_bigendian(data, i, i<0); + } +} + + +/* write an integer */ +bool asn1_write_Integer(struct asn1_data *data, int i) +{ + if (!asn1_push_tag(data, ASN1_INTEGER)) return false; + if (!asn1_write_implicit_Integer(data, i)) return false; + return asn1_pop_tag(data); +} + +bool ber_write_OID_String(DATA_BLOB *blob, const char *OID) +{ + uint_t v, v2; + const char *p = (const char *)OID; + char *newp; + int i; + + v = strtoul(p, &newp, 10); + if (newp[0] != '.') return false; + p = newp + 1; + + v2 = strtoul(p, &newp, 10); + if (newp[0] != '.') return false; + p = newp + 1; + + /*the ber representation can't use more space then the string one */ + *blob = data_blob(NULL, strlen(OID)); + if (!blob->data) return false; + + blob->data[0] = 40*v + v2; + + i = 1; + while (*p) { + v = strtoul(p, &newp, 10); + if (newp[0] == '.') { + p = newp + 1; + } else if (newp[0] == '\0') { + p = newp; + } else { + data_blob_free(blob); + return false; + } + if (v >= (1<<28)) blob->data[i++] = (0x80 | ((v>>28)&0x7f)); + if (v >= (1<<21)) blob->data[i++] = (0x80 | ((v>>21)&0x7f)); + if (v >= (1<<14)) blob->data[i++] = (0x80 | ((v>>14)&0x7f)); + if (v >= (1<<7)) blob->data[i++] = (0x80 | ((v>>7)&0x7f)); + blob->data[i++] = (v&0x7f); + } + + blob->length = i; + + return true; +} + +/* write an object ID to a ASN1 buffer */ +bool asn1_write_OID(struct asn1_data *data, const char *OID) +{ + DATA_BLOB blob; + + if (!asn1_push_tag(data, ASN1_OID)) return false; + + if (!ber_write_OID_String(&blob, OID)) { + data->has_error = true; + return false; + } + + if (!asn1_write(data, blob.data, blob.length)) { + data->has_error = true; + return false; + } + data_blob_free(&blob); + return asn1_pop_tag(data); +} + +/* write an octet string */ +bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length) +{ + asn1_push_tag(data, ASN1_OCTET_STRING); + asn1_write(data, p, length); + asn1_pop_tag(data); + return !data->has_error; +} + +/* write a LDAP string */ +bool asn1_write_LDAPString(struct asn1_data *data, const char *s) +{ + asn1_write(data, s, strlen(s)); + return !data->has_error; +} + +/* write a LDAP string from a DATA_BLOB */ +bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s) +{ + asn1_write(data, s->data, s->length); + return !data->has_error; +} + +/* write a general string */ +bool asn1_write_GeneralString(struct asn1_data *data, const char *s) +{ + asn1_push_tag(data, ASN1_GENERAL_STRING); + asn1_write_LDAPString(data, s); + asn1_pop_tag(data); + return !data->has_error; +} + +bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) +{ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num)); + asn1_write(data, blob->data, blob->length); + asn1_pop_tag(data); + return !data->has_error; +} + +/* write a BOOLEAN */ +bool asn1_write_BOOLEAN(struct asn1_data *data, bool v) +{ + asn1_push_tag(data, ASN1_BOOLEAN); + asn1_write_uint8(data, v ? 0xFF : 0); + asn1_pop_tag(data); + return !data->has_error; +} + +bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v) +{ + uint8_t tmp = 0; + asn1_start_tag(data, ASN1_BOOLEAN); + asn1_read_uint8(data, &tmp); + if (tmp == 0xFF) { + *v = true; + } else { + *v = false; + } + asn1_end_tag(data); + return !data->has_error; +} + +/* check a BOOLEAN */ +bool asn1_check_BOOLEAN(struct asn1_data *data, bool v) +{ + uint8_t b = 0; + + asn1_read_uint8(data, &b); + if (b != ASN1_BOOLEAN) { + data->has_error = true; + return false; + } + asn1_read_uint8(data, &b); + if (b != v) { + data->has_error = true; + return false; + } + return !data->has_error; +} + + +/* load a struct asn1_data structure with a lump of data, ready to be parsed */ +bool asn1_load(struct asn1_data *data, DATA_BLOB blob) +{ + ZERO_STRUCTP(data); + data->data = talloc_memdup(data, blob.data, blob.length); + if (!data->data) { + data->has_error = true; + return false; + } + data->length = blob.length; + return true; +} + +/* Peek into an ASN1 buffer, not advancing the pointer */ +bool asn1_peek(struct asn1_data *data, void *p, int len) +{ + if (data->has_error) + return false; + + if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) + return false; + + if (data->ofs + len > data->length) { + /* we need to mark the buffer as consumed, so the caller knows + this was an out of data error, and not a decode error */ + data->ofs = data->length; + return false; + } + + memcpy(p, data->data + data->ofs, len); + return true; +} + +/* read from a ASN1 buffer, advancing the buffer pointer */ +bool asn1_read(struct asn1_data *data, void *p, int len) +{ + if (!asn1_peek(data, p, len)) { + data->has_error = true; + return false; + } + + data->ofs += len; + return true; +} + +/* read a uint8_t from a ASN1 buffer */ +bool asn1_read_uint8(struct asn1_data *data, uint8_t *v) +{ + return asn1_read(data, v, 1); +} + +bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v) +{ + return asn1_peek(data, v, 1); +} + +bool asn1_peek_tag(struct asn1_data *data, uint8_t tag) +{ + uint8_t b; + + if (asn1_tag_remaining(data) <= 0) { + return false; + } + + if (!asn1_peek_uint8(data, &b)) + return false; + + return (b == tag); +} + +/* start reading a nested asn1 structure */ +bool asn1_start_tag(struct asn1_data *data, uint8_t tag) +{ + uint8_t b; + struct nesting *nesting; + + if (!asn1_read_uint8(data, &b)) + return false; + + if (b != tag) { + data->has_error = true; + return false; + } + nesting = talloc(data, struct nesting); + if (!nesting) { + data->has_error = true; + return false; + } + + if (!asn1_read_uint8(data, &b)) { + return false; + } + + if (b & 0x80) { + int n = b & 0x7f; + if (!asn1_read_uint8(data, &b)) + return false; + nesting->taglen = b; + while (n > 1) { + if (!asn1_read_uint8(data, &b)) + return false; + nesting->taglen = (nesting->taglen << 8) | b; + n--; + } + } else { + nesting->taglen = b; + } + nesting->start = data->ofs; + nesting->next = data->nesting; + data->nesting = nesting; + if (asn1_tag_remaining(data) == -1) { + return false; + } + return !data->has_error; +} + +/* stop reading a tag */ +bool asn1_end_tag(struct asn1_data *data) +{ + struct nesting *nesting; + + /* make sure we read it all */ + if (asn1_tag_remaining(data) != 0) { + data->has_error = true; + return false; + } + + nesting = data->nesting; + + if (!nesting) { + data->has_error = true; + return false; + } + + data->nesting = nesting->next; + talloc_free(nesting); + return true; +} + +/* work out how many bytes are left in this nested tag */ +int asn1_tag_remaining(struct asn1_data *data) +{ + int remaining; + if (data->has_error) { + return -1; + } + + if (!data->nesting) { + data->has_error = true; + return -1; + } + remaining = data->nesting->taglen - (data->ofs - data->nesting->start); + if (remaining > (data->length - data->ofs)) { + data->has_error = true; + return -1; + } + return remaining; +} + +/* read an object ID from a data blob */ +bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID) +{ + int i; + uint8_t *b; + uint_t v; + char *tmp_oid = NULL; + + if (blob.length < 2) return false; + + b = blob.data; + + tmp_oid = talloc_asprintf(mem_ctx, "%u", b[0]/40); + if (!tmp_oid) goto nomem; + tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", b[0]%40); + if (!tmp_oid) goto nomem; + + for(i = 1, v = 0; i < blob.length; i++) { + v = (v<<7) | (b[i]&0x7f); + if ( ! (b[i] & 0x80)) { + tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", v); + v = 0; + } + if (!tmp_oid) goto nomem; + } + + if (v != 0) { + talloc_free(tmp_oid); + return false; + } + + *OID = tmp_oid; + return true; + +nomem: + return false; +} + +/* read an object ID from a ASN1 buffer */ +bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, const char **OID) +{ + DATA_BLOB blob; + int len; + + if (!asn1_start_tag(data, ASN1_OID)) return false; + + len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = true; + return false; + } + + blob = data_blob(NULL, len); + if (!blob.data) { + data->has_error = true; + return false; + } + + asn1_read(data, blob.data, len); + asn1_end_tag(data); + if (data->has_error) { + data_blob_free(&blob); + return false; + } + + if (!ber_read_OID_String(mem_ctx, blob, OID)) { + data->has_error = true; + data_blob_free(&blob); + return false; + } + + data_blob_free(&blob); + return true; +} + +/* check that the next object ID is correct */ +bool asn1_check_OID(struct asn1_data *data, const char *OID) +{ + const char *id; + + if (!asn1_read_OID(data, data, &id)) return false; + + if (strcmp(id, OID) != 0) { + talloc_free(discard_const(id)); + data->has_error = true; + return false; + } + talloc_free(discard_const(id)); + return true; +} + +/* read a LDAPString from a ASN1 buffer */ +bool asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) +{ + int len; + len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = true; + return false; + } + *s = talloc_array(mem_ctx, char, len+1); + if (! *s) { + data->has_error = true; + return false; + } + asn1_read(data, *s, len); + (*s)[len] = 0; + return !data->has_error; +} + + +/* read a GeneralString from a ASN1 buffer */ +bool asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) +{ + if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return false; + if (!asn1_read_LDAPString(data, mem_ctx, s)) return false; + return asn1_end_tag(data); +} + + +/* read a octet string blob */ +bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob) +{ + int len; + ZERO_STRUCTP(blob); + if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return false; + len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = true; + return false; + } + *blob = data_blob_talloc(mem_ctx, NULL, len+1); + if (!blob->data) { + data->has_error = true; + return false; + } + asn1_read(data, blob->data, len); + asn1_end_tag(data); + blob->length--; + blob->data[len] = 0; + + if (data->has_error) { + data_blob_free(blob); + *blob = data_blob(NULL, 0); + return false; + } + return true; +} + +bool asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) +{ + int len; + ZERO_STRUCTP(blob); + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false; + len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = true; + return false; + } + *blob = data_blob(NULL, len); + if ((len != 0) && (!blob->data)) { + data->has_error = true; + return false; + } + asn1_read(data, blob->data, len); + asn1_end_tag(data); + return !data->has_error; +} + +/* read an integer without tag*/ +bool asn1_read_implicit_Integer(struct asn1_data *data, int *i) +{ + uint8_t b; + *i = 0; + + while (!data->has_error && asn1_tag_remaining(data)>0) { + if (!asn1_read_uint8(data, &b)) return false; + *i = (*i << 8) + b; + } + return !data->has_error; + +} + +/* read an integer */ +bool asn1_read_Integer(struct asn1_data *data, int *i) +{ + *i = 0; + + if (!asn1_start_tag(data, ASN1_INTEGER)) return false; + if (!asn1_read_implicit_Integer(data, i)) return false; + return asn1_end_tag(data); +} + +/* read an integer */ +bool asn1_read_enumerated(struct asn1_data *data, int *v) +{ + *v = 0; + + if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false; + while (!data->has_error && asn1_tag_remaining(data)>0) { + uint8_t b; + asn1_read_uint8(data, &b); + *v = (*v << 8) + b; + } + return asn1_end_tag(data); +} + +/* check a enumerated value is correct */ +bool asn1_check_enumerated(struct asn1_data *data, int v) +{ + uint8_t b; + if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false; + asn1_read_uint8(data, &b); + asn1_end_tag(data); + + if (v != b) + data->has_error = false; + + return !data->has_error; +} + +/* write an enumerated value to the stream */ +bool asn1_write_enumerated(struct asn1_data *data, uint8_t v) +{ + if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false; + asn1_write_uint8(data, v); + asn1_pop_tag(data); + return !data->has_error; +} + +/* + check if a ASN.1 blob is a full tag +*/ +NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) +{ + struct asn1_data *asn1 = asn1_init(NULL); + int size; + + NT_STATUS_HAVE_NO_MEMORY(asn1); + + asn1->data = blob.data; + asn1->length = blob.length; + asn1_start_tag(asn1, tag); + if (asn1->has_error) { + talloc_free(asn1); + return STATUS_MORE_ENTRIES; + } + size = asn1_tag_remaining(asn1) + asn1->ofs; + + talloc_free(asn1); + + if (size > blob.length) { + return STATUS_MORE_ENTRIES; + } + + *packet_size = size; + return NT_STATUS_OK; +} diff --git a/source4/lib/util/asn1.h b/source4/lib/util/asn1.h new file mode 100644 index 0000000000..34aa1e2cb9 --- /dev/null +++ b/source4/lib/util/asn1.h @@ -0,0 +1,54 @@ +/* + Unix SMB/CIFS implementation. + simple ASN1 code + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _ASN_1_H +#define _ASN_1_H + +struct nesting { + off_t start; + size_t taglen; /* for parsing */ + struct nesting *next; +}; + +struct asn1_data { + uint8_t *data; + size_t length; + off_t ofs; + struct nesting *nesting; + bool has_error; +}; + +#define ASN1_APPLICATION(x) ((x)+0x60) +#define ASN1_APPLICATION_SIMPLE(x) ((x)+0x40) +#define ASN1_SEQUENCE(x) ((x)+0x30) +#define ASN1_CONTEXT(x) ((x)+0xa0) +#define ASN1_CONTEXT_SIMPLE(x) ((x)+0x80) +#define ASN1_GENERAL_STRING 0x1b +#define ASN1_OCTET_STRING 0x4 +#define ASN1_OID 0x6 +#define ASN1_BOOLEAN 0x1 +#define ASN1_INTEGER 0x2 +#define ASN1_ENUMERATED 0xa +#define ASN1_SET 0x31 + +#define ASN1_MAX_OIDS 20 + +#include "lib/util/asn1_proto.h" + +#endif /* _ASN_1_H */ diff --git a/source4/lib/util/config.mk b/source4/lib/util/config.mk index 01ad14aa95..53a55bf7af 100644 --- a/source4/lib/util/config.mk +++ b/source4/lib/util/config.mk @@ -34,6 +34,11 @@ PUBLIC_DEPENDENCIES = \ SOCKET_WRAPPER EXT_NSL \ CHARSET EXECINFO +[SUBSYSTEM::ASN1_UTIL] +PUBLIC_PROTO_HEADER = asn1_proto.h +PUBLIC_HEADERS = asn1.h +OBJ_FILES = asn1.o + [SUBSYSTEM::UNIX_PRIVS] PRIVATE_PROTO_HEADER = unix_privs.h OBJ_FILES = unix_privs.o diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 8aa98f0331..7a222e0652 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -19,7 +19,7 @@ along with this program. If not, see . */ -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "librpc/gen_ndr/nbt.h" struct ldap_message; diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index adb51c6c9a..eb3c56cf7f 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -8,11 +8,6 @@ OBJ_FILES = util/doserr.o \ util/errormap.o \ util/nterr.o \ -[SUBSYSTEM::ASN1_UTIL] -PUBLIC_PROTO_HEADER = util/asn1_proto.h -PUBLIC_HEADERS = util/asn_1.h -OBJ_FILES = util/asn1.o - [SUBSYSTEM::LIBCLI_LSA] PRIVATE_PROTO_HEADER = util/clilsa.h OBJ_FILES = util/clilsa.o diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 586f2fa653..00a0631753 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -23,7 +23,7 @@ */ #include "includes.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "libcli/ldap/ldap.h" diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 6b8a7a3f28..d99851ee15 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -23,7 +23,7 @@ */ #include "includes.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "lib/util/dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 34e5cccf75..3b94580033 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "libcli/ldap/ldap.h" #include "lib/ldb/include/ldb.h" diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c deleted file mode 100644 index aad55382d9..0000000000 --- a/source4/libcli/util/asn1.c +++ /dev/null @@ -1,770 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple ASN1 routines - Copyright (C) Andrew Tridgell 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "libcli/util/asn_1.h" - -/* allocate an asn1 structure */ -struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx) -{ - struct asn1_data *ret = talloc_zero(mem_ctx, struct asn1_data); - if (ret == NULL) { - DEBUG(0,("asn1_init failed! out of memory\n")); - } - return ret; -} - -/* free an asn1 structure */ -void asn1_free(struct asn1_data *data) -{ - talloc_free(data); -} - -/* write to the ASN1 buffer, advancing the buffer pointer */ -bool asn1_write(struct asn1_data *data, const void *p, int len) -{ - if (data->has_error) return false; - if (data->length < data->ofs+len) { - uint8_t *newp; - newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len); - if (!newp) { - asn1_free(data); - data->has_error = true; - return false; - } - data->data = newp; - data->length = data->ofs+len; - } - memcpy(data->data + data->ofs, p, len); - data->ofs += len; - return true; -} - -/* useful fn for writing a uint8_t */ -bool asn1_write_uint8(struct asn1_data *data, uint8_t v) -{ - return asn1_write(data, &v, 1); -} - -/* push a tag onto the asn1 data buffer. Used for nested structures */ -bool asn1_push_tag(struct asn1_data *data, uint8_t tag) -{ - struct nesting *nesting; - - asn1_write_uint8(data, tag); - nesting = talloc(data, struct nesting); - if (!nesting) { - data->has_error = true; - return false; - } - - nesting->start = data->ofs; - nesting->next = data->nesting; - data->nesting = nesting; - return asn1_write_uint8(data, 0xff); -} - -/* pop a tag */ -bool asn1_pop_tag(struct asn1_data *data) -{ - struct nesting *nesting; - size_t len; - - nesting = data->nesting; - - if (!nesting) { - data->has_error = true; - return false; - } - len = data->ofs - (nesting->start+1); - /* yes, this is ugly. We don't know in advance how many bytes the length - of a tag will take, so we assumed 1 byte. If we were wrong then we - need to correct our mistake */ - if (len > 0xFFFFFF) { - data->data[nesting->start] = 0x84; - if (!asn1_write_uint8(data, 0)) return false; - if (!asn1_write_uint8(data, 0)) return false; - if (!asn1_write_uint8(data, 0)) return false; - if (!asn1_write_uint8(data, 0)) return false; - memmove(data->data+nesting->start+5, data->data+nesting->start+1, len); - data->data[nesting->start+1] = (len>>24) & 0xFF; - data->data[nesting->start+2] = (len>>16) & 0xFF; - data->data[nesting->start+3] = (len>>8) & 0xFF; - data->data[nesting->start+4] = len&0xff; - } else if (len > 0xFFFF) { - data->data[nesting->start] = 0x83; - if (!asn1_write_uint8(data, 0)) return false; - if (!asn1_write_uint8(data, 0)) return false; - if (!asn1_write_uint8(data, 0)) return false; - memmove(data->data+nesting->start+4, data->data+nesting->start+1, len); - data->data[nesting->start+1] = (len>>16) & 0xFF; - data->data[nesting->start+2] = (len>>8) & 0xFF; - data->data[nesting->start+3] = len&0xff; - } else if (len > 255) { - data->data[nesting->start] = 0x82; - if (!asn1_write_uint8(data, 0)) return false; - if (!asn1_write_uint8(data, 0)) return false; - memmove(data->data+nesting->start+3, data->data+nesting->start+1, len); - data->data[nesting->start+1] = len>>8; - data->data[nesting->start+2] = len&0xff; - } else if (len > 127) { - data->data[nesting->start] = 0x81; - if (!asn1_write_uint8(data, 0)) return false; - memmove(data->data+nesting->start+2, data->data+nesting->start+1, len); - data->data[nesting->start+1] = len; - } else { - data->data[nesting->start] = len; - } - - data->nesting = nesting->next; - talloc_free(nesting); - return true; -} - -/* "i" is the one's complement representation, as is the normal result of an - * implicit signed->unsigned conversion */ - -static bool push_int_bigendian(struct asn1_data *data, unsigned int i, bool negative) -{ - uint8_t lowest = i & 0xFF; - - i = i >> 8; - if (i != 0) - if (!push_int_bigendian(data, i, negative)) - return false; - - if (data->nesting->start+1 == data->ofs) { - - /* We did not write anything yet, looking at the highest - * valued byte */ - - if (negative) { - /* Don't write leading 0xff's */ - if (lowest == 0xFF) - return true; - - if ((lowest & 0x80) == 0) { - /* The only exception for a leading 0xff is if - * the highest bit is 0, which would indicate - * a positive value */ - if (!asn1_write_uint8(data, 0xff)) - return false; - } - } else { - if (lowest & 0x80) { - /* The highest bit of a positive integer is 1, - * this would indicate a negative number. Push - * a 0 to indicate a positive one */ - if (!asn1_write_uint8(data, 0)) - return false; - } - } - } - - return asn1_write_uint8(data, lowest); -} - -/* write an Integer without the tag framing. Needed for example for the LDAP - * Abandon Operation */ - -bool asn1_write_implicit_Integer(struct asn1_data *data, int i) -{ - if (i == -1) { - /* -1 is special as it consists of all-0xff bytes. In - push_int_bigendian this is the only case that is not - properly handled, as all 0xff bytes would be handled as - leading ones to be ignored. */ - return asn1_write_uint8(data, 0xff); - } else { - return push_int_bigendian(data, i, i<0); - } -} - - -/* write an integer */ -bool asn1_write_Integer(struct asn1_data *data, int i) -{ - if (!asn1_push_tag(data, ASN1_INTEGER)) return false; - if (!asn1_write_implicit_Integer(data, i)) return false; - return asn1_pop_tag(data); -} - -bool ber_write_OID_String(DATA_BLOB *blob, const char *OID) -{ - uint_t v, v2; - const char *p = (const char *)OID; - char *newp; - int i; - - v = strtoul(p, &newp, 10); - if (newp[0] != '.') return false; - p = newp + 1; - - v2 = strtoul(p, &newp, 10); - if (newp[0] != '.') return false; - p = newp + 1; - - /*the ber representation can't use more space then the string one */ - *blob = data_blob(NULL, strlen(OID)); - if (!blob->data) return false; - - blob->data[0] = 40*v + v2; - - i = 1; - while (*p) { - v = strtoul(p, &newp, 10); - if (newp[0] == '.') { - p = newp + 1; - } else if (newp[0] == '\0') { - p = newp; - } else { - data_blob_free(blob); - return false; - } - if (v >= (1<<28)) blob->data[i++] = (0x80 | ((v>>28)&0x7f)); - if (v >= (1<<21)) blob->data[i++] = (0x80 | ((v>>21)&0x7f)); - if (v >= (1<<14)) blob->data[i++] = (0x80 | ((v>>14)&0x7f)); - if (v >= (1<<7)) blob->data[i++] = (0x80 | ((v>>7)&0x7f)); - blob->data[i++] = (v&0x7f); - } - - blob->length = i; - - return true; -} - -/* write an object ID to a ASN1 buffer */ -bool asn1_write_OID(struct asn1_data *data, const char *OID) -{ - DATA_BLOB blob; - - if (!asn1_push_tag(data, ASN1_OID)) return false; - - if (!ber_write_OID_String(&blob, OID)) { - data->has_error = true; - return false; - } - - if (!asn1_write(data, blob.data, blob.length)) { - data->has_error = true; - return false; - } - data_blob_free(&blob); - return asn1_pop_tag(data); -} - -/* write an octet string */ -bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length) -{ - asn1_push_tag(data, ASN1_OCTET_STRING); - asn1_write(data, p, length); - asn1_pop_tag(data); - return !data->has_error; -} - -/* write a LDAP string */ -bool asn1_write_LDAPString(struct asn1_data *data, const char *s) -{ - asn1_write(data, s, strlen(s)); - return !data->has_error; -} - -/* write a LDAP string from a DATA_BLOB */ -bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s) -{ - asn1_write(data, s->data, s->length); - return !data->has_error; -} - -/* write a general string */ -bool asn1_write_GeneralString(struct asn1_data *data, const char *s) -{ - asn1_push_tag(data, ASN1_GENERAL_STRING); - asn1_write_LDAPString(data, s); - asn1_pop_tag(data); - return !data->has_error; -} - -bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) -{ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num)); - asn1_write(data, blob->data, blob->length); - asn1_pop_tag(data); - return !data->has_error; -} - -/* write a BOOLEAN */ -bool asn1_write_BOOLEAN(struct asn1_data *data, bool v) -{ - asn1_push_tag(data, ASN1_BOOLEAN); - asn1_write_uint8(data, v ? 0xFF : 0); - asn1_pop_tag(data); - return !data->has_error; -} - -bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v) -{ - uint8_t tmp = 0; - asn1_start_tag(data, ASN1_BOOLEAN); - asn1_read_uint8(data, &tmp); - if (tmp == 0xFF) { - *v = true; - } else { - *v = false; - } - asn1_end_tag(data); - return !data->has_error; -} - -/* check a BOOLEAN */ -bool asn1_check_BOOLEAN(struct asn1_data *data, bool v) -{ - uint8_t b = 0; - - asn1_read_uint8(data, &b); - if (b != ASN1_BOOLEAN) { - data->has_error = true; - return false; - } - asn1_read_uint8(data, &b); - if (b != v) { - data->has_error = true; - return false; - } - return !data->has_error; -} - - -/* load a struct asn1_data structure with a lump of data, ready to be parsed */ -bool asn1_load(struct asn1_data *data, DATA_BLOB blob) -{ - ZERO_STRUCTP(data); - data->data = talloc_memdup(data, blob.data, blob.length); - if (!data->data) { - data->has_error = true; - return false; - } - data->length = blob.length; - return true; -} - -/* Peek into an ASN1 buffer, not advancing the pointer */ -bool asn1_peek(struct asn1_data *data, void *p, int len) -{ - if (data->has_error) - return false; - - if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) - return false; - - if (data->ofs + len > data->length) { - /* we need to mark the buffer as consumed, so the caller knows - this was an out of data error, and not a decode error */ - data->ofs = data->length; - return false; - } - - memcpy(p, data->data + data->ofs, len); - return true; -} - -/* read from a ASN1 buffer, advancing the buffer pointer */ -bool asn1_read(struct asn1_data *data, void *p, int len) -{ - if (!asn1_peek(data, p, len)) { - data->has_error = true; - return false; - } - - data->ofs += len; - return true; -} - -/* read a uint8_t from a ASN1 buffer */ -bool asn1_read_uint8(struct asn1_data *data, uint8_t *v) -{ - return asn1_read(data, v, 1); -} - -bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v) -{ - return asn1_peek(data, v, 1); -} - -bool asn1_peek_tag(struct asn1_data *data, uint8_t tag) -{ - uint8_t b; - - if (asn1_tag_remaining(data) <= 0) { - return false; - } - - if (!asn1_peek_uint8(data, &b)) - return false; - - return (b == tag); -} - -/* start reading a nested asn1 structure */ -bool asn1_start_tag(struct asn1_data *data, uint8_t tag) -{ - uint8_t b; - struct nesting *nesting; - - if (!asn1_read_uint8(data, &b)) - return false; - - if (b != tag) { - data->has_error = true; - return false; - } - nesting = talloc(data, struct nesting); - if (!nesting) { - data->has_error = true; - return false; - } - - if (!asn1_read_uint8(data, &b)) { - return false; - } - - if (b & 0x80) { - int n = b & 0x7f; - if (!asn1_read_uint8(data, &b)) - return false; - nesting->taglen = b; - while (n > 1) { - if (!asn1_read_uint8(data, &b)) - return false; - nesting->taglen = (nesting->taglen << 8) | b; - n--; - } - } else { - nesting->taglen = b; - } - nesting->start = data->ofs; - nesting->next = data->nesting; - data->nesting = nesting; - if (asn1_tag_remaining(data) == -1) { - return false; - } - return !data->has_error; -} - -/* stop reading a tag */ -bool asn1_end_tag(struct asn1_data *data) -{ - struct nesting *nesting; - - /* make sure we read it all */ - if (asn1_tag_remaining(data) != 0) { - data->has_error = true; - return false; - } - - nesting = data->nesting; - - if (!nesting) { - data->has_error = true; - return false; - } - - data->nesting = nesting->next; - talloc_free(nesting); - return true; -} - -/* work out how many bytes are left in this nested tag */ -int asn1_tag_remaining(struct asn1_data *data) -{ - int remaining; - if (data->has_error) { - return -1; - } - - if (!data->nesting) { - data->has_error = true; - return -1; - } - remaining = data->nesting->taglen - (data->ofs - data->nesting->start); - if (remaining > (data->length - data->ofs)) { - data->has_error = true; - return -1; - } - return remaining; -} - -/* read an object ID from a data blob */ -bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID) -{ - int i; - uint8_t *b; - uint_t v; - char *tmp_oid = NULL; - - if (blob.length < 2) return false; - - b = blob.data; - - tmp_oid = talloc_asprintf(mem_ctx, "%u", b[0]/40); - if (!tmp_oid) goto nomem; - tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", b[0]%40); - if (!tmp_oid) goto nomem; - - for(i = 1, v = 0; i < blob.length; i++) { - v = (v<<7) | (b[i]&0x7f); - if ( ! (b[i] & 0x80)) { - tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", v); - v = 0; - } - if (!tmp_oid) goto nomem; - } - - if (v != 0) { - talloc_free(tmp_oid); - return false; - } - - *OID = tmp_oid; - return true; - -nomem: - return false; -} - -/* read an object ID from a ASN1 buffer */ -bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, const char **OID) -{ - DATA_BLOB blob; - int len; - - if (!asn1_start_tag(data, ASN1_OID)) return false; - - len = asn1_tag_remaining(data); - if (len < 0) { - data->has_error = true; - return false; - } - - blob = data_blob(NULL, len); - if (!blob.data) { - data->has_error = true; - return false; - } - - asn1_read(data, blob.data, len); - asn1_end_tag(data); - if (data->has_error) { - data_blob_free(&blob); - return false; - } - - if (!ber_read_OID_String(mem_ctx, blob, OID)) { - data->has_error = true; - data_blob_free(&blob); - return false; - } - - data_blob_free(&blob); - return true; -} - -/* check that the next object ID is correct */ -bool asn1_check_OID(struct asn1_data *data, const char *OID) -{ - const char *id; - - if (!asn1_read_OID(data, data, &id)) return false; - - if (strcmp(id, OID) != 0) { - talloc_free(discard_const(id)); - data->has_error = true; - return false; - } - talloc_free(discard_const(id)); - return true; -} - -/* read a LDAPString from a ASN1 buffer */ -bool asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) -{ - int len; - len = asn1_tag_remaining(data); - if (len < 0) { - data->has_error = true; - return false; - } - *s = talloc_array(mem_ctx, char, len+1); - if (! *s) { - data->has_error = true; - return false; - } - asn1_read(data, *s, len); - (*s)[len] = 0; - return !data->has_error; -} - - -/* read a GeneralString from a ASN1 buffer */ -bool asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s) -{ - if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return false; - if (!asn1_read_LDAPString(data, mem_ctx, s)) return false; - return asn1_end_tag(data); -} - - -/* read a octet string blob */ -bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob) -{ - int len; - ZERO_STRUCTP(blob); - if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return false; - len = asn1_tag_remaining(data); - if (len < 0) { - data->has_error = true; - return false; - } - *blob = data_blob_talloc(mem_ctx, NULL, len+1); - if (!blob->data) { - data->has_error = true; - return false; - } - asn1_read(data, blob->data, len); - asn1_end_tag(data); - blob->length--; - blob->data[len] = 0; - - if (data->has_error) { - data_blob_free(blob); - *blob = data_blob(NULL, 0); - return false; - } - return true; -} - -bool asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) -{ - int len; - ZERO_STRUCTP(blob); - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false; - len = asn1_tag_remaining(data); - if (len < 0) { - data->has_error = true; - return false; - } - *blob = data_blob(NULL, len); - if ((len != 0) && (!blob->data)) { - data->has_error = true; - return false; - } - asn1_read(data, blob->data, len); - asn1_end_tag(data); - return !data->has_error; -} - -/* read an integer without tag*/ -bool asn1_read_implicit_Integer(struct asn1_data *data, int *i) -{ - uint8_t b; - *i = 0; - - while (!data->has_error && asn1_tag_remaining(data)>0) { - if (!asn1_read_uint8(data, &b)) return false; - *i = (*i << 8) + b; - } - return !data->has_error; - -} - -/* read an integer */ -bool asn1_read_Integer(struct asn1_data *data, int *i) -{ - *i = 0; - - if (!asn1_start_tag(data, ASN1_INTEGER)) return false; - if (!asn1_read_implicit_Integer(data, i)) return false; - return asn1_end_tag(data); -} - -/* read an integer */ -bool asn1_read_enumerated(struct asn1_data *data, int *v) -{ - *v = 0; - - if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false; - while (!data->has_error && asn1_tag_remaining(data)>0) { - uint8_t b; - asn1_read_uint8(data, &b); - *v = (*v << 8) + b; - } - return asn1_end_tag(data); -} - -/* check a enumerated value is correct */ -bool asn1_check_enumerated(struct asn1_data *data, int v) -{ - uint8_t b; - if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false; - asn1_read_uint8(data, &b); - asn1_end_tag(data); - - if (v != b) - data->has_error = false; - - return !data->has_error; -} - -/* write an enumerated value to the stream */ -bool asn1_write_enumerated(struct asn1_data *data, uint8_t v) -{ - if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false; - asn1_write_uint8(data, v); - asn1_pop_tag(data); - return !data->has_error; -} - -/* - check if a ASN.1 blob is a full tag -*/ -NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) -{ - struct asn1_data *asn1 = asn1_init(NULL); - int size; - - NT_STATUS_HAVE_NO_MEMORY(asn1); - - asn1->data = blob.data; - asn1->length = blob.length; - asn1_start_tag(asn1, tag); - if (asn1->has_error) { - talloc_free(asn1); - return STATUS_MORE_ENTRIES; - } - size = asn1_tag_remaining(asn1) + asn1->ofs; - - talloc_free(asn1); - - if (size > blob.length) { - return STATUS_MORE_ENTRIES; - } - - *packet_size = size; - return NT_STATUS_OK; -} diff --git a/source4/libcli/util/asn_1.h b/source4/libcli/util/asn_1.h deleted file mode 100644 index 612a8a932f..0000000000 --- a/source4/libcli/util/asn_1.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple ASN1 code - Copyright (C) Andrew Tridgell 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef _ASN_1_H -#define _ASN_1_H - -struct nesting { - off_t start; - size_t taglen; /* for parsing */ - struct nesting *next; -}; - -struct asn1_data { - uint8_t *data; - size_t length; - off_t ofs; - struct nesting *nesting; - bool has_error; -}; - -#define ASN1_APPLICATION(x) ((x)+0x60) -#define ASN1_APPLICATION_SIMPLE(x) ((x)+0x40) -#define ASN1_SEQUENCE(x) ((x)+0x30) -#define ASN1_CONTEXT(x) ((x)+0xa0) -#define ASN1_CONTEXT_SIMPLE(x) ((x)+0x80) -#define ASN1_GENERAL_STRING 0x1b -#define ASN1_OCTET_STRING 0x4 -#define ASN1_OID 0x6 -#define ASN1_BOOLEAN 0x1 -#define ASN1_INTEGER 0x2 -#define ASN1_ENUMERATED 0xa -#define ASN1_SET 0x31 - -#define ASN1_MAX_OIDS 20 - -#include "libcli/util/asn1_proto.h" - -#endif /* _ASN_1_H */ diff --git a/source4/librpc/ndr/ndr_drsuapi.c b/source4/librpc/ndr/ndr_drsuapi.c index dedcb0601d..9f755ffaab 100644 --- a/source4/librpc/ndr/ndr_drsuapi.c +++ b/source4/librpc/ndr/ndr_drsuapi.c @@ -23,7 +23,7 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_misc.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" void ndr_print_drsuapi_DsReplicaObjectListItem(struct ndr_print *ndr, const char *name, const struct drsuapi_DsReplicaObjectListItem *r) -- cgit From 0c7f4c23b7c98b41dce1919aca78bc7b760659fe Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Jan 2008 01:08:30 +0100 Subject: python: Update status. (This used to be commit b4b12f00a7eb952024795ddc5ab3481fd4ba03fc) --- source4/scripting/python/STATUS | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'source4') diff --git a/source4/scripting/python/STATUS b/source4/scripting/python/STATUS index 0e88b4041c..6e6475bfde 100644 --- a/source4/scripting/python/STATUS +++ b/source4/scripting/python/STATUS @@ -3,15 +3,13 @@ lib/ldb/tests/python/ldap.py: Fix remaining 3 FIXME's provisioning in LDAP mode(TEST_LDAP=yes PROVISION_PYTHON=yes make test) command-line vampire provisioning: combine some of the python dictionaries -hierarchy -DCE/RPC bindings - - pidl: - Parse::Pidl::Samba::Python - - wrap struct/bitmap/enum/union types - - __ndr_pack__/__ndr_unpack__ members - - scripting/bin/smbstatus.py +finish scripting/bin/smbstatus.py not important before making Python the default: +- hierarchy (rename samr -> dcerpc.samr, misc -> samba.misc, etc) - scripting/python/samba/upgrade.py - install python modules into system - SWAT +- __ndr_pack__/__ndr_unpack__ members for the NDR struct bindings +- generate docstrings in DCE/RPC bindings +- eliminate some variables from the python interface because they can be induced -- cgit From 341ee607b361aed256bfede84f82f790b475d187 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Jan 2008 02:04:20 +0100 Subject: ldap.py: Use constants where possible. (This used to be commit 0885dc9f813e19cd6c28d8259eaeccf1e9b26210) --- source4/lib/ldb/tests/python/ldap.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'source4') diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py index cede927f7a..01b66a3890 100755 --- a/source4/lib/ldb/tests/python/ldap.py +++ b/source4/lib/ldb/tests/python/ldap.py @@ -11,7 +11,10 @@ sys.path.append("scripting/python") import samba.getopt as options from auth import system_session -from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError +from ldb import (SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, + LDB_ERR_NO_SUCH_OBJECT, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS, + LDB_ERR_ENTRY_ALREADY_EXISTS, LDB_ERR_UNWILLING_TO_PERFORM, + LDB_ERR_NOT_ALLOWED_ON_NON_LEAF) from samba import Ldb import param @@ -38,7 +41,7 @@ def delete_force(ldb, dn): try: ldb.delete(dn) except LdbError, (num, _): - if num != 32: # LDAP_NO_SUCH_OBJECT + if num != LDB_ERR_NO_SUCH_OBJECT: assert False def assertEquals(a1, a2): @@ -57,7 +60,7 @@ def basic_tests(ldb, gc_ldb, base_dn, configuration_dn, schema_dn): "objectclass": "group", "member": "cn=ldaptestuser,cn=useRs," + base_dn}) except LdbError, (num, _): - if num != 32: # LDAP_NO_SUCH_OBJECT + if num != LDB_ERR_NO_SUCH_OBJECT: assert False else: assert False @@ -122,8 +125,7 @@ servicePrincipalName: host/ldaptest2computer servicePrincipalName: cifs/ldaptest2computer """) except LdbError, (num, msg): - #LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS - assert num == 20, "Expected error LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS, got : %s" % msg + assert num == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS ldb.modify_ldif(""" dn: cn=ldaptest2computer,cn=computers,""" + base_dn + """ @@ -140,7 +142,7 @@ add: servicePrincipalName servicePrincipalName: host/ldaptest2computer """) except LdbError, (num, msg): - assert num == 20, "Expected error LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS, got :" + msg + assert num == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS print "Testing ranged results" ldb.modify_ldif(""" @@ -347,7 +349,7 @@ add: member member: cn=ldaptestuser3,cn=users,""" + base_dn + """ """) except LdbError, (num, _): - assert num == 32 + assert num == LDB_ERR_NO_SUCH_OBJECT else: assert False @@ -391,7 +393,7 @@ member: cn=ldaptestuser3,cn=users,""" + base_dn + """ "objectClass": ["person", "user"], "cn": "LDAPtestUSER3"}) except LdbError, (num, _): - assert num == 68 #LDB_ERR_ENTRY_ALREADY_EXISTS + assert num == LDB_ERR_ENTRY_ALREADY_EXISTS else: assert False @@ -402,7 +404,7 @@ member: cn=ldaptestuser3,cn=users,""" + base_dn + """ try: ldb.rename("cn=ldaptestuser3,cn=users," + base_dn, "cn=ldaptestuser2,cn=users," + base_dn) except LdbError, (num, _): - assert num == 32 # LDAP_NO_SUCH_OBJECT + assert num == LDB_ERR_NO_SUCH_OBJECT else: assert False @@ -415,7 +417,7 @@ member: cn=ldaptestuser3,cn=users,""" + base_dn + """ try: ldb.rename("cn=ldaptestuser2,cn=users," + base_dn, "cn=ldaptestuser3,cn=users," + base_dn) except LdbError, (num, _): - assert num == 68 #LDB_ERR_ENTRY_ALREADY_EXISTS + assert num == LDB_ERR_ENTRY_ALREADY_EXISTS else: assert False try: @@ -468,7 +470,7 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + base_dn + """ expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_SUBTREE) except LdbError, (num, _): - assert num == 32 + assert num == LDB_ERR_NO_SUCH_OBJECT else: assert False @@ -476,7 +478,7 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + base_dn + """ try: res = ldb.search("cn=ldaptestcontainer," + base_dn, expression="(&(cn=ldaptestuser4)(objectClass=user))", scope=SCOPE_ONELEVEL) except LdbError, (num, _): - assert num == 32 + assert num == LDB_ERR_NO_SUCH_OBJECT else: assert False @@ -495,7 +497,7 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + base_dn + """ try: ldb.rename("cn=ldaptestcontainer2," + base_dn, "cn=ldaptestcontainer,cn=ldaptestcontainer2," + base_dn) except LdbError, (num, _): - assert num == 53 # LDAP_UNWILLING_TO_PERFORM + assert num == LDB_ERR_UNWILLING_TO_PERFORM else: assert False @@ -511,7 +513,7 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + base_dn + """ try: ldb.delete("cn=ldaptestcontainer2," + base_dn) except LdbError, (num, _): - assert num == 66 + assert num == LDB_ERR_NOT_ALLOWED_ON_NON_LEAF else: assert False -- cgit From f233fd11b3afd49269d11653f3447129d97a7fff Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Jan 2008 02:04:42 +0100 Subject: Fix asn1 locations. (This used to be commit 84dc6bc19c166e42c5eca2949e4ef5024c80f513) --- source4/headermap.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/headermap.txt b/source4/headermap.txt index 6ace20519f..acbe81328e 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -103,8 +103,8 @@ dsdb/samdb/samdb_proto.h: samdb/proto.h dsdb/schema/schema.h: samdb/schema.h dsdb/schema/proto.h: samdb/schema_proto.h dsdb/common/proto.h: samdb/common_proto.h -libcli/util/asn_1.h: samba/asn1.h -libcli/util/asn1_proto.h: samba/asn1/proto.h +lib/util/asn1.h: samba/asn1.h +lib/util/asn1_proto.h: samba/asn1/proto.h libcli/util/error.h: core/error.h libcli/util/proto.h: core/error_proto.h lib/tdb_wrap.h: tdb_wrap.h -- cgit From 9170998427ebbb7abfd9b482fb6e0d051bca5205 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Jan 2008 14:05:47 +1100 Subject: merged tdb from ctdb bzr tree (This used to be commit ed0c3a0f74c305b3b8554b05c3f97cf79db8296a) --- source4/lib/tdb/common/freelist.c | 101 ++++++--- source4/lib/tdb/common/io.c | 20 +- source4/lib/tdb/common/lock.c | 7 + source4/lib/tdb/common/open.c | 11 +- source4/lib/tdb/common/tdb.c | 119 +++++++++- source4/lib/tdb/common/tdb_private.h | 7 +- source4/lib/tdb/common/transaction.c | 408 ++++++++++++++++++++--------------- source4/lib/tdb/common/traverse.c | 3 + source4/lib/tdb/include/tdb.h | 5 + 9 files changed, 471 insertions(+), 210 deletions(-) (limited to 'source4') diff --git a/source4/lib/tdb/common/freelist.c b/source4/lib/tdb/common/freelist.c index b109643f23..c086c151fa 100644 --- a/source4/lib/tdb/common/freelist.c +++ b/source4/lib/tdb/common/freelist.c @@ -27,6 +27,12 @@ #include "tdb_private.h" +/* 'right' merges can involve O(n^2) cost when combined with a + traverse, so they are disabled until we find a way to do them in + O(1) time +*/ +#define USE_RIGHT_MERGES 0 + /* read a freelist record and check for simple errors */ int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct list_struct *rec) { @@ -56,7 +62,7 @@ int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct list_struct } - +#if USE_RIGHT_MERGES /* Remove an element from the freelist. Must have alloc lock. */ static int remove_from_freelist(struct tdb_context *tdb, tdb_off_t off, tdb_off_t next) { @@ -75,6 +81,7 @@ static int remove_from_freelist(struct tdb_context *tdb, tdb_off_t off, tdb_off_ TDB_LOG((tdb, TDB_DEBUG_FATAL,"remove_from_freelist: not on list at off=%d\n", off)); return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); } +#endif /* update a record tailer (must hold allocation lock) */ @@ -93,8 +100,6 @@ static int update_tailer(struct tdb_context *tdb, tdb_off_t offset, neccessary. */ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) { - tdb_off_t right, left; - /* Allocation and tailer lock */ if (tdb_lock(tdb, -1, F_WRLCK) != 0) return -1; @@ -105,9 +110,10 @@ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) goto fail; } +#if USE_RIGHT_MERGES /* Look right first (I'm an Australian, dammit) */ - right = offset + sizeof(*rec) + rec->rec_len; - if (right + sizeof(*rec) <= tdb->map_size) { + if (offset + sizeof(*rec) + rec->rec_len + sizeof(*rec) <= tdb->map_size) { + tdb_off_t right = offset + sizeof(*rec) + rec->rec_len; struct list_struct r; if (tdb->methods->tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) { @@ -122,13 +128,18 @@ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) goto left; } rec->rec_len += sizeof(r) + r.rec_len; + if (update_tailer(tdb, offset, rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); + goto fail; + } } } - left: +#endif + /* Look left */ - left = offset - sizeof(tdb_off_t); - if (left > TDB_DATA_START(tdb->header.hash_size)) { + if (offset - sizeof(tdb_off_t) > TDB_DATA_START(tdb->header.hash_size)) { + tdb_off_t left = offset - sizeof(tdb_off_t); struct list_struct l; tdb_off_t leftsize; @@ -145,7 +156,12 @@ left: left = offset - leftsize; - /* Now read in record */ + if (leftsize > offset || + left < TDB_DATA_START(tdb->header.hash_size)) { + goto update; + } + + /* Now read in the left record */ if (tdb->methods->tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); goto update; @@ -153,21 +169,24 @@ left: /* If it's free, expand to include it. */ if (l.magic == TDB_FREE_MAGIC) { - if (remove_from_freelist(tdb, left, l.next) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left free failed at %u\n", left)); - goto update; - } else { - offset = left; - rec->rec_len += leftsize; + /* we now merge the new record into the left record, rather than the other + way around. This makes the operation O(1) instead of O(n). This change + prevents traverse from being O(n^2) after a lot of deletes */ + l.rec_len += sizeof(*rec) + rec->rec_len; + if (tdb_rec_write(tdb, left, &l) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_left failed at %u\n", left)); + goto fail; } + if (update_tailer(tdb, left, &l) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); + goto fail; + } + tdb_unlock(tdb, -1, F_WRLCK); + return 0; } } update: - if (update_tailer(tdb, offset, rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); - goto fail; - } /* Now, prepend to free list */ rec->magic = TDB_FREE_MAGIC; @@ -261,6 +280,7 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st tdb_off_t rec_ptr, last_ptr; tdb_len_t rec_len; } bestfit; + float multiplier = 1.0; if (tdb_lock(tdb, -1, F_WRLCK) == -1) return 0; @@ -295,18 +315,27 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st bestfit.rec_len = rec->rec_len; bestfit.rec_ptr = rec_ptr; bestfit.last_ptr = last_ptr; - /* consider a fit to be good enough if - we aren't wasting more than half - the space */ - if (bestfit.rec_len < 2*length) { - break; - } } } /* move to the next record */ last_ptr = rec_ptr; rec_ptr = rec->next; + + /* if we've found a record that is big enough, then + stop searching if its also not too big. The + definition of 'too big' changes as we scan + through */ + if (bestfit.rec_len > 0 && + bestfit.rec_len < length * multiplier) { + break; + } + + /* this multiplier means we only extremely rarely + search more than 50 or so records. At 50 records we + accept records up to 11 times larger than what we + want */ + multiplier *= 1.05; } if (bestfit.rec_ptr != 0) { @@ -328,3 +357,25 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st return 0; } + + +/* + return the size of the freelist - used to decide if we should repack +*/ +int tdb_freelist_size(struct tdb_context *tdb) +{ + tdb_off_t ptr; + int count=0; + + if (tdb_lock(tdb, -1, F_RDLCK) == -1) { + return -1; + } + + ptr = FREELIST_TOP; + while (tdb_ofs_read(tdb, ptr, &ptr) == 0 && ptr != 0) { + count++; + } + + tdb_unlock(tdb, -1, F_RDLCK); + return count; +} diff --git a/source4/lib/tdb/common/io.c b/source4/lib/tdb/common/io.c index 8ab0768883..172ab69d8c 100644 --- a/source4/lib/tdb/common/io.c +++ b/source4/lib/tdb/common/io.c @@ -101,8 +101,8 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, off+written); } if (written == -1) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %d " "len=%d (%s)\n", off, len, strerror(errno))); return TDB_ERRCODE(TDB_ERR_IO, -1); @@ -111,8 +111,8 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, "write %d bytes at %d in two attempts\n", len, off)); errno = ENOSPC; - return TDB_ERRCODE(TDB_ERR_IO, -1); - } + return TDB_ERRCODE(TDB_ERR_IO, -1); + } } return 0; } @@ -230,7 +230,7 @@ void tdb_mmap(struct tdb_context *tdb) says to use for mmap expansion */ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) { - char buf[1024]; + char buf[8192]; if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; @@ -294,7 +294,7 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad int tdb_expand(struct tdb_context *tdb, tdb_off_t size) { struct list_struct rec; - tdb_off_t offset; + tdb_off_t offset, new_size; if (tdb_lock(tdb, -1, F_WRLCK) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n")); @@ -304,9 +304,11 @@ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) /* must know about any previous expansions by another process */ tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); - /* always make room for at least 10 more records, and round - the database up to a multiple of the page size */ - size = TDB_ALIGN(tdb->map_size + size*10, tdb->page_size) - tdb->map_size; + /* always make room for at least 100 more records, and at + least 25% more space. Round the database up to a multiple + of the page size */ + new_size = MAX(tdb->map_size + size*100, tdb->map_size * 1.25); + size = TDB_ALIGN(new_size, tdb->page_size) - tdb->map_size; if (!(tdb->flags & TDB_INTERNAL)) tdb_munmap(tdb); diff --git a/source4/lib/tdb/common/lock.c b/source4/lib/tdb/common/lock.c index e3fe888c46..f156c0fa7b 100644 --- a/source4/lib/tdb/common/lock.c +++ b/source4/lib/tdb/common/lock.c @@ -505,6 +505,9 @@ int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) /* record lock stops delete underneath */ int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off) { + if (tdb->global_lock.count) { + return 0; + } return off ? tdb->methods->tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0, 1) : 0; } @@ -537,6 +540,10 @@ int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off) struct tdb_traverse_lock *i; uint32_t count = 0; + if (tdb->global_lock.count) { + return 0; + } + if (off == 0) return 0; for (i = &tdb->travlocks; i; i = i->next) diff --git a/source4/lib/tdb/common/open.c b/source4/lib/tdb/common/open.c index 0bd1c91a5e..6bd8fda2bf 100644 --- a/source4/lib/tdb/common/open.c +++ b/source4/lib/tdb/common/open.c @@ -35,7 +35,7 @@ static struct tdb_context *tdbs = NULL; static unsigned int default_tdb_hash(TDB_DATA *key) { uint32_t value; /* Used to compute the hash value. */ - uint32_t i; /* Used to cycle through random values. */ + uint32_t i; /* Used to cycle through random values. */ /* Set the initial value from the key size. */ for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) @@ -90,7 +90,7 @@ static int tdb_new_database(struct tdb_context *tdb, int hash_size) size -= written; written = write(tdb->fd, newdb+written, size); if (written == size) { - ret = 0; + ret = 0; } else if (written >= 0) { /* a second incomplete write - we give up. * guessing the errno... */ @@ -152,6 +152,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, int rev = 0, locked = 0; unsigned char *vp; uint32_t vertest; + unsigned v; if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) { /* Can't log this */ @@ -215,6 +216,10 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, goto fail; /* errno set by open(2) */ } + /* on exec, don't inherit the fd */ + v = fcntl(tdb->fd, F_GETFD, 0); + fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC); + /* ensure there is only one process initialising at once */ if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get global lock on %s: %s\n", @@ -242,7 +247,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, /* its not a valid database - possibly initialise it */ if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) { if (errno == 0) { - errno = EIO; /* ie bad format or something */ + errno = EIO; /* ie bad format or something */ } goto fail; } diff --git a/source4/lib/tdb/common/tdb.c b/source4/lib/tdb/common/tdb.c index 0e9d1dbd74..fd4e1cc8af 100644 --- a/source4/lib/tdb/common/tdb.c +++ b/source4/lib/tdb/common/tdb.c @@ -102,8 +102,7 @@ static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, } /* As tdb_find, but if you succeed, keep the lock */ -tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, - uint32_t hash, int locktype, +tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, struct list_struct *rec) { uint32_t rec_ptr; @@ -237,14 +236,15 @@ int tdb_exists(struct tdb_context *tdb, TDB_DATA key) } /* actually delete an entry in the database given the offset */ -int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct*rec) +int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec) { tdb_off_t last_ptr, i; struct list_struct lastrec; if (tdb->read_only || tdb->traverse_read) return -1; - if (tdb_write_lock_record(tdb, rec_ptr) == -1) { + if (tdb->traverse_write != 0 || + tdb_write_lock_record(tdb, rec_ptr) == -1) { /* Someone traversing here: mark it as dead */ rec->magic = TDB_DEAD_MAGIC; return tdb_rec_write(tdb, rec_ptr, rec); @@ -666,6 +666,16 @@ int tdb_get_flags(struct tdb_context *tdb) return tdb->flags; } +void tdb_add_flags(struct tdb_context *tdb, unsigned flags) +{ + tdb->flags |= flags; +} + +void tdb_remove_flags(struct tdb_context *tdb, unsigned flags) +{ + tdb->flags &= ~flags; +} + /* enable sequence number handling on an open tdb @@ -674,3 +684,104 @@ void tdb_enable_seqnum(struct tdb_context *tdb) { tdb->flags |= TDB_SEQNUM; } + + +/* + wipe the entire database, deleting all records. This can be done + very fast by using a global lock. The entire data portion of the + file becomes a single entry in the freelist. + */ +int tdb_wipe_all(struct tdb_context *tdb) +{ + int i; + tdb_off_t offset = 0; + ssize_t data_len; + + if (tdb_lockall(tdb) != 0) { + return -1; + } + + /* wipe the hashes */ + for (i=0;iheader.hash_size;i++) { + if (tdb_ofs_write(tdb, TDB_HASH_TOP(i), &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write hash %d\n", i)); + goto failed; + } + } + + /* wipe the freelist */ + if (tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write freelist\n")); + goto failed; + } + + if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write recovery head\n")); + goto failed; + } + + /* add all the rest of the file to the freelist */ + data_len = (tdb->map_size - TDB_DATA_START(tdb->header.hash_size)) - sizeof(struct list_struct); + if (data_len > 0) { + struct list_struct rec; + memset(&rec,'\0',sizeof(rec)); + rec.rec_len = data_len; + if (tdb_free(tdb, TDB_DATA_START(tdb->header.hash_size), &rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to add free record\n")); + goto failed; + } + } + + if (tdb_unlockall(tdb) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n")); + goto failed; + } + + return 0; + +failed: + tdb_unlockall(tdb); + return -1; +} + + +/* + validate the integrity of all tdb hash chains. Useful when debugging + */ +int tdb_validate(struct tdb_context *tdb) +{ + int h; + for (h=-1;h<(int)tdb->header.hash_size;h++) { + tdb_off_t rec_ptr; + uint32_t count = 0; + if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &rec_ptr) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_validate: failed ofs_read at top of hash %d\n", h)); + return -1; + } + while (rec_ptr) { + struct list_struct r; + tdb_off_t size; + + if (tdb_rec_read(tdb, rec_ptr, &r) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_validate: failed rec_read h=%d rec_ptr=%u count=%u\n", + h, rec_ptr, count)); + return -1; + } + if (tdb_ofs_read(tdb, rec_ptr + sizeof(r) + r.rec_len - sizeof(tdb_off_t), &size) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_validate: failed ofs_read h=%d rec_ptr=%u count=%u\n", + h, rec_ptr, count)); + return -1; + } + if (size != r.rec_len + sizeof(r)) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_validate: failed size check size=%u h=%d rec_ptr=%u count=%u\n", + size, h, rec_ptr, count)); + return -1; + } + rec_ptr = r.next; + count++; + } + } + return 0; +} + + diff --git a/source4/lib/tdb/common/tdb_private.h b/source4/lib/tdb/common/tdb_private.h index 00bd0eb537..63a6d04e72 100644 --- a/source4/lib/tdb/common/tdb_private.h +++ b/source4/lib/tdb/common/tdb_private.h @@ -38,6 +38,10 @@ typedef uint32_t tdb_len_t; typedef uint32_t tdb_off_t; +#ifndef offsetof +#define offsetof(t,f) ((unsigned int)&((t *)0)->f) +#endif + #define TDB_MAGIC_FOOD "TDB file\n" #define TDB_VERSION (0x26011967 + 6) #define TDB_MAGIC (0x26011999U) @@ -54,7 +58,7 @@ typedef uint32_t tdb_off_t; #define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) #define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t)) #define TDB_HASHTABLE_SIZE(tdb) ((tdb->header.hash_size+1)*sizeof(tdb_off_t)) -#define TDB_DATA_START(hash_size) TDB_HASH_TOP(hash_size-1) +#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + sizeof(tdb_off_t)) #define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start) #define TDB_SEQNUM_OFS offsetof(struct tdb_header, sequence_number) #define TDB_PAD_BYTE 0x42 @@ -144,6 +148,7 @@ struct tdb_context { tdb_len_t map_size; /* how much space has been mapped */ int read_only; /* opened read-only */ int traverse_read; /* read-only traversal */ + int traverse_write; /* read-write traversal */ struct tdb_lock_type global_lock; int num_lockrecs; struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */ diff --git a/source4/lib/tdb/common/transaction.c b/source4/lib/tdb/common/transaction.c index 7eaacf7a16..0ecfb9b7ff 100644 --- a/source4/lib/tdb/common/transaction.c +++ b/source4/lib/tdb/common/transaction.c @@ -87,12 +87,6 @@ */ -struct tdb_transaction_el { - struct tdb_transaction_el *next, *prev; - tdb_off_t offset; - tdb_len_t length; - unsigned char *data; -}; /* hold the context of any current transaction @@ -105,12 +99,12 @@ struct tdb_transaction { /* the original io methods - used to do IOs to the real db */ const struct tdb_methods *io_methods; - /* the list of transaction elements. We use a doubly linked - list with a last pointer to allow us to keep the list - ordered, with first element at the front of the list. It - needs to be doubly linked as the read/write traversals need - to be backwards, while the commit needs to be forwards */ - struct tdb_transaction_el *elements, *elements_last; + /* the list of transaction blocks. When a block is first + written to, it gets created in this list */ + uint8_t **blocks; + uint32_t num_blocks; + uint32_t block_size; /* bytes in each block */ + uint32_t last_block_size; /* number of valid bytes in the last block */ /* non-zero when an internal transaction error has occurred. All write operations will then fail until the @@ -134,52 +128,48 @@ struct tdb_transaction { static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, tdb_len_t len, int cv) { - struct tdb_transaction_el *el; - - /* we need to walk the list backwards to get the most recent data */ - for (el=tdb->transaction->elements_last;el;el=el->prev) { - tdb_len_t partial; + uint32_t blk; - if (off+len <= el->offset) { - continue; - } - if (off >= el->offset + el->length) { - continue; + /* break it down into block sized ops */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_read(tdb, off, buf, len2, cv) != 0) { + return -1; } + len -= len2; + off += len2; + buf = (void *)(len2 + (char *)buf); + } - /* an overlapping read - needs to be split into up to - 2 reads and a memcpy */ - if (off < el->offset) { - partial = el->offset - off; - if (transaction_read(tdb, off, buf, partial, cv) != 0) { - goto fail; - } - len -= partial; - off += partial; - buf = (void *)(partial + (char *)buf); - } - if (off + len <= el->offset + el->length) { - partial = len; - } else { - partial = el->offset + el->length - off; - } - memcpy(buf, el->data + (off - el->offset), partial); - if (cv) { - tdb_convert(buf, len); - } - len -= partial; - off += partial; - buf = (void *)(partial + (char *)buf); - - if (len != 0 && transaction_read(tdb, off, buf, len, cv) != 0) { + if (len == 0) { + return 0; + } + + blk = off / tdb->transaction->block_size; + + /* see if we have it in the block list */ + if (tdb->transaction->num_blocks <= blk || + tdb->transaction->blocks[blk] == NULL) { + /* nope, do a real read */ + if (tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv) != 0) { goto fail; } - return 0; } - /* its not in the transaction elements - do a real read */ - return tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv); + /* it is in the block list. Now check for the last block */ + if (blk == tdb->transaction->num_blocks-1) { + if (len > tdb->transaction->last_block_size) { + goto fail; + } + } + + /* now copy it out of this block */ + memcpy(buf, tdb->transaction->blocks[blk] + (off % tdb->transaction->block_size), len); + if (cv) { + tdb_convert(buf, len); + } + return 0; fail: TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: failed at off=%d len=%d\n", off, len)); @@ -195,12 +185,8 @@ fail: static int transaction_write(struct tdb_context *tdb, tdb_off_t off, const void *buf, tdb_len_t len) { - struct tdb_transaction_el *el, *best_el=NULL; + uint32_t blk; - if (len == 0) { - return 0; - } - /* if the write is to a hash head, then update the transaction hash heads */ if (len == sizeof(tdb_off_t) && off >= FREELIST_TOP && @@ -209,110 +195,149 @@ static int transaction_write(struct tdb_context *tdb, tdb_off_t off, memcpy(&tdb->transaction->hash_heads[chain], buf, len); } - /* first see if we can replace an existing entry */ - for (el=tdb->transaction->elements_last;el;el=el->prev) { - tdb_len_t partial; - - if (best_el == NULL && off == el->offset+el->length) { - best_el = el; - } - - if (off+len <= el->offset) { - continue; + /* break it up into block sized chunks */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_write(tdb, off, buf, len2) != 0) { + return -1; } - if (off >= el->offset + el->length) { - continue; + len -= len2; + off += len2; + if (buf != NULL) { + buf = (const void *)(len2 + (const char *)buf); } + } - /* an overlapping write - needs to be split into up to - 2 writes and a memcpy */ - if (off < el->offset) { - partial = el->offset - off; - if (transaction_write(tdb, off, buf, partial) != 0) { - goto fail; - } - len -= partial; - off += partial; - buf = (const void *)(partial + (const char *)buf); - } - if (off + len <= el->offset + el->length) { - partial = len; + if (len == 0) { + return 0; + } + + blk = off / tdb->transaction->block_size; + off = off % tdb->transaction->block_size; + + if (tdb->transaction->num_blocks <= blk) { + uint8_t **new_blocks; + /* expand the blocks array */ + if (tdb->transaction->blocks == NULL) { + new_blocks = malloc((blk+1)*sizeof(uint8_t *)); } else { - partial = el->offset + el->length - off; + new_blocks = realloc(tdb->transaction->blocks, (blk+1)*sizeof(uint8_t *)); } - memcpy(el->data + (off - el->offset), buf, partial); - len -= partial; - off += partial; - buf = (const void *)(partial + (const char *)buf); - - if (len != 0 && transaction_write(tdb, off, buf, len) != 0) { + if (new_blocks == NULL) { + tdb->ecode = TDB_ERR_OOM; goto fail; } - - return 0; + memset(&new_blocks[tdb->transaction->num_blocks], 0, + (1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *)); + tdb->transaction->blocks = new_blocks; + tdb->transaction->num_blocks = blk+1; + tdb->transaction->last_block_size = 0; } - /* see if we can append the new entry to an existing entry */ - if (best_el && best_el->offset + best_el->length == off && - (off+len < tdb->transaction->old_map_size || - off > tdb->transaction->old_map_size)) { - unsigned char *data = best_el->data; - el = best_el; - el->data = (unsigned char *)realloc(el->data, - el->length + len); - if (el->data == NULL) { + /* allocate and fill a block? */ + if (tdb->transaction->blocks[blk] == NULL) { + tdb->transaction->blocks[blk] = (uint8_t *)calloc(tdb->transaction->block_size, 1); + if (tdb->transaction->blocks[blk] == NULL) { tdb->ecode = TDB_ERR_OOM; tdb->transaction->transaction_error = 1; - el->data = data; + return -1; + } + if (tdb->transaction->old_map_size > blk * tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size; + if (len2 + (blk * tdb->transaction->block_size) > tdb->transaction->old_map_size) { + len2 = tdb->transaction->old_map_size - (blk * tdb->transaction->block_size); + } + if (tdb->transaction->io_methods->tdb_read(tdb, blk * tdb->transaction->block_size, + tdb->transaction->blocks[blk], + len2, 0) != 0) { + SAFE_FREE(tdb->transaction->blocks[blk]); + tdb->ecode = TDB_ERR_IO; + goto fail; + } + if (blk == tdb->transaction->num_blocks-1) { + tdb->transaction->last_block_size = len2; + } + } + } + + /* overwrite part of an existing block */ + if (buf == NULL) { + memset(tdb->transaction->blocks[blk] + off, 0, len); + } else { + memcpy(tdb->transaction->blocks[blk] + off, buf, len); + } + if (blk == tdb->transaction->num_blocks-1) { + if (len + off > tdb->transaction->last_block_size) { + tdb->transaction->last_block_size = len + off; + } + } + + return 0; + +fail: + TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", + (blk*tdb->transaction->block_size) + off, len)); + tdb->transaction->transaction_error = 1; + return -1; +} + + +/* + write while in a transaction - this varient never expands the transaction blocks, it only + updates existing blocks. This means it cannot change the recovery size +*/ +static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, + const void *buf, tdb_len_t len) +{ + uint32_t blk; + + /* break it up into block sized chunks */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_write_existing(tdb, off, buf, len2) != 0) { return -1; } - if (buf) { - memcpy(el->data + el->length, buf, len); - } else { - memset(el->data + el->length, TDB_PAD_BYTE, len); + len -= len2; + off += len2; + if (buf != NULL) { + buf = (const void *)(len2 + (const char *)buf); } - el->length += len; - return 0; } - /* add a new entry at the end of the list */ - el = (struct tdb_transaction_el *)malloc(sizeof(*el)); - if (el == NULL) { - tdb->ecode = TDB_ERR_OOM; - tdb->transaction->transaction_error = 1; - return -1; + if (len == 0) { + return 0; } - el->next = NULL; - el->prev = tdb->transaction->elements_last; - el->offset = off; - el->length = len; - el->data = (unsigned char *)malloc(len); - if (el->data == NULL) { - free(el); - tdb->ecode = TDB_ERR_OOM; - tdb->transaction->transaction_error = 1; - return -1; + + blk = off / tdb->transaction->block_size; + off = off % tdb->transaction->block_size; + + if (tdb->transaction->num_blocks <= blk || + tdb->transaction->blocks[blk] == NULL) { + return 0; } - if (buf) { - memcpy(el->data, buf, len); + + /* overwrite part of an existing block */ + if (buf == NULL) { + memset(tdb->transaction->blocks[blk] + off, 0, len); } else { - memset(el->data, TDB_PAD_BYTE, len); + memcpy(tdb->transaction->blocks[blk] + off, buf, len); } - if (el->prev) { - el->prev->next = el; - } else { - tdb->transaction->elements = el; + if (blk == tdb->transaction->num_blocks-1) { + if (len + off > tdb->transaction->last_block_size) { + tdb->transaction->last_block_size = len + off; + } } - tdb->transaction->elements_last = el; + return 0; fail: - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", off, len)); - tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", + (blk*tdb->transaction->block_size) + off, len)); tdb->transaction->transaction_error = 1; return -1; } + /* accelerated hash chain head search, using the cached hash heads */ @@ -419,10 +444,14 @@ int tdb_transaction_start(struct tdb_context *tdb) return -1; } + /* a page at a time seems like a reasonable compromise between compactness and efficiency */ + tdb->transaction->block_size = tdb->page_size; + /* get the transaction write lock. This is a blocking lock. As discussed with Volker, there are a number of ways we could make this async, which we will probably do in the future */ if (tdb_transaction_lock(tdb, F_WRLCK) == -1) { + SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->transaction); return -1; } @@ -460,21 +489,12 @@ int tdb_transaction_start(struct tdb_context *tdb) tdb->transaction->io_methods = tdb->methods; tdb->methods = &transaction_methods; - /* by calling this transaction write here, we ensure that we don't grow the - transaction linked list due to hash table updates */ - if (transaction_write(tdb, FREELIST_TOP, tdb->transaction->hash_heads, - TDB_HASHTABLE_SIZE(tdb)) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to prime hash table\n")); - tdb->ecode = TDB_ERR_IO; - tdb->methods = tdb->transaction->io_methods; - goto fail; - } - return 0; fail: tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0); tdb_transaction_unlock(tdb); + SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->transaction->hash_heads); SAFE_FREE(tdb->transaction); return -1; @@ -486,6 +506,8 @@ fail: */ int tdb_transaction_cancel(struct tdb_context *tdb) { + int i; + if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n")); return -1; @@ -499,13 +521,13 @@ int tdb_transaction_cancel(struct tdb_context *tdb) tdb->map_size = tdb->transaction->old_map_size; - /* free all the transaction elements */ - while (tdb->transaction->elements) { - struct tdb_transaction_el *el = tdb->transaction->elements; - tdb->transaction->elements = el->next; - free(el->data); - free(el); + /* free all the transaction blocks */ + for (i=0;itransaction->num_blocks;i++) { + if (tdb->transaction->blocks[i] != NULL) { + free(tdb->transaction->blocks[i]); + } } + SAFE_FREE(tdb->transaction->blocks); /* remove any global lock created during the transaction */ if (tdb->global_lock.count != 0) { @@ -515,7 +537,6 @@ int tdb_transaction_cancel(struct tdb_context *tdb) /* remove any locks created during the transaction */ if (tdb->num_locks != 0) { - int i; for (i=0;inum_lockrecs;i++) { tdb_brlock(tdb,FREELIST_TOP+4*tdb->lockrecs[i].list, F_UNLCK,F_SETLKW, 0, 1); @@ -567,16 +588,24 @@ static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t */ static tdb_len_t tdb_recovery_size(struct tdb_context *tdb) { - struct tdb_transaction_el *el; tdb_len_t recovery_size = 0; + int i; recovery_size = sizeof(uint32_t); - for (el=tdb->transaction->elements;el;el=el->next) { - if (el->offset >= tdb->transaction->old_map_size) { + for (i=0;itransaction->num_blocks;i++) { + if (i * tdb->transaction->block_size >= tdb->transaction->old_map_size) { + break; + } + if (tdb->transaction->blocks[i] == NULL) { continue; } - recovery_size += 2*sizeof(tdb_off_t) + el->length; - } + recovery_size += 2*sizeof(tdb_off_t); + if (i == tdb->transaction->num_blocks-1) { + recovery_size += tdb->transaction->last_block_size; + } else { + recovery_size += tdb->transaction->block_size; + } + } return recovery_size; } @@ -658,6 +687,10 @@ static int tdb_recovery_allocate(struct tdb_context *tdb, TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); return -1; } + if (transaction_write_existing(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); + return -1; + } return 0; } @@ -669,7 +702,6 @@ static int tdb_recovery_allocate(struct tdb_context *tdb, static int transaction_setup_recovery(struct tdb_context *tdb, tdb_off_t *magic_offset) { - struct tdb_transaction_el *el; tdb_len_t recovery_size; unsigned char *data, *p; const struct tdb_methods *methods = tdb->transaction->io_methods; @@ -677,6 +709,7 @@ static int transaction_setup_recovery(struct tdb_context *tdb, tdb_off_t recovery_offset, recovery_max_size; tdb_off_t old_map_size = tdb->transaction->old_map_size; uint32_t magic, tailer; + int i; /* check that the recovery area has enough space @@ -704,30 +737,43 @@ static int transaction_setup_recovery(struct tdb_context *tdb, /* build the recovery data into a single blob to allow us to do a single large write, which should be more efficient */ p = data + sizeof(*rec); - for (el=tdb->transaction->elements;el;el=el->next) { - if (el->offset >= old_map_size) { + for (i=0;itransaction->num_blocks;i++) { + tdb_off_t offset; + tdb_len_t length; + + if (tdb->transaction->blocks[i] == NULL) { + continue; + } + + offset = i * tdb->transaction->block_size; + length = tdb->transaction->block_size; + if (i == tdb->transaction->num_blocks-1) { + length = tdb->transaction->last_block_size; + } + + if (offset >= old_map_size) { continue; } - if (el->offset + el->length > tdb->transaction->old_map_size) { + if (offset + length > tdb->transaction->old_map_size) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: transaction data over new region boundary\n")); free(data); tdb->ecode = TDB_ERR_CORRUPT; return -1; } - memcpy(p, &el->offset, 4); - memcpy(p+4, &el->length, 4); + memcpy(p, &offset, 4); + memcpy(p+4, &length, 4); if (DOCONV()) { tdb_convert(p, 8); } /* the recovery area contains the old data, not the new data, so we have to call the original tdb_read method to get it */ - if (methods->tdb_read(tdb, el->offset, p + 8, el->length, 0) != 0) { + if (methods->tdb_read(tdb, offset, p + 8, length, 0) != 0) { free(data); tdb->ecode = TDB_ERR_IO; return -1; } - p += 8 + el->length; + p += 8 + length; } /* and the tailer */ @@ -742,6 +788,12 @@ static int transaction_setup_recovery(struct tdb_context *tdb, tdb->ecode = TDB_ERR_IO; return -1; } + if (transaction_write_existing(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery data\n")); + free(data); + tdb->ecode = TDB_ERR_IO; + return -1; + } /* as we don't have ordered writes, we have to sync the recovery data before we update the magic to indicate that the recovery @@ -763,6 +815,11 @@ static int transaction_setup_recovery(struct tdb_context *tdb, tdb->ecode = TDB_ERR_IO; return -1; } + if (transaction_write_existing(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery magic\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } /* ensure the recovery magic marker is on disk */ if (transaction_sync(tdb, *magic_offset, sizeof(magic)) == -1) { @@ -780,6 +837,7 @@ int tdb_transaction_commit(struct tdb_context *tdb) const struct tdb_methods *methods; tdb_off_t magic_offset = 0; uint32_t zero = 0; + int i; if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n")); @@ -793,13 +851,14 @@ int tdb_transaction_commit(struct tdb_context *tdb) return -1; } + if (tdb->transaction->nesting != 0) { tdb->transaction->nesting--; return 0; } /* check for a null transaction */ - if (tdb->transaction->elements == NULL) { + if (tdb->transaction->blocks == NULL) { tdb_transaction_cancel(tdb); return 0; } @@ -858,10 +917,21 @@ int tdb_transaction_commit(struct tdb_context *tdb) } /* perform all the writes */ - while (tdb->transaction->elements) { - struct tdb_transaction_el *el = tdb->transaction->elements; + for (i=0;itransaction->num_blocks;i++) { + tdb_off_t offset; + tdb_len_t length; - if (methods->tdb_write(tdb, el->offset, el->data, el->length) == -1) { + if (tdb->transaction->blocks[i] == NULL) { + continue; + } + + offset = i * tdb->transaction->block_size; + length = tdb->transaction->block_size; + if (i == tdb->transaction->num_blocks-1) { + length = tdb->transaction->last_block_size; + } + + if (methods->tdb_write(tdb, offset, tdb->transaction->blocks[i], length) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed during commit\n")); /* we've overwritten part of the data and @@ -876,11 +946,12 @@ int tdb_transaction_commit(struct tdb_context *tdb) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n")); return -1; } - tdb->transaction->elements = el->next; - free(el->data); - free(el); + SAFE_FREE(tdb->transaction->blocks[i]); } + SAFE_FREE(tdb->transaction->blocks); + tdb->transaction->num_blocks = 0; + if (!(tdb->flags & TDB_NOSYNC)) { /* ensure the new data is on disk */ if (transaction_sync(tdb, 0, tdb->map_size) == -1) { @@ -919,6 +990,7 @@ int tdb_transaction_commit(struct tdb_context *tdb) /* use a transaction cancel to free memory and remove the transaction locks */ tdb_transaction_cancel(tdb); + return 0; } diff --git a/source4/lib/tdb/common/traverse.c b/source4/lib/tdb/common/traverse.c index 6fc576a55a..2bde1270a0 100644 --- a/source4/lib/tdb/common/traverse.c +++ b/source4/lib/tdb/common/traverse.c @@ -238,7 +238,9 @@ int tdb_traverse(struct tdb_context *tdb, return -1; } + tdb->traverse_write++; ret = tdb_traverse_internal(tdb, fn, private_data, &tl); + tdb->traverse_write--; tdb_transaction_unlock(tdb); @@ -330,3 +332,4 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); return key; } + diff --git a/source4/lib/tdb/include/tdb.h b/source4/lib/tdb/include/tdb.h index 7de4c419a8..0058d55793 100644 --- a/source4/lib/tdb/include/tdb.h +++ b/source4/lib/tdb/include/tdb.h @@ -135,6 +135,8 @@ int tdb_get_seqnum(struct tdb_context *tdb); int tdb_hash_size(struct tdb_context *tdb); size_t tdb_map_size(struct tdb_context *tdb); int tdb_get_flags(struct tdb_context *tdb); +void tdb_add_flags(struct tdb_context *tdb, unsigned flag); +void tdb_remove_flags(struct tdb_context *tdb, unsigned flag); void tdb_enable_seqnum(struct tdb_context *tdb); void tdb_increment_seqnum_nonblock(struct tdb_context *tdb); @@ -153,6 +155,9 @@ void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *sigptr) void tdb_dump_all(struct tdb_context *tdb); int tdb_printfreelist(struct tdb_context *tdb); int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries); +int tdb_wipe_all(struct tdb_context *tdb); +int tdb_freelist_size(struct tdb_context *tdb); +int tdb_validate(struct tdb_context *tdb); extern TDB_DATA tdb_null; -- cgit From 50ba04f51258abed6405ff0c8a6e1ea324ab5892 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 10 Nov 2007 22:31:34 -0800 Subject: Always define PATH_MAX. Makes code simpler (removes a bunch of #defines). Remove pstring from msdfs.c. Jeremy. (lib/replace part from e203ba22275320808bc11b17361ad1f2d5b0b897 metze) (This used to be commit ebc08d23f76ecffc90b1fe84c67fc7e6a4c4a6a3) --- source4/lib/replace/replace.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4') diff --git a/source4/lib/replace/replace.h b/source4/lib/replace/replace.h index f8a89a7213..3557684071 100644 --- a/source4/lib/replace/replace.h +++ b/source4/lib/replace/replace.h @@ -546,4 +546,8 @@ typedef int bool; #define QSORT_CAST (int (*)(const void *, const void *)) #endif +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + #endif /* _LIBREPLACE_REPLACE_H */ -- cgit From 0aed6d4125a2c9b525e1119b72c36b651dd4ef3f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Nov 2007 18:27:26 -0800 Subject: Add MAX_DNS_NAME_LENGTH, remove more pstrings. Jeremy. (lib/replace part of a1725f4ff7ed375808c78ac661b539557748d0a5 metze) (This used to be commit db4eabf7cde1008a40a46e5c40a99e9a73cf3ff5) --- source4/lib/replace/replace.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4') diff --git a/source4/lib/replace/replace.h b/source4/lib/replace/replace.h index 3557684071..3f91544e97 100644 --- a/source4/lib/replace/replace.h +++ b/source4/lib/replace/replace.h @@ -550,4 +550,8 @@ typedef int bool; #define PATH_MAX 1024 #endif +#ifndef MAX_DNS_NAME_LENGTH +#define MAX_DNS_NAME_LENGTH 256 /* Actually 255 but +1 for terminating null. */ +#endif + #endif /* _LIBREPLACE_REPLACE_H */ -- cgit From bab53c5e53bac25b7031838953de6083dbbfbc5d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 26 Nov 2007 15:28:13 +0100 Subject: Fix bug 5055 (lib/replace part of 8bcd2df841bae63e7d58c35d4728b7d853471697 metze) (This used to be commit 8db9e196506f530c780d93e16da590566d16a407) --- source4/lib/replace/replace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/lib/replace/replace.c b/source4/lib/replace/replace.c index cec158be31..b2a240e8ab 100644 --- a/source4/lib/replace/replace.c +++ b/source4/lib/replace/replace.c @@ -218,7 +218,7 @@ long nap(long milliseconds) { #ifndef HAVE_MEMMOVE /******************************************************************* safely copies memory, ensuring no overlap problems. -this is only used if the machine does not have it's own memmove(). +this is only used if the machine does not have its own memmove(). this is not the fastest algorithm in town, but it will do for our needs. ********************************************************************/ -- cgit From 645c6518d75c683865a29d1b8c49247a092399da Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Dec 2007 13:16:35 -0800 Subject: Add patches for bug #4866 from jiri sasek - Sun Microsystems - Prague Czech Republic - slightly modified - Jiri please check ! to allow Solaris to get passwords > 8 chars. Jeremy. (lib/replace part of 657bf8c3479d6192f269e3daef1517e77a9fa9cb metze) (This used to be commit 9f5c443972a09a70de7c8d6695b08c3730484c6c) --- source4/lib/replace/getpass.m4 | 10 ++++++++++ source4/lib/replace/system/passwd.h | 4 ++++ 2 files changed, 14 insertions(+) (limited to 'source4') diff --git a/source4/lib/replace/getpass.m4 b/source4/lib/replace/getpass.m4 index 17dfdf7bf5..c4da9aae59 100644 --- a/source4/lib/replace/getpass.m4 +++ b/source4/lib/replace/getpass.m4 @@ -1,3 +1,11 @@ +AC_CHECK_FUNC(getpass, samba_cv_HAVE_GETPASS=yes) +AC_CHECK_FUNC(getpassphrase, samba_cv_HAVE_GETPASSPHRASE=yes) +if test x"$samba_cv_HAVE_GETPASS" = x"yes" -a x"$samba_cv_HAVE_GETPASSPHRASE" = x"yes"; then + AC_DEFINE(REPLACE_GETPASS_BY_GETPASSPHRASE, 1, [getpass returns <9 chars where getpassphrase returns <265 chars]) + AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced]) + LIBREPLACEOBJ="${LIBREPLACEOBJ} getpass.o" +else + AC_CACHE_CHECK([whether getpass should be replaced],samba_cv_REPLACE_GETPASS,[ SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I$libreplacedir/" @@ -12,3 +20,5 @@ if test x"$samba_cv_REPLACE_GETPASS" = x"yes"; then AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced]) LIBREPLACEOBJ="${LIBREPLACEOBJ} getpass.o" fi + +fi diff --git a/source4/lib/replace/system/passwd.h b/source4/lib/replace/system/passwd.h index 36fca7b4f8..cad3197ccb 100644 --- a/source4/lib/replace/system/passwd.h +++ b/source4/lib/replace/system/passwd.h @@ -68,9 +68,13 @@ #endif #ifdef REPLACE_GETPASS +#if defined(REPLACE_GETPASS_BY_GETPASSPHRASE) +#define getpass(prompt) getpassphrase(prompt) +#else #define getpass(prompt) rep_getpass(prompt) char *rep_getpass(const char *prompt); #endif +#endif #ifndef NGROUPS_MAX #define NGROUPS_MAX 32 /* Guess... */ -- cgit From b1fcae724156c2b25f41264943cf4cec8fe68821 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 17 Dec 2007 10:44:09 -0800 Subject: Fix bug #5121 (unix passwd sync not working on a streams based system). Jeremy. (lib/replace part of 545cd2139cfc9484b733693814d4724d37125942 metze) (This used to be commit 9cff25cce1d39460dbcab006a309bb2984969eed) --- source4/lib/replace/libreplace.m4 | 1 + source4/lib/replace/system/network.h | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'source4') diff --git a/source4/lib/replace/libreplace.m4 b/source4/lib/replace/libreplace.m4 index a577285639..6d1d6b8afc 100644 --- a/source4/lib/replace/libreplace.m4 +++ b/source4/lib/replace/libreplace.m4 @@ -100,6 +100,7 @@ AC_CHECK_HEADERS(sys/socket.h netinet/in.h netdb.h arpa/inet.h) AC_CHECK_HEADERS(netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h) AC_CHECK_HEADERS(sys/sockio.h sys/un.h) AC_CHECK_HEADERS(sys/mount.h mntent.h) +AC_CHECK_HEADERS(stropts.h) dnl we need to check that net/if.h really can be used, to cope with hpux dnl where including it always fails diff --git a/source4/lib/replace/system/network.h b/source4/lib/replace/system/network.h index e2fad5f686..53bef66d48 100644 --- a/source4/lib/replace/system/network.h +++ b/source4/lib/replace/system/network.h @@ -79,6 +79,10 @@ #include #endif +#ifdef HAVE_STROPTS_H +#include +#endif + #ifdef REPLACE_INET_NTOA /* define is in "replace.h" */ char *rep_inet_ntoa(struct in_addr ip); -- cgit