svn commit: samba r17205 - in branches/SAMBA_4_0/source/torture/rpc: .

vlendec at samba.org vlendec at samba.org
Sun Jul 23 16:54:17 GMT 2006


Author: vlendec
Date: 2006-07-23 16:54:16 +0000 (Sun, 23 Jul 2006)
New Revision: 17205

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=17205

Log:
Even if this makes me look foolish, at least start to scratch on the surface
of spoolss. If snum is to be removed, then we should make at least the attempt
to walk parts of the code before and after the changes.

This walks GetPrinterInfo level 0-7.

Volker

Modified:
   branches/SAMBA_4_0/source/torture/rpc/rpc.c
   branches/SAMBA_4_0/source/torture/rpc/samba3rpc.c


Changeset:
Modified: branches/SAMBA_4_0/source/torture/rpc/rpc.c
===================================================================
--- branches/SAMBA_4_0/source/torture/rpc/rpc.c	2006-07-23 13:30:25 UTC (rev 17204)
+++ branches/SAMBA_4_0/source/torture/rpc/rpc.c	2006-07-23 16:54:16 UTC (rev 17205)
@@ -135,6 +135,7 @@
 	register_torture_op("RPC-SAMBA3-GETUSERNAME",
 			    torture_samba3_rpc_getusername);
 	register_torture_op("RPC-SAMBA3-LSA", torture_samba3_rpc_lsa);
+	register_torture_op("RPC-SAMBA3-SPOOLSS", torture_samba3_rpc_spoolss);
 	register_torture_op("RPC-DRSUAPI", torture_rpc_drsuapi);
 	register_torture_op("RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames);
 	register_torture_op("RPC-ROT", torture_rpc_rot);

Modified: branches/SAMBA_4_0/source/torture/rpc/samba3rpc.c
===================================================================
--- branches/SAMBA_4_0/source/torture/rpc/samba3rpc.c	2006-07-23 13:30:25 UTC (rev 17204)
+++ branches/SAMBA_4_0/source/torture/rpc/samba3rpc.c	2006-07-23 16:54:16 UTC (rev 17205)
@@ -32,6 +32,8 @@
 #include "librpc/gen_ndr/ndr_netlogon_c.h"
 #include "librpc/gen_ndr/ndr_srvsvc.h"
 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
+#include "librpc/gen_ndr/ndr_spoolss.h"
+#include "librpc/gen_ndr/ndr_spoolss_c.h"
 #include "lib/cmdline/popt_common.h"
 #include "librpc/rpc/dcerpc.h"
 #include "torture/rpc/rpc.h"
@@ -1355,17 +1357,18 @@
  * open pipe and bind, given an IPC$ context
  */
 
-static struct dcerpc_pipe *pipe_bind_smb(TALLOC_CTX *mem_ctx,
-					 struct smbcli_tree *tree,
-					 const char *pipe_name,
-					 const struct dcerpc_interface_table *iface)
+static NTSTATUS pipe_bind_smb(TALLOC_CTX *mem_ctx,
+			      struct smbcli_tree *tree,
+			      const char *pipe_name,
+			      const struct dcerpc_interface_table *iface,
+			      struct dcerpc_pipe **p)
 {
 	struct dcerpc_pipe *result;
 	NTSTATUS status;
 
 	if (!(result = dcerpc_pipe_init(
 		      mem_ctx, tree->session->transport->socket->event.ctx))) {
-		return NULL;
+		return NT_STATUS_NO_MEMORY;
 	}
 
 	status = dcerpc_pipe_open_smb(result->conn, tree, pipe_name);
@@ -1373,17 +1376,18 @@
 		d_printf("dcerpc_pipe_open_smb failed: %s\n",
 			 nt_errstr(status));
 		talloc_free(result);
-		return NULL;
+		return status;
 	}
 
 	status = dcerpc_bind_auth_none(result, iface);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("schannel bind failed: %s\n", nt_errstr(status));
 		talloc_free(result);
-		return NULL;
+		return status;
 	}
 
