Fwd: [PATCHES] support getprinter level 3 again for server handles

Günther Deschner gd at samba.org
Tue Sep 13 15:11:08 UTC 2016


And here is the patch...


-------- Forwarded Message --------
Subject: [PATCHES] support getprinter level 3 again for server handles
Date: Tue, 13 Sep 2016 17:04:35 +0200
From: Günther Deschner <gd at samba.org>
To: Samba Technical <samba-technical at lists.samba.org>
CC: Andreas Schneider <asn at redhat.com>

Hi,

sometime during the last spoolss rewrite we lost support for displaying
the server security descriptor. Leading to warnings when displaying
server properties with the printer management UI.

This patchset adds it back + tests.

Please review & push.

Thanks,
Guenther
-- 
Günther Deschner                    GPG-ID: 8EE11688
Red Hat                         gdeschner at redhat.com
Samba Team                              gd at samba.org

-------------- next part --------------
From 5fe7122aba369c0f327b0d815e3dc302ba0ac6b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
Date: Fri, 9 Sep 2016 16:00:38 +0200
Subject: [PATCH 1/8] s4-torture: test GetPrinter level 3 on server handle
 (security descriptor query)

Guenther

Signed-off-by: Guenther Deschner <gd at samba.org>
---
 source4/torture/rpc/spoolss.c | 50 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c
index 1fcf379..ec48ecb 100644
--- a/source4/torture/rpc/spoolss.c
+++ b/source4/torture/rpc/spoolss.c
@@ -1189,11 +1189,12 @@ static bool test_GetPrinterDriver2(struct torture_context *tctx,
 				   const char *driver_name,
 				   const char *environment);
 
-bool test_GetPrinter_level(struct torture_context *tctx,
-			   struct dcerpc_binding_handle *b,
-			   struct policy_handle *handle,
-			   uint32_t level,
-			   union spoolss_PrinterInfo *info)
+bool test_GetPrinter_level_exp(struct torture_context *tctx,
+			       struct dcerpc_binding_handle *b,
+			       struct policy_handle *handle,
+			       uint32_t level,
+			       WERROR expected_werror,
+			       union spoolss_PrinterInfo *info)
 {
 	struct spoolss_GetPrinter r;
 	uint32_t needed;
@@ -1218,7 +1219,9 @@ bool test_GetPrinter_level(struct torture_context *tctx,
 			"GetPrinter failed");
 	}
 
-	torture_assert_werr_ok(tctx, r.out.result, "GetPrinter failed");
+	torture_assert_werr_equal(tctx,
+		r.out.result, expected_werror,
+		"GetPrinter failed");
 
 	CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterInfo, r.out.info, r.in.level, needed, 4);
 
@@ -1229,6 +1232,14 @@ bool test_GetPrinter_level(struct torture_context *tctx,
 	return true;
 }
 
