summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/ntptr/ntptr.h3
-rw-r--r--source4/ntptr/ntptr_interface.c12
-rw-r--r--source4/ntptr/simple_ldb/ntptr_simple_ldb.c113
-rw-r--r--source4/rpc_server/spoolss/dcesrv_spoolss.c39
-rw-r--r--source4/torture/rpc/spoolss.c33
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);