diff options
-rw-r--r-- | source4/build/pidl/client.pm | 6 | ||||
-rw-r--r-- | source4/build/pidl/parser.pm | 183 | ||||
-rw-r--r-- | source4/librpc/idl/samr.idl | 10 | ||||
-rw-r--r-- | source4/librpc/ndr/libndr.h | 35 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr.c | 163 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_basic.c | 24 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_sec.c | 50 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 160 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc.h | 6 | ||||
-rw-r--r-- | source4/torture/rpc/atsvc.c | 2 | ||||
-rw-r--r-- | source4/torture/rpc/dfs.c | 2 | ||||
-rw-r--r-- | source4/torture/rpc/echo.c | 2 | ||||
-rw-r--r-- | source4/torture/rpc/epmapper.c | 2 | ||||
-rw-r--r-- | source4/torture/rpc/eventlog.c | 2 | ||||
-rw-r--r-- | source4/torture/rpc/lsa.c | 4 | ||||
-rw-r--r-- | source4/torture/rpc/samr.c | 6 | ||||
-rw-r--r-- | source4/torture/rpc/spoolss.c | 2 | ||||
-rw-r--r-- | source4/torture/rpc/srvsvc.c | 2 | ||||
-rw-r--r-- | source4/torture/rpc/winreg.c | 2 | ||||
-rw-r--r-- | source4/torture/rpc/wkssvc.c | 2 |
20 files changed, 565 insertions, 100 deletions
diff --git a/source4/build/pidl/client.pm b/source4/build/pidl/client.pm index 63a8c7c405..b0c78d7b3a 100644 --- a/source4/build/pidl/client.pm +++ b/source4/build/pidl/client.pm @@ -29,9 +29,9 @@ NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name * } status = dcerpc_ndr_request(p, DCERPC_$uname, mem_ctx, - (ndr_push_fn_t) ndr_push_$name, - (ndr_pull_fn_t) ndr_pull_$name, - r); + (ndr_push_flags_fn_t) ndr_push_$name, + (ndr_pull_flags_fn_t) ndr_pull_$name, + r, sizeof(*r)); if (NT_STATUS_IS_OK(status) && (p->flags & DCERPC_DEBUG_PRINT_OUT)) { NDR_PRINT_OUT_DEBUG($name, r); diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm index 2ed5fd27db..79ee93509d 100644 --- a/source4/build/pidl/parser.pm +++ b/source4/build/pidl/parser.pm @@ -285,12 +285,21 @@ sub ParseArrayPull($$$) pidl "\t}\n"; } - if (util::need_alloc($e) && !util::is_fixed_array($e)) { + if ((util::need_alloc($e) && !util::is_fixed_array($e)) || + ($var_prefix eq "r->in." && util::has_property($e, "ref"))) { if (!util::is_inline_array($e) || $ndr_flags eq "NDR_SCALARS") { pidl "\t\tNDR_ALLOC_N_SIZE(ndr, $var_prefix$e->{NAME}, $alloc_size, sizeof($var_prefix$e->{NAME}\[0]));\n"; } } + if (($var_prefix eq "r->out." && util::has_property($e, "ref"))) { + if (!util::is_inline_array($e) || $ndr_flags eq "NDR_SCALARS") { + pidl "\tif (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {"; + pidl "\t\tNDR_ALLOC_N_SIZE(ndr, $var_prefix$e->{NAME}, $alloc_size, sizeof($var_prefix$e->{NAME}\[0]));\n"; + pidl "\t}\n"; + } + } + pidl "\t{\n"; if (my $length = util::has_property($e, "length_is")) { @@ -321,6 +330,7 @@ sub ParseElementPushScalar($$$) my($var_prefix) = shift; my($ndr_flags) = shift; my $cprefix = util::c_push_prefix($e); + my $sub_size = util::has_property($e, "subcontext"); start_flags($e); @@ -334,8 +344,16 @@ sub ParseElementPushScalar($$$) pidl "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $e->{VALUE}));\n"; } elsif (util::need_wire_pointer($e)) { pidl "\tNDR_CHECK(ndr_push_ptr(ndr, $var_prefix$e->{NAME}));\n"; + } elsif (util::need_alloc($e)) { + # no scalar component } elsif (my $switch = util::has_property($e, "switch_is")) { ParseElementPushSwitch($e, $var_prefix, $ndr_flags, $switch); + } elsif (defined $sub_size) { + if (util::is_builtin_type($e->{TYPE})) { + pidl "\tNDR_CHECK(ndr_push_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_push_fn_t) ndr_pull_$e->{TYPE}));\n"; + } else { + pidl "\tNDR_CHECK(ndr_push_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_push_flags_fn_t) ndr_push_$e->{TYPE}));\n"; + } } elsif (util::is_builtin_type($e->{TYPE})) { pidl "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n"; } else { @@ -494,6 +512,7 @@ sub ParseElementPushBuffer($$$) my($var_prefix) = shift; my($ndr_flags) = shift; my $cprefix = util::c_push_prefix($e); + my $sub_size = util::has_property($e, "subcontext"); if (util::is_pure_scalar($e)) { return; @@ -517,6 +536,14 @@ sub ParseElementPushBuffer($$$) } else { ParseElementPushSwitch($e, $var_prefix, "NDR_BUFFERS", $switch); } + } elsif (defined $sub_size) { + if ($e->{POINTERS}) { + if (util::is_builtin_type($e->{TYPE})) { + pidl "\tNDR_CHECK(ndr_push_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_push_fn_t) ndr_push_$e->{TYPE}));\n"; + } else { + pidl "\tNDR_CHECK(ndr_push_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_push_flags_fn_t) ndr_push_$e->{TYPE}));\n"; + } + } } elsif (util::is_builtin_type($e->{TYPE})) { pidl "\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n"; } elsif ($e->{POINTERS}) { @@ -652,14 +679,14 @@ sub ParseStructPush($) ParseElementPushScalar($e, "r->", "NDR_SCALARS"); } - pidl "\tndr_push_struct_end(ndr);\n"; - pidl "buffers:\n"; pidl "\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n"; foreach my $e (@{$struct->{ELEMENTS}}) { ParseElementPushBuffer($e, "r->", "NDR_BUFFERS"); } + pidl "\tndr_push_struct_end(ndr);\n"; + pidl "done:\n"; end_flags($struct); @@ -715,14 +742,14 @@ sub ParseStructPull($) } } + pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; + pidl "\tNDR_CHECK(ndr_pull_struct_start(ndr));\n"; if (defined $conform_e) { pidl "\tNDR_CHECK(ndr_pull_uint32(ndr, &$conform_e->{CONFORMANT_SIZE}));\n"; } - pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n"; - my $align = struct_alignment($struct); pidl "\tNDR_CHECK(ndr_pull_align(ndr, $align));\n"; @@ -730,14 +757,14 @@ sub ParseStructPull($) ParseElementPullScalar($e, "r->", "NDR_SCALARS"); } - pidl "\tndr_pull_struct_end(ndr);\n"; - pidl "buffers:\n"; pidl "\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n"; foreach my $e (@{$struct->{ELEMENTS}}) { ParseElementPullBuffer($e, "r->", "NDR_BUFFERS"); } + pidl "\tndr_pull_struct_end(ndr);\n"; + pidl "done:\n"; end_flags($struct); @@ -754,6 +781,7 @@ sub ParseUnionPush($) 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); @@ -777,7 +805,6 @@ sub ParseUnionPush($) pidl "\t\treturn ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n"; } pidl "\t}\n"; - pidl "\tndr_push_struct_end(ndr);\n"; pidl "buffers:\n"; pidl "\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n"; pidl "\tswitch (level) {\n"; @@ -797,6 +824,7 @@ sub ParseUnionPush($) pidl "\t\treturn ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n"; } pidl "\t}\n"; + pidl "\tndr_push_struct_end(ndr);\n"; pidl "done:\n"; end_flags($e); } @@ -865,7 +893,6 @@ sub ParseUnionPull($) pidl "\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n"; } pidl "\t}\n"; - pidl "\tndr_pull_struct_end(ndr);\n"; pidl "buffers:\n"; pidl "\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n"; pidl "\tswitch (level) {\n"; @@ -885,6 +912,7 @@ sub ParseUnionPull($) pidl "\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n"; } pidl "\t}\n"; + pidl "\tndr_pull_struct_end(ndr);\n"; pidl "done:\n"; end_flags($e); } @@ -1056,70 +1084,121 @@ sub ParseFunctionPrint($) ##################################################################### +# parse a function element +sub ParseFunctionElementPush($$) +{ + my $e = shift; + my $inout = shift; + + if (util::array_size($e)) { + if (util::need_wire_pointer($e)) { + pidl "\tNDR_CHECK(ndr_push_ptr(ndr, r->$inout.$e->{NAME}));\n"; + } + pidl "\tif (r->$inout.$e->{NAME}) {\n"; + ParseArrayPush($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS"); + pidl "\t}\n"; + } else { + ParseElementPushScalar($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS"); + if ($e->{POINTERS}) { + ParseElementPushBuffer($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS"); + } + } +} + +##################################################################### # parse a function sub ParseFunctionPush($) { - my($function) = shift; + my($fn) = shift; - # Input function - pidl "NTSTATUS ndr_push_$function->{NAME}(struct ndr_push *ndr, struct $function->{NAME} *r)\n{\n"; + pidl "NTSTATUS ndr_push_$fn->{NAME}(struct ndr_push *ndr, int flags, struct $fn->{NAME} *r)\n{\n"; - foreach my $e (@{$function->{DATA}}) { + pidl "\n\tif (!(flags & NDR_IN)) goto ndr_out;\n\n"; + foreach my $e (@{$fn->{DATA}}) { if (util::has_property($e, "in")) { - if (util::array_size($e)) { - if (util::need_wire_pointer($e)) { - pidl "\tNDR_CHECK(ndr_push_ptr(ndr, r->in.$e->{NAME}));\n"; - } - pidl "\tif (r->in.$e->{NAME}) {\n"; - ParseArrayPush($e, "r->in.", "NDR_SCALARS|NDR_BUFFERS"); - pidl "\t}\n"; - } else { - ParseElementPushScalar($e, "r->in.", "NDR_SCALARS|NDR_BUFFERS"); - if ($e->{POINTERS}) { - ParseElementPushBuffer($e, "r->in.", "NDR_SCALARS|NDR_BUFFERS"); - } - } - } + ParseFunctionElementPush($e, "in"); + } + } + + pidl "\nndr_out:\n"; + pidl "\tif (!(flags & NDR_OUT)) goto done;\n\n"; + foreach my $e (@{$fn->{DATA}}) { + if (util::has_property($e, "out")) { + ParseFunctionElementPush($e, "out"); + } + } + + if ($fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") { + pidl "\tNDR_CHECK(ndr_push_$fn->{RETURN_TYPE}(ndr, r->out.result));\n"; } + pidl "\ndone:\n"; pidl "\n\treturn NT_STATUS_OK;\n}\n\n"; } ##################################################################### +# parse a function element +sub ParseFunctionElementPull($$) +{ + my $e = shift; + my $inout = shift; + + if (util::array_size($e)) { + if (util::need_wire_pointer($e)) { + pidl "\tNDR_CHECK(ndr_pull_uint32(ndr, _ptr_$e->{NAME}));\n"; + pidl "\tif (_ptr_$e->{NAME}) {\n"; + } elsif ($inout eq "in" && util::has_property($e, "ref")) { + pidl "\t{\n"; + } else { + pidl "\tif (r->$inout.$e->{NAME}) {\n"; + } + ParseArrayPull($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS"); + pidl "\t}\n"; + } else { + if ($inout eq "out" && util::has_property($e, "ref")) { + pidl "\tif (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {\n"; + pidl "\tNDR_ALLOC(ndr, r->out.$e->{NAME});\n"; + pidl "\t}\n"; + } + if ($inout eq "in" && util::has_property($e, "ref")) { + pidl "\tNDR_ALLOC(ndr, r->in.$e->{NAME});\n"; + } + + ParseElementPullScalar($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS"); + if ($e->{POINTERS}) { + ParseElementPullBuffer($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS"); + } + } +} + +##################################################################### # parse a function sub ParseFunctionPull($) { my($fn) = shift; # pull function args - pidl "NTSTATUS ndr_pull_$fn->{NAME}(struct ndr_pull *ndr, struct $fn->{NAME} *r)\n{\n"; + pidl "NTSTATUS ndr_pull_$fn->{NAME}(struct ndr_pull *ndr, int flags, struct $fn->{NAME} *r)\n{\n"; # declare any internal pointers we need foreach my $e (@{$fn->{DATA}}) { - if (util::has_property($e, "out")) { - if (util::need_wire_pointer($e)) { - pidl "\tuint32 _ptr_$e->{NAME};\n"; - } + if (util::need_wire_pointer($e)) { + pidl "\tuint32 _ptr_$e->{NAME};\n"; + } + } + + pidl "\n\tif (!(flags & NDR_IN)) goto ndr_out;\n\n"; + foreach my $e (@{$fn->{DATA}}) { + if (util::has_property($e, "in")) { + ParseFunctionElementPull($e, "in"); } } + pidl "\nndr_out:\n"; + pidl "\tif (!(flags & NDR_OUT)) goto done;\n\n"; foreach my $e (@{$fn->{DATA}}) { if (util::has_property($e, "out")) { - if (util::array_size($e)) { - if (util::need_wire_pointer($e)) { - pidl "\tNDR_CHECK(ndr_pull_uint32(ndr, _ptr_$e->{NAME}));\n"; - pidl "\tif (_ptr_$e->{NAME}) {\n"; - } else { - pidl "\tif (r->out.$e->{NAME}) {\n"; - } - ParseArrayPull($e, "r->out.", "NDR_SCALARS|NDR_BUFFERS"); - pidl "\t}\n"; - } else { - ParseElementPullScalar($e, "r->out.", "NDR_SCALARS|NDR_BUFFERS"); - if ($e->{POINTERS}) { - ParseElementPullBuffer($e, "r->out.", "NDR_SCALARS|NDR_BUFFERS"); - } - } + ParseFunctionElementPull($e, "out"); } } @@ -1127,7 +1206,7 @@ sub ParseFunctionPull($) pidl "\tNDR_CHECK(ndr_pull_$fn->{RETURN_TYPE}(ndr, &r->out.result));\n"; } - + pidl "\ndone:\n"; pidl "\n\treturn NT_STATUS_OK;\n}\n\n"; } @@ -1177,12 +1256,8 @@ sub NeededFunction($) $needed{"push_$fn->{NAME}"} = 1; foreach my $e (@{$fn->{DATA}}) { $e->{PARENT} = $fn; - if (util::has_property($e, "out")) { - $needed{"pull_$e->{TYPE}"} = 1; - } - if (util::has_property($e, "in")) { - $needed{"push_$e->{TYPE}"} = 1; - } + $needed{"pull_$e->{TYPE}"} = 1; + $needed{"push_$e->{TYPE}"} = 1; } } diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl index bb0e85b7de..f73ad9a8ea 100644 --- a/source4/librpc/idl/samr.idl +++ b/source4/librpc/idl/samr.idl @@ -44,7 +44,7 @@ /* Function: 0x03 */ typedef struct { - uint32 sd_size; + [value(ndr_size_security_descriptor(r->sd))] uint32 sd_size; [subcontext(4)] security_descriptor *sd; } samr_SdBuf; @@ -91,7 +91,7 @@ [in,out,ref] uint32 *resume_handle, [in] uint32 buf_size, [out] samr_SamArray *sam, - [out,ref] uint32 *num_entries + [out] uint32 num_entries ); @@ -224,7 +224,7 @@ [in,out,ref] uint32 *resume_handle, [in] uint32 max_size, [out] samr_SamArray *sam, - [out,ref] uint32 num_entries + [out] uint32 num_entries ); /************************/ @@ -245,7 +245,7 @@ [in] uint32 acct_flags, [in] uint32 max_size, [out] samr_SamArray *sam, - [out,ref] uint32 num_entries + [out] uint32 num_entries ); /************************/ @@ -259,7 +259,7 @@ [in,out,ref] uint32 *resume_handle, [in] uint32 max_size, [out] samr_SamArray *sam, - [out,ref] uint32 num_entries + [out] uint32 num_entries ); /************************/ diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h index 5c771ff2d2..3c77646239 100644 --- a/source4/librpc/ndr/libndr.h +++ b/source4/librpc/ndr/libndr.h @@ -73,7 +73,7 @@ struct ndr_push { struct ndr_ofs_list *ofs_list; /* this list is used by the [relative] code to find the offsets */ - struct ndr_ofs_list *relative_list; + struct ndr_ofs_list *relative_list, *relative_list_end; }; struct ndr_push_save { @@ -101,6 +101,8 @@ struct ndr_print { #define LIBNDR_FLAG_STR_NULLTERM (1<<6) #define LIBNDR_STRING_FLAGS (0x7C) +#define LIBNDR_FLAG_REF_ALLOC (1<<10) + /* useful macro for debugging */ #define NDR_PRINT_DEBUG(type, p) ndr_print_debug((ndr_print_fn_t)ndr_print_ ##type, #p, p) #define NDR_PRINT_UNION_DEBUG(type, level, p) ndr_print_union_debug((ndr_print_union_fn_t)ndr_print_ ##type, #p, level, p) @@ -119,7 +121,10 @@ enum ndr_err_code { NDR_ERR_CHARCNV, NDR_ERR_LENGTH, NDR_ERR_SUBCONTEXT, - NDR_ERR_STRING + NDR_ERR_STRING, + NDR_ERR_VALIDATE, + NDR_ERR_BUFSIZE, + NDR_ERR_ALLOC }; /* @@ -137,7 +142,7 @@ enum ndr_err_code { #define NDR_PULL_NEED_BYTES(ndr, n) do { \ if ((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size) { \ - return NT_STATUS_BUFFER_TOO_SMALL; \ + return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "Pull bytes %u", n); \ } \ } while(0) @@ -146,7 +151,7 @@ enum ndr_err_code { ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \ } \ if (ndr->offset >= ndr->data_size) { \ - return NT_STATUS_BUFFER_TOO_SMALL; \ + return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "Pull align %u", n); \ } \ } while(0) @@ -154,7 +159,7 @@ enum ndr_err_code { #define NDR_PUSH_ALIGN(ndr, n) do { \ if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { \ - uint32 _pad = (ndr->offset & (n-1)); \ + uint32 _pad = ((ndr->offset + (n-1)) & ~(n-1)) - ndr->offset; \ while (_pad--) NDR_CHECK(ndr_push_uint8(ndr, 0)); \ } \ } while(0) @@ -171,7 +176,9 @@ enum ndr_err_code { #define NDR_ALLOC_SIZE(ndr, s, size) do { \ (s) = talloc(ndr->mem_ctx, size); \ - if (!(s)) return NT_STATUS_NO_MEMORY; \ + if (!(s)) return ndr_pull_error(ndr, NDR_ERR_ALLOC, \ + "Alloc %u failed\n", \ + size); \ } while (0) #define NDR_ALLOC(ndr, s) NDR_ALLOC_SIZE(ndr, s, sizeof(*(s))) @@ -182,12 +189,26 @@ enum ndr_err_code { (s) = NULL; \ } else { \ (s) = talloc(ndr->mem_ctx, (n) * elsize); \ - if (!(s)) return NT_STATUS_NO_MEMORY; \ + if (!(s)) return ndr_pull_error(ndr, \ + NDR_ERR_ALLOC, \ + "Alloc %u * %u failed\n", \ + n, elsize); \ } \ } while (0) #define NDR_ALLOC_N(ndr, s, n) NDR_ALLOC_N_SIZE(ndr, s, n, sizeof(*(s))) + +#define NDR_PUSH_ALLOC_SIZE(ndr, s, size) do { \ + (s) = talloc(ndr->mem_ctx, size); \ + if (!(s)) return ndr_push_error(ndr, NDR_ERR_ALLOC, \ + "push alloc %u failed\n",\ + size); \ + } while (0) + +#define NDR_PUSH_ALLOC(ndr, s) NDR_PUSH_ALLOC_SIZE(ndr, s, sizeof(*(s))) + + /* these are used when generic fn pointers are needed for ndr push/pull fns */ typedef NTSTATUS (*ndr_push_fn_t)(struct ndr_push *, void *); typedef NTSTATUS (*ndr_pull_fn_t)(struct ndr_pull *, void *); diff --git a/source4/librpc/ndr/ndr.c b/source4/librpc/ndr/ndr.c index b67fb25b1e..7deee6be3b 100644 --- a/source4/librpc/ndr/ndr.c +++ b/source4/librpc/ndr/ndr.c @@ -81,7 +81,9 @@ NTSTATUS ndr_pull_limit_size(struct ndr_pull *ndr, uint32 size, uint32 ofs) new_size = ndr->offset + size - ofs; if (new_size > ndr->data_size) { - return NT_STATUS_BUFFER_TOO_SMALL; + return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, + "ndr_pull_limit_size %s %u failed", + size, ofs); } ndr->data_size = new_size; @@ -96,7 +98,9 @@ NTSTATUS ndr_pull_advance(struct ndr_pull *ndr, uint32 size) { ndr->offset += size; if (ndr->offset > ndr->data_size) { - return NT_STATUS_BUFFER_TOO_SMALL; + return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, + "ndr_pull_advance by %u failed", + size); } return NT_STATUS_OK; } @@ -108,7 +112,9 @@ NTSTATUS ndr_pull_set_offset(struct ndr_pull *ndr, uint32 ofs) { ndr->offset = ofs; if (ndr->offset > ndr->data_size) { - return NT_STATUS_BUFFER_TOO_SMALL; + return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, + "ndr_pull_set_offset %u failed", + ofs); } return NT_STATUS_OK; } @@ -128,18 +134,13 @@ void ndr_pull_restore(struct ndr_pull *ndr, struct ndr_pull_save *save) } - - /* create a ndr_push structure, ready for some marshalling */ -struct ndr_push *ndr_push_init(void) +struct ndr_push *ndr_push_init_ctx(TALLOC_CTX *mem_ctx) { struct ndr_push *ndr; - TALLOC_CTX *mem_ctx = talloc_init("ndr_push_init"); - if (!mem_ctx) return NULL; ndr = talloc(mem_ctx, sizeof(*ndr)); if (!ndr) { - talloc_destroy(mem_ctx); return NULL; } @@ -148,15 +149,30 @@ struct ndr_push *ndr_push_init(void) ndr->alloc_size = NDR_BASE_MARSHALL_SIZE; ndr->data = talloc(ndr->mem_ctx, ndr->alloc_size); if (!ndr->data) { - ndr_push_free(ndr); return NULL; } ndr->offset = 0; ndr->ptr_count = 0; + ndr->relative_list = NULL; + ndr->relative_list_end = NULL; return ndr; } + +/* create a ndr_push structure, ready for some marshalling */ +struct ndr_push *ndr_push_init(void) +{ + struct ndr_push *ndr; + TALLOC_CTX *mem_ctx = talloc_init("ndr_push_init"); + if (!mem_ctx) return NULL; + ndr = ndr_push_init_ctx(mem_ctx); + if (!ndr) { + talloc_destroy(mem_ctx); + } + return ndr; +} + /* free a ndr_push structure */ void ndr_push_free(struct ndr_push *ndr) { @@ -189,7 +205,8 @@ NTSTATUS ndr_push_expand(struct ndr_push *ndr, uint32 size) } ndr->data = talloc_realloc(ndr->mem_ctx, ndr->data, ndr->alloc_size); if (!ndr->data) { - return NT_STATUS_NO_MEMORY; + return ndr_push_error(ndr, NDR_ERR_ALLOC, "Failed to push_expand to %u", + ndr->alloc_size); } return NT_STATUS_OK; @@ -358,6 +375,20 @@ void ndr_print_function_debug(void (*fn)(struct ndr_print *, const char *, int , talloc_destroy(ndr.mem_ctx); } + +static NTSTATUS ndr_map_error(enum ndr_err_code err) +{ + switch (err) { + case NDR_ERR_BUFSIZE: + return NT_STATUS_BUFFER_TOO_SMALL; + case NDR_ERR_ALLOC: + return NT_STATUS_NO_MEMORY; + } + + /* we should all error codes to different status codes */ + return NT_STATUS_INVALID_PARAMETER; +} + /* return and possibly log an NDR error */ @@ -373,8 +404,8 @@ NTSTATUS ndr_pull_error(struct ndr_pull *ndr, enum ndr_err_code err, const char DEBUG(3,("ndr_pull_error(%u): %s\n", err, s)); free(s); - /* we should map to different status codes */ - return NT_STATUS_INVALID_PARAMETER; + + return ndr_map_error(err); } /* @@ -392,8 +423,8 @@ NTSTATUS ndr_push_error(struct ndr_push *ndr, enum ndr_err_code err, const char DEBUG(3,("ndr_push_error(%u): %s\n", err, s)); free(s); - /* we should map to different status codes */ - return NT_STATUS_INVALID_PARAMETER; + + return ndr_map_error(err); } @@ -494,6 +525,92 @@ NTSTATUS ndr_pull_subcontext_union_fn(struct ndr_pull *ndr, /* + push a subcontext header +*/ +static NTSTATUS ndr_push_subcontext_header(struct ndr_push *ndr, + size_t sub_size, + struct ndr_push *ndr2) +{ + switch (sub_size) { + case 0: + break; + + case 2: + NDR_CHECK(ndr_push_uint16(ndr, ndr2->offset)); + break; + + case 4: + NDR_CHECK(ndr_push_uint32(ndr, ndr2->offset)); + break; + + default: + return ndr_push_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_push_subcontext_fn(struct ndr_push *ndr, + size_t sub_size, + void *base, + NTSTATUS (*fn)(struct ndr_push *, void *)) +{ + struct ndr_push *ndr2; + + ndr2 = ndr_push_init_ctx(ndr->mem_ctx); + if (!ndr2) return NT_STATUS_NO_MEMORY; + + NDR_CHECK(fn(ndr2, base)); + NDR_CHECK(ndr_push_subcontext_header(ndr, sub_size, ndr2)); + NDR_CHECK(ndr_push_bytes(ndr, ndr2->data, ndr2->offset)); + return NT_STATUS_OK; +} + +/* + handle subcontext buffers for function that take a flags arg +*/ +NTSTATUS ndr_push_subcontext_flags_fn(struct ndr_push *ndr, + size_t sub_size, + void *base, + NTSTATUS (*fn)(struct ndr_push *, int, void *)) +{ + struct ndr_push *ndr2; + + ndr2 = ndr_push_init_ctx(ndr->mem_ctx); + if (!ndr2) return NT_STATUS_NO_MEMORY; + + NDR_CHECK(fn(ndr2, NDR_SCALARS|NDR_BUFFERS, base)); + NDR_CHECK(ndr_push_subcontext_header(ndr, sub_size, ndr2)); + NDR_CHECK(ndr_push_bytes(ndr, ndr2->data, ndr2->offset)); + return NT_STATUS_OK; +} + +/* + handle subcontext buffers for function that take a union +*/ +NTSTATUS ndr_push_subcontext_union_fn(struct ndr_push *ndr, + size_t sub_size, + uint32 level, + void *base, + NTSTATUS (*fn)(struct ndr_push *, int, uint32, void *)) +{ + struct ndr_push *ndr2; + + ndr2 = ndr_push_init_ctx(ndr->mem_ctx); + if (!ndr2) return NT_STATUS_NO_MEMORY; + + NDR_CHECK(fn(ndr2, NDR_SCALARS|NDR_BUFFERS, level, base)); + NDR_CHECK(ndr_push_subcontext_header(ndr, sub_size, ndr2)); + NDR_CHECK(ndr_push_bytes(ndr, ndr2->data, ndr2->offset)); + return NT_STATUS_OK; +} + + +/* mark the start of a structure */ NTSTATUS ndr_pull_struct_start(struct ndr_pull *ndr) @@ -520,7 +637,7 @@ void ndr_pull_struct_end(struct ndr_pull *ndr) NTSTATUS ndr_push_struct_start(struct ndr_push *ndr) { struct ndr_ofs_list *ofs; - NDR_ALLOC(ndr, ofs); + NDR_PUSH_ALLOC(ndr, ofs); ofs->offset = ndr->offset; ofs->next = ndr->ofs_list; ndr->ofs_list = ofs; @@ -579,12 +696,17 @@ NTSTATUS ndr_push_relative(struct ndr_push *ndr, int ndr_flags, const void *p, NDR_CHECK(ndr_push_uint32(ndr, 0)); return NT_STATUS_OK; } - NDR_ALLOC(ndr, ofs); + NDR_PUSH_ALLOC(ndr, ofs); NDR_CHECK(ndr_push_align(ndr, 4)); ofs->offset = ndr->offset; NDR_CHECK(ndr_push_uint32(ndr, 0xFFFFFFFF)); - ofs->next = ndr->relative_list; - ndr->relative_list = ofs; + ofs->next = NULL; + if (ndr->relative_list_end) { + ndr->relative_list_end->next = ofs; + } else { + ndr->relative_list = ofs; + } + ndr->relative_list_end = ofs; } if (ndr_flags & NDR_BUFFERS) { struct ndr_push_save save; @@ -596,6 +718,9 @@ NTSTATUS ndr_push_relative(struct ndr_push *ndr, int ndr_flags, const void *p, return ndr_push_error(ndr, NDR_ERR_RELATIVE, "Empty relative stack"); } ndr->relative_list = ndr->relative_list->next; + if (ndr->relative_list == NULL) { + ndr->relative_list_end = NULL; + } NDR_CHECK(ndr_push_align(ndr, 8)); ndr_push_save(ndr, &save); ndr->offset = ofs->offset; diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c index 56c0ab231e..a3c4bc0aec 100644 --- a/source4/librpc/ndr/ndr_basic.c +++ b/source4/librpc/ndr/ndr_basic.c @@ -83,6 +83,14 @@ NTSTATUS ndr_pull_NTSTATUS(struct ndr_pull *ndr, NTSTATUS *status) return NT_STATUS_OK; } +/* + push a NTSTATUS +*/ +NTSTATUS ndr_push_NTSTATUS(struct ndr_push *ndr, NTSTATUS status) +{ + return ndr_push_uint32(ndr, NT_STATUS_V(status)); +} + void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTATUS *r) { ndr->print(ndr, "%-25s: %s", name, nt_errstr(*r)); @@ -99,6 +107,14 @@ NTSTATUS ndr_pull_WERROR(struct ndr_pull *ndr, WERROR *status) return NT_STATUS_OK; } +/* + push a WERROR +*/ +NTSTATUS ndr_push_WERROR(struct ndr_push *ndr, WERROR status) +{ + return ndr_push_uint32(ndr, W_ERROR_V(status)); +} + void ndr_print_WERROR(struct ndr_print *ndr, const char *name, WERROR *r) { ndr->print(ndr, "%-25s: %s", name, win_errstr(*r)); @@ -340,7 +356,9 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) NDR_CHECK(ndr_pull_uint32(ndr, &ofs)); NDR_CHECK(ndr_pull_uint32(ndr, &len2)); if (len2 > len1) { - return NT_STATUS_INVALID_PARAMETER; + return ndr_pull_error(ndr, NDR_ERR_STRING, + "Bad string lengths len1=%u ofs=%u len2=%u\n", + len1, ofs, len2); } if (len2 == 0) { *s = talloc_strdup(ndr->mem_ctx, ""); @@ -395,7 +413,9 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) NDR_CHECK(ndr_pull_uint32(ndr, &ofs)); NDR_CHECK(ndr_pull_uint32(ndr, &len2)); if (len2 > len1) { - return NT_STATUS_INVALID_PARAMETER; + return ndr_pull_error(ndr, NDR_ERR_STRING, + "Bad ascii string lengths len1=%u ofs=%u len2=%u\n", + len1, ofs, len2); } NDR_ALLOC_N(ndr, as, (len2+1)); NDR_CHECK(ndr_pull_bytes(ndr, as, len2)); diff --git a/source4/librpc/ndr/ndr_sec.c b/source4/librpc/ndr/ndr_sec.c index 5a959b9b47..1a8d355149 100644 --- a/source4/librpc/ndr/ndr_sec.c +++ b/source4/librpc/ndr/ndr_sec.c @@ -88,3 +88,53 @@ void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, struct dom_sid2 ndr_print_dom_sid(ndr, name, sid); } + +/* + return the wire size of a security_ace +*/ +size_t ndr_size_security_ace(struct security_ace *ace) +{ + if (!ace) return 0; + return 8 + ndr_size_dom_sid(&ace->trustee); +} + + +/* + return the wire size of a security_acl +*/ +size_t ndr_size_security_acl(struct security_acl *acl) +{ + size_t ret; + int i; + if (!acl) return 0; + ret = 8; + for (i=0;i<acl->num_aces;i++) { + ret += ndr_size_security_ace(&acl->aces[i]); + } + return ret; +} + +/* + return the wire size of a dom_sid +*/ +size_t ndr_size_dom_sid(struct dom_sid *sid) +{ + if (!sid) return 0; + return 8 + 4*sid->num_auths; +} + +/* + return the wire size of a security descriptor +*/ +size_t ndr_size_security_descriptor(struct security_descriptor *sd) +{ + size_t ret; + if (!sd) return 0; + + ret = 20; + ret += ndr_size_dom_sid(sd->owner_sid); + ret += ndr_size_dom_sid(sd->group_sid); + ret += ndr_size_security_acl(sd->dacl); + ret += ndr_size_security_acl(sd->sacl); + return ret; +} diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 7fa24bb171..cb03ff8970 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -731,6 +731,139 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p, /* + this is a paranoid NDR validator. For every packet we push onto the wire + we pull it back again, then push it again. Then we compare the raw NDR data + for that to the NDR we initially generated. If they don't match then we know + we must have a bug in either the pull or push side of our code +*/ +static NTSTATUS dcerpc_ndr_validate_in(TALLOC_CTX *mem_ctx, + DATA_BLOB blob, + size_t struct_size, + NTSTATUS (*ndr_push)(struct ndr_push *, int, void *), + NTSTATUS (*ndr_pull)(struct ndr_pull *, int, void *)) +{ + void *st; + struct ndr_pull *pull; + struct ndr_push *push; + NTSTATUS status; + DATA_BLOB blob2; + + st = talloc(mem_ctx, struct_size); + if (!st) { + return NT_STATUS_NO_MEMORY; + } + + pull = ndr_pull_init_blob(&blob, mem_ctx); + if (!pull) { + return NT_STATUS_NO_MEMORY; + } + + status = ndr_pull(pull, NDR_IN, st); + if (!NT_STATUS_IS_OK(status)) { + return ndr_pull_error(pull, NDR_ERR_VALIDATE, + "Error in input validation pull - %s", + nt_errstr(status)); + } + + push = ndr_push_init_ctx(mem_ctx); + if (!push) { + return NT_STATUS_NO_MEMORY; + } + + status = ndr_push(push, NDR_IN, st); + if (!NT_STATUS_IS_OK(status)) { + return ndr_push_error(push, NDR_ERR_VALIDATE, + "Error in input validation push - %s", + nt_errstr(status)); + } + + blob2 = ndr_push_blob(push); + + if (!data_blob_equal(&blob, &blob2)) { + return ndr_push_error(push, NDR_ERR_VALIDATE, + "Error in input validation data - %s", + nt_errstr(status)); + } + + return NT_STATUS_OK; +} + +/* + this is a paranoid NDR input validator. For every packet we pull + from the wire we push it back again then pull and push it + again. Then we compare the raw NDR data for that to the NDR we + initially generated. If they don't match then we know we must have a + bug in either the pull or push side of our code +*/ +static NTSTATUS dcerpc_ndr_validate_out(TALLOC_CTX *mem_ctx, + void *struct_ptr, + size_t struct_size, + NTSTATUS (*ndr_push)(struct ndr_push *, int, void *), + NTSTATUS (*ndr_pull)(struct ndr_pull *, int, void *)) +{ + void *st; + struct ndr_pull *pull; + struct ndr_push *push; + NTSTATUS status; + DATA_BLOB blob, blob2; + + st = talloc(mem_ctx, struct_size); + if (!st) { + return NT_STATUS_NO_MEMORY; + } + memcpy(st, struct_ptr, struct_size); + + push = ndr_push_init_ctx(mem_ctx); + if (!push) { + return NT_STATUS_NO_MEMORY; + } + + status = ndr_push(push, NDR_OUT, struct_ptr); + if (!NT_STATUS_IS_OK(status)) { + return ndr_push_error(push, NDR_ERR_VALIDATE, + "Error in output validation push - %s", + nt_errstr(status)); + } + + blob = ndr_push_blob(push); + + pull = ndr_pull_init_blob(&blob, mem_ctx); + if (!pull) { + return NT_STATUS_NO_MEMORY; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + status = ndr_pull(pull, NDR_OUT, st); + if (!NT_STATUS_IS_OK(status)) { + return ndr_pull_error(pull, NDR_ERR_VALIDATE, + "Error in output validation pull - %s", + nt_errstr(status)); + } + + push = ndr_push_init_ctx(mem_ctx); + if (!push) { + return NT_STATUS_NO_MEMORY; + } + + status = ndr_push(push, NDR_OUT, st); + if (!NT_STATUS_IS_OK(status)) { + return ndr_push_error(push, NDR_ERR_VALIDATE, + "Error in output validation push2 - %s", + nt_errstr(status)); + } + + blob2 = ndr_push_blob(push); + + if (!data_blob_equal(&blob, &blob2)) { + return ndr_push_error(push, NDR_ERR_VALIDATE, + "Error in output validation data - %s", + nt_errstr(status)); + } + + return NT_STATUS_OK; +} + +/* a useful helper function for synchronous rpc requests this can be used when you have ndr push/pull functions in the @@ -739,9 +872,10 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p, NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, uint32 opnum, TALLOC_CTX *mem_ctx, - NTSTATUS (*ndr_push)(struct ndr_push *, void *), - NTSTATUS (*ndr_pull)(struct ndr_pull *, void *), - void *struct_ptr) + NTSTATUS (*ndr_push)(struct ndr_push *, int, void *), + NTSTATUS (*ndr_pull)(struct ndr_pull *, int, void *), + void *struct_ptr, + size_t struct_size) { struct ndr_push *push; struct ndr_pull *pull; @@ -756,7 +890,7 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, } /* push the structure into a blob */ - status = ndr_push(push, struct_ptr); + status = ndr_push(push, NDR_IN, struct_ptr); if (!NT_STATUS_IS_OK(status)) { goto failed; } @@ -764,6 +898,14 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, /* retrieve the blob */ request = ndr_push_blob(push); + if (p->flags & DCERPC_DEBUG_VALIDATE_IN) { + status = dcerpc_ndr_validate_in(mem_ctx, request, struct_size, + ndr_push, ndr_pull); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + } + DEBUG(10,("rpc request data:\n")); dump_data(10, request.data, request.length); @@ -783,11 +925,19 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, dump_data(10, pull->data, pull->data_size); /* pull the structure from the blob */ - status = ndr_pull(pull, struct_ptr); + status = ndr_pull(pull, NDR_OUT, struct_ptr); if (!NT_STATUS_IS_OK(status)) { goto failed; } + if (p->flags & DCERPC_DEBUG_VALIDATE_OUT) { + status = dcerpc_ndr_validate_out(mem_ctx, struct_ptr, struct_size, + ndr_push, ndr_pull); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + } + if (pull->offset != pull->data_size) { DEBUG(0,("Warning! %d unread bytes\n", pull->data_size - pull->offset)); status = NT_STATUS_INFO_LENGTH_MISMATCH; diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 3f9241e9a3..65566878e3 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -53,10 +53,14 @@ struct dcerpc_pipe { #define DCERPC_PFC_FLAG_NOCALL 0x20 /* dcerpc pipe flags */ -#define DCERPC_DEBUG_PRINT_IN 1 +#define DCERPC_DEBUG_PRINT_IN 1 #define DCERPC_DEBUG_PRINT_OUT 2 #define DCERPC_DEBUG_PRINT_BOTH (DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT) +#define DCERPC_DEBUG_VALIDATE_IN 4 +#define DCERPC_DEBUG_VALIDATE_OUT 8 +#define DCERPC_DEBUG_VALIDATE_BOTH (DCERPC_DEBUG_VALIDATE_IN | DCERPC_DEBUG_VALIDATE_OUT) + /* all dcerpc packets use this structure. */ diff --git a/source4/torture/rpc/atsvc.c b/source4/torture/rpc/atsvc.c index 8dfadb1c16..7d0ac42fa4 100644 --- a/source4/torture/rpc/atsvc.c +++ b/source4/torture/rpc/atsvc.c @@ -159,6 +159,8 @@ BOOL torture_rpc_atsvc(int dummy) return False; } + talloc_destroy(mem_ctx); + torture_rpc_close(p); return ret; diff --git a/source4/torture/rpc/dfs.c b/source4/torture/rpc/dfs.c index abd78a8cd0..7b20e044bb 100644 --- a/source4/torture/rpc/dfs.c +++ b/source4/torture/rpc/dfs.c @@ -196,6 +196,8 @@ BOOL torture_rpc_dfs(int dummy) ret = False; } + talloc_destroy(mem_ctx); + torture_rpc_close(p); return ret; diff --git a/source4/torture/rpc/echo.c b/source4/torture/rpc/echo.c index 8d8a3d7c0c..4ac57e7b6e 100644 --- a/source4/torture/rpc/echo.c +++ b/source4/torture/rpc/echo.c @@ -254,6 +254,8 @@ BOOL torture_rpc_echo(int dummy) printf("\n"); + talloc_destroy(mem_ctx); + torture_rpc_close(p); return ret; } diff --git a/source4/torture/rpc/epmapper.c b/source4/torture/rpc/epmapper.c index f00d52f1a5..7893813f56 100644 --- a/source4/torture/rpc/epmapper.c +++ b/source4/torture/rpc/epmapper.c @@ -88,6 +88,8 @@ BOOL torture_rpc_epmapper(int dummy) ret = False; } + talloc_destroy(mem_ctx); + torture_rpc_close(p); return ret; diff --git a/source4/torture/rpc/eventlog.c b/source4/torture/rpc/eventlog.c index 14b091a0c3..19f0644258 100644 --- a/source4/torture/rpc/eventlog.c +++ b/source4/torture/rpc/eventlog.c @@ -101,6 +101,8 @@ BOOL torture_rpc_eventlog(int dummy) return False; } + talloc_destroy(mem_ctx); + torture_rpc_close(p); return ret; diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index 35b4ff3333..9512493181 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -539,7 +539,7 @@ BOOL torture_rpc_lsa(int dummy) return False; } - p->flags |= DCERPC_DEBUG_PRINT_BOTH; + p->flags |= DCERPC_DEBUG_PRINT_BOTH | DCERPC_DEBUG_VALIDATE_BOTH; if (!test_OpenPolicy(p, mem_ctx)) { ret = False; @@ -575,6 +575,8 @@ BOOL torture_rpc_lsa(int dummy) ret = False; } + talloc_destroy(mem_ctx); + torture_rpc_close(p); return ret; diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index d825ddb02c..ef7d9300d8 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -823,7 +823,6 @@ static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, NTSTATUS status; struct samr_EnumDomains r; uint32 resume_handle = 0; - uint32 num_entries=0; int i; BOOL ret = True; @@ -831,7 +830,6 @@ static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.resume_handle = &resume_handle; r.in.buf_size = (uint32)-1; r.out.resume_handle = &resume_handle; - r.out.num_entries = &num_entries; status = dcerpc_samr_EnumDomains(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -904,7 +902,7 @@ BOOL torture_rpc_samr(int dummy) return False; } - p->flags |= DCERPC_DEBUG_PRINT_BOTH; + p->flags |= DCERPC_DEBUG_PRINT_BOTH | DCERPC_DEBUG_VALIDATE_BOTH; if (!test_Connect(p, mem_ctx, &handle)) { ret = False; @@ -922,6 +920,8 @@ BOOL torture_rpc_samr(int dummy) ret = False; } + talloc_destroy(mem_ctx); + torture_rpc_close(p); return ret; diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index 6b208329e3..6c85a78d20 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -325,6 +325,8 @@ BOOL torture_rpc_spoolss(int dummy) ret = False; } + talloc_destroy(mem_ctx); + torture_rpc_close(p); return ret; diff --git a/source4/torture/rpc/srvsvc.c b/source4/torture/rpc/srvsvc.c index 1f93357907..65dc63ff54 100644 --- a/source4/torture/rpc/srvsvc.c +++ b/source4/torture/rpc/srvsvc.c @@ -287,6 +287,8 @@ BOOL torture_rpc_srvsvc(int dummy) ret = False; } + talloc_destroy(mem_ctx); + torture_rpc_close(p); return ret; diff --git a/source4/torture/rpc/winreg.c b/source4/torture/rpc/winreg.c index 7ca63f722e..3b88b032b7 100644 --- a/source4/torture/rpc/winreg.c +++ b/source4/torture/rpc/winreg.c @@ -385,6 +385,8 @@ BOOL torture_rpc_winreg(int dummy) } } + talloc_destroy(mem_ctx); + torture_rpc_close(p); return ret; diff --git a/source4/torture/rpc/wkssvc.c b/source4/torture/rpc/wkssvc.c index ed1f5d4400..6b09565bda 100644 --- a/source4/torture/rpc/wkssvc.c +++ b/source4/torture/rpc/wkssvc.c @@ -104,6 +104,8 @@ BOOL torture_rpc_wkssvc(int dummy) ret = False; } + talloc_destroy(mem_ctx); + torture_rpc_close(p); return ret; |