From e02abd6c83708f297b1985bb1bdc7d5dfbc924b2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 1 Jul 2011 14:57:32 +0200 Subject: s3-printing: split out printing migration code into a smaller library. Guenther --- 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 +- 5 files changed, 317 insertions(+), 246 deletions(-) create mode 100644 source3/printing/nt_printing_migrate_internal.c create mode 100644 source3/printing/nt_printing_migrate_internal.h (limited to 'source3/printing') diff --git a/source3/printing/nt_printing_migrate.c b/source3/printing/nt_printing_migrate.c index 79145852e7..dc3f3694b7 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, 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_compat(tdb); - kbuf.dptr; - kbuf = tdb_nextkey_compat(tdb, kbuf)) - { - dbuf = tdb_fetch_compat(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 9ab2fa7dae..4991d06bd3 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 0000000000..59f6d33a76 --- /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, 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_compat(tdb); + kbuf.dptr; + kbuf = tdb_nextkey_compat(tdb, kbuf)) + { + dbuf = tdb_fetch_compat(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 0000000000..dfcf9142e9 --- /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 896aee0a53..cb90a9f7c7 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" -- cgit