+bool test_GetPrinter_level(struct torture_context *tctx,
+			   struct dcerpc_binding_handle *b,
+			   struct policy_handle *handle,
+			   uint32_t level,
+			   union spoolss_PrinterInfo *info)
+{
+	return test_GetPrinter_level_exp(tctx, b, handle, level, WERR_OK, info);
+}
 
 static bool test_GetPrinter(struct torture_context *tctx,
 			    struct dcerpc_binding_handle *b,
@@ -8087,6 +8098,32 @@ static bool test_get_printer_driver_package_path(struct torture_context *tctx,
 	return true;
 }
 
+static bool test_get_printer_printserverhandle(struct torture_context *tctx,
+					       void *private_data)
+{
+	struct test_spoolss_context *ctx =
+		talloc_get_type_abort(private_data, struct test_spoolss_context);
+
+	struct dcerpc_pipe *p = ctx->spoolss_pipe;
+	struct dcerpc_binding_handle *b = p->binding_handle;
+	uint32_t levels[] = {0, 1, 2, /* 3,*/ 4, 5, 6, 7, 8};
+	int i;
+
+	for (i=0;i<ARRAY_SIZE(levels);i++) {
+
+		torture_assert(tctx,
+			test_GetPrinter_level_exp(tctx, b, &ctx->server_handle, levels[i], WERR_INVALID_LEVEL, NULL),
+			"failed to call GetPrinter");
+	}
+
+	torture_assert(tctx,
+		test_GetPrinter_level(tctx, b, &ctx->server_handle, 3, NULL),
+		"failed to call GetPrinter");
+
+	return true;
+}
+
+
 static bool test_PrintServer_Forms_Winreg(struct torture_context *tctx,
 					  void *private_data)
 {
@@ -9322,6 +9359,7 @@ struct torture_suite *torture_rpc_spoolss(TALLOC_CTX *mem_ctx)
 	torture_tcase_add_simple_test(tcase, "architecture_buffer", test_architecture_buffer);
 	torture_tcase_add_simple_test(tcase, "get_core_printer_drivers", test_get_core_printer_drivers);
 	torture_tcase_add_simple_test(tcase, "get_printer_driver_package_path", test_get_printer_driver_package_path);
+	torture_tcase_add_simple_test(tcase, "get_printer", test_get_printer_printserverhandle);
 
 	torture_suite_add_suite(suite, torture_rpc_spoolss_printer(suite));
 
-- 
2.7.4


From 990bec56aa6be91338d359ae8881c033fb6e2219 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
Date: Fri, 9 Sep 2016 16:34:57 +0200
Subject: [PATCH 2/8] s3-spoolss: Fix _spoolss_GetPrinter behaviour for server
 handles.

Without this the security tab of the print server properties will be obviously
empty and only display a warning.

Guenther

Signed-off-by: Guenther Deschner <gd at samba.org>
---
 source3/rpc_server/spoolss/srv_spoolss_nt.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index 90aac33..5195c20 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -4804,6 +4804,21 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p,
 		goto err_info_free;
 	}
 
+	if (Printer->printer_type == SPLHND_SERVER) {
+		if (r->in.level != 3) {
+			result = WERR_UNKNOWN_LEVEL;
+			goto err_info_free;
+		}
+
+		result = spoolss_create_default_secdesc(p->mem_ctx,
+							&r->out.info->info3.secdesc);
+		if (!W_ERROR_IS_OK(result)) {
+			goto err_info_free;
+		}
+
+		goto done;
+	}
+
 	if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 		result = WERR_BADFID;
 		goto err_info_free;
@@ -4880,7 +4895,7 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p,
 			  r->in.level, win_errstr(result)));
 		goto err_info_free;
 	}
-
+ done:
 	*r->out.needed	= SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
 					       r->out.info, r->in.level);
 	r->out.info	= SPOOLSS_BUFFER_OK(r->out.info, NULL);
-- 
2.7.4


From 70c03382762ec4f8fd45dcbd6de72d3a294cdf80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
Date: Sat, 10 Sep 2016 00:06:27 +0200
Subject: [PATCH 3/8] s3-rpc_client: add winreg_get_printserver_secdesc.

Guenther

Signed-off-by: Guenther Deschner <gd at samba.org>
---
 source3/rpc_client/cli_winreg_spoolss.c | 52 ++++++++++++++++++++++++---------
 source3/rpc_client/cli_winreg_spoolss.h | 17 +++++++++++
 2 files changed, 56 insertions(+), 13 deletions(-)

diff --git a/source3/rpc_client/cli_winreg_spoolss.c b/source3/rpc_client/cli_winreg_spoolss.c
index 8014e41..6eaa208 100644
--- a/source3/rpc_client/cli_winreg_spoolss.c
+++ b/source3/rpc_client/cli_winreg_spoolss.c
@@ -1605,15 +1605,15 @@ done:
 	return result;
 }
 
-WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
-				  struct dcerpc_binding_handle *winreg_handle,
-				  const char *sharename,
-				  struct spoolss_security_descriptor **psecdesc)
+static WERROR winreg_get_secdesc(TALLOC_CTX *mem_ctx,
+				 struct dcerpc_binding_handle *winreg_handle,
+				 const char *path,
+				 const char *attribute,
+				 struct spoolss_security_descriptor **psecdesc)
 {
 	struct spoolss_security_descriptor *secdesc;
 	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 	struct policy_handle hive_hnd, key_hnd;
-	const char *path;
 	TALLOC_CTX *tmp_ctx;
 	NTSTATUS status;
 	WERROR result;
@@ -1624,12 +1624,6 @@ WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
 		return WERR_NOMEM;
 	}
 
