spoolss.c
来自「samba最新软件」· C语言 代码 · 共 1,770 行 · 第 1/4 页
C
1,770 行
/* Unix SMB/CIFS implementation. test suite for spoolss rpc operations Copyright (C) Tim Potter 2003 Copyright (C) Stefan Metzmacher 2005 Copyright (C) Jelmer Vernooij 2007 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 3 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, see <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "torture/torture.h"#include "torture/rpc/rpc.h"#include "librpc/gen_ndr/ndr_spoolss_c.h"struct test_spoolss_context { /* print server handle */ struct policy_handle server_handle; /* 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(tctx, c,r,e) \ torture_assert_str_equal(tctx, c.e, r.e, "invalid value")/* not every compiler supports __typeof__() */#if (__GNUC__ >= 3)#define _CHECK_FIELD_SIZE(c,r,e,type) do {\ if (sizeof(__typeof__(c.e)) != sizeof(type)) { \ torture_fail(tctx, #c "." #e "field is not " #type "\n"); \ }\ if (sizeof(__typeof__(r.e)) != sizeof(type)) { \ torture_fail(tctx, #r "." #e "field is not " #type "\n"); \ }\} while(0)#else#define _CHECK_FIELD_SIZE(c,r,e,type) do {} while(0)#endif#define COMPARE_UINT32(tctx, c, r, e) do {\ _CHECK_FIELD_SIZE(c, r, e, uint32_t); \ torture_assert_int_equal(tctx, c.e, r.e, "invalid value"); \} while(0)#define COMPARE_STRING_ARRAY(tctx, c,r,e)static bool test_OpenPrinter_server(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx){ NTSTATUS status; struct spoolss_OpenPrinter op; op.in.printername = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p)); op.in.datatype = NULL; op.in.devmode_ctr.devmode= NULL; op.in.access_mask = 0; op.out.handle = &ctx->server_handle; torture_comment(tctx, "Testing OpenPrinter(%s)\n", op.in.printername); status = dcerpc_spoolss_OpenPrinter(p, ctx, &op); torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_OpenPrinter failed"); torture_assert_werr_ok(tctx, op.out.result, "dcerpc_spoolss_OpenPrinter failed"); return true;}static bool test_EnumPorts(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx){ NTSTATUS status; struct spoolss_EnumPorts r; uint16_t levels[] = { 1, 2 }; int i, j; for (i=0;i<ARRAY_SIZE(levels);i++) { int level = levels[i]; DATA_BLOB blob; r.in.servername = ""; r.in.level = level; r.in.buffer = NULL; r.in.offered = 0; torture_comment(tctx, "Testing EnumPorts level %u\n", r.in.level); status = dcerpc_spoolss_EnumPorts(p, ctx, &r); torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPorts failed"); if (W_ERROR_IS_OK(r.out.result)) { /* TODO: do some more checks here */ continue; } torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER, "EnumPorts unexpected return code"); blob = data_blob_talloc(ctx, NULL, r.out.needed); data_blob_clear(&blob); r.in.buffer = &blob; r.in.offered = r.out.needed; status = dcerpc_spoolss_EnumPorts(p, ctx, &r); torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPorts failed"); torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed"); 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]; torture_assert_int_equal(tctx, ctx->port_count[level], ctx->port_count[old_level], "EnumPorts invalid value"); } /* if the array sizes are not the same we would maybe segfault in the following code */ 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][j]; union spoolss_PortInfo *ref = &ctx->ports[2][j]; switch (level) { case 1: COMPARE_STRING(tctx, 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_GetPrinterDriverDirectory(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx){ NTSTATUS status; struct spoolss_GetPrinterDriverDirectory r; struct { uint16_t level; const char *server; } levels[] = {{ .level = 1, .server = NULL },{ .level = 1, .server = "" },{ .level = 78, .server = "" },{ .level = 1, .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p)) },{ .level = 1024, .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p)) } }; int i; for (i=0;i<ARRAY_SIZE(levels);i++) { int level = levels[i].level; DATA_BLOB blob; r.in.server = levels[i].server; r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86; r.in.level = level; r.in.buffer = NULL; r.in.offered = 0; torture_comment(tctx, "Testing GetPrinterDriverDirectory level %u\n", r.in.level); status = dcerpc_spoolss_GetPrinterDriverDirectory(p, ctx, &r); torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_GetPrinterDriverDirectory failed"); torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER, "GetPrinterDriverDirectory unexpected return code"); blob = data_blob_talloc(ctx, NULL, r.out.needed); data_blob_clear(&blob); r.in.buffer = &blob; r.in.offered = r.out.needed; status = dcerpc_spoolss_GetPrinterDriverDirectory(p, ctx, &r); torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_GetPrinterDriverDirectory failed"); torture_assert_werr_ok(tctx, r.out.result, "GetPrinterDriverDirectory failed"); } return true;}static bool test_EnumPrinterDrivers(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx){ NTSTATUS status; struct spoolss_EnumPrinterDrivers r; uint16_t levels[] = { 1, 2, 3, 4, 5, 6 }; int i, j; for (i=0;i<ARRAY_SIZE(levels);i++) { int level = levels[i]; DATA_BLOB blob; r.in.server = ""; r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86; r.in.level = level; r.in.buffer = NULL; r.in.offered = 0; torture_comment(tctx, "Testing EnumPrinterDrivers level %u\n", r.in.level); status = dcerpc_spoolss_EnumPrinterDrivers(p, ctx, &r); torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrinterDrivers failed"); if (W_ERROR_IS_OK(r.out.result)) { /* TODO: do some more checks here */ continue; } torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER, "EnumPrinterDrivers failed"); blob = data_blob_talloc(ctx, NULL, r.out.needed); data_blob_clear(&blob); r.in.buffer = &blob; r.in.offered = r.out.needed; status = dcerpc_spoolss_EnumPrinterDrivers(p, ctx, &r); torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrinterDrivers failed"); torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDrivers failed"); 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]; torture_assert_int_equal(tctx, ctx->driver_count[level], ctx->driver_count[old_level], "EnumPrinterDrivers invalid value"); } 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][j]; union spoolss_DriverInfo *ref = &ctx->drivers[6][j]; switch (level) { case 1: COMPARE_STRING(tctx, cur->info1, ref->info6, driver_name); break; case 2: COMPARE_UINT32(tctx, cur->info2, ref->info6, version); COMPARE_STRING(tctx, cur->info2, ref->info6, driver_name); COMPARE_STRING(tctx, cur->info2, ref->info6, architecture); COMPARE_STRING(tctx, cur->info2, ref->info6, driver_path); COMPARE_STRING(tctx, cur->info2, ref->info6, data_file); COMPARE_STRING(tctx, cur->info2, ref->info6, config_file); break; case 3: COMPARE_UINT32(tctx, cur->info3, ref->info6, version); COMPARE_STRING(tctx, cur->info3, ref->info6, driver_name); COMPARE_STRING(tctx, cur->info3, ref->info6, architecture); COMPARE_STRING(tctx, cur->info3, ref->info6, driver_path); COMPARE_STRING(tctx, cur->info3, ref->info6, data_file); COMPARE_STRING(tctx, cur->info3, ref->info6, config_file); COMPARE_STRING(tctx, cur->info3, ref->info6, help_file); COMPARE_STRING_ARRAY(tctx, cur->info3, ref->info6, dependent_files); COMPARE_STRING(tctx, cur->info3, ref->info6, monitor_name); COMPARE_STRING(tctx, cur->info3, ref->info6, default_datatype); break; case 4: COMPARE_UINT32(tctx, cur->info4, ref->info6, version); COMPARE_STRING(tctx, cur->info4, ref->info6, driver_name); COMPARE_STRING(tctx, cur->info4, ref->info6, architecture); COMPARE_STRING(tctx, cur->info4, ref->info6, driver_path); COMPARE_STRING(tctx, cur->info4, ref->info6, data_file); COMPARE_STRING(tctx, cur->info4, ref->info6, config_file); COMPARE_STRING(tctx, cur->info4, ref->info6, help_file); COMPARE_STRING_ARRAY(tctx, cur->info4, ref->info6, dependent_files); COMPARE_STRING(tctx, cur->info4, ref->info6, monitor_name); COMPARE_STRING(tctx, cur->info4, ref->info6, default_datatype); COMPARE_STRING_ARRAY(tctx, cur->info4, ref->info6, previous_names); break; case 5: COMPARE_UINT32(tctx, cur->info5, ref->info6, version); COMPARE_STRING(tctx, cur->info5, ref->info6, driver_name); COMPARE_STRING(tctx, cur->info5, ref->info6, architecture); COMPARE_STRING(tctx, cur->info5, ref->info6, driver_path); COMPARE_STRING(tctx, cur->info5, ref->info6, data_file); COMPARE_STRING(tctx, cur->info5, ref->info6, config_file); /*COMPARE_UINT32(tctx, cur->info5, ref->info6, driver_attributes);*/ /*COMPARE_UINT32(tctx, cur->info5, ref->info6, config_version);*/ /*TODO: ! COMPARE_UINT32(tctx, 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 true;}static bool test_EnumMonitors(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx){ NTSTATUS status; struct spoolss_EnumMonitors r; uint16_t levels[] = { 1, 2 }; int i, j; for (i=0;i<ARRAY_SIZE(levels);i++) { int level = levels[i]; DATA_BLOB blob; r.in.servername = ""; r.in.level = level; r.in.buffer = NULL; r.in.offered = 0; torture_comment(tctx, "Testing EnumMonitors level %u\n", r.in.level); status = dcerpc_spoolss_EnumMonitors(p, ctx, &r); torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumMonitors failed"); if (W_ERROR_IS_OK(r.out.result)) { /* TODO: do some more checks here */ continue; } torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER, "EnumMonitors failed"); blob = data_blob_talloc(ctx, NULL, r.out.needed); data_blob_clear(&blob); r.in.buffer = &blob; r.in.offered = r.out.needed; status = dcerpc_spoolss_EnumMonitors(p, ctx, &r); torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumMonitors failed"); torture_assert_werr_ok(tctx, r.out.result, "EnumMonitors failed"); 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]; torture_assert_int_equal(tctx, ctx->monitor_count[level], ctx->monitor_count[old_level], "EnumMonitors invalid value"); } 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][j]; union spoolss_MonitorInfo *ref = &ctx->monitors[2][j]; switch (level) { case 1: COMPARE_STRING(tctx, 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 true;}static bool test_EnumPrintProcessors(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx){ NTSTATUS status; struct spoolss_EnumPrintProcessors r; uint16_t levels[] = { 1 }; int i, j; for (i=0;i<ARRAY_SIZE(levels);i++) { int level = levels[i]; DATA_BLOB blob; r.in.servername = ""; r.in.environment = "Windows NT x86"; r.in.level = level; r.in.buffer = NULL; r.in.offered = 0; torture_comment(tctx, "Testing EnumPrintProcessors level %u\n", r.in.level); status = dcerpc_spoolss_EnumPrintProcessors(p, ctx, &r); torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcessors failed"); if (W_ERROR_IS_OK(r.out.result)) { /* TODO: do some more checks here */ continue; } torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER, "EnumPrintProcessors unexpected return code"); blob = data_blob_talloc(ctx, NULL, r.out.needed); data_blob_clear(&blob); r.in.buffer = &blob;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?