[PATCH] s3-printing: fix move_driver_to_download_area() error paths

David Disseldorp ddiss at suse.de
Fri Feb 25 06:19:17 MST 2011


WERR_ACCESS_DENIED errors are mapped to WERR_UNKNOWN_PRINTER_DRIVER,
resulting in incorrect error messages on Windows clients.

move_driver_to_download_area() returns *the same* error status values
to the caller via the *perr argument as well as the return value.

The create_directory() call is not checked for error.
---
 source3/include/nt_printing.h               |    3 +-
 source3/printing/nt_printing.c              |  119 ++++++++++++---------------
 source3/rpc_server/spoolss/srv_spoolss_nt.c |    4 +-
 3 files changed, 54 insertions(+), 72 deletions(-)

diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h
index 6db306e..02a72b3 100644
--- a/source3/include/nt_printing.h
+++ b/source3/include/nt_printing.h
@@ -170,8 +170,7 @@ bool delete_driver_files(const struct auth_serversupplied_info *server_info,
 			 const struct spoolss_DriverInfo8 *r);
 
 WERROR move_driver_to_download_area(struct pipes_struct *p,
-				    struct spoolss_AddDriverInfoCtr *r,
-				    WERROR *perr);
+				    struct spoolss_AddDriverInfoCtr *r);
 
 WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
 			      struct pipes_struct *rpc_pipe,
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 68b53c7..99524f8 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -940,8 +940,7 @@ static WERROR move_driver_file_to_download_area(TALLOC_CTX *mem_ctx,
 }
 
 WERROR move_driver_to_download_area(struct pipes_struct *p,
-				    struct spoolss_AddDriverInfoCtr *r,
-				    WERROR *perr)
+				    struct spoolss_AddDriverInfoCtr *r)
 {
 	struct spoolss_AddDriverInfo3 *driver;
 	struct spoolss_AddDriverInfo3 converted_driver;
@@ -956,8 +955,7 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 	char *oldcwd;
 	char *printdollar = NULL;
 	int printdollar_snum;
-
-	*perr = WERR_OK;
+	WERROR err = WERR_OK;
 
 	switch (r->level) {
 	case 3:
@@ -979,11 +977,9 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 
 	printdollar_snum = find_service(ctx, "print$", &printdollar);
 	if (!printdollar) {
-		*perr = WERR_NOMEM;
 		return WERR_NOMEM;
 	}
 	if (printdollar_snum == -1) {
-		*perr = WERR_NO_SUCH_SHARE;
 		return WERR_NO_SUCH_SHARE;
 	}
 
@@ -993,8 +989,8 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0,("move_driver_to_download_area: create_conn_struct "
 			 "returned %s\n", nt_errstr(nt_status)));
-		*perr = ntstatus_to_werror(nt_status);
-		return *perr;
+		err = ntstatus_to_werror(nt_status);
+		return err;
 	}
 
 	new_dir = talloc_asprintf(ctx,
@@ -1002,18 +998,25 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 				short_architecture,
 				driver->version);
 	if (!new_dir) {
-		*perr = WERR_NOMEM;
+		err = WERR_NOMEM;
 		goto err_exit;
 	}
 	nt_status = driver_unix_convert(conn, new_dir, &smb_dname);
 	if (!NT_STATUS_IS_OK(nt_status)) {
-		*perr = WERR_NOMEM;
+		err = WERR_NOMEM;
 		goto err_exit;
 	}
 
 	DEBUG(5,("Creating first directory: %s\n", smb_dname->base_name));
 