-	path = winreg_printer_data_keyname(tmp_ctx, sharename);
-	if (path == NULL) {
-		talloc_free(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
 	ZERO_STRUCT(hive_hnd);
 	ZERO_STRUCT(key_hnd);
 
@@ -1651,7 +1645,7 @@ WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
 	status = dcerpc_winreg_query_sd(tmp_ctx,
 					winreg_handle,
 					&key_hnd,
-					"Security",
+					attribute,
 					&secdesc,
 					&result);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -1740,7 +1734,7 @@ create_default:
 	status = dcerpc_winreg_set_sd(tmp_ctx,
 					  winreg_handle,
 					  &key_hnd,
-					  "Security",
+					  attribute,
 					  secdesc,
 					  &result);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -1767,6 +1761,38 @@ done:
 	return result;
 }
 
+WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
+				  struct dcerpc_binding_handle *winreg_handle,
+				  const char *sharename,
+				  struct spoolss_security_descriptor **psecdesc)
+{
+	WERROR result;
+	char *path;
+
+	path = winreg_printer_data_keyname(mem_ctx, sharename);
+	if (path == NULL) {
+		return WERR_NOMEM;
+	}
+
+	result = winreg_get_secdesc(mem_ctx, winreg_handle,
+				    path,
+				    "Security",
+				    psecdesc);
+	talloc_free(path);
+
+	return result;
+}
+
+WERROR winreg_get_printserver_secdesc(TALLOC_CTX *mem_ctx,
+				      struct dcerpc_binding_handle *winreg_handle,
+				      struct spoolss_security_descriptor **psecdesc)
+{
+	return winreg_get_secdesc(mem_ctx, winreg_handle,
+				  TOP_LEVEL_CONTROL_KEY,
+				  "ServerSecurityDescriptor",
+				  psecdesc);
+}
+
 WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
 				  struct dcerpc_binding_handle *winreg_handle,
 				  const char *sharename,
