From f65ba94ada0a0de39acb626b2aa72269673e1fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Thu, 12 May 2011 14:33:15 +0200 Subject: [PATCH 01/21] s3-waf: stop building smbtortre4. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther Autobuild-User: Günther Deschner Autobuild-Date: Thu May 12 15:35:02 CEST 2011 on sn-devel-104 (cherry picked from commit c1ac023b588e1ca676cbbf542ca6f93aa199ad32) --- source3/wscript_build | 7 ------- 1 files changed, 0 insertions(+), 7 deletions(-) diff --git a/source3/wscript_build b/source3/wscript_build index 3f9437a..712e8ba 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -640,13 +640,6 @@ t = bld.SAMBA_GENERATOR('build_env.h', t.env.SRCDIR = bld.path.abspath() t.env.BUILDDIR = bld.path.abspath() -if not bld.env.toplevel_build: - bld.SAMBA_GENERATOR('smbtorture4', - source='', - target='', - rule='cd ../; make -f Makefile-smbtorture4 bin/smbtorture4', - always=True) - bld.SETUP_BUILD_GROUPS() if not bld.env.toplevel_build: -- 1.7.6 From d09dd1f0acd829f9fe2bf1a742164a21ca8f2f9a Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Wed, 15 Jun 2011 12:46:55 +0200 Subject: [PATCH 02/21] s3-printing: fill devicemode size in migrate_printer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Günther Deschner (cherry picked from commit a36ce0735ff6cad8124bd63a056a71d9495b238c) --- source3/printing/nt_printing_migrate.c | 1 + source3/utils/net_printing.c | 1 + 2 files changed, 2 insertions(+), 0 deletions(-) diff --git a/source3/printing/nt_printing_migrate.c b/source3/printing/nt_printing_migrate.c index f56fa9a..8d0551c 100644 --- a/source3/printing/nt_printing_migrate.c +++ b/source3/printing/nt_printing_migrate.c @@ -318,6 +318,7 @@ static NTSTATUS migrate_printer(TALLOC_CTX *mem_ctx, dm.pelsheight = r.devmode->pelsheight; dm.pelswidth = r.devmode->pelswidth; dm.printquality = r.devmode->printquality; + dm.size = r.devmode->size; dm.scale = r.devmode->scale; dm.specversion = r.devmode->specversion; dm.ttoption = r.devmode->ttoption; diff --git a/source3/utils/net_printing.c b/source3/utils/net_printing.c index 7e72823..fb7106d 100644 --- a/source3/utils/net_printing.c +++ b/source3/utils/net_printing.c @@ -466,6 +466,7 @@ static NTSTATUS migrate_printer(TALLOC_CTX *mem_ctx, dm.pelsheight = r.devmode->pelsheight; dm.pelswidth = r.devmode->pelswidth; dm.printquality = r.devmode->printquality; + dm.size = r.devmode->size; dm.scale = r.devmode->scale; dm.specversion = r.devmode->specversion; dm.ttoption = r.devmode->ttoption; -- 1.7.6 From 47449be08d25be449651062f4668ce4aeb4d355b Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Wed, 15 Jun 2011 14:59:49 +0200 Subject: [PATCH 03/21] s3-printing: skip migration of non-existent printers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Skip tdb migration of printer and security descriptor entries which refer to non-existent printers. Signed-off-by: Günther Deschner Autobuild-User: Günther Deschner Autobuild-Date: Thu Jun 30 10:54:23 CEST 2011 on sn-devel-104 (cherry picked from commit c9e3f6ab02bdc354a9b656f62744ee66fe9e9e67) --- source3/printing/nt_printing_migrate.c | 26 ++++++++++++++++++-------- 1 files changed, 18 insertions(+), 8 deletions(-) diff --git a/source3/printing/nt_printing_migrate.c b/source3/printing/nt_printing_migrate.c index 8d0551c..e122934 100644 --- a/source3/printing/nt_printing_migrate.c +++ b/source3/printing/nt_printing_migrate.c @@ -459,10 +459,6 @@ static NTSTATUS migrate_secdesc(TALLOC_CTX *mem_ctx, key_name, nt_errstr(status))); return status; } - if (W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME, result)) { - DEBUG(3, ("Ignoring missing printer %s\n", key_name)); - return NT_STATUS_OK; - } if (!W_ERROR_IS_OK(result)) { DEBUG(2, ("OpenPrinter(%s) failed: %s\n", key_name, win_errstr(result))); @@ -588,13 +584,20 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, } if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) { + const char *printer_name = (const char *)(kbuf.dptr + + strlen(PRINTERS_PREFIX)); status = migrate_printer(mem_ctx, pipe_hnd, - (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX), + printer_name, dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); - if (!NT_STATUS_IS_OK(status)) { + /* currently no WERR_INVALID_PRINTER_NAME equivalent */ + if (NT_STATUS_EQUAL(status, + werror_to_ntstatus(WERR_INVALID_PRINTER_NAME))) { + DEBUG(2, ("Skipping migration for non-existent " + "printer: %s\n", printer_name)); + } else if (!NT_STATUS_IS_OK(status)) { tdb_close(tdb); return status; } @@ -602,13 +605,20 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, } if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) { + const char *secdesc_name = (const char *)(kbuf.dptr + + strlen(SECDESC_PREFIX)); status = migrate_secdesc(mem_ctx, pipe_hnd, - (const char *) kbuf.dptr + strlen(SECDESC_PREFIX), + secdesc_name, dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); - if (!NT_STATUS_IS_OK(status)) { + /* currently no WERR_INVALID_PRINTER_NAME equivalent */ + if (NT_STATUS_EQUAL(status, + werror_to_ntstatus(WERR_INVALID_PRINTER_NAME))) { + DEBUG(2, ("Skipping migration for non-existent " + "secdesc: %s\n", secdesc_name)); + } else if (!NT_STATUS_IS_OK(status)) { tdb_close(tdb); return status; } -- 1.7.6 From 5f3f83203c00adc5d5f40d2802459c25c5197d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Fri, 1 Jul 2011 14:57:32 +0200 Subject: [PATCH 04/21] s3-printing: split out printing migration code into a smaller library. Guenther (cherry picked from commit e02abd6c83708f297b1985bb1bdc7d5dfbc924b2) Conflicts: source3/printing/nt_printing_migrate.c source3/wscript_build --- source3/Makefile.in | 1 + source3/printing/nt_printing_migrate.c | 265 ++--------------------- source3/printing/nt_printing_migrate.h | 21 ++- source3/printing/nt_printing_migrate_internal.c | 249 +++++++++++++++++++++ source3/printing/nt_printing_migrate_internal.h | 26 +++ source3/printing/spoolssd.c | 2 +- source3/rpc_server/rpc_ep_setup.c | 2 +- source3/wscript_build | 10 +- 8 files changed, 327 insertions(+), 249 deletions(-) create mode 100644 source3/printing/nt_printing_migrate_internal.c create mode 100644 source3/printing/nt_printing_migrate_internal.h diff --git a/source3/Makefile.in b/source3/Makefile.in index 485de6a..de692cf 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -948,6 +948,7 @@ PRINTBACKEND_OBJ = printing/printing.o \ printing/nt_printing.o \ printing/nt_printing_tdb.o \ printing/nt_printing_migrate.o \ + printing/nt_printing_migrate_internal.o \ printing/nt_printing_ads.o \ librpc/gen_ndr/ndr_ntprinting.o \ ../librpc/ndr/ndr_ntprinting.o \ diff --git a/source3/printing/nt_printing_migrate.c b/source3/printing/nt_printing_migrate.c index e122934..3b2e543 100644 --- a/source3/printing/nt_printing_migrate.c +++ b/source3/printing/nt_printing_migrate.c @@ -19,27 +19,18 @@ */ #include "includes.h" -#include "system/filesys.h" #include "printing/nt_printing_migrate.h" #include "rpc_client/rpc_client.h" #include "librpc/gen_ndr/ndr_ntprinting.h" #include "librpc/gen_ndr/ndr_spoolss_c.h" #include "librpc/gen_ndr/ndr_security.h" -#include "rpc_server/rpc_ncacn_np.h" -#include "auth.h" -#include "util_tdb.h" - -#define FORMS_PREFIX "FORMS/" -#define DRIVERS_PREFIX "DRIVERS/" -#define PRINTERS_PREFIX "PRINTERS/" -#define SECDESC_PREFIX "SECDESC/" - -static NTSTATUS migrate_form(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, - const char *key_name, - unsigned char *data, - size_t length) + +NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx, + struct rpc_pipe_client *pipe_hnd, + const char *key_name, + unsigned char *data, + size_t length) { struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; struct spoolss_DevmodeContainer devmode_ctr; @@ -133,11 +124,11 @@ static NTSTATUS migrate_form(TALLOC_CTX *mem_ctx, return status; } -static NTSTATUS migrate_driver(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, - const char *key_name, - unsigned char *data, - size_t length) +NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx, + struct rpc_pipe_client *pipe_hnd, + const char *key_name, + unsigned char *data, + size_t length) { struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; const char *srv_name_slash; @@ -205,11 +196,11 @@ static NTSTATUS migrate_driver(TALLOC_CTX *mem_ctx, return status; } -static NTSTATUS migrate_printer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, - const char *key_name, - unsigned char *data, - size_t length) +NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, + struct rpc_pipe_client *pipe_hnd, + const char *key_name, + unsigned char *data, + size_t length) { struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; struct policy_handle hnd; @@ -409,11 +400,11 @@ static NTSTATUS migrate_printer(TALLOC_CTX *mem_ctx, return status; } -static NTSTATUS migrate_secdesc(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, - const char *key_name, - unsigned char *data, - size_t length) +NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx, + struct rpc_pipe_client *pipe_hnd, + const char *key_name, + unsigned char *data, + size_t length) { struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; struct policy_handle hnd; @@ -494,217 +485,3 @@ static NTSTATUS migrate_secdesc(TALLOC_CTX *mem_ctx, return status; } - -static int rename_file_with_suffix(TALLOC_CTX *mem_ctx, - const char *path, - const char *suffix) -{ - int rc = -1; - char *dst_path; - - dst_path = talloc_asprintf(mem_ctx, "%s%s", path, suffix); - if (dst_path == NULL) { - DEBUG(3, ("error out of memory\n")); - return rc; - } - - rc = (rename(path, dst_path) != 0); - - if (rc == 0) { - DEBUG(5, ("moved '%s' to '%s'\n", path, dst_path)); - } else if (errno == ENOENT) { - DEBUG(3, ("file '%s' does not exist - so not moved\n", path)); - rc = 0; - } else { - DEBUG(3, ("error renaming %s to %s: %s\n", path, dst_path, - strerror(errno))); - } - - TALLOC_FREE(dst_path); - return rc; -} - -static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, - const char *tdb_path, - struct rpc_pipe_client *pipe_hnd) -{ - const char *backup_suffix = ".bak"; - TDB_DATA kbuf, newkey, dbuf; - TDB_CONTEXT *tdb; - NTSTATUS status; - int rc; - - tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDONLY, 0600); - if (tdb == NULL && errno == ENOENT) { - /* if we have no printers database then migration is - considered successful */ - DEBUG(4, ("No printers database to migrate in %s\n", tdb_path)); - return NT_STATUS_OK; - } - if (tdb == NULL) { - DEBUG(2, ("Failed to open tdb file: %s\n", tdb_path)); - return NT_STATUS_NO_SUCH_FILE; - } - - for (kbuf = tdb_firstkey(tdb); - kbuf.dptr; - newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey) - { - dbuf = tdb_fetch(tdb, kbuf); - if (!dbuf.dptr) { - continue; - } - - if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) { - status = migrate_form(mem_ctx, - pipe_hnd, - (const char *) kbuf.dptr + strlen(FORMS_PREFIX), - dbuf.dptr, - dbuf.dsize); - SAFE_FREE(dbuf.dptr); - if (!NT_STATUS_IS_OK(status)) { - tdb_close(tdb); - return status; - } - continue; - } - - if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) { - status = migrate_driver(mem_ctx, - pipe_hnd, - (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX), - dbuf.dptr, - dbuf.dsize); - SAFE_FREE(dbuf.dptr); - if (!NT_STATUS_IS_OK(status)) { - tdb_close(tdb); - return status; - } - continue; - } - - if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) { - const char *printer_name = (const char *)(kbuf.dptr - + strlen(PRINTERS_PREFIX)); - status = migrate_printer(mem_ctx, - pipe_hnd, - printer_name, - dbuf.dptr, - dbuf.dsize); - SAFE_FREE(dbuf.dptr); - /* currently no WERR_INVALID_PRINTER_NAME equivalent */ - if (NT_STATUS_EQUAL(status, - werror_to_ntstatus(WERR_INVALID_PRINTER_NAME))) { - DEBUG(2, ("Skipping migration for non-existent " - "printer: %s\n", printer_name)); - } else if (!NT_STATUS_IS_OK(status)) { - tdb_close(tdb); - return status; - } - continue; - } - - if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) { - const char *secdesc_name = (const char *)(kbuf.dptr - + strlen(SECDESC_PREFIX)); - status = migrate_secdesc(mem_ctx, - pipe_hnd, - secdesc_name, - dbuf.dptr, - dbuf.dsize); - SAFE_FREE(dbuf.dptr); - /* currently no WERR_INVALID_PRINTER_NAME equivalent */ - if (NT_STATUS_EQUAL(status, - werror_to_ntstatus(WERR_INVALID_PRINTER_NAME))) { - DEBUG(2, ("Skipping migration for non-existent " - "secdesc: %s\n", secdesc_name)); - } else if (!NT_STATUS_IS_OK(status)) { - tdb_close(tdb); - return status; - } - continue; - } - } - - tdb_close(tdb); - - rc = rename_file_with_suffix(mem_ctx, tdb_path, backup_suffix); - if (rc != 0) { - DEBUG(0, ("Error moving tdb to '%s%s'\n", - tdb_path, backup_suffix)); - } - - return NT_STATUS_OK; -} - -bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx) -{ - const char *drivers_path = state_path("ntdrivers.tdb"); - const char *printers_path = state_path("ntprinters.tdb"); - const char *forms_path = state_path("ntforms.tdb"); - bool drivers_exists = file_exist(drivers_path); - bool printers_exists = file_exist(printers_path); - bool forms_exists = file_exist(forms_path); - struct auth_serversupplied_info *session_info; - struct rpc_pipe_client *spoolss_pipe = NULL; - TALLOC_CTX *tmp_ctx = talloc_stackframe(); - NTSTATUS status; - - if (!drivers_exists && !printers_exists && !forms_exists) { - return true; - } - - status = make_session_info_system(tmp_ctx, &session_info); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Couldn't create session_info: %s\n", - nt_errstr(status))); - talloc_free(tmp_ctx); - return false; - } - - status = rpc_pipe_open_interface(tmp_ctx, - &ndr_table_spoolss.syntax_id, - session_info, - NULL, - msg_ctx, - &spoolss_pipe); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Couldn't open internal spoolss pipe: %s\n", - nt_errstr(status))); - talloc_free(tmp_ctx); - return false; - } - - if (drivers_exists) { - status = migrate_internal(tmp_ctx, drivers_path, spoolss_pipe); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Couldn't migrate drivers tdb file: %s\n", - nt_errstr(status))); - talloc_free(tmp_ctx); - return false; - } - } - - if (printers_exists) { - status = migrate_internal(tmp_ctx, printers_path, spoolss_pipe); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Couldn't migrate printers tdb file: %s\n", - nt_errstr(status))); - talloc_free(tmp_ctx); - return false; - } - } - - if (forms_exists) { - status = migrate_internal(tmp_ctx, forms_path, spoolss_pipe); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Couldn't migrate forms tdb file: %s\n", - nt_errstr(status))); - talloc_free(tmp_ctx); - return false; - } - } - - talloc_free(tmp_ctx); - return true; -} diff --git a/source3/printing/nt_printing_migrate.h b/source3/printing/nt_printing_migrate.h index 9ab2fa7..4991d06 100644 --- a/source3/printing/nt_printing_migrate.h +++ b/source3/printing/nt_printing_migrate.h @@ -21,6 +21,25 @@ #ifndef _NT_PRINTING_MIGRATE_H_ #define _NT_PRINTING_MIGRATE_H_ -bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx); +NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx, + struct rpc_pipe_client *pipe_hnd, + const char *key_name, + unsigned char *data, + size_t length); +NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx, + struct rpc_pipe_client *pipe_hnd, + const char *key_name, + unsigned char *data, + size_t length); +NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, + struct rpc_pipe_client *pipe_hnd, + const char *key_name, + unsigned char *data, + size_t length); +NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx, + struct rpc_pipe_client *pipe_hnd, + const char *key_name, + unsigned char *data, + size_t length); #endif /* _NT_PRINTING_MIGRATE_H_ */ diff --git a/source3/printing/nt_printing_migrate_internal.c b/source3/printing/nt_printing_migrate_internal.c new file mode 100644 index 0000000..f868713 --- /dev/null +++ b/source3/printing/nt_printing_migrate_internal.c @@ -0,0 +1,249 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * + * Copyright (c) Andreas Schneider 2010. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" +#include "system/filesys.h" +#include "printing/nt_printing_migrate.h" +#include "printing/nt_printing_migrate_internal.h" + +#include "rpc_client/rpc_client.h" +#include "librpc/gen_ndr/ndr_spoolss_c.h" +#include "rpc_server/rpc_ncacn_np.h" +#include "auth.h" +#include "util_tdb.h" + +#define FORMS_PREFIX "FORMS/" +#define DRIVERS_PREFIX "DRIVERS/" +#define PRINTERS_PREFIX "PRINTERS/" +#define SECDESC_PREFIX "SECDESC/" + +static int rename_file_with_suffix(TALLOC_CTX *mem_ctx, + const char *path, + const char *suffix) +{ + int rc = -1; + char *dst_path; + + dst_path = talloc_asprintf(mem_ctx, "%s%s", path, suffix); + if (dst_path == NULL) { + DEBUG(3, ("error out of memory\n")); + return rc; + } + + rc = (rename(path, dst_path) != 0); + + if (rc == 0) { + DEBUG(5, ("moved '%s' to '%s'\n", path, dst_path)); + } else if (errno == ENOENT) { + DEBUG(3, ("file '%s' does not exist - so not moved\n", path)); + rc = 0; + } else { + DEBUG(3, ("error renaming %s to %s: %s\n", path, dst_path, + strerror(errno))); + } + + TALLOC_FREE(dst_path); + return rc; +} + +static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, + const char *tdb_path, + struct rpc_pipe_client *pipe_hnd) +{ + const char *backup_suffix = ".bak"; + TDB_DATA kbuf, newkey, dbuf; + TDB_CONTEXT *tdb; + NTSTATUS status; + int rc; + + tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDONLY, 0600); + if (tdb == NULL && errno == ENOENT) { + /* if we have no printers database then migration is + considered successful */ + DEBUG(4, ("No printers database to migrate in %s\n", tdb_path)); + return NT_STATUS_OK; + } + if (tdb == NULL) { + DEBUG(2, ("Failed to open tdb file: %s\n", tdb_path)); + return NT_STATUS_NO_SUCH_FILE; + } + + for (kbuf = tdb_firstkey(tdb); + kbuf.dptr; + newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey) + { + dbuf = tdb_fetch(tdb, kbuf); + if (!dbuf.dptr) { + continue; + } + + if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) { + status = printing_tdb_migrate_form(mem_ctx, + pipe_hnd, + (const char *) kbuf.dptr + strlen(FORMS_PREFIX), + dbuf.dptr, + dbuf.dsize); + SAFE_FREE(dbuf.dptr); + if (!NT_STATUS_IS_OK(status)) { + tdb_close(tdb); + return status; + } + continue; + } + + if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) { + status = printing_tdb_migrate_driver(mem_ctx, + pipe_hnd, + (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX), + dbuf.dptr, + dbuf.dsize); + SAFE_FREE(dbuf.dptr); + if (!NT_STATUS_IS_OK(status)) { + tdb_close(tdb); + return status; + } + continue; + } + + if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) { + const char *printer_name = (const char *)(kbuf.dptr + + strlen(PRINTERS_PREFIX)); + status = printing_tdb_migrate_printer(mem_ctx, + pipe_hnd, + printer_name, + dbuf.dptr, + dbuf.dsize); + SAFE_FREE(dbuf.dptr); + /* currently no WERR_INVALID_PRINTER_NAME equivalent */ + if (NT_STATUS_EQUAL(status, + werror_to_ntstatus(WERR_INVALID_PRINTER_NAME))) { + DEBUG(2, ("Skipping migration for non-existent " + "printer: %s\n", printer_name)); + } else if (!NT_STATUS_IS_OK(status)) { + tdb_close(tdb); + return status; + } + continue; + } + + if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) { + const char *secdesc_name = (const char *)(kbuf.dptr + + strlen(SECDESC_PREFIX)); + status = printing_tdb_migrate_secdesc(mem_ctx, + pipe_hnd, + secdesc_name, + dbuf.dptr, + dbuf.dsize); + SAFE_FREE(dbuf.dptr); + /* currently no WERR_INVALID_PRINTER_NAME equivalent */ + if (NT_STATUS_EQUAL(status, + werror_to_ntstatus(WERR_INVALID_PRINTER_NAME))) { + DEBUG(2, ("Skipping migration for non-existent " + "secdesc: %s\n", secdesc_name)); + } else if (!NT_STATUS_IS_OK(status)) { + tdb_close(tdb); + return status; + } + continue; + } + } + + tdb_close(tdb); + + rc = rename_file_with_suffix(mem_ctx, tdb_path, backup_suffix); + if (rc != 0) { + DEBUG(0, ("Error moving tdb to '%s%s'\n", + tdb_path, backup_suffix)); + } + + return NT_STATUS_OK; +} + +bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx) +{ + const char *drivers_path = state_path("ntdrivers.tdb"); + const char *printers_path = state_path("ntprinters.tdb"); + const char *forms_path = state_path("ntforms.tdb"); + bool drivers_exists = file_exist(drivers_path); + bool printers_exists = file_exist(printers_path); + bool forms_exists = file_exist(forms_path); + struct auth_serversupplied_info *session_info; + struct rpc_pipe_client *spoolss_pipe = NULL; + TALLOC_CTX *tmp_ctx = talloc_stackframe(); + NTSTATUS status; + + if (!drivers_exists && !printers_exists && !forms_exists) { + return true; + } + + status = make_session_info_system(tmp_ctx, &session_info); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Couldn't create session_info: %s\n", + nt_errstr(status))); + talloc_free(tmp_ctx); + return false; + } + + status = rpc_pipe_open_interface(tmp_ctx, + &ndr_table_spoolss.syntax_id, + session_info, + NULL, + msg_ctx, + &spoolss_pipe); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Couldn't open internal spoolss pipe: %s\n", + nt_errstr(status))); + talloc_free(tmp_ctx); + return false; + } + + if (drivers_exists) { + status = migrate_internal(tmp_ctx, drivers_path, spoolss_pipe); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Couldn't migrate drivers tdb file: %s\n", + nt_errstr(status))); + talloc_free(tmp_ctx); + return false; + } + } + + if (printers_exists) { + status = migrate_internal(tmp_ctx, printers_path, spoolss_pipe); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Couldn't migrate printers tdb file: %s\n", + nt_errstr(status))); + talloc_free(tmp_ctx); + return false; + } + } + + if (forms_exists) { + status = migrate_internal(tmp_ctx, forms_path, spoolss_pipe); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Couldn't migrate forms tdb file: %s\n", + nt_errstr(status))); + talloc_free(tmp_ctx); + return false; + } + } + + talloc_free(tmp_ctx); + return true; +} diff --git a/source3/printing/nt_printing_migrate_internal.h b/source3/printing/nt_printing_migrate_internal.h new file mode 100644 index 0000000..dfcf914 --- /dev/null +++ b/source3/printing/nt_printing_migrate_internal.h @@ -0,0 +1,26 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * + * Copyright (c) Andreas Schneider 2010. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef _NT_PRINTING_MIGRATE_INTERNAL_H_ +#define _NT_PRINTING_MIGRATE_INTERNAL_H_ + +bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx); + +#endif /* _NT_PRINTING_MIGRATE_INTERNAL_H_ */ diff --git a/source3/printing/spoolssd.c b/source3/printing/spoolssd.c index 896aee0..cb90a9f 100644 --- a/source3/printing/spoolssd.c +++ b/source3/printing/spoolssd.c @@ -22,7 +22,7 @@ #include "messages.h" #include "include/printing.h" -#include "printing/nt_printing_migrate.h" +#include "printing/nt_printing_migrate_internal.h" #include "ntdomain.h" #include "librpc/gen_ndr/srv_winreg.h" #include "librpc/gen_ndr/srv_spoolss.h" diff --git a/source3/rpc_server/rpc_ep_setup.c b/source3/rpc_server/rpc_ep_setup.c index 2d4c7e9..ee2aed0 100644 --- a/source3/rpc_server/rpc_ep_setup.c +++ b/source3/rpc_server/rpc_ep_setup.c @@ -39,7 +39,7 @@ #include "../librpc/gen_ndr/srv_svcctl.h" #include "../librpc/gen_ndr/srv_wkssvc.h" -#include "printing/nt_printing_migrate.h" +#include "printing/nt_printing_migrate_internal.h" #include "rpc_server/eventlog/srv_eventlog_reg.h" #include "rpc_server/svcctl/srv_svcctl_reg.h" #include "rpc_server/spoolss/srv_spoolss_nt.h" diff --git a/source3/wscript_build b/source3/wscript_build index 712e8ba..cf034e2 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -404,7 +404,7 @@ PRINTBASE_SRC = '''printing/notify.c printing/printing_db.c''' PRINTBACKEND_SRC = '''printing/printing.c printing/nt_printing.c printing/nt_printing_tdb.c - printing/nt_printing_migrate.c + printing/nt_printing_migrate_internal.c printing/nt_printing_ads.c''' SMBD_SRC = '''${SMBD_SRC_BASE} ${SMBD_SRC_MAIN}''' @@ -882,9 +882,15 @@ bld.SAMBA3_SUBSYSTEM('PRINTBASE', bld.SAMBA3_SUBSYSTEM('PRINTBACKEND', source=PRINTBACKEND_SRC, - deps='PRINTBASE NDR_NTPRINTING LIBADS_PRINTER', + deps='PRINTBASE LIBADS_PRINTER tdb printing_migrate', vars=locals()) +bld.SAMBA3_LIBRARY('printing_migrate', + source='printing/nt_printing_migrate.c', + deps='NDR_NTPRINTING RPC_NDR_SPOOLSS param', + vars=locals(), + private_library=True) + bld.SAMBA3_SUBSYSTEM('PRINTING', source=PRINTING_SRC, deps='NDR_PRINTCAP', -- 1.7.6 From 302a810556f886e3f048f728ff025021ba047729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Fri, 1 Jul 2011 15:02:26 +0200 Subject: [PATCH 05/21] s3-net: use printing_migrate library, and eliminate duplicate code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther Autobuild-User: Günther Deschner Autobuild-Date: Fri Jul 1 17:57:09 CEST 2011 on sn-devel-104 (cherry picked from commit bafd7212eb4c82e86874b2f80ddf5c04b2d180b9) Conflicts: source3/utils/net_printing.c --- source3/Makefile.in | 2 +- source3/utils/net_printing.c | 421 +----------------------------------------- source3/wscript_build | 1 + 3 files changed, 8 insertions(+), 416 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index de692cf..390f6ea 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1186,7 +1186,7 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_help.o \ rpc_client/init_samr.o \ registry/reg_parse.o registry/reg_format.o \ registry/reg_parse_internal.o registry/reg_import.o \ - lib/cbuf.o lib/srprs.o + lib/cbuf.o lib/srprs.o printing/nt_printing_migrate.o # these are not processed by make proto NET_OBJ2 = utils/net_registry_util.o utils/net_help_common.o diff --git a/source3/utils/net_printing.c b/source3/utils/net_printing.c index fb7106d..3b37d6e 100644 --- a/source3/utils/net_printing.c +++ b/source3/utils/net_printing.c @@ -24,11 +24,11 @@ #include "utils/net.h" #include "rpc_client/rpc_client.h" #include "librpc/gen_ndr/ndr_ntprinting.h" -#include "librpc/gen_ndr/ndr_spoolss_c.h" -#include "rpc_client/cli_spoolss.h" +#include "librpc/gen_ndr/ndr_spoolss.h" #include "../libcli/security/security.h" #include "../librpc/gen_ndr/ndr_security.h" #include "util_tdb.h" +#include "printing/nt_printing_migrate.h" #define FORMS_PREFIX "FORMS/" #define DRIVERS_PREFIX "DRIVERS/" @@ -218,415 +218,6 @@ static int net_printing_dump(struct net_context *c, int argc, return ret; } -static NTSTATUS migrate_form(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, - const char *key_name, - unsigned char *data, - size_t length) -{ - struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; - struct policy_handle hnd; - enum ndr_err_code ndr_err; - struct ntprinting_form r; - union spoolss_AddFormInfo f; - struct spoolss_AddFormInfo1 f1; - DATA_BLOB blob; - NTSTATUS status; - WERROR result; - - blob = data_blob_const(data, length); - - ZERO_STRUCT(r); - - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, - (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - d_fprintf(stderr, _("form pull failed: %s\n"), - ndr_errstr(ndr_err)); - return NT_STATUS_NO_MEMORY; - } - - /* Don't migrate builtin forms */ - if (r.flag == SPOOLSS_FORM_BUILTIN) { - return NT_STATUS_OK; - } - - d_printf(_("Migrating Form: %s\n"), key_name); - - result = rpccli_spoolss_openprinter_ex(pipe_hnd, - mem_ctx, - pipe_hnd->srv_name_slash, - MAXIMUM_ALLOWED_ACCESS, - &hnd); - if (!W_ERROR_IS_OK(result)) { - d_fprintf(stderr, _("OpenPrinter(%s) failed: %s\n"), - pipe_hnd->srv_name_slash, win_errstr(result)); - return werror_to_ntstatus(result); - } - - f1.form_name = key_name; - f1.flags = r.flag; - - f1.size.width = r.width; - f1.size.height = r.length; - - f1.area.top = r.top; - f1.area.right = r.right; - f1.area.bottom = r.bottom; - f1.area.left = r.left; - - f.info1 = &f1; - - status = dcerpc_spoolss_AddForm(b, - mem_ctx, - &hnd, - 1, - f, - &result); - if (!NT_STATUS_IS_OK(status)) { - d_printf(_("\tAddForm(%s) refused -- %s.\n"), - f.info1->form_name, nt_errstr(status)); - } else if (!W_ERROR_IS_OK(result)) { - d_printf(_("\tAddForm(%s) refused -- %s.\n"), - f.info1->form_name, win_errstr(result)); - status = werror_to_ntstatus(result); - } - - dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result); - - return status; -} - -static NTSTATUS migrate_driver(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, - const char *key_name, - unsigned char *data, - size_t length) -{ - struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; - enum ndr_err_code ndr_err; - struct ntprinting_driver r; - struct spoolss_AddDriverInfoCtr d; - struct spoolss_AddDriverInfo3 d3; - struct spoolss_StringArray a; - DATA_BLOB blob; - NTSTATUS status; - WERROR result; - - blob = data_blob_const(data, length); - - ZERO_STRUCT(r); - - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, - (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - d_fprintf(stderr, _("driver pull failed: %s\n"), - ndr_errstr(ndr_err)); - return NT_STATUS_NO_MEMORY; - } - - d_printf(_("Migrating Printer Driver: %s\n"), key_name); - - ZERO_STRUCT(d3); - ZERO_STRUCT(a); - - a.string = r.dependent_files; - - d3.architecture = r.environment; - d3.config_file = r.configfile; - d3.data_file = r.datafile; - d3.default_datatype = r.defaultdatatype; - d3.dependent_files = &a; - d3.driver_path = r.driverpath; - d3.help_file = r.helpfile; - d3.monitor_name = r.monitorname; - d3.driver_name = r.name; - d3.version = r.version; - - d.info.info3 = &d3; - d.level = 3; - - status = dcerpc_spoolss_AddPrinterDriver(b, - mem_ctx, - NULL, - &d, - &result); - if (!NT_STATUS_IS_OK(status)) { - d_printf(_("\tAddDriver driver: [%s] refused -- %s.\n"), - d3.driver_name, nt_errstr(status)); - } else if (!W_ERROR_IS_OK(result)) { - d_printf(_("\tAddDriver driver: [%s] refused -- %s.\n"), - d3.driver_name, win_errstr(result)); - status = werror_to_ntstatus(result); - } - - return status; -} - -static NTSTATUS migrate_printer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, - const char *key_name, - unsigned char *data, - size_t length) -{ - struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; - struct policy_handle hnd; - enum ndr_err_code ndr_err; - struct ntprinting_printer r; - struct spoolss_SetPrinterInfo2 info2; - struct spoolss_DeviceMode dm; - struct spoolss_SetPrinterInfoCtr info_ctr; - struct spoolss_DevmodeContainer devmode_ctr; - struct sec_desc_buf secdesc_ctr; - DATA_BLOB blob; - NTSTATUS status; - WERROR result; - int j; - - if (strequal(key_name, "printers")) { - return NT_STATUS_OK; - } - - blob = data_blob_const(data, length); - - ZERO_STRUCT(r); - - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, - (ndr_pull_flags_fn_t) ndr_pull_ntprinting_printer); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - d_fprintf(stderr, _("printer pull failed: %s\n"), - ndr_errstr(ndr_err)); - return NT_STATUS_NO_MEMORY; - } - - d_printf(_("Migrating Printer: %s\n"), key_name); - - result = rpccli_spoolss_openprinter_ex(pipe_hnd, - mem_ctx, - key_name, - MAXIMUM_ALLOWED_ACCESS, - &hnd); - if (!W_ERROR_IS_OK(result)) { - d_fprintf(stderr, _("OpenPrinter(%s) failed: %s\n"), - key_name, win_errstr(result)); - return werror_to_ntstatus(result); - } - - /* Create printer info level 2 */ - ZERO_STRUCT(info2); - ZERO_STRUCT(devmode_ctr); - ZERO_STRUCT(secdesc_ctr); - - info2.attributes = r.info.attributes; - info2.averageppm = r.info.averageppm; - info2.cjobs = r.info.cjobs; - info2.comment = r.info.comment; - info2.datatype = r.info.datatype; - info2.defaultpriority = r.info.default_priority; - info2.drivername = r.info.drivername; - info2.location = r.info.location; - info2.parameters = r.info.parameters; - info2.portname = r.info.portname; - info2.printername = r.info.printername; - info2.printprocessor = r.info.printprocessor; - info2.priority = r.info.priority; - info2.sepfile = r.info.sepfile; - info2.sharename = r.info.sharename; - info2.starttime = r.info.starttime; - info2.status = r.info.status; - info2.untiltime = r.info.untiltime; - - /* Create Device Mode */ - if (r.devmode != NULL) { - ZERO_STRUCT(dm); - - dm.bitsperpel = r.devmode->bitsperpel; - dm.collate = r.devmode->collate; - dm.color = r.devmode->color; - dm.copies = r.devmode->copies; - dm.defaultsource = r.devmode->defaultsource; - dm.devicename = r.devmode->devicename; - dm.displayflags = r.devmode->displayflags; - dm.displayfrequency = r.devmode->displayfrequency; - dm.dithertype = r.devmode->dithertype; - dm.driverversion = r.devmode->driverversion; - dm.duplex = r.devmode->duplex; - dm.fields = r.devmode->fields; - dm.formname = r.devmode->formname; - dm.icmintent = r.devmode->icmintent; - dm.icmmethod = r.devmode->icmmethod; - dm.logpixels = r.devmode->logpixels; - dm.mediatype = r.devmode->mediatype; - dm.orientation = r.devmode->orientation; - dm.panningheight = r.devmode->pelsheight; - dm.panningwidth = r.devmode->panningwidth; - dm.paperlength = r.devmode->paperlength; - dm.papersize = r.devmode->papersize; - dm.paperwidth = r.devmode->paperwidth; - dm.pelsheight = r.devmode->pelsheight; - dm.pelswidth = r.devmode->pelswidth; - dm.printquality = r.devmode->printquality; - dm.size = r.devmode->size; - dm.scale = r.devmode->scale; - dm.specversion = r.devmode->specversion; - dm.ttoption = r.devmode->ttoption; - dm.yresolution = r.devmode->yresolution; - - if (r.devmode->nt_dev_private != NULL) { - dm.driverextra_data.data = r.devmode->nt_dev_private->data; - dm.driverextra_data.length = r.devmode->nt_dev_private->length; - dm.__driverextra_length = r.devmode->nt_dev_private->length; - } - - devmode_ctr.devmode = &dm; - - info2.devmode_ptr = 1; - } - - info_ctr.info.info2 = &info2; - info_ctr.level = 2; - - status = dcerpc_spoolss_SetPrinter(b, - mem_ctx, - &hnd, - &info_ctr, - &devmode_ctr, - &secdesc_ctr, - 0, /* command */ - &result); - if (!NT_STATUS_IS_OK(status)) { - d_printf(_("\tSetPrinter(%s) level 2 refused -- %s.\n"), - key_name, nt_errstr(status)); - goto done; - } else if (!W_ERROR_IS_OK(result)) { - d_printf(_("\tSetPrinter(%s) level 2 refused -- %s.\n"), - key_name, win_errstr(result)); - status = werror_to_ntstatus(result); - goto done; - } - - /* migrate printerdata */ - for (j = 0; j < r.count; j++) { - char *valuename; - char *keyname; - - if (r.printer_data[j].type == REG_NONE) { - continue; - } - - keyname = CONST_DISCARD(char *, r.printer_data[j].name); - valuename = strchr(keyname, '\\'); - if (valuename == NULL) { - continue; - } else { - valuename[0] = '\0'; - valuename++; - } - - printf(" data: %s\\%s\n", keyname, valuename); - - status = dcerpc_spoolss_SetPrinterDataEx(b, - mem_ctx, - &hnd, - keyname, - valuename, - r.printer_data[j].type, - r.printer_data[j].data.data, - r.printer_data[j].data.length, - &result); - if (!NT_STATUS_IS_OK(status)) { - d_printf(_("\tSetPrinterDataEx: printer [%s], keyname [%s], valuename [%s] refused -- %s.\n"), - key_name, keyname, valuename, nt_errstr(status)); - break; - } else if (!W_ERROR_IS_OK(result)) { - d_printf(_("\tSetPrinterDataEx: printer [%s], keyname [%s], valuename [%s] refused -- %s.\n"), - key_name, keyname, valuename, win_errstr(result)); - status = werror_to_ntstatus(result); - break; - } - } - - done: - dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result); - - return status; -} - -static NTSTATUS migrate_secdesc(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, - const char *key_name, - unsigned char *data, - size_t length) -{ - struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; - struct policy_handle hnd; - enum ndr_err_code ndr_err; - struct sec_desc_buf secdesc_ctr; - struct spoolss_SetPrinterInfo3 info3; - struct spoolss_SetPrinterInfoCtr info_ctr; - struct spoolss_DevmodeContainer devmode_ctr; - DATA_BLOB blob; - NTSTATUS status; - WERROR result; - - if (strequal(key_name, "printers")) { - return NT_STATUS_OK; - } - - blob = data_blob_const(data, length); - - ZERO_STRUCT(secdesc_ctr); - - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &secdesc_ctr, - (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - d_fprintf(stderr, _("security descriptor pull failed: %s\n"), - ndr_errstr(ndr_err)); - return NT_STATUS_NO_MEMORY; - } - - d_printf(_("Migrating Security Descriptor: %s\n"), key_name); - - result = rpccli_spoolss_openprinter_ex(pipe_hnd, - mem_ctx, - key_name, - MAXIMUM_ALLOWED_ACCESS, - &hnd); - if (!W_ERROR_IS_OK(result)) { - d_fprintf(stderr, _("\tOpenPrinter(%s) failed: %s\n"), - key_name, win_errstr(result)); - return werror_to_ntstatus(result); - } - - ZERO_STRUCT(devmode_ctr); - - info3.sec_desc_ptr = 1; - - info_ctr.info.info3 = &info3; - info_ctr.level = 3; - - status = dcerpc_spoolss_SetPrinter(b, - mem_ctx, - &hnd, - &info_ctr, - &devmode_ctr, - &secdesc_ctr, - 0, /* command */ - &result); - if (!NT_STATUS_IS_OK(status)) { - d_printf(_("\tSetPrinter(%s) level 3 refused -- %s.\n"), - key_name, nt_errstr(status)); - } else if (!W_ERROR_IS_OK(result)) { - d_printf(_("\tSetPrinter(%s) level 3 refused -- %s.\n"), - key_name, win_errstr(result)); - status = werror_to_ntstatus(result); - } - - dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result); - - return status; -} - static NTSTATUS printing_migrate_internal(struct net_context *c, const struct dom_sid *domain_sid, const char *domain_name, @@ -663,7 +254,7 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, } if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) { - migrate_form(tmp_ctx, + printing_tdb_migrate_form(tmp_ctx, pipe_hnd, (const char *) kbuf.dptr + strlen(FORMS_PREFIX), dbuf.dptr, @@ -673,7 +264,7 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, } if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) { - migrate_driver(tmp_ctx, + printing_tdb_migrate_driver(tmp_ctx, pipe_hnd, (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX), dbuf.dptr, @@ -683,7 +274,7 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, } if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) { - migrate_printer(tmp_ctx, + printing_tdb_migrate_printer(tmp_ctx, pipe_hnd, (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX), dbuf.dptr, @@ -693,7 +284,7 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, } if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) { - migrate_secdesc(tmp_ctx, + printing_tdb_migrate_secdesc(tmp_ctx, pipe_hnd, (const char *) kbuf.dptr + strlen(SECDESC_PREFIX), dbuf.dptr, diff --git a/source3/wscript_build b/source3/wscript_build index cf034e2..7269d06 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -1091,6 +1091,7 @@ bld.SAMBA3_BINARY('net', LIBCLI_SAMR LIBCLI_LSA3 LIBRPCCLI_NETLOGON LIBCLI_SPOOLSS RPC_NDR_SRVSVC RPC_NDR_WKSSVC RPC_NDR_SVCCTL RPC_NDR_DSSETUP RPC_NDR_INITSHUTDOWN RPC_NDR_DRSUAPI INIT_NETLOGON INIT_SAMR + printing_migrate ''', vars=locals()) -- 1.7.6 From 3a259f0ffe470b126aa6768b16b66a14432c06bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Fri, 1 Jul 2011 15:39:11 +0200 Subject: [PATCH 06/21] s3-printing: open up a winreg pipe handle for the migration code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guenther Autobuild-User: Günther Deschner Autobuild-Date: Mon Jul 4 15:06:41 CEST 2011 on sn-devel-104 (cherry picked from commit ff94539f276bdef73bd12c67bff1f34e697ccbfc) --- source3/printing/nt_printing_migrate.c | 4 +++ source3/printing/nt_printing_migrate.h | 4 +++ source3/printing/nt_printing_migrate_internal.c | 28 +++++++++++++++++++--- source3/utils/net_printing.c | 16 +++++++++++++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/source3/printing/nt_printing_migrate.c b/source3/printing/nt_printing_migrate.c index 3b2e543..caff272 100644 --- a/source3/printing/nt_printing_migrate.c +++ b/source3/printing/nt_printing_migrate.c @@ -28,6 +28,7 @@ NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *pipe_hnd, + struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, size_t length) @@ -126,6 +127,7 @@ NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx, NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *pipe_hnd, + struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, size_t length) @@ -198,6 +200,7 @@ NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx, NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *pipe_hnd, + struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, size_t length) @@ -402,6 +405,7 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *pipe_hnd, + struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, size_t length) diff --git a/source3/printing/nt_printing_migrate.h b/source3/printing/nt_printing_migrate.h index 4991d06..707ddc9 100644 --- a/source3/printing/nt_printing_migrate.h +++ b/source3/printing/nt_printing_migrate.h @@ -23,21 +23,25 @@ NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *pipe_hnd, + struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, size_t length); NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *pipe_hnd, + struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, size_t length); NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *pipe_hnd, + struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, size_t length); NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *pipe_hnd, + struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, size_t length); diff --git a/source3/printing/nt_printing_migrate_internal.c b/source3/printing/nt_printing_migrate_internal.c index f868713..bc4129e 100644 --- a/source3/printing/nt_printing_migrate_internal.c +++ b/source3/printing/nt_printing_migrate_internal.c @@ -25,6 +25,7 @@ #include "rpc_client/rpc_client.h" #include "librpc/gen_ndr/ndr_spoolss_c.h" +#include "librpc/gen_ndr/ndr_winreg.h" #include "rpc_server/rpc_ncacn_np.h" #include "auth.h" #include "util_tdb.h" @@ -65,7 +66,8 @@ static int rename_file_with_suffix(TALLOC_CTX *mem_ctx, static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, const char *tdb_path, - struct rpc_pipe_client *pipe_hnd) + struct rpc_pipe_client *pipe_hnd, + struct rpc_pipe_client *winreg_pipe) { const char *backup_suffix = ".bak"; TDB_DATA kbuf, newkey, dbuf; @@ -97,6 +99,7 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) { status = printing_tdb_migrate_form(mem_ctx, pipe_hnd, + winreg_pipe, (const char *) kbuf.dptr + strlen(FORMS_PREFIX), dbuf.dptr, dbuf.dsize); @@ -111,6 +114,7 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) { status = printing_tdb_migrate_driver(mem_ctx, pipe_hnd, + winreg_pipe, (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX), dbuf.dptr, dbuf.dsize); @@ -127,6 +131,7 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, + strlen(PRINTERS_PREFIX)); status = printing_tdb_migrate_printer(mem_ctx, pipe_hnd, + winreg_pipe, printer_name, dbuf.dptr, dbuf.dsize); @@ -148,6 +153,7 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, + strlen(SECDESC_PREFIX)); status = printing_tdb_migrate_secdesc(mem_ctx, pipe_hnd, + winreg_pipe, secdesc_name, dbuf.dptr, dbuf.dsize); @@ -186,6 +192,7 @@ bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx) bool forms_exists = file_exist(forms_path); struct auth_serversupplied_info *session_info; struct rpc_pipe_client *spoolss_pipe = NULL; + struct rpc_pipe_client *winreg_pipe = NULL; TALLOC_CTX *tmp_ctx = talloc_stackframe(); NTSTATUS status; @@ -214,8 +221,21 @@ bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx) return false; } + status = rpc_pipe_open_interface(tmp_ctx, + &ndr_table_winreg.syntax_id, + session_info, + NULL, + msg_ctx, + &winreg_pipe); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Couldn't open internal winreg pipe: %s\n", + nt_errstr(status))); + talloc_free(tmp_ctx); + return false; + } + if (drivers_exists) { - status = migrate_internal(tmp_ctx, drivers_path, spoolss_pipe); + status = migrate_internal(tmp_ctx, drivers_path, spoolss_pipe, winreg_pipe); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Couldn't migrate drivers tdb file: %s\n", nt_errstr(status))); @@ -225,7 +245,7 @@ bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx) } if (printers_exists) { - status = migrate_internal(tmp_ctx, printers_path, spoolss_pipe); + status = migrate_internal(tmp_ctx, printers_path, spoolss_pipe, winreg_pipe); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Couldn't migrate printers tdb file: %s\n", nt_errstr(status))); @@ -235,7 +255,7 @@ bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx) } if (forms_exists) { - status = migrate_internal(tmp_ctx, forms_path, spoolss_pipe); + status = migrate_internal(tmp_ctx, forms_path, spoolss_pipe, winreg_pipe); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Couldn't migrate forms tdb file: %s\n", nt_errstr(status))); diff --git a/source3/utils/net_printing.c b/source3/utils/net_printing.c index 3b37d6e..df7b56a 100644 --- a/source3/utils/net_printing.c +++ b/source3/utils/net_printing.c @@ -23,10 +23,12 @@ #include "system/filesys.h" #include "utils/net.h" #include "rpc_client/rpc_client.h" +#include "rpc_client/cli_pipe.h" #include "librpc/gen_ndr/ndr_ntprinting.h" #include "librpc/gen_ndr/ndr_spoolss.h" #include "../libcli/security/security.h" #include "../librpc/gen_ndr/ndr_security.h" +#include "../librpc/gen_ndr/ndr_winreg.h" #include "util_tdb.h" #include "printing/nt_printing_migrate.h" @@ -231,12 +233,22 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, TDB_CONTEXT *tdb; TDB_DATA kbuf, newkey, dbuf; NTSTATUS status; + struct rpc_pipe_client *winreg_pipe = NULL; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { return NT_STATUS_NO_MEMORY; } + status = cli_rpc_pipe_open_noauth(rpc_pipe_np_smb_conn(pipe_hnd), + &ndr_table_winreg.syntax_id, + &winreg_pipe); + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, _("failed to open winreg pipe: %s\n"), + nt_errstr(status)); + goto done; + } + tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600); if (tdb == NULL) { d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]); @@ -256,6 +268,7 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) { printing_tdb_migrate_form(tmp_ctx, pipe_hnd, + winreg_pipe, (const char *) kbuf.dptr + strlen(FORMS_PREFIX), dbuf.dptr, dbuf.dsize); @@ -266,6 +279,7 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) { printing_tdb_migrate_driver(tmp_ctx, pipe_hnd, + winreg_pipe, (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX), dbuf.dptr, dbuf.dsize); @@ -276,6 +290,7 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) { printing_tdb_migrate_printer(tmp_ctx, pipe_hnd, + winreg_pipe, (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX), dbuf.dptr, dbuf.dsize); @@ -286,6 +301,7 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) { printing_tdb_migrate_secdesc(tmp_ctx, pipe_hnd, + winreg_pipe, (const char *) kbuf.dptr + strlen(SECDESC_PREFIX), dbuf.dptr, dbuf.dsize); -- 1.7.6 From 868aff6ae58fd12db8fe71e89923a26239d652c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 5 Jul 2011 01:24:48 +0200 Subject: [PATCH 07/21] s3-printing: move os2 related functions to printing/nt_printing_os2.c. Guenther Pair-Programmed-With: David Disseldorp (cherry picked from commit dd5375b4a1798c856fa9c104baa36c137d664b9d) Conflicts: source3/rpc_server/spoolss/srv_spoolss_util.c --- source3/Makefile.in | 1 + source3/include/nt_printing.h | 2 - source3/printing/nt_printing.c | 142 --------------------- source3/printing/nt_printing_os2.c | 165 +++++++++++++++++++++++++ source3/printing/nt_printing_os2.h | 22 ++++ source3/rpc_server/spoolss/srv_spoolss_util.c | 1 + source3/wscript_build | 3 +- 7 files changed, 191 insertions(+), 145 deletions(-) create mode 100644 source3/printing/nt_printing_os2.c create mode 100644 source3/printing/nt_printing_os2.h diff --git a/source3/Makefile.in b/source3/Makefile.in index 390f6ea..7f608c7 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -950,6 +950,7 @@ PRINTBACKEND_OBJ = printing/printing.o \ printing/nt_printing_migrate.o \ printing/nt_printing_migrate_internal.o \ printing/nt_printing_ads.o \ + printing/nt_printing_os2.o \ librpc/gen_ndr/ndr_ntprinting.o \ ../librpc/ndr/ndr_ntprinting.o \ $(PRINTBASE_OBJ) diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h index ad6262e..319e895 100644 --- a/source3/include/nt_printing.h +++ b/source3/include/nt_printing.h @@ -133,8 +133,6 @@ WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx, WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx, struct spoolss_security_descriptor **secdesc); -WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername); - const char *get_short_archi(const char *long_archi); bool print_access_check(const struct auth_serversupplied_info *server_info, diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 6d4bebb..9554ab4 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1340,148 +1340,6 @@ WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx, } /**************************************************************************** - ***************************************************************************/ - -static char *win_driver; -static char *os2_driver; - -static const char *get_win_driver(void) -{ - if (win_driver == NULL) { - return ""; - } - return win_driver; -} - -static const char *get_os2_driver(void) -{ - if (os2_driver == NULL) { - return ""; - } - return os2_driver; -} - -static bool set_driver_mapping(const char *from, const char *to) -{ - SAFE_FREE(win_driver); - SAFE_FREE(os2_driver); - - win_driver = SMB_STRDUP(from); - os2_driver = SMB_STRDUP(to); - - if (win_driver == NULL || os2_driver == NULL) { - SAFE_FREE(win_driver); - SAFE_FREE(os2_driver); - return false; - } - return true; -} - -/** - * @internal - * - * @brief Map a Windows driver to a OS/2 driver. - * - * @param[in] mem_ctx The memory context to use. - * - * @param[in,out] pdrivername The drivername of Windows to remap. - * - * @return WERR_OK on success, a corresponding WERROR on failure. - */ -WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername) -{ - const char *mapfile = lp_os2_driver_map(); - char **lines = NULL; - const char *drivername; - int numlines = 0; - int i; - - if (pdrivername == NULL || *pdrivername == NULL || *pdrivername[0] == '\0') { - return WERR_INVALID_PARAMETER; - } - - drivername = *pdrivername; - - if (mapfile[0] == '\0') { - return WERR_BADFILE; - } - - if (strequal(drivername, get_win_driver())) { - DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n", - drivername, get_os2_driver())); - drivername = talloc_strdup(mem_ctx, get_os2_driver()); - if (drivername == NULL) { - return WERR_NOMEM; - } - *pdrivername = drivername; - return WERR_OK; - } - - lines = file_lines_load(mapfile, &numlines, 0, NULL); - if (numlines == 0 || lines == NULL) { - DEBUG(0,("No entries in OS/2 driver map %s\n", mapfile)); - TALLOC_FREE(lines); - return WERR_EMPTY; - } - - DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile)); - - for( i = 0; i < numlines; i++) { - char *nt_name = lines[i]; - char *os2_name = strchr(nt_name, '='); - - if (os2_name == NULL) { - continue; - } - - *os2_name++ = '\0'; - - while (isspace(*nt_name)) { - nt_name++; - } - - if (*nt_name == '\0' || strchr("#;", *nt_name)) { - continue; - } - - { - int l = strlen(nt_name); - while (l && isspace(nt_name[l - 1])) { - nt_name[l - 1] = 0; - l--; - } - } - - while (isspace(*os2_name)) { - os2_name++; - } - - { - int l = strlen(os2_name); - while (l && isspace(os2_name[l-1])) { - os2_name[l-1] = 0; - l--; - } - } - - if (strequal(nt_name, drivername)) { - DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,os2_name)); - set_driver_mapping(drivername, os2_name); - drivername = talloc_strdup(mem_ctx, os2_name); - TALLOC_FREE(lines); - if (drivername == NULL) { - return WERR_NOMEM; - } - *pdrivername = drivername; - return WERR_OK; - } - } - - TALLOC_FREE(lines); - return WERR_OK; -} - -/**************************************************************************** ****************************************************************************/ bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r, diff --git a/source3/printing/nt_printing_os2.c b/source3/printing/nt_printing_os2.c new file mode 100644 index 0000000..80c02eb --- /dev/null +++ b/source3/printing/nt_printing_os2.c @@ -0,0 +1,165 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-2000, + * Copyright (C) Jean François Micouleau 1998-2000. + * Copyright (C) Gerald Carter 2002-2005. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" +#include "printing/nt_printing_os2.h" + +/**************************************************************************** + ***************************************************************************/ + +static char *win_driver; +static char *os2_driver; + +static const char *get_win_driver(void) +{ + if (win_driver == NULL) { + return ""; + } + return win_driver; +} + +static const char *get_os2_driver(void) +{ + if (os2_driver == NULL) { + return ""; + } + return os2_driver; +} + +static bool set_driver_mapping(const char *from, const char *to) +{ + SAFE_FREE(win_driver); + SAFE_FREE(os2_driver); + + win_driver = SMB_STRDUP(from); + os2_driver = SMB_STRDUP(to); + + if (win_driver == NULL || os2_driver == NULL) { + SAFE_FREE(win_driver); + SAFE_FREE(os2_driver); + return false; + } + return true; +} + +/** + * @internal + * + * @brief Map a Windows driver to a OS/2 driver. + * + * @param[in] mem_ctx The memory context to use. + * + * @param[in,out] pdrivername The drivername of Windows to remap. + * + * @return WERR_OK on success, a corresponding WERROR on failure. + */ +WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername) +{ + const char *mapfile = lp_os2_driver_map(); + char **lines = NULL; + const char *drivername; + int numlines = 0; + int i; + + if (pdrivername == NULL || *pdrivername == NULL || *pdrivername[0] == '\0') { + return WERR_INVALID_PARAMETER; + } + + drivername = *pdrivername; + + if (mapfile[0] == '\0') { + return WERR_BADFILE; + } + + if (strequal(drivername, get_win_driver())) { + DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n", + drivername, get_os2_driver())); + drivername = talloc_strdup(mem_ctx, get_os2_driver()); + if (drivername == NULL) { + return WERR_NOMEM; + } + *pdrivername = drivername; + return WERR_OK; + } + + lines = file_lines_load(mapfile, &numlines, 0, NULL); + if (numlines == 0 || lines == NULL) { + DEBUG(0,("No entries in OS/2 driver map %s\n", mapfile)); + TALLOC_FREE(lines); + return WERR_EMPTY; + } + + DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile)); + + for( i = 0; i < numlines; i++) { + char *nt_name = lines[i]; + char *os2_name = strchr(nt_name, '='); + + if (os2_name == NULL) { + continue; + } + + *os2_name++ = '\0'; + + while (isspace(*nt_name)) { + nt_name++; + } + + if (*nt_name == '\0' || strchr("#;", *nt_name)) { + continue; + } + + { + int l = strlen(nt_name); + while (l && isspace(nt_name[l - 1])) { + nt_name[l - 1] = 0; + l--; + } + } + + while (isspace(*os2_name)) { + os2_name++; + } + + { + int l = strlen(os2_name); + while (l && isspace(os2_name[l-1])) { + os2_name[l-1] = 0; + l--; + } + } + + if (strequal(nt_name, drivername)) { + DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,os2_name)); + set_driver_mapping(drivername, os2_name); + drivername = talloc_strdup(mem_ctx, os2_name); + TALLOC_FREE(lines); + if (drivername == NULL) { + return WERR_NOMEM; + } + *pdrivername = drivername; + return WERR_OK; + } + } + + TALLOC_FREE(lines); + return WERR_OK; +} diff --git a/source3/printing/nt_printing_os2.h b/source3/printing/nt_printing_os2.h new file mode 100644 index 0000000..0ef07de --- /dev/null +++ b/source3/printing/nt_printing_os2.h @@ -0,0 +1,22 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-2000, + * Copyright (C) Jean François Micouleau 1998-2000. + * Copyright (C) Gerald Carter 2002-2005. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername); diff --git a/source3/rpc_server/spoolss/srv_spoolss_util.c b/source3/rpc_server/spoolss/srv_spoolss_util.c index 9c41ac3..5adffb5 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_util.c +++ b/source3/rpc_server/spoolss/srv_spoolss_util.c @@ -30,6 +30,7 @@ #include "../libcli/security/security.h" #include "rpc_client/cli_winreg.h" #include "../libcli/registry/util_reg.h" +#include "printing/nt_printing_os2.h" #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print" #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers" diff --git a/source3/wscript_build b/source3/wscript_build index 7269d06..c896027 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -405,7 +405,8 @@ PRINTBACKEND_SRC = '''printing/printing.c printing/nt_printing.c printing/nt_printing_tdb.c printing/nt_printing_migrate_internal.c - printing/nt_printing_ads.c''' + printing/nt_printing_ads.c + printing/nt_printing_os2.c''' SMBD_SRC = '''${SMBD_SRC_BASE} ${SMBD_SRC_MAIN}''' -- 1.7.6 From 13e6fb03c425f4277351e687a8866041bf9c3231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 5 Jul 2011 02:12:24 +0200 Subject: [PATCH 08/21] s3-printing: move driver_info_ctr_to_info8 to init_spoolss.h Guenther Pair-Programmed-With: David Disseldorp (cherry picked from commit 74e416031b2fc5d9c6af30f692d5b73cb1942cf4) --- source3/include/nt_printing.h | 3 - source3/printing/nt_printing.c | 90 ------------------------- source3/rpc_client/init_spoolss.c | 89 ++++++++++++++++++++++++ source3/rpc_client/init_spoolss.h | 2 + source3/rpc_server/spoolss/srv_spoolss_util.c | 1 + 5 files changed, 92 insertions(+), 93 deletions(-) diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h index 319e895..a8430aa 100644 --- a/source3/include/nt_printing.h +++ b/source3/include/nt_printing.h @@ -153,9 +153,6 @@ bool is_printer_published(TALLOC_CTX *mem_ctx, WERROR check_published_printers(struct messaging_context *msg_ctx); -bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r, - struct spoolss_DriverInfo8 *_info8); - bool printer_driver_in_use(TALLOC_CTX *mem_ctx, const struct auth_serversupplied_info *server_info, struct messaging_context *msg_ctx, diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 9554ab4..dcb4e2b 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1340,96 +1340,6 @@ WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx, } /**************************************************************************** -****************************************************************************/ - -bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r, - struct spoolss_DriverInfo8 *_info8) -{ - struct spoolss_DriverInfo8 info8; - - ZERO_STRUCT(info8); - - switch (r->level) { - case 3: - info8.version = r->info.info3->version; - info8.driver_name = r->info.info3->driver_name; - info8.architecture = r->info.info3->architecture; - info8.driver_path = r->info.info3->driver_path; - info8.data_file = r->info.info3->data_file; - info8.config_file = r->info.info3->config_file; - info8.help_file = r->info.info3->help_file; - info8.monitor_name = r->info.info3->monitor_name; - info8.default_datatype = r->info.info3->default_datatype; - if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) { - info8.dependent_files = r->info.info3->dependent_files->string; - } - break; - case 6: - info8.version = r->info.info6->version; - info8.driver_name = r->info.info6->driver_name; - info8.architecture = r->info.info6->architecture; - info8.driver_path = r->info.info6->driver_path; - info8.data_file = r->info.info6->data_file; - info8.config_file = r->info.info6->config_file; - info8.help_file = r->info.info6->help_file; - info8.monitor_name = r->info.info6->monitor_name; - info8.default_datatype = r->info.info6->default_datatype; - if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) { - info8.dependent_files = r->info.info6->dependent_files->string; - } - info8.driver_date = r->info.info6->driver_date; - info8.driver_version = r->info.info6->driver_version; - info8.manufacturer_name = r->info.info6->manufacturer_name; - info8.manufacturer_url = r->info.info6->manufacturer_url; - info8.hardware_id = r->info.info6->hardware_id; - info8.provider = r->info.info6->provider; - break; - case 8: - info8.version = r->info.info8->version; - info8.driver_name = r->info.info8->driver_name; - info8.architecture = r->info.info8->architecture; - info8.driver_path = r->info.info8->driver_path; - info8.data_file = r->info.info8->data_file; - info8.config_file = r->info.info8->config_file; - info8.help_file = r->info.info8->help_file; - info8.monitor_name = r->info.info8->monitor_name; - info8.default_datatype = r->info.info8->default_datatype; - if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) { - info8.dependent_files = r->info.info8->dependent_files->string; - } - if (r->info.info8->previous_names && r->info.info8->previous_names->string) { - info8.previous_names = r->info.info8->previous_names->string; - } - info8.driver_date = r->info.info8->driver_date; - info8.driver_version = r->info.info8->driver_version; - info8.manufacturer_name = r->info.info8->manufacturer_name; - info8.manufacturer_url = r->info.info8->manufacturer_url; - info8.hardware_id = r->info.info8->hardware_id; - info8.provider = r->info.info8->provider; - info8.print_processor = r->info.info8->print_processor; - info8.vendor_setup = r->info.info8->vendor_setup; - if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) { - info8.color_profiles = r->info.info8->color_profiles->string; - } - info8.inf_path = r->info.info8->inf_path; - info8.printer_driver_attributes = r->info.info8->printer_driver_attributes; - if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) { - info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string; - } - info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date; - info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version; - break; - default: - return false; - } - - *_info8 = info8; - - return true; -} - - -/**************************************************************************** Determine whether or not a particular driver is currently assigned to a printer ****************************************************************************/ diff --git a/source3/rpc_client/init_spoolss.c b/source3/rpc_client/init_spoolss.c index d1dc7e6..ac1d4a5 100644 --- a/source3/rpc_client/init_spoolss.c +++ b/source3/rpc_client/init_spoolss.c @@ -119,3 +119,92 @@ void spoolss_printerinfo2_to_setprinterinfo2(const struct spoolss_PrinterInfo2 * s->cjobs = i->cjobs; s->averageppm = i->averageppm; } + +/**************************************************************************** +****************************************************************************/ + +bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r, + struct spoolss_DriverInfo8 *_info8) +{ + struct spoolss_DriverInfo8 info8; + + ZERO_STRUCT(info8); + + switch (r->level) { + case 3: + info8.version = r->info.info3->version; + info8.driver_name = r->info.info3->driver_name; + info8.architecture = r->info.info3->architecture; + info8.driver_path = r->info.info3->driver_path; + info8.data_file = r->info.info3->data_file; + info8.config_file = r->info.info3->config_file; + info8.help_file = r->info.info3->help_file; + info8.monitor_name = r->info.info3->monitor_name; + info8.default_datatype = r->info.info3->default_datatype; + if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) { + info8.dependent_files = r->info.info3->dependent_files->string; + } + break; + case 6: + info8.version = r->info.info6->version; + info8.driver_name = r->info.info6->driver_name; + info8.architecture = r->info.info6->architecture; + info8.driver_path = r->info.info6->driver_path; + info8.data_file = r->info.info6->data_file; + info8.config_file = r->info.info6->config_file; + info8.help_file = r->info.info6->help_file; + info8.monitor_name = r->info.info6->monitor_name; + info8.default_datatype = r->info.info6->default_datatype; + if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) { + info8.dependent_files = r->info.info6->dependent_files->string; + } + info8.driver_date = r->info.info6->driver_date; + info8.driver_version = r->info.info6->driver_version; + info8.manufacturer_name = r->info.info6->manufacturer_name; + info8.manufacturer_url = r->info.info6->manufacturer_url; + info8.hardware_id = r->info.info6->hardware_id; + info8.provider = r->info.info6->provider; + break; + case 8: + info8.version = r->info.info8->version; + info8.driver_name = r->info.info8->driver_name; + info8.architecture = r->info.info8->architecture; + info8.driver_path = r->info.info8->driver_path; + info8.data_file = r->info.info8->data_file; + info8.config_file = r->info.info8->config_file; + info8.help_file = r->info.info8->help_file; + info8.monitor_name = r->info.info8->monitor_name; + info8.default_datatype = r->info.info8->default_datatype; + if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) { + info8.dependent_files = r->info.info8->dependent_files->string; + } + if (r->info.info8->previous_names && r->info.info8->previous_names->string) { + info8.previous_names = r->info.info8->previous_names->string; + } + info8.driver_date = r->info.info8->driver_date; + info8.driver_version = r->info.info8->driver_version; + info8.manufacturer_name = r->info.info8->manufacturer_name; + info8.manufacturer_url = r->info.info8->manufacturer_url; + info8.hardware_id = r->info.info8->hardware_id; + info8.provider = r->info.info8->provider; + info8.print_processor = r->info.info8->print_processor; + info8.vendor_setup = r->info.info8->vendor_setup; + if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) { + info8.color_profiles = r->info.info8->color_profiles->string; + } + info8.inf_path = r->info.info8->inf_path; + info8.printer_driver_attributes = r->info.info8->printer_driver_attributes; + if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) { + info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string; + } + info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date; + info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version; + break; + default: + return false; + } + + *_info8 = info8; + + return true; +} diff --git a/source3/rpc_client/init_spoolss.h b/source3/rpc_client/init_spoolss.h index a937445..f2844aa 100644 --- a/source3/rpc_client/init_spoolss.h +++ b/source3/rpc_client/init_spoolss.h @@ -34,5 +34,7 @@ WERROR push_spoolss_PrinterData(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, union spoolss_PrinterData *data); void spoolss_printerinfo2_to_setprinterinfo2(const struct spoolss_PrinterInfo2 *i, struct spoolss_SetPrinterInfo2 *s); +bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r, + struct spoolss_DriverInfo8 *_info8); #endif /* _RPC_CLIENT_INIT_SPOOLSS_H_ */ diff --git a/source3/rpc_server/spoolss/srv_spoolss_util.c b/source3/rpc_server/spoolss/srv_spoolss_util.c index 5adffb5..d8caec1 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_util.c +++ b/source3/rpc_server/spoolss/srv_spoolss_util.c @@ -31,6 +31,7 @@ #include "rpc_client/cli_winreg.h" #include "../libcli/registry/util_reg.h" #include "printing/nt_printing_os2.h" +#include "rpc_client/init_spoolss.h" #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print" #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers" -- 1.7.6 From 2ef09588df3ad45cbcf8839d8fb7d55aeb7d769b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 5 Jul 2011 02:15:35 +0200 Subject: [PATCH 09/21] s3-printing: move spoolss_create_default_devmode/secdesc to init_spoolss.h Guenther Pair-Programmed-With: David Disseldorp (cherry picked from commit 43cf3a28dc539351da8a316e0e52a8292ec40cc7) --- source3/include/nt_printing.h | 7 -- source3/printing/nt_printing.c | 172 ------------------------------------ source3/rpc_client/init_spoolss.c | 175 +++++++++++++++++++++++++++++++++++++ source3/rpc_client/init_spoolss.h | 7 ++ 4 files changed, 182 insertions(+), 179 deletions(-) diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h index a8430aa..4f85159 100644 --- a/source3/include/nt_printing.h +++ b/source3/include/nt_printing.h @@ -126,13 +126,6 @@ struct print_architecture_table_node { bool nt_printing_init(struct messaging_context *msg_ctx); -WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx, - const char *devicename, - struct spoolss_DeviceMode **devmode); - -WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx, - struct spoolss_security_descriptor **secdesc); - const char *get_short_archi(const char *long_archi); bool print_access_check(const struct auth_serversupplied_info *server_info, diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index dcb4e2b..782a626 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1168,178 +1168,6 @@ WERROR move_driver_to_download_area(struct auth_serversupplied_info *session_inf } /**************************************************************************** - Create and allocate a default devicemode. -****************************************************************************/ - -WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx, - const char *devicename, - struct spoolss_DeviceMode **devmode) -{ - struct spoolss_DeviceMode *dm; - char *dname; - - dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode); - if (dm == NULL) { - return WERR_NOMEM; - } - - dname = talloc_asprintf(dm, "%s", devicename); - if (dname == NULL) { - return WERR_NOMEM; - } - if (strlen(dname) > MAXDEVICENAME) { - dname[MAXDEVICENAME] = '\0'; - } - dm->devicename = dname; - - dm->formname = talloc_strdup(dm, "Letter"); - if (dm->formname == NULL) { - return WERR_NOMEM; - } - - dm->specversion = DMSPEC_NT4_AND_ABOVE; - dm->driverversion = 0x0400; - dm->size = 0x00DC; - dm->__driverextra_length = 0; - dm->fields = DEVMODE_FORMNAME | - DEVMODE_TTOPTION | - DEVMODE_PRINTQUALITY | - DEVMODE_DEFAULTSOURCE | - DEVMODE_COPIES | - DEVMODE_SCALE | - DEVMODE_PAPERSIZE | - DEVMODE_ORIENTATION; - dm->orientation = DMORIENT_PORTRAIT; - dm->papersize = DMPAPER_LETTER; - dm->paperlength = 0; - dm->paperwidth = 0; - dm->scale = 0x64; - dm->copies = 1; - dm->defaultsource = DMBIN_FORMSOURCE; - dm->printquality = DMRES_HIGH; /* 0x0258 */ - dm->color = DMRES_MONOCHROME; - dm->duplex = DMDUP_SIMPLEX; - dm->yresolution = 0; - dm->ttoption = DMTT_SUBDEV; - dm->collate = DMCOLLATE_FALSE; - dm->icmmethod = 0; - dm->icmintent = 0; - dm->mediatype = 0; - dm->dithertype = 0; - - dm->logpixels = 0; - dm->bitsperpel = 0; - dm->pelswidth = 0; - dm->pelsheight = 0; - dm->displayflags = 0; - dm->displayfrequency = 0; - dm->reserved1 = 0; - dm->reserved2 = 0; - dm->panningwidth = 0; - dm->panningheight = 0; - - dm->driverextra_data.data = NULL; - dm->driverextra_data.length = 0; - - *devmode = dm; - return WERR_OK; -} - -WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx, - struct spoolss_security_descriptor **secdesc) -{ - struct security_ace ace[7]; /* max number of ace entries */ - int i = 0; - uint32_t sa; - struct security_acl *psa = NULL; - struct security_descriptor *psd = NULL; - struct dom_sid adm_sid; - size_t sd_size; - - /* Create an ACE where Everyone is allowed to print */ - - sa = PRINTER_ACE_PRINT; - init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, - sa, SEC_ACE_FLAG_CONTAINER_INHERIT); - - /* Add the domain admins group if we are a DC */ - - if ( IS_DC ) { - struct dom_sid domadmins_sid; - - sid_compose(&domadmins_sid, get_global_sam_sid(), - DOMAIN_RID_ADMINS); - - sa = PRINTER_ACE_FULL_CONTROL; - init_sec_ace(&ace[i++], &domadmins_sid, - SEC_ACE_TYPE_ACCESS_ALLOWED, sa, - SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); - init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, - sa, SEC_ACE_FLAG_CONTAINER_INHERIT); - } - else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) { - sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR); - - sa = PRINTER_ACE_FULL_CONTROL; - init_sec_ace(&ace[i++], &adm_sid, - SEC_ACE_TYPE_ACCESS_ALLOWED, sa, - SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); - init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, - sa, SEC_ACE_FLAG_CONTAINER_INHERIT); - } - - /* add BUILTIN\Administrators as FULL CONTROL */ - - sa = PRINTER_ACE_FULL_CONTROL; - init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, - SEC_ACE_TYPE_ACCESS_ALLOWED, sa, - SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); - init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, - SEC_ACE_TYPE_ACCESS_ALLOWED, - sa, SEC_ACE_FLAG_CONTAINER_INHERIT); - - /* add BUILTIN\Print Operators as FULL CONTROL */ - - sa = PRINTER_ACE_FULL_CONTROL; - init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators, - SEC_ACE_TYPE_ACCESS_ALLOWED, sa, - SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); - init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators, - SEC_ACE_TYPE_ACCESS_ALLOWED, - sa, SEC_ACE_FLAG_CONTAINER_INHERIT); - - /* Make the security descriptor owned by the BUILTIN\Administrators */ - - /* The ACL revision number in rpc_secdesc.h differs from the one - created by NT when setting ACE entries in printer - descriptors. NT4 complains about the property being edited by a - NT5 machine. */ - - if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) { - psd = make_sec_desc(mem_ctx, - SD_REVISION, - SEC_DESC_SELF_RELATIVE, - &global_sid_Builtin_Administrators, - &global_sid_Builtin_Administrators, - NULL, - psa, - &sd_size); - } - - if (psd == NULL) { - DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n")); - return WERR_NOMEM; - } - - DEBUG(4,("construct_default_printer_sdb: size = %u.\n", - (unsigned int)sd_size)); - - *secdesc = psd; - - return WERR_OK; -} - -/**************************************************************************** Determine whether or not a particular driver is currently assigned to a printer ****************************************************************************/ diff --git a/source3/rpc_client/init_spoolss.c b/source3/rpc_client/init_spoolss.c index ac1d4a5..8b66227 100644 --- a/source3/rpc_client/init_spoolss.c +++ b/source3/rpc_client/init_spoolss.c @@ -20,6 +20,9 @@ #include "includes.h" #include "../librpc/gen_ndr/ndr_spoolss.h" #include "rpc_client/init_spoolss.h" +#include "../libcli/security/security.h" +#include "secrets.h" +#include "passdb/machine_sid.h" /******************************************************************* ********************************************************************/ @@ -208,3 +211,175 @@ bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r, return true; } + +/**************************************************************************** + Create and allocate a default devicemode. +****************************************************************************/ + +WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx, + const char *devicename, + struct spoolss_DeviceMode **devmode) +{ + struct spoolss_DeviceMode *dm; + char *dname; + + dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode); + if (dm == NULL) { + return WERR_NOMEM; + } + + dname = talloc_asprintf(dm, "%s", devicename); + if (dname == NULL) { + return WERR_NOMEM; + } + if (strlen(dname) > MAXDEVICENAME) { + dname[MAXDEVICENAME] = '\0'; + } + dm->devicename = dname; + + dm->formname = talloc_strdup(dm, "Letter"); + if (dm->formname == NULL) { + return WERR_NOMEM; + } + + dm->specversion = DMSPEC_NT4_AND_ABOVE; + dm->driverversion = 0x0400; + dm->size = 0x00DC; + dm->__driverextra_length = 0; + dm->fields = DEVMODE_FORMNAME | + DEVMODE_TTOPTION | + DEVMODE_PRINTQUALITY | + DEVMODE_DEFAULTSOURCE | + DEVMODE_COPIES | + DEVMODE_SCALE | + DEVMODE_PAPERSIZE | + DEVMODE_ORIENTATION; + dm->orientation = DMORIENT_PORTRAIT; + dm->papersize = DMPAPER_LETTER; + dm->paperlength = 0; + dm->paperwidth = 0; + dm->scale = 0x64; + dm->copies = 1; + dm->defaultsource = DMBIN_FORMSOURCE; + dm->printquality = DMRES_HIGH; /* 0x0258 */ + dm->color = DMRES_MONOCHROME; + dm->duplex = DMDUP_SIMPLEX; + dm->yresolution = 0; + dm->ttoption = DMTT_SUBDEV; + dm->collate = DMCOLLATE_FALSE; + dm->icmmethod = 0; + dm->icmintent = 0; + dm->mediatype = 0; + dm->dithertype = 0; + + dm->logpixels = 0; + dm->bitsperpel = 0; + dm->pelswidth = 0; + dm->pelsheight = 0; + dm->displayflags = 0; + dm->displayfrequency = 0; + dm->reserved1 = 0; + dm->reserved2 = 0; + dm->panningwidth = 0; + dm->panningheight = 0; + + dm->driverextra_data.data = NULL; + dm->driverextra_data.length = 0; + + *devmode = dm; + return WERR_OK; +} + +WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx, + struct spoolss_security_descriptor **secdesc) +{ + struct security_ace ace[7]; /* max number of ace entries */ + int i = 0; + uint32_t sa; + struct security_acl *psa = NULL; + struct security_descriptor *psd = NULL; + struct dom_sid adm_sid; + size_t sd_size; + + /* Create an ACE where Everyone is allowed to print */ + + sa = PRINTER_ACE_PRINT; + init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, + sa, SEC_ACE_FLAG_CONTAINER_INHERIT); + + /* Add the domain admins group if we are a DC */ + + if ( IS_DC ) { + struct dom_sid domadmins_sid; + + sid_compose(&domadmins_sid, get_global_sam_sid(), + DOMAIN_RID_ADMINS); + + sa = PRINTER_ACE_FULL_CONTROL; + init_sec_ace(&ace[i++], &domadmins_sid, + SEC_ACE_TYPE_ACCESS_ALLOWED, sa, + SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); + init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, + sa, SEC_ACE_FLAG_CONTAINER_INHERIT); + } + else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) { + sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR); + + sa = PRINTER_ACE_FULL_CONTROL; + init_sec_ace(&ace[i++], &adm_sid, + SEC_ACE_TYPE_ACCESS_ALLOWED, sa, + SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); + init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, + sa, SEC_ACE_FLAG_CONTAINER_INHERIT); + } + + /* add BUILTIN\Administrators as FULL CONTROL */ + + sa = PRINTER_ACE_FULL_CONTROL; + init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, + SEC_ACE_TYPE_ACCESS_ALLOWED, sa, + SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); + init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, + SEC_ACE_TYPE_ACCESS_ALLOWED, + sa, SEC_ACE_FLAG_CONTAINER_INHERIT); + + /* add BUILTIN\Print Operators as FULL CONTROL */ + + sa = PRINTER_ACE_FULL_CONTROL; + init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators, + SEC_ACE_TYPE_ACCESS_ALLOWED, sa, + SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); + init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators, + SEC_ACE_TYPE_ACCESS_ALLOWED, + sa, SEC_ACE_FLAG_CONTAINER_INHERIT); + + /* Make the security descriptor owned by the BUILTIN\Administrators */ + + /* The ACL revision number in rpc_secdesc.h differs from the one + created by NT when setting ACE entries in printer + descriptors. NT4 complains about the property being edited by a + NT5 machine. */ + + if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) { + psd = make_sec_desc(mem_ctx, + SD_REVISION, + SEC_DESC_SELF_RELATIVE, + &global_sid_Builtin_Administrators, + &global_sid_Builtin_Administrators, + NULL, + psa, + &sd_size); + } + + if (psd == NULL) { + DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n")); + return WERR_NOMEM; + } + + DEBUG(4,("construct_default_printer_sdb: size = %u.\n", + (unsigned int)sd_size)); + + *secdesc = psd; + + return WERR_OK; +} diff --git a/source3/rpc_client/init_spoolss.h b/source3/rpc_client/init_spoolss.h index f2844aa..247f711 100644 --- a/source3/rpc_client/init_spoolss.h +++ b/source3/rpc_client/init_spoolss.h @@ -37,4 +37,11 @@ void spoolss_printerinfo2_to_setprinterinfo2(const struct spoolss_PrinterInfo2 * bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r, struct spoolss_DriverInfo8 *_info8); +WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx, + const char *devicename, + struct spoolss_DeviceMode **devmode); + +WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx, + struct spoolss_security_descriptor **secdesc); + #endif /* _RPC_CLIENT_INIT_SPOOLSS_H_ */ -- 1.7.6 From 8e3aacf606ac1f6f64e4210061c8cc0e8267b0ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 5 Jul 2011 11:29:37 +0200 Subject: [PATCH 10/21] s3-waf: make LIBCLI_SPOOLSS a shared library Guenther Pair-Programmed-With: David Disseldorp (cherry picked from commit a0fc64a88ee6f1f45d4c2b95d6773eccab50ebb4) --- source3/wscript_build | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source3/wscript_build b/source3/wscript_build index c896027..c00c137 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -997,9 +997,10 @@ bld.SAMBA3_SUBSYSTEM('LIBRPCCLI_NETLOGON', source=LIBRPCCLI_NETLOGON_SRC, deps='RPC_NDR_NETLOGON') -bld.SAMBA3_SUBSYSTEM('LIBCLI_SPOOLSS', - source=LIBCLI_SPOOLSS_SRC, - deps='RPC_NDR_SPOOLSS') +bld.SAMBA3_LIBRARY('LIBCLI_SPOOLSS', + source=LIBCLI_SPOOLSS_SRC, + deps='RPC_NDR_SPOOLSS param SECRETS3', + private_library=True) bld.SAMBA3_SUBSYSTEM('LIBCLI_WINREG', source=LIBCLI_WINREG_SRC, -- 1.7.6 From 5330bfa9e43053257beedcea24c889e5be6253c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Mon, 4 Jul 2011 19:47:29 +0200 Subject: [PATCH 11/21] s3-printing: add rpc_client/cli_winreg_spoolss.c Guenther Pair-Programmed-With: David Disseldorp (cherry picked from commit f2be8378b92669092f8444df038f769fc9312ff4) --- source3/Makefile.in | 5 +- source3/rpc_client/cli_winreg_spoolss.c | 4093 +++++++++++++++++++++++++++++++ source3/rpc_client/cli_winreg_spoolss.h | 569 +++++ source3/wscript_build | 7 +- 4 files changed, 4668 insertions(+), 6 deletions(-) create mode 100644 source3/rpc_client/cli_winreg_spoolss.c create mode 100644 source3/rpc_client/cli_winreg_spoolss.h diff --git a/source3/Makefile.in b/source3/Makefile.in index 7f608c7..c2b4a3a 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -346,7 +346,9 @@ LIBNDR_XATTR_OBJ = librpc/gen_ndr/ndr_xattr.o \ LIBCLI_SPOOLSS_OBJ = librpc/gen_ndr/ndr_spoolss_c.o \ rpc_client/cli_spoolss.o \ - rpc_client/init_spoolss.o + rpc_client/init_spoolss.o \ + rpc_client/cli_winreg_spoolss.o \ + printing/nt_printing_os2.o LIBCLI_EVENTLOG_OBJ = librpc/gen_ndr/ndr_eventlog_c.o @@ -950,7 +952,6 @@ PRINTBACKEND_OBJ = printing/printing.o \ printing/nt_printing_migrate.o \ printing/nt_printing_migrate_internal.o \ printing/nt_printing_ads.o \ - printing/nt_printing_os2.o \ librpc/gen_ndr/ndr_ntprinting.o \ ../librpc/ndr/ndr_ntprinting.o \ $(PRINTBASE_OBJ) diff --git a/source3/rpc_client/cli_winreg_spoolss.c b/source3/rpc_client/cli_winreg_spoolss.c new file mode 100644 index 0000000..b4c892a --- /dev/null +++ b/source3/rpc_client/cli_winreg_spoolss.c @@ -0,0 +1,4093 @@ +/* + * Unix SMB/CIFS implementation. + * + * SPOOLSS RPC Pipe server / winreg client routines + * + * Copyright (c) 2010 Andreas Schneider + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" +#include "nt_printing.h" +#include "../librpc/gen_ndr/ndr_spoolss.h" +#include "../librpc/gen_ndr/ndr_winreg_c.h" +#include "../librpc/gen_ndr/ndr_security.h" +#include "secrets.h" +#include "../libcli/security/security.h" +#include "rpc_client/cli_winreg.h" +#include "../libcli/registry/util_reg.h" +#include "rpc_client/cli_winreg_spoolss.h" +#include "printing/nt_printing_os2.h" +#include "rpc_client/init_spoolss.h" + +#define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print" +#define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers" +#define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print" +#define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms" + +#define EMPTY_STRING "" + +#define FILL_STRING(mem_ctx, in, out) \ + do { \ + if (in && strlen(in)) { \ + out = talloc_strdup(mem_ctx, in); \ + } else { \ + out = talloc_strdup(mem_ctx, ""); \ + } \ + W_ERROR_HAVE_NO_MEMORY(out); \ + } while (0); + +#define CHECK_ERROR(result) \ + if (W_ERROR_IS_OK(result)) continue; \ + if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \ + if (!W_ERROR_IS_OK(result)) break + +/* FLAGS, NAME, with, height, left, top, right, bottom */ +static const struct spoolss_FormInfo1 builtin_forms1[] = { + { SPOOLSS_FORM_BUILTIN, "10x11", {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} }, + { SPOOLSS_FORM_BUILTIN, "10x14", {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} }, + { SPOOLSS_FORM_BUILTIN, "11x17", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} }, + { SPOOLSS_FORM_BUILTIN, "12x11", {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} }, + { SPOOLSS_FORM_BUILTIN, "15x11", {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} }, + { SPOOLSS_FORM_BUILTIN, "6 3/4 Envelope", {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} }, + { SPOOLSS_FORM_BUILTIN, "9x11", {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} }, + { SPOOLSS_FORM_BUILTIN, "A0", {0xcd528,0x122488},{0x0,0x0,0xcd528,0x122488} }, + { SPOOLSS_FORM_BUILTIN, "A1", {0x91050,0xcd528}, {0x0,0x0,0x91050,0xcd528} }, + { SPOOLSS_FORM_BUILTIN, "A2", {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} }, + { SPOOLSS_FORM_BUILTIN, "A3 Extra Transverse", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} }, + { SPOOLSS_FORM_BUILTIN, "A3 Extra", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} }, + { SPOOLSS_FORM_BUILTIN, "A3 Rotated", {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} }, + { SPOOLSS_FORM_BUILTIN, "A3 Transverse", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} }, + { SPOOLSS_FORM_BUILTIN, "A3", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} }, + { SPOOLSS_FORM_BUILTIN, "A4 Extra", {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} }, + { SPOOLSS_FORM_BUILTIN, "A4 Plus", {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} }, + { SPOOLSS_FORM_BUILTIN, "A4 Rotated", {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} }, + { SPOOLSS_FORM_BUILTIN, "A4 Small", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} }, + { SPOOLSS_FORM_BUILTIN, "A4 Transverse", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} }, + { SPOOLSS_FORM_BUILTIN, "A4", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} }, + { SPOOLSS_FORM_BUILTIN, "A5 Extra", {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} }, + { SPOOLSS_FORM_BUILTIN, "A5 Rotated", {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} }, + { SPOOLSS_FORM_BUILTIN, "A5 Transverse", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} }, + { SPOOLSS_FORM_BUILTIN, "A5", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} }, + { SPOOLSS_FORM_BUILTIN, "A6 Rotated", {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} }, + { SPOOLSS_FORM_BUILTIN, "A6", {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} }, + { SPOOLSS_FORM_BUILTIN, "B4 (ISO)", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} }, + { SPOOLSS_FORM_BUILTIN, "B4 (JIS) Rotated", {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} }, + { SPOOLSS_FORM_BUILTIN, "B4 (JIS)", {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} }, + { SPOOLSS_FORM_BUILTIN, "B5 (ISO) Extra", {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} }, + { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Rotated", {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} }, + { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Transverse", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} }, + { SPOOLSS_FORM_BUILTIN, "B5 (JIS)", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} }, + { SPOOLSS_FORM_BUILTIN, "B6 (JIS) Rotated", {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} }, + { SPOOLSS_FORM_BUILTIN, "B6 (JIS)", {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} }, + { SPOOLSS_FORM_BUILTIN, "C size sheet", {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} }, + { SPOOLSS_FORM_BUILTIN, "D size sheet", {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} }, + { SPOOLSS_FORM_BUILTIN, "Double Japan Postcard Rotated", {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} }, + { SPOOLSS_FORM_BUILTIN, "E size sheet", {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} }, + { SPOOLSS_FORM_BUILTIN, "Envelope #10", {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} }, + { SPOOLSS_FORM_BUILTIN, "Envelope #11", {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} }, + { SPOOLSS_FORM_BUILTIN, "Envelope #12", {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} }, + { SPOOLSS_FORM_BUILTIN, "Envelope #14", {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} }, + { SPOOLSS_FORM_BUILTIN, "Envelope #9", {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} }, + { SPOOLSS_FORM_BUILTIN, "Envelope B4", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} }, + { SPOOLSS_FORM_BUILTIN, "Envelope B5", {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} }, + { SPOOLSS_FORM_BUILTIN, "Envelope B6", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} }, + { SPOOLSS_FORM_BUILTIN, "Envelope C3", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} }, + { SPOOLSS_FORM_BUILTIN, "Envelope C4", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} }, + { SPOOLSS_FORM_BUILTIN, "Envelope C5", {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} }, + { SPOOLSS_FORM_BUILTIN, "Envelope C6", {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} }, + { SPOOLSS_FORM_BUILTIN, "Envelope C65", {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} }, + { SPOOLSS_FORM_BUILTIN, "Envelope DL", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} }, + { SPOOLSS_FORM_BUILTIN, "Envelope Invite", {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} }, + { SPOOLSS_FORM_BUILTIN, "Envelope Monarch", {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} }, + { SPOOLSS_FORM_BUILTIN, "Envelope", {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} }, + { SPOOLSS_FORM_BUILTIN, "Executive", {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} }, + { SPOOLSS_FORM_BUILTIN, "Folio", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} }, + { SPOOLSS_FORM_BUILTIN, "German Legal Fanfold", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} }, + { SPOOLSS_FORM_BUILTIN, "German Std Fanfold", {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} }, + { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} }, + { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} }, + { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} }, + { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} }, + { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4 Rotated", {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} }, + { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4", {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} }, + { SPOOLSS_FORM_BUILTIN, "Japanese Double Postcard", {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} }, + { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #3", {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} }, + { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #4", {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} }, + { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #2", {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} }, + { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #3", {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} }, + { SPOOLSS_FORM_BUILTIN, "Japanese Postcard Rotated", {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} }, + { SPOOLSS_FORM_BUILTIN, "Japanese Postcard", {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} }, + { SPOOLSS_FORM_BUILTIN, "Ledger", {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} }, + { SPOOLSS_FORM_BUILTIN, "Legal Extra", {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} }, + { SPOOLSS_FORM_BUILTIN, "Legal", {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} }, + { SPOOLSS_FORM_BUILTIN, "Letter Extra Transverse", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} }, + { SPOOLSS_FORM_BUILTIN, "Letter Extra", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} }, + { SPOOLSS_FORM_BUILTIN, "Letter Plus", {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} }, + { SPOOLSS_FORM_BUILTIN, "Letter Rotated", {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} }, + { SPOOLSS_FORM_BUILTIN, "Letter Small", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} }, + { SPOOLSS_FORM_BUILTIN, "Letter Transverse", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} }, + { SPOOLSS_FORM_BUILTIN, "Letter", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} }, + { SPOOLSS_FORM_BUILTIN, "Note", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} }, + { SPOOLSS_FORM_BUILTIN, "PRC 16K Rotated", {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} }, + { SPOOLSS_FORM_BUILTIN, "PRC 16K", {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} }, + { SPOOLSS_FORM_BUILTIN, "PRC 32K Rotated", {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} }, + { SPOOLSS_FORM_BUILTIN, "PRC 32K", {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} }, + { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big) Rotated", {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} }, + { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big)", {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1 Rotated", {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1", {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10 Rotated", {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2 Rotated", {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2", {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3 Rotated", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3", {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4 Rotated", {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4", {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5 Rotated", {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6 Rotated", {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6", {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7 Rotated", {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7", {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8 Rotated", {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8", {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9 Rotated", {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} }, + { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} }, + { SPOOLSS_FORM_BUILTIN, "Quarto", {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} }, + { SPOOLSS_FORM_BUILTIN, "Reserved48", {0x1,0x1}, {0x0,0x0,0x1,0x1} }, + { SPOOLSS_FORM_BUILTIN, "Reserved49", {0x1,0x1}, {0x0,0x0,0x1,0x1} }, + { SPOOLSS_FORM_BUILTIN, "Statement", {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} }, + { SPOOLSS_FORM_BUILTIN, "Super A", {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} }, + { SPOOLSS_FORM_BUILTIN, "Super B", {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} }, + { SPOOLSS_FORM_BUILTIN, "Tabloid Extra", {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} }, + { SPOOLSS_FORM_BUILTIN, "Tabloid", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} }, + { SPOOLSS_FORM_BUILTIN, "US Std Fanfold", {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} } +}; + +/******************************************************************** + static helper functions +********************************************************************/ + +/**************************************************************************** + Update the changeid time. +****************************************************************************/ +/** + * @internal + * + * @brief Update the ChangeID time of a printer. + * + * This is SO NASTY as some drivers need this to change, others need it + * static. This value will change every second, and I must hope that this + * is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF + * UTAH ! JRA. + * + * @return The ChangeID. + */ +static uint32_t winreg_printer_rev_changeid(void) +{ + struct timeval tv; + + get_process_uptime(&tv); + +#if 1 /* JERRY */ + /* Return changeid as msec since spooler restart */ + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +#else + /* + * This setting seems to work well but is too untested + * to replace the above calculation. Left in for experimentation + * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002) + */ + return tv.tv_sec * 10 + tv.tv_usec / 100000; +#endif +} + +static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *binding_handle, + const char *path, + const char *key, + bool create_key, + uint32_t access_mask, + struct policy_handle *hive_handle, + struct policy_handle *key_handle) +{ + struct winreg_String wkey, wkeyclass; + char *keyname; + NTSTATUS status; + WERROR result = WERR_OK; + + status = dcerpc_winreg_OpenHKLM(binding_handle, + mem_ctx, + NULL, + access_mask, + hive_handle, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n", + nt_errstr(status))); + return ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n", + win_errstr(result))); + return result; + } + + if (key && *key) { + keyname = talloc_asprintf(mem_ctx, "%s\\%s", path, key); + } else { + keyname = talloc_strdup(mem_ctx, path); + } + if (keyname == NULL) { + return WERR_NOMEM; + } + + ZERO_STRUCT(wkey); + wkey.name = keyname; + + if (create_key) { + enum winreg_CreateAction action = REG_ACTION_NONE; + + ZERO_STRUCT(wkeyclass); + wkeyclass.name = ""; + + status = dcerpc_winreg_CreateKey(binding_handle, + mem_ctx, + hive_handle, + wkey, + wkeyclass, + 0, + access_mask, + NULL, + key_handle, + &action, + &result); + switch (action) { + case REG_ACTION_NONE: + DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n")); + break; + case REG_CREATED_NEW_KEY: + DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname)); + break; + case REG_OPENED_EXISTING_KEY: + DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname)); + break; + } + } else { + status = dcerpc_winreg_OpenKey(binding_handle, + mem_ctx, + hive_handle, + wkey, + 0, + access_mask, + key_handle, + &result); + } + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + return result; + } + + return WERR_OK; +} + +/** + * @brief Create the registry keyname for the given printer. + * + * @param[in] mem_ctx The memory context to use. + * + * @param[in] printer The name of the printer to get the registry key. + * + * @return The registry key or NULL on error. + */ +static char *winreg_printer_data_keyname(TALLOC_CTX *mem_ctx, const char *printer) { + return talloc_asprintf(mem_ctx, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY, printer); +} + +/** + * @internal + * + * @brief Enumerate values of an opened key handle and retrieve the data. + * + * @param[in] mem_ctx The memory context to use. + * + * @param[in] winreg_handle The binding handle for the rpc connection. + * + * @param[in] key_hnd The opened key handle. + * + * @param[out] pnum_values A pointer to store he number of values found. + * + * @param[out] pnum_values A pointer to store the number of values we found. + * + * @return WERR_OK on success, the corresponding DOS error + * code if something gone wrong. + */ +static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + struct policy_handle *key_hnd, + uint32_t *pnum_values, + struct spoolss_PrinterEnumValues **penum_values) +{ + TALLOC_CTX *tmp_ctx; + uint32_t num_subkeys, max_subkeylen, max_classlen; + uint32_t num_values, max_valnamelen, max_valbufsize; + uint32_t secdescsize; + uint32_t i; + NTTIME last_changed_time; + struct winreg_String classname; + + struct spoolss_PrinterEnumValues *enum_values; + + WERROR result = WERR_OK; + NTSTATUS status; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + ZERO_STRUCT(classname); + + status = dcerpc_winreg_QueryInfoKey(winreg_handle, + tmp_ctx, + key_hnd, + &classname, + &num_subkeys, + &max_subkeylen, + &max_classlen, + &num_values, + &max_valnamelen, + &max_valbufsize, + &secdescsize, + &last_changed_time, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n", + nt_errstr(status))); + result = ntstatus_to_werror(status); + goto error; + } + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n", + win_errstr(result))); + goto error; + } + + if (num_values == 0) { + *pnum_values = 0; + TALLOC_FREE(tmp_ctx); + return WERR_OK; + } + + enum_values = talloc_array(tmp_ctx, struct spoolss_PrinterEnumValues, num_values); + if (enum_values == NULL) { + result = WERR_NOMEM; + goto error; + } + + for (i = 0; i < num_values; i++) { + struct spoolss_PrinterEnumValues val; + struct winreg_ValNameBuf name_buf; + enum winreg_Type type = REG_NONE; + uint8_t *data; + uint32_t data_size; + uint32_t length; + char n = '\0'; + + name_buf.name = &n; + name_buf.size = max_valnamelen + 2; + name_buf.length = 0; + + data_size = max_valbufsize; + data = NULL; + if (data_size) { + data = (uint8_t *) talloc_zero_size(tmp_ctx, data_size); + } + length = 0; + + status = dcerpc_winreg_EnumValue(winreg_handle, + tmp_ctx, + key_hnd, + i, + &name_buf, + &type, + data, + data_size ? &data_size : NULL, + &length, + &result); + if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) { + result = WERR_OK; + status = NT_STATUS_OK; + break; + } + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n", + nt_errstr(status))); + result = ntstatus_to_werror(status); + goto error; + } + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n", + win_errstr(result))); + goto error; + } + + if (name_buf.name == NULL) { + result = WERR_INVALID_PARAMETER; + goto error; + } + + val.value_name = talloc_strdup(enum_values, name_buf.name); + if (val.value_name == NULL) { + result = WERR_NOMEM; + goto error; + } + val.value_name_len = strlen_m_term(val.value_name) * 2; + + val.type = type; + val.data_length = length; + val.data = NULL; + if (val.data_length) { + val.data = talloc(enum_values, DATA_BLOB); + if (val.data == NULL) { + result = WERR_NOMEM; + goto error; + } + *val.data = data_blob_talloc(val.data, data, val.data_length); + } + + enum_values[i] = val; + } + + *pnum_values = num_values; + if (penum_values) { + *penum_values = talloc_move(mem_ctx, &enum_values); + } + + result = WERR_OK; + + error: + TALLOC_FREE(tmp_ctx); + return result; +} + +/** + * @internal + * + * @brief A function to delete a key and its subkeys recurively. + * + * @param[in] mem_ctx The memory context to use. + * + * @param[in] winreg_handle The binding handle for the rpc connection. + * + * @param[in] hive_handle A opened hive handle to the key. + * + * @param[in] access_mask The access mask to access the key. + * + * @param[in] key The key to delete + * + * @return WERR_OK on success, the corresponding DOS error + * code if something gone wrong. + */ +static WERROR winreg_printer_delete_subkeys(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + struct policy_handle *hive_handle, + uint32_t access_mask, + const char *key) +{ + const char **subkeys = NULL; + uint32_t num_subkeys = 0; + struct policy_handle key_hnd; + struct winreg_String wkey = { 0, }; + WERROR result = WERR_OK; + NTSTATUS status; + uint32_t i; + + ZERO_STRUCT(key_hnd); + wkey.name = key; + + DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key)); + /* open the key */ + status = dcerpc_winreg_OpenKey(winreg_handle, + mem_ctx, + hive_handle, + wkey, + 0, + access_mask, + &key_hnd, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n", + wkey.name, nt_errstr(status))); + return ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n", + wkey.name, win_errstr(result))); + return result; + } + + status = dcerpc_winreg_enum_keys(mem_ctx, + winreg_handle, + &key_hnd, + &num_subkeys, + &subkeys, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + for (i = 0; i < num_subkeys; i++) { + /* create key + subkey */ + char *subkey = talloc_asprintf(mem_ctx, "%s\\%s", key, subkeys[i]); + if (subkey == NULL) { + goto done; + } + + DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey)); + result = winreg_printer_delete_subkeys(mem_ctx, + winreg_handle, + hive_handle, + access_mask, + subkey); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (is_valid_policy_hnd(&key_hnd)) { + WERROR ignore; + dcerpc_winreg_CloseKey(winreg_handle, mem_ctx, &key_hnd, &ignore); + } + + wkey.name = key; + + status = dcerpc_winreg_DeleteKey(winreg_handle, + mem_ctx, + hive_handle, + wkey, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + +done: + if (is_valid_policy_hnd(&key_hnd)) { + WERROR ignore; + + dcerpc_winreg_CloseKey(winreg_handle, mem_ctx, &key_hnd, &ignore); + } + + return result; +} + +static WERROR winreg_printer_opendriver(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *drivername, + const char *architecture, + uint32_t version, + uint32_t access_mask, + bool create, + struct policy_handle *hive_hnd, + struct policy_handle *key_hnd) +{ + WERROR result; + char *key_name; + + key_name = talloc_asprintf(mem_ctx, "%s\\Environments\\%s\\Drivers\\Version-%u", + TOP_LEVEL_CONTROL_KEY, + architecture, version); + if (!key_name) { + return WERR_NOMEM; + } + + result = winreg_printer_openkey(mem_ctx, + winreg_handle, + key_name, + drivername, + create, + access_mask, + hive_hnd, + key_hnd); + return result; +} + +static WERROR winreg_enumval_to_dword(TALLOC_CTX *mem_ctx, + struct spoolss_PrinterEnumValues *v, + const char *valuename, uint32_t *dw) +{ + /* just return if it is not the one we are looking for */ + if (strcmp(valuename, v->value_name) != 0) { + return WERR_NOT_FOUND; + } + + if (v->type != REG_DWORD) { + return WERR_INVALID_DATATYPE; + } + + if (v->data_length != 4) { + *dw = 0; + return WERR_OK; + } + + *dw = IVAL(v->data->data, 0); + return WERR_OK; +} + +static WERROR winreg_enumval_to_sz(TALLOC_CTX *mem_ctx, + struct spoolss_PrinterEnumValues *v, + const char *valuename, const char **_str) +{ + /* just return if it is not the one we are looking for */ + if (strcmp(valuename, v->value_name) != 0) { + return WERR_NOT_FOUND; + } + + if (v->type != REG_SZ) { + return WERR_INVALID_DATATYPE; + } + + if (v->data_length == 0) { + *_str = talloc_strdup(mem_ctx, EMPTY_STRING); + if (*_str == NULL) { + return WERR_NOMEM; + } + return WERR_OK; + } + + if (!pull_reg_sz(mem_ctx, v->data, _str)) { + return WERR_NOMEM; + } + + return WERR_OK; +} + +static WERROR winreg_enumval_to_multi_sz(TALLOC_CTX *mem_ctx, + struct spoolss_PrinterEnumValues *v, + const char *valuename, + const char ***array) +{ + /* just return if it is not the one we are looking for */ + if (strcmp(valuename, v->value_name) != 0) { + return WERR_NOT_FOUND; + } + + if (v->type != REG_MULTI_SZ) { + return WERR_INVALID_DATATYPE; + } + + if (v->data_length == 0) { + *array = talloc_array(mem_ctx, const char *, 1); + if (*array == NULL) { + return WERR_NOMEM; + } + *array[0] = NULL; + return WERR_OK; + } + + if (!pull_reg_multi_sz(mem_ctx, v->data, array)) { + return WERR_NOMEM; + } + + return WERR_OK; +} + +static WERROR winreg_printer_write_date(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + struct policy_handle *key_handle, + const char *value, + NTTIME data) +{ + struct winreg_String wvalue = { 0, }; + DATA_BLOB blob; + WERROR result = WERR_OK; + NTSTATUS status; + const char *str; + struct tm *tm; + time_t t; + + if (data == 0) { + str = talloc_strdup(mem_ctx, "01/01/1601"); + } else { + t = nt_time_to_unix(data); + tm = localtime(&t); + if (tm == NULL) { + return map_werror_from_unix(errno); + } + str = talloc_asprintf(mem_ctx, "%02d/%02d/%04d", + tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900); + } + if (!str) { + return WERR_NOMEM; + } + + wvalue.name = value; + if (!push_reg_sz(mem_ctx, &blob, str)) { + return WERR_NOMEM; + } + status = dcerpc_winreg_SetValue(winreg_handle, + mem_ctx, + key_handle, + wvalue, + REG_SZ, + blob.data, + blob.length, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n", + wvalue.name, win_errstr(result))); + } + + return result; +} + +static WERROR winreg_printer_date_to_NTTIME(const char *str, NTTIME *data) +{ + struct tm tm; + time_t t; + + if (strequal(str, "01/01/1601")) { + *data = 0; + return WERR_OK; + } + + ZERO_STRUCT(tm); + + if (sscanf(str, "%d/%d/%d", + &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3) { + return WERR_INVALID_PARAMETER; + } + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = -1; + + t = mktime(&tm); + unix_to_nt_time(data, t); + + return WERR_OK; +} + +static WERROR winreg_printer_write_ver(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + struct policy_handle *key_handle, + const char *value, + uint64_t data) +{ + struct winreg_String wvalue = { 0, }; + DATA_BLOB blob; + WERROR result = WERR_OK; + NTSTATUS status; + char *str; + + /* FIXME: check format is right, + * this needs to be something like: 6.1.7600.16385 */ + str = talloc_asprintf(mem_ctx, "%u.%u.%u.%u", + (unsigned)((data >> 48) & 0xFFFF), + (unsigned)((data >> 32) & 0xFFFF), + (unsigned)((data >> 16) & 0xFFFF), + (unsigned)(data & 0xFFFF)); + if (!str) { + return WERR_NOMEM; + } + + wvalue.name = value; + if (!push_reg_sz(mem_ctx, &blob, str)) { + return WERR_NOMEM; + } + status = dcerpc_winreg_SetValue(winreg_handle, + mem_ctx, + key_handle, + wvalue, + REG_SZ, + blob.data, + blob.length, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n", + wvalue.name, win_errstr(result))); + } + + return result; +} + +static WERROR winreg_printer_ver_to_dword(const char *str, uint64_t *data) +{ + unsigned int v1, v2, v3, v4; + + if (sscanf(str, "%u.%u.%u.%u", &v1, &v2, &v3, &v4) != 4) { + return WERR_INVALID_PARAMETER; + } + + *data = ((uint64_t)(v1 & 0xFFFF) << 48) + + ((uint64_t)(v2 & 0xFFFF) << 32) + + ((uint64_t)(v3 & 0xFFFF) << 16) + + (uint64_t)(v2 & 0xFFFF); + + return WERR_OK; +} + +/******************************************************************** + Public winreg function for spoolss +********************************************************************/ + +WERROR winreg_create_printer(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *sharename) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + struct spoolss_SetPrinterInfo2 *info2; + struct security_descriptor *secdesc; + struct winreg_String wkey, wkeyclass; + const char *path; + const char *subkeys[] = { SPOOL_DSDRIVER_KEY, SPOOL_DSSPOOLER_KEY, SPOOL_PRINTERDATA_KEY }; + uint32_t i, count = ARRAY_SIZE(subkeys); + uint32_t info2_mask = 0; + WERROR result = WERR_OK; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + 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); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + "", + false, + access_mask, + &hive_hnd, + &key_hnd); + if (W_ERROR_IS_OK(result)) { + DEBUG(2, ("winreg_create_printer: Skipping, %s already exists\n", path)); + goto done; + } else if (W_ERROR_EQUAL(result, WERR_BADFILE)) { + DEBUG(2, ("winreg_create_printer: Creating default values in %s\n", path)); + } else if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_create_printer: Could not open key %s: %s\n", + path, win_errstr(result))); + goto done; + } + + /* Create the main key */ + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + "", + true, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n", + path, win_errstr(result))); + goto done; + } + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result); + } + + /* Create subkeys */ + for (i = 0; i < count; i++) { + NTSTATUS status; + enum winreg_CreateAction action = REG_ACTION_NONE; + + ZERO_STRUCT(key_hnd); + ZERO_STRUCT(wkey); + + wkey.name = talloc_asprintf(tmp_ctx, "%s\\%s", path, subkeys[i]); + if (wkey.name == NULL) { + result = WERR_NOMEM; + goto done; + } + + ZERO_STRUCT(wkeyclass); + wkeyclass.name = ""; + + status = dcerpc_winreg_CreateKey(winreg_handle, + tmp_ctx, + &hive_hnd, + wkey, + wkeyclass, + 0, + access_mask, + NULL, + &key_hnd, + &action, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n", + wkey.name, win_errstr(result))); + goto done; + } + + if (strequal(subkeys[i], SPOOL_DSSPOOLER_KEY)) { + const char *dnssuffix; + const char *longname; + const char *uncname; + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + SPOOL_REG_PRINTERNAME, + sharename, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + SPOOL_REG_SHORTSERVERNAME, + global_myname(), + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + /* We make the assumption that the netbios name + * is the same as the DNS name since the former + * will be what we used to join the domain + */ + dnssuffix = get_mydnsdomname(tmp_ctx); + if (dnssuffix != NULL && dnssuffix[0] != '\0') { + longname = talloc_asprintf(tmp_ctx, "%s.%s", global_myname(), dnssuffix); + } else { + longname = talloc_strdup(tmp_ctx, global_myname()); + } + if (longname == NULL) { + result = WERR_NOMEM; + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + SPOOL_REG_SERVERNAME, + longname, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + uncname = talloc_asprintf(tmp_ctx, "\\\\%s\\%s", + longname, sharename); + if (uncname == NULL) { + result = WERR_NOMEM; + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + SPOOL_REG_UNCNAME, + uncname, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + SPOOL_REG_VERSIONNUMBER, + 4, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + SPOOL_REG_PRINTSTARTTIME, + 0, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + SPOOL_REG_PRINTENDTIME, + 0, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + SPOOL_REG_PRIORITY, + 1, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + SPOOL_REG_PRINTKEEPPRINTEDJOBS, + 0, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result); + } + } + info2 = talloc_zero(tmp_ctx, struct spoolss_SetPrinterInfo2); + if (info2 == NULL) { + result = WERR_NOMEM; + goto done; + } + + info2->printername = sharename; + if (info2->printername == NULL) { + result = WERR_NOMEM; + goto done; + } + info2_mask |= SPOOLSS_PRINTER_INFO_PRINTERNAME; + + info2->sharename = sharename; + info2_mask |= SPOOLSS_PRINTER_INFO_SHARENAME; + + info2->portname = SAMBA_PRINTER_PORT_NAME; + info2_mask |= SPOOLSS_PRINTER_INFO_PORTNAME; + + info2->printprocessor = "winprint"; + info2_mask |= SPOOLSS_PRINTER_INFO_PRINTPROCESSOR; + + info2->datatype = "RAW"; + info2_mask |= SPOOLSS_PRINTER_INFO_DATATYPE; + + info2->comment = ""; + info2_mask |= SPOOLSS_PRINTER_INFO_COMMENT; + + info2->attributes = PRINTER_ATTRIBUTE_SAMBA; + info2_mask |= SPOOLSS_PRINTER_INFO_ATTRIBUTES; + + info2->starttime = 0; /* Minutes since 12:00am GMT */ + info2_mask |= SPOOLSS_PRINTER_INFO_STARTTIME; + + info2->untiltime = 0; /* Minutes since 12:00am GMT */ + info2_mask |= SPOOLSS_PRINTER_INFO_UNTILTIME; + + info2->priority = 1; + info2_mask |= SPOOLSS_PRINTER_INFO_PRIORITY; + + info2->defaultpriority = 1; + info2_mask |= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY; + + result = spoolss_create_default_secdesc(tmp_ctx, &secdesc); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + info2_mask |= SPOOLSS_PRINTER_INFO_SECDESC; + + /* + * Don't write a default Device Mode to the registry! The Device Mode is + * only written to disk with a SetPrinter level 2 or 8. + */ + + result = winreg_update_printer(tmp_ctx, + winreg_handle, + sharename, + info2_mask, + info2, + NULL, + secdesc); + +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + talloc_free(tmp_ctx); + return result; +} + +WERROR winreg_update_printer(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *sharename, + uint32_t info2_mask, + struct spoolss_SetPrinterInfo2 *info2, + struct spoolss_DeviceMode *devmode, + struct security_descriptor *secdesc) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + int snum = lp_servicenumber(sharename); + enum ndr_err_code ndr_err; + DATA_BLOB blob; + char *path; + WERROR result = WERR_OK; + NTSTATUS status; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + 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); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + "", + true, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n", + path, win_errstr(result))); + goto done; + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_ATTRIBUTES) { + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + "Attributes", + info2->attributes, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + +#if 0 + if (info2_mask & SPOOLSS_PRINTER_INFO_AVERAGEPPM) { + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + "AveragePpm", + info2->attributes, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } +#endif + + if (info2_mask & SPOOLSS_PRINTER_INFO_COMMENT) { + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Description", + info2->comment, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_DATATYPE) { + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Datatype", + info2->datatype, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY) { + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + "Default Priority", + info2->defaultpriority, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_DEVMODE) { + /* + * Some client drivers freak out if there is a NULL devmode + * (probably the driver is not checking before accessing + * the devmode pointer) --jerry + */ + if (devmode == NULL && lp_default_devmode(snum) && info2 != NULL) { + result = spoolss_create_default_devmode(tmp_ctx, + info2->printername, + &devmode); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (devmode->size != (ndr_size_spoolss_DeviceMode(devmode, 0) - devmode->__driverextra_length)) { + result = WERR_INVALID_PARAM; + goto done; + } + + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, devmode, + (ndr_push_flags_fn_t) ndr_push_spoolss_DeviceMode); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n")); + result = WERR_NOMEM; + goto done; + } + + status = dcerpc_winreg_set_binary(tmp_ctx, + winreg_handle, + &key_hnd, + "Default DevMode", + &blob, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_DRIVERNAME) { + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Printer Driver", + info2->drivername, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_LOCATION) { + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Location", + info2->location, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_PARAMETERS) { + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Parameters", + info2->parameters, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_PORTNAME) { + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Port", + info2->portname, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTERNAME) { + /* + * in addprinter: no servername and the printer is the name + * in setprinter: servername is \\server + * and printer is \\server\\printer + * + * Samba manages only local printers. + * we currently don't support things like i + * path=\\other_server\printer + * + * We only store the printername, not \\server\printername + */ + const char *p = strrchr(info2->printername, '\\'); + if (p == NULL) { + p = info2->printername; + } else { + p++; + } + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Name", + p, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTPROCESSOR) { + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Print Processor", + info2->printprocessor, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_PRIORITY) { + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + "Priority", + info2->priority, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_SECDESC) { + /* + * We need a security descriptor, if it isn't specified by + * AddPrinter{Ex} then create a default descriptor. + */ + if (secdesc == NULL) { + result = spoolss_create_default_secdesc(tmp_ctx, &secdesc); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + result = winreg_set_printer_secdesc(tmp_ctx, + winreg_handle, + sharename, + secdesc); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_SEPFILE) { + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Separator File", + info2->sepfile, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_SHARENAME) { + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Share Name", + info2->sharename, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_STARTTIME) { + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + "StartTime", + info2->starttime, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_STATUS) { + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + "Status", + info2->status, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_UNTILTIME) { + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + "UntilTime", + info2->untiltime, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + "ChangeID", + winreg_printer_rev_changeid(), + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +WERROR winreg_get_printer(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *printer, + struct spoolss_PrinterInfo2 **pinfo2) +{ + struct spoolss_PrinterInfo2 *info2; + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + struct spoolss_PrinterEnumValues *enum_values = NULL; + struct spoolss_PrinterEnumValues *v = NULL; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + int snum = lp_servicenumber(printer); + uint32_t num_values = 0; + uint32_t i; + char *path; + NTSTATUS status; + WERROR result = WERR_OK; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + path = winreg_printer_data_keyname(tmp_ctx, printer); + if (path == NULL) { + TALLOC_FREE(tmp_ctx); + return WERR_NOMEM; + } + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + "", + false, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(2, ("winreg_get_printer: Could not open key %s: %s\n", + path, win_errstr(result))); + goto done; + } + + result = winreg_printer_enumvalues(tmp_ctx, + winreg_handle, + &key_hnd, + &num_values, + &enum_values); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n", + path, win_errstr(result))); + goto done; + } + + info2 = talloc_zero(tmp_ctx, struct spoolss_PrinterInfo2); + if (info2 == NULL) { + result = WERR_NOMEM; + goto done; + } + + FILL_STRING(info2, EMPTY_STRING, info2->servername); + FILL_STRING(info2, EMPTY_STRING, info2->printername); + FILL_STRING(info2, EMPTY_STRING, info2->sharename); + FILL_STRING(info2, EMPTY_STRING, info2->portname); + FILL_STRING(info2, EMPTY_STRING, info2->drivername); + FILL_STRING(info2, EMPTY_STRING, info2->comment); + FILL_STRING(info2, EMPTY_STRING, info2->location); + FILL_STRING(info2, EMPTY_STRING, info2->sepfile); + FILL_STRING(info2, EMPTY_STRING, info2->printprocessor); + FILL_STRING(info2, EMPTY_STRING, info2->datatype); + FILL_STRING(info2, EMPTY_STRING, info2->parameters); + + for (i = 0; i < num_values; i++) { + v = &enum_values[i]; + + result = winreg_enumval_to_sz(info2, + v, + "Name", + &info2->printername); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info2, + v, + "Share Name", + &info2->sharename); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info2, + v, + "Port", + &info2->portname); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info2, + v, + "Description", + &info2->comment); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info2, + v, + "Location", + &info2->location); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info2, + v, + "Separator File", + &info2->sepfile); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info2, + v, + "Print Processor", + &info2->printprocessor); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info2, + v, + "Datatype", + &info2->datatype); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info2, + v, + "Parameters", + &info2->parameters); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info2, + v, + "Printer Driver", + &info2->drivername); + CHECK_ERROR(result); + + result = winreg_enumval_to_dword(info2, + v, + "Attributes", + &info2->attributes); + CHECK_ERROR(result); + + result = winreg_enumval_to_dword(info2, + v, + "Priority", + &info2->priority); + CHECK_ERROR(result); + + result = winreg_enumval_to_dword(info2, + v, + "Default Priority", + &info2->defaultpriority); + CHECK_ERROR(result); + + result = winreg_enumval_to_dword(info2, + v, + "StartTime", + &info2->starttime); + CHECK_ERROR(result); + + result = winreg_enumval_to_dword(info2, + v, + "UntilTime", + &info2->untiltime); + CHECK_ERROR(result); + + result = winreg_enumval_to_dword(info2, + v, + "Status", + &info2->status); + CHECK_ERROR(result); + + result = winreg_enumval_to_dword(info2, + v, + "StartTime", + &info2->starttime); + CHECK_ERROR(result); + } + + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed " + "for %s: %s\n", + v->value_name, + win_errstr(result))); + goto done; + } + + /* Construct the Device Mode */ + status = dcerpc_winreg_query_binary(tmp_ctx, + winreg_handle, + &key_hnd, + "Default DevMode", + &blob, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (W_ERROR_IS_OK(result)) { + info2->devmode = talloc_zero(info2, struct spoolss_DeviceMode); + if (info2->devmode == NULL) { + result = WERR_NOMEM; + goto done; + } + ndr_err = ndr_pull_struct_blob(&blob, + info2->devmode, + info2->devmode, + (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeviceMode); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n")); + result = WERR_NOMEM; + goto done; + } + } + + if (info2->devmode == NULL && lp_default_devmode(snum)) { + result = spoolss_create_default_devmode(info2, + info2->printername, + &info2->devmode); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2->devmode) { + info2->devmode->size = ndr_size_spoolss_DeviceMode(info2->devmode, 0) - info2->devmode->driverextra_data.length; + } + + result = winreg_get_printer_secdesc(info2, + winreg_handle, + printer, + &info2->secdesc); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + /* Fix for OS/2 drivers. */ + if (get_remote_arch() == RA_OS2) { + spoolss_map_to_os2_driver(info2, &info2->drivername); + } + + if (pinfo2) { + *pinfo2 = talloc_move(mem_ctx, &info2); + } + + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + 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) +{ + 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; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + 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); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + "", + false, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + if (W_ERROR_EQUAL(result, WERR_BADFILE)) { + goto create_default; + } + goto done; + } + + status = dcerpc_winreg_query_sd(tmp_ctx, + winreg_handle, + &key_hnd, + "Security", + &secdesc, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + if (W_ERROR_EQUAL(result, WERR_BADFILE)) { + goto create_default; + } + goto done; + } + + if (psecdesc) { + *psecdesc = talloc_move(mem_ctx, &secdesc); + } + + result = WERR_OK; + goto done; + +create_default: + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + "", + true, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + result = spoolss_create_default_secdesc(tmp_ctx, &secdesc); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + /* If security descriptor is owned by S-1-1-0 and winbindd is up, + this security descriptor has been created when winbindd was + down. Take ownership of security descriptor. */ + if (dom_sid_equal(secdesc->owner_sid, &global_sid_World)) { + struct dom_sid owner_sid; + + /* Change sd owner to workgroup administrator */ + + if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) { + struct spoolss_security_descriptor *new_secdesc; + size_t size; + + /* Create new sd */ + sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR); + + new_secdesc = make_sec_desc(tmp_ctx, + secdesc->revision, + secdesc->type, + &owner_sid, + secdesc->group_sid, + secdesc->sacl, + secdesc->dacl, + &size); + + if (new_secdesc == NULL) { + result = WERR_NOMEM; + goto done; + } + + /* Swap with other one */ + secdesc = new_secdesc; + } + } + + status = dcerpc_winreg_set_sd(tmp_ctx, + winreg_handle, + &key_hnd, + "Security", + secdesc, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + return result; + } + + if (psecdesc) { + *psecdesc = talloc_move(mem_ctx, &secdesc); + } + + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + talloc_free(tmp_ctx); + 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) +{ + 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; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + 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 + * permissions through NT. If they are NULL in the new security + * descriptor then copy them over from the old one. + */ + if (!secdesc->owner_sid || !secdesc->group_sid) { + struct dom_sid *owner_sid, *group_sid; + struct security_acl *dacl, *sacl; + size_t size; + + result = winreg_get_printer_secdesc(tmp_ctx, + winreg_handle, + sharename, + &old_secdesc); + if (!W_ERROR_IS_OK(result)) { + talloc_free(tmp_ctx); + return result; + } + + /* Pick out correct owner and group sids */ + owner_sid = secdesc->owner_sid ? + secdesc->owner_sid : + old_secdesc->owner_sid; + + group_sid = secdesc->group_sid ? + secdesc->group_sid : + old_secdesc->group_sid; + + dacl = secdesc->dacl ? + secdesc->dacl : + old_secdesc->dacl; + + sacl = secdesc->sacl ? + secdesc->sacl : + old_secdesc->sacl; + + /* Make a deep copy of the security descriptor */ + new_secdesc = make_sec_desc(tmp_ctx, + secdesc->revision, + secdesc->type, + owner_sid, + group_sid, + sacl, + dacl, + &size); + if (new_secdesc == NULL) { + talloc_free(tmp_ctx); + return WERR_NOMEM; + } + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + "", + false, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sd(tmp_ctx, + winreg_handle, + &key_hnd, + "Security", + new_secdesc, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + talloc_free(tmp_ctx); + return result; +} + +/* Set printer data over the winreg pipe. */ +WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *printer, + const char *key, + const char *value, + enum winreg_Type type, + uint8_t *data, + uint32_t data_size) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + struct winreg_String wvalue = { 0, }; + char *path; + WERROR result = WERR_OK; + NTSTATUS status; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + path = winreg_printer_data_keyname(tmp_ctx, printer); + if (path == NULL) { + TALLOC_FREE(tmp_ctx); + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n", + key, value, access_mask, printer)); + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + key, + true, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n", + key, win_errstr(result))); + goto done; + } + + wvalue.name = value; + status = dcerpc_winreg_SetValue(winreg_handle, + tmp_ctx, + &key_hnd, + wvalue, + type, + data, + data_size, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n", + value, nt_errstr(status))); + result = ntstatus_to_werror(status); + } + +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +/* Get printer data over a winreg pipe. */ +WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *printer, + const char *key, + const char *value, + enum winreg_Type *type, + uint8_t **data, + uint32_t *data_size) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + struct winreg_String wvalue; + enum winreg_Type type_in = REG_NONE; + char *path; + uint8_t *data_in = NULL; + uint32_t data_in_size = 0; + uint32_t value_len = 0; + WERROR result = WERR_OK; + NTSTATUS status; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + path = winreg_printer_data_keyname(tmp_ctx, printer); + if (path == NULL) { + TALLOC_FREE(tmp_ctx); + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + key, + false, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(2, ("winreg_get_printer_dataex: Could not open key %s: %s\n", + key, win_errstr(result))); + goto done; + } + + wvalue.name = value; + + /* + * call QueryValue once with data == NULL to get the + * needed memory size to be allocated, then allocate + * data buffer and call again. + */ + status = dcerpc_winreg_QueryValue(winreg_handle, + tmp_ctx, + &key_hnd, + &wvalue, + &type_in, + NULL, + &data_in_size, + &value_len, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n", + value, nt_errstr(status))); + result = ntstatus_to_werror(status); + goto done; + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size); + if (data_in == NULL) { + result = WERR_NOMEM; + goto done; + } + value_len = 0; + + status = dcerpc_winreg_QueryValue(winreg_handle, + tmp_ctx, + &key_hnd, + &wvalue, + &type_in, + data_in, + &data_in_size, + &value_len, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n", + value, nt_errstr(status))); + result = ntstatus_to_werror(status); + goto done; + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + *type = type_in; + *data_size = data_in_size; + if (data_in_size) { + *data = talloc_move(mem_ctx, &data_in); + } + + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +/* Enumerate on the values of a given key and provide the data. */ +WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *printer, + const char *key, + uint32_t *pnum_values, + struct spoolss_PrinterEnumValues **penum_values) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + + struct spoolss_PrinterEnumValues *enum_values = NULL; + uint32_t num_values = 0; + char *path; + WERROR result = WERR_OK; + + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + path = winreg_printer_data_keyname(tmp_ctx, printer); + if (path == NULL) { + TALLOC_FREE(tmp_ctx); + return WERR_NOMEM; + } + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + key, + false, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(2, ("winreg_enum_printer_dataex: Could not open key %s: %s\n", + key, win_errstr(result))); + goto done; + } + + result = winreg_printer_enumvalues(tmp_ctx, + winreg_handle, + &key_hnd, + &num_values, + &enum_values); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n", + key, win_errstr(result))); + goto done; + } + + *pnum_values = num_values; + if (penum_values) { + *penum_values = talloc_move(mem_ctx, &enum_values); + } + + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +/* Delete printer data over a winreg pipe. */ +WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *printer, + const char *key, + const char *value) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + struct winreg_String wvalue = { 0, }; + char *path; + WERROR result = WERR_OK; + NTSTATUS status; + + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + path = winreg_printer_data_keyname(tmp_ctx, printer); + if (path == NULL) { + TALLOC_FREE(tmp_ctx); + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + key, + false, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n", + key, win_errstr(result))); + goto done; + } + + wvalue.name = value; + status = dcerpc_winreg_DeleteValue(winreg_handle, + tmp_ctx, + &key_hnd, + wvalue, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n", + value, nt_errstr(status))); + result = ntstatus_to_werror(status); + } + +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +/* Enumerate on the subkeys of a given key and provide the data. */ +WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *printer, + const char *key, + uint32_t *pnum_subkeys, + const char ***psubkeys) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + char *path; + const char **subkeys = NULL; + uint32_t num_subkeys = -1; + + WERROR result = WERR_OK; + NTSTATUS status; + + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + path = winreg_printer_data_keyname(tmp_ctx, printer); + if (path == NULL) { + TALLOC_FREE(tmp_ctx); + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + key, + false, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(2, ("winreg_enum_printer_key: Could not open key %s: %s\n", + key, win_errstr(result))); + goto done; + } + + status = dcerpc_winreg_enum_keys(tmp_ctx, + winreg_handle, + &key_hnd, + &num_subkeys, + &subkeys, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n", + key, win_errstr(result))); + goto done; + } + + *pnum_subkeys = num_subkeys; + if (psubkeys) { + *psubkeys = talloc_move(mem_ctx, &subkeys); + } + + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +/* Delete a key with subkeys of a given printer. */ +WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *printer, + const char *key) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + char *keyname; + char *path; + WERROR result; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + path = winreg_printer_data_keyname(tmp_ctx, printer); + if (path == NULL) { + TALLOC_FREE(tmp_ctx); + return WERR_NOMEM; + } + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + key, + false, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + /* key doesn't exist */ + if (W_ERROR_EQUAL(result, WERR_BADFILE)) { + result = WERR_OK; + goto done; + } + + DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n", + key, win_errstr(result))); + goto done; + } + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result); + } + + if (key == NULL || key[0] == '\0') { + keyname = path; + } else { + keyname = talloc_asprintf(tmp_ctx, + "%s\\%s", + path, + key); + if (keyname == NULL) { + result = WERR_NOMEM; + goto done; + } + } + + result = winreg_printer_delete_subkeys(tmp_ctx, + winreg_handle, + &hive_hnd, + access_mask, + keyname); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n", + key, win_errstr(result))); + goto done; + } + +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *printer) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + char *path; + NTSTATUS status; + WERROR result; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + path = winreg_printer_data_keyname(tmp_ctx, printer); + if (path == NULL) { + TALLOC_FREE(tmp_ctx); + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + "", + false, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_update_changeid: Could not open key %s: %s\n", + path, win_errstr(result))); + goto done; + } + + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + "ChangeID", + winreg_printer_rev_changeid(), + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *printer, + uint32_t *pchangeid) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + uint32_t changeid = 0; + char *path; + NTSTATUS status; + WERROR result; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + path = winreg_printer_data_keyname(tmp_ctx, printer); + if (path == NULL) { + TALLOC_FREE(tmp_ctx); + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + "", + false, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(2, ("winreg_printer_get_changeid: Could not open key %s: %s\n", + path, win_errstr(result))); + goto done; + } + + DEBUG(10, ("winreg_printer_get_changeid: get changeid from %s\n", path)); + + status = dcerpc_winreg_query_dword(tmp_ctx, + winreg_handle, + &key_hnd, + "ChangeID", + &changeid, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + if (pchangeid) { + *pchangeid = changeid; + } + + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +/* + * The special behaviour of the spoolss forms is documented at the website: + * + * Managing Win32 Printserver Forms + * http://unixwiz.net/techtips/winspooler-forms.html + */ + +WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + struct spoolss_AddFormInfo1 *form) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + struct winreg_String wvalue = { 0, }; + DATA_BLOB blob; + uint32_t num_info = 0; + union spoolss_FormInfo *info = NULL; + uint32_t i; + WERROR result; + NTSTATUS status; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + TOP_LEVEL_CONTROL_FORMS_KEY, + "", + true, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n", + TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); + goto done; + } + + result = winreg_printer_enumforms1(tmp_ctx, winreg_handle, + &num_info, &info); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n", + TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); + goto done; + } + + /* If form name already exists or is builtin return ALREADY_EXISTS */ + for (i = 0; i < num_info; i++) { + if (strequal(info[i].info1.form_name, form->form_name)) { + result = WERR_FILE_EXISTS; + goto done; + } + } + + wvalue.name = form->form_name; + + blob = data_blob_talloc(tmp_ctx, NULL, 32); + SIVAL(blob.data, 0, form->size.width); + SIVAL(blob.data, 4, form->size.height); + SIVAL(blob.data, 8, form->area.left); + SIVAL(blob.data, 12, form->area.top); + SIVAL(blob.data, 16, form->area.right); + SIVAL(blob.data, 20, form->area.bottom); + SIVAL(blob.data, 24, num_info + 1); /* FIXME */ + SIVAL(blob.data, 28, form->flags); + + status = dcerpc_winreg_SetValue(winreg_handle, + tmp_ctx, + &key_hnd, + wvalue, + REG_BINARY, + blob.data, + blob.length, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n", + wvalue.name, nt_errstr(status))); + result = ntstatus_to_werror(status); + } + +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(info); + TALLOC_FREE(tmp_ctx); + return result; +} + +WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + uint32_t *pnum_info, + union spoolss_FormInfo **pinfo) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + union spoolss_FormInfo *info; + struct spoolss_PrinterEnumValues *enum_values = NULL; + uint32_t num_values = 0; + uint32_t num_builtin = ARRAY_SIZE(builtin_forms1); + uint32_t i; + WERROR result; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + TOP_LEVEL_CONTROL_FORMS_KEY, + "", + true, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + /* key doesn't exist */ + if (W_ERROR_EQUAL(result, WERR_BADFILE)) { + result = WERR_OK; + goto done; + } + + DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n", + TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); + goto done; + } + + result = winreg_printer_enumvalues(tmp_ctx, + winreg_handle, + &key_hnd, + &num_values, + &enum_values); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n", + TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); + goto done; + } + + info = talloc_array(tmp_ctx, union spoolss_FormInfo, num_builtin + num_values); + if (info == NULL) { + result = WERR_NOMEM; + goto done; + } + + /* Enumerate BUILTIN forms */ + for (i = 0; i < num_builtin; i++) { + info[i].info1 = builtin_forms1[i]; + } + + /* Enumerate registry forms */ + for (i = 0; i < num_values; i++) { + union spoolss_FormInfo val; + + if (enum_values[i].type != REG_BINARY || + enum_values[i].data_length != 32) { + continue; + } + + val.info1.form_name = talloc_strdup(info, enum_values[i].value_name); + if (val.info1.form_name == NULL) { + result = WERR_NOMEM; + goto done; + } + + val.info1.size.width = IVAL(enum_values[i].data->data, 0); + val.info1.size.height = IVAL(enum_values[i].data->data, 4); + val.info1.area.left = IVAL(enum_values[i].data->data, 8); + val.info1.area.top = IVAL(enum_values[i].data->data, 12); + val.info1.area.right = IVAL(enum_values[i].data->data, 16); + val.info1.area.bottom = IVAL(enum_values[i].data->data, 20); + /* skip form index IVAL(enum_values[i].data->data, 24)));*/ + val.info1.flags = (enum spoolss_FormFlags) IVAL(enum_values[i].data->data, 28); + + info[i + num_builtin] = val; + } + + *pnum_info = num_builtin + num_values; + if (pinfo) { + *pinfo = talloc_move(mem_ctx, &info); + } + +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(enum_values); + TALLOC_FREE(tmp_ctx); + return result; +} + +WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *form_name) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + struct winreg_String wvalue = { 0, }; + uint32_t num_builtin = ARRAY_SIZE(builtin_forms1); + uint32_t i; + WERROR result = WERR_OK; + NTSTATUS status; + TALLOC_CTX *tmp_ctx; + + for (i = 0; i < num_builtin; i++) { + if (strequal(builtin_forms1[i].form_name, form_name)) { + return WERR_INVALID_PARAMETER; + } + } + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + TOP_LEVEL_CONTROL_FORMS_KEY, + "", + false, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n", + TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); + if (W_ERROR_EQUAL(result, WERR_BADFILE)) { + result = WERR_INVALID_FORM_NAME; + } + goto done; + } + + wvalue.name = form_name; + status = dcerpc_winreg_DeleteValue(winreg_handle, + tmp_ctx, + &key_hnd, + wvalue, + &result); + if (!NT_STATUS_IS_OK(status)) { + /* If the value doesn't exist, return WERR_INVALID_FORM_NAME */ + DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n", + wvalue.name, nt_errstr(status))); + result = ntstatus_to_werror(status); + goto done; + } + + if (W_ERROR_EQUAL(result, WERR_BADFILE)) { + result = WERR_INVALID_FORM_NAME; + } + +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *form_name, + struct spoolss_AddFormInfo1 *form) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + struct winreg_String wvalue = { 0, }; + DATA_BLOB blob; + uint32_t num_builtin = ARRAY_SIZE(builtin_forms1); + uint32_t i; + WERROR result; + NTSTATUS status; + TALLOC_CTX *tmp_ctx = NULL; + + for (i = 0; i < num_builtin; i++) { + if (strequal(builtin_forms1[i].form_name, form->form_name)) { + result = WERR_INVALID_PARAM; + goto done; + } + } + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + TOP_LEVEL_CONTROL_FORMS_KEY, + "", + true, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n", + TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); + goto done; + } + + /* If form_name != form->form_name then we renamed the form */ + if (strequal(form_name, form->form_name)) { + result = winreg_printer_deleteform1(tmp_ctx, winreg_handle, + form_name); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n", + TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); + goto done; + } + } + + wvalue.name = form->form_name; + + blob = data_blob_talloc(tmp_ctx, NULL, 32); + SIVAL(blob.data, 0, form->size.width); + SIVAL(blob.data, 4, form->size.height); + SIVAL(blob.data, 8, form->area.left); + SIVAL(blob.data, 12, form->area.top); + SIVAL(blob.data, 16, form->area.right); + SIVAL(blob.data, 20, form->area.bottom); + SIVAL(blob.data, 24, 42); + SIVAL(blob.data, 28, form->flags); + + status = dcerpc_winreg_SetValue(winreg_handle, + tmp_ctx, + &key_hnd, + wvalue, + REG_BINARY, + blob.data, + blob.length, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n", + wvalue.name, nt_errstr(status))); + result = ntstatus_to_werror(status); + } + +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *form_name, + struct spoolss_FormInfo1 *r) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + struct winreg_String wvalue; + enum winreg_Type type_in = REG_NONE; + uint8_t *data_in = NULL; + uint32_t data_in_size = 0; + uint32_t value_len = 0; + uint32_t num_builtin = ARRAY_SIZE(builtin_forms1); + uint32_t i; + WERROR result; + NTSTATUS status; + TALLOC_CTX *tmp_ctx; + + /* check builtin forms first */ + for (i = 0; i < num_builtin; i++) { + if (strequal(builtin_forms1[i].form_name, form_name)) { + *r = builtin_forms1[i]; + return WERR_OK; + } + } + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + TOP_LEVEL_CONTROL_FORMS_KEY, + "", + true, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(2, ("winreg_printer_getform1: Could not open key %s: %s\n", + TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); + goto done; + } + + wvalue.name = form_name; + + /* + * call QueryValue once with data == NULL to get the + * needed memory size to be allocated, then allocate + * data buffer and call again. + */ + status = dcerpc_winreg_QueryValue(winreg_handle, + tmp_ctx, + &key_hnd, + &wvalue, + &type_in, + NULL, + &data_in_size, + &value_len, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n", + wvalue.name, nt_errstr(status))); + result = ntstatus_to_werror(status); + goto done; + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size); + if (data_in == NULL) { + result = WERR_NOMEM; + goto done; + } + value_len = 0; + + status = dcerpc_winreg_QueryValue(winreg_handle, + tmp_ctx, + &key_hnd, + &wvalue, + &type_in, + data_in, + &data_in_size, + &value_len, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n", + wvalue.name, nt_errstr(status))); + result = ntstatus_to_werror(status); + goto done; + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + r->form_name = talloc_strdup(mem_ctx, form_name); + if (r->form_name == NULL) { + result = WERR_NOMEM; + goto done; + } + + r->size.width = IVAL(data_in, 0); + r->size.height = IVAL(data_in, 4); + r->area.left = IVAL(data_in, 8); + r->area.top = IVAL(data_in, 12); + r->area.right = IVAL(data_in, 16); + r->area.bottom = IVAL(data_in, 20); + /* skip index IVAL(data_in, 24)));*/ + r->flags = (enum spoolss_FormFlags) IVAL(data_in, 28); + + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +WERROR winreg_add_driver(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + struct spoolss_AddDriverInfoCtr *r, + const char **driver_name, + uint32_t *driver_version) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + struct spoolss_DriverInfo8 info8; + TALLOC_CTX *tmp_ctx = NULL; + NTSTATUS status; + WERROR result; + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + ZERO_STRUCT(info8); + + if (!driver_info_ctr_to_info8(r, &info8)) { + result = WERR_INVALID_PARAMETER; + goto done; + } + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + result = winreg_printer_opendriver(tmp_ctx, + winreg_handle, + info8.driver_name, + info8.architecture, + info8.version, + access_mask, true, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_add_driver: " + "Could not open driver key (%s,%s,%d): %s\n", + info8.driver_name, info8.architecture, + info8.version, win_errstr(result))); + goto done; + } + + /* TODO: "Attributes" ? */ + + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + "Version", + info8.version, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Driver", + info8.driver_path, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Data File", + info8.data_file, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Configuration File", + info8.config_file, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Help File", + info8.help_file, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_multi_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Dependent Files", + info8.dependent_files, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Monitor", + info8.monitor_name, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Datatype", + info8.default_datatype, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_multi_sz(tmp_ctx, + winreg_handle, + &key_hnd, "Previous Names", + info8.previous_names, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + result = winreg_printer_write_date(tmp_ctx, winreg_handle, + &key_hnd, "DriverDate", + info8.driver_date); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + result = winreg_printer_write_ver(tmp_ctx, winreg_handle, + &key_hnd, "DriverVersion", + info8.driver_version); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Manufacturer", + info8.manufacturer_name, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "OEM URL", + info8.manufacturer_url, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "HardwareID", + info8.hardware_id, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Provider", + info8.provider, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Print Processor", + info8.print_processor, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "VendorSetup", + info8.vendor_setup, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_multi_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "Color Profiles", + info8.color_profiles, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "InfPath", + info8.inf_path, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_dword(tmp_ctx, + winreg_handle, + &key_hnd, + "PrinterDriverAttributes", + info8.printer_driver_attributes, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + status = dcerpc_winreg_set_multi_sz(tmp_ctx, + winreg_handle, + &key_hnd, + "CoreDependencies", + info8.core_driver_dependencies, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + result = winreg_printer_write_date(tmp_ctx, winreg_handle, + &key_hnd, "MinInboxDriverVerDate", + info8.min_inbox_driver_ver_date); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + result = winreg_printer_write_ver(tmp_ctx, winreg_handle, &key_hnd, + "MinInboxDriverVerVersion", + info8.min_inbox_driver_ver_version); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + *driver_name = info8.driver_name; + *driver_version = info8.version; + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +WERROR winreg_get_driver(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *architecture, + const char *driver_name, + uint32_t driver_version, + struct spoolss_DriverInfo8 **_info8) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + struct spoolss_DriverInfo8 i8, *info8; + struct spoolss_PrinterEnumValues *enum_values = NULL; + struct spoolss_PrinterEnumValues *v; + uint32_t num_values = 0; + TALLOC_CTX *tmp_ctx; + WERROR result; + uint32_t i; + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + ZERO_STRUCT(i8); + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + if (driver_version == DRIVER_ANY_VERSION) { + /* look for Win2k first and then for NT4 */ + result = winreg_printer_opendriver(tmp_ctx, + winreg_handle, + driver_name, + architecture, + 3, + access_mask, false, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + result = winreg_printer_opendriver(tmp_ctx, + winreg_handle, + driver_name, + architecture, + 2, + access_mask, false, + &hive_hnd, + &key_hnd); + } + } else { + /* ok normal case */ + result = winreg_printer_opendriver(tmp_ctx, + winreg_handle, + driver_name, + architecture, + driver_version, + access_mask, false, + &hive_hnd, + &key_hnd); + } + if (!W_ERROR_IS_OK(result)) { + DEBUG(5, ("winreg_get_driver: " + "Could not open driver key (%s,%s,%d): %s\n", + driver_name, architecture, + driver_version, win_errstr(result))); + goto done; + } + + result = winreg_printer_enumvalues(tmp_ctx, + winreg_handle, + &key_hnd, + &num_values, + &enum_values); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_get_driver: " + "Could not enumerate values for (%s,%s,%d): %s\n", + driver_name, architecture, + driver_version, win_errstr(result))); + goto done; + } + + info8 = talloc_zero(tmp_ctx, struct spoolss_DriverInfo8); + if (info8 == NULL) { + result = WERR_NOMEM; + goto done; + } + + info8->driver_name = talloc_strdup(info8, driver_name); + if (info8->driver_name == NULL) { + result = WERR_NOMEM; + goto done; + } + + info8->architecture = talloc_strdup(info8, architecture); + if (info8->architecture == NULL) { + result = WERR_NOMEM; + goto done; + } + + result = WERR_OK; + + for (i = 0; i < num_values; i++) { + const char *tmp_str; + uint32_t tmp = 0; + + v = &enum_values[i]; + + result = winreg_enumval_to_dword(info8, v, + "Version", + &tmp); + if (NT_STATUS_IS_OK(result)) { + info8->version = (enum spoolss_DriverOSVersion) tmp; + } + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "Driver", + &info8->driver_path); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "Data File", + &info8->data_file); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "Configuration File", + &info8->config_file); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "Help File", + &info8->help_file); + CHECK_ERROR(result); + + result = winreg_enumval_to_multi_sz(info8, v, + "Dependent Files", + &info8->dependent_files); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "Monitor", + &info8->monitor_name); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "Datatype", + &info8->default_datatype); + CHECK_ERROR(result); + + result = winreg_enumval_to_multi_sz(info8, v, + "Previous Names", + &info8->previous_names); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "DriverDate", + &tmp_str); + if (W_ERROR_IS_OK(result)) { + result = winreg_printer_date_to_NTTIME(tmp_str, + &info8->driver_date); + } + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "DriverVersion", + &tmp_str); + if (W_ERROR_IS_OK(result)) { + result = winreg_printer_ver_to_dword(tmp_str, + &info8->driver_version); + } + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "Manufacturer", + &info8->manufacturer_name); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "OEM URL", + &info8->manufacturer_url); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "HardwareID", + &info8->hardware_id); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "Provider", + &info8->provider); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "Print Processor", + &info8->print_processor); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "VendorSetup", + &info8->vendor_setup); + CHECK_ERROR(result); + + result = winreg_enumval_to_multi_sz(info8, v, + "Color Profiles", + &info8->color_profiles); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "InfPath", + &info8->inf_path); + CHECK_ERROR(result); + + result = winreg_enumval_to_dword(info8, v, + "PrinterDriverAttributes", + &info8->printer_driver_attributes); + CHECK_ERROR(result); + + result = winreg_enumval_to_multi_sz(info8, v, + "CoreDependencies", + &info8->core_driver_dependencies); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "MinInboxDriverVerDate", + &tmp_str); + if (W_ERROR_IS_OK(result)) { + result = winreg_printer_date_to_NTTIME(tmp_str, + &info8->min_inbox_driver_ver_date); + } + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(info8, v, + "MinInboxDriverVerVersion", + &tmp_str); + if (W_ERROR_IS_OK(result)) { + result = winreg_printer_ver_to_dword(tmp_str, + &info8->min_inbox_driver_ver_version); + } + CHECK_ERROR(result); + } + + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_enumval_to_TYPE() failed " + "for %s: %s\n", v->value_name, + win_errstr(result))); + goto done; + } + + *_info8 = talloc_steal(mem_ctx, info8); + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +WERROR winreg_del_driver(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + struct spoolss_DriverInfo8 *info8, + uint32_t version) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + TALLOC_CTX *tmp_ctx; + char *key_name; + WERROR result; + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + /* test that the key exists */ + result = winreg_printer_opendriver(tmp_ctx, + winreg_handle, + info8->driver_name, + info8->architecture, + version, + access_mask, false, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + /* key doesn't exist */ + if (W_ERROR_EQUAL(result, WERR_BADFILE)) { + result = WERR_OK; + goto done; + } + + DEBUG(5, ("winreg_del_driver: " + "Could not open driver (%s,%s,%u): %s\n", + info8->driver_name, info8->architecture, + version, win_errstr(result))); + goto done; + } + + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result); + } + + key_name = talloc_asprintf(tmp_ctx, + "%s\\Environments\\%s\\Drivers\\Version-%u\\%s", + TOP_LEVEL_CONTROL_KEY, + info8->architecture, version, + info8->driver_name); + if (key_name == NULL) { + result = WERR_NOMEM; + goto done; + } + + result = winreg_printer_delete_subkeys(tmp_ctx, + winreg_handle, + &hive_hnd, + access_mask, + key_name); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_del_driver: " + "Could not open driver (%s,%s,%u): %s\n", + info8->driver_name, info8->architecture, + version, win_errstr(result))); + goto done; + } + + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} + +WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *architecture, + uint32_t version, + uint32_t *num_drivers, + const char ***drivers_p) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + const char **drivers; + TALLOC_CTX *tmp_ctx; + WERROR result; + NTSTATUS status; + + *num_drivers = 0; + *drivers_p = NULL; + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + /* use NULL for the driver name so we open the key that is + * parent of all drivers for this architecture and version */ + result = winreg_printer_opendriver(tmp_ctx, + winreg_handle, + NULL, + architecture, + version, + access_mask, false, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(5, ("winreg_get_driver_list: " + "Could not open key (%s,%u): %s\n", + architecture, version, win_errstr(result))); + result = WERR_OK; + goto done; + } + + status = dcerpc_winreg_enum_keys(tmp_ctx, + winreg_handle, + &key_hnd, + num_drivers, + &drivers, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_get_driver_list: " + "Could not enumerate drivers for (%s,%u): %s\n", + architecture, version, win_errstr(result))); + goto done; + } + + *drivers_p = talloc_steal(mem_ctx, drivers); + + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} diff --git a/source3/rpc_client/cli_winreg_spoolss.h b/source3/rpc_client/cli_winreg_spoolss.h new file mode 100644 index 0000000..aa4d98f --- /dev/null +++ b/source3/rpc_client/cli_winreg_spoolss.h @@ -0,0 +1,569 @@ +/* + * Unix SMB/CIFS implementation. + * + * SPOOLSS RPC Pipe server / winreg client routines + * + * Copyright (c) 2010 Andreas Schneider + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef _RPC_CLIENT_CLI_WINREG_SPOOLSS_H_ +#define _RPC_CLIENT_CLI_WINREG_SPOOLSS_H_ + +struct dcerpc_binding_handle; + +enum spoolss_PrinterInfo2Mask { + SPOOLSS_PRINTER_INFO_ATTRIBUTES = (int)(0x00000001), + SPOOLSS_PRINTER_INFO_AVERAGEPPM = (int)(0x00000002), + SPOOLSS_PRINTER_INFO_CJOBS = (int)(0x00000004), + SPOOLSS_PRINTER_INFO_COMMENT = (int)(0x00000008), + SPOOLSS_PRINTER_INFO_DATATYPE = (int)(0x00000010), + SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY = (int)(0x00000020), + SPOOLSS_PRINTER_INFO_DEVMODE = (int)(0x00000040), + SPOOLSS_PRINTER_INFO_DRIVERNAME = (int)(0x00000080), + SPOOLSS_PRINTER_INFO_LOCATION = (int)(0x00000100), + SPOOLSS_PRINTER_INFO_NAME = (int)(0x00000200), + SPOOLSS_PRINTER_INFO_PARAMETERS = (int)(0x00000400), + SPOOLSS_PRINTER_INFO_PORTNAME = (int)(0x00000800), + SPOOLSS_PRINTER_INFO_PRINTERNAME = (int)(0x00001000), + SPOOLSS_PRINTER_INFO_PRINTPROCESSOR = (int)(0x00002000), + SPOOLSS_PRINTER_INFO_PRIORITY = (int)(0x00004000), + SPOOLSS_PRINTER_INFO_SECDESC = (int)(0x00008000), + SPOOLSS_PRINTER_INFO_SEPFILE = (int)(0x00010000), + SPOOLSS_PRINTER_INFO_SERVERNAME = (int)(0x00020000), + SPOOLSS_PRINTER_INFO_SHARENAME = (int)(0x00040000), + SPOOLSS_PRINTER_INFO_STARTTIME = (int)(0x00080000), + SPOOLSS_PRINTER_INFO_STATUS = (int)(0x00100000), + SPOOLSS_PRINTER_INFO_UNTILTIME = (int)(0x00200000) +}; + +#define SPOOLSS_PRINTER_INFO_ALL SPOOLSS_PRINTER_INFO_ATTRIBUTES | \ + SPOOLSS_PRINTER_INFO_AVERAGEPPM | \ + SPOOLSS_PRINTER_INFO_CJOBS | \ + SPOOLSS_PRINTER_INFO_COMMENT | \ + SPOOLSS_PRINTER_INFO_DATATYPE | \ + SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY | \ + SPOOLSS_PRINTER_INFO_DEVMODE | \ + SPOOLSS_PRINTER_INFO_DRIVERNAME | \ + SPOOLSS_PRINTER_INFO_LOCATION | \ + SPOOLSS_PRINTER_INFO_NAME | \ + SPOOLSS_PRINTER_INFO_PARAMETERS | \ + SPOOLSS_PRINTER_INFO_PORTNAME | \ + SPOOLSS_PRINTER_INFO_PRINTERNAME | \ + SPOOLSS_PRINTER_INFO_PRINTPROCESSOR | \ + SPOOLSS_PRINTER_INFO_PRIORITY | \ + SPOOLSS_PRINTER_INFO_SECDESC | \ + SPOOLSS_PRINTER_INFO_SEPFILE | \ + SPOOLSS_PRINTER_INFO_SERVERNAME | \ + SPOOLSS_PRINTER_INFO_SHARENAME | \ + SPOOLSS_PRINTER_INFO_STARTTIME | \ + SPOOLSS_PRINTER_INFO_STATUS | \ + SPOOLSS_PRINTER_INFO_UNTILTIME + +WERROR winreg_create_printer(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *sharename); + +/** + * @internal + * + * @brief Update the information of a printer in the registry. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] sharename The share name. + * + * @param[in] info2_mask A bitmask which defines which values should be set. + * + * @param[in] info2 A SetPrinterInfo2 structure with the data to set. + * + * @param[in] devmode A device mode structure with the data to set. + * + * @param[in] secdesc A security descriptor structure with the data to set. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_update_printer(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *sharename, + uint32_t info2_mask, + struct spoolss_SetPrinterInfo2 *info2, + struct spoolss_DeviceMode *devmode, + struct security_descriptor *secdesc); + + +/** + * @brief Get the inforamtion of a printer stored in the registry. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] printer The name of the printer to get. + * + * @param[out] pinfo2 A pointer to store a PRINTER_INFO_2 structure. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_get_printer(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *printer, + struct spoolss_PrinterInfo2 **pinfo2); + +/** + * @brief Get the security descriptor for a printer. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] sharename The share name. + * + * @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_printer_secdesc(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *sharename, + struct spoolss_security_descriptor **psecdesc); + +/** + * @brief Set the security descriptor for a printer. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] sharename The share name. + * + * @param[in] secdesc The security descriptor to save. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *sharename, + const struct spoolss_security_descriptor *secdesc); + +/** + * @internal + * + * @brief Set printer data over the winreg pipe. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] printer The printer name. + * + * @param[in] key The key of the printer data to store the value. + * + * @param[in] value The value name to save. + * + * @param[in] type The type of the value to use. + * + * @param[in] data The data which sould be saved under the given value. + * + * @param[in] data_size The size of the data. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *printer, + const char *key, + const char *value, + enum winreg_Type type, + uint8_t *data, + uint32_t data_size); + +/** + * @internal + * + * @brief Get printer data over a winreg pipe. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] printer The printer name. + * + * @param[in] key The key of the printer data to get the value. + * + * @param[in] value The name of the value to query. + * + * @param[in] type The type of the value to query. + * + * @param[out] data A pointer to store the data. + * + * @param[out] data_size A pointer to store the size of the data. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *printer, + const char *key, + const char *value, + enum winreg_Type *type, + uint8_t **data, + uint32_t *data_size); + +/** + * @internal + * + * @brief Enumerate on the values of a given key and provide the data. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] printer The printer name. + * + * @param[in] key The key of the printer data to get the value. + * + * @param[out] pnum_values A pointer to store the number of values we found. + * + * @param[out] penum_values A pointer to store the values and its data. + * + * @return WERR_OK on success, the corresponding DOS error + * code if something gone wrong. + */ +WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *printer, + const char *key, + uint32_t *pnum_values, + struct spoolss_PrinterEnumValues **penum_values); + +/** + * @internal + * + * @brief Delete printer data over a winreg pipe. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] printer The printer name. + * + * @param[in] key The key of the printer data to delete. + * + * @param[in] value The name of the value to delete. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *printer, + const char *key, + const char *value); + +/** + * @internal + * + * @brief Enumerate on the subkeys of a given key and provide the data. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] printer The printer name. + * + * @param[in] key The key of the printer data to get the value. + * + * @param[out] pnum_subkeys A pointer to store the number of subkeys found. + * + * @param[in] psubkeys A pointer to an array to store the names of the subkeys + * found. + * + * @return WERR_OK on success, the corresponding DOS error + * code if something gone wrong. + */ +WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *printer, + const char *key, + uint32_t *pnum_subkeys, + const char ***psubkeys); + +/** + * @internal + * + * @brief Delete a key with subkeys of a given printer. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] printer The printer name. + * + * @param[in] key The key of the printer to delete. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *printer, + const char *key); + +/** + * @brief Update the ChangeID of a printer. + * + * The ChangeID **must** be increasing over the lifetime of client's spoolss + * service in order for the client's cache to show updates. + * + * If a form is updated of a printer, the we need to update the ChangeID of the + * pritner. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] printer The printer name. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *printer); + +/** + * @brief Get the ChangeID of the given printer. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] printer The printer name. + * + * @param[in] changeid A pointer to store the changeid. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *printer, + uint32_t *pchangeid); + +/** + * @internal + * + * @brief This function adds a form to the list of available forms that can be + * selected for the specified printer. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] form The form to add. + * + * @return WERR_OK on success. + * WERR_ALREADY_EXISTS if the form already exists or is a + * builtin form. + * A corresponding DOS error is something went wrong. + */ +WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + struct spoolss_AddFormInfo1 *form); + +/* + * @brief This function enumerates the forms supported by the specified printer. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[out] pnum_info A pointer to store the FormInfo count. + * + * @param[out] pinfo A pointer to store an array with FormInfo. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + uint32_t *pnum_info, + union spoolss_FormInfo **pinfo); + +/** + * @brief This function removes a form name from the list of supported forms. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] form_name The name of the form to delete. + * + * @return WERR_OK on success. + * WERR_INVALID_PARAM if the form is a builtin form. + * WERR_INVALID_FORM_NAME if the form or key doesn't exist. + * A corresponding DOS error is something went wrong. + */ +WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *form_name); + +/** + * @brief This function sets the form information for the specified printer. + * + * If one provides both the name in the API call and inside the FormInfo + * structure, then the form gets renamed. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] form_name The name of the form to set or rename. + * + * @param[in] form The FormInfo structure to save. + * + * @return WERR_OK on success. + * WERR_INVALID_PARAM if the form is a builtin form. + * A corresponding DOS error is something went wrong. + */ +WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *form_name, + struct spoolss_AddFormInfo1 *form); + +/** + * @brief This function retrieves information about a specified form. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] form_name The name of the form to query. + * + * @param[out] form A pointer to a form structure to fill out. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *form_name, + struct spoolss_FormInfo1 *form); + +/** + * @brief This function adds a new spool driver + * + * @param[in] mem_ctx A talloc memory context. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] r The structure containing the new driver data. + * + * @param[out] driver_name Returns the driver name. + * + * @param[out] driver_version Returns the driver version. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_add_driver(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + struct spoolss_AddDriverInfoCtr *r, + const char **driver_name, + uint32_t *driver_version); + +/** + * @brief This function gets printer driver information + * + * @param[in] mem_ctx A talloc memory context. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] architecture The architecture type. + * + * @param[in] driver_name The driver name. + * + * @param[in] driver_version The driver version. + * + * @param[out] _info8 The structure that holds the full driver information. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ + +WERROR winreg_get_driver(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *architecture, + const char *driver_name, + uint32_t driver_version, + struct spoolss_DriverInfo8 **_info8); + +/** + * @brief This function deletes a printer driver information + * + * @param[in] mem_ctx A talloc memory context. + * + * @param[in] b The dcerpc binding handle + * + * @param[out] info8 The structure that holds the full driver information. + * + * @param[in] version The driver type version. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ + +WERROR winreg_del_driver(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + struct spoolss_DriverInfo8 *info8, + uint32_t version); + +/** + * @brief This function gets printer drivers list for the specified + * architecture and type version + * + * @param[in] mem_ctx A talloc memory context. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] architecture The architecture type. + * + * @param[in] version The driver version. + * + * @param[out] num_drivers The number of drivers. + * + * @param[out] version The drivers names. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ + +WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + const char *architecture, + uint32_t version, + uint32_t *num_drivers, + const char ***drivers); + +#endif /* _RPC_CLIENT_CLI_WINREG_SPOOLSS_H_ */ diff --git a/source3/wscript_build b/source3/wscript_build index c00c137..4d47acb 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -405,8 +405,7 @@ PRINTBACKEND_SRC = '''printing/printing.c printing/nt_printing.c printing/nt_printing_tdb.c printing/nt_printing_migrate_internal.c - printing/nt_printing_ads.c - printing/nt_printing_os2.c''' + printing/nt_printing_ads.c''' SMBD_SRC = '''${SMBD_SRC_BASE} ${SMBD_SRC_MAIN}''' @@ -887,8 +886,8 @@ bld.SAMBA3_SUBSYSTEM('PRINTBACKEND', vars=locals()) bld.SAMBA3_LIBRARY('printing_migrate', - source='printing/nt_printing_migrate.c', - deps='NDR_NTPRINTING RPC_NDR_SPOOLSS param', + source='printing/nt_printing_migrate.c rpc_client/cli_winreg_spoolss.c printing/nt_printing_os2.c', + deps='NDR_NTPRINTING LIBCLI_SPOOLSS RPC_NDR_WINREG LIBCLI_WINREG param', vars=locals(), private_library=True) -- 1.7.6 From 7f2045c150b5d7439377d1ac3450e0c73b86e61a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Mon, 4 Jul 2011 20:09:54 +0200 Subject: [PATCH 12/21] s3-printing: add winreg_printer_binding_handle and remove most of srv_spoolss_util.c. Guenther Pair-Programmed-With: David Disseldorp (cherry picked from commit a762eda519c995214c041170e2615c5c51b2a2b1) Conflicts: source3/rpc_server/spoolss/srv_spoolss_util.c --- source3/rpc_server/spoolss/srv_spoolss_util.c | 4218 +------------------------ source3/rpc_server/spoolss/srv_spoolss_util.h | 568 +---- 2 files changed, 13 insertions(+), 4773 deletions(-) diff --git a/source3/rpc_server/spoolss/srv_spoolss_util.c b/source3/rpc_server/spoolss/srv_spoolss_util.c index d8caec1..0d2b6d7 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_util.c +++ b/source3/rpc_server/spoolss/srv_spoolss_util.c @@ -20,249 +20,17 @@ */ #include "includes.h" -#include "nt_printing.h" -#include "srv_spoolss_util.h" -#include "../librpc/gen_ndr/ndr_spoolss.h" -#include "../librpc/gen_ndr/ndr_winreg_c.h" -#include "../librpc/gen_ndr/ndr_security.h" -#include "secrets.h" #include "rpc_server/rpc_ncacn_np.h" -#include "../libcli/security/security.h" -#include "rpc_client/cli_winreg.h" -#include "../libcli/registry/util_reg.h" -#include "printing/nt_printing_os2.h" -#include "rpc_client/init_spoolss.h" - -#define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print" -#define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers" -#define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print" -#define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms" - -#define EMPTY_STRING "" - -#define FILL_STRING(mem_ctx, in, out) \ - do { \ - if (in && strlen(in)) { \ - out = talloc_strdup(mem_ctx, in); \ - } else { \ - out = talloc_strdup(mem_ctx, ""); \ - } \ - W_ERROR_HAVE_NO_MEMORY(out); \ - } while (0); - -#define CHECK_ERROR(result) \ - if (W_ERROR_IS_OK(result)) continue; \ - if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \ - if (!W_ERROR_IS_OK(result)) break - -/* FLAGS, NAME, with, height, left, top, right, bottom */ -static const struct spoolss_FormInfo1 builtin_forms1[] = { - { SPOOLSS_FORM_BUILTIN, "10x11", {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} }, - { SPOOLSS_FORM_BUILTIN, "10x14", {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} }, - { SPOOLSS_FORM_BUILTIN, "11x17", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} }, - { SPOOLSS_FORM_BUILTIN, "12x11", {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} }, - { SPOOLSS_FORM_BUILTIN, "15x11", {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} }, - { SPOOLSS_FORM_BUILTIN, "6 3/4 Envelope", {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} }, - { SPOOLSS_FORM_BUILTIN, "9x11", {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} }, - { SPOOLSS_FORM_BUILTIN, "A0", {0xcd528,0x122488},{0x0,0x0,0xcd528,0x122488} }, - { SPOOLSS_FORM_BUILTIN, "A1", {0x91050,0xcd528}, {0x0,0x0,0x91050,0xcd528} }, - { SPOOLSS_FORM_BUILTIN, "A2", {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} }, - { SPOOLSS_FORM_BUILTIN, "A3 Extra Transverse", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} }, - { SPOOLSS_FORM_BUILTIN, "A3 Extra", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} }, - { SPOOLSS_FORM_BUILTIN, "A3 Rotated", {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} }, - { SPOOLSS_FORM_BUILTIN, "A3 Transverse", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} }, - { SPOOLSS_FORM_BUILTIN, "A3", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} }, - { SPOOLSS_FORM_BUILTIN, "A4 Extra", {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} }, - { SPOOLSS_FORM_BUILTIN, "A4 Plus", {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} }, - { SPOOLSS_FORM_BUILTIN, "A4 Rotated", {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} }, - { SPOOLSS_FORM_BUILTIN, "A4 Small", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} }, - { SPOOLSS_FORM_BUILTIN, "A4 Transverse", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} }, - { SPOOLSS_FORM_BUILTIN, "A4", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} }, - { SPOOLSS_FORM_BUILTIN, "A5 Extra", {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} }, - { SPOOLSS_FORM_BUILTIN, "A5 Rotated", {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} }, - { SPOOLSS_FORM_BUILTIN, "A5 Transverse", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} }, - { SPOOLSS_FORM_BUILTIN, "A5", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} }, - { SPOOLSS_FORM_BUILTIN, "A6 Rotated", {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} }, - { SPOOLSS_FORM_BUILTIN, "A6", {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} }, - { SPOOLSS_FORM_BUILTIN, "B4 (ISO)", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} }, - { SPOOLSS_FORM_BUILTIN, "B4 (JIS) Rotated", {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} }, - { SPOOLSS_FORM_BUILTIN, "B4 (JIS)", {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} }, - { SPOOLSS_FORM_BUILTIN, "B5 (ISO) Extra", {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} }, - { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Rotated", {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} }, - { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Transverse", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} }, - { SPOOLSS_FORM_BUILTIN, "B5 (JIS)", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} }, - { SPOOLSS_FORM_BUILTIN, "B6 (JIS) Rotated", {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} }, - { SPOOLSS_FORM_BUILTIN, "B6 (JIS)", {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} }, - { SPOOLSS_FORM_BUILTIN, "C size sheet", {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} }, - { SPOOLSS_FORM_BUILTIN, "D size sheet", {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} }, - { SPOOLSS_FORM_BUILTIN, "Double Japan Postcard Rotated", {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} }, - { SPOOLSS_FORM_BUILTIN, "E size sheet", {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} }, - { SPOOLSS_FORM_BUILTIN, "Envelope #10", {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} }, - { SPOOLSS_FORM_BUILTIN, "Envelope #11", {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} }, - { SPOOLSS_FORM_BUILTIN, "Envelope #12", {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} }, - { SPOOLSS_FORM_BUILTIN, "Envelope #14", {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} }, - { SPOOLSS_FORM_BUILTIN, "Envelope #9", {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} }, - { SPOOLSS_FORM_BUILTIN, "Envelope B4", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} }, - { SPOOLSS_FORM_BUILTIN, "Envelope B5", {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} }, - { SPOOLSS_FORM_BUILTIN, "Envelope B6", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} }, - { SPOOLSS_FORM_BUILTIN, "Envelope C3", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} }, - { SPOOLSS_FORM_BUILTIN, "Envelope C4", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} }, - { SPOOLSS_FORM_BUILTIN, "Envelope C5", {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} }, - { SPOOLSS_FORM_BUILTIN, "Envelope C6", {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} }, - { SPOOLSS_FORM_BUILTIN, "Envelope C65", {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} }, - { SPOOLSS_FORM_BUILTIN, "Envelope DL", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} }, - { SPOOLSS_FORM_BUILTIN, "Envelope Invite", {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} }, - { SPOOLSS_FORM_BUILTIN, "Envelope Monarch", {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} }, - { SPOOLSS_FORM_BUILTIN, "Envelope", {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} }, - { SPOOLSS_FORM_BUILTIN, "Executive", {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} }, - { SPOOLSS_FORM_BUILTIN, "Folio", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} }, - { SPOOLSS_FORM_BUILTIN, "German Legal Fanfold", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} }, - { SPOOLSS_FORM_BUILTIN, "German Std Fanfold", {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} }, - { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} }, - { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} }, - { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} }, - { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} }, - { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4 Rotated", {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} }, - { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4", {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} }, - { SPOOLSS_FORM_BUILTIN, "Japanese Double Postcard", {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} }, - { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #3", {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} }, - { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #4", {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} }, - { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #2", {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} }, - { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #3", {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} }, - { SPOOLSS_FORM_BUILTIN, "Japanese Postcard Rotated", {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} }, - { SPOOLSS_FORM_BUILTIN, "Japanese Postcard", {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} }, - { SPOOLSS_FORM_BUILTIN, "Ledger", {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} }, - { SPOOLSS_FORM_BUILTIN, "Legal Extra", {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} }, - { SPOOLSS_FORM_BUILTIN, "Legal", {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} }, - { SPOOLSS_FORM_BUILTIN, "Letter Extra Transverse", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} }, - { SPOOLSS_FORM_BUILTIN, "Letter Extra", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} }, - { SPOOLSS_FORM_BUILTIN, "Letter Plus", {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} }, - { SPOOLSS_FORM_BUILTIN, "Letter Rotated", {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} }, - { SPOOLSS_FORM_BUILTIN, "Letter Small", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} }, - { SPOOLSS_FORM_BUILTIN, "Letter Transverse", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} }, - { SPOOLSS_FORM_BUILTIN, "Letter", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} }, - { SPOOLSS_FORM_BUILTIN, "Note", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} }, - { SPOOLSS_FORM_BUILTIN, "PRC 16K Rotated", {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} }, - { SPOOLSS_FORM_BUILTIN, "PRC 16K", {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} }, - { SPOOLSS_FORM_BUILTIN, "PRC 32K Rotated", {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} }, - { SPOOLSS_FORM_BUILTIN, "PRC 32K", {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} }, - { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big) Rotated", {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} }, - { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big)", {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1 Rotated", {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1", {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10 Rotated", {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2 Rotated", {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2", {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3 Rotated", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3", {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4 Rotated", {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4", {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5 Rotated", {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6 Rotated", {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6", {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7 Rotated", {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7", {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8 Rotated", {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8", {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9 Rotated", {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} }, - { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} }, - { SPOOLSS_FORM_BUILTIN, "Quarto", {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} }, - { SPOOLSS_FORM_BUILTIN, "Reserved48", {0x1,0x1}, {0x0,0x0,0x1,0x1} }, - { SPOOLSS_FORM_BUILTIN, "Reserved49", {0x1,0x1}, {0x0,0x0,0x1,0x1} }, - { SPOOLSS_FORM_BUILTIN, "Statement", {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} }, - { SPOOLSS_FORM_BUILTIN, "Super A", {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} }, - { SPOOLSS_FORM_BUILTIN, "Super B", {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} }, - { SPOOLSS_FORM_BUILTIN, "Tabloid Extra", {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} }, - { SPOOLSS_FORM_BUILTIN, "Tabloid", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} }, - { SPOOLSS_FORM_BUILTIN, "US Std Fanfold", {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} } -}; - -/******************************************************************** - static helper functions -********************************************************************/ - -/**************************************************************************** - Update the changeid time. -****************************************************************************/ -/** - * @internal - * - * @brief Update the ChangeID time of a printer. - * - * This is SO NASTY as some drivers need this to change, others need it - * static. This value will change every second, and I must hope that this - * is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF - * UTAH ! JRA. - * - * @return The ChangeID. - */ -static uint32_t winreg_printer_rev_changeid(void) -{ - struct timeval tv; - - get_process_uptime(&tv); - -#if 1 /* JERRY */ - /* Return changeid as msec since spooler restart */ - return tv.tv_sec * 1000 + tv.tv_usec / 1000; -#else - /* - * This setting seems to work well but is too untested - * to replace the above calculation. Left in for experimentation - * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002) - */ - return tv.tv_sec * 10 + tv.tv_usec / 100000; -#endif -} +#include "srv_spoolss_util.h" +#include "../librpc/gen_ndr/ndr_winreg.h" -/** - * @internal - * - * @brief Connect to the interal winreg server and open the given printer key. - * - * The function will create the needed subkeys if they don't exist. - * - * @param[in] mem_ctx The memory context to use. - * - * @param[in] session_info The supplied server info. - * - * @param[out] binding_handle A pointer for the winreg dcerpc binding handle. - * - * @param[in] path The path to the key to open. - * - * @param[in] key The key to open. - * - * @param[in] create_key Set to true if the key should be created if it - * doesn't exist. - * - * @param[in] access_mask The access mask to open the key. - * - * @param[out] hive_handle A policy handle for the opened hive. - * - * @param[out] key_handle A policy handle for the opened key. - * - * @return WERR_OK on success, the corresponding DOS error - * code if something gone wrong. - */ -static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - struct dcerpc_binding_handle **winreg_binding_handle, - const char *path, - const char *key, - bool create_key, - uint32_t access_mask, - struct policy_handle *hive_handle, - struct policy_handle *key_handle) +WERROR winreg_printer_binding_handle(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + struct dcerpc_binding_handle **winreg_binding_handle) { static struct client_address client_id; - struct dcerpc_binding_handle *binding_handle; - struct winreg_String wkey, wkeyclass; - char *keyname; NTSTATUS status; - WERROR result = WERR_OK; strlcpy(client_id.addr, "127.0.0.1", sizeof(client_id.addr)); client_id.name = "127.0.0.1"; @@ -272,3982 +40,12 @@ static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx, &client_id, session_info, msg_ctx, - &binding_handle); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_printer_openkey: Could not connect to winreg pipe: %s\n", - nt_errstr(status))); - return ntstatus_to_werror(status); - } - - status = dcerpc_winreg_OpenHKLM(binding_handle, - mem_ctx, - NULL, - access_mask, - hive_handle, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n", - nt_errstr(status))); - talloc_free(binding_handle); - return ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n", - win_errstr(result))); - talloc_free(binding_handle); - return result; - } - - if (key && *key) { - keyname = talloc_asprintf(mem_ctx, "%s\\%s", path, key); - } else { - keyname = talloc_strdup(mem_ctx, path); - } - if (keyname == NULL) { - talloc_free(binding_handle); - return WERR_NOMEM; - } - - ZERO_STRUCT(wkey); - wkey.name = keyname; - - if (create_key) { - enum winreg_CreateAction action = REG_ACTION_NONE; - - ZERO_STRUCT(wkeyclass); - wkeyclass.name = ""; - - status = dcerpc_winreg_CreateKey(binding_handle, - mem_ctx, - hive_handle, - wkey, - wkeyclass, - 0, - access_mask, - NULL, - key_handle, - &action, - &result); - switch (action) { - case REG_ACTION_NONE: - DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n")); - break; - case REG_CREATED_NEW_KEY: - DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname)); - break; - case REG_OPENED_EXISTING_KEY: - DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname)); - break; - } - } else { - status = dcerpc_winreg_OpenKey(binding_handle, - mem_ctx, - hive_handle, - wkey, - 0, - access_mask, - key_handle, - &result); - } - if (!NT_STATUS_IS_OK(status)) { - talloc_free(binding_handle); - return ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - talloc_free(binding_handle); - return result; - } - - *winreg_binding_handle = binding_handle; - - return WERR_OK; -} - -/** - * @brief Create the registry keyname for the given printer. - * - * @param[in] mem_ctx The memory context to use. - * - * @param[in] printer The name of the printer to get the registry key. - * - * @return The registry key or NULL on error. - */ -static char *winreg_printer_data_keyname(TALLOC_CTX *mem_ctx, const char *printer) { - return talloc_asprintf(mem_ctx, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY, printer); -} - -/** - * @internal - * - * @brief Enumerate values of an opened key handle and retrieve the data. - * - * @param[in] mem_ctx The memory context to use. - * - * @param[in] winreg_handle The binding handle for the rpc connection. - * - * @param[in] key_hnd The opened key handle. - * - * @param[out] pnum_values A pointer to store he number of values found. - * - * @param[out] pnum_values A pointer to store the number of values we found. - * - * @return WERR_OK on success, the corresponding DOS error - * code if something gone wrong. - */ -static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx, - struct dcerpc_binding_handle *winreg_handle, - struct policy_handle *key_hnd, - uint32_t *pnum_values, - struct spoolss_PrinterEnumValues **penum_values) -{ - TALLOC_CTX *tmp_ctx; - uint32_t num_subkeys, max_subkeylen, max_classlen; - uint32_t num_values, max_valnamelen, max_valbufsize; - uint32_t secdescsize; - uint32_t i; - NTTIME last_changed_time; - struct winreg_String classname; - - struct spoolss_PrinterEnumValues *enum_values; - - WERROR result = WERR_OK; - NTSTATUS status; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - ZERO_STRUCT(classname); - - status = dcerpc_winreg_QueryInfoKey(winreg_handle, - tmp_ctx, - key_hnd, - &classname, - &num_subkeys, - &max_subkeylen, - &max_classlen, - &num_values, - &max_valnamelen, - &max_valbufsize, - &secdescsize, - &last_changed_time, - &result); + winreg_binding_handle); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n", + DEBUG(0, ("winreg_printer_binding_handle: Could not connect to winreg pipe: %s\n", nt_errstr(status))); - result = ntstatus_to_werror(status); - goto error; - } - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n", - win_errstr(result))); - goto error; - } - - if (num_values == 0) { - *pnum_values = 0; - TALLOC_FREE(tmp_ctx); - return WERR_OK; - } - - enum_values = TALLOC_ARRAY(tmp_ctx, struct spoolss_PrinterEnumValues, num_values); - if (enum_values == NULL) { - result = WERR_NOMEM; - goto error; - } - - for (i = 0; i < num_values; i++) { - struct spoolss_PrinterEnumValues val; - struct winreg_ValNameBuf name_buf; - enum winreg_Type type = REG_NONE; - uint8_t *data; - uint32_t data_size; - uint32_t length; - char n = '\0'; - - name_buf.name = &n; - name_buf.size = max_valnamelen + 2; - name_buf.length = 0; - - data_size = max_valbufsize; - data = NULL; - if (data_size) { - data = (uint8_t *) talloc_zero_size(tmp_ctx, data_size); - } - length = 0; - - status = dcerpc_winreg_EnumValue(winreg_handle, - tmp_ctx, - key_hnd, - i, - &name_buf, - &type, - data, - data_size ? &data_size : NULL, - &length, - &result); - if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) { - result = WERR_OK; - status = NT_STATUS_OK; - break; - } - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n", - nt_errstr(status))); - result = ntstatus_to_werror(status); - goto error; - } - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n", - win_errstr(result))); - goto error; - } - - if (name_buf.name == NULL) { - result = WERR_INVALID_PARAMETER; - goto error; - } - - val.value_name = talloc_strdup(enum_values, name_buf.name); - if (val.value_name == NULL) { - result = WERR_NOMEM; - goto error; - } - val.value_name_len = strlen_m_term(val.value_name) * 2; - - val.type = type; - val.data_length = length; - val.data = NULL; - if (val.data_length) { - val.data = talloc(enum_values, DATA_BLOB); - if (val.data == NULL) { - result = WERR_NOMEM; - goto error; - } - *val.data = data_blob_talloc(val.data, data, val.data_length); - } - - enum_values[i] = val; - } - - *pnum_values = num_values; - if (penum_values) { - *penum_values = talloc_move(mem_ctx, &enum_values); - } - - result = WERR_OK; - - error: - TALLOC_FREE(tmp_ctx); - return result; -} - -/** - * @internal - * - * @brief A function to delete a key and its subkeys recurively. - * - * @param[in] mem_ctx The memory context to use. - * - * @param[in] winreg_handle The binding handle for the rpc connection. - * - * @param[in] hive_handle A opened hive handle to the key. - * - * @param[in] access_mask The access mask to access the key. - * - * @param[in] key The key to delete - * - * @return WERR_OK on success, the corresponding DOS error - * code if something gone wrong. - */ -static WERROR winreg_printer_delete_subkeys(TALLOC_CTX *mem_ctx, - struct dcerpc_binding_handle *winreg_handle, - struct policy_handle *hive_handle, - uint32_t access_mask, - const char *key) -{ - const char **subkeys = NULL; - uint32_t num_subkeys = 0; - struct policy_handle key_hnd; - struct winreg_String wkey = { 0, }; - WERROR result = WERR_OK; - NTSTATUS status; - uint32_t i; - - ZERO_STRUCT(key_hnd); - wkey.name = key; - - DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key)); - /* open the key */ - status = dcerpc_winreg_OpenKey(winreg_handle, - mem_ctx, - hive_handle, - wkey, - 0, - access_mask, - &key_hnd, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n", - wkey.name, nt_errstr(status))); return ntstatus_to_werror(status); } - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n", - wkey.name, win_errstr(result))); - return result; - } - - status = dcerpc_winreg_enum_keys(mem_ctx, - winreg_handle, - &key_hnd, - &num_subkeys, - &subkeys, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - for (i = 0; i < num_subkeys; i++) { - /* create key + subkey */ - char *subkey = talloc_asprintf(mem_ctx, "%s\\%s", key, subkeys[i]); - if (subkey == NULL) { - goto done; - } - - DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey)); - result = winreg_printer_delete_subkeys(mem_ctx, - winreg_handle, - hive_handle, - access_mask, - subkey); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (is_valid_policy_hnd(&key_hnd)) { - WERROR ignore; - dcerpc_winreg_CloseKey(winreg_handle, mem_ctx, &key_hnd, &ignore); - } - - wkey.name = key; - - status = dcerpc_winreg_DeleteKey(winreg_handle, - mem_ctx, - hive_handle, - wkey, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - -done: - if (is_valid_policy_hnd(&key_hnd)) { - WERROR ignore; - - dcerpc_winreg_CloseKey(winreg_handle, mem_ctx, &key_hnd, &ignore); - } - - return result; -} - -static WERROR winreg_printer_opendriver(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *drivername, - const char *architecture, - uint32_t version, - uint32_t access_mask, - bool create, - struct dcerpc_binding_handle **winreg_binding_handle, - struct policy_handle *hive_hnd, - struct policy_handle *key_hnd) -{ - WERROR result; - char *key_name; - - key_name = talloc_asprintf(mem_ctx, "%s\\Environments\\%s\\Drivers\\Version-%u", - TOP_LEVEL_CONTROL_KEY, - architecture, version); - if (!key_name) { - return WERR_NOMEM; - } - - result = winreg_printer_openkey(mem_ctx, - session_info, - msg_ctx, - winreg_binding_handle, - key_name, - drivername, - create, - access_mask, - hive_hnd, - key_hnd); - return result; -} - -static WERROR winreg_enumval_to_dword(TALLOC_CTX *mem_ctx, - struct spoolss_PrinterEnumValues *v, - const char *valuename, uint32_t *dw) -{ - /* just return if it is not the one we are looking for */ - if (strcmp(valuename, v->value_name) != 0) { - return WERR_NOT_FOUND; - } - - if (v->type != REG_DWORD) { - return WERR_INVALID_DATATYPE; - } - - if (v->data_length != 4) { - *dw = 0; - return WERR_OK; - } - - *dw = IVAL(v->data->data, 0); - return WERR_OK; -} - -static WERROR winreg_enumval_to_sz(TALLOC_CTX *mem_ctx, - struct spoolss_PrinterEnumValues *v, - const char *valuename, const char **_str) -{ - /* just return if it is not the one we are looking for */ - if (strcmp(valuename, v->value_name) != 0) { - return WERR_NOT_FOUND; - } - - if (v->type != REG_SZ) { - return WERR_INVALID_DATATYPE; - } - - if (v->data_length == 0) { - *_str = talloc_strdup(mem_ctx, EMPTY_STRING); - if (*_str == NULL) { - return WERR_NOMEM; - } - return WERR_OK; - } - - if (!pull_reg_sz(mem_ctx, v->data, _str)) { - return WERR_NOMEM; - } - - return WERR_OK; -} - -static WERROR winreg_enumval_to_multi_sz(TALLOC_CTX *mem_ctx, - struct spoolss_PrinterEnumValues *v, - const char *valuename, - const char ***array) -{ - /* just return if it is not the one we are looking for */ - if (strcmp(valuename, v->value_name) != 0) { - return WERR_NOT_FOUND; - } - - if (v->type != REG_MULTI_SZ) { - return WERR_INVALID_DATATYPE; - } - - if (v->data_length == 0) { - *array = talloc_array(mem_ctx, const char *, 1); - if (*array == NULL) { - return WERR_NOMEM; - } - *array[0] = NULL; - return WERR_OK; - } - - if (!pull_reg_multi_sz(mem_ctx, v->data, array)) { - return WERR_NOMEM; - } - - return WERR_OK; -} - -static WERROR winreg_printer_write_date(TALLOC_CTX *mem_ctx, - struct dcerpc_binding_handle *winreg_handle, - struct policy_handle *key_handle, - const char *value, - NTTIME data) -{ - struct winreg_String wvalue = { 0, }; - DATA_BLOB blob; - WERROR result = WERR_OK; - NTSTATUS status; - const char *str; - struct tm *tm; - time_t t; - - if (data == 0) { - str = talloc_strdup(mem_ctx, "01/01/1601"); - } else { - t = nt_time_to_unix(data); - tm = localtime(&t); - if (tm == NULL) { - return map_werror_from_unix(errno); - } - str = talloc_asprintf(mem_ctx, "%02d/%02d/%04d", - tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900); - } - if (!str) { - return WERR_NOMEM; - } - - wvalue.name = value; - if (!push_reg_sz(mem_ctx, &blob, str)) { - return WERR_NOMEM; - } - status = dcerpc_winreg_SetValue(winreg_handle, - mem_ctx, - key_handle, - wvalue, - REG_SZ, - blob.data, - blob.length, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n", - wvalue.name, win_errstr(result))); - } - - return result; -} - -static WERROR winreg_printer_date_to_NTTIME(const char *str, NTTIME *data) -{ - struct tm tm; - time_t t; - - if (strequal(str, "01/01/1601")) { - *data = 0; - return WERR_OK; - } - - ZERO_STRUCT(tm); - - if (sscanf(str, "%d/%d/%d", - &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3) { - return WERR_INVALID_PARAMETER; - } - tm.tm_mon -= 1; - tm.tm_year -= 1900; - tm.tm_isdst = -1; - - t = mktime(&tm); - unix_to_nt_time(data, t); - - return WERR_OK; -} - -static WERROR winreg_printer_write_ver(TALLOC_CTX *mem_ctx, - struct dcerpc_binding_handle *winreg_handle, - struct policy_handle *key_handle, - const char *value, - uint64_t data) -{ - struct winreg_String wvalue = { 0, }; - DATA_BLOB blob; - WERROR result = WERR_OK; - NTSTATUS status; - char *str; - - /* FIXME: check format is right, - * this needs to be something like: 6.1.7600.16385 */ - str = talloc_asprintf(mem_ctx, "%u.%u.%u.%u", - (unsigned)((data >> 48) & 0xFFFF), - (unsigned)((data >> 32) & 0xFFFF), - (unsigned)((data >> 16) & 0xFFFF), - (unsigned)(data & 0xFFFF)); - if (!str) { - return WERR_NOMEM; - } - - wvalue.name = value; - if (!push_reg_sz(mem_ctx, &blob, str)) { - return WERR_NOMEM; - } - status = dcerpc_winreg_SetValue(winreg_handle, - mem_ctx, - key_handle, - wvalue, - REG_SZ, - blob.data, - blob.length, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n", - wvalue.name, win_errstr(result))); - } - - return result; -} - -static WERROR winreg_printer_ver_to_dword(const char *str, uint64_t *data) -{ - unsigned int v1, v2, v3, v4; - - if (sscanf(str, "%u.%u.%u.%u", &v1, &v2, &v3, &v4) != 4) { - return WERR_INVALID_PARAMETER; - } - - *data = ((uint64_t)(v1 & 0xFFFF) << 48) + - ((uint64_t)(v2 & 0xFFFF) << 32) + - ((uint64_t)(v3 & 0xFFFF) << 16) + - (uint64_t)(v2 & 0xFFFF); return WERR_OK; } - -/******************************************************************** - Public winreg function for spoolss -********************************************************************/ - -WERROR winreg_create_printer(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *sharename) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - struct spoolss_SetPrinterInfo2 *info2; - struct security_descriptor *secdesc; - struct winreg_String wkey, wkeyclass; - const char *path; - const char *subkeys[] = { SPOOL_DSDRIVER_KEY, SPOOL_DSSPOOLER_KEY, SPOOL_PRINTERDATA_KEY }; - uint32_t i, count = ARRAY_SIZE(subkeys); - uint32_t info2_mask = 0; - WERROR result = WERR_OK; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - 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); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - "", - false, - access_mask, - &hive_hnd, - &key_hnd); - if (W_ERROR_IS_OK(result)) { - DEBUG(2, ("winreg_create_printer: Skipping, %s already exists\n", path)); - goto done; - } else if (W_ERROR_EQUAL(result, WERR_BADFILE)) { - DEBUG(2, ("winreg_create_printer: Creating default values in %s\n", path)); - } else if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_create_printer: Could not open key %s: %s\n", - path, win_errstr(result))); - goto done; - } - - /* Create the main key */ - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - "", - true, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n", - path, win_errstr(result))); - goto done; - } - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result); - } - - /* Create subkeys */ - for (i = 0; i < count; i++) { - NTSTATUS status; - enum winreg_CreateAction action = REG_ACTION_NONE; - - ZERO_STRUCT(key_hnd); - ZERO_STRUCT(wkey); - - wkey.name = talloc_asprintf(tmp_ctx, "%s\\%s", path, subkeys[i]); - if (wkey.name == NULL) { - result = WERR_NOMEM; - goto done; - } - - ZERO_STRUCT(wkeyclass); - wkeyclass.name = ""; - - status = dcerpc_winreg_CreateKey(winreg_handle, - tmp_ctx, - &hive_hnd, - wkey, - wkeyclass, - 0, - access_mask, - NULL, - &key_hnd, - &action, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n", - wkey.name, win_errstr(result))); - goto done; - } - - if (strequal(subkeys[i], SPOOL_DSSPOOLER_KEY)) { - const char *dnssuffix; - const char *longname; - const char *uncname; - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - SPOOL_REG_PRINTERNAME, - sharename, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - SPOOL_REG_SHORTSERVERNAME, - global_myname(), - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - /* We make the assumption that the netbios name - * is the same as the DNS name since the former - * will be what we used to join the domain - */ - dnssuffix = get_mydnsdomname(tmp_ctx); - if (dnssuffix != NULL && dnssuffix[0] != '\0') { - longname = talloc_asprintf(tmp_ctx, "%s.%s", global_myname(), dnssuffix); - } else { - longname = talloc_strdup(tmp_ctx, global_myname()); - } - if (longname == NULL) { - result = WERR_NOMEM; - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - SPOOL_REG_SERVERNAME, - longname, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - uncname = talloc_asprintf(tmp_ctx, "\\\\%s\\%s", - longname, sharename); - if (uncname == NULL) { - result = WERR_NOMEM; - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - SPOOL_REG_UNCNAME, - uncname, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - SPOOL_REG_VERSIONNUMBER, - 4, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - SPOOL_REG_PRINTSTARTTIME, - 0, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - SPOOL_REG_PRINTENDTIME, - 0, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - SPOOL_REG_PRIORITY, - 1, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - SPOOL_REG_PRINTKEEPPRINTEDJOBS, - 0, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result); - } - } - info2 = talloc_zero(tmp_ctx, struct spoolss_SetPrinterInfo2); - if (info2 == NULL) { - result = WERR_NOMEM; - goto done; - } - - info2->printername = sharename; - if (info2->printername == NULL) { - result = WERR_NOMEM; - goto done; - } - info2_mask |= SPOOLSS_PRINTER_INFO_PRINTERNAME; - - info2->sharename = sharename; - info2_mask |= SPOOLSS_PRINTER_INFO_SHARENAME; - - info2->portname = SAMBA_PRINTER_PORT_NAME; - info2_mask |= SPOOLSS_PRINTER_INFO_PORTNAME; - - info2->printprocessor = "winprint"; - info2_mask |= SPOOLSS_PRINTER_INFO_PRINTPROCESSOR; - - info2->datatype = "RAW"; - info2_mask |= SPOOLSS_PRINTER_INFO_DATATYPE; - - info2->comment = ""; - info2_mask |= SPOOLSS_PRINTER_INFO_COMMENT; - - info2->attributes = PRINTER_ATTRIBUTE_SAMBA; - info2_mask |= SPOOLSS_PRINTER_INFO_ATTRIBUTES; - - info2->starttime = 0; /* Minutes since 12:00am GMT */ - info2_mask |= SPOOLSS_PRINTER_INFO_STARTTIME; - - info2->untiltime = 0; /* Minutes since 12:00am GMT */ - info2_mask |= SPOOLSS_PRINTER_INFO_UNTILTIME; - - info2->priority = 1; - info2_mask |= SPOOLSS_PRINTER_INFO_PRIORITY; - - info2->defaultpriority = 1; - info2_mask |= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY; - - result = spoolss_create_default_secdesc(tmp_ctx, &secdesc); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - info2_mask |= SPOOLSS_PRINTER_INFO_SECDESC; - - /* - * Don't write a default Device Mode to the registry! The Device Mode is - * only written to disk with a SetPrinter level 2 or 8. - */ - - result = winreg_update_printer(tmp_ctx, - session_info, - msg_ctx, - sharename, - info2_mask, - info2, - NULL, - secdesc); - -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - talloc_free(tmp_ctx); - return result; -} - -WERROR winreg_update_printer(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *sharename, - uint32_t info2_mask, - struct spoolss_SetPrinterInfo2 *info2, - struct spoolss_DeviceMode *devmode, - struct security_descriptor *secdesc) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - int snum = lp_servicenumber(sharename); - enum ndr_err_code ndr_err; - DATA_BLOB blob; - char *path; - WERROR result = WERR_OK; - NTSTATUS status; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - 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); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - "", - true, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n", - path, win_errstr(result))); - goto done; - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_ATTRIBUTES) { - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - "Attributes", - info2->attributes, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - -#if 0 - if (info2_mask & SPOOLSS_PRINTER_INFO_AVERAGEPPM) { - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - "AveragePpm", - info2->attributes, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } -#endif - - if (info2_mask & SPOOLSS_PRINTER_INFO_COMMENT) { - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Description", - info2->comment, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_DATATYPE) { - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Datatype", - info2->datatype, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY) { - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - "Default Priority", - info2->defaultpriority, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_DEVMODE) { - /* - * Some client drivers freak out if there is a NULL devmode - * (probably the driver is not checking before accessing - * the devmode pointer) --jerry - */ - if (devmode == NULL && lp_default_devmode(snum) && info2 != NULL) { - result = spoolss_create_default_devmode(tmp_ctx, - info2->printername, - &devmode); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (devmode->size != (ndr_size_spoolss_DeviceMode(devmode, 0) - devmode->__driverextra_length)) { - result = WERR_INVALID_PARAM; - goto done; - } - - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, devmode, - (ndr_push_flags_fn_t) ndr_push_spoolss_DeviceMode); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n")); - result = WERR_NOMEM; - goto done; - } - - status = dcerpc_winreg_set_binary(tmp_ctx, - winreg_handle, - &key_hnd, - "Default DevMode", - &blob, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_DRIVERNAME) { - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Printer Driver", - info2->drivername, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_LOCATION) { - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Location", - info2->location, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_PARAMETERS) { - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Parameters", - info2->parameters, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_PORTNAME) { - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Port", - info2->portname, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTERNAME) { - /* - * in addprinter: no servername and the printer is the name - * in setprinter: servername is \\server - * and printer is \\server\\printer - * - * Samba manages only local printers. - * we currently don't support things like i - * path=\\other_server\printer - * - * We only store the printername, not \\server\printername - */ - const char *p = strrchr(info2->printername, '\\'); - if (p == NULL) { - p = info2->printername; - } else { - p++; - } - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Name", - p, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTPROCESSOR) { - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Print Processor", - info2->printprocessor, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_PRIORITY) { - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - "Priority", - info2->priority, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_SECDESC) { - /* - * We need a security descriptor, if it isn't specified by - * AddPrinter{Ex} then create a default descriptor. - */ - if (secdesc == NULL) { - result = spoolss_create_default_secdesc(tmp_ctx, &secdesc); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - result = winreg_set_printer_secdesc(tmp_ctx, - session_info, - msg_ctx, - sharename, - secdesc); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_SEPFILE) { - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Separator File", - info2->sepfile, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_SHARENAME) { - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Share Name", - info2->sharename, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_STARTTIME) { - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - "StartTime", - info2->starttime, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_STATUS) { - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - "Status", - info2->status, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2_mask & SPOOLSS_PRINTER_INFO_UNTILTIME) { - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - "UntilTime", - info2->untiltime, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - "ChangeID", - winreg_printer_rev_changeid(), - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -WERROR winreg_get_printer(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - struct spoolss_PrinterInfo2 **pinfo2) -{ - struct spoolss_PrinterInfo2 *info2; - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - struct spoolss_PrinterEnumValues *enum_values = NULL; - struct spoolss_PrinterEnumValues *v = NULL; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - int snum = lp_servicenumber(printer); - uint32_t num_values = 0; - uint32_t i; - char *path; - NTSTATUS status; - WERROR result = WERR_OK; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - path = winreg_printer_data_keyname(tmp_ctx, printer); - if (path == NULL) { - TALLOC_FREE(tmp_ctx); - return WERR_NOMEM; - } - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - "", - false, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(2, ("winreg_get_printer: Could not open key %s: %s\n", - path, win_errstr(result))); - goto done; - } - - result = winreg_printer_enumvalues(tmp_ctx, - winreg_handle, - &key_hnd, - &num_values, - &enum_values); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n", - path, win_errstr(result))); - goto done; - } - - info2 = talloc_zero(tmp_ctx, struct spoolss_PrinterInfo2); - if (info2 == NULL) { - result = WERR_NOMEM; - goto done; - } - - FILL_STRING(info2, EMPTY_STRING, info2->servername); - FILL_STRING(info2, EMPTY_STRING, info2->printername); - FILL_STRING(info2, EMPTY_STRING, info2->sharename); - FILL_STRING(info2, EMPTY_STRING, info2->portname); - FILL_STRING(info2, EMPTY_STRING, info2->drivername); - FILL_STRING(info2, EMPTY_STRING, info2->comment); - FILL_STRING(info2, EMPTY_STRING, info2->location); - FILL_STRING(info2, EMPTY_STRING, info2->sepfile); - FILL_STRING(info2, EMPTY_STRING, info2->printprocessor); - FILL_STRING(info2, EMPTY_STRING, info2->datatype); - FILL_STRING(info2, EMPTY_STRING, info2->parameters); - - for (i = 0; i < num_values; i++) { - v = &enum_values[i]; - - result = winreg_enumval_to_sz(info2, - v, - "Name", - &info2->printername); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info2, - v, - "Share Name", - &info2->sharename); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info2, - v, - "Port", - &info2->portname); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info2, - v, - "Description", - &info2->comment); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info2, - v, - "Location", - &info2->location); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info2, - v, - "Separator File", - &info2->sepfile); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info2, - v, - "Print Processor", - &info2->printprocessor); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info2, - v, - "Datatype", - &info2->datatype); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info2, - v, - "Parameters", - &info2->parameters); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info2, - v, - "Printer Driver", - &info2->drivername); - CHECK_ERROR(result); - - result = winreg_enumval_to_dword(info2, - v, - "Attributes", - &info2->attributes); - CHECK_ERROR(result); - - result = winreg_enumval_to_dword(info2, - v, - "Priority", - &info2->priority); - CHECK_ERROR(result); - - result = winreg_enumval_to_dword(info2, - v, - "Default Priority", - &info2->defaultpriority); - CHECK_ERROR(result); - - result = winreg_enumval_to_dword(info2, - v, - "StartTime", - &info2->starttime); - CHECK_ERROR(result); - - result = winreg_enumval_to_dword(info2, - v, - "UntilTime", - &info2->untiltime); - CHECK_ERROR(result); - - result = winreg_enumval_to_dword(info2, - v, - "Status", - &info2->status); - CHECK_ERROR(result); - - result = winreg_enumval_to_dword(info2, - v, - "StartTime", - &info2->starttime); - CHECK_ERROR(result); - } - - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed " - "for %s: %s\n", - v->value_name, - win_errstr(result))); - goto done; - } - - /* Construct the Device Mode */ - status = dcerpc_winreg_query_binary(tmp_ctx, - winreg_handle, - &key_hnd, - "Default DevMode", - &blob, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (W_ERROR_IS_OK(result)) { - info2->devmode = talloc_zero(info2, struct spoolss_DeviceMode); - if (info2->devmode == NULL) { - result = WERR_NOMEM; - goto done; - } - ndr_err = ndr_pull_struct_blob(&blob, - info2->devmode, - info2->devmode, - (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeviceMode); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n")); - result = WERR_NOMEM; - goto done; - } - } - - if (info2->devmode == NULL && lp_default_devmode(snum)) { - result = spoolss_create_default_devmode(info2, - info2->printername, - &info2->devmode); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - } - - if (info2->devmode) { - info2->devmode->size = ndr_size_spoolss_DeviceMode(info2->devmode, 0) - info2->devmode->driverextra_data.length; - } - - result = winreg_get_printer_secdesc(info2, - session_info, - msg_ctx, - printer, - &info2->secdesc); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - /* Fix for OS/2 drivers. */ - if (get_remote_arch() == RA_OS2) { - spoolss_map_to_os2_driver(info2, &info2->drivername); - } - - if (pinfo2) { - *pinfo2 = talloc_move(mem_ctx, &info2); - } - - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *sharename, - struct spoolss_security_descriptor **psecdesc) -{ - struct spoolss_security_descriptor *secdesc; - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - const char *path; - TALLOC_CTX *tmp_ctx; - NTSTATUS status; - WERROR result; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - 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); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - "", - false, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - if (W_ERROR_EQUAL(result, WERR_BADFILE)) { - goto create_default; - } - goto done; - } - - status = dcerpc_winreg_query_sd(tmp_ctx, - winreg_handle, - &key_hnd, - "Security", - &secdesc, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - if (W_ERROR_EQUAL(result, WERR_BADFILE)) { - goto create_default; - } - goto done; - } - - if (psecdesc) { - *psecdesc = talloc_move(mem_ctx, &secdesc); - } - - result = WERR_OK; - goto done; - -create_default: - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - "", - true, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - result = spoolss_create_default_secdesc(tmp_ctx, &secdesc); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - /* If security descriptor is owned by S-1-1-0 and winbindd is up, - this security descriptor has been created when winbindd was - down. Take ownership of security descriptor. */ - if (dom_sid_equal(secdesc->owner_sid, &global_sid_World)) { - struct dom_sid owner_sid; - - /* Change sd owner to workgroup administrator */ - - if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) { - struct spoolss_security_descriptor *new_secdesc; - size_t size; - - /* Create new sd */ - sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR); - - new_secdesc = make_sec_desc(tmp_ctx, - secdesc->revision, - secdesc->type, - &owner_sid, - secdesc->group_sid, - secdesc->sacl, - secdesc->dacl, - &size); - - if (new_secdesc == NULL) { - result = WERR_NOMEM; - goto done; - } - - /* Swap with other one */ - secdesc = new_secdesc; - } - } - - status = dcerpc_winreg_set_sd(tmp_ctx, - winreg_handle, - &key_hnd, - "Security", - secdesc, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - return result; - } - - if (psecdesc) { - *psecdesc = talloc_move(mem_ctx, &secdesc); - } - - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - talloc_free(tmp_ctx); - return result; -} - -WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *sharename, - 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 dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - const char *path; - TALLOC_CTX *tmp_ctx; - NTSTATUS status; - WERROR result; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - 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 - * permissions through NT. If they are NULL in the new security - * descriptor then copy them over from the old one. - */ - if (!secdesc->owner_sid || !secdesc->group_sid) { - struct dom_sid *owner_sid, *group_sid; - struct security_acl *dacl, *sacl; - size_t size; - - result = winreg_get_printer_secdesc(tmp_ctx, - session_info, - msg_ctx, - sharename, - &old_secdesc); - if (!W_ERROR_IS_OK(result)) { - talloc_free(tmp_ctx); - return result; - } - - /* Pick out correct owner and group sids */ - owner_sid = secdesc->owner_sid ? - secdesc->owner_sid : - old_secdesc->owner_sid; - - group_sid = secdesc->group_sid ? - secdesc->group_sid : - old_secdesc->group_sid; - - dacl = secdesc->dacl ? - secdesc->dacl : - old_secdesc->dacl; - - sacl = secdesc->sacl ? - secdesc->sacl : - old_secdesc->sacl; - - /* Make a deep copy of the security descriptor */ - new_secdesc = make_sec_desc(tmp_ctx, - secdesc->revision, - secdesc->type, - owner_sid, - group_sid, - sacl, - dacl, - &size); - if (new_secdesc == NULL) { - talloc_free(tmp_ctx); - return WERR_NOMEM; - } - } - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - "", - false, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sd(tmp_ctx, - winreg_handle, - &key_hnd, - "Security", - new_secdesc, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - talloc_free(tmp_ctx); - return result; -} - -/* Set printer data over the winreg pipe. */ -WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - const char *key, - const char *value, - enum winreg_Type type, - uint8_t *data, - uint32_t data_size) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - struct winreg_String wvalue = { 0, }; - char *path; - WERROR result = WERR_OK; - NTSTATUS status; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - path = winreg_printer_data_keyname(tmp_ctx, printer); - if (path == NULL) { - TALLOC_FREE(tmp_ctx); - return WERR_NOMEM; - } - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n", - key, value, access_mask, printer)); - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - key, - true, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n", - key, win_errstr(result))); - goto done; - } - - wvalue.name = value; - status = dcerpc_winreg_SetValue(winreg_handle, - tmp_ctx, - &key_hnd, - wvalue, - type, - data, - data_size, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n", - value, nt_errstr(status))); - result = ntstatus_to_werror(status); - } - -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -/* Get printer data over a winreg pipe. */ -WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - const char *key, - const char *value, - enum winreg_Type *type, - uint8_t **data, - uint32_t *data_size) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - struct winreg_String wvalue; - enum winreg_Type type_in = REG_NONE; - char *path; - uint8_t *data_in = NULL; - uint32_t data_in_size = 0; - uint32_t value_len = 0; - WERROR result = WERR_OK; - NTSTATUS status; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - path = winreg_printer_data_keyname(tmp_ctx, printer); - if (path == NULL) { - TALLOC_FREE(tmp_ctx); - return WERR_NOMEM; - } - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - key, - false, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(2, ("winreg_get_printer_dataex: Could not open key %s: %s\n", - key, win_errstr(result))); - goto done; - } - - wvalue.name = value; - - /* - * call QueryValue once with data == NULL to get the - * needed memory size to be allocated, then allocate - * data buffer and call again. - */ - status = dcerpc_winreg_QueryValue(winreg_handle, - tmp_ctx, - &key_hnd, - &wvalue, - &type_in, - NULL, - &data_in_size, - &value_len, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n", - value, nt_errstr(status))); - result = ntstatus_to_werror(status); - goto done; - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size); - if (data_in == NULL) { - result = WERR_NOMEM; - goto done; - } - value_len = 0; - - status = dcerpc_winreg_QueryValue(winreg_handle, - tmp_ctx, - &key_hnd, - &wvalue, - &type_in, - data_in, - &data_in_size, - &value_len, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n", - value, nt_errstr(status))); - result = ntstatus_to_werror(status); - goto done; - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - *type = type_in; - *data_size = data_in_size; - if (data_in_size) { - *data = talloc_move(mem_ctx, &data_in); - } - - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -/* Enumerate on the values of a given key and provide the data. */ -WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - const char *key, - uint32_t *pnum_values, - struct spoolss_PrinterEnumValues **penum_values) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - - struct spoolss_PrinterEnumValues *enum_values = NULL; - uint32_t num_values = 0; - char *path; - WERROR result = WERR_OK; - - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - path = winreg_printer_data_keyname(tmp_ctx, printer); - if (path == NULL) { - TALLOC_FREE(tmp_ctx); - return WERR_NOMEM; - } - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - key, - false, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(2, ("winreg_enum_printer_dataex: Could not open key %s: %s\n", - key, win_errstr(result))); - goto done; - } - - result = winreg_printer_enumvalues(tmp_ctx, - winreg_handle, - &key_hnd, - &num_values, - &enum_values); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n", - key, win_errstr(result))); - goto done; - } - - *pnum_values = num_values; - if (penum_values) { - *penum_values = talloc_move(mem_ctx, &enum_values); - } - - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -/* Delete printer data over a winreg pipe. */ -WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - const char *key, - const char *value) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - struct winreg_String wvalue = { 0, }; - char *path; - WERROR result = WERR_OK; - NTSTATUS status; - - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - path = winreg_printer_data_keyname(tmp_ctx, printer); - if (path == NULL) { - TALLOC_FREE(tmp_ctx); - return WERR_NOMEM; - } - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - key, - false, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n", - key, win_errstr(result))); - goto done; - } - - wvalue.name = value; - status = dcerpc_winreg_DeleteValue(winreg_handle, - tmp_ctx, - &key_hnd, - wvalue, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n", - value, nt_errstr(status))); - result = ntstatus_to_werror(status); - } - -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -/* Enumerate on the subkeys of a given key and provide the data. */ -WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - const char *key, - uint32_t *pnum_subkeys, - const char ***psubkeys) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - char *path; - const char **subkeys = NULL; - uint32_t num_subkeys = -1; - - WERROR result = WERR_OK; - NTSTATUS status; - - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - path = winreg_printer_data_keyname(tmp_ctx, printer); - if (path == NULL) { - TALLOC_FREE(tmp_ctx); - return WERR_NOMEM; - } - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - key, - false, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(2, ("winreg_enum_printer_key: Could not open key %s: %s\n", - key, win_errstr(result))); - goto done; - } - - status = dcerpc_winreg_enum_keys(tmp_ctx, - winreg_handle, - &key_hnd, - &num_subkeys, - &subkeys, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n", - key, win_errstr(result))); - goto done; - } - - *pnum_subkeys = num_subkeys; - if (psubkeys) { - *psubkeys = talloc_move(mem_ctx, &subkeys); - } - - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -/* Delete a key with subkeys of a given printer. */ -WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - const char *key) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - char *keyname; - char *path; - WERROR result; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - path = winreg_printer_data_keyname(tmp_ctx, printer); - if (path == NULL) { - TALLOC_FREE(tmp_ctx); - return WERR_NOMEM; - } - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - key, - false, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - /* key doesn't exist */ - if (W_ERROR_EQUAL(result, WERR_BADFILE)) { - result = WERR_OK; - goto done; - } - - DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n", - key, win_errstr(result))); - goto done; - } - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result); - } - - if (key == NULL || key[0] == '\0') { - keyname = path; - } else { - keyname = talloc_asprintf(tmp_ctx, - "%s\\%s", - path, - key); - if (keyname == NULL) { - result = WERR_NOMEM; - goto done; - } - } - - result = winreg_printer_delete_subkeys(tmp_ctx, - winreg_handle, - &hive_hnd, - access_mask, - keyname); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n", - key, win_errstr(result))); - goto done; - } - -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - char *path; - NTSTATUS status; - WERROR result; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - path = winreg_printer_data_keyname(tmp_ctx, printer); - if (path == NULL) { - TALLOC_FREE(tmp_ctx); - return WERR_NOMEM; - } - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - "", - false, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_update_changeid: Could not open key %s: %s\n", - path, win_errstr(result))); - goto done; - } - - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - "ChangeID", - winreg_printer_rev_changeid(), - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - uint32_t *pchangeid) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - uint32_t changeid = 0; - char *path; - NTSTATUS status; - WERROR result; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - path = winreg_printer_data_keyname(tmp_ctx, printer); - if (path == NULL) { - TALLOC_FREE(tmp_ctx); - return WERR_NOMEM; - } - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - path, - "", - false, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(2, ("winreg_printer_get_changeid: Could not open key %s: %s\n", - path, win_errstr(result))); - goto done; - } - - DEBUG(10, ("winreg_printer_get_changeid: get changeid from %s\n", path)); - - status = dcerpc_winreg_query_dword(tmp_ctx, - winreg_handle, - &key_hnd, - "ChangeID", - &changeid, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - if (pchangeid) { - *pchangeid = changeid; - } - - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -/* - * The special behaviour of the spoolss forms is documented at the website: - * - * Managing Win32 Printserver Forms - * http://unixwiz.net/techtips/winspooler-forms.html - */ - -WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - struct spoolss_AddFormInfo1 *form) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - struct winreg_String wvalue = { 0, }; - DATA_BLOB blob; - uint32_t num_info = 0; - union spoolss_FormInfo *info = NULL; - uint32_t i; - WERROR result; - NTSTATUS status; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - TOP_LEVEL_CONTROL_FORMS_KEY, - "", - true, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n", - TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); - goto done; - } - - result = winreg_printer_enumforms1(tmp_ctx, session_info, msg_ctx, - &num_info, &info); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n", - TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); - goto done; - } - - /* If form name already exists or is builtin return ALREADY_EXISTS */ - for (i = 0; i < num_info; i++) { - if (strequal(info[i].info1.form_name, form->form_name)) { - result = WERR_FILE_EXISTS; - goto done; - } - } - - wvalue.name = form->form_name; - - blob = data_blob_talloc(tmp_ctx, NULL, 32); - SIVAL(blob.data, 0, form->size.width); - SIVAL(blob.data, 4, form->size.height); - SIVAL(blob.data, 8, form->area.left); - SIVAL(blob.data, 12, form->area.top); - SIVAL(blob.data, 16, form->area.right); - SIVAL(blob.data, 20, form->area.bottom); - SIVAL(blob.data, 24, num_info + 1); /* FIXME */ - SIVAL(blob.data, 28, form->flags); - - status = dcerpc_winreg_SetValue(winreg_handle, - tmp_ctx, - &key_hnd, - wvalue, - REG_BINARY, - blob.data, - blob.length, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n", - wvalue.name, nt_errstr(status))); - result = ntstatus_to_werror(status); - } - -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(info); - TALLOC_FREE(tmp_ctx); - return result; -} - -WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - uint32_t *pnum_info, - union spoolss_FormInfo **pinfo) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - union spoolss_FormInfo *info; - struct spoolss_PrinterEnumValues *enum_values = NULL; - uint32_t num_values = 0; - uint32_t num_builtin = ARRAY_SIZE(builtin_forms1); - uint32_t i; - WERROR result; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - TOP_LEVEL_CONTROL_FORMS_KEY, - "", - true, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - /* key doesn't exist */ - if (W_ERROR_EQUAL(result, WERR_BADFILE)) { - result = WERR_OK; - goto done; - } - - DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n", - TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); - goto done; - } - - result = winreg_printer_enumvalues(tmp_ctx, - winreg_handle, - &key_hnd, - &num_values, - &enum_values); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n", - TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); - goto done; - } - - info = TALLOC_ARRAY(tmp_ctx, union spoolss_FormInfo, num_builtin + num_values); - if (info == NULL) { - result = WERR_NOMEM; - goto done; - } - - /* Enumerate BUILTIN forms */ - for (i = 0; i < num_builtin; i++) { - info[i].info1 = builtin_forms1[i]; - } - - /* Enumerate registry forms */ - for (i = 0; i < num_values; i++) { - union spoolss_FormInfo val; - - if (enum_values[i].type != REG_BINARY || - enum_values[i].data_length != 32) { - continue; - } - - val.info1.form_name = talloc_strdup(info, enum_values[i].value_name); - if (val.info1.form_name == NULL) { - result = WERR_NOMEM; - goto done; - } - - val.info1.size.width = IVAL(enum_values[i].data->data, 0); - val.info1.size.height = IVAL(enum_values[i].data->data, 4); - val.info1.area.left = IVAL(enum_values[i].data->data, 8); - val.info1.area.top = IVAL(enum_values[i].data->data, 12); - val.info1.area.right = IVAL(enum_values[i].data->data, 16); - val.info1.area.bottom = IVAL(enum_values[i].data->data, 20); - /* skip form index IVAL(enum_values[i].data->data, 24)));*/ - val.info1.flags = (enum spoolss_FormFlags) IVAL(enum_values[i].data->data, 28); - - info[i + num_builtin] = val; - } - - *pnum_info = num_builtin + num_values; - if (pinfo) { - *pinfo = talloc_move(mem_ctx, &info); - } - -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(enum_values); - TALLOC_FREE(tmp_ctx); - return result; -} - -WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *form_name) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - struct winreg_String wvalue = { 0, }; - uint32_t num_builtin = ARRAY_SIZE(builtin_forms1); - uint32_t i; - WERROR result = WERR_OK; - NTSTATUS status; - TALLOC_CTX *tmp_ctx; - - for (i = 0; i < num_builtin; i++) { - if (strequal(builtin_forms1[i].form_name, form_name)) { - return WERR_INVALID_PARAMETER; - } - } - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - TOP_LEVEL_CONTROL_FORMS_KEY, - "", - false, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n", - TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); - if (W_ERROR_EQUAL(result, WERR_BADFILE)) { - result = WERR_INVALID_FORM_NAME; - } - goto done; - } - - wvalue.name = form_name; - status = dcerpc_winreg_DeleteValue(winreg_handle, - tmp_ctx, - &key_hnd, - wvalue, - &result); - if (!NT_STATUS_IS_OK(status)) { - /* If the value doesn't exist, return WERR_INVALID_FORM_NAME */ - DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n", - wvalue.name, nt_errstr(status))); - result = ntstatus_to_werror(status); - goto done; - } - - if (W_ERROR_EQUAL(result, WERR_BADFILE)) { - result = WERR_INVALID_FORM_NAME; - } - -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *form_name, - struct spoolss_AddFormInfo1 *form) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - struct winreg_String wvalue = { 0, }; - DATA_BLOB blob; - uint32_t num_builtin = ARRAY_SIZE(builtin_forms1); - uint32_t i; - WERROR result; - NTSTATUS status; - TALLOC_CTX *tmp_ctx = NULL; - - for (i = 0; i < num_builtin; i++) { - if (strequal(builtin_forms1[i].form_name, form->form_name)) { - result = WERR_INVALID_PARAM; - goto done; - } - } - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - TOP_LEVEL_CONTROL_FORMS_KEY, - "", - true, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n", - TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); - goto done; - } - - /* If form_name != form->form_name then we renamed the form */ - if (strequal(form_name, form->form_name)) { - result = winreg_printer_deleteform1(tmp_ctx, session_info, - msg_ctx, form_name); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n", - TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); - goto done; - } - } - - wvalue.name = form->form_name; - - blob = data_blob_talloc(tmp_ctx, NULL, 32); - SIVAL(blob.data, 0, form->size.width); - SIVAL(blob.data, 4, form->size.height); - SIVAL(blob.data, 8, form->area.left); - SIVAL(blob.data, 12, form->area.top); - SIVAL(blob.data, 16, form->area.right); - SIVAL(blob.data, 20, form->area.bottom); - SIVAL(blob.data, 24, 42); - SIVAL(blob.data, 28, form->flags); - - status = dcerpc_winreg_SetValue(winreg_handle, - tmp_ctx, - &key_hnd, - wvalue, - REG_BINARY, - blob.data, - blob.length, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n", - wvalue.name, nt_errstr(status))); - result = ntstatus_to_werror(status); - } - -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *form_name, - struct spoolss_FormInfo1 *r) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - struct winreg_String wvalue; - enum winreg_Type type_in = REG_NONE; - uint8_t *data_in = NULL; - uint32_t data_in_size = 0; - uint32_t value_len = 0; - uint32_t num_builtin = ARRAY_SIZE(builtin_forms1); - uint32_t i; - WERROR result; - NTSTATUS status; - TALLOC_CTX *tmp_ctx; - - /* check builtin forms first */ - for (i = 0; i < num_builtin; i++) { - if (strequal(builtin_forms1[i].form_name, form_name)) { - *r = builtin_forms1[i]; - return WERR_OK; - } - } - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - result = winreg_printer_openkey(tmp_ctx, - session_info, - msg_ctx, - &winreg_handle, - TOP_LEVEL_CONTROL_FORMS_KEY, - "", - true, - access_mask, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(2, ("winreg_printer_getform1: Could not open key %s: %s\n", - TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); - goto done; - } - - wvalue.name = form_name; - - /* - * call QueryValue once with data == NULL to get the - * needed memory size to be allocated, then allocate - * data buffer and call again. - */ - status = dcerpc_winreg_QueryValue(winreg_handle, - tmp_ctx, - &key_hnd, - &wvalue, - &type_in, - NULL, - &data_in_size, - &value_len, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n", - wvalue.name, nt_errstr(status))); - result = ntstatus_to_werror(status); - goto done; - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size); - if (data_in == NULL) { - result = WERR_NOMEM; - goto done; - } - value_len = 0; - - status = dcerpc_winreg_QueryValue(winreg_handle, - tmp_ctx, - &key_hnd, - &wvalue, - &type_in, - data_in, - &data_in_size, - &value_len, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n", - wvalue.name, nt_errstr(status))); - result = ntstatus_to_werror(status); - goto done; - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - r->form_name = talloc_strdup(mem_ctx, form_name); - if (r->form_name == NULL) { - result = WERR_NOMEM; - goto done; - } - - r->size.width = IVAL(data_in, 0); - r->size.height = IVAL(data_in, 4); - r->area.left = IVAL(data_in, 8); - r->area.top = IVAL(data_in, 12); - r->area.right = IVAL(data_in, 16); - r->area.bottom = IVAL(data_in, 20); - /* skip index IVAL(data_in, 24)));*/ - r->flags = (enum spoolss_FormFlags) IVAL(data_in, 28); - - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -WERROR winreg_add_driver(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - struct spoolss_AddDriverInfoCtr *r, - const char **driver_name, - uint32_t *driver_version) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - struct spoolss_DriverInfo8 info8; - TALLOC_CTX *tmp_ctx = NULL; - NTSTATUS status; - WERROR result; - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - ZERO_STRUCT(info8); - - if (!driver_info_ctr_to_info8(r, &info8)) { - result = WERR_INVALID_PARAMETER; - goto done; - } - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - result = winreg_printer_opendriver(tmp_ctx, - session_info, - msg_ctx, - info8.driver_name, - info8.architecture, - info8.version, - access_mask, true, - &winreg_handle, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_add_driver: " - "Could not open driver key (%s,%s,%d): %s\n", - info8.driver_name, info8.architecture, - info8.version, win_errstr(result))); - goto done; - } - - /* TODO: "Attributes" ? */ - - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - "Version", - info8.version, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Driver", - info8.driver_path, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Data File", - info8.data_file, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Configuration File", - info8.config_file, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Help File", - info8.help_file, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_multi_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Dependent Files", - info8.dependent_files, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Monitor", - info8.monitor_name, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Datatype", - info8.default_datatype, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_multi_sz(tmp_ctx, - winreg_handle, - &key_hnd, "Previous Names", - info8.previous_names, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - result = winreg_printer_write_date(tmp_ctx, winreg_handle, - &key_hnd, "DriverDate", - info8.driver_date); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - result = winreg_printer_write_ver(tmp_ctx, winreg_handle, - &key_hnd, "DriverVersion", - info8.driver_version); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Manufacturer", - info8.manufacturer_name, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "OEM URL", - info8.manufacturer_url, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "HardwareID", - info8.hardware_id, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Provider", - info8.provider, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Print Processor", - info8.print_processor, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "VendorSetup", - info8.vendor_setup, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_multi_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "Color Profiles", - info8.color_profiles, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "InfPath", - info8.inf_path, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_dword(tmp_ctx, - winreg_handle, - &key_hnd, - "PrinterDriverAttributes", - info8.printer_driver_attributes, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - status = dcerpc_winreg_set_multi_sz(tmp_ctx, - winreg_handle, - &key_hnd, - "CoreDependencies", - info8.core_driver_dependencies, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - result = winreg_printer_write_date(tmp_ctx, winreg_handle, - &key_hnd, "MinInboxDriverVerDate", - info8.min_inbox_driver_ver_date); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - result = winreg_printer_write_ver(tmp_ctx, winreg_handle, &key_hnd, - "MinInboxDriverVerVersion", - info8.min_inbox_driver_ver_version); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - *driver_name = info8.driver_name; - *driver_version = info8.version; - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -WERROR winreg_get_driver(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *architecture, - const char *driver_name, - uint32_t driver_version, - struct spoolss_DriverInfo8 **_info8) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - struct spoolss_DriverInfo8 i8, *info8; - struct spoolss_PrinterEnumValues *enum_values = NULL; - struct spoolss_PrinterEnumValues *v; - uint32_t num_values = 0; - TALLOC_CTX *tmp_ctx; - WERROR result; - uint32_t i; - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - ZERO_STRUCT(i8); - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - if (driver_version == DRIVER_ANY_VERSION) { - /* look for Win2k first and then for NT4 */ - result = winreg_printer_opendriver(tmp_ctx, - session_info, - msg_ctx, - driver_name, - architecture, - 3, - access_mask, false, - &winreg_handle, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - result = winreg_printer_opendriver(tmp_ctx, - session_info, - msg_ctx, - driver_name, - architecture, - 2, - access_mask, false, - &winreg_handle, - &hive_hnd, - &key_hnd); - } - } else { - /* ok normal case */ - result = winreg_printer_opendriver(tmp_ctx, - session_info, - msg_ctx, - driver_name, - architecture, - driver_version, - access_mask, false, - &winreg_handle, - &hive_hnd, - &key_hnd); - } - if (!W_ERROR_IS_OK(result)) { - DEBUG(5, ("winreg_get_driver: " - "Could not open driver key (%s,%s,%d): %s\n", - driver_name, architecture, - driver_version, win_errstr(result))); - goto done; - } - - result = winreg_printer_enumvalues(tmp_ctx, - winreg_handle, - &key_hnd, - &num_values, - &enum_values); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_get_driver: " - "Could not enumerate values for (%s,%s,%d): %s\n", - driver_name, architecture, - driver_version, win_errstr(result))); - goto done; - } - - info8 = talloc_zero(tmp_ctx, struct spoolss_DriverInfo8); - if (info8 == NULL) { - result = WERR_NOMEM; - goto done; - } - - info8->driver_name = talloc_strdup(info8, driver_name); - if (info8->driver_name == NULL) { - result = WERR_NOMEM; - goto done; - } - - info8->architecture = talloc_strdup(info8, architecture); - if (info8->architecture == NULL) { - result = WERR_NOMEM; - goto done; - } - - result = WERR_OK; - - for (i = 0; i < num_values; i++) { - const char *tmp_str; - uint32_t tmp = 0; - - v = &enum_values[i]; - - result = winreg_enumval_to_dword(info8, v, - "Version", - &tmp); - if (NT_STATUS_IS_OK(result)) { - info8->version = (enum spoolss_DriverOSVersion) tmp; - } - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "Driver", - &info8->driver_path); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "Data File", - &info8->data_file); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "Configuration File", - &info8->config_file); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "Help File", - &info8->help_file); - CHECK_ERROR(result); - - result = winreg_enumval_to_multi_sz(info8, v, - "Dependent Files", - &info8->dependent_files); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "Monitor", - &info8->monitor_name); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "Datatype", - &info8->default_datatype); - CHECK_ERROR(result); - - result = winreg_enumval_to_multi_sz(info8, v, - "Previous Names", - &info8->previous_names); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "DriverDate", - &tmp_str); - if (W_ERROR_IS_OK(result)) { - result = winreg_printer_date_to_NTTIME(tmp_str, - &info8->driver_date); - } - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "DriverVersion", - &tmp_str); - if (W_ERROR_IS_OK(result)) { - result = winreg_printer_ver_to_dword(tmp_str, - &info8->driver_version); - } - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "Manufacturer", - &info8->manufacturer_name); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "OEM URL", - &info8->manufacturer_url); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "HardwareID", - &info8->hardware_id); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "Provider", - &info8->provider); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "Print Processor", - &info8->print_processor); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "VendorSetup", - &info8->vendor_setup); - CHECK_ERROR(result); - - result = winreg_enumval_to_multi_sz(info8, v, - "Color Profiles", - &info8->color_profiles); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "InfPath", - &info8->inf_path); - CHECK_ERROR(result); - - result = winreg_enumval_to_dword(info8, v, - "PrinterDriverAttributes", - &info8->printer_driver_attributes); - CHECK_ERROR(result); - - result = winreg_enumval_to_multi_sz(info8, v, - "CoreDependencies", - &info8->core_driver_dependencies); - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "MinInboxDriverVerDate", - &tmp_str); - if (W_ERROR_IS_OK(result)) { - result = winreg_printer_date_to_NTTIME(tmp_str, - &info8->min_inbox_driver_ver_date); - } - CHECK_ERROR(result); - - result = winreg_enumval_to_sz(info8, v, - "MinInboxDriverVerVersion", - &tmp_str); - if (W_ERROR_IS_OK(result)) { - result = winreg_printer_ver_to_dword(tmp_str, - &info8->min_inbox_driver_ver_version); - } - CHECK_ERROR(result); - } - - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_enumval_to_TYPE() failed " - "for %s: %s\n", v->value_name, - win_errstr(result))); - goto done; - } - - *_info8 = talloc_steal(mem_ctx, info8); - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -WERROR winreg_del_driver(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - struct spoolss_DriverInfo8 *info8, - uint32_t version) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - TALLOC_CTX *tmp_ctx; - char *key_name; - WERROR result; - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - /* test that the key exists */ - result = winreg_printer_opendriver(tmp_ctx, - session_info, - msg_ctx, - info8->driver_name, - info8->architecture, - version, - access_mask, false, - &winreg_handle, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - /* key doesn't exist */ - if (W_ERROR_EQUAL(result, WERR_BADFILE)) { - result = WERR_OK; - goto done; - } - - DEBUG(5, ("winreg_del_driver: " - "Could not open driver (%s,%s,%u): %s\n", - info8->driver_name, info8->architecture, - version, win_errstr(result))); - goto done; - } - - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result); - } - - key_name = talloc_asprintf(tmp_ctx, - "%s\\Environments\\%s\\Drivers\\Version-%u\\%s", - TOP_LEVEL_CONTROL_KEY, - info8->architecture, version, - info8->driver_name); - if (key_name == NULL) { - result = WERR_NOMEM; - goto done; - } - - result = winreg_printer_delete_subkeys(tmp_ctx, - winreg_handle, - &hive_hnd, - access_mask, - key_name); - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_del_driver: " - "Could not open driver (%s,%s,%u): %s\n", - info8->driver_name, info8->architecture, - version, win_errstr(result))); - goto done; - } - - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} - -WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *architecture, - uint32_t version, - uint32_t *num_drivers, - const char ***drivers_p) -{ - uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - struct dcerpc_binding_handle *winreg_handle = NULL; - struct policy_handle hive_hnd, key_hnd; - const char **drivers; - TALLOC_CTX *tmp_ctx; - WERROR result; - NTSTATUS status; - - *num_drivers = 0; - *drivers_p = NULL; - - ZERO_STRUCT(hive_hnd); - ZERO_STRUCT(key_hnd); - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return WERR_NOMEM; - } - - /* use NULL for the driver name so we open the key that is - * parent of all drivers for this architecture and version */ - result = winreg_printer_opendriver(tmp_ctx, - session_info, - msg_ctx, - NULL, - architecture, - version, - access_mask, false, - &winreg_handle, - &hive_hnd, - &key_hnd); - if (!W_ERROR_IS_OK(result)) { - DEBUG(5, ("winreg_get_driver_list: " - "Could not open key (%s,%u): %s\n", - architecture, version, win_errstr(result))); - result = WERR_OK; - goto done; - } - - status = dcerpc_winreg_enum_keys(tmp_ctx, - winreg_handle, - &key_hnd, - num_drivers, - &drivers, - &result); - if (!NT_STATUS_IS_OK(status)) { - result = ntstatus_to_werror(status); - } - if (!W_ERROR_IS_OK(result)) { - DEBUG(0, ("winreg_get_driver_list: " - "Could not enumerate drivers for (%s,%u): %s\n", - architecture, version, win_errstr(result))); - goto done; - } - - *drivers_p = talloc_steal(mem_ctx, drivers); - - result = WERR_OK; -done: - if (winreg_handle != NULL) { - WERROR ignore; - - if (is_valid_policy_hnd(&key_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); - } - if (is_valid_policy_hnd(&hive_hnd)) { - dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); - } - } - - TALLOC_FREE(tmp_ctx); - return result; -} diff --git a/source3/rpc_server/spoolss/srv_spoolss_util.h b/source3/rpc_server/spoolss/srv_spoolss_util.h index 49a46ee..2b236af 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_util.h +++ b/source3/rpc_server/spoolss/srv_spoolss_util.h @@ -23,569 +23,11 @@ #define _SRV_SPOOLSS_UITL_H struct auth_serversupplied_info; +struct dcerpc_binding_handle; -enum spoolss_PrinterInfo2Mask { - SPOOLSS_PRINTER_INFO_ATTRIBUTES = (int)(0x00000001), - SPOOLSS_PRINTER_INFO_AVERAGEPPM = (int)(0x00000002), - SPOOLSS_PRINTER_INFO_CJOBS = (int)(0x00000004), - SPOOLSS_PRINTER_INFO_COMMENT = (int)(0x00000008), - SPOOLSS_PRINTER_INFO_DATATYPE = (int)(0x00000010), - SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY = (int)(0x00000020), - SPOOLSS_PRINTER_INFO_DEVMODE = (int)(0x00000040), - SPOOLSS_PRINTER_INFO_DRIVERNAME = (int)(0x00000080), - SPOOLSS_PRINTER_INFO_LOCATION = (int)(0x00000100), - SPOOLSS_PRINTER_INFO_NAME = (int)(0x00000200), - SPOOLSS_PRINTER_INFO_PARAMETERS = (int)(0x00000400), - SPOOLSS_PRINTER_INFO_PORTNAME = (int)(0x00000800), - SPOOLSS_PRINTER_INFO_PRINTERNAME = (int)(0x00001000), - SPOOLSS_PRINTER_INFO_PRINTPROCESSOR = (int)(0x00002000), - SPOOLSS_PRINTER_INFO_PRIORITY = (int)(0x00004000), - SPOOLSS_PRINTER_INFO_SECDESC = (int)(0x00008000), - SPOOLSS_PRINTER_INFO_SEPFILE = (int)(0x00010000), - SPOOLSS_PRINTER_INFO_SERVERNAME = (int)(0x00020000), - SPOOLSS_PRINTER_INFO_SHARENAME = (int)(0x00040000), - SPOOLSS_PRINTER_INFO_STARTTIME = (int)(0x00080000), - SPOOLSS_PRINTER_INFO_STATUS = (int)(0x00100000), - SPOOLSS_PRINTER_INFO_UNTILTIME = (int)(0x00200000) -}; - -#define SPOOLSS_PRINTER_INFO_ALL SPOOLSS_PRINTER_INFO_ATTRIBUTES | \ - SPOOLSS_PRINTER_INFO_AVERAGEPPM | \ - SPOOLSS_PRINTER_INFO_CJOBS | \ - SPOOLSS_PRINTER_INFO_COMMENT | \ - SPOOLSS_PRINTER_INFO_DATATYPE | \ - SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY | \ - SPOOLSS_PRINTER_INFO_DEVMODE | \ - SPOOLSS_PRINTER_INFO_DRIVERNAME | \ - SPOOLSS_PRINTER_INFO_LOCATION | \ - SPOOLSS_PRINTER_INFO_NAME | \ - SPOOLSS_PRINTER_INFO_PARAMETERS | \ - SPOOLSS_PRINTER_INFO_PORTNAME | \ - SPOOLSS_PRINTER_INFO_PRINTERNAME | \ - SPOOLSS_PRINTER_INFO_PRINTPROCESSOR | \ - SPOOLSS_PRINTER_INFO_PRIORITY | \ - SPOOLSS_PRINTER_INFO_SECDESC | \ - SPOOLSS_PRINTER_INFO_SEPFILE | \ - SPOOLSS_PRINTER_INFO_SERVERNAME | \ - SPOOLSS_PRINTER_INFO_SHARENAME | \ - SPOOLSS_PRINTER_INFO_STARTTIME | \ - SPOOLSS_PRINTER_INFO_STATUS | \ - SPOOLSS_PRINTER_INFO_UNTILTIME - -WERROR winreg_create_printer(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *sharename); - -/** - * @internal - * - * @brief Update the information of a printer in the registry. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] sharename The share name. - * - * @param[in] info2_mask A bitmask which defines which values should be set. - * - * @param[in] info2 A SetPrinterInfo2 structure with the data to set. - * - * @param[in] devmode A device mode structure with the data to set. - * - * @param[in] secdesc A security descriptor structure with the data to set. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ -WERROR winreg_update_printer(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *sharename, - uint32_t info2_mask, - struct spoolss_SetPrinterInfo2 *info2, - struct spoolss_DeviceMode *devmode, - struct security_descriptor *secdesc); - - -/** - * @brief Get the inforamtion of a printer stored in the registry. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] printer The name of the printer to get. - * - * @param[out] pinfo2 A pointer to store a PRINTER_INFO_2 structure. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ -WERROR winreg_get_printer(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - struct spoolss_PrinterInfo2 **pinfo2); - -/** - * @brief Get the security descriptor for a printer. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] sharename The share name. - * - * @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_printer_secdesc(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *sharename, - struct spoolss_security_descriptor **psecdesc); - -/** - * @brief Set the security descriptor for a printer. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] sharename The share name. - * - * @param[in] secdesc The security descriptor to save. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ -WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *sharename, - const struct spoolss_security_descriptor *secdesc); - -/** - * @internal - * - * @brief Set printer data over the winreg pipe. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] printer The printer name. - * - * @param[in] key The key of the printer data to store the value. - * - * @param[in] value The value name to save. - * - * @param[in] type The type of the value to use. - * - * @param[in] data The data which sould be saved under the given value. - * - * @param[in] data_size The size of the data. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ -WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - const char *key, - const char *value, - enum winreg_Type type, - uint8_t *data, - uint32_t data_size); - -/** - * @internal - * - * @brief Get printer data over a winreg pipe. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] printer The printer name. - * - * @param[in] key The key of the printer data to get the value. - * - * @param[in] value The name of the value to query. - * - * @param[in] type The type of the value to query. - * - * @param[out] data A pointer to store the data. - * - * @param[out] data_size A pointer to store the size of the data. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ -WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - const char *key, - const char *value, - enum winreg_Type *type, - uint8_t **data, - uint32_t *data_size); - -/** - * @internal - * - * @brief Enumerate on the values of a given key and provide the data. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] printer The printer name. - * - * @param[in] key The key of the printer data to get the value. - * - * @param[out] pnum_values A pointer to store the number of values we found. - * - * @param[out] penum_values A pointer to store the values and its data. - * - * @return WERR_OK on success, the corresponding DOS error - * code if something gone wrong. - */ -WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - const char *key, - uint32_t *pnum_values, - struct spoolss_PrinterEnumValues **penum_values); - -/** - * @internal - * - * @brief Delete printer data over a winreg pipe. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] printer The printer name. - * - * @param[in] key The key of the printer data to delete. - * - * @param[in] value The name of the value to delete. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ -WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - const char *key, - const char *value); - -/** - * @internal - * - * @brief Enumerate on the subkeys of a given key and provide the data. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] printer The printer name. - * - * @param[in] key The key of the printer data to get the value. - * - * @param[out] pnum_subkeys A pointer to store the number of subkeys found. - * - * @param[in] psubkeys A pointer to an array to store the names of the subkeys - * found. - * - * @return WERR_OK on success, the corresponding DOS error - * code if something gone wrong. - */ -WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - const char *key, - uint32_t *pnum_subkeys, - const char ***psubkeys); - -/** - * @internal - * - * @brief Delete a key with subkeys of a given printer. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] printer The printer name. - * - * @param[in] key The key of the printer to delete. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ -WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - const char *key); - -/** - * @brief Update the ChangeID of a printer. - * - * The ChangeID **must** be increasing over the lifetime of client's spoolss - * service in order for the client's cache to show updates. - * - * If a form is updated of a printer, the we need to update the ChangeID of the - * pritner. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] printer The printer name. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ -WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer); - -/** - * @brief Get the ChangeID of the given printer. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] printer The printer name. - * - * @param[in] changeid A pointer to store the changeid. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ -WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *printer, - uint32_t *pchangeid); - -/** - * @internal - * - * @brief This function adds a form to the list of available forms that can be - * selected for the specified printer. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] form The form to add. - * - * @return WERR_OK on success. - * WERR_ALREADY_EXISTS if the form already exists or is a - * builtin form. - * A corresponding DOS error is something went wrong. - */ -WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - struct spoolss_AddFormInfo1 *form); - -/* - * @brief This function enumerates the forms supported by the specified printer. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[out] pnum_info A pointer to store the FormInfo count. - * - * @param[out] pinfo A pointer to store an array with FormInfo. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ -WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - uint32_t *pnum_info, - union spoolss_FormInfo **pinfo); - -/** - * @brief This function removes a form name from the list of supported forms. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] form_name The name of the form to delete. - * - * @return WERR_OK on success. - * WERR_INVALID_PARAM if the form is a builtin form. - * WERR_INVALID_FORM_NAME if the form or key doesn't exist. - * A corresponding DOS error is something went wrong. - */ -WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *form_name); - -/** - * @brief This function sets the form information for the specified printer. - * - * If one provides both the name in the API call and inside the FormInfo - * structure, then the form gets renamed. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] form_name The name of the form to set or rename. - * - * @param[in] form The FormInfo structure to save. - * - * @return WERR_OK on success. - * WERR_INVALID_PARAM if the form is a builtin form. - * A corresponding DOS error is something went wrong. - */ -WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *form_name, - struct spoolss_AddFormInfo1 *form); - -/** - * @brief This function retrieves information about a specified form. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] session_info The server supplied session info. - * - * @param[in] form_name The name of the form to query. - * - * @param[out] form A pointer to a form structure to fill out. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ -WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *form_name, - struct spoolss_FormInfo1 *form); - -/** - * @brief This function adds a new spool driver - * - * @param[in] mem_ctx A talloc memory context. - * - * @param[in] session_info Auth info to open the pipe. - * - * @param[in] r The structure containing the new driver data. - * - * @param[out] driver_name Returns the driver name. - * - * @param[out] driver_version Returns the driver version. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ -WERROR winreg_add_driver(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - struct spoolss_AddDriverInfoCtr *r, - const char **driver_name, - uint32_t *driver_version); - -/** - * @brief This function gets printer driver information - * - * @param[in] mem_ctx A talloc memory context. - * - * @param[in] session_info Auth info to open the pipe. - * - * @param[in] architecture The architecture type. - * - * @param[in] driver_name The driver name. - * - * @param[in] driver_version The driver version. - * - * @param[out] _info8 The structure that holds the full driver information. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ - -WERROR winreg_get_driver(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *architecture, - const char *driver_name, - uint32_t driver_version, - struct spoolss_DriverInfo8 **_info8); - -/** - * @brief This function deletes a printer driver information - * - * @param[in] mem_ctx A talloc memory context. - * - * @param[in] session_info Auth info to open the pipe. - * - * @param[out] info8 The structure that holds the full driver information. - * - * @param[in] version The driver type version. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ - -WERROR winreg_del_driver(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - struct spoolss_DriverInfo8 *info8, - uint32_t version); - -/** - * @brief This function gets printer drivers list for the specified - * architecture and type version - * - * @param[in] mem_ctx A talloc memory context. - * - * @param[in] session_info Auth info to open the pipe. - * - * @param[in] architecture The architecture type. - * - * @param[in] version The driver version. - * - * @param[out] num_drivers The number of drivers. - * - * @param[out] version The drivers names. - * - * @return On success WERR_OK, a corresponding DOS error is - * something went wrong. - */ - -WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx, - const struct auth_serversupplied_info *session_info, - struct messaging_context *msg_ctx, - const char *architecture, - uint32_t version, - uint32_t *num_drivers, - const char ***drivers); +WERROR winreg_printer_binding_handle(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + struct dcerpc_binding_handle **winreg_binding_handle); #endif /* _SRV_SPOOLSS_UITL_H */ -- 1.7.6 From 10aa94c629058651ede70756414706fcfe293853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 5 Jul 2011 00:16:47 +0200 Subject: [PATCH 13/21] s3-printing: add winreg_internal functions. Guenther Pair-Programmed-With: David Disseldorp (cherry picked from commit ada5380d2090179fc57eee66e2b46788f4944db0) Conflicts: source3/rpc_server/spoolss/srv_spoolss_nt.c source3/rpc_server/spoolss/srv_spoolss_util.c --- source3/printing/nt_printing_ads.c | 1 + source3/rpc_server/spoolss/srv_spoolss_nt.c | 1 + source3/rpc_server/spoolss/srv_spoolss_util.c | 413 ++++++++++++++++++++++++- source3/rpc_server/spoolss/srv_spoolss_util.h | 127 ++++++++ 4 files changed, 541 insertions(+), 1 deletions(-) diff --git a/source3/printing/nt_printing_ads.c b/source3/printing/nt_printing_ads.c index 1ab1b0e..e47ba23 100644 --- a/source3/printing/nt_printing_ads.c +++ b/source3/printing/nt_printing_ads.c @@ -29,6 +29,7 @@ #include "../libcli/registry/util_reg.h" #include "auth.h" #include "../librpc/ndr/libndr.h" +#include "rpc_client/cli_winreg_spoolss.h" #ifdef HAVE_ADS /***************************************************************** diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index 99bf56c..8a4f17d 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -53,6 +53,7 @@ #include "util_tdb.h" #include "libsmb/libsmb.h" #include "printing/printer_list.h" +#include "rpc_client/cli_winreg_spoolss.h" /* macros stolen from s4 spoolss server */ #define SPOOLSS_BUFFER_UNION(fn,info,level) \ diff --git a/source3/rpc_server/spoolss/srv_spoolss_util.c b/source3/rpc_server/spoolss/srv_spoolss_util.c index 0d2b6d7..328e170 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_util.c +++ b/source3/rpc_server/spoolss/srv_spoolss_util.c @@ -21,8 +21,10 @@ #include "includes.h" #include "rpc_server/rpc_ncacn_np.h" -#include "srv_spoolss_util.h" +#include "../librpc/gen_ndr/ndr_spoolss.h" #include "../librpc/gen_ndr/ndr_winreg.h" +#include "srv_spoolss_util.h" +#include "rpc_client/cli_winreg_spoolss.h" WERROR winreg_printer_binding_handle(TALLOC_CTX *mem_ctx, const struct auth_serversupplied_info *session_info, @@ -49,3 +51,412 @@ WERROR winreg_printer_binding_handle(TALLOC_CTX *mem_ctx, return WERR_OK; } + +WERROR winreg_delete_printer_key_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + const char *key) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_delete_printer_key(mem_ctx, b, + printer, + key); +} + +WERROR winreg_printer_update_changeid_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_printer_update_changeid(mem_ctx, b, + printer); +} + +WERROR winreg_printer_get_changeid_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + uint32_t *pchangeid) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_printer_get_changeid(mem_ctx, b, + printer, + pchangeid); +} + +WERROR winreg_get_printer_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + struct spoolss_PrinterInfo2 **pinfo2) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_get_printer(mem_ctx, b, + printer, + pinfo2); + +} + +WERROR winreg_create_printer_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *sharename) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_create_printer(mem_ctx, b, + sharename); +} + +WERROR winreg_update_printer_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *sharename, + uint32_t info2_mask, + struct spoolss_SetPrinterInfo2 *info2, + struct spoolss_DeviceMode *devmode, + struct security_descriptor *secdesc) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_update_printer(mem_ctx, b, + sharename, + info2_mask, + info2, + devmode, + secdesc); +} + +WERROR winreg_set_printer_dataex_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + const char *key, + const char *value, + enum winreg_Type type, + uint8_t *data, + uint32_t data_size) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_set_printer_dataex(mem_ctx, b, + printer, + key, + value, + type, + data, + data_size); +} + +WERROR winreg_enum_printer_dataex_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + const char *key, + uint32_t *pnum_values, + struct spoolss_PrinterEnumValues **penum_values) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_enum_printer_dataex(mem_ctx, b, + printer, + key, + pnum_values, + penum_values); +} + +WERROR winreg_get_printer_dataex_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + const char *key, + const char *value, + enum winreg_Type *type, + uint8_t **data, + uint32_t *data_size) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_get_printer_dataex(mem_ctx, b, + printer, + key, + value, + type, + data, + data_size); +} + +WERROR winreg_delete_printer_dataex_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + const char *key, + const char *value) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_delete_printer_dataex(mem_ctx, b, + printer, + key, + value); +} + +WERROR winreg_get_driver_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *architecture, + const char *driver_name, + uint32_t driver_version, + struct spoolss_DriverInfo8 **_info8) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_get_driver(mem_ctx, b, + architecture, + driver_name, + driver_version, + _info8); +} + +WERROR winreg_get_driver_list_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *architecture, + uint32_t version, + uint32_t *num_drivers, + const char ***drivers_p) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_get_driver_list(mem_ctx, b, + architecture, + version, + num_drivers, + drivers_p); +} + +WERROR winreg_del_driver_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + struct spoolss_DriverInfo8 *info8, + uint32_t version) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_del_driver(mem_ctx, b, + info8, + version); +} + +WERROR winreg_add_driver_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + struct spoolss_AddDriverInfoCtr *r, + const char **driver_name, + uint32_t *driver_version) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_add_driver(mem_ctx, b, + r, + driver_name, + driver_version); +} + +WERROR winreg_get_printer_secdesc_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *sharename, + struct spoolss_security_descriptor **psecdesc) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_get_printer_secdesc(mem_ctx, b, + sharename, + psecdesc); +} + +WERROR winreg_set_printer_secdesc_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *sharename, + const struct spoolss_security_descriptor *secdesc) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_set_printer_secdesc(mem_ctx, b, + sharename, + secdesc); +} + +WERROR winreg_printer_enumforms1_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + uint32_t *pnum_info, + union spoolss_FormInfo **pinfo) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_printer_enumforms1(mem_ctx, b, + pnum_info, + pinfo); +} + +WERROR winreg_printer_getform1_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *form_name, + struct spoolss_FormInfo1 *r) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_printer_getform1(mem_ctx, b, + form_name, + r); +} + +WERROR winreg_printer_addform1_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + struct spoolss_AddFormInfo1 *form) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_printer_addform1(mem_ctx, b, + form); +} + +WERROR winreg_printer_setform1_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *form_name, + struct spoolss_AddFormInfo1 *form) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_printer_setform1(mem_ctx, b, + form_name, + form); +} + +WERROR winreg_printer_deleteform1_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *form_name) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_printer_deleteform1(mem_ctx, b, + form_name); +} + +WERROR winreg_enum_printer_key_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + const char *key, + uint32_t *pnum_subkeys, + const char ***psubkeys) +{ + WERROR result; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); + W_ERROR_NOT_OK_RETURN(result); + + return winreg_enum_printer_key(mem_ctx, b, + printer, + key, + pnum_subkeys, + psubkeys); +} diff --git a/source3/rpc_server/spoolss/srv_spoolss_util.h b/source3/rpc_server/spoolss/srv_spoolss_util.h index 2b236af..2ae3a60 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_util.h +++ b/source3/rpc_server/spoolss/srv_spoolss_util.h @@ -30,4 +30,131 @@ WERROR winreg_printer_binding_handle(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx, struct dcerpc_binding_handle **winreg_binding_handle); +WERROR winreg_delete_printer_key_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + const char *key); +WERROR winreg_printer_update_changeid_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer); +WERROR winreg_printer_get_changeid_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + uint32_t *pchangeid); +WERROR winreg_get_printer_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + struct spoolss_PrinterInfo2 **pinfo2); +WERROR winreg_create_printer_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *sharename); +WERROR winreg_update_printer_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *sharename, + uint32_t info2_mask, + struct spoolss_SetPrinterInfo2 *info2, + struct spoolss_DeviceMode *devmode, + struct security_descriptor *secdesc); +WERROR winreg_set_printer_dataex_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + const char *key, + const char *value, + enum winreg_Type type, + uint8_t *data, + uint32_t data_size); +WERROR winreg_enum_printer_dataex_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + const char *key, + uint32_t *pnum_values, + struct spoolss_PrinterEnumValues **penum_values); +WERROR winreg_get_printer_dataex_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + const char *key, + const char *value, + enum winreg_Type *type, + uint8_t **data, + uint32_t *data_size); +WERROR winreg_delete_printer_dataex_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + const char *key, + const char *value); +WERROR winreg_get_driver_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *architecture, + const char *driver_name, + uint32_t driver_version, + struct spoolss_DriverInfo8 **_info8); +WERROR winreg_get_driver_list_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *architecture, + uint32_t version, + uint32_t *num_drivers, + const char ***drivers_p); +WERROR winreg_del_driver_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + struct spoolss_DriverInfo8 *info8, + uint32_t version); +WERROR winreg_add_driver_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + struct spoolss_AddDriverInfoCtr *r, + const char **driver_name, + uint32_t *driver_version); +WERROR winreg_get_printer_secdesc_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *sharename, + struct spoolss_security_descriptor **psecdesc); +WERROR winreg_set_printer_secdesc_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *sharename, + const struct spoolss_security_descriptor *secdesc); +WERROR winreg_printer_enumforms1_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + uint32_t *pnum_info, + union spoolss_FormInfo **pinfo); +WERROR winreg_printer_getform1_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *form_name, + struct spoolss_FormInfo1 *r); +WERROR winreg_printer_addform1_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + struct spoolss_AddFormInfo1 *form); +WERROR winreg_printer_setform1_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *form_name, + struct spoolss_AddFormInfo1 *form); +WERROR winreg_printer_deleteform1_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *form_name); +WERROR winreg_enum_printer_key_internal(TALLOC_CTX *mem_ctx, + const struct auth_serversupplied_info *session_info, + struct messaging_context *msg_ctx, + const char *printer, + const char *key, + uint32_t *pnum_subkeys, + const char ***psubkeys); #endif /* _SRV_SPOOLSS_UITL_H */ -- 1.7.6 From cd22d74fa70848613f9921aeb28776e7c6349d41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 5 Jul 2011 00:16:03 +0200 Subject: [PATCH 14/21] s3-printing: use winreg_internal functions. Guenther Pair-Programmed-With: David Disseldorp (cherry picked from commit 0a1ec73b965f66977a90fb7febb3b56b52ebab20) Conflicts: source3/rpc_server/spoolss/srv_spoolss_nt.c --- source3/printing/nt_printing.c | 18 ++-- source3/printing/nt_printing_ads.c | 10 +- source3/rpc_server/spoolss/srv_spoolss_nt.c | 146 +++++++++++++------------- 3 files changed, 87 insertions(+), 87 deletions(-) diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 782a626..40d5fc1 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1196,7 +1196,7 @@ bool printer_driver_in_use(TALLOC_CTX *mem_ctx, continue; } - result = winreg_get_printer(mem_ctx, session_info, msg_ctx, + result = winreg_get_printer_internal(mem_ctx, session_info, msg_ctx, lp_servicename(snum), &pinfo2); if (!W_ERROR_IS_OK(result)) { @@ -1222,18 +1222,18 @@ bool printer_driver_in_use(TALLOC_CTX *mem_ctx, "Windows NT x86" version 2 or 3 left */ if (!strequal("Windows NT x86", r->architecture)) { - werr = winreg_get_driver(mem_ctx, session_info, msg_ctx, + werr = winreg_get_driver_internal(mem_ctx, session_info, msg_ctx, "Windows NT x86", r->driver_name, DRIVER_ANY_VERSION, &driver); } else if (r->version == 2) { - werr = winreg_get_driver(mem_ctx, session_info, msg_ctx, + werr = winreg_get_driver_internal(mem_ctx, session_info, msg_ctx, "Windows NT x86", r->driver_name, 3, &driver); } else if (r->version == 3) { - werr = winreg_get_driver(mem_ctx, session_info, msg_ctx, + werr = winreg_get_driver_internal(mem_ctx, session_info, msg_ctx, "Windows NT x86", r->driver_name, 2, &driver); @@ -1424,7 +1424,7 @@ bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx, /* get the list of drivers */ - result = winreg_get_driver_list(mem_ctx, session_info, msg_ctx, + result = winreg_get_driver_list_internal(mem_ctx, session_info, msg_ctx, info->architecture, version, &num_drivers, &drivers); if (!W_ERROR_IS_OK(result)) { @@ -1441,7 +1441,7 @@ bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx, driver = NULL; - result = winreg_get_driver(mem_ctx, session_info, msg_ctx, + result = winreg_get_driver_internal(mem_ctx, session_info, msg_ctx, info->architecture, drivers[i], version, &driver); if (!W_ERROR_IS_OK(result)) { @@ -1737,7 +1737,7 @@ bool print_access_check(const struct auth_serversupplied_info *session_info, return False; } - result = winreg_get_printer_secdesc(mem_ctx, + result = winreg_get_printer_secdesc_internal(mem_ctx, get_session_info_system(), msg_ctx, pname, @@ -1813,7 +1813,7 @@ bool print_time_access_check(const struct auth_serversupplied_info *session_info struct tm *t; uint32 mins; - result = winreg_get_printer(NULL, session_info, msg_ctx, + result = winreg_get_printer_internal(NULL, session_info, msg_ctx, servicename, &pinfo2); if (!W_ERROR_IS_OK(result)) { return False; @@ -1846,7 +1846,7 @@ void nt_printer_remove(TALLOC_CTX *mem_ctx, { WERROR result; - result = winreg_delete_printer_key(mem_ctx, session_info, msg_ctx, + result = winreg_delete_printer_key_internal(mem_ctx, session_info, msg_ctx, printer, ""); if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("nt_printer_remove: failed to remove rpinter %s", diff --git a/source3/printing/nt_printing_ads.c b/source3/printing/nt_printing_ads.c index e47ba23..92378b1 100644 --- a/source3/printing/nt_printing_ads.c +++ b/source3/printing/nt_printing_ads.c @@ -74,7 +74,7 @@ static void store_printer_guid(struct messaging_context *msg_ctx, goto done; } - result = winreg_set_printer_dataex(tmp_ctx, session_info, msg_ctx, + result = winreg_set_printer_dataex_internal(tmp_ctx, session_info, msg_ctx, printer, SPOOL_DSSPOOLER_KEY, "objectGUID", REG_SZ, blob.data, blob.length); @@ -275,7 +275,7 @@ WERROR nt_printer_publish(TALLOC_CTX *mem_ctx, sinfo2->attributes = pinfo2->attributes; - win_rc = winreg_update_printer(mem_ctx, session_info, msg_ctx, + win_rc = winreg_update_printer_internal(mem_ctx, session_info, msg_ctx, pinfo2->sharename, info2_mask, sinfo2, NULL, NULL); if (!W_ERROR_IS_OK(win_rc)) { @@ -365,7 +365,7 @@ WERROR check_published_printers(struct messaging_context *msg_ctx) continue; } - result = winreg_get_printer(tmp_ctx, session_info, msg_ctx, + result = winreg_get_printer_internal(tmp_ctx, session_info, msg_ctx, lp_servicename(snum), &pinfo2); if (!W_ERROR_IS_OK(result)) { @@ -400,7 +400,7 @@ bool is_printer_published(TALLOC_CTX *mem_ctx, WERROR result; NTSTATUS status; - result = winreg_get_printer(mem_ctx, session_info, msg_ctx, + result = winreg_get_printer_internal(mem_ctx, session_info, msg_ctx, printer, &pinfo2); if (!W_ERROR_IS_OK(result)) { return false; @@ -417,7 +417,7 @@ bool is_printer_published(TALLOC_CTX *mem_ctx, /* fetching printer guids really ought to be a separate function. */ - result = winreg_get_printer_dataex(mem_ctx, session_info, msg_ctx, + result = winreg_get_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer, SPOOL_DSSPOOLER_KEY, "objectGUID", &type, &data, &data_size); diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index 8a4f17d..71a3521 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -464,7 +464,7 @@ static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle /* this does not need a become root since the access check has been done on the handle already */ - result = winreg_delete_printer_key(p->mem_ctx, + result = winreg_delete_printer_key_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, Printer->sharename, @@ -686,7 +686,7 @@ static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx, continue; } - result = winreg_get_printer(mem_ctx, + result = winreg_get_printer_internal(mem_ctx, session_info, msg_ctx, sname, @@ -1573,7 +1573,7 @@ void do_drv_upgrade_printer(struct messaging_context *msg, continue; } - result = winreg_get_printer(tmp_ctx, session_info, msg, + result = winreg_get_printer_internal(tmp_ctx, session_info, msg, lp_const_servicename(snum), &pinfo2); @@ -1592,7 +1592,7 @@ void do_drv_upgrade_printer(struct messaging_context *msg, DEBUG(6,("Updating printer [%s]\n", pinfo2->printername)); /* all we care about currently is the change_id */ - result = winreg_printer_update_changeid(tmp_ctx, + result = winreg_printer_update_changeid_internal(tmp_ctx, session_info, msg, pinfo2->printername); @@ -1912,7 +1912,7 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p, DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER) ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" )); - winreg_create_printer(p->mem_ctx, + winreg_create_printer_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum)); @@ -2003,7 +2003,7 @@ WERROR _spoolss_DeletePrinter(struct pipes_struct *p, } if (get_printer_snum(p, r->in.handle, &snum, NULL)) { - winreg_delete_printer_key(p->mem_ctx, + winreg_delete_printer_key_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum), @@ -2078,7 +2078,7 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p, if ((version = get_version_id(r->in.architecture)) == -1) return WERR_INVALID_ENVIRONMENT; - status = winreg_get_driver(p->mem_ctx, + status = winreg_get_driver_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, r->in.architecture, r->in.driver, @@ -2089,7 +2089,7 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p, if ( version == 2 ) { version = 3; - status = winreg_get_driver(p->mem_ctx, + status = winreg_get_driver_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, r->in.architecture, @@ -2117,7 +2117,7 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p, } if (version == 2) { - status = winreg_get_driver(p->mem_ctx, + status = winreg_get_driver_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, r->in.architecture, @@ -2126,7 +2126,7 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p, /* if we get to here, we now have 2 driver info structures to remove */ /* remove the Win2k driver first*/ - status = winreg_del_driver(p->mem_ctx, + status = winreg_del_driver_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, info_win2k, 3); @@ -2139,7 +2139,7 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p, } } - status = winreg_del_driver(p->mem_ctx, + status = winreg_del_driver_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, info, version); @@ -2186,7 +2186,7 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p, if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) version = r->in.version; - status = winreg_get_driver(p->mem_ctx, + status = winreg_get_driver_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, r->in.architecture, @@ -2208,7 +2208,7 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p, /* try for Win2k driver if "Windows NT x86" */ version = 3; - status = winreg_get_driver(info, + status = winreg_get_driver_internal(info, get_session_info_system(), p->msg_ctx, r->in.architecture, @@ -2259,7 +2259,7 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p, /* 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(info, + status = winreg_get_driver_internal(info, get_session_info_system(), p->msg_ctx, r->in.architecture, @@ -2281,7 +2281,7 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p, /* if we get to here, we now have 2 driver info structures to remove */ /* remove the Win2k driver first*/ - status = winreg_del_driver(info, + status = winreg_del_driver_internal(info, get_session_info_system(), p->msg_ctx, info_win2k, @@ -2305,7 +2305,7 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p, } } - status = winreg_del_driver(info, + status = winreg_del_driver_internal(info, get_session_info_system(), p->msg_ctx, info, @@ -3592,7 +3592,7 @@ static WERROR printserver_notify_info(struct pipes_struct *p, } /* Maybe we should use the SYSTEM session_info here... */ - result = winreg_get_printer(mem_ctx, + result = winreg_get_printer_internal(mem_ctx, get_session_info_system(), p->msg_ctx, lp_servicename(snum), @@ -3680,7 +3680,7 @@ static WERROR printer_notify_info(struct pipes_struct *p, } /* Maybe we should use the SYSTEM session_info here... */ - result = winreg_get_printer(mem_ctx, + result = winreg_get_printer_internal(mem_ctx, get_session_info_system(), p->msg_ctx, lp_servicename(snum), &pinfo2); @@ -3929,7 +3929,7 @@ static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx, r->high_part_total_bytes = 0x0; /* ChangeID in milliseconds*/ - winreg_printer_get_changeid(mem_ctx, session_info, msg_ctx, + winreg_printer_get_changeid_internal(mem_ctx, session_info, msg_ctx, info2->sharename, &r->change_id); r->last_error = WERR_OK; @@ -4300,7 +4300,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", printer, snum)); - result = winreg_create_printer(mem_ctx, + result = winreg_create_printer_internal(mem_ctx, session_info, msg_ctx, printer); @@ -4316,7 +4316,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, goto out; } - result = winreg_get_printer(mem_ctx, session_info, msg_ctx, + result = winreg_get_printer_internal(mem_ctx, session_info, msg_ctx, printer, &info2); if (!W_ERROR_IS_OK(result)) { goto out; @@ -4733,7 +4733,7 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p, return WERR_BADFID; } - result = winreg_get_printer(p->mem_ctx, + result = winreg_get_printer_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum), @@ -5511,7 +5511,7 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx, return WERR_UNKNOWN_LEVEL; } - result = winreg_get_printer(mem_ctx, + result = winreg_get_printer_internal(mem_ctx, session_info, msg_ctx, lp_const_servicename(snum), @@ -5524,7 +5524,7 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx, return WERR_INVALID_PRINTER_NAME; } - result = winreg_get_driver(mem_ctx, session_info, msg_ctx, + result = winreg_get_driver_internal(mem_ctx, session_info, msg_ctx, architecture, pinfo2->drivername, version, &driver); @@ -5543,7 +5543,7 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx, /* Yes - try again with a WinNT driver. */ version = 2; - result = winreg_get_driver(mem_ctx, session_info, msg_ctx, + result = winreg_get_driver_internal(mem_ctx, session_info, msg_ctx, architecture, pinfo2->drivername, version, &driver); @@ -5958,13 +5958,13 @@ 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(p->mem_ctx, + result = winreg_get_printer_secdesc_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, printer, &old_secdesc); if (!W_ERROR_IS_OK(result)) { - DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n")); + DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc_internal() failed\n")); result = WERR_BADFID; goto done; } @@ -6010,7 +6010,7 @@ static WERROR update_printer_sec(struct policy_handle *handle, goto done; } - result = winreg_set_printer_secdesc(p->mem_ctx, + result = winreg_set_printer_secdesc_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, printer, @@ -6221,7 +6221,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || !strequal(printer->drivername, old_printer->drivername)) { push_reg_sz(mem_ctx, &buffer, printer->drivername); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6243,7 +6243,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || !strequal(printer->comment, old_printer->comment)) { push_reg_sz(mem_ctx, &buffer, printer->comment); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6262,7 +6262,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || !strequal(printer->sharename, old_printer->sharename)) { push_reg_sz(mem_ctx, &buffer, printer->sharename); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6291,7 +6291,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, } push_reg_sz(mem_ctx, &buffer, p); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6309,7 +6309,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || !strequal(printer->portname, old_printer->portname)) { push_reg_sz(mem_ctx, &buffer, printer->portname); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6328,7 +6328,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || !strequal(printer->location, old_printer->location)) { push_reg_sz(mem_ctx, &buffer, printer->location); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6348,7 +6348,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) { push_reg_sz(mem_ctx, &buffer, printer->sepfile); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6369,7 +6369,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || printer->starttime != old_printer->starttime) { buffer = data_blob_talloc(mem_ctx, NULL, 4); SIVAL(buffer.data, 0, printer->starttime); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6383,7 +6383,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || printer->untiltime != old_printer->untiltime) { buffer = data_blob_talloc(mem_ctx, NULL, 4); SIVAL(buffer.data, 0, printer->untiltime); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6397,7 +6397,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || printer->priority != old_printer->priority) { buffer = data_blob_talloc(mem_ctx, NULL, 4); SIVAL(buffer.data, 0, printer->priority); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6412,7 +6412,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, buffer = data_blob_talloc(mem_ctx, NULL, 4); SIVAL(buffer.data, 0, (printer->attributes & PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS)); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6436,7 +6436,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, spooling = "unknown"; } push_reg_sz(mem_ctx, &buffer, spooling); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6448,7 +6448,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, } push_reg_sz(mem_ctx, &buffer, global_myname()); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6470,7 +6470,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, } push_reg_sz(mem_ctx, &buffer, longname); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6483,7 +6483,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s", global_myname(), printer->sharename); push_reg_sz(mem_ctx, &buffer, uncname); - winreg_set_printer_dataex(mem_ctx, + winreg_set_printer_dataex_internal(mem_ctx, session_info, msg_ctx, printer->sharename, @@ -6532,7 +6532,7 @@ static WERROR update_printer(struct pipes_struct *p, goto done; } - result = winreg_get_printer(tmp_ctx, + result = winreg_get_printer_internal(tmp_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum), @@ -6588,7 +6588,7 @@ static WERROR update_printer(struct pipes_struct *p, if (devmode == NULL) { printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE; } - result = winreg_update_printer(tmp_ctx, + result = winreg_update_printer_internal(tmp_ctx, get_session_info_system(), p->msg_ctx, printer->sharename, @@ -6629,7 +6629,7 @@ static WERROR publish_or_unpublish_printer(struct pipes_struct *p, if (!get_printer_snum(p, handle, &snum, NULL)) return WERR_BADFID; - result = winreg_get_printer(p->mem_ctx, + result = winreg_get_printer_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_servicename(snum), @@ -6678,7 +6678,7 @@ static WERROR update_printer_devmode(struct pipes_struct *p, return WERR_ACCESS_DENIED; } - return winreg_update_printer(p->mem_ctx, + return winreg_update_printer_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum), @@ -7092,7 +7092,7 @@ WERROR _spoolss_EnumJobs(struct pipes_struct *p, return WERR_BADFID; } - result = winreg_get_printer(p->mem_ctx, + result = winreg_get_printer_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum), @@ -7282,7 +7282,7 @@ static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx, *info_p = NULL; for (version=0; versionin.level) { case 1: - result = winreg_printer_enumforms1(p->mem_ctx, + result = winreg_printer_enumforms1_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, r->out.count, @@ -7553,7 +7553,7 @@ WERROR _spoolss_GetForm(struct pipes_struct *p, switch (r->in.level) { case 1: - result = winreg_printer_getform1(p->mem_ctx, + result = winreg_printer_getform1_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, r->in.form_name, @@ -7928,7 +7928,7 @@ static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p, info2, NULL); - err = winreg_update_printer(p->mem_ctx, + err = winreg_update_printer_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, info2->sharename, @@ -8055,7 +8055,7 @@ WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p, goto done; } - err = winreg_add_driver(p->mem_ctx, + err = winreg_add_driver_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, r->in.info_ctr, @@ -8496,7 +8496,7 @@ WERROR _spoolss_AddForm(struct pipes_struct *p, return WERR_INVALID_PARAM; } - status = winreg_printer_addform1(p->mem_ctx, + status = winreg_printer_addform1_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, form); @@ -8512,7 +8512,7 @@ WERROR _spoolss_AddForm(struct pipes_struct *p, return WERR_BADFID; } - status = winreg_printer_update_changeid(p->mem_ctx, + status = winreg_printer_update_changeid_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum)); @@ -8555,7 +8555,7 @@ WERROR _spoolss_DeleteForm(struct pipes_struct *p, return WERR_ACCESS_DENIED; } - status = winreg_printer_deleteform1(p->mem_ctx, + status = winreg_printer_deleteform1_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, form_name); @@ -8571,7 +8571,7 @@ WERROR _spoolss_DeleteForm(struct pipes_struct *p, return WERR_BADFID; } - status = winreg_printer_update_changeid(p->mem_ctx, + status = winreg_printer_update_changeid_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum)); @@ -8619,7 +8619,7 @@ WERROR _spoolss_SetForm(struct pipes_struct *p, return WERR_ACCESS_DENIED; } - status = winreg_printer_setform1(p->mem_ctx, + status = winreg_printer_setform1_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, form_name, @@ -8636,7 +8636,7 @@ WERROR _spoolss_SetForm(struct pipes_struct *p, return WERR_BADFID; } - status = winreg_printer_update_changeid(p->mem_ctx, + status = winreg_printer_update_changeid_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum)); @@ -9130,7 +9130,7 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, return WERR_BADFID; } - result = winreg_get_printer(p->mem_ctx, + result = winreg_get_printer_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum), @@ -9257,7 +9257,7 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p, if (r->in.offered >= *r->out.needed) { uint32_t changeid = 0; - result = winreg_printer_get_changeid(p->mem_ctx, + result = winreg_printer_get_changeid_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, printer, @@ -9272,7 +9272,7 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p, goto done; } - result = winreg_get_printer_dataex(p->mem_ctx, + result = winreg_get_printer_dataex_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, printer, @@ -9347,7 +9347,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p, return WERR_ACCESS_DENIED; } - result = winreg_get_printer(Printer, + result = winreg_get_printer_internal(Printer, get_session_info_system(), p->msg_ctx, lp_servicename(snum), @@ -9366,7 +9366,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p, /* save the registry data */ - result = winreg_set_printer_dataex(p->mem_ctx, + result = winreg_set_printer_dataex_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, pinfo2->sharename, @@ -9392,7 +9392,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p, * previous set_printer_dataex() call. I have no idea if * this is right. --jerry */ - winreg_set_printer_dataex(p->mem_ctx, + winreg_set_printer_dataex_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, pinfo2->sharename, @@ -9403,7 +9403,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p, strlen(oid_string) + 1); } - result = winreg_printer_update_changeid(p->mem_ctx, + result = winreg_printer_update_changeid_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum)); @@ -9451,14 +9451,14 @@ WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p, } printer = lp_const_servicename(snum); - status = winreg_delete_printer_dataex(p->mem_ctx, + status = winreg_delete_printer_dataex_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, printer, r->in.key_name, r->in.value_name); if (W_ERROR_IS_OK(status)) { - status = winreg_printer_update_changeid(p->mem_ctx, + status = winreg_printer_update_changeid_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, printer); @@ -9493,7 +9493,7 @@ WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p, return WERR_BADFID; } - result = winreg_enum_printer_key(p->mem_ctx, + result = winreg_enum_printer_key_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum), @@ -9567,13 +9567,13 @@ WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p, printer = lp_const_servicename(snum); /* delete the key and all subkeys */ - status = winreg_delete_printer_key(p->mem_ctx, + status = winreg_delete_printer_key_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, printer, r->in.key_name); if (W_ERROR_IS_OK(status)) { - status = winreg_printer_update_changeid(p->mem_ctx, + status = winreg_printer_update_changeid_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, printer); @@ -9624,7 +9624,7 @@ WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p, } /* now look for a match on the key name */ - result = winreg_enum_printer_dataex(p->mem_ctx, + result = winreg_enum_printer_dataex_internal(p->mem_ctx, get_session_info_system(), p->msg_ctx, lp_const_servicename(snum), -- 1.7.6 From d960d0b21fcfad863da943dc66e2c5cef7d5f6aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 5 Jul 2011 00:55:35 +0200 Subject: [PATCH 15/21] s3-printing: safe a ton of roundtrips by reusing existing winreg binding_handles. Guenther Pair-Programmed-With: David Disseldorp (cherry picked from commit 72b1f8be5619ed778c4aa0b967f6a4f34d7e9de8) Conflicts: source3/rpc_server/spoolss/srv_spoolss_nt.c --- source3/printing/nt_printing.c | 33 +++- source3/printing/nt_printing_ads.c | 13 +- source3/rpc_server/spoolss/srv_spoolss_nt.c | 339 +++++++++++++++------------ 3 files changed, 229 insertions(+), 156 deletions(-) diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 40d5fc1..d6b8bb1 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -32,6 +32,7 @@ #include "auth.h" #include "messages.h" #include "rpc_server/spoolss/srv_spoolss_nt.h" +#include "rpc_client/cli_winreg_spoolss.h" /* Map generic permissions to printer object specific permissions */ @@ -1182,6 +1183,7 @@ bool printer_driver_in_use(TALLOC_CTX *mem_ctx, bool in_use = False; struct spoolss_PrinterInfo2 *pinfo2 = NULL; WERROR result; + struct dcerpc_binding_handle *b = NULL; if (!r) { return false; @@ -1196,7 +1198,17 @@ bool printer_driver_in_use(TALLOC_CTX *mem_ctx, continue; } - result = winreg_get_printer_internal(mem_ctx, session_info, msg_ctx, + if (b == NULL) { + result = winreg_printer_binding_handle(mem_ctx, + session_info, + msg_ctx, + &b); + if (!W_ERROR_IS_OK(result)) { + return false; + } + } + + result = winreg_get_printer(mem_ctx, b, lp_servicename(snum), &pinfo2); if (!W_ERROR_IS_OK(result)) { @@ -1222,18 +1234,18 @@ bool printer_driver_in_use(TALLOC_CTX *mem_ctx, "Windows NT x86" version 2 or 3 left */ if (!strequal("Windows NT x86", r->architecture)) { - werr = winreg_get_driver_internal(mem_ctx, session_info, msg_ctx, + werr = winreg_get_driver(mem_ctx, b, "Windows NT x86", r->driver_name, DRIVER_ANY_VERSION, &driver); } else if (r->version == 2) { - werr = winreg_get_driver_internal(mem_ctx, session_info, msg_ctx, + werr = winreg_get_driver(mem_ctx, b, "Windows NT x86", r->driver_name, 3, &driver); } else if (r->version == 3) { - werr = winreg_get_driver_internal(mem_ctx, session_info, msg_ctx, + werr = winreg_get_driver(mem_ctx, b, "Windows NT x86", r->driver_name, 2, &driver); @@ -1412,6 +1424,7 @@ bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx, uint32_t num_drivers; const char **drivers; WERROR result; + struct dcerpc_binding_handle *b; if ( !info ) return False; @@ -1424,7 +1437,15 @@ bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx, /* get the list of drivers */ - result = winreg_get_driver_list_internal(mem_ctx, session_info, msg_ctx, + result = winreg_printer_binding_handle(mem_ctx, + session_info, + msg_ctx, + &b); + if (!W_ERROR_IS_OK(result)) { + return false; + } + + result = winreg_get_driver_list(mem_ctx, b, info->architecture, version, &num_drivers, &drivers); if (!W_ERROR_IS_OK(result)) { @@ -1441,7 +1462,7 @@ bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx, driver = NULL; - result = winreg_get_driver_internal(mem_ctx, session_info, msg_ctx, + result = winreg_get_driver(mem_ctx, b, info->architecture, drivers[i], version, &driver); if (!W_ERROR_IS_OK(result)) { diff --git a/source3/printing/nt_printing_ads.c b/source3/printing/nt_printing_ads.c index 92378b1..67046bc 100644 --- a/source3/printing/nt_printing_ads.c +++ b/source3/printing/nt_printing_ads.c @@ -399,8 +399,17 @@ bool is_printer_published(TALLOC_CTX *mem_ctx, uint32_t data_size; WERROR result; NTSTATUS status; + struct dcerpc_binding_handle *b; - result = winreg_get_printer_internal(mem_ctx, session_info, msg_ctx, + result = winreg_printer_binding_handle(mem_ctx, + session_info, + msg_ctx, + &b); + if (!W_ERROR_IS_OK(result)) { + return false; + } + + result = winreg_get_printer(mem_ctx, b, printer, &pinfo2); if (!W_ERROR_IS_OK(result)) { return false; @@ -417,7 +426,7 @@ bool is_printer_published(TALLOC_CTX *mem_ctx, /* fetching printer guids really ought to be a separate function. */ - result = winreg_get_printer_dataex_internal(mem_ctx, session_info, msg_ctx, + result = winreg_get_printer_dataex(mem_ctx, b, printer, SPOOL_DSSPOOLER_KEY, "objectGUID", &type, &data, &data_size); diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index 71a3521..c309c65 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -1541,6 +1541,7 @@ void do_drv_upgrade_printer(struct messaging_context *msg, const char *drivername; int snum; int n_services = lp_numservices(); + struct dcerpc_binding_handle *b = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return; @@ -1573,7 +1574,17 @@ void do_drv_upgrade_printer(struct messaging_context *msg, continue; } - result = winreg_get_printer_internal(tmp_ctx, session_info, msg, + if (b == NULL) { + result = winreg_printer_binding_handle(tmp_ctx, + session_info, + msg, + &b); + if (!W_ERROR_IS_OK(result)) { + break; + } + } + + result = winreg_get_printer(tmp_ctx, b, lp_const_servicename(snum), &pinfo2); @@ -1592,9 +1603,7 @@ void do_drv_upgrade_printer(struct messaging_context *msg, DEBUG(6,("Updating printer [%s]\n", pinfo2->printername)); /* all we care about currently is the change_id */ - result = winreg_printer_update_changeid_internal(tmp_ctx, - session_info, - msg, + result = winreg_printer_update_changeid(tmp_ctx, b, pinfo2->printername); if (!W_ERROR_IS_OK(result)) { @@ -2057,6 +2066,7 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p, struct spoolss_DriverInfo8 *info_win2k = NULL; int version; WERROR status; + struct dcerpc_binding_handle *b; /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege, and not a printer admin, then fail */ @@ -2078,9 +2088,15 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p, if ((version = get_version_id(r->in.architecture)) == -1) return WERR_INVALID_ENVIRONMENT; - status = winreg_get_driver_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_printer_binding_handle(p->mem_ctx, + get_session_info_system(), + p->msg_ctx, + &b); + if (!W_ERROR_IS_OK(status)) { + return status; + } + + status = winreg_get_driver(p->mem_ctx, b, r->in.architecture, r->in.driver, version, &info); if (!W_ERROR_IS_OK(status)) { @@ -2089,9 +2105,7 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p, if ( version == 2 ) { version = 3; - status = winreg_get_driver_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_get_driver(p->mem_ctx, b, r->in.architecture, r->in.driver, version, &info); @@ -2117,18 +2131,14 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p, } if (version == 2) { - status = winreg_get_driver_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_get_driver(p->mem_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_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_del_driver(p->mem_ctx, b, info_win2k, 3); talloc_free(info_win2k); @@ -2139,9 +2149,7 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p, } } - status = winreg_del_driver_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_del_driver(p->mem_ctx, b, info, version); done: @@ -2162,6 +2170,7 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p, int version; bool delete_files; WERROR status; + struct dcerpc_binding_handle *b; /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege, and not a printer admin, then fail */ @@ -2186,9 +2195,15 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p, if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) version = r->in.version; - status = winreg_get_driver_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_printer_binding_handle(p->mem_ctx, + get_session_info_system(), + p->msg_ctx, + &b); + if (!W_ERROR_IS_OK(status)) { + return status; + } + + status = winreg_get_driver(p->mem_ctx, b, r->in.architecture, r->in.driver, version, @@ -2208,9 +2223,7 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p, /* try for Win2k driver if "Windows NT x86" */ version = 3; - status = winreg_get_driver_internal(info, - get_session_info_system(), - p->msg_ctx, + status = winreg_get_driver(info, b, r->in.architecture, r->in.driver, version, &info); @@ -2259,9 +2272,7 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p, /* 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_internal(info, - get_session_info_system(), - p->msg_ctx, + status = winreg_get_driver(info, b, r->in.architecture, r->in.driver, 3, &info_win2k); if (W_ERROR_IS_OK(status)) { @@ -2281,9 +2292,7 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p, /* if we get to here, we now have 2 driver info structures to remove */ /* remove the Win2k driver first*/ - status = winreg_del_driver_internal(info, - get_session_info_system(), - p->msg_ctx, + status = winreg_del_driver(info, b, info_win2k, 3); @@ -2305,9 +2314,7 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p, } } - status = winreg_del_driver_internal(info, - get_session_info_system(), - p->msg_ctx, + status = winreg_del_driver(info, b, info, version); if (!W_ERROR_IS_OK(status)) { @@ -4282,6 +4289,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, union spoolss_PrinterInfo *info = NULL; uint32_t count = 0; WERROR result = WERR_OK; + struct dcerpc_binding_handle *b = NULL; *count_p = 0; *info_p = NULL; @@ -4300,9 +4308,17 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", printer, snum)); - result = winreg_create_printer_internal(mem_ctx, - session_info, - msg_ctx, + if (b == NULL) { + result = winreg_printer_binding_handle(mem_ctx, + session_info, + msg_ctx, + &b); + if (!W_ERROR_IS_OK(result)) { + goto out; + } + } + + result = winreg_create_printer(mem_ctx, b, printer); if (!W_ERROR_IS_OK(result)) { goto out; @@ -4316,7 +4332,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, goto out; } - result = winreg_get_printer_internal(mem_ctx, session_info, msg_ctx, + result = winreg_get_printer(mem_ctx, b, printer, &info2); if (!W_ERROR_IS_OK(result)) { goto out; @@ -5506,14 +5522,21 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx, struct spoolss_PrinterInfo2 *pinfo2 = NULL; struct spoolss_DriverInfo8 *driver; WERROR result; + struct dcerpc_binding_handle *b; if (level == 101) { return WERR_UNKNOWN_LEVEL; } - result = winreg_get_printer_internal(mem_ctx, - session_info, - msg_ctx, + result = winreg_printer_binding_handle(mem_ctx, + session_info, + msg_ctx, + &b); + if (!W_ERROR_IS_OK(result)) { + return result; + } + + result = winreg_get_printer(mem_ctx, b, lp_const_servicename(snum), &pinfo2); @@ -5524,7 +5547,7 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx, return WERR_INVALID_PRINTER_NAME; } - result = winreg_get_driver_internal(mem_ctx, session_info, msg_ctx, + result = winreg_get_driver(mem_ctx, b, architecture, pinfo2->drivername, version, &driver); @@ -5543,7 +5566,7 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx, /* Yes - try again with a WinNT driver. */ version = 2; - result = winreg_get_driver_internal(mem_ctx, session_info, msg_ctx, + result = winreg_get_driver(mem_ctx, b, architecture, pinfo2->drivername, version, &driver); @@ -5927,8 +5950,8 @@ static WERROR update_printer_sec(struct policy_handle *handle, const char *printer; WERROR result; int snum; - struct printer_handle *Printer = find_printer_index_by_hnd(p, handle); + struct dcerpc_binding_handle *b; if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) { DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n", @@ -5956,11 +5979,17 @@ static WERROR update_printer_sec(struct policy_handle *handle, goto done; } + result = winreg_printer_binding_handle(p->mem_ctx, + get_session_info_system(), + p->msg_ctx, + &b); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + /* NT seems to like setting the security descriptor even though nothing may have actually changed. */ - result = winreg_get_printer_secdesc_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + result = winreg_get_printer_secdesc(p->mem_ctx, b, printer, &old_secdesc); if (!W_ERROR_IS_OK(result)) { @@ -6010,9 +6039,7 @@ static WERROR update_printer_sec(struct policy_handle *handle, goto done; } - result = winreg_set_printer_secdesc_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + result = winreg_set_printer_secdesc(p->mem_ctx, b, printer, new_secdesc); @@ -6218,12 +6245,19 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, const char *spooling; DATA_BLOB buffer; WERROR result = WERR_OK; + struct dcerpc_binding_handle *b; + + result = winreg_printer_binding_handle(mem_ctx, + session_info, + msg_ctx, + &b); + if (!W_ERROR_IS_OK(result)) { + return result; + } if (force_update || !strequal(printer->drivername, old_printer->drivername)) { push_reg_sz(mem_ctx, &buffer, printer->drivername); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_DRIVERNAME, @@ -6243,9 +6277,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || !strequal(printer->comment, old_printer->comment)) { push_reg_sz(mem_ctx, &buffer, printer->comment); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_DESCRIPTION, @@ -6262,9 +6294,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || !strequal(printer->sharename, old_printer->sharename)) { push_reg_sz(mem_ctx, &buffer, printer->sharename); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_PRINTSHARENAME, @@ -6291,9 +6321,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, } push_reg_sz(mem_ctx, &buffer, p); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_PRINTERNAME, @@ -6309,9 +6337,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || !strequal(printer->portname, old_printer->portname)) { push_reg_sz(mem_ctx, &buffer, printer->portname); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_PORTNAME, @@ -6328,9 +6354,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || !strequal(printer->location, old_printer->location)) { push_reg_sz(mem_ctx, &buffer, printer->location); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_LOCATION, @@ -6348,9 +6372,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) { push_reg_sz(mem_ctx, &buffer, printer->sepfile); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_PRINTSEPARATORFILE, @@ -6369,9 +6391,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || printer->starttime != old_printer->starttime) { buffer = data_blob_talloc(mem_ctx, NULL, 4); SIVAL(buffer.data, 0, printer->starttime); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_PRINTSTARTTIME, @@ -6383,9 +6403,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || printer->untiltime != old_printer->untiltime) { buffer = data_blob_talloc(mem_ctx, NULL, 4); SIVAL(buffer.data, 0, printer->untiltime); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_PRINTENDTIME, @@ -6397,9 +6415,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, if (force_update || printer->priority != old_printer->priority) { buffer = data_blob_talloc(mem_ctx, NULL, 4); SIVAL(buffer.data, 0, printer->priority); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_PRIORITY, @@ -6412,9 +6428,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, buffer = data_blob_talloc(mem_ctx, NULL, 4); SIVAL(buffer.data, 0, (printer->attributes & PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS)); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_PRINTKEEPPRINTEDJOBS, @@ -6436,9 +6450,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, spooling = "unknown"; } push_reg_sz(mem_ctx, &buffer, spooling); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_PRINTSPOOLING, @@ -6448,9 +6460,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, } push_reg_sz(mem_ctx, &buffer, global_myname()); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_SHORTSERVERNAME, @@ -6470,9 +6480,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, } push_reg_sz(mem_ctx, &buffer, longname); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_SERVERNAME, @@ -6483,9 +6491,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx, uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s", global_myname(), printer->sharename); push_reg_sz(mem_ctx, &buffer, uncname); - winreg_set_printer_dataex_internal(mem_ctx, - session_info, - msg_ctx, + winreg_set_printer_dataex(mem_ctx, b, printer->sharename, SPOOL_DSSPOOLER_KEY, SPOOL_REG_UNCNAME, @@ -6514,6 +6520,7 @@ static WERROR update_printer(struct pipes_struct *p, int snum; WERROR result = WERR_OK; TALLOC_CTX *tmp_ctx; + struct dcerpc_binding_handle *b; DEBUG(8,("update_printer\n")); @@ -6532,9 +6539,15 @@ static WERROR update_printer(struct pipes_struct *p, goto done; } - result = winreg_get_printer_internal(tmp_ctx, - get_session_info_system(), - p->msg_ctx, + result = winreg_printer_binding_handle(tmp_ctx, + get_session_info_system(), + p->msg_ctx, + &b); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + result = winreg_get_printer(tmp_ctx, b, lp_const_servicename(snum), &old_printer); if (!W_ERROR_IS_OK(result)) { @@ -6588,9 +6601,7 @@ static WERROR update_printer(struct pipes_struct *p, if (devmode == NULL) { printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE; } - result = winreg_update_printer_internal(tmp_ctx, - get_session_info_system(), - p->msg_ctx, + result = winreg_update_printer(tmp_ctx, b, printer->sharename, printer_mask, printer, @@ -7277,12 +7288,21 @@ static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx, WERROR result = WERR_OK; uint32_t num_drivers; const char **drivers; + struct dcerpc_binding_handle *b; *count_p = 0; *info_p = NULL; + result = winreg_printer_binding_handle(mem_ctx, + session_info, + msg_ctx, + &b); + if (!W_ERROR_IS_OK(result)) { + goto out; + } + for (version=0; versionin.info.info1; int snum = -1; WERROR status = WERR_OK; - struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle); + struct dcerpc_binding_handle *b; DEBUG(5,("_spoolss_AddForm\n")); @@ -8496,9 +8515,15 @@ WERROR _spoolss_AddForm(struct pipes_struct *p, return WERR_INVALID_PARAM; } - status = winreg_printer_addform1_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_printer_binding_handle(p->mem_ctx, + get_session_info_system(), + p->msg_ctx, + &b); + if (!W_ERROR_IS_OK(status)) { + return status; + } + + status = winreg_printer_addform1(p->mem_ctx, b, form); if (!W_ERROR_IS_OK(status)) { return status; @@ -8512,9 +8537,7 @@ WERROR _spoolss_AddForm(struct pipes_struct *p, return WERR_BADFID; } - status = winreg_printer_update_changeid_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_printer_update_changeid(p->mem_ctx, b, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(status)) { return status; @@ -8535,6 +8558,7 @@ WERROR _spoolss_DeleteForm(struct pipes_struct *p, struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle); int snum = -1; WERROR status = WERR_OK; + struct dcerpc_binding_handle *b; DEBUG(5,("_spoolss_DeleteForm\n")); @@ -8555,9 +8579,15 @@ WERROR _spoolss_DeleteForm(struct pipes_struct *p, return WERR_ACCESS_DENIED; } - status = winreg_printer_deleteform1_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_printer_binding_handle(p->mem_ctx, + get_session_info_system(), + p->msg_ctx, + &b); + if (!W_ERROR_IS_OK(status)) { + return status; + } + + status = winreg_printer_deleteform1(p->mem_ctx, b, form_name); if (!W_ERROR_IS_OK(status)) { return status; @@ -8571,9 +8601,7 @@ WERROR _spoolss_DeleteForm(struct pipes_struct *p, return WERR_BADFID; } - status = winreg_printer_update_changeid_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_printer_update_changeid(p->mem_ctx, b, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(status)) { return status; @@ -8594,6 +8622,7 @@ WERROR _spoolss_SetForm(struct pipes_struct *p, const char *form_name = r->in.form_name; int snum = -1; WERROR status = WERR_OK; + struct dcerpc_binding_handle *b; struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle); @@ -8619,9 +8648,15 @@ WERROR _spoolss_SetForm(struct pipes_struct *p, return WERR_ACCESS_DENIED; } - status = winreg_printer_setform1_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_printer_binding_handle(p->mem_ctx, + get_session_info_system(), + p->msg_ctx, + &b); + if (!W_ERROR_IS_OK(status)) { + return status; + } + + status = winreg_printer_setform1(p->mem_ctx, b, form_name, form); if (!W_ERROR_IS_OK(status)) { @@ -8636,9 +8671,7 @@ WERROR _spoolss_SetForm(struct pipes_struct *p, return WERR_BADFID; } - status = winreg_printer_update_changeid_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_printer_update_changeid(p->mem_ctx, b, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(status)) { return status; @@ -9191,7 +9224,7 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p, enum winreg_Type val_type = REG_NONE; uint8_t *val_data = NULL; uint32_t val_size = 0; - + struct dcerpc_binding_handle *b; DEBUG(4,("_spoolss_GetPrinterDataEx\n")); @@ -9249,6 +9282,14 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p, return WERR_INVALID_PARAM; } + result = winreg_printer_binding_handle(p->mem_ctx, + get_session_info_system(), + p->msg_ctx, + &b); + if (!W_ERROR_IS_OK(result)) { + return result; + } + /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */ if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) && strequal(r->in.value_name, "ChangeId")) { @@ -9257,9 +9298,7 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p, if (r->in.offered >= *r->out.needed) { uint32_t changeid = 0; - result = winreg_printer_get_changeid_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + result = winreg_printer_get_changeid(p->mem_ctx, b, printer, &changeid); if (!W_ERROR_IS_OK(result)) { @@ -9272,9 +9311,7 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p, goto done; } - result = winreg_get_printer_dataex_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + result = winreg_get_printer_dataex(p->mem_ctx, b, printer, r->in.key_name, r->in.value_name, @@ -9311,6 +9348,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p, WERROR result = WERR_OK; struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle); char *oid_string; + struct dcerpc_binding_handle *b; DEBUG(4,("_spoolss_SetPrinterDataEx\n")); @@ -9347,9 +9385,15 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p, return WERR_ACCESS_DENIED; } - result = winreg_get_printer_internal(Printer, - get_session_info_system(), - p->msg_ctx, + result = winreg_printer_binding_handle(p->mem_ctx, + get_session_info_system(), + p->msg_ctx, + &b); + if (!W_ERROR_IS_OK(result)) { + return result; + } + + result = winreg_get_printer(Printer, b, lp_servicename(snum), &pinfo2); if (!W_ERROR_IS_OK(result)) { @@ -9366,9 +9410,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p, /* save the registry data */ - result = winreg_set_printer_dataex_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + result = winreg_set_printer_dataex(p->mem_ctx, b, pinfo2->sharename, r->in.key_name, r->in.value_name, @@ -9392,9 +9434,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p, * previous set_printer_dataex() call. I have no idea if * this is right. --jerry */ - winreg_set_printer_dataex_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + winreg_set_printer_dataex(p->mem_ctx, b, pinfo2->sharename, str, r->in.value_name, @@ -9403,9 +9443,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p, strlen(oid_string) + 1); } - result = winreg_printer_update_changeid_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + result = winreg_printer_update_changeid(p->mem_ctx, b, lp_const_servicename(snum)); } @@ -9541,6 +9579,7 @@ WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p, int snum=0; WERROR status; const char *printer; + struct dcerpc_binding_handle *b; DEBUG(5,("_spoolss_DeletePrinterKey\n")); @@ -9566,16 +9605,20 @@ WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p, printer = lp_const_servicename(snum); + status = winreg_printer_binding_handle(p->mem_ctx, + get_session_info_system(), + p->msg_ctx, + &b); + if (!W_ERROR_IS_OK(status)) { + return status; + } + /* delete the key and all subkeys */ - status = winreg_delete_printer_key_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_delete_printer_key(p->mem_ctx, b, printer, r->in.key_name); if (W_ERROR_IS_OK(status)) { - status = winreg_printer_update_changeid_internal(p->mem_ctx, - get_session_info_system(), - p->msg_ctx, + status = winreg_printer_update_changeid(p->mem_ctx, b, printer); } -- 1.7.6 From 80c68d9a23b6c41dde3856e982d5bdba3b2b8826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Mon, 4 Jul 2011 19:47:07 +0200 Subject: [PATCH 16/21] s3-printing: use winreg interface for migration, instead of spoolss. Guenther Pair-Programmed-With: David Disseldorp (cherry picked from commit 8f3d5f5333a61922c4ea7ff1e1d244978958e857) Conflicts: source3/printing/nt_printing_migrate.c --- source3/printing/nt_printing_migrate.c | 219 ++++++-------------------------- 1 files changed, 38 insertions(+), 181 deletions(-) diff --git a/source3/printing/nt_printing_migrate.c b/source3/printing/nt_printing_migrate.c index caff272..5166a75 100644 --- a/source3/printing/nt_printing_migrate.c +++ b/source3/printing/nt_printing_migrate.c @@ -25,6 +25,7 @@ #include "librpc/gen_ndr/ndr_ntprinting.h" #include "librpc/gen_ndr/ndr_spoolss_c.h" #include "librpc/gen_ndr/ndr_security.h" +#include "rpc_client/cli_winreg_spoolss.h" NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *pipe_hnd, @@ -33,19 +34,13 @@ NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx, unsigned char *data, size_t length) { - struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; - struct spoolss_DevmodeContainer devmode_ctr; - struct policy_handle hnd; + struct dcerpc_binding_handle *b = winreg_pipe->binding_handle; enum ndr_err_code ndr_err; struct ntprinting_form r; - union spoolss_AddFormInfo f; struct spoolss_AddFormInfo1 f1; - const char *srv_name_slash; DATA_BLOB blob; - NTSTATUS status; WERROR result; - blob = data_blob_const(data, length); ZERO_STRUCT(r); @@ -65,33 +60,6 @@ NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx, DEBUG(2, ("Migrating Form: %s\n", key_name)); - srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", global_myname()); - if (srv_name_slash == NULL) { - return NT_STATUS_NO_MEMORY; - } - - ZERO_STRUCT(devmode_ctr); - - status = dcerpc_spoolss_OpenPrinter(b, - mem_ctx, - srv_name_slash, - NULL, - devmode_ctr, - SEC_FLAG_MAXIMUM_ALLOWED, - &hnd, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("dcerpc_spoolss_OpenPrinter(%s) failed: %s\n", - srv_name_slash, nt_errstr(status))); - return status; - } - if (!W_ERROR_IS_OK(result)) { - DEBUG(2, ("OpenPrinter(%s) failed: %s\n", - srv_name_slash, win_errstr(result))); - status = werror_to_ntstatus(result); - return status; - } - f1.form_name = key_name; f1.flags = r.flag; @@ -103,26 +71,14 @@ NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx, f1.area.bottom = r.bottom; f1.area.left = r.left; - f.info1 = &f1; - - status = dcerpc_spoolss_AddForm(b, - mem_ctx, - &hnd, - 1, - f, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("dcerpc_spoolss_AddForm(%s) refused -- %s.\n", - f.info1->form_name, nt_errstr(status))); - } else if (!W_ERROR_IS_OK(result)) { - DEBUG(2, ("AddForm(%s) refused -- %s.\n", - f.info1->form_name, win_errstr(result))); - status = werror_to_ntstatus(result); + result = winreg_printer_addform1(mem_ctx, + b, + &f1); + if (!W_ERROR_IS_OK(result)) { + return werror_to_ntstatus(result); } - dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result); - - return status; + return NT_STATUS_OK; } NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx, @@ -132,16 +88,16 @@ NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx, unsigned char *data, size_t length) { - struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; - const char *srv_name_slash; + struct dcerpc_binding_handle *b = winreg_pipe->binding_handle; enum ndr_err_code ndr_err; struct ntprinting_driver r; struct spoolss_AddDriverInfoCtr d; struct spoolss_AddDriverInfo3 d3; struct spoolss_StringArray a; DATA_BLOB blob; - NTSTATUS status; WERROR result; + const char *driver_name; + uint32_t driver_version; blob = data_blob_const(data, length); @@ -157,11 +113,6 @@ NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx, DEBUG(2, ("Migrating Printer Driver: %s\n", key_name)); - srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", global_myname()); - if (srv_name_slash == NULL) { - return NT_STATUS_NO_MEMORY; - } - ZERO_STRUCT(d3); ZERO_STRUCT(a); @@ -181,21 +132,16 @@ NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx, d.level = 3; d.info.info3 = &d3; - status = dcerpc_spoolss_AddPrinterDriver(b, - mem_ctx, - srv_name_slash, - &d, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("dcerpc_spoolss_AddPrinterDriver(%s) refused -- %s.\n", - d3.driver_name, nt_errstr(status))); - } else if (!W_ERROR_IS_OK(result)) { - DEBUG(2, ("AddPrinterDriver(%s) refused -- %s.\n", - d3.driver_name, win_errstr(result))); - status = werror_to_ntstatus(result); + result = winreg_add_driver(mem_ctx, + b, + &d, + &driver_name, + &driver_version); + if (!W_ERROR_IS_OK(result)) { + return werror_to_ntstatus(result); } - return status; + return NT_STATUS_OK; } NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, @@ -205,13 +151,11 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, unsigned char *data, size_t length) { - struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; - struct policy_handle hnd; + struct dcerpc_binding_handle *b = winreg_pipe->binding_handle; enum ndr_err_code ndr_err; struct ntprinting_printer r; struct spoolss_SetPrinterInfo2 info2; struct spoolss_DeviceMode dm; - struct spoolss_SetPrinterInfoCtr info_ctr; struct spoolss_DevmodeContainer devmode_ctr; struct sec_desc_buf secdesc_ctr; DATA_BLOB blob; @@ -239,26 +183,6 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, ZERO_STRUCT(devmode_ctr); - status = dcerpc_spoolss_OpenPrinter(b, - mem_ctx, - key_name, - NULL, - devmode_ctr, - SEC_FLAG_MAXIMUM_ALLOWED, - &hnd, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("dcerpc_spoolss_OpenPrinter(%s) failed: %s\n", - key_name, nt_errstr(status))); - return status; - } - if (!W_ERROR_IS_OK(result)) { - DEBUG(2, ("OpenPrinter(%s) failed: %s\n", - key_name, win_errstr(result))); - status = werror_to_ntstatus(result); - return status; - } - /* Create printer info level 2 */ ZERO_STRUCT(info2); ZERO_STRUCT(secdesc_ctr); @@ -329,22 +253,12 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, info2.devmode_ptr = 1; } - info_ctr.info.info2 = &info2; - info_ctr.level = 2; - - status = dcerpc_spoolss_SetPrinter(b, - mem_ctx, - &hnd, - &info_ctr, - &devmode_ctr, - &secdesc_ctr, - 0, /* command */ - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("dcerpc_spoolss_SetPrinter(%s) level 2 refused -- %s.\n", - key_name, nt_errstr(status))); - goto done; - } + result = winreg_update_printer(mem_ctx, b, + key_name, + 0, /// FIXME !!!!!!!!!!!!!!!!!!!!!!! + &info2, + &dm, + NULL); if (!W_ERROR_IS_OK(result)) { DEBUG(2, ("SetPrinter(%s) level 2 refused -- %s.\n", key_name, win_errstr(result))); @@ -370,23 +284,13 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, valuename++; } - status = dcerpc_spoolss_SetPrinterDataEx(b, - mem_ctx, - &hnd, - keyname, - valuename, - r.printer_data[j].type, - r.printer_data[j].data.data, - r.printer_data[j].data.length, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("dcerpc_spoolss_SetPrinterDataEx: " - "printer [%s], keyname [%s], " - "valuename [%s] refused -- %s.\n", - key_name, keyname, valuename, - nt_errstr(status))); - break; - } + result = winreg_set_printer_dataex(mem_ctx, b, + key_name, + keyname, + valuename, + r.printer_data[j].type, + r.printer_data[j].data.data, + r.printer_data[j].data.length); if (!W_ERROR_IS_OK(result)) { DEBUG(2, ("SetPrinterDataEx: printer [%s], keyname [%s], " "valuename [%s] refused -- %s.\n", @@ -398,7 +302,6 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, } done: - dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result); return status; } @@ -410,15 +313,10 @@ NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx, unsigned char *data, size_t length) { - struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; - struct policy_handle hnd; + struct dcerpc_binding_handle *b = winreg_pipe->binding_handle; enum ndr_err_code ndr_err; struct sec_desc_buf secdesc_ctr; - struct spoolss_SetPrinterInfo3 info3; - struct spoolss_SetPrinterInfoCtr info_ctr; - struct spoolss_DevmodeContainer devmode_ctr; DATA_BLOB blob; - NTSTATUS status; WERROR result; if (strequal(key_name, "printers")) { @@ -439,53 +337,12 @@ NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx, DEBUG(2, ("Migrating Security Descriptor: %s\n", key_name)); - ZERO_STRUCT(devmode_ctr); - - status = dcerpc_spoolss_OpenPrinter(b, - mem_ctx, + result = winreg_set_printer_secdesc(mem_ctx, b, key_name, - NULL, - devmode_ctr, - SEC_FLAG_MAXIMUM_ALLOWED, - &hnd, - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("dcerpc_spoolss_OpenPrinter(%s) failed: %s\n", - key_name, nt_errstr(status))); - return status; - } + secdesc_ctr.sd); if (!W_ERROR_IS_OK(result)) { - DEBUG(2, ("OpenPrinter(%s) failed: %s\n", - key_name, win_errstr(result))); - status = werror_to_ntstatus(result); - return status; + return werror_to_ntstatus(result); } - ZERO_STRUCT(devmode_ctr); - - info3.sec_desc_ptr = 1; - - info_ctr.info.info3 = &info3; - info_ctr.level = 3; - - status = dcerpc_spoolss_SetPrinter(b, - mem_ctx, - &hnd, - &info_ctr, - &devmode_ctr, - &secdesc_ctr, - 0, /* command */ - &result); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("dcerpc_spoolss_SetPrinter(%s) level 3 refused -- %s.\n", - key_name, nt_errstr(status))); - } else if (!W_ERROR_IS_OK(result)) { - DEBUG(2, ("SetPrinter(%s) level 3 refused -- %s.\n", - key_name, win_errstr(result))); - status = werror_to_ntstatus(result); - } - - dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result); - - return status; + return NT_STATUS_OK; } -- 1.7.6 From f4f163d83878acda7eea2124b39c2838c6d98005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 5 Jul 2011 02:33:23 +0200 Subject: [PATCH 17/21] s3-printing: remove spoolss pipe from migration library, only using winreg finally. Guenther Pair-Programmed-With: David Disseldorp (cherry picked from commit 57bbb32c64db1027e2b9ae1aef7f5f3b33ae3882) --- source3/printing/nt_printing_migrate.c | 4 --- source3/printing/nt_printing_migrate.h | 4 --- source3/printing/nt_printing_migrate_internal.c | 25 ++-------------------- source3/utils/net_printing.c | 18 +-------------- 4 files changed, 5 insertions(+), 46 deletions(-) diff --git a/source3/printing/nt_printing_migrate.c b/source3/printing/nt_printing_migrate.c index 5166a75..beead16 100644 --- a/source3/printing/nt_printing_migrate.c +++ b/source3/printing/nt_printing_migrate.c @@ -28,7 +28,6 @@ #include "rpc_client/cli_winreg_spoolss.h" NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, @@ -82,7 +81,6 @@ NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx, } NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, @@ -145,7 +143,6 @@ NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx, } NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, @@ -307,7 +304,6 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, } NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, diff --git a/source3/printing/nt_printing_migrate.h b/source3/printing/nt_printing_migrate.h index 707ddc9..3da8db4 100644 --- a/source3/printing/nt_printing_migrate.h +++ b/source3/printing/nt_printing_migrate.h @@ -22,25 +22,21 @@ #define _NT_PRINTING_MIGRATE_H_ NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, size_t length); NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, size_t length); NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, size_t length); NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_hnd, struct rpc_pipe_client *winreg_pipe, const char *key_name, unsigned char *data, diff --git a/source3/printing/nt_printing_migrate_internal.c b/source3/printing/nt_printing_migrate_internal.c index bc4129e..f298863 100644 --- a/source3/printing/nt_printing_migrate_internal.c +++ b/source3/printing/nt_printing_migrate_internal.c @@ -66,7 +66,6 @@ static int rename_file_with_suffix(TALLOC_CTX *mem_ctx, static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, const char *tdb_path, - struct rpc_pipe_client *pipe_hnd, struct rpc_pipe_client *winreg_pipe) { const char *backup_suffix = ".bak"; @@ -98,7 +97,6 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) { status = printing_tdb_migrate_form(mem_ctx, - pipe_hnd, winreg_pipe, (const char *) kbuf.dptr + strlen(FORMS_PREFIX), dbuf.dptr, @@ -113,7 +111,6 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) { status = printing_tdb_migrate_driver(mem_ctx, - pipe_hnd, winreg_pipe, (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX), dbuf.dptr, @@ -130,7 +127,6 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, const char *printer_name = (const char *)(kbuf.dptr + strlen(PRINTERS_PREFIX)); status = printing_tdb_migrate_printer(mem_ctx, - pipe_hnd, winreg_pipe, printer_name, dbuf.dptr, @@ -152,7 +148,6 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, const char *secdesc_name = (const char *)(kbuf.dptr + strlen(SECDESC_PREFIX)); status = printing_tdb_migrate_secdesc(mem_ctx, - pipe_hnd, winreg_pipe, secdesc_name, dbuf.dptr, @@ -191,7 +186,6 @@ bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx) bool printers_exists = file_exist(printers_path); bool forms_exists = file_exist(forms_path); struct auth_serversupplied_info *session_info; - struct rpc_pipe_client *spoolss_pipe = NULL; struct rpc_pipe_client *winreg_pipe = NULL; TALLOC_CTX *tmp_ctx = talloc_stackframe(); NTSTATUS status; @@ -209,19 +203,6 @@ bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx) } status = rpc_pipe_open_interface(tmp_ctx, - &ndr_table_spoolss.syntax_id, - session_info, - NULL, - msg_ctx, - &spoolss_pipe); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Couldn't open internal spoolss pipe: %s\n", - nt_errstr(status))); - talloc_free(tmp_ctx); - return false; - } - - status = rpc_pipe_open_interface(tmp_ctx, &ndr_table_winreg.syntax_id, session_info, NULL, @@ -235,7 +216,7 @@ bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx) } if (drivers_exists) { - status = migrate_internal(tmp_ctx, drivers_path, spoolss_pipe, winreg_pipe); + status = migrate_internal(tmp_ctx, drivers_path, winreg_pipe); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Couldn't migrate drivers tdb file: %s\n", nt_errstr(status))); @@ -245,7 +226,7 @@ bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx) } if (printers_exists) { - status = migrate_internal(tmp_ctx, printers_path, spoolss_pipe, winreg_pipe); + status = migrate_internal(tmp_ctx, printers_path, winreg_pipe); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Couldn't migrate printers tdb file: %s\n", nt_errstr(status))); @@ -255,7 +236,7 @@ bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx) } if (forms_exists) { - status = migrate_internal(tmp_ctx, forms_path, spoolss_pipe, winreg_pipe); + status = migrate_internal(tmp_ctx, forms_path, winreg_pipe); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Couldn't migrate forms tdb file: %s\n", nt_errstr(status))); diff --git a/source3/utils/net_printing.c b/source3/utils/net_printing.c index df7b56a..29973ed 100644 --- a/source3/utils/net_printing.c +++ b/source3/utils/net_printing.c @@ -224,7 +224,7 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, - struct rpc_pipe_client *pipe_hnd, + struct rpc_pipe_client *winreg_pipe, TALLOC_CTX *mem_ctx, int argc, const char **argv) @@ -233,22 +233,12 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, TDB_CONTEXT *tdb; TDB_DATA kbuf, newkey, dbuf; NTSTATUS status; - struct rpc_pipe_client *winreg_pipe = NULL; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { return NT_STATUS_NO_MEMORY; } - status = cli_rpc_pipe_open_noauth(rpc_pipe_np_smb_conn(pipe_hnd), - &ndr_table_winreg.syntax_id, - &winreg_pipe); - if (!NT_STATUS_IS_OK(status)) { - d_fprintf(stderr, _("failed to open winreg pipe: %s\n"), - nt_errstr(status)); - goto done; - } - tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600); if (tdb == NULL) { d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]); @@ -267,7 +257,6 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) { printing_tdb_migrate_form(tmp_ctx, - pipe_hnd, winreg_pipe, (const char *) kbuf.dptr + strlen(FORMS_PREFIX), dbuf.dptr, @@ -278,7 +267,6 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) { printing_tdb_migrate_driver(tmp_ctx, - pipe_hnd, winreg_pipe, (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX), dbuf.dptr, @@ -289,7 +277,6 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) { printing_tdb_migrate_printer(tmp_ctx, - pipe_hnd, winreg_pipe, (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX), dbuf.dptr, @@ -300,7 +287,6 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) { printing_tdb_migrate_secdesc(tmp_ctx, - pipe_hnd, winreg_pipe, (const char *) kbuf.dptr + strlen(SECDESC_PREFIX), dbuf.dptr, @@ -333,7 +319,7 @@ static int net_printing_migrate(struct net_context *c, return run_rpc_command(c, NULL, - &ndr_table_spoolss.syntax_id, + &ndr_table_winreg.syntax_id, 0, printing_migrate_internal, argc, -- 1.7.6 From 7cd5becbfb69855fe166edb13cc5a86db9c7a98f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Tue, 5 Jul 2011 14:01:40 +0200 Subject: [PATCH 18/21] s3-printing: make sure to first migrate the printers then the security descriptor. Guenther Pair-Programmed-With: David Disseldorp (cherry picked from commit cfc3b6e5f79f253e83dfbd13d47b671deb5801b3) --- source3/printing/nt_printing_migrate_internal.c | 20 ++++++++++++++++---- source3/utils/net_printing.c | 12 ++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/source3/printing/nt_printing_migrate_internal.c b/source3/printing/nt_printing_migrate_internal.c index f298863..84b0c31 100644 --- a/source3/printing/nt_printing_migrate_internal.c +++ b/source3/printing/nt_printing_migrate_internal.c @@ -143,6 +143,17 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, } continue; } + SAFE_FREE(dbuf.dptr); + } + + for (kbuf = tdb_firstkey(tdb); + kbuf.dptr; + newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey) + { + dbuf = tdb_fetch(tdb, kbuf); + if (!dbuf.dptr) { + continue; + } if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) { const char *secdesc_name = (const char *)(kbuf.dptr @@ -154,16 +165,17 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, dbuf.dsize); SAFE_FREE(dbuf.dptr); /* currently no WERR_INVALID_PRINTER_NAME equivalent */ - if (NT_STATUS_EQUAL(status, - werror_to_ntstatus(WERR_INVALID_PRINTER_NAME))) { - DEBUG(2, ("Skipping migration for non-existent " - "secdesc: %s\n", secdesc_name)); + if (NT_STATUS_EQUAL(status, werror_to_ntstatus(WERR_INVALID_PRINTER_NAME)) || + NT_STATUS_EQUAL(status, werror_to_ntstatus(WERR_BADFILE))) { + DEBUG(2, ("Skipping secdesc migration for non-existent " + "printer: %s\n", secdesc_name)); } else if (!NT_STATUS_IS_OK(status)) { tdb_close(tdb); return status; } continue; } + SAFE_FREE(dbuf.dptr); } tdb_close(tdb); diff --git a/source3/utils/net_printing.c b/source3/utils/net_printing.c index 29973ed..a52d31f 100644 --- a/source3/utils/net_printing.c +++ b/source3/utils/net_printing.c @@ -284,6 +284,17 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, SAFE_FREE(dbuf.dptr); continue; } + SAFE_FREE(dbuf.dptr); + } + + for (kbuf = tdb_firstkey(tdb); + kbuf.dptr; + newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey) + { + dbuf = tdb_fetch(tdb, kbuf); + if (!dbuf.dptr) { + continue; + } if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) { printing_tdb_migrate_secdesc(tmp_ctx, @@ -294,6 +305,7 @@ static NTSTATUS printing_migrate_internal(struct net_context *c, SAFE_FREE(dbuf.dptr); continue; } + SAFE_FREE(dbuf.dptr); } -- 1.7.6 From aa6667c90da6b4379d3685db047fed8494dacd13 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Tue, 5 Jul 2011 11:34:47 +0200 Subject: [PATCH 19/21] s3-printing: fill info2_mask in printer migration Also fix possibly uninitialised status return from printing_tdb_migrate_printer(). (cherry picked from commit 5dd8185d852afc3843253c9471326677f8816a77) --- source3/printing/nt_printing_migrate.c | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/source3/printing/nt_printing_migrate.c b/source3/printing/nt_printing_migrate.c index beead16..9320448 100644 --- a/source3/printing/nt_printing_migrate.c +++ b/source3/printing/nt_printing_migrate.c @@ -154,11 +154,12 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, struct spoolss_SetPrinterInfo2 info2; struct spoolss_DeviceMode dm; struct spoolss_DevmodeContainer devmode_ctr; - struct sec_desc_buf secdesc_ctr; DATA_BLOB blob; NTSTATUS status; WERROR result; int j; + uint32_t info2_mask = (SPOOLSS_PRINTER_INFO_ALL) + & ~SPOOLSS_PRINTER_INFO_SECDESC; if (strequal(key_name, "printers")) { return NT_STATUS_OK; @@ -182,7 +183,6 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, /* Create printer info level 2 */ ZERO_STRUCT(info2); - ZERO_STRUCT(secdesc_ctr); info2.attributes = r.info.attributes; info2.averageppm = r.info.averageppm; @@ -204,7 +204,9 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, info2.untiltime = r.info.untiltime; /* Create Device Mode */ - if (r.devmode != NULL) { + if (r.devmode == NULL) { + info2_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE; + } else { ZERO_STRUCT(dm); dm.bitsperpel = r.devmode->bitsperpel; @@ -252,7 +254,7 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, result = winreg_update_printer(mem_ctx, b, key_name, - 0, /// FIXME !!!!!!!!!!!!!!!!!!!!!!! + info2_mask, &info2, &dm, NULL); @@ -298,6 +300,7 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx, } } + status = NT_STATUS_OK; done: return status; -- 1.7.6 From 37a2693289dd5b35720e5fda1de8166e86099dc3 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Tue, 5 Jul 2011 15:04:02 +0200 Subject: [PATCH 20/21] s3-printing: remove tdb migration invalid printer name checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WERR_INVALID_PRINTER_NAME only needed to be handled when printing tdb migration used spoolss, with winreg such errors are no longer possible. Signed-off-by: Günther Deschner Autobuild-User: Günther Deschner Autobuild-Date: Thu Jul 7 19:15:34 CEST 2011 on sn-devel-104 (cherry picked from commit e5955903fdc5ed6f8660b72db0716d4da25c711c) --- source3/printing/nt_printing_migrate_internal.c | 11 ++--------- 1 files changed, 2 insertions(+), 9 deletions(-) diff --git a/source3/printing/nt_printing_migrate_internal.c b/source3/printing/nt_printing_migrate_internal.c index 84b0c31..5d8edc7 100644 --- a/source3/printing/nt_printing_migrate_internal.c +++ b/source3/printing/nt_printing_migrate_internal.c @@ -132,12 +132,7 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); - /* currently no WERR_INVALID_PRINTER_NAME equivalent */ - if (NT_STATUS_EQUAL(status, - werror_to_ntstatus(WERR_INVALID_PRINTER_NAME))) { - DEBUG(2, ("Skipping migration for non-existent " - "printer: %s\n", printer_name)); - } else if (!NT_STATUS_IS_OK(status)) { + if (!NT_STATUS_IS_OK(status)) { tdb_close(tdb); return status; } @@ -164,9 +159,7 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx, dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); - /* currently no WERR_INVALID_PRINTER_NAME equivalent */ - if (NT_STATUS_EQUAL(status, werror_to_ntstatus(WERR_INVALID_PRINTER_NAME)) || - NT_STATUS_EQUAL(status, werror_to_ntstatus(WERR_BADFILE))) { + if (NT_STATUS_EQUAL(status, werror_to_ntstatus(WERR_BADFILE))) { DEBUG(2, ("Skipping secdesc migration for non-existent " "printer: %s\n", secdesc_name)); } else if (!NT_STATUS_IS_OK(status)) { -- 1.7.6 From ba61ee300a192e23abcd9c23af0bec2c1e29e6f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Fri, 8 Jul 2011 17:17:17 +0200 Subject: [PATCH 21/21] s3-waf: split out LIBCLI_WINREG_INTERNAL as LIBCLI_WINREG was pulling in rpc server code in undesired places. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Andreas, please check. Guenther Autobuild-User: Günther Deschner Autobuild-Date: Fri Jul 8 18:34:44 CEST 2011 on sn-devel-104 (cherry picked from commit f4add4fbf545313f5d24e0d9e5c9eb0f8fac630a) Conflicts: source3/rpc_server/wscript_build source3/wscript_build --- source3/rpc_server/wscript_build | 6 +++--- source3/wscript_build | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/source3/rpc_server/wscript_build b/source3/rpc_server/wscript_build index 346d770..65f1c17 100644 --- a/source3/rpc_server/wscript_build +++ b/source3/rpc_server/wscript_build @@ -77,7 +77,7 @@ bld.SAMBA3_SUBSYSTEM('RPC_WKSSVC', bld.SAMBA3_SUBSYSTEM('RPC_SVCCTL', source=RPC_SVCCTL_SRC, - deps='SERVICES LIBCLI_WINREG', + deps='SERVICES LIBCLI_WINREG_INTERNAL', vars=locals()) bld.SAMBA3_SUBSYSTEM('RPC_NTSVCS', @@ -98,12 +98,12 @@ bld.SAMBA3_SUBSYSTEM('RPC_SRVSVC', bld.SAMBA3_SUBSYSTEM('RPC_SPOOLSS', source=RPC_SPOOLSS_SRC, - deps='cups PRINTING PRINTBACKEND LIBCLI_WINREG', + deps='cups PRINTING PRINTBACKEND LIBCLI_WINREG_INTERNAL', vars=locals()) bld.SAMBA3_SUBSYSTEM('RPC_EVENTLOG', source=RPC_EVENTLOG_SRC, - deps='LIBEVENTLOG LIBCLI_WINREG', + deps='LIBEVENTLOG LIBCLI_WINREG_INTERNAL', vars=locals()) bld.SAMBA3_SUBSYSTEM('RPC_RPCECHO', diff --git a/source3/wscript_build b/source3/wscript_build index 4d47acb..40935d1 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -50,9 +50,6 @@ LIBCLI_SAMR_SRC = 'rpc_client/cli_samr.c' LIBRPCCLI_NETLOGON_SRC = 'rpc_client/cli_netlogon.c rpc_client/util_netlogon.c' -LIBCLI_WINREG_SRC = '''rpc_client/cli_winreg.c - rpc_client/cli_winreg_int.c''' - # this includes only the low level parse code, not stuff # that requires knowledge of security contexts REG_PARSE_PRS_SRC = '''registry/reg_parse_prs.c''' @@ -1002,9 +999,13 @@ bld.SAMBA3_LIBRARY('LIBCLI_SPOOLSS', private_library=True) bld.SAMBA3_SUBSYSTEM('LIBCLI_WINREG', - source=LIBCLI_WINREG_SRC, + source='rpc_client/cli_winreg.c', deps='RPC_NDR_WINREG') +bld.SAMBA3_SUBSYSTEM('LIBCLI_WINREG_INTERNAL', + source='rpc_client/cli_winreg_int.c', + deps='LIBCLI_WINREG RPC_NCACN_NP') + bld.SAMBA3_SUBSYSTEM('RPC_CLIENT_SCHANNEL', source=RPC_CLIENT_SCHANNEL_SRC, vars=locals()) -- 1.7.6