python: models: rename argument ldb to samdb
[samba.git] / source3 / utils / net_printing.c
blob04a3acc363645c020cb5d24425b1a7f55bef1e33
1 /*
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/>.
22 #include "includes.h"
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"
32 #include "util_tdb.h"
33 #include "printing/nt_printing_migrate.h"
34 #include "lib/param/param.h"
36 #define FORMS_PREFIX "FORMS/"
37 #define FORMS_PREFIX_LEN 6
38 #define DRIVERS_PREFIX "DRIVERS/"
39 #define DRIVERS_PREFIX_LEN 8
40 #define PRINTERS_PREFIX "PRINTERS/"
41 #define PRINTERS_PREFIX_LEN 9
42 #define SECDESC_PREFIX "SECDESC/"
43 #define SECDESC_PREFIX_LEN 8
45 #define ARG_ENCODING "encoding="
47 struct printing_opts {
48 const char *encoding;
49 const char *tdb;
52 static NTSTATUS printing_parse_args(TALLOC_CTX *mem_ctx,
53 struct printing_opts **popts,
54 int argc, const char **argv)
56 size_t c;
57 struct printing_opts *o;
59 if (argc == 0) {
60 return NT_STATUS_INVALID_PARAMETER;
63 o = talloc_zero(mem_ctx, struct printing_opts);
64 if (o == NULL) {
65 return NT_STATUS_INVALID_PARAMETER;
68 for (c = 0; c < argc; c++) {
69 if (strnequal(argv[c], ARG_ENCODING, sizeof(ARG_ENCODING) - 1)) {
70 o->encoding = talloc_strdup(o,
71 argv[c] + sizeof(ARG_ENCODING) - 1);
72 if (o->encoding == NULL) {
73 return NT_STATUS_NO_MEMORY;
75 } else {
76 o->tdb = talloc_strdup(o, argv[c]);
77 if (o->tdb == NULL) {
78 return NT_STATUS_NO_MEMORY;
83 *popts = o;
84 return NT_STATUS_OK;
87 static void dump_form(TALLOC_CTX *mem_ctx,
88 const char *key_name,
89 unsigned char *data,
90 size_t length)
92 enum ndr_err_code ndr_err;
93 DATA_BLOB blob;
94 char *s;
95 struct ntprinting_form r;
97 printf("found form: %s\n", key_name);
99 blob = data_blob_const(data, length);
101 ZERO_STRUCT(r);
103 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
104 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
105 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
106 d_fprintf(stderr, _("form pull failed: %s\n"),
107 ndr_errstr(ndr_err));
108 return;
111 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_form, &r);
112 if (s) {
113 printf("%s\n", s);
117 static void dump_driver(TALLOC_CTX *mem_ctx,
118 const char *key_name,
119 unsigned char *data,
120 size_t length,
121 bool do_string_conversion)
123 enum ndr_err_code ndr_err;
124 DATA_BLOB blob;
125 char *s;
126 struct ntprinting_driver r;
128 printf("found driver: %s\n", key_name);
130 blob = data_blob_const(data, length);
132 ZERO_STRUCT(r);
134 if (do_string_conversion) {
135 r.string_flags = LIBNDR_FLAG_STR_ASCII;
138 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
139 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
140 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
141 d_fprintf(stderr, _("driver pull failed: %s\n"),
142 ndr_errstr(ndr_err));
143 return;
146 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_driver, &r);
147 if (s) {
148 printf("%s\n", s);
152 static void dump_printer(TALLOC_CTX *mem_ctx,
153 const char *key_name,
154 unsigned char *data,
155 size_t length,
156 bool do_string_conversion)
158 enum ndr_err_code ndr_err;
159 DATA_BLOB blob;
160 char *s;
161 struct ntprinting_printer r;
163 printf("found printer: %s\n", key_name);
165 blob = data_blob_const(data, length);
167 ZERO_STRUCT(r);
169 if (do_string_conversion) {
170 r.info.string_flags = LIBNDR_FLAG_STR_ASCII;
173 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
174 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_printer);
175 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
176 d_fprintf(stderr, _("printer pull failed: %s\n"),
177 ndr_errstr(ndr_err));
178 return;
181 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_printer, &r);
182 if (s) {
183 printf("%s\n", s);
187 static void dump_sd(TALLOC_CTX *mem_ctx,
188 const char *key_name,
189 unsigned char *data,
190 size_t length)
192 enum ndr_err_code ndr_err;
193 DATA_BLOB blob;
194 char *s;
195 struct sec_desc_buf r;
197 printf("found security descriptor: %s\n", key_name);
199 blob = data_blob_const(data, length);
201 ZERO_STRUCT(r);
203 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
204 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
205 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
206 d_fprintf(stderr, _("security descriptor pull failed: %s\n"),
207 ndr_errstr(ndr_err));
208 return;
211 s = NDR_PRINT_STRUCT_STRING(mem_ctx, sec_desc_buf, &r);
212 if (s) {
213 printf("%s\n", s);
218 static int net_printing_dump(struct net_context *c, int argc,
219 const char **argv)
221 int ret = -1;
222 TALLOC_CTX *ctx = talloc_stackframe();
223 TDB_CONTEXT *tdb;
224 TDB_DATA kbuf, newkey, dbuf;
225 struct printing_opts *o;
226 const char *save_dos_charset = lp_dos_charset();
227 bool do_string_conversion = false;
228 NTSTATUS status;
230 if (argc < 1 || c->display_usage) {
231 d_printf( "%s\n"
232 "net printing dump [options] <file.tdb>\n"
233 " %s\n",
234 _("Usage:"),
235 _("Dump formatted printer information of the tdb."));
236 d_printf(_("Valid options:\n"));
237 d_printf(_(" encoding=<CP> Set the Code Page of the tdb file.\n"
238 " See iconv -l for the list of CP values\n"
239 " (CP1252 is Western latin1, CP1251 is Cyrillic).\n"));
240 goto done;
243 status = printing_parse_args(ctx, &o, argc, argv);
244 if (!NT_STATUS_IS_OK(status)) {
245 d_fprintf(stderr, _("failed to parse arguments\n"));
246 goto done;
249 tdb = tdb_open_log(o->tdb, 0, TDB_DEFAULT, O_RDONLY, 0600);
250 if (!tdb) {
251 d_fprintf(stderr, _("failed to open tdb file: %s\n"), o->tdb);
252 goto done;
255 if (o->encoding != NULL) {
256 lpcfg_set_cmdline(c->lp_ctx, "dos charset", o->encoding);
257 d_fprintf(stderr, _("do string conversion from %s to %s\n"),
258 lp_dos_charset(), lp_unix_charset());
259 do_string_conversion = true;
262 for (kbuf = tdb_firstkey(tdb);
263 kbuf.dptr;
264 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf=newkey)
266 int cmp;
268 dbuf = tdb_fetch(tdb, kbuf);
269 if (!dbuf.dptr) {
270 continue;
273 cmp = strncmp((const char *)kbuf.dptr,
274 FORMS_PREFIX,
275 FORMS_PREFIX_LEN);
276 if (cmp == 0) {
277 char *key_name = NULL;
278 size_t converted_size = 0;
279 bool ok;
281 ok = pull_ascii_talloc(ctx,
282 &key_name,
283 (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
284 &converted_size);
285 if (!ok) {
286 continue;
289 dump_form(ctx, key_name, dbuf.dptr, dbuf.dsize);
290 TALLOC_FREE(key_name);
291 SAFE_FREE(dbuf.dptr);
292 continue;
295 cmp = strncmp((const char *)kbuf.dptr,
296 DRIVERS_PREFIX,
297 DRIVERS_PREFIX_LEN);
298 if (cmp == 0) {
299 char *key_name = NULL;
300 size_t converted_size = 0;
301 bool ok;
303 ok = pull_ascii_talloc(ctx,
304 &key_name,
305 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
306 &converted_size);
307 if (!ok) {
308 continue;
311 dump_driver(ctx,
312 key_name,
313 dbuf.dptr,
314 dbuf.dsize,
315 do_string_conversion);
316 TALLOC_FREE(key_name);
317 SAFE_FREE(dbuf.dptr);
318 continue;
321 cmp = strncmp((const char *)kbuf.dptr,
322 PRINTERS_PREFIX,
323 PRINTERS_PREFIX_LEN);
324 if (cmp == 0) {
325 char *key_name = NULL;
326 size_t converted_size = 0;
327 bool ok;
329 ok = pull_ascii_talloc(ctx,
330 &key_name,
331 (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
332 &converted_size);
333 if (!ok) {
334 continue;
337 dump_printer(ctx,
338 key_name,
339 dbuf.dptr,
340 dbuf.dsize,
341 do_string_conversion);
342 TALLOC_FREE(key_name);
343 SAFE_FREE(dbuf.dptr);
344 continue;
347 cmp = strncmp((const char *)kbuf.dptr,
348 SECDESC_PREFIX,
349 SECDESC_PREFIX_LEN);
350 if (cmp == 0) {
351 dump_sd(ctx, (const char *)kbuf.dptr+strlen(SECDESC_PREFIX), dbuf.dptr, dbuf.dsize);
352 SAFE_FREE(dbuf.dptr);
353 continue;
358 ret = 0;
360 done:
361 lpcfg_set_cmdline(c->lp_ctx, "dos charset", save_dos_charset);
362 talloc_free(ctx);
363 return ret;
366 static NTSTATUS printing_migrate_internal(struct net_context *c,
367 const struct dom_sid *domain_sid,
368 const char *domain_name,
369 struct cli_state *cli,
370 struct rpc_pipe_client *winreg_pipe,
371 TALLOC_CTX *mem_ctx,
372 int argc,
373 const char **argv)
375 struct printing_opts *o;
376 TALLOC_CTX *tmp_ctx;
377 TDB_CONTEXT *tdb;
378 TDB_DATA kbuf, newkey, dbuf;
379 NTSTATUS status;
380 const char *save_dos_charset = lp_dos_charset();
381 bool do_string_conversion = false;
383 tmp_ctx = talloc_new(mem_ctx);
384 if (tmp_ctx == NULL) {
385 return NT_STATUS_NO_MEMORY;
388 status = printing_parse_args(tmp_ctx, &o, argc, argv);
389 if (!NT_STATUS_IS_OK(status)) {
390 d_fprintf(stderr, _("failed to parse arguments\n"));
391 goto done;
394 tdb = tdb_open_log(o->tdb, 0, TDB_DEFAULT, O_RDONLY, 0600);
395 if (tdb == NULL) {
396 d_fprintf(stderr, _("failed to open tdb file: %s\n"), o->tdb);
397 status = NT_STATUS_NO_SUCH_FILE;
398 goto done;
401 if (o->encoding != NULL) {
402 lpcfg_set_cmdline(c->lp_ctx, "dos charset", o->encoding);
403 d_fprintf(stderr, _("do string conversion from %s to %s\n"),
404 lp_dos_charset(), lp_unix_charset());
405 do_string_conversion = true;
408 for (kbuf = tdb_firstkey(tdb);
409 kbuf.dptr;
410 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
412 int cmp;
414 dbuf = tdb_fetch(tdb, kbuf);
415 if (!dbuf.dptr) {
416 continue;
419 cmp = strncmp((const char *) kbuf.dptr,
420 FORMS_PREFIX,
421 FORMS_PREFIX_LEN);
422 if (cmp == 0) {
423 char *key_name = NULL;
424 size_t converted_size = 0;
425 bool ok;
427 ok = pull_ascii_talloc(tmp_ctx,
428 &key_name,
429 (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
430 &converted_size);
431 if (!ok) {
432 continue;
435 printing_tdb_migrate_form(tmp_ctx,
436 winreg_pipe,
437 key_name,
438 dbuf.dptr,
439 dbuf.dsize);
440 TALLOC_FREE(key_name);
441 SAFE_FREE(dbuf.dptr);
442 continue;
445 cmp = strncmp((const char *) kbuf.dptr,
446 DRIVERS_PREFIX,
447 DRIVERS_PREFIX_LEN);
448 if (cmp == 0) {
449 char *key_name = NULL;
450 size_t converted_size = 0;
451 bool ok;
453 ok = pull_ascii_talloc(tmp_ctx,
454 &key_name,
455 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
456 &converted_size);
457 if (!ok) {
458 continue;
461 printing_tdb_migrate_driver(tmp_ctx,
462 winreg_pipe,
463 key_name,
464 dbuf.dptr,
465 dbuf.dsize,
466 do_string_conversion);
467 TALLOC_FREE(key_name);
468 SAFE_FREE(dbuf.dptr);
469 continue;
472 cmp = strncmp((const char *) kbuf.dptr,
473 PRINTERS_PREFIX,
474 PRINTERS_PREFIX_LEN);
475 if (cmp == 0) {
476 char *key_name = NULL;
477 size_t converted_size = 0;
478 bool ok;
480 ok = pull_ascii_talloc(tmp_ctx,
481 &key_name,
482 (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
483 &converted_size);
484 if (!ok) {
485 continue;
488 printing_tdb_migrate_printer(tmp_ctx,
489 winreg_pipe,
490 key_name,
491 dbuf.dptr,
492 dbuf.dsize,
493 do_string_conversion);
494 TALLOC_FREE(key_name);
495 SAFE_FREE(dbuf.dptr);
496 continue;
498 SAFE_FREE(dbuf.dptr);
501 for (kbuf = tdb_firstkey(tdb);
502 kbuf.dptr;
503 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
505 dbuf = tdb_fetch(tdb, kbuf);
506 if (!dbuf.dptr) {
507 continue;
510 if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
511 printing_tdb_migrate_secdesc(tmp_ctx,
512 winreg_pipe,
513 (const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
514 dbuf.dptr,
515 dbuf.dsize);
516 SAFE_FREE(dbuf.dptr);
517 continue;
519 SAFE_FREE(dbuf.dptr);
523 status = NT_STATUS_OK;
525 done:
526 lpcfg_set_cmdline(c->lp_ctx, "dos charset", save_dos_charset);
527 talloc_free(tmp_ctx);
528 return status;
531 static int net_printing_migrate(struct net_context *c,
532 int argc,
533 const char **argv)
535 if (argc < 1 || c->display_usage) {
536 d_printf( "%s\n"
537 "net printing migrate [options] <file.tdb>\n"
538 " %s\n",
539 _("Usage:"),
540 _("Migrate tdb printing files to new storage"));
541 d_printf(_("Valid options:\n"));
542 d_printf(_(" encoding=<CP> Set the Code Page of the tdb file.\n"
543 " See iconv -l for the list of CP values\n"
544 " (CP1252 is Western latin1, CP1251 is Cyrillic).\n"));
545 return 0;
548 return run_rpc_command(c,
549 NULL,
550 &ndr_table_winreg,
552 printing_migrate_internal,
553 argc,
554 argv);
557 * 'net printing' entrypoint.
558 * @param argc Standard main() style argc.
559 * @param argv Standard main() style argv. Initial components are already
560 * stripped.
563 int net_printing(struct net_context *c, int argc, const char **argv)
565 int ret = -1;
567 struct functable func[] = {
569 "dump",
570 net_printing_dump,
571 NET_TRANSPORT_LOCAL,
572 N_("Dump printer databases"),
573 N_("net printing dump\n"
574 " Dump tdb printing file")
578 "migrate",
579 net_printing_migrate,
580 NET_TRANSPORT_LOCAL | NET_TRANSPORT_RPC,
581 N_("Migrate printer databases"),
582 N_("net printing migrate\n"
583 " Migrate tdb printing files to new storage")
586 { NULL, NULL, 0, NULL, NULL }
589 ret = net_run_function(c, argc, argv, "net printing", func);
591 return ret;