diff --git a/source3/rpc_client/cli_winreg_spoolss.h b/source3/rpc_client/cli_winreg_spoolss.h
index aa4d98f..279e585 100644
--- a/source3/rpc_client/cli_winreg_spoolss.h
+++ b/source3/rpc_client/cli_winreg_spoolss.h
@@ -146,6 +146,23 @@ WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
 				  struct spoolss_security_descriptor **psecdesc);
 
 /**
+ * @brief Get the security descriptor for a printserver.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[out] psecdesc   A pointer to store the security descriptor.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+
+WERROR winreg_get_printserver_secdesc(TALLOC_CTX *mem_ctx,
+				      struct dcerpc_binding_handle *winreg_handle,
+				      struct spoolss_security_descriptor **psecdesc);
+
+/**
  * @brief Set the security descriptor for a printer.
  *
  * @param[in]  mem_ctx  The talloc memory context to use.
-- 
2.7.4


From 69626216d0abe20d0a80d252c0435e9e9b7c8dc9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
Date: Sat, 10 Sep 2016 00:07:23 +0200
Subject: [PATCH 4/8] s3-rpc_client: add winreg_set_printserver_secdesc.

Guenther

Signed-off-by: Guenther Deschner <gd at samba.org>
---
 source3/rpc_client/cli_winreg_spoolss.c | 58 ++++++++++++++++++++++++---------
 source3/rpc_client/cli_winreg_spoolss.h | 17 ++++++++++
 2 files changed, 59 insertions(+), 16 deletions(-)

diff --git a/source3/rpc_client/cli_winreg_spoolss.c b/source3/rpc_client/cli_winreg_spoolss.c
index 6eaa208..37a20ad 100644
--- a/source3/rpc_client/cli_winreg_spoolss.c
+++ b/source3/rpc_client/cli_winreg_spoolss.c
@@ -1793,16 +1793,16 @@ WERROR winreg_get_printserver_secdesc(TALLOC_CTX *mem_ctx,
 				  psecdesc);
 }
 
-WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
-				  struct dcerpc_binding_handle *winreg_handle,
-				  const char *sharename,
-				  const struct spoolss_security_descriptor *secdesc)
+static WERROR winreg_set_secdesc(TALLOC_CTX *mem_ctx,
+				 struct dcerpc_binding_handle *winreg_handle,
+				 const char *path,
+				 const char *attribute,
+				 const struct spoolss_security_descriptor *secdesc)
 {
 	const struct spoolss_security_descriptor *new_secdesc = secdesc;
 	struct spoolss_security_descriptor *old_secdesc;
 	uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 	struct policy_handle hive_hnd, key_hnd;
-	const char *path;
 	TALLOC_CTX *tmp_ctx;
 	NTSTATUS status;
 	WERROR result;
@@ -1813,12 +1813,6 @@ WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
 		return WERR_NOMEM;
 	}
 
-	path = winreg_printer_data_keyname(tmp_ctx, sharename);
-	if (path == NULL) {
-		talloc_free(tmp_ctx);
-		return WERR_NOMEM;
-	}
-
 	/*
 	 * The old owner and group sids of the security descriptor are not
 	 * present when new ACEs are added or removed by changing printer
@@ -1830,10 +1824,11 @@ WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
 		struct security_acl *dacl, *sacl;
 		size_t size;
 
-		result = winreg_get_printer_secdesc(tmp_ctx,
-						    winreg_handle,
-						    sharename,
-						    &old_secdesc);
+		result = winreg_get_secdesc(tmp_ctx,
+					    winreg_handle,
+					    path,
+					    attribute,
+					    &old_secdesc);
 		if (!W_ERROR_IS_OK(result)) {
 			talloc_free(tmp_ctx);
 			return result;
@@ -1889,7 +1884,7 @@ WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
 	status = dcerpc_winreg_set_sd(tmp_ctx,
 				      winreg_handle,
 				      &key_hnd,
-				      "Security",
+				      attribute,
 				      new_secdesc,
 				      &result);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -1908,6 +1903,37 @@ done:
 	return result;
 }
 
+WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
+				  struct dcerpc_binding_handle *winreg_handle,
+				  const char *sharename,
+				  const struct spoolss_security_descriptor *secdesc)
+{
+	char *path;
+	WERROR result;
+
+	path = winreg_printer_data_keyname(mem_ctx, sharename);
+	if (path == NULL) {
+		return WERR_NOMEM;
+	}
+
+	result = winreg_set_secdesc(mem_ctx, winreg_handle,
+				    path,
+				    "Security", secdesc);
+	talloc_free(path);
+
+	return result;
+}
+
+WERROR winreg_set_printserver_secdesc(TALLOC_CTX *mem_ctx,
+				      struct dcerpc_binding_handle *winreg_handle,
+				      const struct spoolss_security_descriptor *secdesc)
+{
+	return winreg_set_secdesc(mem_ctx, winreg_handle,
+				  TOP_LEVEL_CONTROL_KEY,
+				  "ServerSecurityDescriptor",
+				  secdesc);
+}
+
 /* Set printer data over the winreg pipe. */
 WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
 				 struct dcerpc_binding_handle *winreg_handle,
