From a465add90f3291f022104600c6221e8d90287e64 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Nov 2003 13:14:17 +0000 Subject: * changed the way strings are handled in pidl to a much more general interface. We now support an arbitrary set of flags to each parser, and these can be used to control the string types. I have provided some common IDL string types in librpc/idl/idl_types.h which needs to be included in every IDL file. * added IDL for the endpoint mapper. Added a test suite that enumerates all endpoints on the server. (This used to be commit d2665f36a75b482ff82733f72ffac938c2acf87a) --- source4/Makefile.in | 9 +- source4/build/pidl/NOTES.txt | 11 ++ source4/build/pidl/header.pm | 9 +- source4/build/pidl/idl.gram | 5 +- source4/build/pidl/parser.pm | 105 +++++++++-- source4/build/pidl/util.pm | 16 +- source4/librpc/idl/atsvc.idl | 2 + source4/librpc/idl/dfs.idl | 2 + source4/librpc/idl/echo.idl | 3 + source4/librpc/idl/epmapper.idl | 134 +++++++++++++ source4/librpc/idl/eventlog.idl | 2 + source4/librpc/idl/lsa.idl | 4 +- source4/librpc/idl/misc.idl | 2 + source4/librpc/idl/samr.idl | 24 ++- source4/librpc/idl/spoolss.idl | 4 +- source4/librpc/idl/srvsvc.idl | 4 +- source4/librpc/idl/winreg.idl | 2 + source4/librpc/idl/wkssvc.idl | 2 + source4/librpc/ndr/libndr.h | 24 ++- source4/librpc/ndr/ndr.c | 78 ++++++-- source4/librpc/ndr/ndr_basic.c | 408 +++++++++++++++++++--------------------- source4/torture/rpc/epmapper.c | 87 +++++++++ source4/torture/rpc/samr.c | 28 +++ source4/torture/torture.c | 1 + 24 files changed, 683 insertions(+), 283 deletions(-) create mode 100644 source4/librpc/idl/epmapper.idl create mode 100644 source4/torture/rpc/epmapper.c (limited to 'source4') diff --git a/source4/Makefile.in b/source4/Makefile.in index 0d577d93e1..6614e4ebec 100644 --- a/source4/Makefile.in +++ b/source4/Makefile.in @@ -200,14 +200,15 @@ LIBRAW_NDR_OBJ = librpc/ndr/ndr.o librpc/ndr/ndr_basic.o librpc/ndr/ndr_sec.o \ librpc/gen_ndr/ndr_samr.o librpc/gen_ndr/ndr_spoolss.o \ librpc/gen_ndr/ndr_wkssvc.o librpc/gen_ndr/ndr_srvsvc.o \ librpc/gen_ndr/ndr_atsvc.o librpc/gen_ndr/ndr_eventlog.o \ - librpc/gen_ndr/ndr_winreg.o + librpc/gen_ndr/ndr_epmapper.o librpc/gen_ndr/ndr_winreg.o LIBRAW_RPC_OBJ = librpc/rpc/dcerpc.o librpc/rpc/dcerpc_smb.o \ librpc/gen_rpc/rpc_echo.o librpc/gen_rpc/rpc_lsa.o \ librpc/gen_rpc/rpc_dfs.o librpc/gen_rpc/rpc_spoolss.o \ librpc/gen_rpc/rpc_samr.o librpc/gen_rpc/rpc_wkssvc.o \ librpc/gen_rpc/rpc_srvsvc.o librpc/gen_rpc/rpc_atsvc.o \ - librpc/gen_rpc/rpc_eventlog.o librpc/gen_rpc/rpc_winreg.o + librpc/gen_rpc/rpc_eventlog.o librpc/gen_rpc/rpc_epmapper.o \ + librpc/gen_rpc/rpc_winreg.o LIBRAW_OBJ = libcli/raw/rawfile.o libcli/raw/smb_signing.o \ libcli/raw/clisocket.o libcli/raw/clitransport.o \ @@ -444,8 +445,8 @@ SMBTORTURE_RAW_OBJ = torture/raw/qfsinfo.o torture/raw/qfileinfo.o torture/raw/s SMBTORTURE_RPC_OBJ = torture/rpc/lsa.o torture/rpc/echo.o torture/rpc/dfs.o \ torture/rpc/spoolss.o torture/rpc/samr.o torture/rpc/wkssvc.o \ - torture/rpc/srvsvc.o torture/rpc/atsvc.o \ - torture/rpc/eventlog.o torture/rpc/winreg.o + torture/rpc/srvsvc.o torture/rpc/atsvc.o torture/rpc/eventlog.o \ + torture/rpc/epmapper.o torture/rpc/winreg.o SMBTORTURE_OBJ1 = torture/torture.o torture/torture_util.o torture/nbio.o torture/scanner.o \ torture/utable.o torture/denytest.o torture/mangle_test.o \ diff --git a/source4/build/pidl/NOTES.txt b/source4/build/pidl/NOTES.txt index 4f729ecb95..6210281244 100644 --- a/source4/build/pidl/NOTES.txt +++ b/source4/build/pidl/NOTES.txt @@ -64,6 +64,17 @@ midl.exe would write the above array as the following C header: long s[1]; } Struct1; +pidl takes a different approach, and writes it like this: + + typedef struct { + long abc; + long count; + long foo; + long *s; + } Struct1; + + + VARYING ARRAYS -------------- diff --git a/source4/build/pidl/header.pm b/source4/build/pidl/header.pm index ec8b8451ad..25f0fecd47 100644 --- a/source4/build/pidl/header.pm +++ b/source4/build/pidl/header.pm @@ -49,7 +49,8 @@ sub HeaderElement($) $res .= tabs(); HeaderType($element, $element->{TYPE}, ""); $res .= " "; - if ($element->{POINTERS}) { + if ($element->{POINTERS} && + $element->{TYPE} ne "string") { my($n) = $element->{POINTERS}; for (my($i)=$n; $i > 0; $i--) { $res .= "*"; @@ -125,11 +126,7 @@ sub HeaderType($$$) HeaderUnion($data, $name); return; } - if ($data =~ "unistr" || - $data =~ "ascstr") { - $res .= "const char"; - } elsif ($data =~ "nstring" || - $data =~ "lstring") { + if ($data =~ "string") { $res .= "const char *"; } elsif (util::is_scalar_type($data)) { $res .= "$data"; diff --git a/source4/build/pidl/idl.gram b/source4/build/pidl/idl.gram index d90c2238b4..ac373a5260 100644 --- a/source4/build/pidl/idl.gram +++ b/source4/build/pidl/idl.gram @@ -120,7 +120,8 @@ property: 'unique' | 'noprint' | 'relative' | 'nodiscriminant' - | 'subcontext' + | 'subcontext' '(' constant ')' {{ "$item[1]" => "$item{constant}" }} + | 'flag' '(' anytext ')' {{ "$item[1]" => "$item{anytext}" }} | 'byte_count_pointer' '(' expression ')' {{ "$item[1]" => "$item{expression}" }} | 'size_is' '(' expression ')' {{ "$item[1]" => "$item{expression}" }} | 'length_is' '(' expression ')' {{ "$item[1]" => "$item{expression}" }} @@ -153,7 +154,7 @@ type : text: /[\w\s\..?-]*/ -text2: /[\w\s\*\>\/\..?-]*/ +text2: /[\|\w\s\*\>\/\..?-]*/ anytext: text2 '(' anytext ')' anytext {{ "$item[1]($item[4])$item[6]" }} diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm index 2438ef902a..c57610e9ae 100644 --- a/source4/build/pidl/parser.pm +++ b/source4/build/pidl/parser.pm @@ -42,6 +42,10 @@ sub find_sibling($$) my($name) = shift; my($fn) = $e->{PARENT}; + if ($name =~ /\*(.*)/) { + $name = $1; + } + if ($fn->{TYPE} eq "FUNCTION") { for my $e2 (@{$fn->{DATA}}) { if ($e2->{NAME} eq $name) { @@ -74,17 +78,24 @@ sub find_size_var($$) return $size; } + my $prefix = ""; + + if ($size =~ /\*(.*)/) { + $size = $1; + $prefix = "*"; + } + if ($fn->{TYPE} ne "FUNCTION") { - return "r->$size"; + return $prefix . "r->$size"; } my $e2 = find_sibling($e, $size); if (util::has_property($e2, "in")) { - return "r->in.$size"; + return $prefix . "r->in.$size"; } if (util::has_property($e2, "out")) { - return "r->out.$size"; + return $prefix . "r->out.$size"; } die "invalid variable in $size for element $e->{NAME} in $fn->{NAME}\n"; @@ -103,6 +114,30 @@ sub fn_prefix($) } +################################################################### +# setup any special flags for an element or structure +sub start_flags($) +{ + my $e = shift; + my $flags = util::has_property($e, "flag"); + if (defined $flags) { + pidl "\t{ uint32 _flags_save_$e->{TYPE} = ndr->flags;\n"; + pidl "\tndr->flags |= $flags;\n"; + } +} + +################################################################### +# end any special flags for an element or structure +sub end_flags($) +{ + my $e = shift; + my $flags = util::has_property($e, "flag"); + if (defined $flags) { + pidl "\tndr->flags = _flags_save_$e->{TYPE};\n\t}\n"; + } +} + + ##################################################################### # work out the correct alignment for a structure sub struct_alignment @@ -287,6 +322,8 @@ sub ParseElementPushScalar($$$) my($ndr_flags) = shift; my $cprefix = util::c_push_prefix($e); + start_flags($e); + if (util::has_property($e, "relative")) { pidl "\tNDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, $var_prefix$e->{NAME}, (ndr_push_const_fn_t) ndr_push_$e->{TYPE}));\n"; } elsif (util::is_inline_array($e)) { @@ -304,6 +341,8 @@ sub ParseElementPushScalar($$$) } else { pidl "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n"; } + + end_flags($e); } ##################################################################### @@ -351,8 +390,9 @@ sub ParseElementPullSwitch($$$$) pidl "\t}\n"; } - if (util::has_property($e, "subcontext")) { - pidl "\tNDR_CHECK(ndr_pull_subcontext_union_fn(ndr, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_pull_union_fn_t) ndr_pull_$e->{TYPE}));\n"; + my $sub_size = util::has_property($e, "subcontext"); + if (defined $sub_size) { + pidl "\tNDR_CHECK(ndr_pull_subcontext_union_fn(ndr, $sub_size, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_pull_union_fn_t) ndr_pull_$e->{TYPE}));\n"; } else { pidl "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $switch_var, $cprefix$var_prefix$e->{NAME}));\n"; } @@ -378,8 +418,9 @@ sub ParseElementPushSwitch($$$$) pidl "\tNDR_CHECK(ndr_push_$e2->{TYPE}(ndr, $switch_var));\n"; } - if (util::has_property($e, "subcontext")) { - pidl "\tNDR_CHECK(ndr_push_subcontext_union_fn(ndr, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_push_union_fn_t) ndr_pull_$e->{TYPE}));\n"; + my $sub_size = util::has_property($e, "subcontext"); + if (defined $sub_size) { + pidl "\tNDR_CHECK(ndr_push_subcontext_union_fn(ndr, $sub_size, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_push_union_fn_t) ndr_pull_$e->{TYPE}));\n"; } else { pidl "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $switch_var, $cprefix$var_prefix$e->{NAME}));\n"; } @@ -407,6 +448,9 @@ sub ParseElementPullScalar($$$) my($var_prefix) = shift; my($ndr_flags) = shift; my $cprefix = util::c_pull_prefix($e); + my $sub_size = util::has_property($e, "subcontext"); + + start_flags($e); if (util::has_property($e, "relative")) { pidl "\tNDR_CHECK(ndr_pull_relative(ndr, (const void **)&$var_prefix$e->{NAME}, sizeof(*$var_prefix$e->{NAME}), (ndr_pull_flags_fn_t)ndr_pull_$e->{TYPE}));\n"; @@ -425,17 +469,19 @@ sub ParseElementPullScalar($$$) # no scalar component } elsif (my $switch = util::has_property($e, "switch_is")) { ParseElementPullSwitch($e, $var_prefix, $ndr_flags, $switch); - } elsif (util::has_property($e, "subcontext")) { + } elsif (defined $sub_size) { if (util::is_builtin_type($e->{TYPE})) { - pidl "\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n"; + pidl "\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n"; } else { - pidl "\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n"; + pidl "\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n"; } } elsif (util::is_builtin_type($e->{TYPE})) { pidl "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n"; } else { pidl "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n"; } + + end_flags($e); } ##################################################################### @@ -451,6 +497,8 @@ sub ParseElementPushBuffer($$$) return; } + start_flags($e); + if (util::need_wire_pointer($e)) { pidl "\tif ($var_prefix$e->{NAME}) {\n"; } @@ -478,6 +526,8 @@ sub ParseElementPushBuffer($$$) if (util::need_wire_pointer($e)) { pidl "\t}\n"; } + + end_flags($e); } ##################################################################### @@ -514,6 +564,7 @@ sub ParseElementPullBuffer($$$) my($var_prefix) = shift; my($ndr_flags) = shift; my $cprefix = util::c_pull_prefix($e); + my $sub_size = util::has_property($e, "subcontext"); if (util::is_pure_scalar($e)) { return; @@ -523,6 +574,8 @@ sub ParseElementPullBuffer($$$) return; } + start_flags($e); + if (util::need_wire_pointer($e)) { pidl "\tif ($var_prefix$e->{NAME}) {\n"; } @@ -537,11 +590,13 @@ sub ParseElementPullBuffer($$$) } else { ParseElementPullSwitch($e, $var_prefix, "NDR_BUFFERS", $switch); } - } elsif (util::has_property($e, "subcontext")) { - if (util::is_builtin_type($e->{TYPE})) { - pidl "\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n"; - } else { - pidl "\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n"; + } elsif (defined $sub_size) { + if ($e->{POINTERS}) { + if (util::is_builtin_type($e->{TYPE})) { + pidl "\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n"; + } else { + pidl "\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n"; + } } } elsif (util::is_builtin_type($e->{TYPE})) { pidl "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n"; @@ -554,6 +609,8 @@ sub ParseElementPullBuffer($$$) if (util::need_wire_pointer($e)) { pidl "\t}\n"; } + + end_flags($e); } ##################################################################### @@ -562,11 +619,13 @@ sub ParseStructPush($) { my($struct) = shift; my $conform_e; - + if (! defined $struct->{ELEMENTS}) { return; } + start_flags($struct); + # see if the structure contains a conformant array. If it # does, then it must be the last element of the structure, and # we need to push the conformant length early, as it fits on @@ -600,6 +659,8 @@ sub ParseStructPush($) } pidl "done:\n"; + + end_flags($struct); } ##################################################################### @@ -630,6 +691,8 @@ sub ParseStructPull($) return; } + start_flags($struct); + # see if the structure contains a conformant array. If it # does, then it must be the last element of the structure, and # we need to pull the conformant length early, as it fits on @@ -674,6 +737,8 @@ sub ParseStructPull($) } pidl "done:\n"; + + end_flags($struct); } @@ -683,8 +748,10 @@ sub ParseUnionPush($) { my $e = shift; my $have_default = 0; - pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; + start_flags($e); + + pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; pidl "\tNDR_CHECK(ndr_push_struct_start(ndr));\n"; # my $align = union_alignment($e); @@ -729,6 +796,7 @@ sub ParseUnionPush($) } pidl "\t}\n"; pidl "done:\n"; + end_flags($e); } ##################################################################### @@ -764,6 +832,8 @@ sub ParseUnionPull($) my $e = shift; my $have_default = 0; + start_flags($e); + pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; pidl "\tNDR_CHECK(ndr_pull_struct_start(ndr));\n"; @@ -814,6 +884,7 @@ sub ParseUnionPull($) } pidl "\t}\n"; pidl "done:\n"; + end_flags($e); } ##################################################################### diff --git a/source4/build/pidl/util.pm b/source4/build/pidl/util.pm index 566253699d..2f94d80012 100644 --- a/source4/build/pidl/util.pm +++ b/source4/build/pidl/util.pm @@ -149,7 +149,7 @@ sub has_property($$) my($p) = shift; if (!defined $e->{PROPERTIES}) { - return; + return undef; } my($props) = $e->{PROPERTIES}; @@ -168,7 +168,7 @@ sub has_property($$) } } - return undef; + return undef; } @@ -222,8 +222,6 @@ sub is_builtin_type($) my($type) = shift; return 1, if (is_scalar_type($type)); - return 1, if ($type =~ "unistr.*"); - return 1, if ($type =~ "ascstr.*"); return 0; } @@ -304,6 +302,11 @@ sub need_alloc($) sub c_push_prefix($) { my $e = shift; + + if ($e->{TYPE} =~ "string") { + return ""; + } + if (is_scalar_type($e->{TYPE}) && $e->{POINTERS}) { return "*"; @@ -327,10 +330,7 @@ sub c_pull_prefix($) return "&"; } - if ($e->{TYPE} =~ "unistr.*" || - $e->{TYPE} =~ "nstring.*" || - $e->{TYPE} =~ "ascstr.*" || - $e->{TYPE} =~ "lstring.*") { + if ($e->{TYPE} =~ "string") { return "&"; } diff --git a/source4/librpc/idl/atsvc.idl b/source4/librpc/idl/atsvc.idl index 81394c747b..39add81b09 100644 --- a/source4/librpc/idl/atsvc.idl +++ b/source4/librpc/idl/atsvc.idl @@ -2,6 +2,8 @@ atsvc interface definition */ +#include "idl_types.h" + [ uuid(1ff70682-0a51-30e8-076d-740be8cee98b), version(1.0), pointer_default(unique) diff --git a/source4/librpc/idl/dfs.idl b/source4/librpc/idl/dfs.idl index 8e8488e367..fd9e164ffa 100644 --- a/source4/librpc/idl/dfs.idl +++ b/source4/librpc/idl/dfs.idl @@ -2,6 +2,8 @@ dfs interface definition */ +#include "idl_types.h" + [ uuid(4fc742e0-4a10-11cf-8273-00aa004ae673), version(3.0), pointer_default(unique) diff --git a/source4/librpc/idl/echo.idl b/source4/librpc/idl/echo.idl index 38650e990d..e6d93e52c4 100644 --- a/source4/librpc/idl/echo.idl +++ b/source4/librpc/idl/echo.idl @@ -1,3 +1,6 @@ +#include "idl_types.h" + + [ uuid(60a15ec5-4de8-11d7-a637-005056a20182), version(1.0) diff --git a/source4/librpc/idl/epmapper.idl b/source4/librpc/idl/epmapper.idl new file mode 100644 index 0000000000..c58ceb1fc0 --- /dev/null +++ b/source4/librpc/idl/epmapper.idl @@ -0,0 +1,134 @@ +#include "idl_types.h" + +/* + endpoint mapper interface +*/ + +[ + uuid(e1af8308-5d1f-11c9-91a4-08002b14a0fa), + version(3.0), + pointer_default(unique) +] +interface epmapper +{ + + typedef struct { + GUID uuid; + uint16 version; + } epm_prot_uuid; + + typedef [nodiscriminant] union { + [case(13)] epm_prot_uuid uuid; + [default] ; + } epm_protocol_info; + + typedef struct { + uint8 protocol; + [switch_is(protocol)] epm_protocol_info info; + } epm_lhs; + + typedef struct { + uint16 unknown; + } epm_rhs; + + typedef struct { + [subcontext(2)] epm_lhs lhs; + [subcontext(2)] epm_rhs rhs; + } epm_floor; + + typedef [flag(NDR_NOALIGN)] struct { + uint16 num_floors; + epm_floor floors[num_floors]; + } epm_towers; + + typedef struct { + uint32 tower_length; + [subcontext(4)] epm_towers towers; + } twr_t; + + typedef struct { + GUID object; + twr_t *tower; + ascstr2 annotation; + } epm_entry_t; + + typedef struct { + GUID uuid; + uint16 vers_major; + uint16 vers_minor; + } rpc_if_id_t; + + /**********************/ + /* Function 0x0 */ + void epm_Insert( + [in] uint32 num_ents, + [in,size_is(num_ents)] epm_entry_t entries[], + [in] uint32 replace, + [out] uint32 *status + ); + + /**********************/ + /* Function 0x1 */ + void epm_Delete( + [in] uint32 num_ents, + [in, size_is(num_ents)] epm_entry_t entries[], + [out] uint32 *status + ); + + /**********************/ + /* Function 0x02 */ + void epm_Lookup( + [in] uint32 inquiry_type, + [in] GUID *object, + [in] rpc_if_id_t *interface_id, + [in] uint32 vers_option, + [in, out, ref] policy_handle *entry_handle, + [in] uint32 max_ents, + [out] uint32 num_ents, + [out, length_is(num_ents), size_is(max_ents)] epm_entry_t entries[], + [out] uint32 status + ); + + + /**********************/ + /* Function 0x03 */ + + typedef struct { + twr_t *twr; + } twr_p_t; + + void epm_Map( + [in] GUID *object, + [in] twr_t *map_tower, + [in, out] policy_handle *entry_handle, + [in] uint32 max_towers, + [out] uint32 *num_towers, + [out, length_is(*num_towers), size_is(max_towers)] twr_p_t towers[], + [out] uint32 *status + ); + + + /**********************/ + /* Function 0x04 */ + void epm_LookupHandleFree( + [in, out] policy_handle *entry_handle, + [out] uint32 *status + ); + + /**********************/ + /* Function 0x05 */ + void epm_InqObject( + [out] GUID *epm_object, + [out] uint32 *status + ); + + + /**********************/ + /* Function 0x05 */ + void epm_MgmtDelete( + [in] uint32 object_speced, + [in] GUID *object, + [in] twr_t *tower, + [out] uint32 *status + ); +} diff --git a/source4/librpc/idl/eventlog.idl b/source4/librpc/idl/eventlog.idl index a8eba4ae16..ee5bd8bba8 100644 --- a/source4/librpc/idl/eventlog.idl +++ b/source4/librpc/idl/eventlog.idl @@ -1,3 +1,5 @@ +#include "idl_types.h" + /* eventlog interface definition */ diff --git a/source4/librpc/idl/lsa.idl b/source4/librpc/idl/lsa.idl index 6aedd33b97..7b2de5bd8f 100644 --- a/source4/librpc/idl/lsa.idl +++ b/source4/librpc/idl/lsa.idl @@ -1,3 +1,5 @@ +#include "idl_types.h" + /* lsa interface definition */ @@ -54,7 +56,7 @@ typedef struct { uint32 size; - [subcontext] security_descriptor *sd; + [subcontext(4)] security_descriptor *sd; } sec_desc_buf; NTSTATUS lsa_QuerySecObj ( diff --git a/source4/librpc/idl/misc.idl b/source4/librpc/idl/misc.idl index 031ca89821..04e03fc814 100644 --- a/source4/librpc/idl/misc.idl +++ b/source4/librpc/idl/misc.idl @@ -1,3 +1,5 @@ +#include "idl_types.h" + /* miscellaneous IDL structures */ diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl index 29ba402503..bb0e85b7de 100644 --- a/source4/librpc/idl/samr.idl +++ b/source4/librpc/idl/samr.idl @@ -1,6 +1,7 @@ +#include "idl_types.h" + /* samr interface definition - */ /* @@ -44,7 +45,7 @@ typedef struct { uint32 sd_size; - [subcontext] security_descriptor *sd; + [subcontext(4)] security_descriptor *sd; } samr_SdBuf; NTSTATUS samr_QuerySecurity ( @@ -727,9 +728,26 @@ /* Function 0x2b */ NTSTATUS samr_TEST_PRIVATE_FUNCTIONS_USER(); + /************************/ /* Function 0x2c */ - NTSTATUS samr_GET_USRDOM_PWINFO(); + +/* +const ULONG DOMAIN_PASSWORD_COMPLEX = 0x00000001; +const ULONG DOMAIN_PASSWORD_NO_ANON_CHANGE = 0x00000002; +const ULONG DOMAIN_PASSWORD_NO_CLEAR_CHANGE = 0x00000004; +const ULONG DOMAIN_PASSWORD_STORE_CLEARTEXT = 0x00000010; +const ULONG DOMAIN_REFUSE_PASSWORD_CHANGE = 0x00000020; +*/ + typedef struct { + uint16 min_pwd_len; + uint32 passwd_properties; + } samr_PwInfo; + + NTSTATUS samr_GetUserPwInfo( + [in,ref] policy_handle *handle, + [out] samr_PwInfo info + ); /************************/ /* Function 0x2d */ diff --git a/source4/librpc/idl/spoolss.idl b/source4/librpc/idl/spoolss.idl index 586536b69c..a9d653458b 100644 --- a/source4/librpc/idl/spoolss.idl +++ b/source4/librpc/idl/spoolss.idl @@ -1,3 +1,5 @@ +#include "idl_types.h" + /* spoolss interface definitions */ @@ -179,7 +181,7 @@ [in,ref] policy_handle *handle, [in] uint32 level, [in] DATA_BLOB *buffer, - [out,subcontext,switch_is(level)] spoolss_PrinterInfo *info, + [out,subcontext(4),switch_is(level)] spoolss_PrinterInfo *info, [in,out,ref] uint32 *buf_size ); diff --git a/source4/librpc/idl/srvsvc.idl b/source4/librpc/idl/srvsvc.idl index 530b19d6cf..ac421d8626 100644 --- a/source4/librpc/idl/srvsvc.idl +++ b/source4/librpc/idl/srvsvc.idl @@ -1,3 +1,5 @@ +#include "idl_types.h" + /* srvsvc interface definitions */ @@ -302,7 +304,7 @@ unistr *path; uint32 *password; uint32 unknown; - [subcontext] security_descriptor *sd; + [subcontext(4)] security_descriptor *sd; } srvsvc_NetShare502; typedef struct { diff --git a/source4/librpc/idl/winreg.idl b/source4/librpc/idl/winreg.idl index 68b13f8245..84250a61a5 100644 --- a/source4/librpc/idl/winreg.idl +++ b/source4/librpc/idl/winreg.idl @@ -1,3 +1,5 @@ +#include "idl_types.h" + /* winreg interface definition */ diff --git a/source4/librpc/idl/wkssvc.idl b/source4/librpc/idl/wkssvc.idl index 2a1fb83f79..31e37d4759 100644 --- a/source4/librpc/idl/wkssvc.idl +++ b/source4/librpc/idl/wkssvc.idl @@ -1,3 +1,5 @@ +#include "idl_types.h" + /* wkssvc interface definitions */ diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h index 7876d3cc1c..5c771ff2d2 100644 --- a/source4/librpc/ndr/libndr.h +++ b/source4/librpc/ndr/libndr.h @@ -91,8 +91,15 @@ struct ndr_print { void *private; }; -#define LIBNDR_FLAG_BIGENDIAN 1 +#define LIBNDR_FLAG_BIGENDIAN (1<<0) +#define LIBNDR_FLAG_NOALIGN (1<<1) +#define LIBNDR_FLAG_STR_ASCII (1<<2) +#define LIBNDR_FLAG_STR_LEN4 (1<<3) +#define LIBNDR_FLAG_STR_SIZE4 (1<<4) +#define LIBNDR_FLAG_STR_NOTERM (1<<5) +#define LIBNDR_FLAG_STR_NULLTERM (1<<6) +#define LIBNDR_STRING_FLAGS (0x7C) /* useful macro for debugging */ #define NDR_PRINT_DEBUG(type, p) ndr_print_debug((ndr_print_fn_t)ndr_print_ ##type, #p, p) @@ -110,7 +117,9 @@ enum ndr_err_code { NDR_ERR_OFFSET, NDR_ERR_RELATIVE, NDR_ERR_CHARCNV, - NDR_ERR_LENGTH + NDR_ERR_LENGTH, + NDR_ERR_SUBCONTEXT, + NDR_ERR_STRING }; /* @@ -133,7 +142,9 @@ enum ndr_err_code { } while(0) #define NDR_PULL_ALIGN(ndr, n) do { \ - ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \ + if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { \ + ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \ + } \ if (ndr->offset >= ndr->data_size) { \ return NT_STATUS_BUFFER_TOO_SMALL; \ } \ @@ -142,8 +153,10 @@ enum ndr_err_code { #define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, ndr->offset+(n))) #define NDR_PUSH_ALIGN(ndr, n) do { \ - uint32 _pad = (ndr->offset & (n-1)); \ - while (_pad--) NDR_CHECK(ndr_push_uint8(ndr, 0)); \ + if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { \ + uint32 _pad = (ndr->offset & (n-1)); \ + while (_pad--) NDR_CHECK(ndr_push_uint8(ndr, 0)); \ + } \ } while(0) @@ -201,4 +214,5 @@ typedef void (*ndr_print_union_fn_t)(struct ndr_print *, const char *, uint32, v #include "librpc/gen_ndr/ndr_srvsvc.h" #include "librpc/gen_ndr/ndr_atsvc.h" #include "librpc/gen_ndr/ndr_eventlog.h" +#include "librpc/gen_ndr/ndr_epmapper.h" #include "librpc/gen_ndr/ndr_winreg.h" diff --git a/source4/librpc/ndr/ndr.c b/source4/librpc/ndr/ndr.c index 2f0754d78f..dcd0066083 100644 --- a/source4/librpc/ndr/ndr.c +++ b/source4/librpc/ndr/ndr.c @@ -61,6 +61,7 @@ NTSTATUS ndr_pull_subcontext(struct ndr_pull *ndr, struct ndr_pull *ndr2, uint32 ndr2->data += ndr2->offset; ndr2->offset = 0; ndr2->data_size = size; + ndr2->flags = ndr->flags; return NT_STATUS_OK; } @@ -396,57 +397,98 @@ NTSTATUS ndr_push_error(struct ndr_push *ndr, enum ndr_err_code err, const char } +/* + handle subcontext buffers, which in midl land are user-marshalled, but + we use magic in pidl to make them easier to cope with +*/ +static NTSTATUS ndr_pull_subcontext_header(struct ndr_pull *ndr, + size_t sub_size, + struct ndr_pull *ndr2) +{ + switch (sub_size) { + case 0: { + uint32 size = ndr->data_size - ndr->offset; + if (size == 0) return NT_STATUS_OK; + NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, size)); + break; + } + + case 2: { + uint16 size; + NDR_CHECK(ndr_pull_uint16(ndr, &size)); + if (size == 0) return NT_STATUS_OK; + NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, size)); + break; + } + + case 4: { + uint32 size; + NDR_CHECK(ndr_pull_uint32(ndr, &size)); + if (size == 0) return NT_STATUS_OK; + NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, size)); + break; + } + default: + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext size %d", + sub_size); + } + return NT_STATUS_OK; +} + /* handle subcontext buffers, which in midl land are user-marshalled, but we use magic in pidl to make them easier to cope with */ NTSTATUS ndr_pull_subcontext_fn(struct ndr_pull *ndr, + size_t sub_size, void *base, NTSTATUS (*fn)(struct ndr_pull *, void *)) { - uint32 size; struct ndr_pull ndr2; - NDR_CHECK(ndr_pull_uint32(ndr, &size)); - NDR_CHECK(ndr_pull_subcontext(ndr, &ndr2, size)); + NDR_CHECK(ndr_pull_subcontext_header(ndr, sub_size, &ndr2)); NDR_CHECK(fn(&ndr2, base)); - NDR_CHECK(ndr_pull_advance(ndr, size)); + if (sub_size) { + NDR_CHECK(ndr_pull_advance(ndr, ndr2.data_size)); + } else { + NDR_CHECK(ndr_pull_advance(ndr, ndr2.offset)); + } return NT_STATUS_OK; } NTSTATUS ndr_pull_subcontext_flags_fn(struct ndr_pull *ndr, + size_t sub_size, void *base, NTSTATUS (*fn)(struct ndr_pull *, int , void *)) { - uint32 size; struct ndr_pull ndr2; - NDR_CHECK(ndr_pull_uint32(ndr, &size)); - if (size == 0) { - return NT_STATUS_OK; - } - NDR_CHECK(ndr_pull_subcontext(ndr, &ndr2, size)); + NDR_CHECK(ndr_pull_subcontext_header(ndr, sub_size, &ndr2)); NDR_CHECK(fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, base)); - NDR_CHECK(ndr_pull_advance(ndr, size)); + if (sub_size) { + NDR_CHECK(ndr_pull_advance(ndr, ndr2.data_size)); + } else { + NDR_CHECK(ndr_pull_advance(ndr, ndr2.offset)); + } return NT_STATUS_OK; } NTSTATUS ndr_pull_subcontext_union_fn(struct ndr_pull *ndr, + size_t sub_size, uint32 level, void *base, NTSTATUS (*fn)(struct ndr_pull *, int , uint32 , void *)) { - uint32 size; struct ndr_pull ndr2; - NDR_CHECK(ndr_pull_uint32(ndr, &size)); - if (size == 0) { - return NT_STATUS_OK; - } - NDR_CHECK(ndr_pull_subcontext(ndr, &ndr2, size)); + NDR_CHECK(ndr_pull_subcontext_header(ndr, sub_size, &ndr2)); NDR_CHECK(fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, level, base)); - NDR_CHECK(ndr_pull_advance(ndr, size)); + if (sub_size) { + NDR_CHECK(ndr_pull_advance(ndr, ndr2.data_size)); + } else { + NDR_CHECK(ndr_pull_advance(ndr, ndr2.offset)); + } return NT_STATUS_OK; } diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c index 49cff11480..56c0ab231e 100644 --- a/source4/librpc/ndr/ndr_basic.c +++ b/source4/librpc/ndr/ndr_basic.c @@ -314,119 +314,219 @@ NTSTATUS ndr_push_ptr(struct ndr_push *ndr, const void *p) which means we can handle the case where a MS programmer forgot to mark a pointer as unique */ ndr->ptr_count++; - ptr = 0xaabbcc00 + ndr->ptr_count; + ptr = ndr->ptr_count; } return ndr_push_uint32(ndr, ptr); } -/* - push a comformant, variable ucs2 string onto the wire from a C string -*/ -NTSTATUS ndr_push_unistr(struct ndr_push *ndr, const char *s) -{ - char *ws; - ssize_t len; - len = push_ucs2_talloc(ndr->mem_ctx, (smb_ucs2_t **)&ws, s); - if (len == -1) { - return NT_STATUS_INVALID_PARAMETER; - } - NDR_CHECK(ndr_push_uint32(ndr, len/2)); - NDR_CHECK(ndr_push_uint32(ndr, 0)); - NDR_CHECK(ndr_push_uint32(ndr, len/2)); - NDR_CHECK(ndr_push_bytes(ndr, ws, len)); - return NT_STATUS_OK; -} /* - push a comformant, variable ascii string onto the wire from a C string - TODO: need to look at what charset this should be in + pull a general string from the wire */ -NTSTATUS ndr_push_ascstr(struct ndr_push *ndr, const char *s) +NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) { - ssize_t len = s?strlen(s):0; - NDR_CHECK(ndr_push_uint32(ndr, len)); - NDR_CHECK(ndr_push_uint32(ndr, 0)); - NDR_CHECK(ndr_push_uint32(ndr, len?len+1:0)); - if (s) { - NDR_CHECK(ndr_push_bytes(ndr, s, len)); + char *as=NULL; + uint32 len1, ofs, len2; + int ret; + + if (!(ndr_flags & NDR_SCALARS)) { + return NT_STATUS_OK; } - return NT_STATUS_OK; -} -/* - push a comformant, variable ucs2 string onto the wire from a C string - don't send the null -*/ -NTSTATUS ndr_push_unistr_noterm(struct ndr_push *ndr, const char *s) -{ - char *ws; - ssize_t len; - len = push_ucs2_talloc(ndr->mem_ctx, (smb_ucs2_t **)&ws, s); - if (len == -1) { - return NT_STATUS_INVALID_PARAMETER; + switch (ndr->flags & LIBNDR_STRING_FLAGS) { + case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: + case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM: + NDR_CHECK(ndr_pull_uint32(ndr, &len1)); + NDR_CHECK(ndr_pull_uint32(ndr, &ofs)); + NDR_CHECK(ndr_pull_uint32(ndr, &len2)); + if (len2 > len1) { + return NT_STATUS_INVALID_PARAMETER; + } + if (len2 == 0) { + *s = talloc_strdup(ndr->mem_ctx, ""); + break; + } + NDR_PULL_NEED_BYTES(ndr, len2*2); + ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, + ndr->data+ndr->offset, + len2*2, + (const void **)&as); + if (ret == -1) { + return ndr_pull_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + NDR_CHECK(ndr_pull_advance(ndr, len2*2)); + *s = as; + break; + + case LIBNDR_FLAG_STR_SIZE4: + NDR_CHECK(ndr_pull_uint32(ndr, &len1)); + NDR_PULL_NEED_BYTES(ndr, len1*2); + if (len1 == 0) { + *s = talloc_strdup(ndr->mem_ctx, ""); + break; + } + ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, + ndr->data+ndr->offset, + len1*2, + (const void **)&as); + if (ret == -1) { + return ndr_pull_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + NDR_CHECK(ndr_pull_advance(ndr, len1*2)); + *s = as; + break; + + case LIBNDR_FLAG_STR_NULLTERM: + ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, + ndr->data+ndr->offset, + ndr->data_size - ndr->offset, + (const void **)s); + if (ret == -1) { + return ndr_pull_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + NDR_CHECK(ndr_pull_advance(ndr, ret)); + break; + + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: + NDR_CHECK(ndr_pull_uint32(ndr, &len1)); + NDR_CHECK(ndr_pull_uint32(ndr, &ofs)); + NDR_CHECK(ndr_pull_uint32(ndr, &len2)); + if (len2 > len1) { + return NT_STATUS_INVALID_PARAMETER; + } + NDR_ALLOC_N(ndr, as, (len2+1)); + NDR_CHECK(ndr_pull_bytes(ndr, as, len2)); + as[len2] = 0; + (*s) = as; + break; + + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4: + NDR_CHECK(ndr_pull_uint32(ndr, &ofs)); + NDR_CHECK(ndr_pull_uint32(ndr, &len2)); + NDR_ALLOC_N(ndr, as, (len2+1)); + NDR_CHECK(ndr_pull_bytes(ndr, as, len2)); + as[len2] = 0; + (*s) = as; + break; + + default: + return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n", + ndr->flags & LIBNDR_STRING_FLAGS); } - NDR_CHECK(ndr_push_uint32(ndr, len/2 - 1)); - NDR_CHECK(ndr_push_uint32(ndr, 0)); - NDR_CHECK(ndr_push_uint32(ndr, len/2 - 1)); - NDR_CHECK(ndr_push_bytes(ndr, ws, len - 2)); + return NT_STATUS_OK; } + /* - pull a comformant, variable ucs2 string from the wire into a C string + push a general string onto the wire */ -NTSTATUS ndr_pull_unistr(struct ndr_pull *ndr, const char **s) +NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s) { - char *ws, *as=NULL; - uint32 len1, ofs, len2; + ssize_t s_len, c_len; + int ret; - NDR_CHECK(ndr_pull_uint32(ndr, &len1)); - NDR_CHECK(ndr_pull_uint32(ndr, &ofs)); - NDR_CHECK(ndr_pull_uint32(ndr, &len2)); - if (len2 > len1) { - return NT_STATUS_INVALID_PARAMETER; - } - NDR_ALLOC_N(ndr, ws, (len1+1)*2); - NDR_CHECK(ndr_pull_bytes(ndr, ws, len2*2)); - SSVAL(ws, len1*2, 0); - SSVAL(ws, len2*2, 0); - pull_ucs2_talloc(ndr->mem_ctx, &as, (const smb_ucs2_t *)ws); - if (!as) { - return NT_STATUS_INVALID_PARAMETER; + if (!(ndr_flags & NDR_SCALARS)) { + return NT_STATUS_OK; } - *s = as; - return NT_STATUS_OK; -} + + s_len = s?strlen(s):0; + c_len = s?strlen_m(s):0; -/* - pull a comformant, variable ascii string from the wire into a C string - TODO: check what charset this is in -*/ -NTSTATUS ndr_pull_ascstr(struct ndr_pull *ndr, const char **s) -{ - uint32 len1, ofs, len2; - char *as; + switch (ndr->flags & LIBNDR_STRING_FLAGS) { + case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: + NDR_CHECK(ndr_push_uint32(ndr, c_len+1)); + NDR_CHECK(ndr_push_uint32(ndr, 0)); + NDR_CHECK(ndr_push_uint32(ndr, c_len+1)); + NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2); + ret = convert_string(CH_UNIX, CH_UCS2, + s, s_len+1, + ndr->data+ndr->offset, c_len*2 + 2); + if (ret == -1) { + return ndr_push_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr->offset += c_len*2 + 2; + break; + + case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM: + NDR_CHECK(ndr_push_uint32(ndr, c_len)); + NDR_CHECK(ndr_push_uint32(ndr, 0)); + NDR_CHECK(ndr_push_uint32(ndr, c_len)); + NDR_PUSH_NEED_BYTES(ndr, c_len*2); + ret = convert_string(CH_UNIX, CH_UCS2, + s, s_len, + ndr->data+ndr->offset, c_len*2); + if (ret == -1) { + return ndr_push_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr->offset += c_len*2; + break; + + case LIBNDR_FLAG_STR_SIZE4: + NDR_CHECK(ndr_push_uint32(ndr, c_len + 1)); + NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2); + ret = convert_string(CH_UNIX, CH_UCS2, + s, s_len + 1, + ndr->data+ndr->offset, c_len*2 + 2); + if (ret == -1) { + return ndr_push_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr->offset += c_len*2 + 2; + break; + + case LIBNDR_FLAG_STR_NULLTERM: + NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2); + ret = convert_string(CH_UNIX, CH_UCS2, + s, s_len+1, + ndr->data+ndr->offset, c_len*2 + 2); + if (ret == -1) { + return ndr_push_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr->offset += c_len*2 + 2; + break; + + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: + NDR_CHECK(ndr_push_uint32(ndr, c_len+1)); + NDR_CHECK(ndr_push_uint32(ndr, 0)); + NDR_CHECK(ndr_push_uint32(ndr, c_len+1)); + NDR_PUSH_NEED_BYTES(ndr, c_len + 1); + ret = convert_string(CH_UNIX, CH_DOS, + s, s_len + 1, + ndr->data+ndr->offset, c_len + 1); + if (ret == -1) { + return ndr_push_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr->offset += c_len + 1; + break; + + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4: + NDR_CHECK(ndr_push_uint32(ndr, 0)); + NDR_CHECK(ndr_push_uint32(ndr, c_len+1)); + NDR_PUSH_NEED_BYTES(ndr, c_len + 1); + ret = convert_string(CH_UNIX, CH_DOS, + s, s_len + 1, + ndr->data+ndr->offset, c_len + 1); + if (ret == -1) { + return ndr_push_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr->offset += c_len + 1; + break; - NDR_CHECK(ndr_pull_uint32(ndr, &len1)); - NDR_CHECK(ndr_pull_uint32(ndr, &ofs)); - NDR_CHECK(ndr_pull_uint32(ndr, &len2)); - if (len2 > len1) { - return NT_STATUS_INVALID_PARAMETER; + default: + return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n", + ndr->flags & LIBNDR_STRING_FLAGS); } - NDR_ALLOC_N(ndr, as, (len1+1)); - NDR_CHECK(ndr_pull_bytes(ndr, as, len2)); - as[len2] = 0; - as[len1] = 0; - (*s) = as; - return NT_STATUS_OK; -} -/* - pull a comformant, variable ucs2 string from the wire into a C string -*/ -NTSTATUS ndr_pull_unistr_noterm(struct ndr_pull *ndr, const char **s) -{ - return ndr_pull_unistr(ndr, s); + return NT_STATUS_OK; } /* @@ -523,7 +623,7 @@ void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p) } } -void ndr_print_unistr(struct ndr_print *ndr, const char *name, const char *s) +void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s) { if (s) { ndr->print(ndr, "%-25s: '%s'", name, s); @@ -532,16 +632,6 @@ void ndr_print_unistr(struct ndr_print *ndr, const char *name, const char *s) } } -void ndr_print_unistr_noterm(struct ndr_print *ndr, const char *name, const char *s) -{ - ndr_print_unistr(ndr, name, s); -} - -void ndr_print_ascstr(struct ndr_print *ndr, const char *name, const char *s) -{ - ndr_print_unistr(ndr, name, s); -} - void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t) { ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr->mem_ctx, &t)); @@ -603,122 +693,6 @@ void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID * guid->info[14], guid->info[15]); } - -/* - pull a null terminated UCS2 string -*/ -NTSTATUS ndr_pull_nstring(struct ndr_pull *ndr, int ndr_flags, const char **s) -{ - int ret; - - if (!(ndr_flags & NDR_SCALARS)) { - return NT_STATUS_OK; - } - - ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, - ndr->data+ndr->offset, - ndr->data_size - ndr->offset, - (const void **)s); - if (ret == -1) { - return ndr_pull_error(ndr, NDR_ERR_CHARCNV, "Bad character conversion"); - } - ndr->offset += ret; - return NT_STATUS_OK; -} - -/* - pull a length prefixed UCS2 string -*/ -NTSTATUS ndr_pull_lstring(struct ndr_pull *ndr, int ndr_flags, const char **s) -{ - int ret; - uint32 size; - - if (!(ndr_flags & NDR_SCALARS)) { - return NT_STATUS_OK; - } - - NDR_CHECK(ndr_pull_uint32(ndr, &size)); - if (size == 0) { - *s = NULL; - return NT_STATUS_OK; - } - - NDR_PULL_NEED_BYTES(ndr, size*2); - - ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, - ndr->data+ndr->offset, - size*2, - (const void **)s); - if (ret == -1) { - return ndr_pull_error(ndr, NDR_ERR_CHARCNV, "Bad character conversion"); - } - ndr->offset += size*2; - return NT_STATUS_OK; -} - -/* - push a spoolss style "relative string" -*/ -NTSTATUS ndr_push_nstring(struct ndr_push *ndr, int ndr_flags, const char **s) -{ - uint32 len; - int ret; - - if (!(ndr_flags & NDR_SCALARS)) { - return NT_STATUS_OK; - } - - len = 2*(strlen_m(*s)+1); - NDR_PUSH_NEED_BYTES(ndr, len); - ret = push_ucs2(NULL, ndr->data + ndr->offset, *s, len, STR_TERMINATE); - if (ret == -1) { - return ndr_push_error(ndr, NDR_ERR_CHARCNV, "Bad string conversion"); - } - ndr->offset += len; - return NT_STATUS_OK; -} - -/* - push a length prefixed ucs2 string -*/ -NTSTATUS ndr_push_lstring(struct ndr_push *ndr, int ndr_flags, const char **s) -{ - uint32 len; - int ret; - - if (!(ndr_flags & NDR_SCALARS)) { - return NT_STATUS_OK; - } - - if (! *s) { - NDR_CHECK(ndr_push_uint32(ndr, 0)); - return NT_STATUS_OK; - } - - len = (strlen_m(*s)+1); - - NDR_CHECK(ndr_push_uint32(ndr, len)); - NDR_PUSH_NEED_BYTES(ndr, len*2); - - ret = push_ucs2(NULL, ndr->data + ndr->offset, *s, len*2, STR_TERMINATE); - if (ret == -1) { - return ndr_push_error(ndr, NDR_ERR_CHARCNV, "Bad string conversion"); - } - ndr->offset += len*2; - return NT_STATUS_OK; -} - -void ndr_print_nstring(struct ndr_print *ndr, const char *name, const char **s) -{ - ndr_print_unistr(ndr, name, *s); -} - -void ndr_print_lstring(struct ndr_print *ndr, const char *name, const char **s) -{ - ndr_print_unistr(ndr, name, *s); -} - void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r) { ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, r.length); diff --git a/source4/torture/rpc/epmapper.c b/source4/torture/rpc/epmapper.c new file mode 100644 index 0000000000..0e4e5e04f6 --- /dev/null +++ b/source4/torture/rpc/epmapper.c @@ -0,0 +1,87 @@ +/* + Unix SMB/CIFS implementation. + test suite for epmapper rpc operations + + Copyright (C) Andrew Tridgell 2003 + + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + + +static BOOL test_Lookup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + struct epm_Lookup r; + struct GUID uuid; + struct rpc_if_id_t iface; + struct policy_handle handle; + + ZERO_STRUCT(uuid); + ZERO_STRUCT(iface); + ZERO_STRUCT(handle); + + r.in.inquiry_type = 0; + r.in.object = &uuid; + r.in.interface_id = &iface; + r.in.vers_option = 0; + r.in.entry_handle = &handle; + r.out.entry_handle = &handle; + r.in.max_ents = 1; + + do { + status = dcerpc_epm_Lookup(p, mem_ctx, &r); + if (NT_STATUS_IS_OK(status) && r.out.status == 0) { + printf("Found '%s'\n", r.out.entries[0].annotation); + } + } while (NT_STATUS_IS_OK(status) && r.out.status == 0); + + if (!NT_STATUS_IS_OK(status)) { + printf("Lookup failed - %s\n", nt_errstr(status)); + return False; + } + + + return True; +} + +BOOL torture_rpc_epmapper(int dummy) +{ + NTSTATUS status; + struct dcerpc_pipe *p; + TALLOC_CTX *mem_ctx; + BOOL ret = True; + + mem_ctx = talloc_init("torture_rpc_epmapper"); + + status = torture_rpc_connection(&p, + DCERPC_EPMAPPER_NAME, + DCERPC_EPMAPPER_UUID, + DCERPC_EPMAPPER_VERSION); + if (!NT_STATUS_IS_OK(status)) { + return False; + } + + p->flags |= DCERPC_DEBUG_PRINT_BOTH; + + if (!test_Lookup(p, mem_ctx)) { + ret = False; + } + + torture_rpc_close(p); + + return ret; +} diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 047da518b3..d825ddb02c 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -202,6 +202,26 @@ static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return ret; } +static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, + struct policy_handle *handle) +{ + NTSTATUS status; + struct samr_GetUserPwInfo r; + BOOL ret = True; + + printf("Testing GetUserPwInfo\n"); + + r.in.handle = handle; + + status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) { + printf("GetUserPwInfo failed - %s\n", nt_errstr(status)); + ret = False; + } + + return ret; +} + static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle) @@ -220,6 +240,10 @@ static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, ret = False; } + if (!test_GetUserPwInfo(p, mem_ctx, handle)) { + ret = False; + } + return ret; } @@ -434,6 +458,10 @@ static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, ret = False; } + if (!test_GetUserPwInfo(p, mem_ctx, &acct_handle)) { + ret = False; + } + if (!test_Close(p, mem_ctx, &acct_handle)) { ret = False; } diff --git a/source4/torture/torture.c b/source4/torture/torture.c index 25602e3a83..105abcf9eb 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -3996,6 +3996,7 @@ static struct { {"RPC-SRVSVC", torture_rpc_srvsvc, 0}, {"RPC-ATSVC", torture_rpc_atsvc, 0}, {"RPC-EVENTLOG", torture_rpc_eventlog, 0}, + {"RPC-EPMAPPER", torture_rpc_epmapper, 0}, {"RPC-WINREG", torture_rpc_winreg, 0}, {NULL, NULL, 0}}; -- cgit