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 + -
显示快捷键?