diff --git a/source3/rpc_client/cli_winreg_spoolss.h b/source3/rpc_client/cli_winreg_spoolss.h
index 279e585..4fcb64e 100644
--- a/source3/rpc_client/cli_winreg_spoolss.h
+++ b/source3/rpc_client/cli_winreg_spoolss.h
@@ -182,6 +182,23 @@ WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
 				  const struct spoolss_security_descriptor *secdesc);
 
 /**
+ * @brief Set the security descriptor for a printserver.
+ *
+ * @param[in]  mem_ctx  The talloc memory context to use.
+ *
+ * @param[in]  b The dcerpc binding handle
+ *
+ * @param[in]  secdesc  The security descriptor to save.
+ *
+ * @return              On success WERR_OK, a corresponding DOS error is
+ *                      something went wrong.
+ */
+WERROR winreg_set_printserver_secdesc(TALLOC_CTX *mem_ctx,
+				      struct dcerpc_binding_handle *b,
+				      const struct spoolss_security_descriptor *secdesc);
+
+
+/**
  * @internal
  *
  * @brief Set printer data over the winreg pipe.
-- 
2.7.4


From 9ae2d086ae9a7d3d18ec81a127a2944ec0491793 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
Date: Sat, 10 Sep 2016 11:07:06 +0200
Subject: [PATCH 5/8] s4-torture: test spoolss_SetPrinter level 3 on server
 handle.

Guenther

Signed-off-by: Guenther Deschner <gd at samba.org>
---
 source4/torture/rpc/spoolss.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c
index ec48ecb..89cb161 100644
--- a/source4/torture/rpc/spoolss.c
+++ b/source4/torture/rpc/spoolss.c
@@ -284,7 +284,7 @@ static bool test_OpenPrinter_server(struct torture_context *tctx,
 	op.in.printername	= talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
 	op.in.datatype		= NULL;
 	op.in.devmode_ctr.devmode= NULL;
-	op.in.access_mask	= 0;
+	op.in.access_mask	= SEC_FLAG_MAXIMUM_ALLOWED;
 	op.out.handle		= server_handle;
 
 	torture_comment(tctx, "Testing OpenPrinter(%s)\n", op.in.printername);
@@ -8123,6 +8123,43 @@ static bool test_get_printer_printserverhandle(struct torture_context *tctx,
 	return true;
 }
 
+static bool test_set_printer_printserverhandle(struct torture_context *tctx,
+					       void *private_data)
+{
+	struct test_spoolss_context *ctx =
+		talloc_get_type_abort(private_data, struct test_spoolss_context);
+
+	struct dcerpc_pipe *p = ctx->spoolss_pipe;
+	struct dcerpc_binding_handle *b = p->binding_handle;
+	union spoolss_PrinterInfo info;
+	struct spoolss_SetPrinterInfoCtr info_ctr;
+	struct spoolss_SetPrinterInfo3 info3;
+	struct spoolss_DevmodeContainer devmode_ctr;
+	struct sec_desc_buf secdesc_ctr;
+
+	torture_assert(tctx,
+		test_GetPrinter_level(tctx, b, &ctx->server_handle, 3, &info),
+		"failed to call GetPrinter");
+
+	secdesc_ctr.sd = info.info3.secdesc;
+	secdesc_ctr.sd->owner_sid = NULL;
+	secdesc_ctr.sd->group_sid = NULL;
+
+	info3.sec_desc_ptr = NULL;
+
+	info_ctr.level = 3;
+	info_ctr.info.info3 = &info3;
+
+	ZERO_STRUCT(devmode_ctr);
+
+	torture_assert(tctx,
+		test_SetPrinter(tctx, b, &ctx->server_handle, &info_ctr,
+				&devmode_ctr, &secdesc_ctr, 0),
+		"");
+
+	return true;
+}
+
 
 static bool test_PrintServer_Forms_Winreg(struct torture_context *tctx,
 					  void *private_data)
@@ -9360,6 +9397,7 @@ struct torture_suite *torture_rpc_spoolss(TALLOC_CTX *mem_ctx)
 	torture_tcase_add_simple_test(tcase, "get_core_printer_drivers", test_get_core_printer_drivers);
 	torture_tcase_add_simple_test(tcase, "get_printer_driver_package_path", test_get_printer_driver_package_path);
 	torture_tcase_add_simple_test(tcase, "get_printer", test_get_printer_printserverhandle);
+	torture_tcase_add_simple_test(tcase, "set_printer", test_set_printer_printserverhandle);
 
 	torture_suite_add_suite(suite, torture_rpc_spoolss_printer(suite));
 
-- 
2.7.4


From 2b0f6936d0b1558c99c38beea04e63794ee7585d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
Date: Sat, 10 Sep 2016 11:09:44 +0200
Subject: [PATCH 6/8] s3-spoolss: use server sd stored in the backend in
 _spoolss_GetPrinter level 3

Guenther

Signed-off-by: Guenther Deschner <gd at samba.org>
---
 source3/rpc_server/spoolss/srv_spoolss_nt.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index 5195c20..1cbea09 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -4805,12 +4805,24 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p,
 	}
 
 	if (Printer->printer_type == SPLHND_SERVER) {
+
+		struct dcerpc_binding_handle *b;
+
 		if (r->in.level != 3) {
 			result = WERR_UNKNOWN_LEVEL;
 			goto err_info_free;
 		}
 
-		result = spoolss_create_default_secdesc(p->mem_ctx,
+		result = winreg_printer_binding_handle(p->mem_ctx,
+						       get_session_info_system(),
+						       p->msg_ctx,
+						       &b);
+		if (!W_ERROR_IS_OK(result)) {
+			goto err_info_free;
+		}
+
+		result = winreg_get_printserver_secdesc(p->mem_ctx,
+							b,
 							&r->out.info->info3.secdesc);
 		if (!W_ERROR_IS_OK(result)) {
 			goto err_info_free;
-- 
2.7.4


From 2a3608e5b73c1a8b14ee3ebf73b3bb7a4af1f43f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
Date: Sat, 10 Sep 2016 11:10:12 +0200
Subject: [PATCH 7/8] s3-spoolss: allow SetPrinter level 3 for server handles
 as well.

Guenther

Signed-off-by: Guenther Deschner <gd at samba.org>
---
 source3/rpc_server/spoolss/srv_spoolss_nt.c | 60 +++++++++++++++++++++++------
 1 file changed, 49 insertions(+), 11 deletions(-)

diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index 1cbea09..5b385d0 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -6083,14 +6083,15 @@ static WERROR update_printer_sec(struct policy_handle *handle,
 {
 	struct spoolss_security_descriptor *new_secdesc = NULL;
 	struct spoolss_security_descriptor *old_secdesc = NULL;
-	const char *printer;
+	const char *printer = NULL;
 	WERROR result;
 	int snum;
 	struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
 	struct dcerpc_binding_handle *b;
 	TALLOC_CTX *tmp_ctx = NULL;
+	bool ok = false;
 
-	if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
+	if (!Printer) {
 		DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
 			 OUR_HANDLE(handle)));
 
@@ -6103,15 +6104,41 @@ static WERROR update_printer_sec(struct policy_handle *handle,
 		result = WERR_INVALID_PARAM;
 		goto done;
 	}
-	printer = lp_const_servicename(snum);
+
+	switch (Printer->printer_type) {
+	case SPLHND_SERVER:
+		break;
+	case SPLHND_PRINTER:
+		if (!get_printer_snum(p, handle, &snum, NULL)) {
+			DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
+				 OUR_HANDLE(handle)));
+			result = WERR_BADFID;
+			goto done;
+		}
+		printer = lp_const_servicename(snum);
+		break;
+	default:
+		break;
+	}
 
 	/* Check the user has permissions to change the security
 	   descriptor.  By experimentation with two NT machines, the user
 	   requires Full Access to the printer to change security
 	   information. */
 
