Author: metze Date: 2005-03-15 14:33:38 +0000 (Tue, 15 Mar 2005) New Revision: 5797
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=5797 Log: - add idl property [subcontext_size()] this can be used like this [subcontext_size(28),subcontext(0)] dom_sid sid; this descripes a fixed 28 byte buffer which contains a dom_sid, and the rest of the buffer is padded with zero bytes if the dom_sid doesn't need all 28 byte in it's ndr encoding. - only push and pull the subcontext when we are in the NDR_SCALARS section (tridge, jelmer: I hope this is correct for all cases...!?:-) metze Modified: branches/SAMBA_4_0/source/build/pidl/ndr.pm branches/SAMBA_4_0/source/build/pidl/validator.pm branches/SAMBA_4_0/source/librpc/ndr/ndr.c Changeset: Modified: branches/SAMBA_4_0/source/build/pidl/ndr.pm =================================================================== --- branches/SAMBA_4_0/source/build/pidl/ndr.pm 2005-03-15 14:25:59 UTC (rev 5796) +++ branches/SAMBA_4_0/source/build/pidl/ndr.pm 2005-03-15 14:33:38 UTC (rev 5797) @@ -600,12 +600,12 @@ } } -sub ParseSubcontextPushStart($) +sub ParseSubcontextPushStart($$) { my $e = shift; - my $sub_size = util::has_property($e, "subcontext"); + my $ndr_flags = shift; - pidl "{"; + pidl "if (($ndr_flags) & NDR_SCALARS) {"; indent; pidl "struct ndr_push *_ndr_$e->{NAME};"; pidl ""; @@ -620,34 +620,48 @@ sub ParseSubcontextPushEnd($) { my $e = shift; - my $sub_size = util::has_property($e, "subcontext"); - pidl "NDR_CHECK(ndr_push_subcontext_header(ndr, $sub_size, _ndr_$e->{NAME}));"; + my $header_size = util::has_property($e, "subcontext"); + my $size_is = util::has_property($e, "subcontext_size"); + + if (not defined($size_is)) { + $size_is = "-1"; + } + + pidl "NDR_CHECK(ndr_push_subcontext_header(ndr, $header_size, $size_is, _ndr_$e->{NAME}));"; pidl "NDR_CHECK(ndr_push_bytes(ndr, _ndr_$e->{NAME}->data, _ndr_$e->{NAME}->offset));"; deindent; pidl "}"; } -sub ParseSubcontextPullStart($) +sub ParseSubcontextPullStart($$) { my $e = shift; - my $sub_size = util::has_property($e, "subcontext"); + my $ndr_flags = shift; + my $header_size = util::has_property($e, "subcontext"); + my $size_is = util::has_property($e, "subcontext_size"); - pidl "{"; + if (not defined($size_is)) { + $size_is = "-1"; + } + + pidl "if (($ndr_flags) & NDR_SCALARS) {"; indent; pidl "struct ndr_pull *_ndr_$e->{NAME};"; pidl "NDR_ALLOC(ndr, _ndr_$e->{NAME});"; - pidl "NDR_CHECK(ndr_pull_subcontext_header(ndr, $sub_size, _ndr_$e->{NAME}));"; - + pidl "NDR_CHECK(ndr_pull_subcontext_header(ndr, $header_size, $size_is, _ndr_$e->{NAME}));"; return "_ndr_$e->{NAME}"; } sub ParseSubcontextPullEnd($) { my $e = shift; - my $sub_size = util::has_property($e, "subcontext"); + my $header_size = util::has_property($e, "subcontext"); + my $size_is = util::has_property($e, "subcontext_size"); my $advance; - if ($sub_size) { + if (defined ($size_is)) { + $advance = "$size_is"; + } elsif ($header_size) { $advance = "_ndr_$e->{NAME}->data_size"; } else { $advance = "_ndr_$e->{NAME}->offset"; @@ -676,7 +690,7 @@ } if (defined $sub_size and $e->{POINTERS} == 0) { - $ndr = ParseSubcontextPushStart($e); + $ndr = ParseSubcontextPushStart($e, "NDR_SCALARS"); } if (need_wire_pointer($e)) { @@ -819,7 +833,7 @@ start_flags($e); if (defined $sub_size && $e->{POINTERS} == 0) { - $ndr = ParseSubcontextPullStart($e); + $ndr = ParseSubcontextPullStart($e, $ndr_flags); $ndr_flags = "NDR_SCALARS|NDR_BUFFERS"; } @@ -909,10 +923,10 @@ } if (defined $sub_size) { - $ndr = ParseSubcontextPushStart($e); + $ndr = ParseSubcontextPushStart($e, $ndr_flags); $ndr_flags = "NDR_SCALARS|NDR_BUFFERS"; } - + if (util::array_size($e)) { ParseArrayPush($e, $ndr, "r->", $ndr_flags); } else { @@ -972,7 +986,7 @@ } if (defined $sub_size) { - $ndr = ParseSubcontextPullStart($e); + $ndr = ParseSubcontextPullStart($e, $ndr_flags); $ndr_flags = "NDR_SCALARS|NDR_BUFFERS"; } Modified: branches/SAMBA_4_0/source/build/pidl/validator.pm =================================================================== --- branches/SAMBA_4_0/source/build/pidl/validator.pm 2005-03-15 14:25:59 UTC (rev 5796) +++ branches/SAMBA_4_0/source/build/pidl/validator.pm 2005-03-15 14:33:38 UTC (rev 5797) @@ -72,6 +72,10 @@ fatal(el_name($e) . " : length_is() on non-array element"); } + if (defined (util::has_property($e, "subcontext_size")) and not defined(util::has_property($e, "subcontext"))) { + fatal(el_name($e) . " : subcontext_size() on non-subcontext element"); + } + if (!$e->{POINTERS} && ( util::has_property($e, "ptr") or util::has_property($e, "unique") or Modified: branches/SAMBA_4_0/source/librpc/ndr/ndr.c =================================================================== --- branches/SAMBA_4_0/source/librpc/ndr/ndr.c 2005-03-15 14:25:59 UTC (rev 5796) +++ branches/SAMBA_4_0/source/librpc/ndr/ndr.c 2005-03-15 14:33:38 UTC (rev 5797) @@ -433,34 +433,46 @@ we use magic in pidl to make them easier to cope with */ NTSTATUS ndr_pull_subcontext_header(struct ndr_pull *ndr, - size_t sub_size, + size_t header_size, + ssize_t size_is, struct ndr_pull *ndr2) { ndr2->flags = ndr->flags; - switch (sub_size) { + switch (header_size) { case 0: { - uint32_t size = ndr->data_size - ndr->offset; - NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, size)); + uint32_t content_size = ndr->data_size - ndr->offset; + if (size_is >= 0) { + content_size = size_is; + } + NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, content_size)); break; } case 2: { - uint16_t size; - NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &size)); - NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, size)); + uint16_t content_size; + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &content_size)); + if (size_is >= 0 && size_is != content_size) { + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) size_is(%d) mismatch content_size %d", + size_is, content_size); + } + NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, content_size)); break; } case 4: { - uint32_t size; - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &size)); - NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, size)); + uint32_t content_size; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &content_size)); + if (size_is >= 0 && size_is != content_size) { + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) size_is(%d) mismatch content_size %d", + size_is, content_size); + } + NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, content_size)); break; } default: - return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext size %d", - sub_size); + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) header_size %d", + header_size); } return NT_STATUS_OK; } @@ -469,10 +481,21 @@ push a subcontext header */ NTSTATUS ndr_push_subcontext_header(struct ndr_push *ndr, - size_t sub_size, + size_t header_size, + ssize_t size_is, struct ndr_push *ndr2) { - switch (sub_size) { + if (size_is >= 0) { + ssize_t padding_len = size_is - ndr2->offset; + if (padding_len > 0) { + NDR_CHECK(ndr_push_zero(ndr2, padding_len)); + } else if (padding_len < 0) { + return ndr_push_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PUSH) content_size %d is larger than size_is(%d)", + ndr2->offset, size_is); + } + } + + switch (header_size) { case 0: break; @@ -485,8 +508,8 @@ break; default: - return ndr_push_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext size %d", - sub_size); + return ndr_push_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext header size %d", + header_size); } return NT_STATUS_OK; }