diff options
-rw-r--r-- | source4/ntptr/ntptr.h | 3 | ||||
-rw-r--r-- | source4/ntptr/ntptr_interface.c | 12 | ||||
-rw-r--r-- | source4/ntptr/simple_ldb/ntptr_simple_ldb.c | 113 | ||||
-rw-r--r-- | source4/rpc_server/spoolss/dcesrv_spoolss.c | 39 | ||||
-rw-r--r-- | source4/torture/rpc/spoolss.c | 33 |
5 files changed, 121 insertions, 79 deletions
diff --git a/source4/ntptr/ntptr.h b/source4/ntptr/ntptr.h index 847cef97c3..0f07f26cbb 100644 --- a/source4/ntptr/ntptr.h +++ b/source4/ntptr/ntptr.h @@ -35,6 +35,7 @@ enum ntptr_HandleType { struct ntptr_GenericHandle { enum ntptr_HandleType type; struct ntptr_context *ntptr; + const char *object_name; uint32_t access_mask; void *private_data; }; @@ -68,8 +69,6 @@ struct ntptr_ops { struct spoolss_EnumForms *r); WERROR (*AddPrintServerForm)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, struct spoolss_AddForm *r); - WERROR (*GetPrintServerForm)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, - struct spoolss_GetForm *r); WERROR (*SetPrintServerForm)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, struct spoolss_SetForm *r); WERROR (*DeletePrintServerForm)(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, diff --git a/source4/ntptr/ntptr_interface.c b/source4/ntptr/ntptr_interface.c index b389a5b894..1920b37f21 100644 --- a/source4/ntptr/ntptr_interface.c +++ b/source4/ntptr/ntptr_interface.c @@ -112,18 +112,6 @@ WERROR ntptr_AddPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX * return server->ntptr->ops->AddPrintServerForm(server, mem_ctx, r); } -WERROR ntptr_GetPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, - struct spoolss_GetForm *r) -{ - if (server->type != NTPTR_HANDLE_SERVER) { - return WERR_FOOBAR; - } - if (!server->ntptr->ops->GetPrintServerForm) { - return WERR_NOT_SUPPORTED; - } - return server->ntptr->ops->GetPrintServerForm(server, mem_ctx, r); -} - WERROR ntptr_SetPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, struct spoolss_SetForm *r) { diff --git a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c index dc79ba8a1a..c83cac4440 100644 --- a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c +++ b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c @@ -105,7 +105,9 @@ static WERROR sptr_OpenPrintServer(struct ntptr_context *ntptr, TALLOC_CTX *mem_ server->type = NTPTR_HANDLE_SERVER; server->ntptr = ntptr; - server->access_mask = r->in.access_mask; + server->object_name = talloc_strdup(server, server_name); + W_ERROR_HAVE_NO_MEMORY(server->object_name); + server->access_mask = 0; server->private_data = NULL; *_server = server; @@ -174,7 +176,7 @@ static WERROR sptr_EnumPrintServerForms(struct ntptr_GenericHandle *server, TALL union spoolss_FormInfo *info; count = sptr_db_search(sptr_db, mem_ctx, "CN=Forms,CN=PrintServer", &msgs, NULL, - "(&(objectclass=form))"); + "(&(objectClass=form))"); if (count == 0) return WERR_OK; if (count < 0) return WERR_GENERAL_FAILURE; @@ -271,54 +273,6 @@ static WERROR sptr_AddPrintServerForm(struct ntptr_GenericHandle *server, TALLOC return WERR_OK; } -static WERROR sptr_GetPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, - struct spoolss_GetForm *r) -{ - struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context); - struct ldb_message **msgs; - int count; - union spoolss_FormInfo *info; - - /* TODO: do checks access here - * if (!(server->access_mask & desired_access)) { - * return WERR_FOOBAR; - * } - */ - - count = sptr_db_search(sptr_db, mem_ctx, "CN=Forms,CN=PrintServer", &msgs, NULL, - "(&(form_name=%s)(objectClass=form))", - r->in.form_name); - - if (count == 0) return WERR_FOOBAR; - if (count > 1) return WERR_FOOBAR; - if (count < 0) return WERR_GENERAL_FAILURE; - - info = talloc(mem_ctx, union spoolss_FormInfo); - W_ERROR_HAVE_NO_MEMORY(info); - - switch (r->in.level) { - case 1: - info->info1.flags = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN); - - info->info1.form_name = samdb_result_string(msgs[0], "form_name", NULL); - W_ERROR_HAVE_NO_MEMORY(info->info1.form_name); - - info->info1.size.width = samdb_result_uint(msgs[0], "size_width", 0); - info->info1.size.height = samdb_result_uint(msgs[0], "size_height", 0); - - info->info1.area.left = samdb_result_uint(msgs[0], "area_left", 0); - info->info1.area.top = samdb_result_uint(msgs[0], "area_top", 0); - info->info1.area.right = samdb_result_uint(msgs[0], "area_right", 0); - info->info1.area.bottom = samdb_result_uint(msgs[0], "area_bottom", 0); - break; - default: - return WERR_UNKNOWN_LEVEL; - } - - r->out.info = info; - return WERR_OK; -} - static WERROR sptr_SetPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, struct spoolss_SetForm *r) { @@ -688,6 +642,60 @@ static WERROR sptr_EnumMonitors(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx return WERR_OK; } +/* Printer Form functions */ +static WERROR sptr_GetPrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx, + struct spoolss_GetForm *r) +{ + struct ldb_context *sptr_db = talloc_get_type(printer->ntptr->private_data, struct ldb_context); + struct ldb_message **msgs; + const char *base_dn; + int count; + union spoolss_FormInfo *info; + + /* TODO: do checks access here + * if (!(printer->access_mask & desired_access)) { + * return WERR_FOOBAR; + * } + */ + + base_dn = talloc_asprintf(mem_ctx, "CN=Forms,CN=%s,CN=Printers", printer->object_name); + W_ERROR_HAVE_NO_MEMORY(base_dn); + + count = sptr_db_search(sptr_db, mem_ctx, base_dn, &msgs, NULL, + "(&(form_name=%s)(objectClass=form))", + r->in.form_name); + + if (count == 0) return WERR_FOOBAR; + if (count > 1) return WERR_FOOBAR; + if (count < 0) return WERR_GENERAL_FAILURE; + + info = talloc(mem_ctx, union spoolss_FormInfo); + W_ERROR_HAVE_NO_MEMORY(info); + + switch (r->in.level) { + case 1: + info->info1.flags = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN); + + info->info1.form_name = samdb_result_string(msgs[0], "form_name", NULL); + W_ERROR_HAVE_NO_MEMORY(info->info1.form_name); + + info->info1.size.width = samdb_result_uint(msgs[0], "size_width", 0); + info->info1.size.height = samdb_result_uint(msgs[0], "size_height", 0); + + info->info1.area.left = samdb_result_uint(msgs[0], "area_left", 0); + info->info1.area.top = samdb_result_uint(msgs[0], "area_top", 0); + info->info1.area.right = samdb_result_uint(msgs[0], "area_right", 0); + info->info1.area.bottom = samdb_result_uint(msgs[0], "area_bottom", 0); + break; + default: + return WERR_UNKNOWN_LEVEL; + } + + r->out.info = info; + return WERR_OK; +} + + /* initialialise the simble ldb backend, registering ourselves with the ntptr subsystem */ @@ -707,7 +715,6 @@ static const struct ntptr_ops ntptr_simple_ldb_ops = { /* PrintServer Form functions */ .EnumPrintServerForms = sptr_EnumPrintServerForms, .AddPrintServerForm = sptr_AddPrintServerForm, - .GetPrintServerForm = sptr_GetPrintServerForm, .SetPrintServerForm = sptr_SetPrintServerForm, .DeletePrintServerForm = sptr_DeletePrintServerForm, @@ -748,8 +755,8 @@ static const struct ntptr_ops ntptr_simple_ldb_ops = { /* Printer Form functions */ /* .EnumPrinterForms = sptr_EnumPrinterForms, .AddPrinterForm = sptr_AddPrinterForm, - .GetPrinterForm = sptr_GetPrinterForm, - .SetPrinterForm = sptr_SetPrinterForm, +*/ .GetPrinterForm = sptr_GetPrinterForm, +/* .SetPrinterForm = sptr_SetPrinterForm, .DeletePrinterForm = sptr_DeletePrinterForm, */ /* Printer Job functions */ diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c index f8a0ab5efa..dfa935b750 100644 --- a/source4/rpc_server/spoolss/dcesrv_spoolss.c +++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c @@ -144,28 +144,50 @@ static WERROR spoolss_check_server_name(struct dcesrv_call_state *dce_call, const char *server_name) { BOOL ret; - const char *ip_str; + char *str; + /* NULL is ok */ if (!server_name) return WERR_OK; + /* "" is ok */ ret = strequal("",server_name); if (ret) return WERR_OK; + /* just "\\" is invalid */ + if (strequal("\\\\", server_name)) { + return WERR_INVALID_PRINTER_NAME; + } + + /* then we need "\\" */ if (strncmp("\\\\", server_name, 2) != 0) { return WERR_INVALID_PRINTER_NAME; } server_name += 2; + /* NETBIOS NAME is ok */ ret = strequal(lp_netbios_name(), server_name); if (ret) return WERR_OK; - /* TODO: check dns name here ? */ + /* DNS NAME is ok + * TODO: we need to check if aliases are also ok + */ + if (lp_realm() != NULL) { + str = talloc_asprintf(mem_ctx, "%s.%s", + lp_netbios_name(), + lp_realm()); + W_ERROR_HAVE_NO_MEMORY(str); + + ret = strequal(str, server_name); + talloc_free(str); + if (ret) return WERR_OK; + } - ip_str = socket_get_my_addr(dce_call->conn->srv_conn->socket, mem_ctx); - W_ERROR_HAVE_NO_MEMORY(ip_str); + str = socket_get_my_addr(dce_call->conn->srv_conn->socket, mem_ctx); + W_ERROR_HAVE_NO_MEMORY(str); - ret = strequal(ip_str, server_name); + ret = strequal(str, server_name); + talloc_free(str); if (ret) return WERR_OK; return WERR_INVALID_PRINTER_NAME; @@ -650,9 +672,10 @@ static WERROR spoolss_GetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *me switch (handle->type) { case NTPTR_HANDLE_SERVER: - status = ntptr_GetPrintServerForm(handle, mem_ctx, r); - W_ERROR_NOT_OK_RETURN(status); - break; + /* + * stupid, but w2k3 returns WERR_BADFID here? + */ + return WERR_BADFID; case NTPTR_HANDLE_PRINTER: status = ntptr_GetPrinterForm(handle, mem_ctx, r); W_ERROR_NOT_OK_RETURN(status); diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index f7bb454335..fcbec4e561 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -838,6 +838,17 @@ static BOOL test_GetForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.buffer = &blob; r.in.offered = r.out.needed; status = dcerpc_spoolss_GetForm(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) { + printf("GetForm failed - %s\n", + nt_errstr(status)); + return False; + } + + if (!W_ERROR_IS_OK(r.out.result)) { + printf("GetForm failed - %s\n", + win_errstr(r.out.result)); + return False; + } if (!r.out.info) { printf("No form info returned\n"); @@ -845,6 +856,13 @@ static BOOL test_GetForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, } } + + if (!W_ERROR_IS_OK(r.out.result)) { + printf("GetForm failed - %s\n", + win_errstr(r.out.result)); + return False; + } + return True; } @@ -853,6 +871,7 @@ static BOOL test_EnumForms(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct spoolss_EnumForms r; + BOOL ret = True; r.in.handle = handle; r.in.level = 1; @@ -890,7 +909,7 @@ static BOOL test_EnumForms(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, info = r.out.info; for (j = 0; j < r.out.count; j++) { - test_GetForm(p, mem_ctx, handle, info[j].info1.form_name); + if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, info[j].info1.form_name); } } @@ -933,7 +952,7 @@ static BOOL test_DeleteForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, } static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, - struct policy_handle *handle) + struct policy_handle *handle, BOOL print_server) { struct spoolss_AddForm r; struct spoolss_AddFormInfo1 addform; @@ -961,10 +980,12 @@ static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, } if (!W_ERROR_IS_OK(r.out.result)) { - printf("AddForm failed - %s\n", nt_errstr(status)); + printf("AddForm failed - %s\n", win_errstr(r.out.result)); goto done; } + if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, form_name); + { struct spoolss_SetForm sf; struct spoolss_AddFormInfo1 setform; @@ -996,6 +1017,8 @@ static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, } } + if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, form_name); + done: if (!test_DeleteForm(p, mem_ctx, handle, form_name)) { printf("DeleteForm failed\n"); @@ -1821,7 +1844,7 @@ static BOOL test_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, ret = False; } - if (!test_AddForm(p, mem_ctx, &handle)) { + if (!test_AddForm(p, mem_ctx, &handle, False)) { ret = False; } @@ -2074,6 +2097,8 @@ BOOL torture_rpc_spoolss(void) ret &= test_EnumForms(ctx->p, ctx, &ctx->server_handle, True); + ret &= test_AddForm(ctx->p, ctx, &ctx->server_handle, True); + ret &= test_EnumPorts(ctx); ret &= test_GetPrinterDriverDirectory(ctx); |