-	if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
-		DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
+	switch (Printer->printer_type) {
+	case SPLHND_SERVER:
+		ok = Printer->access_granted == SERVER_ACCESS_ADMINISTER;
+		break;
+	case SPLHND_PRINTER:
+		ok = Printer->access_granted == PRINTER_ACCESS_ADMINISTER;
+		break;
+	default:
+		break;
+	}
+
+	if (!ok) {
+		DEBUG(4,("update_printer_sec: updated denied by printer permissions (access_granted: 0x%08x)\n", Printer->access_granted));
 		result = WERR_ACCESS_DENIED;
 		goto done;
 	}
@@ -6131,9 +6158,15 @@ static WERROR update_printer_sec(struct policy_handle *handle,
 
 	/* NT seems to like setting the security descriptor even though
 	   nothing may have actually changed. */
-	result = winreg_get_printer_secdesc(tmp_ctx, b,
-					    printer,
-					    &old_secdesc);
+
+	if (printer != NULL) {
+		result = winreg_get_printer_secdesc(tmp_ctx, b,
+						    printer,
+						    &old_secdesc);
+	} else {
+		result = winreg_get_printserver_secdesc(tmp_ctx, b,
+							&old_secdesc);
+	}
 	if (!W_ERROR_IS_OK(result)) {
 		DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc_internal() failed\n"));
 		result = WERR_BADFID;
@@ -6181,9 +6214,14 @@ static WERROR update_printer_sec(struct policy_handle *handle,
 		goto done;
 	}
 
-	result = winreg_set_printer_secdesc(tmp_ctx, b,
-					    printer,
-					    new_secdesc);
+	if (printer != NULL) {
+		result = winreg_set_printer_secdesc(tmp_ctx, b,
+						    printer,
+						    new_secdesc);
+	} else {
+		result = winreg_set_printserver_secdesc(tmp_ctx, b,
+							new_secdesc);
+	}
 
 done:
 	talloc_free(tmp_ctx);
-- 
2.7.4


From fdffc268d605556d4c7106f275a97ed50c7025bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
Date: Tue, 13 Sep 2016 09:28:03 +0200
Subject: [PATCH 8/8] s4-torture: add new test to compare
 "ServerSecurityDescriptor" and GetPrinter level 3.

Guenther

Signed-off-by: Guenther Deschner <gd at samba.org>
---
 source4/torture/rpc/spoolss.c | 75 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 74 insertions(+), 1 deletion(-)

diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c
index 89cb161..ad7df37 100644
--- a/source4/torture/rpc/spoolss.c
+++ b/source4/torture/rpc/spoolss.c
@@ -4952,13 +4952,43 @@ do {\
 	}
 
 #undef test_dm
-#undef test_sd
 
 	torture_comment(tctx, "Printer Info and winreg consistency test succeeded\n\n");
 
 	return true;
 }
 
+static bool test_GetPrintserverInfo_winreg(struct torture_context *tctx,
+					   struct dcerpc_binding_handle *b,
+					   struct policy_handle *handle,
+					   struct dcerpc_binding_handle *winreg_handle,
+					   struct policy_handle *hive_handle)
+{
+	union spoolss_PrinterInfo info;
+	struct policy_handle key_handle;
+
+	torture_comment(tctx, "Testing Printserver Info and winreg consistency\n");
+
+	torture_assert(tctx,
+		test_GetPrinter_level(tctx, b, handle, 3, &info),
+		"failed to get printer info level 2");
+
+	torture_assert(tctx,
+		test_winreg_OpenKey(tctx, winreg_handle, hive_handle, TOP_LEVEL_CONTROL_KEY, &key_handle), "");
+
+	test_sd("ServerSecurityDescriptor", info.info3.secdesc);
+
+	torture_assert(tctx,
+		test_winreg_CloseKey(tctx, winreg_handle, &key_handle), "");
+
+#undef test_sd
+
+	torture_comment(tctx, "Printserver Info and winreg consistency test succeeded\n\n");
+
+	return true;
+}
+
+
 static bool test_PrintProcessors(struct torture_context *tctx,
 				 struct dcerpc_binding_handle *b,
 				 const char *environment,
@@ -5770,6 +5800,33 @@ static bool test_PrinterInfo_winreg(struct torture_context *tctx,
 	return ret;
 }
 
+static bool test_PrintserverInfo_winreg(struct torture_context *tctx,
+					struct dcerpc_pipe *p,
+					struct policy_handle *handle)
+{
+	struct dcerpc_binding_handle *b = p->binding_handle;
+	struct dcerpc_pipe *p2;
+	bool ret = true;
+	struct policy_handle hive_handle;
+	struct dcerpc_binding_handle *b2;
+
+	torture_assert_ntstatus_ok(tctx,
+		torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
+		"could not open winreg pipe");
+	b2 = p2->binding_handle;
+
+	torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
+
+	ret = test_GetPrintserverInfo_winreg(tctx, b, handle, b2, &hive_handle);
+
+	test_winreg_CloseKey(tctx, b2, &hive_handle);
+
+	talloc_free(p2);
+
+	return ret;
+}
+
+
 static bool test_DriverInfo_winreg(struct torture_context *tctx,
 				   struct dcerpc_pipe *p,
 				   struct policy_handle *handle,
@@ -8726,6 +8783,21 @@ static bool test_printer_info_winreg(struct torture_context *tctx,
 	return true;
 }
 
+static bool test_printserver_info_winreg(struct torture_context *tctx,
+					 void *private_data)
+{
+	struct test_spoolss_context *t =
+		(struct test_spoolss_context *)talloc_get_type_abort(private_data, struct test_spoolss_context);
+	struct dcerpc_pipe *p = t->spoolss_pipe;
+
+	torture_assert(tctx,
+		test_PrintserverInfo_winreg(tctx, p, &t->server_handle),
+		"failed to test printserver info winreg");
+
+	return true;
+}
+
+
 static bool test_printer_change_id(struct torture_context *tctx,
 				   void *private_data)
 {
@@ -9398,6 +9470,7 @@ struct torture_suite *torture_rpc_spoolss(TALLOC_CTX *mem_ctx)
 	torture_tcase_add_simple_test(tcase, "get_printer_driver_package_path", test_get_printer_driver_package_path);
 	torture_tcase_add_simple_test(tcase, "get_printer", test_get_printer_printserverhandle);
 	torture_tcase_add_simple_test(tcase, "set_printer", test_set_printer_printserverhandle);
+	torture_tcase_add_simple_test(tcase, "printserver_info_winreg", test_printserver_info_winreg);
 
 	torture_suite_add_suite(suite, torture_rpc_spoolss_printer(suite));
 
-- 
2.7.4



More information about the samba-technical mailing list