mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r5797: - 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
(This used to be commit 483bb1418f
)
This commit is contained in:
parent
ebc34d2157
commit
a81a2c22a2
@ -600,12 +600,12 @@ sub ParseArrayPull($$$$)
|
||||
}
|
||||
}
|
||||
|
||||
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 ParseSubcontextPushStart($)
|
||||
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 @@ sub ParseElementPushScalar($$$)
|
||||
}
|
||||
|
||||
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 @@ sub ParseElementPullScalar($$$)
|
||||
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 @@ sub ParseElementPushBuffer($$)
|
||||
}
|
||||
|
||||
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 @@ sub ParseElementPullBuffer($$)
|
||||
}
|
||||
|
||||
if (defined $sub_size) {
|
||||
$ndr = ParseSubcontextPullStart($e);
|
||||
$ndr = ParseSubcontextPullStart($e, $ndr_flags);
|
||||
$ndr_flags = "NDR_SCALARS|NDR_BUFFERS";
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,10 @@ sub ValidElement($)
|
||||
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
|
||||
|
@ -433,34 +433,46 @@ NTSTATUS ndr_push_error(struct ndr_push *ndr, enum ndr_err_code err, const char
|
||||
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 @@ NTSTATUS ndr_pull_subcontext_header(struct ndr_pull *ndr,
|
||||
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 @@ NTSTATUS ndr_push_subcontext_header(struct ndr_push *ndr,
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user