[SCM] Samba Shared Repository - branch master updated

David Disseldorp ddiss at samba.org
Fri Jan 20 10:21:01 MST 2012


The branch, master has been updated
       via  3bfcf34 torture: add spoolss overlapping driver deletion tests
       via  7123b59 s3-spoolss: fix printer_driver_files_in_use() call ordering
       via  b37f66c torture: confirm printer driver file removal
       via  cc8cd7b torture: add spoolss del printer driver test
       via  b5f780c s3-spoolss: fix printer driver version deletion
       via  b2c9317 s3-spoolss: prefix print$ path on driver file deletion
      from  957ec28 s3: Fix a typo

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 3bfcf343cf451c25ed6873943ffc871a7abbb4c7
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Jan 17 17:07:01 2012 +0100

    torture: add spoolss overlapping driver deletion tests
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User: David Disseldorp <ddiss at samba.org>
    Autobuild-Date: Fri Jan 20 18:20:14 CET 2012 on sn-devel-104

commit 7123b592fe10f879d4e62ca25a35eefe82b02652
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Jan 17 17:06:38 2012 +0100

    s3-spoolss: fix printer_driver_files_in_use() call ordering
    
    printer_driver_files_in_use() performs two tasks: it returns whether any
    of the files in the to-be-deleted driver overlap with other drivers, it
    also trims such files from the info structure passed in.
    
    In processing a DeletePrinterDataEx request with DPD_DELETE_UNUSED_FILES
    set, printer_driver_files_in_use() must be called to ensure files in
    use by other drivers are not removed.
    
    https://bugzilla.samba.org/show_bug.cgi?id=4942
    
    Signed-off-by: Andreas Schneider <asn at samba.org>

commit b37f66c7b79e548aaa477ea0af12954ad2f2d205
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Jan 17 15:20:51 2012 +0100

    torture: confirm printer driver file removal
    
    Signed-off-by: Andreas Schneider <asn at samba.org>

commit cc8cd7b038a5184323a7e594280d5dbe579da73a
Author: David Disseldorp <ddiss at samba.org>
Date:   Mon Jan 16 16:30:17 2012 +0100

    torture: add spoolss del printer driver test
    
    Test handling of DeletePrinterDriverEx when the DPD_DELETE_ALL_FILES
    flag is set.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>

commit b5f780c418d08fd693f666ba8be557ddf9912337
Author: David Disseldorp <ddiss at samba.org>
Date:   Thu Jan 12 16:27:37 2012 +0100

    s3-spoolss: fix printer driver version deletion
    
    Spoolss delete printer driver code currently makes invalid version
    assumptions based on the architecture requested by the client.
    
    Ugly hacks are in place to cover removal of other versions (2 and 3).
    This change wraps multi version deletion in a simple for loop.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>

commit b2c9317cd1104e6c7d70e76e995b10079726f216
Author: David Disseldorp <ddiss at samba.org>
Date:   Wed Jan 11 19:50:36 2012 +0100

    s3-spoolss: prefix print$ path on driver file deletion
    
    Driver file paths stored in the registry do not include the server path
    prefix. delete_driver_files() incorrectly assumes such a prefix.
    
    https://bugzilla.samba.org/show_bug.cgi?id=8697
    
    Signed-off-by: Andreas Schneider <asn at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/printing/nt_printing.c              |   81 ++++-----
 source3/rpc_server/spoolss/srv_spoolss_nt.c |  280 +++++++++++----------------
 source4/torture/rpc/spoolss.c               |  260 +++++++++++++++++++++++++
 3 files changed, 410 insertions(+), 211 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index a8fde25..70346b2 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1474,20 +1474,30 @@ bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
 }
 
 static NTSTATUS driver_unlink_internals(connection_struct *conn,
-					const char *name)
+					const char *short_arch,
+					int vers,
+					const char *fname)
 {
+	TALLOC_CTX *tmp_ctx = talloc_new(conn);
 	struct smb_filename *smb_fname = NULL;
-	NTSTATUS status;
+	char *print_dlr_path;
+	NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+	print_dlr_path = talloc_asprintf(tmp_ctx, "%s/%d/%s",
+					 short_arch, vers, fname);
+	if (print_dlr_path == NULL) {
+		goto err_out;
+	}
 
-	status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
-	    &smb_fname);
+	status = create_synthetic_smb_fname(tmp_ctx, print_dlr_path,
+					    NULL, NULL, &smb_fname);
 	if (!NT_STATUS_IS_OK(status)) {
-		return status;
+		goto err_out;
 	}
 
 	status = unlink_internals(conn, NULL, 0, smb_fname, false);