-	create_directory(conn, NULL, smb_dname);
+	nt_status = create_directory(conn, NULL, smb_dname);
+	if (!NT_STATUS_IS_OK(nt_status)
+	 && !NT_STATUS_EQUAL(nt_status, NT_STATUS_OBJECT_NAME_COLLISION)) {
+		DEBUG(0, ("failed to create driver destination directory: %s\n",
+			  nt_errstr(nt_status)));
+		err = ntstatus_to_werror(nt_status);
+		goto err_exit;
+	}
 
 	/* For each driver file, archi\filexxx.yyy, if there is a duplicate file
 	 * listed for this driver which has already been moved, skip it (note:
@@ -1036,16 +1039,13 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 
 	if (driver->driver_path && strlen(driver->driver_path)) {
 
-		*perr = move_driver_file_to_download_area(ctx,
-							  conn,
-							  driver->driver_path,
-							  short_architecture,
-							  driver->version,
-							  ver);
-		if (!W_ERROR_IS_OK(*perr)) {
-			if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
-				ver = -1;
-			}
+		err = move_driver_file_to_download_area(ctx,
+							conn,
+							driver->driver_path,
+							short_architecture,
+							driver->version,
+							ver);
+		if (!W_ERROR_IS_OK(err)) {
 			goto err_exit;
 		}
 	}
@@ -1053,16 +1053,13 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 	if (driver->data_file && strlen(driver->data_file)) {
 		if (!strequal(driver->data_file, driver->driver_path)) {
 
-			*perr = move_driver_file_to_download_area(ctx,
-								  conn,
-								  driver->data_file,
-								  short_architecture,
-								  driver->version,
-								  ver);
-			if (!W_ERROR_IS_OK(*perr)) {
-				if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
-					ver = -1;
-				}
+			err = move_driver_file_to_download_area(ctx,
+								conn,
+								driver->data_file,
+								short_architecture,
+								driver->version,
+								ver);
+			if (!W_ERROR_IS_OK(err)) {
 				goto err_exit;
 			}
 		}
@@ -1072,16 +1069,13 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 		if (!strequal(driver->config_file, driver->driver_path) &&
 		    !strequal(driver->config_file, driver->data_file)) {
 
-			*perr = move_driver_file_to_download_area(ctx,
-								  conn,
-								  driver->config_file,
-								  short_architecture,
-								  driver->version,
-								  ver);
-			if (!W_ERROR_IS_OK(*perr)) {
-				if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
-					ver = -1;
-				}
+			err = move_driver_file_to_download_area(ctx,
+								conn,
+								driver->config_file,
+								short_architecture,
+								driver->version,
+								ver);
+			if (!W_ERROR_IS_OK(err)) {
 				goto err_exit;
 			}
 		}
@@ -1092,16 +1086,13 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 		    !strequal(driver->help_file, driver->data_file) &&
 		    !strequal(driver->help_file, driver->config_file)) {
 
-			*perr = move_driver_file_to_download_area(ctx,
-								  conn,
-								  driver->help_file,
-								  short_architecture,
-								  driver->version,
-								  ver);
-			if (!W_ERROR_IS_OK(*perr)) {
-				if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
-					ver = -1;
-				}
+			err = move_driver_file_to_download_area(ctx,
+								conn,
+								driver->help_file,
+								short_architecture,
+								driver->version,
+								ver);
+			if (!W_ERROR_IS_OK(err)) {
 				goto err_exit;
 			}
 		}
@@ -1120,16 +1111,13 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 					}
 				}
 
-				*perr = move_driver_file_to_download_area(ctx,
-									  conn,
-									  driver->dependent_files->string[i],
-									  short_architecture,
-									  driver->version,
-									  ver);
-				if (!W_ERROR_IS_OK(*perr)) {
-					if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
-						ver = -1;
-					}
+				err = move_driver_file_to_download_area(ctx,
+									conn,
+									driver->dependent_files->string[i],
+									short_architecture,
+									driver->version,
+									ver);
+				if (!W_ERROR_IS_OK(err)) {
 					goto err_exit;
 				}
 			}
@@ -1137,6 +1125,7 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 		}
 	}
 
+	err = WERR_OK;
   err_exit:
 	TALLOC_FREE(smb_dname);
 
@@ -1145,13 +1134,7 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
 		conn_free(conn);
 	}
 
-	if (W_ERROR_EQUAL(*perr, WERR_OK)) {
-		return WERR_OK;
-	}
-	if (ver == -1) {
-		return WERR_UNKNOWN_PRINTER_DRIVER;
-	}
-	return (*perr);
+	return err;
 }
 
 /****************************************************************************
diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index 8d8dd61..e5485cc 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -8002,8 +8002,8 @@ WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
 		goto done;
 
 	DEBUG(5,("Moving driver to final destination\n"));
-	if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
-							      &err)) ) {
+	err = move_driver_to_download_area(p, r->in.info_ctr);
+	if (!W_ERROR_IS_OK(err)) {
 		goto done;
 	}
 
-- 
1.7.1



More information about the samba-technical mailing list