2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Local printing tdb migration interface
6 Copyright (C) Guenther Deschner 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "system/filesys.h"
24 #include "utils/net.h"
25 #include "rpc_client/rpc_client.h"
26 #include "rpc_client/cli_pipe.h"
27 #include "librpc/gen_ndr/ndr_ntprinting.h"
28 #include "librpc/gen_ndr/ndr_spoolss.h"
29 #include "../libcli/security/security.h"
30 #include "../librpc/gen_ndr/ndr_security.h"
31 #include "../librpc/gen_ndr/ndr_winreg.h"
33 #include "printing/nt_printing_migrate.h"
35 #define FORMS_PREFIX "FORMS/"
36 #define FORMS_PREFIX_LEN 6
37 #define DRIVERS_PREFIX "DRIVERS/"
38 #define DRIVERS_PREFIX_LEN 8
39 #define PRINTERS_PREFIX "PRINTERS/"
40 #define PRINTERS_PREFIX_LEN 9
41 #define SECDESC_PREFIX "SECDESC/"
42 #define SECDESC_PREFIX_LEN 8
44 #define ARG_ENCODING "encoding="
46 struct printing_opts {
51 static NTSTATUS printing_parse_args(TALLOC_CTX *mem_ctx,
52 struct printing_opts **popts,
53 int argc, const char **argv)
56 struct printing_opts *o;
59 return NT_STATUS_INVALID_PARAMETER;
62 o = talloc_zero(mem_ctx, struct printing_opts);
64 return NT_STATUS_INVALID_PARAMETER;
67 for (c = 0; c < argc; c++) {
68 if (strnequal(argv[c], ARG_ENCODING, sizeof(ARG_ENCODING) - 1)) {
69 o->encoding = talloc_strdup(o,
70 argv[c] + sizeof(ARG_ENCODING) - 1);
71 if (o->encoding == NULL) {
72 return NT_STATUS_NO_MEMORY;
75 o->tdb = talloc_strdup(o, argv[c]);
77 return NT_STATUS_NO_MEMORY;
86 static void dump_form(TALLOC_CTX *mem_ctx,
91 enum ndr_err_code ndr_err;
94 struct ntprinting_form r;
96 printf("found form: %s\n", key_name);
98 blob = data_blob_const(data, length);
102 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
103 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
104 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
105 d_fprintf(stderr, _("form pull failed: %s\n"),
106 ndr_errstr(ndr_err));
110 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_form, &r);
116 static void dump_driver(TALLOC_CTX *mem_ctx,
117 const char *key_name,
120 bool do_string_conversion)
122 enum ndr_err_code ndr_err;
125 struct ntprinting_driver r;
127 printf("found driver: %s\n", key_name);
129 blob = data_blob_const(data, length);
133 if (do_string_conversion) {
134 r.string_flags = LIBNDR_FLAG_STR_ASCII;
137 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
138 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
139 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
140 d_fprintf(stderr, _("driver pull failed: %s\n"),
141 ndr_errstr(ndr_err));
145 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_driver, &r);
151 static void dump_printer(TALLOC_CTX *mem_ctx,
152 const char *key_name,
155 bool do_string_conversion)
157 enum ndr_err_code ndr_err;
160 struct ntprinting_printer r;
162 printf("found printer: %s\n", key_name);
164 blob = data_blob_const(data, length);
168 if (do_string_conversion) {
169 r.info.string_flags = LIBNDR_FLAG_STR_ASCII;
172 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
173 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_printer);
174 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
175 d_fprintf(stderr, _("printer pull failed: %s\n"),
176 ndr_errstr(ndr_err));
180 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_printer, &r);
186 static void dump_sd(TALLOC_CTX *mem_ctx,
187 const char *key_name,
191 enum ndr_err_code ndr_err;
194 struct sec_desc_buf r;
196 printf("found security descriptor: %s\n", key_name);
198 blob = data_blob_const(data, length);
202 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
203 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
204 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
205 d_fprintf(stderr, _("security descriptor pull failed: %s\n"),
206 ndr_errstr(ndr_err));
210 s = NDR_PRINT_STRUCT_STRING(mem_ctx, sec_desc_buf, &r);
217 static int net_printing_dump(struct net_context *c, int argc,
221 TALLOC_CTX *ctx = talloc_stackframe();
223 TDB_DATA kbuf, newkey, dbuf;
224 struct printing_opts *o;
225 const char *save_dos_charset = lp_dos_charset();
226 bool do_string_conversion = false;
229 if (argc < 1 || c->display_usage) {
231 "net printing dump [options] <file.tdb>\n"
234 _("Dump formatted printer information of the tdb."));
235 d_printf(_("Valid options:\n"));
236 d_printf(_(" encoding=<CP> Set the Code Page of the tdb file.\n"
237 " See iconv -l for the list of CP values\n"
238 " (CP1252 is Western latin1, CP1251 is Cyrillic).\n"));
242 status = printing_parse_args(ctx, &o, argc, argv);
243 if (!NT_STATUS_IS_OK(status)) {
244 d_fprintf(stderr, _("failed to parse arguments\n"));
248 tdb = tdb_open_log(o->tdb, 0, TDB_DEFAULT, O_RDONLY, 0600);
250 d_fprintf(stderr, _("failed to open tdb file: %s\n"), o->tdb);
254 if (o->encoding != NULL) {
255 lp_set_cmdline("dos charset", o->encoding);
256 d_fprintf(stderr, _("do string conversion from %s to %s\n"),
257 lp_dos_charset(), lp_unix_charset());
258 do_string_conversion = true;
261 for (kbuf = tdb_firstkey(tdb);
263 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf=newkey)
267 dbuf = tdb_fetch(tdb, kbuf);
272 cmp = strncmp((const char *)kbuf.dptr,
276 char *key_name = NULL;
277 size_t converted_size = 0;
280 ok = pull_ascii_talloc(ctx,
282 (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
288 dump_form(ctx, key_name, dbuf.dptr, dbuf.dsize);
289 TALLOC_FREE(key_name);
290 SAFE_FREE(dbuf.dptr);
294 cmp = strncmp((const char *)kbuf.dptr,
298 char *key_name = NULL;
299 size_t converted_size = 0;
302 ok = pull_ascii_talloc(ctx,
304 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
314 do_string_conversion);
315 TALLOC_FREE(key_name);
316 SAFE_FREE(dbuf.dptr);
320 cmp = strncmp((const char *)kbuf.dptr,
322 PRINTERS_PREFIX_LEN);
324 char *key_name = NULL;
325 size_t converted_size = 0;
328 ok = pull_ascii_talloc(ctx,
330 (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
340 do_string_conversion);
341 TALLOC_FREE(key_name);
342 SAFE_FREE(dbuf.dptr);
346 cmp = strncmp((const char *)kbuf.dptr,
350 dump_sd(ctx, (const char *)kbuf.dptr+strlen(SECDESC_PREFIX), dbuf.dptr, dbuf.dsize);
351 SAFE_FREE(dbuf.dptr);
360 lp_set_cmdline("dos charset", save_dos_charset);
365 static NTSTATUS printing_migrate_internal(struct net_context *c,
366 const struct dom_sid *domain_sid,
367 const char *domain_name,
368 struct cli_state *cli,
369 struct rpc_pipe_client *winreg_pipe,
374 struct printing_opts *o;
377 TDB_DATA kbuf, newkey, dbuf;
379 const char *save_dos_charset = lp_dos_charset();
380 bool do_string_conversion = false;
382 tmp_ctx = talloc_new(mem_ctx);
383 if (tmp_ctx == NULL) {
384 return NT_STATUS_NO_MEMORY;
387 status = printing_parse_args(tmp_ctx, &o, argc, argv);
388 if (!NT_STATUS_IS_OK(status)) {
389 d_fprintf(stderr, _("failed to parse arguments\n"));
393 tdb = tdb_open_log(o->tdb, 0, TDB_DEFAULT, O_RDONLY, 0600);
395 d_fprintf(stderr, _("failed to open tdb file: %s\n"), o->tdb);
396 status = NT_STATUS_NO_SUCH_FILE;
400 if (o->encoding != NULL) {
401 lp_set_cmdline("dos charset", o->encoding);
402 d_fprintf(stderr, _("do string conversion from %s to %s\n"),
403 lp_dos_charset(), lp_unix_charset());
404 do_string_conversion = true;
407 for (kbuf = tdb_firstkey(tdb);
409 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
413 dbuf = tdb_fetch(tdb, kbuf);
418 cmp = strncmp((const char *) kbuf.dptr,
422 char *key_name = NULL;
423 size_t converted_size = 0;
426 ok = pull_ascii_talloc(tmp_ctx,
428 (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
434 printing_tdb_migrate_form(tmp_ctx,
439 TALLOC_FREE(key_name);
440 SAFE_FREE(dbuf.dptr);
444 cmp = strncmp((const char *) kbuf.dptr,
448 char *key_name = NULL;
449 size_t converted_size = 0;
452 ok = pull_ascii_talloc(tmp_ctx,
454 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
460 printing_tdb_migrate_driver(tmp_ctx,
465 do_string_conversion);
466 TALLOC_FREE(key_name);
467 SAFE_FREE(dbuf.dptr);
471 cmp = strncmp((const char *) kbuf.dptr,
473 PRINTERS_PREFIX_LEN);
475 char *key_name = NULL;
476 size_t converted_size = 0;
479 ok = pull_ascii_talloc(tmp_ctx,
481 (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
487 printing_tdb_migrate_printer(tmp_ctx,
492 do_string_conversion);
493 TALLOC_FREE(key_name);
494 SAFE_FREE(dbuf.dptr);
497 SAFE_FREE(dbuf.dptr);
500 for (kbuf = tdb_firstkey(tdb);
502 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
504 dbuf = tdb_fetch(tdb, kbuf);
509 if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
510 printing_tdb_migrate_secdesc(tmp_ctx,
512 (const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
515 SAFE_FREE(dbuf.dptr);
518 SAFE_FREE(dbuf.dptr);
522 status = NT_STATUS_OK;
525 lp_set_cmdline("dos charset", save_dos_charset);
526 talloc_free(tmp_ctx);
530 static int net_printing_migrate(struct net_context *c,
534 if (argc < 1 || c->display_usage) {
536 "net printing migrate [options] <file.tdb>\n"
539 _("Migrate tdb printing files to new storage"));
540 d_printf(_("Valid options:\n"));
541 d_printf(_(" encoding=<CP> Set the Code Page of the tdb file.\n"
542 " See iconv -l for the list of CP values\n"
543 " (CP1252 is Western latin1, CP1251 is Cyrillic).\n"));
547 return run_rpc_command(c,
551 printing_migrate_internal,
556 * 'net printing' entrypoint.
557 * @param argc Standard main() style argc.
558 * @param argv Standard main() style argv. Initial components are already
562 int net_printing(struct net_context *c, int argc, const char **argv)
566 struct functable func[] = {
571 N_("Dump printer databases"),
572 N_("net printing dump\n"
573 " Dump tdb printing file")
578 net_printing_migrate,
579 NET_TRANSPORT_LOCAL | NET_TRANSPORT_RPC,
580 N_("Migrate printer databases"),
581 N_("net printing migrate\n"
582 " Migrate tdb printing files to new storage")
585 { NULL, NULL, 0, NULL, NULL }
588 ret = net_run_function(c, argc, argv, "net printing", func);