1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-24 13:57:43 +03:00

r7580: - add GetPrinterDriverDirectory() idl, torture test and server code

- add EnumMonitors() server code and return "Standard TCP/IP Port"
- add parsing for opening Ports and Monitors with OpenPrinterEx()

metze
(This used to be commit 08e6de37bc293e2f000d03b51642964d92d6e95e)
This commit is contained in:
Stefan Metzmacher 2005-06-14 18:44:22 +00:00 committed by Gerald (Jerry) Carter
parent bc1f32b8ad
commit 056d63c62f
4 changed files with 250 additions and 21 deletions

View File

@ -573,7 +573,26 @@
/******************/
/* Function: 0x0c */
typedef struct {
nstring directory_name;
} spoolss_DriverDirectoryInfo1;
/* NOTE: it's seems that w2k3 completly ignores the level
in its server code
*/
typedef [nodiscriminant,relative_base,gensize,public] union {
[case(1)] spoolss_DriverDirectoryInfo1 info1;
[default] spoolss_DriverDirectoryInfo1 info1;
} spoolss_DriverDirectoryInfo;
WERROR spoolss_GetPrinterDriverDirectory(
[in] unistr *server,
[in] unistr *environment,
[in] uint32 level,
[in] DATA_BLOB *buffer,
[in] uint32 offered,
[out,subcontext(4),switch_is(level)] spoolss_DriverDirectoryInfo *info,
[out] uint32 needed
);
/******************/

View File

