From c7fd83d0b280810f16f7ef99ba58efb007f93920 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 24 Nov 2003 01:24:29 +0000 Subject: added the dcerpc remote management interfaces as mgmt.idl, and wrote a test suite. The test suite dumps all of the interfaces available on all pipes. There sure are a lot more interfaces on w2k3 than w2k ! (This used to be commit f94bc079902d725b63155d8d2de5bf408c6e7335) --- source4/Makefile.in | 7 +-- source4/librpc/idl/dcerpc.idl | 3 +- source4/librpc/idl/epmapper.idl | 14 +++--- source4/librpc/idl/idl_types.h | 9 ++++ source4/librpc/idl/mgmt.idl | 63 ++++++++++++++++++++++++++ source4/librpc/ndr/libndr.h | 6 +++ source4/librpc/ndr/ndr.c | 19 ++++++++ source4/librpc/ndr/ndr_basic.c | 19 +++++--- source4/librpc/rpc/dcerpc.c | 7 ++- source4/torture/rpc/mgmt.c | 98 +++++++++++++++++++++++++++++++++++++++++ source4/torture/torture.c | 1 + source4/utils/ndrdump.c | 28 +++--------- 12 files changed, 233 insertions(+), 41 deletions(-) create mode 100644 source4/librpc/idl/mgmt.idl create mode 100644 source4/torture/rpc/mgmt.c diff --git a/source4/Makefile.in b/source4/Makefile.in index 2484b80a0f..52dce72edc 100644 --- a/source4/Makefile.in +++ b/source4/Makefile.in @@ -202,7 +202,8 @@ 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_epmapper.o librpc/gen_ndr/ndr_winreg.o + librpc/gen_ndr/ndr_epmapper.o librpc/gen_ndr/ndr_winreg.o \ + librpc/gen_ndr/ndr_mgmt.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 \ @@ -210,7 +211,7 @@ LIBRAW_RPC_OBJ = librpc/rpc/dcerpc.o librpc/rpc/dcerpc_smb.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_epmapper.o \ - librpc/gen_rpc/rpc_winreg.o + librpc/gen_rpc/rpc_winreg.o librpc/gen_rpc/rpc_mgmt.o LIBRAW_OBJ = libcli/raw/rawfile.o libcli/raw/smb_signing.o \ libcli/raw/clisocket.o libcli/raw/clitransport.o \ @@ -448,7 +449,7 @@ 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/epmapper.o torture/rpc/winreg.o + torture/rpc/epmapper.o torture/rpc/winreg.o torture/rpc/mgmt.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/librpc/idl/dcerpc.idl b/source4/librpc/idl/dcerpc.idl index f24e6ffc45..c45309ba68 100644 --- a/source4/librpc/idl/dcerpc.idl +++ b/source4/librpc/idl/dcerpc.idl @@ -10,7 +10,8 @@ interface dcerpc { typedef struct { GUID uuid; - uint32 if_version; + uint16 major_version; + uint16 minor_version; } dcerpc_syntax_id; typedef struct { diff --git a/source4/librpc/idl/epmapper.idl b/source4/librpc/idl/epmapper.idl index d2e34e4c31..f542d5f42a 100644 --- a/source4/librpc/idl/epmapper.idl +++ b/source4/librpc/idl/epmapper.idl @@ -77,7 +77,7 @@ interface epmapper [in] uint32 num_ents, [in,size_is(num_ents)] epm_entry_t entries[], [in] uint32 replace, - [out] uint32 *status + [out] error_status_t *status ); /**********************/ @@ -85,7 +85,7 @@ interface epmapper void epm_Delete( [in] uint32 num_ents, [in, size_is(num_ents)] epm_entry_t entries[], - [out] uint32 *status + [out] error_status_t *status ); /**********************/ @@ -99,7 +99,7 @@ interface epmapper [in] uint32 max_ents, [out] uint32 num_ents, [out, length_is(num_ents), size_is(max_ents)] epm_entry_t entries[], - [out] uint32 status + [out] error_status_t status ); @@ -117,7 +117,7 @@ interface epmapper [in] uint32 max_towers, [out] uint32 *num_towers, [out, length_is(*num_towers), size_is(max_towers)] twr_p_t towers[], - [out] uint32 *status + [out] error_status_t *status ); @@ -125,14 +125,14 @@ interface epmapper /* Function 0x04 */ void epm_LookupHandleFree( [in, out] policy_handle *entry_handle, - [out] uint32 *status + [out] error_status_t *status ); /**********************/ /* Function 0x05 */ void epm_InqObject( [out] GUID *epm_object, - [out] uint32 *status + [out] error_status_t *status ); @@ -142,6 +142,6 @@ interface epmapper [in] uint32 object_speced, [in] GUID *object, [in] twr_t *tower, - [out] uint32 *status + [out] error_status_t *status ); } diff --git a/source4/librpc/idl/idl_types.h b/source4/librpc/idl/idl_types.h index d2bbe1ab45..06794d0243 100644 --- a/source4/librpc/idl/idl_types.h +++ b/source4/librpc/idl/idl_types.h @@ -50,3 +50,12 @@ #define NDR_ALIGN2 LIBNDR_FLAG_ALIGN2 #define NDR_ALIGN4 LIBNDR_FLAG_ALIGN4 #define NDR_ALIGN8 LIBNDR_FLAG_ALIGN8 + + +/* + these are used by the epmapper and mgmt interfaces +*/ +#define error_status_t uint32 +#define boolean32 uint32 +#define unsigned32 uint32 + diff --git a/source4/librpc/idl/mgmt.idl b/source4/librpc/idl/mgmt.idl new file mode 100644 index 0000000000..94439bdea3 --- /dev/null +++ b/source4/librpc/idl/mgmt.idl @@ -0,0 +1,63 @@ +#include "idl_types.h" + +/* + dcerpc remote management interface +*/ + + +[ + uuid(afa8bd80-7d8a-11c9-bef4-08002b102989), + version(1) +] +interface mgmt +{ + typedef struct { + dcerpc_syntax_id *id; + } dcerpc_syntax_id_p; + + typedef struct { + unsigned32 count; + [size_is(count)] dcerpc_syntax_id_p if_id[*]; + } rpc_if_id_vector_t; + + + /***********************/ + /* Function 0x00 */ + void mgmt_inq_if_ids ( + [out] rpc_if_id_vector_t *if_id_vector, + [out] error_status_t status + ); + + + + /***********************/ + /* Function 0x01 */ + void mgmt_inq_stats ( + [in, out] unsigned32 *count, + [out, size_is(*count)] unsigned32 *statistics, + [out] error_status_t *status + ); + + /***********************/ + /* Function 0x02 */ + boolean32 mgmt_is_server_listening ( + [out] error_status_t status + ); + + + /***********************/ + /* Function 0x03 */ + void mgmt_stop_server_listening ( + [out] error_status_t status + ); + + + /***********************/ + /* Function 0x04 */ + void mgmt_inq_princ_name ( + [in] unsigned32 authn_proto, + [in] unsigned32 princ_name_size, + [out] ascstr2 princ_name, + [out] error_status_t status + ); +} diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h index 5c51113874..42238fd17b 100644 --- a/source4/librpc/ndr/libndr.h +++ b/source4/librpc/ndr/libndr.h @@ -247,3 +247,9 @@ typedef void (*ndr_print_union_fn_t)(struct ndr_print *, const char *, uint32, v #include "librpc/gen_ndr/ndr_eventlog.h" #include "librpc/gen_ndr/ndr_epmapper.h" #include "librpc/gen_ndr/ndr_winreg.h" +#include "librpc/gen_ndr/ndr_mgmt.h" + +/* this can be used to loop over all pipes - please extend the table + in librpc/ndr/ndr.c +*/ +extern const struct dcerpc_interface_table *dcerpc_pipes[]; diff --git a/source4/librpc/ndr/ndr.c b/source4/librpc/ndr/ndr.c index 00f8eaed46..6116150cea 100644 --- a/source4/librpc/ndr/ndr.c +++ b/source4/librpc/ndr/ndr.c @@ -31,6 +31,23 @@ #define NDR_BASE_MARSHALL_SIZE 1024 +const struct dcerpc_interface_table *dcerpc_pipes[] = { + &dcerpc_table_samr, + &dcerpc_table_lsarpc, + &dcerpc_table_netdfs, + &dcerpc_table_atsvc, + &dcerpc_table_dcerpc, + &dcerpc_table_rpcecho, + &dcerpc_table_epmapper, + &dcerpc_table_eventlog, + &dcerpc_table_spoolss, + &dcerpc_table_srvsvc, + &dcerpc_table_winreg, + &dcerpc_table_wkssvc, + &dcerpc_table_mgmt, + NULL +}; + /* work out the number of bytes needed to align on a n byte boundary @@ -772,3 +789,5 @@ NTSTATUS ndr_pull_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p, } return fn(ndr, NDR_SCALARS|NDR_BUFFERS, p); } + + diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c index 081d9ff87a..5f59899133 100644 --- a/source4/librpc/ndr/ndr_basic.c +++ b/source4/librpc/ndr/ndr_basic.c @@ -730,14 +730,21 @@ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name, ndr->depth--; } +const char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid) +{ + return talloc_asprintf(mem_ctx, + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + IVAL(guid->info, 0), SVAL(guid->info, 4), + SVAL(guid->info, 6), + guid->info[8], guid->info[9], + guid->info[10], guid->info[11], + guid->info[12], guid->info[13], + guid->info[14], guid->info[15]); +} + void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid) { - ndr->print(ndr, "%-25s: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - name, - IVAL(guid->info, 0), SVAL(guid->info, 4), SVAL(guid->info, 6), - guid->info[8], guid->info[9], - guid->info[10], guid->info[11], guid->info[12], guid->info[13], - guid->info[14], guid->info[15]); + ndr->print(ndr, "%-25s: %s", GUID_string(ndr->mem_ctx, guid)); } void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 6a8b867136..6322123279 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -237,14 +237,17 @@ NTSTATUS dcerpc_bind_byuuid(struct dcerpc_pipe *p, DEBUG(2,("Invalid uuid string in dcerpc_bind_byuuid\n")); return status; } - syntax.if_version = version; + syntax.major_version = version; + syntax.minor_version = 0; status = guid_from_string("8a885d04-1ceb-11c9-9fe8-08002b104860", &transfer_syntax.uuid); if (!NT_STATUS_IS_OK(status)) { return status; } - transfer_syntax.if_version = 2; + + transfer_syntax.major_version = 2; + transfer_syntax.minor_version = 0; return dcerpc_bind(p, &syntax, &transfer_syntax); } diff --git a/source4/torture/rpc/mgmt.c b/source4/torture/rpc/mgmt.c new file mode 100644 index 0000000000..5eb0a56a7d --- /dev/null +++ b/source4/torture/rpc/mgmt.c @@ -0,0 +1,98 @@ +/* + Unix SMB/CIFS implementation. + test suite for mgmt 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_inq_if_ids(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx) +{ + 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)); + return False; + } + + if (r.out.status != 0) { + printf("inq_if_ids gave error code 0x%x\n", r.out.status); + return False; + } + + if (!r.out.if_id_vector) { + printf("inq_if_ids gave NULL if_id_vector\n"); + return False; + } + + for (i=0;icount;i++) { + struct dcerpc_syntax_id *id = r.out.if_id_vector->if_id[i].id; + if (!id) continue; + printf("\tuuid %s version 0x%04x:0x%04x\n", + GUID_string(mem_ctx, &id->uuid), + id->major_version, id->minor_version); + } + + return True; +} + +BOOL torture_rpc_mgmt(int dummy) +{ + NTSTATUS status; + struct dcerpc_pipe *p; + TALLOC_CTX *mem_ctx; + BOOL ret = True; + int i; + + mem_ctx = talloc_init("torture_rpc_mgmt"); + + for (i=0;dcerpc_pipes[i];i++) { + + /* some interfaces are not mappable */ + if (dcerpc_pipes[i]->num_calls == 0 || + strcmp(dcerpc_pipes[i]->name, "mgmt") == 0) { + continue; + } + + printf("\nTesting pipe '%s'\n", dcerpc_pipes[i]->name); + + status = torture_rpc_connection(&p, + dcerpc_pipes[i]->name, + DCERPC_MGMT_UUID, + DCERPC_MGMT_VERSION); + if (!NT_STATUS_IS_OK(status)) { + ret = False; + continue; + } + + p->flags |= DCERPC_DEBUG_PRINT_BOTH; + + if (!test_inq_if_ids(p, mem_ctx)) { + ret = False; + } + + torture_rpc_close(p); + } + + return ret; +} diff --git a/source4/torture/torture.c b/source4/torture/torture.c index 4fdfe8ccd5..e13933a231 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -3999,6 +3999,7 @@ static struct { {"RPC-EVENTLOG", torture_rpc_eventlog, 0}, {"RPC-EPMAPPER", torture_rpc_epmapper, 0}, {"RPC-WINREG", torture_rpc_winreg, 0}, + {"RPC-MGMT", torture_rpc_mgmt, 0}, {NULL, NULL, 0}}; diff --git a/source4/utils/ndrdump.c b/source4/utils/ndrdump.c index 6118192b33..7916ccec34 100644 --- a/source4/utils/ndrdump.c +++ b/source4/utils/ndrdump.c @@ -20,35 +20,19 @@ #include "includes.h" -struct dcerpc_interface_table *pipes[] = { - &dcerpc_table_samr, - &dcerpc_table_lsarpc, - &dcerpc_table_netdfs, - &dcerpc_table_atsvc, - &dcerpc_table_dcerpc, - &dcerpc_table_rpcecho, - &dcerpc_table_epmapper, - &dcerpc_table_eventlog, - &dcerpc_table_spoolss, - &dcerpc_table_srvsvc, - &dcerpc_table_winreg, - &dcerpc_table_wkssvc, - NULL -}; - static struct dcerpc_interface_table *find_pipe(const char *pipe_name) { int i; - for (i=0;pipes[i];i++) { - if (strcmp(pipes[i]->name, pipe_name) == 0) { + for (i=0;dcerpc_pipes[i];i++) { + if (strcmp(dcerpc_pipes[i]->name, pipe_name) == 0) { break; } } - if (!pipes[i]) { + if (!dcerpc_pipes[i]) { printf("pipe '%s' not in table\n", pipe_name); exit(1); } - return pipes[i]; + return dcerpc_pipes[i]; } static const struct dcerpc_interface_call *find_function( @@ -80,8 +64,8 @@ static void show_pipes(void) usage(); printf("\nYou must specify a pipe\n"); printf("known pipes are:\n"); - for (i=0;pipes[i];i++) { - printf("\t%s\n", pipes[i]->name); + for (i=0;dcerpc_pipes[i];i++) { + printf("\t%s\n", dcerpc_pipes[i]->name); } exit(1); } -- cgit