diff options
-rw-r--r-- | source4/include/cli_context.h | 4 | ||||
-rw-r--r-- | source4/libcli/raw/clitransport.c | 6 | ||||
-rw-r--r-- | source4/librpc/idl/spoolss.idl | 7 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_spoolss.c | 20 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_spoolss.h | 11 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 7 | ||||
-rw-r--r-- | source4/librpc/rpc/rpc_spoolss.c | 16 | ||||
-rw-r--r-- | source4/torture/rpc/spoolss.c | 36 |
8 files changed, 89 insertions, 18 deletions
diff --git a/source4/include/cli_context.h b/source4/include/cli_context.h index e74262fa81..bffb6c9f6a 100644 --- a/source4/include/cli_context.h +++ b/source4/include/cli_context.h @@ -161,6 +161,10 @@ struct cli_transport { /* a list of async requests that are pending on this connection */ struct cli_request *pending_requests; + + /* remember the called name - some sub-protocols require us to + know the server name */ + struct nmb_name called; }; /* this is the context for the user */ diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 80bb1e301f..2d614cc3bd 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -42,6 +42,8 @@ struct cli_transport *cli_transport_init(struct cli_socket *sock) cli_null_set_signing(transport); transport->socket->reference_count++; + ZERO_STRUCT(transport->called); + return transport; } @@ -71,6 +73,10 @@ BOOL cli_transport_connect(struct cli_transport *transport, int len = NBT_HDR_SIZE; struct cli_request *req; + if (called) { + transport->called = *called; + } + /* 445 doesn't have session request */ if (transport->socket->port == 445) { return True; diff --git a/source4/librpc/idl/spoolss.idl b/source4/librpc/idl/spoolss.idl index 515ac0fd51..be6f9a8f51 100644 --- a/source4/librpc/idl/spoolss.idl +++ b/source4/librpc/idl/spoolss.idl @@ -128,7 +128,12 @@ /******************/ /* Function: 0x01 */ - NTSTATUS spoolss_01( + WERROR spoolss_OpenPrinter( + [in] unistr *server, + [in] unistr *printer, + [in] DATA_BLOB *buffer, + [in] uint32 access_mask, + [out,ref] policy_handle *handle ); /******************/ diff --git a/source4/librpc/ndr/ndr_spoolss.c b/source4/librpc/ndr/ndr_spoolss.c index f88e46890a..5b64f9067a 100644 --- a/source4/librpc/ndr/ndr_spoolss.c +++ b/source4/librpc/ndr/ndr_spoolss.c @@ -292,8 +292,21 @@ NTSTATUS ndr_push_spoolss_EnumPrinters(struct ndr_push *ndr, struct spoolss_Enum return NT_STATUS_OK; } -NTSTATUS ndr_push_spoolss_01(struct ndr_push *ndr, struct spoolss_01 *r) +NTSTATUS ndr_push_spoolss_OpenPrinter(struct ndr_push *ndr, struct spoolss_OpenPrinter *r) { + NDR_CHECK(ndr_push_ptr(ndr, r->in.server)); + if (r->in.server) { + NDR_CHECK(ndr_push_unistr(ndr, r->in.server)); + } + NDR_CHECK(ndr_push_ptr(ndr, r->in.printer)); + if (r->in.printer) { + NDR_CHECK(ndr_push_unistr(ndr, r->in.printer)); + } + NDR_CHECK(ndr_push_ptr(ndr, r->in.buffer)); + if (r->in.buffer) { + NDR_CHECK(ndr_push_DATA_BLOB(ndr, *r->in.buffer)); + } + NDR_CHECK(ndr_push_uint32(ndr, r->in.access_mask)); return NT_STATUS_OK; } @@ -1249,9 +1262,10 @@ NTSTATUS ndr_pull_spoolss_EnumPrinters(struct ndr_pull *ndr, struct spoolss_Enum return NT_STATUS_OK; } -NTSTATUS ndr_pull_spoolss_01(struct ndr_pull *ndr, struct spoolss_01 *r) +NTSTATUS ndr_pull_spoolss_OpenPrinter(struct ndr_pull *ndr, struct spoolss_OpenPrinter *r) { - NDR_CHECK(ndr_pull_NTSTATUS(ndr, &r->out.result)); + NDR_CHECK(ndr_pull_policy_handle(ndr, r->out.handle)); + NDR_CHECK(ndr_pull_WERROR(ndr, &r->out.result)); return NT_STATUS_OK; } diff --git a/source4/librpc/ndr/ndr_spoolss.h b/source4/librpc/ndr/ndr_spoolss.h index 61aeed9b54..60738b494a 100644 --- a/source4/librpc/ndr/ndr_spoolss.h +++ b/source4/librpc/ndr/ndr_spoolss.h @@ -124,12 +124,17 @@ struct spoolss_EnumPrinters { }; -struct spoolss_01 { +struct spoolss_OpenPrinter { struct { + const char *server; + const char *printer; + DATA_BLOB *buffer; + uint32 access_mask; } in; struct { - NTSTATUS result; + struct policy_handle *handle; + WERROR result; } out; }; @@ -1135,7 +1140,7 @@ struct spoolss_5f { }; #define DCERPC_SPOOLSS_ENUMPRINTERS 0 -#define DCERPC_SPOOLSS_01 1 +#define DCERPC_SPOOLSS_OPENPRINTER 1 #define DCERPC_SPOOLSS_02 2 #define DCERPC_SPOOLSS_03 3 #define DCERPC_SPOOLSS_ENUMJOBS 4 diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 6e6436887b..aa8b8520f3 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -814,3 +814,10 @@ failed: } +/* + a useful function for retrieving the server name we connected to +*/ +const char *dcerpc_server_name(struct dcerpc_pipe *p) +{ + return p->tree->session->transport->called.name; +} diff --git a/source4/librpc/rpc/rpc_spoolss.c b/source4/librpc/rpc/rpc_spoolss.c index 366072c42c..e2d3a1ae35 100644 --- a/source4/librpc/rpc/rpc_spoolss.c +++ b/source4/librpc/rpc/rpc_spoolss.c @@ -11,18 +11,12 @@ NTSTATUS dcerpc_spoolss_EnumPrinters(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r); } -NTSTATUS dcerpc_spoolss_01(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct spoolss_01 *r) +NTSTATUS dcerpc_spoolss_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct spoolss_OpenPrinter *r) { - NTSTATUS status; - status = dcerpc_ndr_request(p, DCERPC_SPOOLSS_01, mem_ctx, - (ndr_push_fn_t) ndr_push_spoolss_01, - (ndr_pull_fn_t) ndr_pull_spoolss_01, - r); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - return r->out.result; + return dcerpc_ndr_request(p, DCERPC_SPOOLSS_OPENPRINTER, mem_ctx, + (ndr_push_fn_t) ndr_push_spoolss_OpenPrinter, + (ndr_pull_fn_t) ndr_pull_spoolss_OpenPrinter, + r); } NTSTATUS dcerpc_spoolss_02(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct spoolss_02 *r) diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index 13e2b2642f..0f104491b6 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -21,6 +21,35 @@ #include "includes.h" +static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, + struct spoolss_PrinterInfo1 *info1) +{ + NTSTATUS status; + struct spoolss_OpenPrinter r; + struct policy_handle handle; + DATA_BLOB blob; + + blob = data_blob(NULL, 0); + + r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); + r.in.printer = info1->name; + r.in.buffer = &blob; + r.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED; + r.out.handle = &handle; + + printf("Testing OpenPrinter(\\\\%s\\%s)\n", r.in.server, r.in.printer); + + status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { + printf("OpenPrinter failed - %s/%s\n", + nt_errstr(status), win_errstr(r.out.result)); + return False; + } + + + return True; +} + static BOOL test_EnumPrinters(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) { struct spoolss_EnumPrinters r; @@ -74,6 +103,13 @@ static BOOL test_EnumPrinters(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) printf("Printer %d\n", j); NDR_PRINT_UNION_DEBUG(spoolss_PrinterEnum, r.in.level, &info[j]); } + + for (j=0;j<r.out.count;j++) { + if (r.in.level == 1 && + !test_OpenPrinter(p, mem_ctx, &info[j].info1)) { + ret = False; + } + } } return ret; |