mirror of
https://github.com/samba-team/samba.git
synced 2025-02-05 21:57:51 +03:00
r5503: - add torture test which tests for invalid printernames
- add OpenPrinter() server code that just calls OpenPrinterEx() - fix OpenPrinterEx logic, we pass the invalid printer names test now metze
This commit is contained in:
parent
ac062a2979
commit
3085d3728e
@ -143,14 +143,37 @@ static WERROR spoolss_EnumPrinters(struct dcesrv_call_state *dce_call, TALLOC_CT
|
||||
return WERR_UNKNOWN_LEVEL;
|
||||
}
|
||||
|
||||
|
||||
static WERROR spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct spoolss_OpenPrinterEx *r);
|
||||
/*
|
||||
spoolss_OpenPrinter
|
||||
*/
|
||||
static WERROR spoolss_OpenPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct spoolss_OpenPrinter *r)
|
||||
{
|
||||
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
|
||||
WERROR status;
|
||||
struct spoolss_OpenPrinterEx *r2;
|
||||
|
||||
r2 = talloc(mem_ctx, struct spoolss_OpenPrinterEx);
|
||||
W_ERROR_HAVE_NO_MEMORY(r2);
|
||||
|
||||
r2->in.printername = r->in.printername;
|
||||
r2->in.datatype = r->in.datatype;
|
||||
r2->in.devmode_ctr = r->in.devmode_ctr;
|
||||
r2->in.access_mask = r->in.access_mask;
|
||||
r2->in.level = 1;
|
||||
r2->in.userlevel.level1 = NULL;
|
||||
|
||||
r2->out.handle = r->out.handle;
|
||||
|
||||
/* TODO: we should take care about async replies here,
|
||||
if spoolss_OpenPrinterEx() would be async!
|
||||
*/
|
||||
status = spoolss_OpenPrinterEx(dce_call, mem_ctx, r2);
|
||||
|
||||
r->out.handle = r2->out.handle;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@ -836,49 +859,46 @@ static WERROR spoolss_44(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx
|
||||
|
||||
static WERROR spoolss_OpenPrinterEx_server(struct dcesrv_call_state *dce_call,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct spoolss_OpenPrinterEx *r)
|
||||
struct spoolss_OpenPrinterEx *r,
|
||||
const char *server_name)
|
||||
{
|
||||
struct spoolss_openprinter_state *state;
|
||||
struct spoolss_handle_server *state;
|
||||
struct dcesrv_handle *handle;
|
||||
BOOL ret;
|
||||
|
||||
/* Check printername is our name */
|
||||
|
||||
if (!strequal(r->in.printername + 2, lp_netbios_name()))
|
||||
return WERR_INVALID_PRINTER_NAME;
|
||||
/* Check printername is our name or our ip address
|
||||
*/
|
||||
ret = strequal(server_name, lp_netbios_name());
|
||||
if (!ret) {
|
||||
/* TODO:
|
||||
ret = strequal(server_name, ...our_ip...);*/
|
||||
if (!ret) {
|
||||
return WERR_INVALID_PRINTER_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
handle = dcesrv_handle_new(dce_call->context, SPOOLSS_HANDLE_SERVER);
|
||||
if (!handle) {
|
||||
return WERR_NOMEM;
|
||||
}
|
||||
W_ERROR_HAVE_NO_MEMORY(handle);
|
||||
|
||||
state = talloc(handle, struct spoolss_openprinter_state);
|
||||
if (!state) {
|
||||
return WERR_OK;
|
||||
}
|
||||
state = talloc(handle, struct spoolss_handle_server);
|
||||
W_ERROR_HAVE_NO_MEMORY(state);
|
||||
|
||||
handle->data = state;
|
||||
|
||||
state->access_mask = r->in.access_mask;
|
||||
*r->out.handle = handle->wire_handle;
|
||||
state->handle_type = SPOOLSS_HANDLE_SERVER;
|
||||
state->access_mask = r->in.access_mask;
|
||||
|
||||
*r->out.handle = handle->wire_handle;
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR spoolss_OpenPrinterEx_printer(struct dcesrv_call_state *dce_call,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct spoolss_OpenPrinterEx *r)
|
||||
struct spoolss_OpenPrinterEx *r,
|
||||
const char *printer_name)
|
||||
{
|
||||
char *server = talloc_strdup(mem_ctx, r->in.printername + 2);
|
||||
char *pos, *printer;
|
||||
|
||||
pos = strchr(server, '\\');
|
||||
*pos = 0;
|
||||
printer = talloc_strdup(mem_ctx, pos + 1);
|
||||
|
||||
if (!strequal(server, lp_netbios_name()))
|
||||
return WERR_INVALID_PRINTER_NAME;
|
||||
|
||||
DEBUG(0, ("looking for server %s, printer %s\n", server, printer));
|
||||
DEBUG(0, ("looking for printer %s\n", printer_name));
|
||||
|
||||
return WERR_INVALID_PRINTER_NAME;
|
||||
}
|
||||
@ -889,17 +909,40 @@ static WERROR spoolss_OpenPrinterEx_printer(struct dcesrv_call_state *dce_call,
|
||||
static WERROR spoolss_OpenPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct spoolss_OpenPrinterEx *r)
|
||||
{
|
||||
const char *p;
|
||||
const char *printer = r->in.printername;
|
||||
ZERO_STRUCTP(r->out.handle);
|
||||
|
||||
/* Printername must start with \\ */
|
||||
/* just "\\" is invalid */
|
||||
if (strequal(r->in.printername, "\\\\")) {
|
||||
return WERR_INVALID_PRINTER_NAME;
|
||||
}
|
||||
|
||||
if (strncmp(r->in.printername, "\\\\", 2) == 0)
|
||||
return WERR_INVALID_PARAM;
|
||||
if (strncmp(r->in.printername, "\\\\", 2) == 0) {
|
||||
/* here we know we have "\\" in front not followed
|
||||
* by '\0', now see if we have another "\" in the string
|
||||
*/
|
||||
p = strchr_m(r->in.printername + 2, '\\');
|
||||
if (!p) {
|
||||
/* there's no other "\", so it's ("\\%s",server)
|
||||
*/
|
||||
const char *server = r->in.printername + 2;
|
||||
DEBUG(0,("print server: [%s][%s]\n", r->in.printername, server));
|
||||
return spoolss_OpenPrinterEx_server(dce_call, mem_ctx, r, server);
|
||||
}
|
||||
/* here we know that we have ("\\%s\",server),
|
||||
* if we have '\0' as next then it's an invalid name
|
||||
* otherwise the printer_name
|
||||
*/
|
||||
p++;
|
||||
if (p[0] == '\0') {
|
||||
return WERR_INVALID_PRINTER_NAME;
|
||||
}
|
||||
printer = p;
|
||||
}
|
||||
|
||||
if (strchr_m(r->in.printername + 2, '\\'))
|
||||
return spoolss_OpenPrinterEx_server(dce_call, mem_ctx, r);
|
||||
|
||||
return spoolss_OpenPrinterEx_printer(dce_call, mem_ctx, r);
|
||||
DEBUG(0,("printer: [%s][%s]\n", r->in.printername, printer));
|
||||
return spoolss_OpenPrinterEx_printer(dce_call, mem_ctx, r, printer);
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
/*
|
||||
this type allows us to distinguish handle types
|
||||
*/
|
||||
enum spoolss_handle {
|
||||
enum spoolss_handle_type {
|
||||
SPOOLSS_HANDLE_SERVER,
|
||||
SPOOLSS_HANDLE_PRINTER
|
||||
};
|
||||
@ -31,7 +31,7 @@ enum spoolss_handle {
|
||||
/*
|
||||
state asscoiated with a spoolss_OpenPrinter{,Ex}() operation
|
||||
*/
|
||||
struct spoolss_openprinter_state {
|
||||
void *openprinter_ctx;
|
||||
struct spoolss_handle_server {
|
||||
enum spoolss_handle_type handle_type;
|
||||
uint32_t access_mask;
|
||||
};
|
||||
|
@ -640,6 +640,85 @@ static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL test_OpenPrinter_badname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *name)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct spoolss_OpenPrinter op;
|
||||
struct spoolss_OpenPrinterEx opEx;
|
||||
struct policy_handle handle;
|
||||
BOOL ret = True;
|
||||
|
||||
op.in.printername = name;
|
||||
op.in.datatype = NULL;
|
||||
op.in.devmode_ctr.size = 0;
|
||||
op.in.devmode_ctr.devmode= NULL;
|
||||
op.in.access_mask = 0;
|
||||
op.out.handle = &handle;
|
||||
|
||||
printf("\nTesting OpenPrinter(%s) with bad name\n", op.in.printername);
|
||||
|
||||
status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &op);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("OpenPrinter failed - %s\n", nt_errstr(status));
|
||||
ret = False;
|
||||
}
|
||||
if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,op.out.result)) {
|
||||
printf("OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
|
||||
name, win_errstr(op.out.result));
|
||||
}
|
||||
|
||||
if (W_ERROR_IS_OK(op.out.result)) {
|
||||
ret &=test_ClosePrinter(p, mem_ctx, &handle);
|
||||
}
|
||||
|
||||
opEx.in.printername = name;
|
||||
opEx.in.datatype = NULL;
|
||||
opEx.in.devmode_ctr.size = 0;
|
||||
opEx.in.devmode_ctr.devmode = NULL;
|
||||
opEx.in.access_mask = 0;
|
||||
opEx.in.level = 1;
|
||||
opEx.in.userlevel.level1 = NULL;
|
||||
opEx.out.handle = &handle;
|
||||
|
||||
printf("\nTesting OpenPrinter(%s) with bad name\n", opEx.in.printername);
|
||||
|
||||
status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &opEx);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("OpenPrinter failed - %s\n", nt_errstr(status));
|
||||
ret = False;
|
||||
}
|
||||
if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,opEx.out.result)) {
|
||||
printf("OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
|
||||
name, win_errstr(opEx.out.result));
|
||||
}
|
||||
|
||||
if (W_ERROR_IS_OK(opEx.out.result)) {
|
||||
ret &=test_ClosePrinter(p, mem_ctx, &handle);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL test_OpenPrinter_badnames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
BOOL ret = True;
|
||||
char *name;
|
||||
|
||||
ret &= test_OpenPrinter_badname(p, mem_ctx, "__INVALID_PRINTER__");
|
||||
ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\127.0.0.1");
|
||||
ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\localhost");
|
||||
|
||||
name = talloc_asprintf(mem_ctx, "\\\\%s\\", dcerpc_server_name(p));
|
||||
ret &= test_OpenPrinter_badname(p, mem_ctx, name);
|
||||
talloc_free(name);
|
||||
|
||||
name = talloc_asprintf(mem_ctx, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p));
|
||||
ret &= test_OpenPrinter_badname(p, mem_ctx, name);
|
||||
talloc_free(name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
const char *name)
|
||||
{
|
||||
@ -661,8 +740,7 @@ static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
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));
|
||||
/* don't consider failing this an error until we understand it */
|
||||
return True;
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!test_GetPrinter(p, mem_ctx, &handle)) {
|
||||
@ -687,18 +765,20 @@ static BOOL call_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct spoolss_UserLevel1 userlevel1;
|
||||
NTSTATUS status;
|
||||
|
||||
if (name && name[0])
|
||||
if (name && name[0]) {
|
||||
r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
|
||||
dcerpc_server_name(p), name);
|
||||
else
|
||||
} else {
|
||||
r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
|
||||
dcerpc_server_name(p));
|
||||
}
|
||||
|
||||
r.in.datatype = NULL;
|
||||
r.in.devmode_ctr.size = 0;
|
||||
r.in.devmode_ctr.devmode = NULL;
|
||||
r.in.access_mask = 0x02000000;
|
||||
r.in.level = 1;
|
||||
r.in.datatype = NULL;
|
||||
r.in.devmode_ctr.size = 0;
|
||||
r.in.devmode_ctr.devmode= NULL;
|
||||
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r.in.level = 1;
|
||||
r.in.userlevel.level1 = &userlevel1;
|
||||
r.out.handle = handle;
|
||||
|
||||
userlevel1.size = 1234;
|
||||
@ -708,7 +788,6 @@ static BOOL call_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
userlevel1.major = 2;
|
||||
userlevel1.minor = 3;
|
||||
userlevel1.processor = 4;
|
||||
r.in.userlevel.level1 = &userlevel1;
|
||||
|
||||
printf("Testing OpenPrinterEx(%s)\n", r.in.printername);
|
||||
|
||||
@ -968,18 +1047,14 @@ BOOL torture_rpc_spoolss(void)
|
||||
|
||||
mem_ctx = talloc_init("torture_rpc_spoolss");
|
||||
|
||||
if (!test_EnumPorts(p, mem_ctx)) {
|
||||
ret = False;
|
||||
}
|
||||
ret &= test_OpenPrinter_badnames(p, mem_ctx);
|
||||
|
||||
if (!test_EnumPrinters(p, mem_ctx)) {
|
||||
ret = False;
|
||||
}
|
||||
ret &= test_EnumPorts(p, mem_ctx);
|
||||
|
||||
ret &= test_EnumPrinters(p, mem_ctx);
|
||||
|
||||
ret &= test_EnumPrinterDrivers(p, mem_ctx);
|
||||
|
||||
if (!test_EnumPrinterDrivers(p, mem_ctx)) {
|
||||
ret = False;
|
||||
}
|
||||
printf("blub\n");
|
||||
talloc_free(mem_ctx);
|
||||
|
||||
torture_rpc_close(p);
|
||||
|
Loading…
x
Reference in New Issue
Block a user