summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2003-11-24 03:21:49 +0000
committerAndrew Tridgell <tridge@samba.org>2003-11-24 03:21:49 +0000
commite4773b184cd6ccf1e46ec151afbfd9fb9ad3ede8 (patch)
tree980d9a236b4800aa018d7cc3a2b615919b69f7f5
parentc7fd83d0b280810f16f7ef99ba58efb007f93920 (diff)
downloadsamba-e4773b184cd6ccf1e46ec151afbfd9fb9ad3ede8.tar.gz
samba-e4773b184cd6ccf1e46ec151afbfd9fb9ad3ede8.tar.bz2
samba-e4773b184cd6ccf1e46ec151afbfd9fb9ad3ede8.zip
added tests for the remaining calls on the rpc management interface
(This used to be commit 00f9b0e12061c175334f96805ca8333f28f74d91)
-rw-r--r--source4/build/pidl/parser.pm48
-rw-r--r--source4/build/pidl/util.pm3
-rw-r--r--source4/librpc/idl/mgmt.idl20
-rw-r--r--source4/librpc/ndr/ndr_basic.c32
-rw-r--r--source4/librpc/rpc/dcerpc.c35
-rw-r--r--source4/torture/rpc/mgmt.c115
6 files changed, 201 insertions, 52 deletions
diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm
index b92729a80a..788660c198 100644
--- a/source4/build/pidl/parser.pm
+++ b/source4/build/pidl/parser.pm
@@ -64,10 +64,12 @@ sub find_sibling($$)
####################################################################
# work out the name of a size_is() variable
-sub find_size_var($$)
+sub find_size_var($$$)
{
my($e) = shift;
my($size) = shift;
+ my($var_prefix) = shift;
+
my($fn) = $e->{PARENT};
if (util::is_constant($size)) {
@@ -91,6 +93,9 @@ sub find_size_var($$)
my $e2 = find_sibling($e, $size);
+ if (util::has_property($e2, "in") && util::has_property($e2, "out")) {
+ return $prefix . "$var_prefix$size";
+ }
if (util::has_property($e2, "in")) {
return $prefix . "r->in.$size";
}
@@ -212,7 +217,7 @@ sub ParseArrayPush($$$)
my $var_prefix = shift;
my $ndr_flags = shift;
- my $size = find_size_var($e, util::array_size($e));
+ my $size = find_size_var($e, util::array_size($e), $var_prefix);
if (defined $e->{CONFORMANT_SIZE}) {
# the conformant size has already been pushed
@@ -222,7 +227,7 @@ sub ParseArrayPush($$$)
}
if (my $length = util::has_property($e, "length_is")) {
- $length = find_size_var($e, $length);
+ $length = find_size_var($e, $length, $var_prefix);
pidl "\t\tNDR_CHECK(ndr_push_uint32(ndr, 0));\n";
pidl "\t\tNDR_CHECK(ndr_push_uint32(ndr, $length));\n";
$size = $length;
@@ -241,11 +246,11 @@ sub ParseArrayPrint($$)
{
my $e = shift;
my $var_prefix = shift;
- my $size = find_size_var($e, util::array_size($e));
+ my $size = find_size_var($e, util::array_size($e), $var_prefix);
my $length = util::has_property($e, "length_is");
if (defined $length) {
- $size = find_size_var($e, $length);
+ $size = find_size_var($e, $length, $var_prefix);
}
if (util::is_scalar_type($e->{TYPE})) {
@@ -263,7 +268,7 @@ sub ParseArrayPull($$$)
my $var_prefix = shift;
my $ndr_flags = shift;
- my $size = find_size_var($e, util::array_size($e));
+ my $size = find_size_var($e, util::array_size($e), $var_prefix);
my $alloc_size = $size;
# if this is a conformant array then we use that size to allocate, and make sure
@@ -275,13 +280,22 @@ sub ParseArrayPull($$$)
pidl "\t\treturn ndr_pull_error(ndr, NDR_ERR_CONFORMANT_SIZE, \"Bad conformant size %u should be %u\", $alloc_size, $size);\n";
pidl "\t}\n";
} elsif (!util::is_inline_array($e)) {
+ if ($var_prefix =~ /^r->out/ && $size =~ /^\*r->in/) {
+ my $size2 = substr($size, 1);
+ pidl "if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_ALLOC(ndr, $size2); }\n";
+ }
+
# non fixed arrays encode the size just before the array
pidl "\t{\n";
pidl "\t\tuint32 _array_size;\n";
pidl "\t\tNDR_CHECK(ndr_pull_uint32(ndr, &_array_size));\n";
- pidl "\t\tif ($size > _array_size) {\n";
+ if ($size =~ /r->in/) {
+ pidl "\t\tif (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _array_size != $size) {\n";
+ } else {
+ pidl "\t\tif ($size != _array_size) {\n";
+ }
pidl "\t\t\treturn ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, \"Bad array size %u should be %u\", _array_size, $size);\n";
- pidl "\t\t}\n";
+ pidl "\t\t} else { $size = _array_size; }\n";
pidl "\t}\n";
}
@@ -303,7 +317,7 @@ sub ParseArrayPull($$$)
pidl "\t{\n";
if (my $length = util::has_property($e, "length_is")) {
- $length = find_size_var($e, $length);
+ $length = find_size_var($e, $length, $var_prefix);
pidl "\t\tuint32 _offset, _length;\n";
pidl "\t\tNDR_CHECK(ndr_pull_uint32(ndr, &_offset));\n";
pidl "\t\tNDR_CHECK(ndr_pull_uint32(ndr, &_length));\n";
@@ -395,7 +409,7 @@ sub ParseElementPullSwitch($$$$)
my($var_prefix) = shift;
my($ndr_flags) = shift;
my $switch = shift;
- my $switch_var = find_size_var($e, $switch);
+ my $switch_var = find_size_var($e, $switch, $var_prefix);
my $cprefix = util::c_pull_prefix($e);
@@ -433,7 +447,7 @@ sub ParseElementPushSwitch($$$$)
my($var_prefix) = shift;
my($ndr_flags) = shift;
my $switch = shift;
- my $switch_var = find_size_var($e, $switch);
+ my $switch_var = find_size_var($e, $switch, $var_prefix);
my $cprefix = util::c_push_prefix($e);
my $utype = $structs{$e->{TYPE}};
@@ -460,7 +474,7 @@ sub ParseElementPrintSwitch($$$)
my($e) = shift;
my($var_prefix) = shift;
my $switch = shift;
- my $switch_var = find_size_var($e, $switch);
+ my $switch_var = find_size_var($e, $switch, $var_prefix);
my $cprefix = util::c_push_prefix($e);
pidl "\tndr_print_$e->{TYPE}(ndr, \"$e->{NAME}\", $switch_var, $cprefix$var_prefix$e->{NAME});\n";
@@ -667,7 +681,7 @@ sub ParseStructPush($)
# alignment)
my $e = $struct->{ELEMENTS}[-1];
if (defined $e->{ARRAY_LEN} && $e->{ARRAY_LEN} eq "*") {
- my $size = find_size_var($e, util::array_size($e));
+ my $size = find_size_var($e, util::array_size($e), "r->");
$e->{CONFORMANT_SIZE} = $size;
$conform_e = $e;
pidl "\tNDR_CHECK(ndr_push_uint32(ndr, $size));\n";
@@ -1078,7 +1092,11 @@ sub ParseFunctionPrint($)
}
}
if ($fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") {
- pidl "\tndr_print_$fn->{RETURN_TYPE}(ndr, \"result\", &r->out.result);\n";
+ if (util::is_scalar_type($fn->{RETURN_TYPE})) {
+ pidl "\tndr_print_$fn->{RETURN_TYPE}(ndr, \"result\", r->out.result);\n";
+ } else {
+ pidl "\tndr_print_$fn->{RETURN_TYPE}(ndr, \"result\", &r->out.result);\n";
+ }
}
pidl "\tndr->depth--;\n";
pidl "\t}\n";
@@ -1150,7 +1168,7 @@ sub ParseFunctionElementPull($$)
if (util::array_size($e)) {
if (util::need_wire_pointer($e)) {
- pidl "\tNDR_CHECK(ndr_pull_uint32(ndr, _ptr_$e->{NAME}));\n";
+ 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";
diff --git a/source4/build/pidl/util.pm b/source4/build/pidl/util.pm
index 2f94d80012..e99942f0ea 100644
--- a/source4/build/pidl/util.pm
+++ b/source4/build/pidl/util.pm
@@ -183,6 +183,9 @@ sub is_scalar_type($)
return 1, if ($type eq "uint8");
return 1, if ($type eq "uint16");
return 1, if ($type eq "NTTIME");
+ return 1, if ($type eq "error_status_t");
+ return 1, if ($type eq "boolean32");
+ return 1, if ($type eq "unsigned32");
return 1, if ($type eq "HYPER_T");
return 1, if ($type eq "wchar_t");
return 1, if ($type eq "DATA_BLOB");
diff --git a/source4/librpc/idl/mgmt.idl b/source4/librpc/idl/mgmt.idl
index 94439bdea3..2bc752da3d 100644
--- a/source4/librpc/idl/mgmt.idl
+++ b/source4/librpc/idl/mgmt.idl
@@ -32,12 +32,26 @@ interface mgmt
/***********************/
/* Function 0x01 */
+
+ const int mgmt_stats_calls_in = 0;
+ const int mgmt_stats_calls_out = 1;
+ const int mgmt_stats_pkts_in = 2;
+ const int mgmt_stats_pkts_out = 3;
+ const int mgmt_stats_array_max_size = 4;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] uint32 statistics[*];
+ } mgmt_statistics;
+
void mgmt_inq_stats (
- [in, out] unsigned32 *count,
- [out, size_is(*count)] unsigned32 *statistics,
- [out] error_status_t *status
+ [in] uint32 max_count,
+ [in] uint32 unknown,
+ [out] mgmt_statistics statistics,
+ [out] error_status_t status
);
+
/***********************/
/* Function 0x02 */
boolean32 mgmt_is_server_listening (
diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c
index 5f59899133..a45771ef28 100644
--- a/source4/librpc/ndr/ndr_basic.c
+++ b/source4/librpc/ndr/ndr_basic.c
@@ -730,6 +730,38 @@ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
ndr->depth--;
}
+/*
+ build a GUID from a string
+*/
+NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
+{
+ uint32 time_low;
+ uint32 time_mid, time_hi_and_version;
+ uint32 clock_seq_hi_and_reserved;
+ uint32 clock_seq_low;
+ uint32 node[6];
+ int i;
+
+ if (11 != sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ &time_low, &time_mid, &time_hi_and_version,
+ &clock_seq_hi_and_reserved, &clock_seq_low,
+ &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ SIVAL(guid->info, 0, time_low);
+ SSVAL(guid->info, 4, time_mid);
+ SSVAL(guid->info, 6, time_hi_and_version);
+ SCVAL(guid->info, 8, clock_seq_hi_and_reserved);
+ SCVAL(guid->info, 9, clock_seq_low);
+ for (i=0;i<6;i++) {
+ SCVAL(guid->info, 10 + i, node[i]);
+ }
+
+ return NT_STATUS_OK;
+}
+
+
const char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
{
return talloc_asprintf(mem_ctx,
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index 6322123279..276b3c9ef4 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -60,37 +60,6 @@ void dcerpc_pipe_close(struct dcerpc_pipe *p)
}
-/*
- build a GUID from a string
-*/
-static NTSTATUS guid_from_string(const char *s, struct GUID *guid)
-{
- uint32 time_low;
- uint32 time_mid, time_hi_and_version;
- uint32 clock_seq_hi_and_reserved;
- uint32 clock_seq_low;
- uint32 node[6];
- int i;
-
- if (11 != sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- &time_low, &time_mid, &time_hi_and_version,
- &clock_seq_hi_and_reserved, &clock_seq_low,
- &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- SIVAL(guid->info, 0, time_low);
- SSVAL(guid->info, 4, time_mid);
- SSVAL(guid->info, 6, time_hi_and_version);
- SCVAL(guid->info, 8, clock_seq_hi_and_reserved);
- SCVAL(guid->info, 9, clock_seq_low);
- for (i=0;i<6;i++) {
- SCVAL(guid->info, 10 + i, node[i]);
- }
-
- return NT_STATUS_OK;
-}
-
/*
parse a data blob into a dcerpc_packet structure. This handles both
input and output packets
@@ -232,7 +201,7 @@ NTSTATUS dcerpc_bind_byuuid(struct dcerpc_pipe *p,
struct dcerpc_syntax_id transfer_syntax;
NTSTATUS status;
- status = guid_from_string(uuid, &syntax.uuid);
+ status = GUID_from_string(uuid, &syntax.uuid);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(2,("Invalid uuid string in dcerpc_bind_byuuid\n"));
return status;
@@ -240,7 +209,7 @@ NTSTATUS dcerpc_bind_byuuid(struct dcerpc_pipe *p,
syntax.major_version = version;
syntax.minor_version = 0;
- status = guid_from_string("8a885d04-1ceb-11c9-9fe8-08002b104860",
+ status = GUID_from_string("8a885d04-1ceb-11c9-9fe8-08002b104860",
&transfer_syntax.uuid);
if (!NT_STATUS_IS_OK(status)) {
return status;
diff --git a/source4/torture/rpc/mgmt.c b/source4/torture/rpc/mgmt.c
index 5eb0a56a7d..693703eb82 100644
--- a/source4/torture/rpc/mgmt.c
+++ b/source4/torture/rpc/mgmt.c
@@ -28,7 +28,7 @@ static BOOL test_inq_if_ids(struct dcerpc_pipe *p,
NTSTATUS status;
struct mgmt_inq_if_ids r;
int i;
-
+
status = dcerpc_mgmt_inq_if_ids(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
printf("inq_if_ids failed - %s\n", nt_errstr(status));
@@ -56,6 +56,103 @@ static BOOL test_inq_if_ids(struct dcerpc_pipe *p,
return True;
}
+static BOOL test_inq_stats(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx)
+{
+ NTSTATUS status;
+ struct mgmt_inq_stats r;
+
+ r.in.max_count = mgmt_stats_array_max_size;
+ r.in.unknown = 0;
+
+ status = dcerpc_mgmt_inq_stats(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("inq_stats failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ if (r.out.statistics.count != mgmt_stats_array_max_size) {
+ printf("Unexpected array size %d\n", r.out.statistics.count);
+ return False;
+ }
+
+ printf("\tcalls_in %6d calls_out %6d\n\tpkts_in %6d pkts_out %6d\n",
+ r.out.statistics.statistics[mgmt_stats_calls_in],
+ r.out.statistics.statistics[mgmt_stats_calls_out],
+ r.out.statistics.statistics[mgmt_stats_pkts_in],
+ r.out.statistics.statistics[mgmt_stats_pkts_out]);
+
+ return True;
+}
+
+static BOOL test_inq_princ_name(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx)
+{
+#if 0
+ NTSTATUS status;
+ struct mgmt_inq_princ_name r;
+
+ r.in.authn_proto = 1;
+ r.in.princ_name_size = 1000;
+
+ status = dcerpc_mgmt_inq_princ_name(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("inq_princ_name failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ return True;
+#else
+ /* this is broken */
+ printf("\tnot doing inq_princ_name\n");
+ return True;
+#endif
+}
+
+static BOOL test_is_server_listening(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx)
+{
+ NTSTATUS status;
+ struct mgmt_is_server_listening r;
+
+ status = dcerpc_mgmt_is_server_listening(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("is_server_listening failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ if (r.out.status != 0 || r.out.result == 0) {
+ printf("\tserver is NOT listening\n");
+ } else {
+ printf("\tserver is listening\n");
+ }
+
+ return True;
+}
+
+static BOOL test_stop_server_listening(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx)
+{
+ NTSTATUS status;
+ struct mgmt_stop_server_listening r;
+
+ status = dcerpc_mgmt_stop_server_listening(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("stop_server_listening failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ if (r.out.status != 0) {
+ printf("\tserver refused to stop listening\n");
+ } else {
+ printf("\tserver allowed a stop_server_listening request\n");
+ return False;
+ }
+
+ return True;
+}
+
+
BOOL torture_rpc_mgmt(int dummy)
{
NTSTATUS status;
@@ -87,6 +184,22 @@ BOOL torture_rpc_mgmt(int dummy)
p->flags |= DCERPC_DEBUG_PRINT_BOTH;
+ if (!test_is_server_listening(p, mem_ctx)) {
+ ret = False;
+ }
+
+ if (!test_stop_server_listening(p, mem_ctx)) {
+ ret = False;
+ }
+
+ if (!test_inq_stats(p, mem_ctx)) {
+ ret = False;
+ }
+
+ if (!test_inq_princ_name(p, mem_ctx)) {
+ ret = False;
+ }
+
if (!test_inq_if_ids(p, mem_ctx)) {
ret = False;
}