| 1 | /*
|
|---|
| 2 | * Unix SMB/CIFS implementation.
|
|---|
| 3 | * RPC Pipe client / server routines
|
|---|
| 4 | *
|
|---|
| 5 | * Copyright (c) Andreas Schneider 2010.
|
|---|
| 6 | *
|
|---|
| 7 | * This program is free software; you can redistribute it and/or modify
|
|---|
| 8 | * it under the terms of the GNU General Public License as published by
|
|---|
| 9 | * the Free Software Foundation; either version 3 of the License, or
|
|---|
| 10 | * (at your option) any later version.
|
|---|
| 11 | *
|
|---|
| 12 | * This program is distributed in the hope that it will be useful,
|
|---|
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 15 | * GNU General Public License for more details.
|
|---|
| 16 | *
|
|---|
| 17 | * You should have received a copy of the GNU General Public License
|
|---|
| 18 | * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|---|
| 19 | */
|
|---|
| 20 |
|
|---|
| 21 | #include "includes.h"
|
|---|
| 22 | #include "system/filesys.h"
|
|---|
| 23 | #include "printing/nt_printing_migrate.h"
|
|---|
| 24 | #include "printing/nt_printing_migrate_internal.h"
|
|---|
| 25 |
|
|---|
| 26 | #include "rpc_client/rpc_client.h"
|
|---|
| 27 | #include "librpc/gen_ndr/ndr_spoolss_c.h"
|
|---|
| 28 | #include "librpc/gen_ndr/ndr_winreg.h"
|
|---|
| 29 | #include "rpc_server/rpc_ncacn_np.h"
|
|---|
| 30 | #include "auth.h"
|
|---|
| 31 | #include "util_tdb.h"
|
|---|
| 32 |
|
|---|
| 33 | #define FORMS_PREFIX "FORMS/"
|
|---|
| 34 | #define DRIVERS_PREFIX "DRIVERS/"
|
|---|
| 35 | #define PRINTERS_PREFIX "PRINTERS/"
|
|---|
| 36 | #define SECDESC_PREFIX "SECDESC/"
|
|---|
| 37 |
|
|---|
| 38 | static int rename_file_with_suffix(TALLOC_CTX *mem_ctx,
|
|---|
| 39 | const char *path,
|
|---|
| 40 | const char *suffix)
|
|---|
| 41 | {
|
|---|
| 42 | int rc = -1;
|
|---|
| 43 | char *dst_path;
|
|---|
| 44 |
|
|---|
| 45 | dst_path = talloc_asprintf(mem_ctx, "%s%s", path, suffix);
|
|---|
| 46 | if (dst_path == NULL) {
|
|---|
| 47 | DEBUG(3, ("error out of memory\n"));
|
|---|
| 48 | return rc;
|
|---|
| 49 | }
|
|---|
| 50 |
|
|---|
| 51 | rc = (rename(path, dst_path) != 0);
|
|---|
| 52 |
|
|---|
| 53 | if (rc == 0) {
|
|---|
| 54 | DEBUG(5, ("moved '%s' to '%s'\n", path, dst_path));
|
|---|
| 55 | } else if (errno == ENOENT) {
|
|---|
| 56 | DEBUG(3, ("file '%s' does not exist - so not moved\n", path));
|
|---|
| 57 | rc = 0;
|
|---|
| 58 | } else {
|
|---|
| 59 | DEBUG(3, ("error renaming %s to %s: %s\n", path, dst_path,
|
|---|
| 60 | strerror(errno)));
|
|---|
| 61 | }
|
|---|
| 62 |
|
|---|
| 63 | TALLOC_FREE(dst_path);
|
|---|
| 64 | return rc;
|
|---|
| 65 | }
|
|---|
| 66 |
|
|---|
| 67 | static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx,
|
|---|
| 68 | const char *tdb_path,
|
|---|
| 69 | struct rpc_pipe_client *winreg_pipe)
|
|---|
| 70 | {
|
|---|
| 71 | const char *backup_suffix = ".bak";
|
|---|
| 72 | TDB_DATA kbuf, newkey, dbuf;
|
|---|
| 73 | TDB_CONTEXT *tdb;
|
|---|
| 74 | NTSTATUS status;
|
|---|
| 75 | int rc;
|
|---|
| 76 |
|
|---|
| 77 | tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDONLY, 0600);
|
|---|
| 78 | if (tdb == NULL && errno == ENOENT) {
|
|---|
| 79 | /* if we have no printers database then migration is
|
|---|
| 80 | considered successful */
|
|---|
| 81 | DEBUG(4, ("No printers database to migrate in %s\n", tdb_path));
|
|---|
| 82 | return NT_STATUS_OK;
|
|---|
| 83 | }
|
|---|
| 84 | if (tdb == NULL) {
|
|---|
| 85 | DEBUG(2, ("Failed to open tdb file: %s\n", tdb_path));
|
|---|
| 86 | return NT_STATUS_NO_SUCH_FILE;
|
|---|
| 87 | }
|
|---|
| 88 |
|
|---|
| 89 | for (kbuf = tdb_firstkey(tdb);
|
|---|
| 90 | kbuf.dptr;
|
|---|
| 91 | newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
|
|---|
| 92 | {
|
|---|
| 93 | dbuf = tdb_fetch(tdb, kbuf);
|
|---|
| 94 | if (!dbuf.dptr) {
|
|---|
| 95 | continue;
|
|---|
| 96 | }
|
|---|
| 97 |
|
|---|
| 98 | if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
|
|---|
| 99 | status = printing_tdb_migrate_form(mem_ctx,
|
|---|
| 100 | winreg_pipe,
|
|---|
| 101 | (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
|
|---|
| 102 | dbuf.dptr,
|
|---|
| 103 | dbuf.dsize);
|
|---|
| 104 | SAFE_FREE(dbuf.dptr);
|
|---|
| 105 | if (!NT_STATUS_IS_OK(status)) {
|
|---|
| 106 | tdb_close(tdb);
|
|---|
| 107 | return status;
|
|---|
| 108 | }
|
|---|
| 109 | continue;
|
|---|
| 110 | }
|
|---|
| 111 |
|
|---|
| 112 | if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
|
|---|
| 113 | status = printing_tdb_migrate_driver(mem_ctx,
|
|---|
| 114 | winreg_pipe,
|
|---|
| 115 | (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
|
|---|
| 116 | dbuf.dptr,
|
|---|
| 117 | dbuf.dsize,
|
|---|
| 118 | false);
|
|---|
| 119 | SAFE_FREE(dbuf.dptr);
|
|---|
| 120 | if (!NT_STATUS_IS_OK(status)) {
|
|---|
| 121 | tdb_close(tdb);
|
|---|
| 122 | return status;
|
|---|
| 123 | }
|
|---|
| 124 | continue;
|
|---|
| 125 | }
|
|---|
| 126 |
|
|---|
| 127 | if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
|
|---|
| 128 | const char *printer_name = (const char *)(kbuf.dptr
|
|---|
| 129 | + strlen(PRINTERS_PREFIX));
|
|---|
| 130 | status = printing_tdb_migrate_printer(mem_ctx,
|
|---|
| 131 | winreg_pipe,
|
|---|
| 132 | printer_name,
|
|---|
| 133 | dbuf.dptr,
|
|---|
| 134 | dbuf.dsize,
|
|---|
| 135 | false);
|
|---|
| 136 | SAFE_FREE(dbuf.dptr);
|
|---|
| 137 | if (!NT_STATUS_IS_OK(status)) {
|
|---|
| 138 | tdb_close(tdb);
|
|---|
| 139 | return status;
|
|---|
| 140 | }
|
|---|
| 141 | continue;
|
|---|
| 142 | }
|
|---|
| 143 | SAFE_FREE(dbuf.dptr);
|
|---|
| 144 | }
|
|---|
| 145 |
|
|---|
| 146 | for (kbuf = tdb_firstkey(tdb);
|
|---|
| 147 | kbuf.dptr;
|
|---|
| 148 | newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
|
|---|
| 149 | {
|
|---|
| 150 | dbuf = tdb_fetch(tdb, kbuf);
|
|---|
| 151 | if (!dbuf.dptr) {
|
|---|
| 152 | continue;
|
|---|
| 153 | }
|
|---|
| 154 |
|
|---|
| 155 | if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
|
|---|
| 156 | const char *secdesc_name = (const char *)(kbuf.dptr
|
|---|
| 157 | + strlen(SECDESC_PREFIX));
|
|---|
| 158 | status = printing_tdb_migrate_secdesc(mem_ctx,
|
|---|
| 159 | winreg_pipe,
|
|---|
| 160 | secdesc_name,
|
|---|
| 161 | dbuf.dptr,
|
|---|
| 162 | dbuf.dsize);
|
|---|
| 163 | SAFE_FREE(dbuf.dptr);
|
|---|
| 164 | if (NT_STATUS_EQUAL(status, werror_to_ntstatus(WERR_BADFILE))) {
|
|---|
| 165 | DEBUG(2, ("Skipping secdesc migration for non-existent "
|
|---|
| 166 | "printer: %s\n", secdesc_name));
|
|---|
| 167 | } else if (!NT_STATUS_IS_OK(status)) {
|
|---|
| 168 | tdb_close(tdb);
|
|---|
| 169 | return status;
|
|---|
| 170 | }
|
|---|
| 171 | continue;
|
|---|
| 172 | }
|
|---|
| 173 | SAFE_FREE(dbuf.dptr);
|
|---|
| 174 | }
|
|---|
| 175 |
|
|---|
| 176 | tdb_close(tdb);
|
|---|
| 177 |
|
|---|
| 178 | rc = rename_file_with_suffix(mem_ctx, tdb_path, backup_suffix);
|
|---|
| 179 | if (rc != 0) {
|
|---|
| 180 | DEBUG(0, ("Error moving tdb to '%s%s'\n",
|
|---|
| 181 | tdb_path, backup_suffix));
|
|---|
| 182 | }
|
|---|
| 183 |
|
|---|
| 184 | return NT_STATUS_OK;
|
|---|
| 185 | }
|
|---|
| 186 |
|
|---|
| 187 | bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx)
|
|---|
| 188 | {
|
|---|
| 189 | const char *drivers_path = state_path("ntdrivers.tdb");
|
|---|
| 190 | const char *printers_path = state_path("ntprinters.tdb");
|
|---|
| 191 | const char *forms_path = state_path("ntforms.tdb");
|
|---|
| 192 | bool drivers_exists = file_exist(drivers_path);
|
|---|
| 193 | bool printers_exists = file_exist(printers_path);
|
|---|
| 194 | bool forms_exists = file_exist(forms_path);
|
|---|
| 195 | struct auth_serversupplied_info *session_info;
|
|---|
| 196 | struct rpc_pipe_client *winreg_pipe = NULL;
|
|---|
| 197 | TALLOC_CTX *tmp_ctx = talloc_stackframe();
|
|---|
| 198 | NTSTATUS status;
|
|---|
| 199 |
|
|---|
| 200 | if (!drivers_exists && !printers_exists && !forms_exists) {
|
|---|
| 201 | return true;
|
|---|
| 202 | }
|
|---|
| 203 |
|
|---|
| 204 | status = make_session_info_system(tmp_ctx, &session_info);
|
|---|
| 205 | if (!NT_STATUS_IS_OK(status)) {
|
|---|
| 206 | DEBUG(0, ("Couldn't create session_info: %s\n",
|
|---|
| 207 | nt_errstr(status)));
|
|---|
| 208 | talloc_free(tmp_ctx);
|
|---|
| 209 | return false;
|
|---|
| 210 | }
|
|---|
| 211 |
|
|---|
| 212 | status = rpc_pipe_open_interface(tmp_ctx,
|
|---|
| 213 | &ndr_table_winreg.syntax_id,
|
|---|
| 214 | session_info,
|
|---|
| 215 | NULL,
|
|---|
| 216 | msg_ctx,
|
|---|
| 217 | &winreg_pipe);
|
|---|
| 218 | if (!NT_STATUS_IS_OK(status)) {
|
|---|
| 219 | DEBUG(0, ("Couldn't open internal winreg pipe: %s\n",
|
|---|
| 220 | nt_errstr(status)));
|
|---|
| 221 | talloc_free(tmp_ctx);
|
|---|
| 222 | return false;
|
|---|
| 223 | }
|
|---|
| 224 |
|
|---|
| 225 | if (drivers_exists) {
|
|---|
| 226 | status = migrate_internal(tmp_ctx, drivers_path, winreg_pipe);
|
|---|
| 227 | if (!NT_STATUS_IS_OK(status)) {
|
|---|
| 228 | DEBUG(0, ("Couldn't migrate drivers tdb file: %s\n",
|
|---|
| 229 | nt_errstr(status)));
|
|---|
| 230 | talloc_free(tmp_ctx);
|
|---|
| 231 | return false;
|
|---|
| 232 | }
|
|---|
| 233 | }
|
|---|
| 234 |
|
|---|
| 235 | if (printers_exists) {
|
|---|
| 236 | status = migrate_internal(tmp_ctx, printers_path, winreg_pipe);
|
|---|
| 237 | if (!NT_STATUS_IS_OK(status)) {
|
|---|
| 238 | DEBUG(0, ("Couldn't migrate printers tdb file: %s\n",
|
|---|
| 239 | nt_errstr(status)));
|
|---|
| 240 | talloc_free(tmp_ctx);
|
|---|
| 241 | return false;
|
|---|
| 242 | }
|
|---|
| 243 | }
|
|---|
| 244 |
|
|---|
| 245 | if (forms_exists) {
|
|---|
| 246 | status = migrate_internal(tmp_ctx, forms_path, winreg_pipe);
|
|---|
| 247 | if (!NT_STATUS_IS_OK(status)) {
|
|---|
| 248 | DEBUG(0, ("Couldn't migrate forms tdb file: %s\n",
|
|---|
| 249 | nt_errstr(status)));
|
|---|
| 250 | talloc_free(tmp_ctx);
|
|---|
| 251 | return false;
|
|---|
| 252 | }
|
|---|
| 253 | }
|
|---|
| 254 |
|
|---|
| 255 | talloc_free(tmp_ctx);
|
|---|
| 256 | return true;
|
|---|
| 257 | }
|
|---|