summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/include/structs.h2
-rw-r--r--source4/librpc/idl/spoolss.idl51
-rw-r--r--source4/librpc/ndr/ndr_spoolss_buf.c274
-rw-r--r--source4/torture/rpc/spoolss.c633
4 files changed, 951 insertions, 9 deletions
diff --git a/source4/include/structs.h b/source4/include/structs.h
index c11a2a054b..c69bc87fa7 100644
--- a/source4/include/structs.h
+++ b/source4/include/structs.h
@@ -28,6 +28,8 @@ struct spoolss_EnumForms;
struct spoolss_EnumJobs;
struct spoolss_EnumPrinterDrivers;
struct spoolss_EnumPorts;
+struct spoolss_EnumMonitors;
+struct spoolss_EnumPrintProcessors;
struct drsuapi_DsReplicaObjectListItem;
struct drsuapi_DsReplicaObjectListItemEx;
diff --git a/source4/librpc/idl/spoolss.idl b/source4/librpc/idl/spoolss.idl
index 79b8d5b7cc..d5bfd687ac 100644
--- a/source4/librpc/idl/spoolss.idl
+++ b/source4/librpc/idl/spoolss.idl
@@ -243,6 +243,7 @@
[case(7)] spoolss_PrinterInfo7 info7;
[case(8)] spoolss_DeviceModeInfo info8;
[case(9)] spoolss_DeviceModeInfo info9;
+ [default];
} spoolss_PrinterInfo;
/******************/
@@ -315,6 +316,7 @@
typedef [nodiscriminant,public] union {
[case(1)] spoolss_JobInfo1 info1;
+ [default];
} spoolss_JobInfo;
/******************/
@@ -463,6 +465,7 @@
[case(4)] spoolss_DriverInfo4 info4;
[case(5)] spoolss_DriverInfo5 info5;
[case(6)] spoolss_DriverInfo6 info6;
+ [default];
} spoolss_DriverInfo;
/******************/
@@ -504,7 +507,25 @@
/******************/
/* Function: 0x0f */
- WERROR spoolss_EnumPrintProcessors(
+ typedef struct {
+ [relative] nstring *print_processor_name;
+ } spoolss_PrintProcessorInfo1;
+
+ typedef [nodiscriminant,public] union {
+ [case(1)] spoolss_PrintProcessorInfo1 info1;
+ [default];
+ } spoolss_PrintProcessorInfo;
+
+ [noprint,nopull,nopush] WERROR spoolss_EnumPrintProcessors(
+ [in] unistr *servername,
+ [in] unistr *environment,
+ [in] uint32 level,
+ [in] DATA_BLOB *buffer,
+ /* [out,subcontext(4),switch_is(level)] spoolss_PrintProcessorInfo *info[count],*/
+ [out,subcontext(4),switch_is(level)] spoolss_PrintProcessorInfo **info,
+ /* [out,subcontext(4),flag(NDR_REMAINING)] DATA_BLOB *info,*/
+ [in,out,ref] uint32 *buf_size,
+ [out] uint32 count
);
/******************/
@@ -668,6 +689,7 @@
typedef [nodiscriminant,public] union {
[case(1)] spoolss_FormInfo1 info1;
+ [default];
} spoolss_FormInfo;
/******************/
@@ -704,6 +726,7 @@
typedef [nodiscriminant,public] union {
[case(1)] spoolss_PortInfo1 info1;
[case(2)] spoolss_PortInfo2 info2;
+ [default];
} spoolss_PortInfo;
/******************/
@@ -720,7 +743,31 @@
/******************/
/* Function: 0x24 */
- WERROR spoolss_EnumMonitors(
+ typedef struct {
+ [relative] nstring *monitor_name;
+ } spoolss_MonitorInfo1;
+
+ typedef struct {
+ [relative] nstring *monitor_name;
+ [relative] nstring *environment;
+ [relative] nstring *dll_name;
+ } spoolss_MonitorInfo2;
+
+ typedef [nodiscriminant,public] union {
+ [case(1)] spoolss_MonitorInfo1 info1;
+ [case(2)] spoolss_MonitorInfo2 info2;
+ [default];
+ } spoolss_MonitorInfo;
+
+ [noprint,nopull,nopush] WERROR spoolss_EnumMonitors(
+ [in] unistr *servername,
+ [in] uint32 level,
+ [in] DATA_BLOB *buffer,
+ /* [out,subcontext(4),switch_is(level)] spoolss_MonitorInfo *info[count], */
+ [out,subcontext(4),switch_is(level)] spoolss_MonitorInfo **info,
+ /* [out,subcontext(4),flag(NDR_REMAINING)] DATA_BLOB *info,*/
+ [in,out,ref] uint32 *buf_size,
+ [out] uint32 count
);
/******************/
diff --git a/source4/librpc/ndr/ndr_spoolss_buf.c b/source4/librpc/ndr/ndr_spoolss_buf.c
index ecb8f374c6..4da604b187 100644
--- a/source4/librpc/ndr/ndr_spoolss_buf.c
+++ b/source4/librpc/ndr/ndr_spoolss_buf.c
@@ -711,3 +711,277 @@ void ndr_print_spoolss_EnumPorts(struct ndr_print *ndr, const char *name, int fl
}
ndr->depth--;
}
+
+/*
+ spoolss_EnumMonitors
+*/
+NTSTATUS ndr_push_spoolss_EnumMonitors(struct ndr_push *ndr, int flags, struct spoolss_EnumMonitors *r)
+{
+ if (!(flags & NDR_IN)) goto ndr_out;
+
+ { uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4);
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.servername));
+ ndr->flags = _flags_save_string;
+ }
+ { uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4);
+ if (r->in.servername) {
+ NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.servername));
+ }
+ ndr->flags = _flags_save_string;
+ }
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.level));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.buffer));
+ if (r->in.buffer) {
+ NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buffer));
+ }
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buf_size));
+ ndr_out:
+ if (!(flags & NDR_OUT)) goto done;
+
+ NDR_SPOOLSS_PUSH_ENUM_OUT(spoolss_EnumMonitors,spoolss_MonitorInfo);
+
+ done:
+ return NT_STATUS_OK;
+}
+
+NTSTATUS ndr_pull_spoolss_EnumMonitors(struct ndr_pull *ndr, int flags, struct spoolss_EnumMonitors *r)
+{
+ uint32_t _ptr_servername;
+ uint32_t _ptr_buffer;
+ uint32_t _ptr_info;
+ if (!(flags & NDR_IN)) goto ndr_out;
+
+ ZERO_STRUCT(r->out);
+
+ { uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4);
+ NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_servername));
+ if (_ptr_servername) {
+ NDR_ALLOC(ndr, r->in.servername);
+ } else {
+ r->in.servername = NULL;
+ }
+ ndr->flags = _flags_save_string;
+ }
+ { uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4);
+ if (r->in.servername) {
+ NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.servername));
+ }
+ ndr->flags = _flags_save_string;
+ }
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.level));
+ NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_buffer));
+ if (_ptr_buffer) {
+ NDR_ALLOC(ndr, r->in.buffer);
+ } else {
+ r->in.buffer = NULL;
+ }
+ if (r->in.buffer) {
+ NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buffer));
+ }
+ NDR_ALLOC(ndr, r->in.buf_size);
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buf_size));
+ NDR_ALLOC(ndr, r->out.buf_size);
+ *r->out.buf_size = *r->in.buf_size;
+ ndr_out:
+ if (!(flags & NDR_OUT)) goto done;
+
+ NDR_SPOOLSS_PULL_ENUM_OUT(spoolss_EnumMonitors,spoolss_MonitorInfo);
+
+ done:
+
+ return NT_STATUS_OK;
+}
+
+void ndr_print_spoolss_EnumMonitors(struct ndr_print *ndr, const char *name, int flags, struct spoolss_EnumMonitors *r)
+{
+ ndr_print_struct(ndr, name, "spoolss_EnumMonitors");
+ ndr->depth++;
+ if (flags & NDR_SET_VALUES) {
+ ndr->flags |= LIBNDR_PRINT_SET_VALUES;
+ }
+ if (flags & NDR_IN) {
+ ndr_print_struct(ndr, "in", "spoolss_EnumMonitors");
+ ndr->depth++;
+ ndr_print_ptr(ndr, "servername", r->in.servername);
+ ndr->depth++;
+ if (r->in.servername) {
+ ndr_print_string(ndr, "servername", r->in.servername);
+ }
+ ndr->depth--;
+ ndr_print_uint32(ndr, "level", r->in.level);
+ ndr_print_ptr(ndr, "buffer", r->in.buffer);
+ ndr->depth++;
+ if (r->in.buffer) {
+ ndr_print_DATA_BLOB(ndr, "buffer", *r->in.buffer);
+ }
+ ndr->depth--;
+ ndr_print_ptr(ndr, "buf_size", r->in.buf_size);
+ ndr->depth++;
+ ndr_print_uint32(ndr, "buf_size", *r->in.buf_size);
+ ndr->depth--;
+ ndr->depth--;
+ }
+ if (flags & NDR_OUT) {
+ NDR_SPOOLSS_PRINT_ENUM_OUT(spoolss_EnumMonitors,spoolss_MonitorInfo);
+ }
+ ndr->depth--;
+}
+
+/*
+ spoolss_EnumPrintProcessors
+*/
+NTSTATUS ndr_push_spoolss_EnumPrintProcessors(struct ndr_push *ndr, int flags, struct spoolss_EnumPrintProcessors *r)
+{
+ if (!(flags & NDR_IN)) goto ndr_out;
+
+ { uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4);
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.servername));
+ ndr->flags = _flags_save_string;
+ }
+ { uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4);
+ if (r->in.servername) {
+ NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.servername));
+ }
+ ndr->flags = _flags_save_string;
+ }
+ { uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4);
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.environment));
+ ndr->flags = _flags_save_string;
+ }
+ { uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4);
+ if (r->in.environment) {
+ NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.environment));
+ }
+ ndr->flags = _flags_save_string;
+ }
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.level));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.buffer));
+ if (r->in.buffer) {
+ NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buffer));
+ }
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buf_size));
+ ndr_out:
+ if (!(flags & NDR_OUT)) goto done;
+
+ NDR_SPOOLSS_PUSH_ENUM_OUT(spoolss_EnumPrintProcessors,spoolss_PrintProcessorInfo);
+
+ done:
+ return NT_STATUS_OK;
+}
+
+NTSTATUS ndr_pull_spoolss_EnumPrintProcessors(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrintProcessors *r)
+{
+ uint32_t _ptr_servername;
+ uint32_t _ptr_environment;
+ uint32_t _ptr_buffer;
+ uint32_t _ptr_info;
+ if (!(flags & NDR_IN)) goto ndr_out;
+
+ ZERO_STRUCT(r->out);
+
+ { uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4);
+ NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_servername));
+ if (_ptr_servername) {
+ NDR_ALLOC(ndr, r->in.servername);
+ } else {
+ r->in.servername = NULL;
+ }
+ ndr->flags = _flags_save_string;
+ }
+ { uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4);
+ if (r->in.servername) {
+ NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.servername));
+ }
+ ndr->flags = _flags_save_string;
+ }
+ { uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4);
+ NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_environment));
+ if (_ptr_environment) {
+ NDR_ALLOC(ndr, r->in.environment);
+ } else {
+ r->in.environment = NULL;
+ }
+ ndr->flags = _flags_save_string;
+ }
+ { uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4);
+ if (r->in.environment) {
+ NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.environment));
+ }
+ ndr->flags = _flags_save_string;
+ }
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.level));
+ NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_buffer));
+ if (_ptr_buffer) {
+ NDR_ALLOC(ndr, r->in.buffer);
+ } else {
+ r->in.buffer = NULL;
+ }
+ if (r->in.buffer) {
+ NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buffer));
+ }
+ NDR_ALLOC(ndr, r->in.buf_size);
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buf_size));
+ NDR_ALLOC(ndr, r->out.buf_size);
+ *r->out.buf_size = *r->in.buf_size;
+ ndr_out:
+ if (!(flags & NDR_OUT)) goto done;
+
+ NDR_SPOOLSS_PULL_ENUM_OUT(spoolss_EnumPrintProcessors,spoolss_PrintProcessorInfo);
+
+ done:
+
+ return NT_STATUS_OK;
+}
+
+void ndr_print_spoolss_EnumPrintProcessors(struct ndr_print *ndr, const char *name, int flags, struct spoolss_EnumPrintProcessors *r)
+{
+ ndr_print_struct(ndr, name, "spoolss_EnumPrintProcessors");
+ ndr->depth++;
+ if (flags & NDR_SET_VALUES) {
+ ndr->flags |= LIBNDR_PRINT_SET_VALUES;
+ }
+ if (flags & NDR_IN) {
+ ndr_print_struct(ndr, "in", "spoolss_EnumPrintProcessors");
+ ndr->depth++;
+ ndr_print_ptr(ndr, "servername", r->in.servername);
+ ndr->depth++;
+ if (r->in.servername) {
+ ndr_print_string(ndr, "servername", r->in.servername);
+ }
+ ndr->depth--;
+ ndr_print_ptr(ndr, "environment", r->in.environment);
+ ndr->depth++;
+ if (r->in.environment) {
+ ndr_print_string(ndr, "environment", r->in.environment);
+ }
+ ndr->depth--;
+ ndr_print_uint32(ndr, "level", r->in.level);
+ ndr_print_ptr(ndr, "buffer", r->in.buffer);
+ ndr->depth++;
+ if (r->in.buffer) {
+ ndr_print_DATA_BLOB(ndr, "buffer", *r->in.buffer);
+ }
+ ndr->depth--;
+ ndr_print_ptr(ndr, "buf_size", r->in.buf_size);
+ ndr->depth++;
+ ndr_print_uint32(ndr, "buf_size", *r->in.buf_size);
+ ndr->depth--;
+ ndr->depth--;
+ }
+ if (flags & NDR_OUT) {
+ NDR_SPOOLSS_PRINT_ENUM_OUT(spoolss_EnumPrintProcessors,spoolss_PrintProcessorInfo);
+ }
+ ndr->depth--;
+}
diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c
index acaa5828dc..c2be0b5324 100644
--- a/source4/torture/rpc/spoolss.c
+++ b/source4/torture/rpc/spoolss.c
@@ -3,6 +3,7 @@
test suite for spoolss rpc operations
Copyright (C) Tim Potter 2003
+ Copyright (C) Stefan Metzmacher 2005
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
@@ -22,6 +23,610 @@
#include "includes.h"
#include "librpc/gen_ndr/ndr_spoolss.h"
+struct test_spoolss_context {
+ struct dcerpc_pipe *p;
+
+ /* for EnumPorts */
+ uint32_t port_count[3];
+ union spoolss_PortInfo **ports[3];
+
+ /* for EnumPrinterDrivers */
+ uint32_t driver_count[7];
+ union spoolss_DriverInfo **drivers[7];
+
+ /* for EnumMonitors */
+ uint32_t monitor_count[3];
+ union spoolss_MonitorInfo **monitors[3];
+
+ /* for EnumPrintProcessors */
+ uint32_t print_processor_count[2];
+ union spoolss_PrintProcessorInfo **print_processors[2];
+
+ /* for EnumPrinters */
+ uint32_t printer_count[6];
+ union spoolss_PrinterInfo **printers[6];
+};
+
+#define COMPARE_STRING(c,r,e) do {\
+ BOOL _ok = True;\
+ if (c.e && !r.e) _ok = False;\
+ if (!c.e && r.e) _ok = False;\
+ if (c.e && r.e && strcmp_safe(c.e, r.e) != 0) _ok = False;\
+ if (!_ok){\
+ printf("%s: " #c "." #e " [%s] doesn't match " #r "." #e " [%s]\n",\
+ __location__, c.e, r.e);\
+ ret = False;\
+ }\
+} while(0)
+
+#define COMPARE_UINT16(c,r,e) do {\
+ if (c.e != r.e){\
+ printf("%s: " #c "." #e " 0x%08X (%u) doesn't match " #r "." #e " 0x%08X (%u)\n",\
+ __location__, c.e, c.e, r.e, r.e);\
+ ret = False;\
+ }\
+} while(0)
+
+#define COMPARE_UINT32(c,r,e) do {\
+ if (c.e != r.e){\
+ printf("%s: " #c "." #e " 0x%04X (%u) doesn't match " #r "." #e " 0x%04X (%u)\n",\
+ __location__, c.e, c.e, r.e, r.e);\
+ ret = False;\
+ }\
+} while(0)
+
+#define COMPARE_UINT64(c,r,e) do {\
+ if (c.e != r.e){\
+ printf("%s: " #c "." #e " 0x%08X%08X (%llu) doesn't match " #r "." #e " 0x%08X%08X (%llu)\n",\
+ __location__, (uint32_t)(c.e >> 32), (uint32_t)(c.e & 0xFFFFFFFF), c.e,\
+ (uint32_t)(r.e >> 32), (uint32_t)(r.e & 0xFFFFFFFF), r.e);\
+ ret = False;\
+ }\
+} while(0)
+
+/* TODO: ! */
+#define COMPARE_SEC_DESC(c,r,e)
+#define COMPARE_SPOOLSS_TIME(c,r,e)
+#define COMPARE_STRING_ARRAY(c,r,e)
+
+static BOOL test_EnumPorts(struct test_spoolss_context *ctx)
+{
+ NTSTATUS status;
+ struct spoolss_EnumPorts r;
+ uint16_t levels[] = { 1, 2 };
+ int i, j;
+ BOOL ret = True;
+
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ DATA_BLOB blob;
+ uint32_t buf_size = 0;
+
+ r.in.servername = "";
+ r.in.level = level;
+ r.in.buffer = NULL;
+ buf_size = 0;
+ r.in.buf_size = &buf_size;
+ r.out.buf_size = &buf_size;
+
+ printf("Testing EnumPorts level %u\n", r.in.level);
+
+ status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status));
+ ret = False;
+ continue;
+ }
+
+ if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ printf("EnumPorts unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
+ win_errstr(r.out.result));
+ ret = False;
+ continue;
+ }
+
+ blob = data_blob_talloc(ctx, NULL, buf_size);
+ data_blob_clear(&blob);
+ r.in.buffer = &blob;
+
+ status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status));
+ ret = False;
+ continue;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("EnumPorts failed - %s\n",
+ win_errstr(r.out.result));
+ ret = False;
+ continue;
+ }
+
+ ctx->port_count[level] = r.out.count;
+ ctx->ports[level] = r.out.info;
+ }
+
+ for (i=1;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ int old_level = levels[i-1];
+ if (ctx->port_count[level] != ctx->port_count[old_level]) {
+ printf("EnumPorts level[%d] returns [%u] ports, but level[%d] returns [%u]\n",
+ level, ctx->port_count[level], old_level, ctx->port_count[old_level]);
+ ret = False;
+ }
+ }
+ /* if the array sizes are not the same we would maybe segfault in the following code */
+ if (!ret) return ret;
+
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ for (j=0;j<ctx->port_count[level];j++) {
+ union spoolss_PortInfo *cur = &ctx->ports[level][0][j];
+ union spoolss_PortInfo *ref = &ctx->ports[2][0][j];
+ switch (level) {
+ case 1:
+ COMPARE_STRING(cur->info1, ref->info2, port_name);
+ break;
+ case 2:
+ /* level 2 is our reference, and it makes no sense to compare it to itself */
+ break;
+ }
+ }
+ }
+
+ return True;
+}
+
+static BOOL test_EnumPrinterDrivers(struct test_spoolss_context *ctx)
+{
+ NTSTATUS status;
+ struct spoolss_EnumPrinterDrivers r;
+ uint16_t levels[] = { 1, 2, 3, 4, 5, 6 };
+ int i, j;
+ BOOL ret = True;
+
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ DATA_BLOB blob;
+ uint32_t buf_size = 0;
+
+ r.in.server = "";
+ r.in.environment = "Windows NT x86";
+ r.in.level = level;
+ r.in.buffer = NULL;
+ buf_size = 0;
+ r.in.buf_size = &buf_size;
+ r.out.buf_size = &buf_size;
+
+ printf("Testing EnumPrinterDrivers level %u\n", r.in.level);
+
+ status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status));
+ ret = False;
+ continue;
+ }
+
+ if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ printf("EnumPrinterDrivers unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
+ win_errstr(r.out.result));
+ ret = False;
+ continue;
+ }
+
+ blob = data_blob_talloc(ctx, NULL, buf_size);
+ data_blob_clear(&blob);
+ r.in.buffer = &blob;
+
+ status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status));
+ ret = False;
+ continue;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("EnumPrinterDrivers failed - %s\n",
+ win_errstr(r.out.result));
+ ret = False;
+ continue;
+ }
+
+ ctx->driver_count[level] = r.out.count;
+ ctx->drivers[level] = r.out.info;
+ }
+
+ for (i=1;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ int old_level = levels[i-1];
+ if (ctx->driver_count[level] != ctx->driver_count[old_level]) {
+ printf("EnumPrinterDrivers level[%d] returns [%u] drivers, but level[%d] returns [%u]\n",
+ level, ctx->driver_count[level], old_level, ctx->driver_count[old_level]);
+ ret = False;
+ }
+ }
+ /* if the array sizes are not the same we would maybe segfault in the following code */
+ if (!ret) return ret;
+
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ for (j=0;j<ctx->driver_count[level];j++) {
+ union spoolss_DriverInfo *cur = &ctx->drivers[level][0][j];
+ union spoolss_DriverInfo *ref = &ctx->drivers[6][0][j];
+ switch (level) {
+ case 1:
+ COMPARE_STRING(cur->info1, ref->info6, driver_name);
+ break;
+ case 2:
+ COMPARE_UINT32(cur->info2, ref->info6, version);
+ COMPARE_STRING(cur->info2, ref->info6, driver_name);
+ COMPARE_STRING(cur->info2, ref->info6, architecture);
+ COMPARE_STRING(cur->info2, ref->info6, driver_path);
+ COMPARE_STRING(cur->info2, ref->info6, data_file);
+ COMPARE_STRING(cur->info2, ref->info6, config_file);
+ break;
+ case 3:
+ COMPARE_UINT32(cur->info3, ref->info6, version);
+ COMPARE_STRING(cur->info3, ref->info6, driver_name);
+ COMPARE_STRING(cur->info3, ref->info6, architecture);
+ COMPARE_STRING(cur->info3, ref->info6, driver_path);
+ COMPARE_STRING(cur->info3, ref->info6, data_file);
+ COMPARE_STRING(cur->info3, ref->info6, config_file);
+ COMPARE_STRING(cur->info3, ref->info6, help_file);
+ COMPARE_STRING_ARRAY(cur->info3, ref->info6, dependent_files);
+ COMPARE_STRING(cur->info3, ref->info6, monitor_name);
+ COMPARE_STRING(cur->info3, ref->info6, default_datatype);
+ break;
+ case 4:
+ COMPARE_UINT32(cur->info4, ref->info6, version);
+ COMPARE_STRING(cur->info4, ref->info6, driver_name);
+ COMPARE_STRING(cur->info4, ref->info6, architecture);
+ COMPARE_STRING(cur->info4, ref->info6, driver_path);
+ COMPARE_STRING(cur->info4, ref->info6, data_file);
+ COMPARE_STRING(cur->info4, ref->info6, config_file);
+ COMPARE_STRING(cur->info4, ref->info6, help_file);
+ COMPARE_STRING_ARRAY(cur->info4, ref->info6, dependent_files);
+ COMPARE_STRING(cur->info4, ref->info6, monitor_name);
+ COMPARE_STRING(cur->info4, ref->info6, default_datatype);
+ COMPARE_STRING_ARRAY(cur->info4, ref->info6, previous_names);
+ break;
+ case 5:
+ COMPARE_UINT32(cur->info5, ref->info6, version);
+ COMPARE_STRING(cur->info5, ref->info6, driver_name);
+ COMPARE_STRING(cur->info5, ref->info6, architecture);
+ COMPARE_STRING(cur->info5, ref->info6, driver_path);
+ COMPARE_STRING(cur->info5, ref->info6, data_file);
+ COMPARE_STRING(cur->info5, ref->info6, config_file);
+ /*COMPARE_UINT32(cur->info5, ref->info6, driver_attributes);*/
+ /*COMPARE_UINT32(cur->info5, ref->info6, config_version);*/
+ /*TODO: ! COMPARE_UINT32(cur->info5, ref->info6, driver_version); */
+ break;
+ case 6:
+ /* level 6 is our reference, and it makes no sense to compare it to itself */
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static BOOL test_EnumMonitors(struct test_spoolss_context *ctx)
+{
+ NTSTATUS status;
+ struct spoolss_EnumMonitors r;
+ uint16_t levels[] = { 1, 2 };
+ int i, j;
+ BOOL ret = True;
+
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ DATA_BLOB blob;
+ uint32_t buf_size = 0;
+
+ r.in.servername = "";
+ r.in.level = level;
+ r.in.buffer = NULL;
+ buf_size = 0;
+ r.in.buf_size = &buf_size;
+ r.out.buf_size = &buf_size;
+
+ printf("Testing EnumMonitors level %u\n", r.in.level);
+
+ status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status));
+ ret = False;
+ continue;
+ }
+
+ if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ printf("EnumMonitors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
+ win_errstr(r.out.result));
+ ret = False;
+ continue;
+ }
+
+ blob = data_blob_talloc(ctx, NULL, buf_size);
+ data_blob_clear(&blob);
+ r.in.buffer = &blob;
+
+ status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status));
+ ret = False;
+ continue;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("EnumMonitors failed - %s\n",
+ win_errstr(r.out.result));
+ ret = False;
+ continue;
+ }
+
+ ctx->monitor_count[level] = r.out.count;
+ ctx->monitors[level] = r.out.info;
+ }
+
+ for (i=1;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ int old_level = levels[i-1];
+ if (ctx->monitor_count[level] != ctx->monitor_count[old_level]) {
+ printf("EnumMonitors level[%d] returns [%u] monitors, but level[%d] returns [%u]\n",
+ level, ctx->monitor_count[level], old_level, ctx->monitor_count[old_level]);
+ ret = False;
+ }
+ }
+ /* if the array sizes are not the same we would maybe segfault in the following code */
+ if (!ret) return ret;
+
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ for (j=0;j<ctx->monitor_count[level];j++) {
+ union spoolss_MonitorInfo *cur = &ctx->monitors[level][0][j];
+ union spoolss_MonitorInfo *ref = &ctx->monitors[2][0][j];
+ switch (level) {
+ case 1:
+ COMPARE_STRING(cur->info1, ref->info2, monitor_name);
+ break;
+ case 2:
+ /* level 2 is our reference, and it makes no sense to compare it to itself */
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static BOOL test_EnumPrintProcessors(struct test_spoolss_context *ctx)
+{
+ NTSTATUS status;
+ struct spoolss_EnumPrintProcessors r;
+ uint16_t levels[] = { 1 };
+ int i, j;
+ BOOL ret = True;
+
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ DATA_BLOB blob;
+ uint32_t buf_size = 0;
+
+ r.in.servername = "";
+ r.in.environment = "Windows NT x86";
+ r.in.level = level;
+ r.in.buffer = NULL;
+ buf_size = 0;
+ r.in.buf_size = &buf_size;
+ r.out.buf_size = &buf_size;
+
+ printf("Testing EnumPrintProcessors level %u\n", r.in.level);
+
+ status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status));
+ ret = False;
+ continue;
+ }
+
+ if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ printf("EnumPrintProcessors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
+ win_errstr(r.out.result));
+ ret = False;
+ continue;
+ }
+
+ blob = data_blob_talloc(ctx, NULL, buf_size);
+ data_blob_clear(&blob);
+ r.in.buffer = &blob;
+
+ status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status));
+ ret = False;
+ continue;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("EnumPrintProcessors failed - %s\n",
+ win_errstr(r.out.result));
+ ret = False;
+ continue;
+ }
+
+ ctx->print_processor_count[level] = r.out.count;
+ ctx->print_processors[level] = r.out.info;
+ }
+
+ for (i=1;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ int old_level = levels[i-1];
+ if (ctx->print_processor_count[level] != ctx->print_processor_count[old_level]) {
+ printf("EnumPrintProcessors level[%d] returns [%u] print_processors, but level[%d] returns [%u]\n",
+ level, ctx->print_processor_count[level], old_level, ctx->print_processor_count[old_level]);
+ ret = False;
+ }
+ }
+ /* if the array sizes are not the same we would maybe segfault in the following code */
+ if (!ret) return ret;
+
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ for (j=0;j<ctx->print_processor_count[level];j++) {
+#if 0
+ union spoolss_PrintProcessorInfo *cur = &ctx->print_processors[level][0][j];
+ union spoolss_PrintProcessorInfo *ref = &ctx->print_processors[1][0][j];
+#endif
+ switch (level) {
+ case 1:
+ /* level 1 is our reference, and it makes no sense to compare it to itself */
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static BOOL test_EnumPrinters(struct test_spoolss_context *ctx)
+{
+ struct spoolss_EnumPrinters r;
+ NTSTATUS status;
+ uint16_t levels[] = { 0, 1, 2, 4, 5 };
+ int i, j;
+ BOOL ret = True;
+
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ DATA_BLOB blob;
+ uint32_t buf_size = 0;
+
+ r.in.flags = PRINTER_ENUM_LOCAL;
+ r.in.server = "";
+ r.in.level = level;
+ r.in.buffer = NULL;
+ r.in.buf_size = &buf_size;
+ r.out.buf_size = &buf_size;
+
+ printf("\nTesting EnumPrinters level %u\n", r.in.level);
+
+ status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
+ ret = False;
+ continue;
+ }
+
+ if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ printf("EnumPrinters unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
+ win_errstr(r.out.result));
+ ret = False;
+ continue;
+ }
+
+ blob = data_blob_talloc(ctx, NULL, buf_size);
+ data_blob_clear(&blob);
+ r.in.buffer = &blob;
+ status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
+ ret = False;
+ continue;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("EnumPrinters failed - %s\n",
+ win_errstr(r.out.result));
+ continue;
+ }
+
+ ctx->printer_count[level] = r.out.count;
+ ctx->printers[level] = r.out.info;
+ }
+
+ for (i=1;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ int old_level = levels[i-1];
+ if (ctx->printer_count[level] != ctx->printer_count[old_level]) {
+ printf("EnumPrinters level[%d] returns [%u] printers, but level[%d] returns [%u]\n",
+ level, ctx->printer_count[level], old_level, ctx->printer_count[old_level]);
+ ret = False;
+ }
+ }
+ /* if the array sizes are not the same we would maybe segfault in the following code */
+ if (!ret) return ret;
+
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ int level = levels[i];
+ for (j=0;j<ctx->printer_count[level];j++) {
+ union spoolss_PrinterInfo *cur = &ctx->printers[level][0][j];
+ union spoolss_PrinterInfo *ref = &ctx->printers[2][0][j];
+ switch (level) {
+ case 0:
+ COMPARE_STRING(cur->info0, ref->info2, printername);
+ COMPARE_STRING(cur->info0, ref->info2, servername);
+ COMPARE_UINT32(cur->info0, ref->info2, cjobs);
+ /*COMPARE_UINT32(cur->info0, ref->info2, total_jobs);
+ COMPARE_UINT32(cur->info0, ref->info2, total_bytes);
+ COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);
+ COMPARE_UINT32(cur->info0, ref->info2, global_counter);
+ COMPARE_UINT32(cur->info0, ref->info2, total_pages);
+ COMPARE_UINT32(cur->info0, ref->info2, version);
+ COMPARE_UINT32(cur->info0, ref->info2, unknown10);
+ COMPARE_UINT32(cur->info0, ref->info2, unknown11);
+ COMPARE_UINT32(cur->info0, ref->info2, unknown12);
+ COMPARE_UINT32(cur->info0, ref->info2, session_counter);
+ COMPARE_UINT32(cur->info0, ref->info2, unknown14);
+ COMPARE_UINT32(cur->info0, ref->info2, printer_errors);
+ COMPARE_UINT32(cur->info0, ref->info2, unknown16);
+ COMPARE_UINT32(cur->info0, ref->info2, unknown17);
+ COMPARE_UINT32(cur->info0, ref->info2, unknown18);
+ COMPARE_UINT32(cur->info0, ref->info2, unknown19);
+ COMPARE_UINT32(cur->info0, ref->info2, change_id);
+ COMPARE_UINT32(cur->info0, ref->info2, unknown21);*/
+ COMPARE_UINT32(cur->info0, ref->info2, status);
+ /*COMPARE_UINT32(cur->info0, ref->info2, unknown23);
+ COMPARE_UINT32(cur->info0, ref->info2, c_setprinter);
+ COMPARE_UINT16(cur->info0, ref->info2, unknown25);
+ COMPARE_UINT16(cur->info0, ref->info2, unknown26);
+ COMPARE_UINT32(cur->info0, ref->info2, unknown27);
+ COMPARE_UINT32(cur->info0, ref->info2, unknown28);
+ COMPARE_UINT32(cur->info0, ref->info2, unknown29);*/
+ break;
+ case 1:
+ /*COMPARE_UINT32(cur->info1, ref->info2, flags);*/
+ /*COMPARE_STRING(cur->info1, ref->info2, name);*/
+ /*COMPARE_STRING(cur->info1, ref->info2, description);*/
+ COMPARE_STRING(cur->info1, ref->info2, comment);
+ break;
+ case 2:
+ /* level 2 is our reference, and it makes no sense to compare it to itself */
+ break;
+ case 4:
+ COMPARE_STRING(cur->info4, ref->info2, printername);
+ COMPARE_STRING(cur->info4, ref->info2, servername);
+ COMPARE_UINT32(cur->info4, ref->info2, attributes);
+ break;
+ case 5:
+ COMPARE_STRING(cur->info5, ref->info2, printername);
+ COMPARE_STRING(cur->info5, ref->info2, portname);
+ COMPARE_UINT32(cur->info5, ref->info2, attributes);
+ /*COMPARE_UINT32(cur->info5, ref->info2, device_not_selected_timeout);
+ COMPARE_UINT32(cur->info5, ref->info2, transmission_retry_timeout);*/
+ break;
+ }
+ }
+ }
+
+ /* TODO:
+ * - verify that the port of a printer was in the list returned by EnumPorts
+ */
+
+ return ret;
+}
+
static BOOL test_GetPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle)
{
@@ -284,7 +889,7 @@ static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return ret;
}
-static BOOL test_EnumPorts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+static BOOL test_EnumPorts_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
{
NTSTATUS status;
struct spoolss_EnumPorts r;
@@ -975,7 +1580,7 @@ static BOOL test_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return ret;
}
-static BOOL test_EnumPrinters(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+static BOOL test_EnumPrinters_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
{
struct spoolss_EnumPrinters r;
NTSTATUS status;
@@ -1095,8 +1700,8 @@ static BOOL test_GetPrinterDriver2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return True;
}
#endif
-
-static BOOL test_EnumPrinterDrivers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+
+static BOOL test_EnumPrinterDrivers_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
{
struct spoolss_EnumPrinterDrivers r;
NTSTATUS status;
@@ -1164,6 +1769,7 @@ BOOL torture_rpc_spoolss(void)
struct dcerpc_pipe *p;
TALLOC_CTX *mem_ctx;
BOOL ret = True;
+ struct test_spoolss_context *ctx;
mem_ctx = talloc_init("torture_rpc_spoolss");
@@ -1177,15 +1783,28 @@ BOOL torture_rpc_spoolss(void)
return False;
}
+ ctx = talloc_zero(mem_ctx, struct test_spoolss_context);
+ ctx->p = p;
+
+ ret &= test_EnumPorts(ctx);
+
+ ret &= test_EnumPrinterDrivers(ctx);
+
+ ret &= test_EnumMonitors(ctx);
+
+ ret &= test_EnumPrintProcessors(ctx);
+
+ ret &= test_EnumPrinters(ctx);
+
ret &= test_OpenPrinter_badnames(p, mem_ctx);
ret &= test_AddPort(p, mem_ctx);
- ret &= test_EnumPorts(p, mem_ctx);
+ ret &= test_EnumPorts_old(p, mem_ctx);
- ret &= test_EnumPrinters(p, mem_ctx);
+ ret &= test_EnumPrinters_old(p, mem_ctx);
- ret &= test_EnumPrinterDrivers(p, mem_ctx);
+ ret &= test_EnumPrinterDrivers_old(p, mem_ctx);
talloc_free(mem_ctx);