-
-	TALLOC_FREE(smb_fname);
+err_out:
+	talloc_free(tmp_ctx);
 	return status;
 }
 
@@ -1500,9 +1510,7 @@ static NTSTATUS driver_unlink_internals(connection_struct *conn,
 bool delete_driver_files(const struct auth_session_info *session_info,
 			 const struct spoolss_DriverInfo8 *r)
 {
-	int i = 0;
-	char *s;
-	const char *file;
+	const char *short_arch;
 	connection_struct *conn;
 	NTSTATUS nt_status;
 	char *oldcwd;
@@ -1554,55 +1562,40 @@ bool delete_driver_files(const struct auth_session_info *session_info,
 		goto err_out;
 	}
 
-	/* now delete the files; must strip the '\print$' string from
-	   fron of path                                                */
+	short_arch = get_short_archi(r->architecture);
+	if (short_arch == NULL) {
+		DEBUG(0, ("bad architecture %s\n", r->architecture));
+		ret = false;
+		goto err_out;
+	}
+
+	/* now delete the files */
 
 	if (r->driver_path && r->driver_path[0]) {
-		if ((s = strchr(&r->driver_path[1], '\\')) != NULL) {
-			file = s;
-			DEBUG(10,("deleting driverfile [%s]\n", s));
-			driver_unlink_internals(conn, file);
-		}
+		DEBUG(10,("deleting driverfile [%s]\n", r->driver_path));
+		driver_unlink_internals(conn, short_arch, r->version, r->driver_path);
 	}
 
 	if (r->config_file && r->config_file[0]) {
-		if ((s = strchr(&r->config_file[1], '\\')) != NULL) {
-			file = s;
-			DEBUG(10,("deleting configfile [%s]\n", s));
-			driver_unlink_internals(conn, file);
-		}
+		DEBUG(10,("deleting configfile [%s]\n", r->config_file));
+		driver_unlink_internals(conn, short_arch, r->version, r->config_file);
 	}
 
 	if (r->data_file && r->data_file[0]) {
-		if ((s = strchr(&r->data_file[1], '\\')) != NULL) {
-			file = s;
-			DEBUG(10,("deleting datafile [%s]\n", s));
-			driver_unlink_internals(conn, file);
-		}
+		DEBUG(10,("deleting datafile [%s]\n", r->data_file));
+		driver_unlink_internals(conn, short_arch, r->version, r->data_file);
 	}
 
 	if (r->help_file && r->help_file[0]) {
-		if ((s = strchr(&r->help_file[1], '\\')) != NULL) {
-			file = s;
-			DEBUG(10,("deleting helpfile [%s]\n", s));
-			driver_unlink_internals(conn, file);
-		}
+		DEBUG(10,("deleting helpfile [%s]\n", r->help_file));
+		driver_unlink_internals(conn, short_arch, r->version, r->help_file);
 	}
 
-	/* check if we are done removing files */
-
 	if (r->dependent_files) {
+		int i = 0;
 		while (r->dependent_files[i] && r->dependent_files[i][0]) {
-			char *p;
-
-			/* bypass the "\print$" portion of the path */
-
-			if ((p = strchr(r->dependent_files[i]+1, '\\')) != NULL) {
-				file = p;
-				DEBUG(10,("deleting dependent file [%s]\n", file));
-				driver_unlink_internals(conn, file);
-			}
-
+			DEBUG(10,("deleting dependent file [%s]\n", r->dependent_files[i]));
+			driver_unlink_internals(conn, short_arch, r->version, r->dependent_files[i]);
 			i++;
 		}
 	}
diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index 7a51703..c691b4a 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -2039,6 +2039,12 @@ static const struct print_architecture_table_node archi_table[]= {
 	{NULL,                   "",		-1 }
 };
 
+static const int drv_cversion[] = {SPOOLSS_DRIVER_VERSION_9X,
+				   SPOOLSS_DRIVER_VERSION_NT35,
+				   SPOOLSS_DRIVER_VERSION_NT4,
+				   SPOOLSS_DRIVER_VERSION_200X,
+				   -1};
+
 static int get_version_id(const char *arch)
 {
 	int i;
@@ -2061,11 +2067,12 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
 {
 
 	struct spoolss_DriverInfo8 *info = NULL;
-	struct spoolss_DriverInfo8 *info_win2k = NULL;
 	int				version;
 	WERROR				status;
 	struct dcerpc_binding_handle *b;
 	TALLOC_CTX *tmp_ctx = NULL;
+	int i;
+	bool found;
 
 	/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
 	   and not a printer admin, then fail */
@@ -2101,64 +2108,100 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
 		goto done;
 	}
 
-	status = winreg_get_driver(tmp_ctx, b,
-				   r->in.architecture, r->in.driver,
-				   version, &info);
-	if (!W_ERROR_IS_OK(status)) {
-		/* try for Win2k driver if "Windows NT x86" */
-
-		if ( version == 2 ) {
-			version = 3;
-
-			status = winreg_get_driver(tmp_ctx, b,
-						   r->in.architecture,
-						   r->in.driver,
-						   version, &info);
-			if (!W_ERROR_IS_OK(status)) {
-				status = WERR_UNKNOWN_PRINTER_DRIVER;
-				goto done;
-			}
+	for (found = false, i = 0; drv_cversion[i] >= 0; i++) {
+		status = winreg_get_driver(tmp_ctx, b,
+					   r->in.architecture, r->in.driver,
+					   drv_cversion[i], &info);
+		if (!W_ERROR_IS_OK(status)) {
+			DEBUG(5, ("skipping del of driver with version %d\n",
+				  drv_cversion[i]));
+			continue;
 		}
-		/* otherwise it was a failure */
-		else {
-			status = WERR_UNKNOWN_PRINTER_DRIVER;
+		found = true;
+
+		if (printer_driver_in_use(tmp_ctx, b, info)) {
+			status = WERR_PRINTER_DRIVER_IN_USE;
 			goto done;
 		}
 
+		status = winreg_del_driver(tmp_ctx, b, info, drv_cversion[i]);
+		if (!W_ERROR_IS_OK(status)) {
+			DEBUG(0, ("failed del of driver with version %d\n",
+				  drv_cversion[i]));
+			goto done;
+		}
+	}
+	if (found == false) {
+		DEBUG(0, ("driver %s not found for deletion\n", r->in.driver));
+		status = WERR_UNKNOWN_PRINTER_DRIVER;
+	} else {
+		status = WERR_OK;
 	}
 
-	if (printer_driver_in_use(tmp_ctx,
-				  b,
-				  info)) {
+done:
+	talloc_free(tmp_ctx);
+
+	return status;
+}
+
+static WERROR spoolss_dpd_version(TALLOC_CTX *mem_ctx,
+				  struct pipes_struct *p,
+				  struct spoolss_DeletePrinterDriverEx *r,
+				  struct dcerpc_binding_handle *b,
+				  struct spoolss_DriverInfo8 *info)
+{
+	WERROR status;
+	bool delete_files;
+
+	if (printer_driver_in_use(mem_ctx, b, info)) {
 		status = WERR_PRINTER_DRIVER_IN_USE;
 		goto done;
 	}
 
-	if (version == 2) {
-		status = winreg_get_driver(tmp_ctx, b,
-					   r->in.architecture,
-					   r->in.driver, 3, &info_win2k);
-		if (W_ERROR_IS_OK(status)) {
-			/* if we get to here, we now have 2 driver info structures to remove */
-			/* remove the Win2k driver first*/
-
-			status = winreg_del_driver(tmp_ctx, b,
-						   info_win2k, 3);
-			talloc_free(info_win2k);
-
-			/* this should not have failed---if it did, report to client */
-			if (!W_ERROR_IS_OK(status)) {
-				goto done;
-			}
+	/*
+	 * we have a couple of cases to consider.
+	 * (1) Are any files in use?  If so and DPD_DELETE_ALL_FILES is set,
+	 *     then the delete should fail if **any** files overlap with
+	 *     other drivers
+	 * (2) If DPD_DELETE_UNUSED_FILES is set, then delete all
+	 *     non-overlapping files
+	 * (3) If neither DPD_DELETE_ALL_FILES nor DPD_DELETE_UNUSED_FILES
+	 *     are set, then do not delete any files
+	 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
+	 */
+
+	delete_files = r->in.delete_flags
+			& (DPD_DELETE_ALL_FILES | DPD_DELETE_UNUSED_FILES);
+
+
+	if (delete_files) {
+		bool in_use = printer_driver_files_in_use(mem_ctx, b, info);
+		if (in_use && (r->in.delete_flags & DPD_DELETE_ALL_FILES)) {
+			status = WERR_PRINTER_DRIVER_IN_USE;
+			goto done;
 		}
+		/*
+		 * printer_driver_files_in_use() has trimmed overlapping files
+		 * from info so they are not removed on DPD_DELETE_UNUSED_FILES
+		 */
 	}
 
-	status = winreg_del_driver(tmp_ctx, b,
-				   info, version);
 
-done:
-	talloc_free(tmp_ctx);
+	status = winreg_del_driver(mem_ctx, b, info, info->version);
+	if (!W_ERROR_IS_OK(status)) {
+		goto done;
+	}
+
+	/*
+	 * now delete any associated files if delete_files is
+	 * true. Even if this part failes, we return succes
+	 * because the driver doesn not exist any more
+	 */
+	if (delete_files) {
+		delete_driver_files(get_session_info_system(), info);
+	}
 
+done:
 	return status;
 }
 
@@ -2169,13 +2212,12 @@ done:
 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
 				      struct spoolss_DeletePrinterDriverEx *r)
 {
-	struct spoolss_DriverInfo8	*info = NULL;
-	struct spoolss_DriverInfo8	*info_win2k = NULL;
-	int				version;
-	bool				delete_files;
+	struct spoolss_DriverInfo8 *info = NULL;
 	WERROR				status;
 	struct dcerpc_binding_handle *b;
 	TALLOC_CTX *tmp_ctx = NULL;
+	int i;
+	bool found;
 
 	/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
 	   and not a printer admin, then fail */
@@ -2192,15 +2234,11 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
 	}
 
 	/* check that we have a valid driver name first */
-	if ((version = get_version_id(r->in.architecture)) == -1) {
+	if (get_version_id(r->in.architecture) == -1) {
 		/* this is what NT returns */
 		return WERR_INVALID_ENVIRONMENT;
 	}
 
-	if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) {
-		version = r->in.version;
-	}
-
 	tmp_ctx = talloc_new(p->mem_ctx);
 	if (!tmp_ctx) {
 		return WERR_NOMEM;
@@ -2214,127 +2252,35 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
 		goto done;
 	}
 
-	status = winreg_get_driver(tmp_ctx, b,
-				   r->in.architecture,
-				   r->in.driver,
-				   version,
-				   &info);
-	if (!W_ERROR_IS_OK(status)) {
-		status = WERR_UNKNOWN_PRINTER_DRIVER;
-
-		/*
-		 * if the client asked for a specific version,
-		 * or this is something other than Windows NT x86,
-		 * then we've failed
-		 */
-
-		if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
-			goto done;
-
-		/* try for Win2k driver if "Windows NT x86" */
+	for (found = false, i = 0; drv_cversion[i] >= 0; i++) {
+		if ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
+		 && (drv_cversion[i] != r->in.version)) {
+			continue;
+		}
 
-		version = 3;
+		/* check if a driver with this version exists before delete */
 		status = winreg_get_driver(tmp_ctx, b,
-					   r->in.architecture,
-					   r->in.driver,
-					   version, &info);
+					   r->in.architecture, r->in.driver,
+					   drv_cversion[i], &info);
 		if (!W_ERROR_IS_OK(status)) {
-			status = WERR_UNKNOWN_PRINTER_DRIVER;
-			goto done;
+			DEBUG(5, ("skipping del of driver with version %d\n",
+				  drv_cversion[i]));
+			continue;
 		}
-	}
-
-	if (printer_driver_in_use(tmp_ctx,
-				  b,
-				  info)) {
-		status = WERR_PRINTER_DRIVER_IN_USE;
-		goto done;
-	}
-
-	/*
-	 * we have a couple of cases to consider.
-	 * (1) Are any files in use?  If so and DPD_DELTE_ALL_FILE is set,
-	 *     then the delete should fail if **any** files overlap with
-	 *     other drivers
-	 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
-	 *     non-overlapping files
-	 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
-	 *     is set, the do not delete any files
-	 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
-	 */
-
-	delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
-
-	/* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
-
-	if (delete_files &&
-	    (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
-	    printer_driver_files_in_use(tmp_ctx,
-					b,
-					info)) {
-		status = WERR_PRINTER_DRIVER_IN_USE;
-		goto done;
-	}
-
-
-	/* also check for W32X86/3 if necessary; maybe we already have? */
-
-	if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION)  ) {
-		status = winreg_get_driver(tmp_ctx, b,
-					   r->in.architecture,
-					   r->in.driver, 3, &info_win2k);
-		if (W_ERROR_IS_OK(status)) {
-
-			if (delete_files &&
-			    (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
-			    printer_driver_files_in_use(info,
-							b,
-							info_win2k)) {
-				/* no idea of the correct error here */
-				talloc_free(info_win2k);
-				status = WERR_ACCESS_DENIED;
-				goto done;
-			}
-
-			/* if we get to here, we now have 2 driver info structures to remove */
-			/* remove the Win2k driver first*/
-
-			status = winreg_del_driver(tmp_ctx, b,
-						   info_win2k,
-						   3);
-
-			/* this should not have failed---if it did, report to client */
-
-			if (!W_ERROR_IS_OK(status)) {
-				goto done;
-			}
+		found = true;
 
-			/*
-			 * now delete any associated files if delete_files is
-			 * true. Even if this part failes, we return succes
-			 * because the driver doesn not exist any more
-			 */
-			if (delete_files) {
-				delete_driver_files(get_session_info_system(),
-						    info_win2k);
-			}
+		status = spoolss_dpd_version(tmp_ctx, p, r, b, info);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0, ("failed to delete driver with version %d\n",
+				  drv_cversion[i]));
+			goto done;
 		}
 	}
-
-	status = winreg_del_driver(tmp_ctx, b,
-				   info,
-				   version);
-	if (!W_ERROR_IS_OK(status)) {
-		goto done;
-	}
-
-	/*
-	 * now delete any associated files if delete_files is
-	 * true. Even if this part failes, we return succes
-	 * because the driver doesn not exist any more
-	 */
-	if (delete_files) {
-		delete_driver_files(get_session_info_system(), info);
+	if (found == false) {
+		DEBUG(0, ("driver %s not found for deletion\n", r->in.driver));
+		status = WERR_UNKNOWN_PRINTER_DRIVER;
+	} else {
+		status = WERR_OK;
 	}
 
 done:
diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c
index 3809136..df800dc 100644
--- a/source4/torture/rpc/spoolss.c
+++ b/source4/torture/rpc/spoolss.c
@@ -49,6 +49,8 @@
 #define TORTURE_DRIVER_EX_ADOBE		"torture_driver_ex_adobe"
 #define TORTURE_DRIVER_ADOBE_CUPSADDSMB	"torture_driver_adobe_cupsaddsmb"
 #define TORTURE_DRIVER_TIMESTAMPS	"torture_driver_timestamps"
+#define TORTURE_DRIVER_DELETER		"torture_driver_deleter"
+#define TORTURE_DRIVER_DELETERIN	"torture_driver_deleterin"
 
 #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
 #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"


-- 
Samba Shared Repository


More information about the samba-cvs mailing list