-	return result;
+	*p = result;
+	return NT_STATUS_OK;
 }
 
 /*
@@ -1486,9 +1490,11 @@
 	struct lsa_StringPointer authority_name_p;
 	struct dom_sid *result;
 
-	if (!(lsa = pipe_bind_smb(mem_ctx, tree, "\\pipe\\lsarpc",
-				  &dcerpc_table_lsarpc))) {
-		d_printf("Could not bind to LSA\n");
+	status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\lsarpc",
+			       &dcerpc_table_lsarpc, &lsa);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("(%s) Could not bind to LSA: %s\n",
+			 __location__, nt_errstr(status));
 		return NULL;
 	}
 
@@ -1800,6 +1806,7 @@
 	BOOL ret = True;
 	const char *sharename = NULL;
 	struct smbcli_state *cli;
+	NTSTATUS status;
 
 	if (!(mem_ctx = talloc_new(torture))) {
 		return False;
@@ -1812,9 +1819,11 @@
 		return False;
 	}
 
-	if (!(p = pipe_bind_smb(mem_ctx, cli->tree, "\\pipe\\srvsvc",
-				&dcerpc_table_srvsvc))) {
-		d_printf("could not bind to srvsvc pipe\n");
+	status = pipe_bind_smb(mem_ctx, cli->tree, "\\pipe\\srvsvc",
+			       &dcerpc_table_srvsvc, &p);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("(%s) could not bind to srvsvc pipe: %s\n",
+			 __location__, nt_errstr(status));
 		ret = False;
 		goto done;
 	}
@@ -1853,9 +1862,11 @@
 		return NULL;
 	}
 
-	if (!(p = pipe_bind_smb(mem_ctx, tree, "\\pipe\\srvsvc",
-				&dcerpc_table_srvsvc))) {
-		d_printf("could not bind to srvsvc pipe\n");
+	status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\srvsvc",
+			       &dcerpc_table_srvsvc, &p);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("(%s) could not bind to srvsvc pipe: %s\n",
+			 __location__, nt_errstr(status));
 		talloc_free(tmp_ctx);
 		return NULL;
 	}
@@ -1906,9 +1917,11 @@
 		return NT_STATUS_UNSUCCESSFUL;
 	}
 
-	if (!(p = pipe_bind_smb(mem_ctx, tree, "\\pipe\\srvsvc",
-				&dcerpc_table_srvsvc))) {
-		d_printf("could not bind to srvsvc pipe\n");
+	status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\srvsvc",
+			       &dcerpc_table_srvsvc, &p);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("(%s) could not bind to srvsvc pipe: %s\n",
+			 __location__, nt_errstr(status));
 		talloc_free(tmp_ctx);
 		return NT_STATUS_UNSUCCESSFUL;
 	}
@@ -2094,10 +2107,11 @@
 		return False;
 	}
 
-	p = pipe_bind_smb(mem_ctx, cli->tree, "\\lsarpc",
-			  &dcerpc_table_lsarpc);
-	if (p == NULL) {
-		d_printf("(%s) pipe_bind_smb failed\n", __location__);
+	status = pipe_bind_smb(mem_ctx, cli->tree, "\\lsarpc",
+			       &dcerpc_table_lsarpc, &p);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
+			 nt_errstr(status));
 		talloc_free(mem_ctx);
 		return False;
 	}
@@ -2148,3 +2162,272 @@
 
 	return ret;
 }
+
+static NTSTATUS find_printers(TALLOC_CTX *ctx, struct smbcli_tree *tree,
+			      const char ***printers, int *num_printers)
+{
+	TALLOC_CTX *mem_ctx;
+	NTSTATUS status;
+	struct dcerpc_pipe *p;
+	struct srvsvc_NetShareEnum r;
+	struct srvsvc_NetShareCtr1 c1_in;
+	struct srvsvc_NetShareCtr1 *c1;
+	int i;
+
+	mem_ctx = talloc_new(ctx);
+	if (mem_ctx == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	status = pipe_bind_smb(mem_ctx, tree, "\\srvsvc", &dcerpc_table_srvsvc,
+			       &p);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("could not bind to srvsvc pipe\n");
+		talloc_free(mem_ctx);
+		return status;
+	}
+
+	r.in.server_unc = talloc_asprintf(
+		mem_ctx, "\\\\%s", dcerpc_server_name(p));
+	r.in.level = 1;
+	ZERO_STRUCT(c1_in);
+	r.in.ctr.ctr1 = &c1_in;
+	r.in.max_buffer = (uint32_t)-1;
+	r.in.resume_handle = NULL;
+
+	status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("NetShareEnum level %u failed - %s\n",
+			 r.in.level, nt_errstr(status));
+		talloc_free(mem_ctx);
+		return status;
+	}
+
+	*printers = NULL;
+	*num_printers = 0;
+	c1 = r.out.ctr.ctr1;
+	for (i=0; i<c1->count; i++) {
+		if (c1->array[i].type != STYPE_PRINTQ) {
+			continue;
+		}
+		if (!add_string_to_array(ctx, c1->array[i].name,
+					 printers, num_printers)) {
+			talloc_free(ctx);
+			return NT_STATUS_NO_MEMORY;
+		}
+	}
+
+	talloc_free(mem_ctx);
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS getprinterinfo(TALLOC_CTX *ctx, struct dcerpc_pipe *pipe,
+			       struct policy_handle *handle, int level,
+			       union spoolss_PrinterInfo **res)
+{
+	TALLOC_CTX *mem_ctx;
+	struct spoolss_GetPrinter r;
+	DATA_BLOB blob;
+	NTSTATUS status;
+
+	mem_ctx = talloc_new(ctx);
+	if (mem_ctx == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	r.in.handle = handle;
+	r.in.level = level;
+	r.in.buffer = NULL;
+	r.in.offered = 0;
+
+	status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s\n",
+			 __location__, nt_errstr(status));
+		talloc_free(mem_ctx);
+		return status;
+	}
+
+	if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+		printf("GetPrinter unexpected return code %s, should "
+		       "be WERR_INSUFFICIENT_BUFFER\n",
+		       win_errstr(r.out.result));
+		talloc_free(mem_ctx);
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	r.in.handle = handle;
+	r.in.level = level;
+	blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
+	if (blob.data == NULL) {
+		talloc_free(mem_ctx);
+		return NT_STATUS_NO_MEMORY;
+	}
+	memset(blob.data, 0, blob.length);
+	r.in.buffer = &blob;
+	r.in.offered = r.out.needed;
+
+	status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
+	if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
+		d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s, "
+			 "%s\n", __location__, nt_errstr(status),
+			 win_errstr(r.out.result));
+		talloc_free(mem_ctx);
+		return NT_STATUS_IS_OK(status) ?
+			NT_STATUS_UNSUCCESSFUL : status;
+	}
+
+	if (res != NULL) {
+		*res = talloc_steal(ctx, r.out.info);
+	}
+
+	talloc_free(mem_ctx);
+	return NT_STATUS_OK;
+}
+	
+
+BOOL torture_samba3_rpc_spoolss(struct torture_context *torture)
+{
+	TALLOC_CTX *mem_ctx;
+	BOOL ret = True;
+	struct smbcli_state *cli;
+	struct dcerpc_pipe *p;
+	NTSTATUS status;
+	struct policy_handle server_handle, printer_handle;
+	const char **printers;
+	int num_printers;
+	struct spoolss_UserLevel1 userlevel1;
+
+	if (!(mem_ctx = talloc_new(torture))) {
+		return False;
+	}
+
+	if (!(torture_open_connection_share(
+		      mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
+		      "IPC$", NULL))) {
+		d_printf("IPC$ connection failed\n");
+		talloc_free(mem_ctx);
+		return False;
+	}
+
+	if (!NT_STATUS_IS_OK(find_printers(mem_ctx, cli->tree,
+					   &printers, &num_printers))) {
+		talloc_free(mem_ctx);
+		return False;
+	}
+
+	if (num_printers == 0) {
+		d_printf("Did not find printers\n");
+		talloc_free(mem_ctx);
+		return True;
+	}
+
+	status = pipe_bind_smb(mem_ctx, cli->tree, "\\spoolss",
+			       &dcerpc_table_spoolss, &p);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
+			 nt_errstr(status));
+		talloc_free(mem_ctx);
+		return False;
+	}
+
+	ZERO_STRUCT(userlevel1);
+	userlevel1.client = talloc_asprintf(
+		mem_ctx, "\\\\%s", lp_netbios_name());
+	userlevel1.user = cli_credentials_get_username(cmdline_credentials);
+	userlevel1.build = 2600;
+	userlevel1.major = 3;
+	userlevel1.minor = 0;
+	userlevel1.processor = 0;
+
+	{
+		struct spoolss_OpenPrinterEx r;
+
+		ZERO_STRUCT(r);
+		r.in.printername = talloc_asprintf(
+			mem_ctx, "\\\\%s", dcerpc_server_name(p));
+		r.in.datatype = NULL;
+		r.in.access_mask = 0;
+		r.in.level = 1;
+		r.in.userlevel.level1 = &userlevel1;
+		r.out.handle = &server_handle;
+
+		status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
+		if (!NT_STATUS_IS_OK(status)) {
+			d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
+				 "%s\n", __location__, nt_errstr(status));
+			talloc_free(mem_ctx);
+			return False;
+		}
+	}
+
+	{
+		struct spoolss_ClosePrinter r;
+
+		r.in.handle = &server_handle;
+		r.out.handle = &server_handle;
+
+		status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
+		if (!NT_STATUS_IS_OK(status)) {
+			d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
+				 "%s\n", __location__, nt_errstr(status));
+			talloc_free(mem_ctx);
+			return False;
+		}
+	}
+
+	{
+		struct spoolss_OpenPrinterEx r;
+
+		ZERO_STRUCT(r);
+		r.in.printername = talloc_asprintf(
+			mem_ctx, "\\\\%s\\%s", dcerpc_server_name(p),
+			printers[0]);
+		r.in.datatype = NULL;
+		r.in.access_mask = 0;
+		r.in.level = 1;
+		r.in.userlevel.level1 = &userlevel1;
+		r.out.handle = &printer_handle;
+
+		status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
+		if (!NT_STATUS_IS_OK(status)) {
+			d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
+				 "%s\n", __location__, nt_errstr(status));
+			talloc_free(mem_ctx);
+			return False;
+		}
+	}
+
+	{
+		int i;
+
+		for (i=0; i<8; i++) {
+			status = getprinterinfo(mem_ctx, p, &printer_handle,
+						i, NULL);
+			if (!NT_STATUS_IS_OK(status)) {
+				d_printf("(%s) getprinterinfo %d failed: %s\n",
+					 __location__, i, nt_errstr(status));
+				ret = False;
+			}
+		}
+	}
+
+	{
+		struct spoolss_ClosePrinter r;
+
+		r.in.handle = &printer_handle;
+		r.out.handle = &printer_handle;
+
+		status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
+		if (!NT_STATUS_IS_OK(status)) {
+			d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
+				 "%s\n", __location__, nt_errstr(status));
+			talloc_free(mem_ctx);
+			return False;
+		}
+	}
+
+	talloc_free(mem_ctx);
+
+	return ret;
+}



More information about the samba-cvs mailing list