summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2016-11-15 14:29:29 +0100
committerJeremy Allison <jra@samba.org>2016-11-20 17:29:07 +0100
commit4d9f4bfc69a5899bdf91406dfb7efb70a530446c (patch)
tree0a1e92ca74c90a1eac050beea2fef2361c4ececc
parent4f702e4b4463319db6d7638901834611a665b884 (diff)
downloadsamba-4d9f4bfc69a5899bdf91406dfb7efb70a530446c.tar.gz
s3:spoolss: Add support for COPY_FROM_DIRECTORY in AddPrinterDriverEx
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12415 Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
-rw-r--r--source3/include/nt_printing.h7
-rw-r--r--source3/printing/nt_printing.c96
-rw-r--r--source3/rpc_server/spoolss/srv_spoolss_nt.c18
3 files changed, 100 insertions, 21 deletions
diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h
index e253658fa20..e0003f98762 100644
--- a/source3/include/nt_printing.h
+++ b/source3/include/nt_printing.h
@@ -170,11 +170,14 @@ bool delete_driver_files(const struct auth_session_info *server_info,
const struct spoolss_DriverInfo8 *r);
WERROR move_driver_to_download_area(struct auth_session_info *session_info,
- struct spoolss_AddDriverInfoCtr *r);
+ struct spoolss_AddDriverInfoCtr *r,
+ const char *driver_directory);
WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
struct auth_session_info *session_info,
- struct spoolss_AddDriverInfoCtr *r);
+ struct spoolss_AddDriverInfoCtr *r,
+ uint32_t flags,
+ const char **driver_directory);
void map_printer_permissions(struct security_descriptor *sd);
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 334a56e7556..394a3e5e7e1 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -864,7 +864,9 @@ static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
const char **config_file,
const char **help_file,
struct spoolss_StringArray *dependent_files,
- enum spoolss_DriverOSVersion *version)
+ enum spoolss_DriverOSVersion *version,
+ uint32_t flags,
+ const char **driver_directory)
{
const char *short_architecture;
int i;
@@ -879,6 +881,43 @@ static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
return WERR_INVALID_PARAMETER;
}
+ if (flags & APD_COPY_FROM_DIRECTORY) {
+ char *path;
+ char *q;
+
+ /*
+ * driver_path is set to:
+ *
+ * \\PRINTSRV\print$\x64\{279245b0-a8bd-4431-bf6f-baee92ac15c0}\pscript5.dll
+ */
+ path = talloc_strdup(mem_ctx, *driver_path);
+ if (path == NULL) {
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* Remove pscript5.dll */
+ q = strrchr_m(path, '\\');
+ if (q == NULL) {
+ return WERR_INVALID_PARAMETER;
+ }
+ *q = '\0';
+
+ /* Get \{279245b0-a8bd-4431-bf6f-baee92ac15c0} */
+ q = strrchr_m(path, '\\');
+ if (q == NULL) {
+ return WERR_INVALID_PARAMETER;
+ }
+
+ /*
+ * Set driver_directory to:
+ *
+ * {279245b0-a8bd-4431-bf6f-baee92ac15c0}
+ *
+ * This is the directory where all the files have been uploaded
+ */
+ *driver_directory = q + 1;
+ }
+
/* clean up the driver name.
* we can get .\driver.dll
* or worse c:\windows\system\driver.dll !
@@ -931,7 +970,9 @@ static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
struct auth_session_info *session_info,
- struct spoolss_AddDriverInfoCtr *r)
+ struct spoolss_AddDriverInfoCtr *r,
+ uint32_t flags,
+ const char **driver_directory)
{
switch (r->level) {
case 3:
@@ -942,7 +983,9 @@ WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
&r->info.info3->config_file,
&r->info.info3->help_file,
r->info.info3->dependent_files,
- &r->info.info3->version);
+ &r->info.info3->version,
+ flags,
+ driver_directory);
case 6:
return clean_up_driver_struct_level(mem_ctx, session_info,
r->info.info6->architecture,
@@ -951,7 +994,9 @@ WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
&r->info.info6->config_file,
&r->info.info6->help_file,
r->info.info6->dependent_files,
- &r->info.info6->version);
+ &r->info.info6->version,
+ flags,
+ driver_directory);
case 8:
return clean_up_driver_struct_level(mem_ctx, session_info,
r->info.info8->architecture,
@@ -960,7 +1005,9 @@ WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
&r->info.info8->config_file,
&r->info.info8->help_file,
r->info.info8->dependent_files,
- &r->info.info8->version);
+ &r->info.info8->version,
+ flags,
+ driver_directory);
default:
return WERR_NOT_SUPPORTED;
}
@@ -1012,7 +1059,8 @@ static WERROR move_driver_file_to_download_area(TALLOC_CTX *mem_ctx,
const char *driver_file,
const char *short_architecture,
uint32_t driver_version,
- uint32_t version)
+ uint32_t version,
+ const char *driver_directory)
{
struct smb_filename *smb_fname_old = NULL;
struct smb_filename *smb_fname_new = NULL;
@@ -1021,9 +1069,21 @@ static WERROR move_driver_file_to_download_area(TALLOC_CTX *mem_ctx,
NTSTATUS status;
WERROR ret;
- old_name = talloc_asprintf(mem_ctx, "%s/%s",
- short_architecture, driver_file);
- W_ERROR_HAVE_NO_MEMORY(old_name);
+ if (driver_directory != NULL) {
+ old_name = talloc_asprintf(mem_ctx,
+ "%s/%s/%s",
+ short_architecture,
+ driver_directory,
+ driver_file);
+ } else {
+ old_name = talloc_asprintf(mem_ctx,
+ "%s/%s",
+ short_architecture,
+ driver_file);
+ }
+ if (old_name == NULL) {
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
new_name = talloc_asprintf(mem_ctx, "%s/%d/%s",
short_architecture, driver_version, driver_file);
@@ -1076,7 +1136,8 @@ static WERROR move_driver_file_to_download_area(TALLOC_CTX *mem_ctx,
}
WERROR move_driver_to_download_area(struct auth_session_info *session_info,
- struct spoolss_AddDriverInfoCtr *r)
+ struct spoolss_AddDriverInfoCtr *r,
+ const char *driver_directory)
{
struct spoolss_AddDriverInfo3 *driver;
struct spoolss_AddDriverInfo3 converted_driver;
@@ -1201,7 +1262,8 @@ WERROR move_driver_to_download_area(struct auth_session_info *session_info,
driver->driver_path,
short_architecture,
driver->version,
- ver);
+ ver,
+ driver_directory);
if (!W_ERROR_IS_OK(err)) {
goto err_exit;
}
@@ -1215,7 +1277,8 @@ WERROR move_driver_to_download_area(struct auth_session_info *session_info,
driver->data_file,
short_architecture,
driver->version,
- ver);
+ ver,
+ driver_directory);
if (!W_ERROR_IS_OK(err)) {
goto err_exit;
}
@@ -1231,7 +1294,8 @@ WERROR move_driver_to_download_area(struct auth_session_info *session_info,
driver->config_file,
short_architecture,
driver->version,
- ver);
+ ver,
+ driver_directory);
if (!W_ERROR_IS_OK(err)) {
goto err_exit;
}
@@ -1248,7 +1312,8 @@ WERROR move_driver_to_download_area(struct auth_session_info *session_info,
driver->help_file,
short_architecture,
driver->version,
- ver);
+ ver,
+ driver_directory);
if (!W_ERROR_IS_OK(err)) {
goto err_exit;
}
@@ -1273,7 +1338,8 @@ WERROR move_driver_to_download_area(struct auth_session_info *session_info,
driver->dependent_files->string[i],
short_architecture,
driver->version,
- ver);
+ ver,
+ driver_directory);
if (!W_ERROR_IS_OK(err)) {
goto err_exit;
}
diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index 2b28332acec..2e19cf43d5f 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -8567,7 +8567,9 @@ WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
{
WERROR err = WERR_OK;
const char *driver_name = NULL;
+ const char *driver_directory = NULL;
uint32_t version;
+
/*
* we only support the semantics of AddPrinterDriver()
* i.e. only copy files that are newer than existing ones
@@ -8577,7 +8579,8 @@ WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
return WERR_INVALID_PARAMETER;
}
- if (r->in.flags != APD_COPY_NEW_FILES) {
+ if (!(r->in.flags & APD_COPY_ALL_FILES) &&
+ !(r->in.flags & APD_COPY_NEW_FILES)) {
return WERR_ACCESS_DENIED;
}
@@ -8591,12 +8594,19 @@ WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
}
DEBUG(5,("Cleaning driver's information\n"));
- err = clean_up_driver_struct(p->mem_ctx, p->session_info, r->in.info_ctr);
- if (!W_ERROR_IS_OK(err))
+ err = clean_up_driver_struct(p->mem_ctx,
+ p->session_info,
+ r->in.info_ctr,
+ r->in.flags,
+ &driver_directory);
+ if (!W_ERROR_IS_OK(err)) {
goto done;
+ }
DEBUG(5,("Moving driver to final destination\n"));
- err = move_driver_to_download_area(p->session_info, r->in.info_ctr);
+ err = move_driver_to_download_area(p->session_info,
+ r->in.info_ctr,
+ driver_directory);
if (!W_ERROR_IS_OK(err)) {
goto done;
}