@ -356,7 +356,43 @@ static WERROR spoolss_GetPrinterDriver(struct dcesrv_call_state *dce_call, TALLO
static WERROR spoolss_GetPrinterDriverDirectory(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_GetPrinterDriverDirectory *r)
{
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
union spoolss_DriverDirectoryInfo *info;
const char *prefix;
const char *postfix;
/*
* NOTE: normally r->in.level is 1, but both w2k3 and nt4 sp6a
* are ignoring the r->in.level completely, so we do :-)
*/
/*
* TODO: check the server name is ours
* - if it's a invalid UNC then return WERR_INVALID_NAME
* - if it's the wrong host name return WERR_INVALID_PARAM
* - if it's "" then we need to return a local WINDOWS path
*/
if (strcmp("", r->in.server) == 0) {
prefix = "C:\\DRIVERS";
} else {
prefix = talloc_asprintf(mem_ctx, "%s\\print$", r->in.server);
W_ERROR_HAVE_NO_MEMORY(prefix);
}
if (strcmp(SPOOLSS_ARCHITECTURE_NT_X86, r->in.environment) == 0) {
postfix = "W32X86";
} else {
return WERR_INVALID_ENVIRONMENT;
}
info = talloc(mem_ctx, union spoolss_DriverDirectoryInfo);
W_ERROR_HAVE_NO_MEMORY(info);
info->info1.directory_name = talloc_asprintf(mem_ctx, "%s\\%s", prefix, postfix);
W_ERROR_HAVE_NO_MEMORY(info->info1.directory_name);
r->out.needed = ndr_size_spoolss_DriverDirectoryInfo(info, r->in.level, 0);
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
@ -666,16 +702,16 @@ static WERROR spoolss_EnumForms(struct dcesrv_call_state *dce_call, TALLOC_CTX *
for (i=0; i < count; i++) {
info[i].info1.flags = SPOOLSS_FORM_PRINTER;
info[i].info1.form_name = talloc_strdup(mem_ctx, "Samba Printer Form");
info[i].info1.form_name = talloc_strdup(mem_ctx, "Letter");
W_ERROR_HAVE_NO_MEMORY(info[i].info1.form_name);
info[i].info1.size.width = 30;
info[i].info1.size.height = 40;
info[i].info1.size.width = 0x34b5c;
info[i].info1.size.height = 0x44368;
info[i].info1.area.left = 0;
info[i].info1.area.top = 0;
info[i].info1.area.right = 30;
info[i].info1.area.bottom = 40;
info[i].info1.area.right = 0x34b5c;
info[i].info1.area.bottom = 0x44368;
}
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumForms, r->in.level, count, info);
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
@ -745,7 +781,46 @@ static WERROR spoolss_EnumPorts(struct dcesrv_call_state *dce_call, TALLOC_CTX *
static WERROR spoolss_EnumMonitors(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_EnumMonitors *r)
{
return WERR_OK;
union spoolss_MonitorInfo *info;
int count;
int i;
count = 1;
if (count == 0) return WERR_OK;
if (count < 0) return WERR_GENERAL_FAILURE;
info = talloc_array(mem_ctx, union spoolss_MonitorInfo, count);
W_ERROR_HAVE_NO_MEMORY(info);
switch (r->in.level) {
case 1:
for (i=0; i < count; i++) {
info[i].info1.monitor_name = talloc_strdup(mem_ctx, "Standard TCP/IP Port");
W_ERROR_HAVE_NO_MEMORY(info[i].info1.monitor_name);
}
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumMonitors, r->in.level, count, info);
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
case 2:
for (i=0; i < count; i++) {
info[i].info2.monitor_name = talloc_strdup(mem_ctx, "Standard TCP/IP Port");
W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name);
info[i].info2.environment = talloc_strdup(mem_ctx, SPOOLSS_ARCHITECTURE_NT_X86);
W_ERROR_HAVE_NO_MEMORY(info[i].info2.environment);
info[i].info2.dll_name = talloc_strdup(mem_ctx, "tcpmon.dll");
W_ERROR_HAVE_NO_MEMORY(info[i].info2.dll_name);
}
r->out.needed = SPOOLSS_BUFFER_SIZE(spoolss_EnumMonitors, r->in.level, count, info);
r->out.info = SPOOLSS_BUFFER_OK(info, NULL);
r->out.count = SPOOLSS_BUFFER_OK(count, 0);
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
return WERR_UNKNOWN_LEVEL;
}
@ -1108,6 +1183,41 @@ static WERROR spoolss_OpenPrinterEx_server(struct dcesrv_call_state *dce_call,
return WERR_OK;
}
static WERROR spoolss_OpenPrinterEx_port(struct dcesrv_call_state *dce_call,
TALLOC_CTX *mem_ctx,
struct spoolss_OpenPrinterEx *r,
const char *server_name,
const char *port_name)
{
DEBUG(1, ("looking for port [%s] (server[%s])\n", port_name, server_name));
return WERR_INVALID_PRINTER_NAME;
}
static WERROR spoolss_OpenPrinterEx_monitor(struct dcesrv_call_state *dce_call,
TALLOC_CTX *mem_ctx,
struct spoolss_OpenPrinterEx *r,
const char *server_name,
const char *monitor_name)
{
if (strequal("Standard TCP/IP Port", monitor_name)) {
struct dcesrv_handle *handle;
handle = dcesrv_handle_new(dce_call->context, SPOOLSS_HANDLE_MONITOR);
W_ERROR_HAVE_NO_MEMORY(handle);
handle->data = NULL;
*r->out.handle = handle->wire_handle;
return WERR_OK;
}
DEBUG(1, ("looking for monitor [%s] (server[%s])\n", monitor_name, server_name));
return WERR_INVALID_PRINTER_NAME;
}
static WERROR spoolss_OpenPrinterEx_printer(struct dcesrv_call_state *dce_call,
TALLOC_CTX *mem_ctx,
struct spoolss_OpenPrinterEx *r,
@ -1127,7 +1237,7 @@ static WERROR spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_C
{
char *p;
char *server = NULL;
const char *printer = r->in.printername;
const char *object = r->in.printername;
ZERO_STRUCTP(r->out.handle);
/* no printername is there it's like open server */
@ -1160,25 +1270,49 @@ static WERROR spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_C
p[0] = '\0';
/* everything that follows is the printer name */
p++;
printer = p;
object = p;
/* just "" as server is invalid */
if (strequal(server, "")) {
DEBUG(2,("ivalid server: [%s][%s][%s]\n", r->in.printername, server, printer));
DEBUG(2,("OpenPrinterEx invalid print server: [%s][%s][%s]\n", r->in.printername, server, object));
return WERR_INVALID_PRINTER_NAME;
}
}
/* just "" is invalid */
if (strequal(printer, "")) {
DEBUG(2,("invalid printer: [%s][%s][%s]\n", r->in.printername, server, printer));
if (strequal(object, "")) {
DEBUG(2,("OpenPrinterEx invalid object: [%s][%s][%s]\n", r->in.printername, server, object));
return WERR_INVALID_PRINTER_NAME;
}
DEBUG(3,("printer: [%s][%s][%s]\n", r->in.printername, server, printer));
return spoolss_OpenPrinterEx_printer(dce_call, mem_ctx, r, server, printer);
}
DEBUG(3,("OpenPrinterEx object: [%s][%s][%s]\n", r->in.printername, server, object));
#define XCV_PORT ",XcvPort "
#define XCV_MONITOR ",XcvMonitor "
if (strncmp(object, XCV_PORT, strlen(XCV_PORT)) == 0) {
object += strlen(XCV_PORT);
/* just "" is invalid */
if (strequal(object, "")) {
DEBUG(2,("OpenPrinterEx invalid port: [%s][%s][%s]\n", r->in.printername, server, object));
return WERR_INVALID_PRINTER_NAME;
}
return spoolss_OpenPrinterEx_port(dce_call, mem_ctx, r, server, object);
} else if (strncmp(object, XCV_MONITOR, strlen(XCV_MONITOR)) == 0) {
object += strlen(XCV_MONITOR);
/* just "" is invalid */
if (strequal(object, "")) {
DEBUG(2,("OpenPrinterEx invalid monitor: [%s][%s][%s]\n", r->in.printername, server, object));
return WERR_INVALID_PRINTER_NAME;
}
return spoolss_OpenPrinterEx_monitor(dce_call, mem_ctx, r, server, object);
}
return spoolss_OpenPrinterEx_printer(dce_call, mem_ctx, r, server, object);
}
/*
spoolss_AddPrinterEx

View File

@ -25,7 +25,9 @@
*/
enum spoolss_handle_type {
SPOOLSS_HANDLE_SERVER,
SPOOLSS_HANDLE_PRINTER
SPOOLSS_HANDLE_PRINTER,
SPOOLSS_HANDLE_PORT,
SPOOLSS_HANDLE_MONITOR
};
/*

View File

@ -211,6 +211,78 @@ static BOOL test_EnumPorts(struct test_spoolss_context *ctx)
return True;
}
static BOOL test_GetPrinterDriverDirectory(struct test_spoolss_context *ctx)
{
NTSTATUS status;
struct spoolss_GetPrinterDriverDirectory r;
struct {
uint16_t level;
const char *server;
} levels[] = {{
.level = 1,
.server = ""
},{
.level = 78,
.server = ""
},{
.level = 1,
.server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p))
},{
.level = 1024,
.server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p))
}
};
int i;
BOOL ret = True;
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;
printf("Testing GetPrinterDriverDirectory level %u\n", r.in.level);
status = dcerpc_spoolss_GetPrinterDriverDirectory(ctx->p, ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
printf("dcerpc_spoolss_GetPrinterDriverDirectory failed - %s\n", nt_errstr(status));
ret = False;
continue;
}
if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
printf("GetPrinterDriverDirectory unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
win_errstr(r.out.result));
ret = False;
continue;
}
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(ctx->p, ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
printf("dcerpc_spoolss_GetPrinterDriverDirectory failed - %s\n", nt_errstr(status));
ret = False;
continue;
}
if (!W_ERROR_IS_OK(r.out.result)) {
printf("GetPrinterDriverDirectory failed - %s\n",
win_errstr(r.out.result));
ret = False;
continue;
}
}
return True;
}
static BOOL test_EnumPrinterDrivers(struct test_spoolss_context *ctx)
{
NTSTATUS status;
@ -223,11 +295,11 @@ static BOOL test_EnumPrinterDrivers(struct test_spoolss_context *ctx)
int level = levels[i];
DATA_BLOB blob;
r.in.server = "";
r.in.environment = "Windows NT x86";
r.in.level = level;
r.in.buffer = NULL;
r.in.offered = 0;
r.in.server = "";
r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86;
r.in.level = level;
r.in.buffer = NULL;
r.in.offered = 0;
printf("Testing EnumPrinterDrivers level %u\n", r.in.level);
@ -1994,6 +2066,8 @@ BOOL torture_rpc_spoolss(void)
ret &= test_EnumPorts(ctx);
ret &= test_GetPrinterDriverDirectory(ctx);
ret &= test_EnumPrinterDrivers(ctx);
ret &= test_EnumMonitors(ctx);