s3-smbclient: Fix cli_errstr() usage (part of bug #7864)
[Samba/gebeck_regimport.git] / source3 / utils / net_printing.c
blob689fac214b9bcd51271210d25f2870a48b776927
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 "utils/net.h"
24 #include "librpc/gen_ndr/ndr_ntprinting.h"
25 #include "librpc/gen_ndr/ndr_spoolss_c.h"
26 #include "rpc_client/cli_spoolss.h"
27 #include "../libcli/security/security.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
30 #define FORMS_PREFIX "FORMS/"
31 #define DRIVERS_PREFIX "DRIVERS/"
32 #define PRINTERS_PREFIX "PRINTERS/"
33 #define SECDESC_PREFIX "SECDESC/"
35 static void dump_form(TALLOC_CTX *mem_ctx,
36 const char *key_name,
37 unsigned char *data,
38 size_t length)
40 enum ndr_err_code ndr_err;
41 DATA_BLOB blob;
42 char *s;
43 struct ntprinting_form r;
45 printf("found form: %s\n", key_name);
47 blob = data_blob_const(data, length);
49 ZERO_STRUCT(r);
51 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
52 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
53 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
54 d_fprintf(stderr, _("form pull failed: %s\n"),
55 ndr_errstr(ndr_err));
56 return;
59 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_form, &r);
60 if (s) {
61 printf("%s\n", s);
65 static void dump_driver(TALLOC_CTX *mem_ctx,
66 const char *key_name,
67 unsigned char *data,
68 size_t length)
70 enum ndr_err_code ndr_err;
71 DATA_BLOB blob;
72 char *s;
73 struct ntprinting_driver r;
75 printf("found driver: %s\n", key_name);
77 blob = data_blob_const(data, length);
79 ZERO_STRUCT(r);
81 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
82 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
83 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
84 d_fprintf(stderr, _("driver pull failed: %s\n"),
85 ndr_errstr(ndr_err));
86 return;
89 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_driver, &r);
90 if (s) {
91 printf("%s\n", s);
95 static void dump_printer(TALLOC_CTX *mem_ctx,
96 const char *key_name,
97 unsigned char *data,
98 size_t length)
100 enum ndr_err_code ndr_err;
101 DATA_BLOB blob;
102 char *s;
103 struct ntprinting_printer r;
105 printf("found printer: %s\n", key_name);
107 blob = data_blob_const(data, length);
109 ZERO_STRUCT(r);
111 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
112 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_printer);
113 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
114 d_fprintf(stderr, _("printer pull failed: %s\n"),
115 ndr_errstr(ndr_err));
116 return;
119 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_printer, &r);
120 if (s) {
121 printf("%s\n", s);
125 static void dump_sd(TALLOC_CTX *mem_ctx,
126 const char *key_name,
127 unsigned char *data,
128 size_t length)
130 enum ndr_err_code ndr_err;
131 DATA_BLOB blob;
132 char *s;
133 struct sec_desc_buf r;
135 printf("found security descriptor: %s\n", key_name);
137 blob = data_blob_const(data, length);
139 ZERO_STRUCT(r);
141 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
142 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
143 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
144 d_fprintf(stderr, _("security descriptor pull failed: %s\n"),
145 ndr_errstr(ndr_err));
146 return;
149 s = NDR_PRINT_STRUCT_STRING(mem_ctx, sec_desc_buf, &r);
150 if (s) {
151 printf("%s\n", s);
156 static int net_printing_dump(struct net_context *c, int argc,
157 const char **argv)
159 int ret = -1;
160 TALLOC_CTX *ctx = talloc_stackframe();
161 TDB_CONTEXT *tdb;
162 TDB_DATA kbuf, newkey, dbuf;
164 if (argc < 1 || c->display_usage) {
165 d_fprintf(stderr, "%s\nnet printing dump <file.tdb>\n",
166 _("Usage:"));
167 goto done;
170 tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600);
171 if (!tdb) {
172 d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]);
173 goto done;
176 for (kbuf = tdb_firstkey(tdb);
177 kbuf.dptr;
178 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf=newkey)
180 dbuf = tdb_fetch(tdb, kbuf);
181 if (!dbuf.dptr) {
182 continue;
185 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
186 dump_form(ctx, (const char *)kbuf.dptr+strlen(FORMS_PREFIX), dbuf.dptr, dbuf.dsize);
187 SAFE_FREE(dbuf.dptr);
188 continue;
191 if (strncmp((const char *)kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
192 dump_driver(ctx, (const char *)kbuf.dptr+strlen(DRIVERS_PREFIX), dbuf.dptr, dbuf.dsize);
193 SAFE_FREE(dbuf.dptr);
194 continue;
197 if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
198 dump_printer(ctx, (const char *)kbuf.dptr+strlen(PRINTERS_PREFIX), dbuf.dptr, dbuf.dsize);
199 SAFE_FREE(dbuf.dptr);
200 continue;
203 if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
204 dump_sd(ctx, (const char *)kbuf.dptr+strlen(SECDESC_PREFIX), dbuf.dptr, dbuf.dsize);
205 SAFE_FREE(dbuf.dptr);
206 continue;
211 ret = 0;
213 done:
214 talloc_free(ctx);
215 return ret;
218 static NTSTATUS migrate_form(TALLOC_CTX *mem_ctx,
219 struct rpc_pipe_client *pipe_hnd,
220 const char *key_name,
221 unsigned char *data,
222 size_t length)
224 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
225 struct policy_handle hnd;
226 enum ndr_err_code ndr_err;
227 struct ntprinting_form r;
228 union spoolss_AddFormInfo f;
229 struct spoolss_AddFormInfo1 f1;
230 DATA_BLOB blob;
231 NTSTATUS status;
232 WERROR result;
234 blob = data_blob_const(data, length);
236 ZERO_STRUCT(r);
238 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
239 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
240 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
241 d_fprintf(stderr, _("form pull failed: %s\n"),
242 ndr_errstr(ndr_err));
243 return NT_STATUS_NO_MEMORY;
246 /* Don't migrate builtin forms */
247 if (r.flag == SPOOLSS_FORM_BUILTIN) {
248 return NT_STATUS_OK;
251 d_printf(_("Migrating Form: %s\n"), key_name);
253 result = rpccli_spoolss_openprinter_ex(pipe_hnd,
254 mem_ctx,
255 pipe_hnd->srv_name_slash,
256 MAXIMUM_ALLOWED_ACCESS,
257 &hnd);
258 if (!W_ERROR_IS_OK(result)) {
259 d_fprintf(stderr, _("OpenPrinter(%s) failed: %s\n"),
260 pipe_hnd->srv_name_slash, win_errstr(result));
261 return werror_to_ntstatus(result);
264 f1.form_name = key_name;
265 f1.flags = r.flag;
267 f1.size.width = r.width;
268 f1.size.height = r.length;
270 f1.area.top = r.top;
271 f1.area.right = r.right;
272 f1.area.bottom = r.bottom;
273 f1.area.left = r.left;
275 f.info1 = &f1;
277 status = dcerpc_spoolss_AddForm(b,
278 mem_ctx,
279 &hnd,
282 &result);
283 if (!NT_STATUS_IS_OK(status)) {
284 d_printf(_("\tAddForm(%s) refused -- %s.\n"),
285 f.info1->form_name, nt_errstr(status));
286 } else if (!W_ERROR_IS_OK(result)) {
287 d_printf(_("\tAddForm(%s) refused -- %s.\n"),
288 f.info1->form_name, win_errstr(result));
289 status = werror_to_ntstatus(result);
292 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
294 return status;
297 static NTSTATUS migrate_driver(TALLOC_CTX *mem_ctx,
298 struct rpc_pipe_client *pipe_hnd,
299 const char *key_name,
300 unsigned char *data,
301 size_t length)
303 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
304 enum ndr_err_code ndr_err;
305 struct ntprinting_driver r;
306 struct spoolss_AddDriverInfoCtr d;
307 struct spoolss_AddDriverInfo3 d3;
308 struct spoolss_StringArray a;
309 DATA_BLOB blob;
310 NTSTATUS status;
311 WERROR result;
313 blob = data_blob_const(data, length);
315 ZERO_STRUCT(r);
317 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
318 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
319 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
320 d_fprintf(stderr, _("driver pull failed: %s\n"),
321 ndr_errstr(ndr_err));
322 return NT_STATUS_NO_MEMORY;
325 d_printf(_("Migrating Printer Driver: %s\n"), key_name);
327 ZERO_STRUCT(d3);
328 ZERO_STRUCT(a);
330 a.string = r.dependent_files;
332 d3.architecture = r.environment;
333 d3.config_file = r.configfile;
334 d3.data_file = r.datafile;
335 d3.default_datatype = r.defaultdatatype;
336 d3.dependent_files = &a;
337 d3.driver_path = r.driverpath;
338 d3.help_file = r.helpfile;
339 d3.monitor_name = r.monitorname;
340 d3.driver_name = r.name;
341 d3.version = r.version;
343 d.info.info3 = &d3;
344 d.level = 3;
346 status = dcerpc_spoolss_AddPrinterDriver(b,
347 mem_ctx,
348 NULL,
350 &result);
351 if (!NT_STATUS_IS_OK(status)) {
352 d_printf(_("\tAddDriver driver: [%s] refused -- %s.\n"),
353 d3.driver_name, nt_errstr(status));
354 } else if (!W_ERROR_IS_OK(result)) {
355 d_printf(_("\tAddDriver driver: [%s] refused -- %s.\n"),
356 d3.driver_name, win_errstr(result));
357 status = werror_to_ntstatus(result);
360 return status;
363 static NTSTATUS migrate_printer(TALLOC_CTX *mem_ctx,
364 struct rpc_pipe_client *pipe_hnd,
365 const char *key_name,
366 unsigned char *data,
367 size_t length)
369 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
370 struct policy_handle hnd;
371 enum ndr_err_code ndr_err;
372 struct ntprinting_printer r;
373 struct spoolss_SetPrinterInfo2 info2;
374 struct spoolss_DeviceMode dm;
375 struct spoolss_SetPrinterInfoCtr info_ctr;
376 struct spoolss_DevmodeContainer devmode_ctr;
377 struct sec_desc_buf secdesc_ctr;
378 DATA_BLOB blob;
379 NTSTATUS status;
380 WERROR result;
381 int j;
383 if (strequal(key_name, "printers")) {
384 return NT_STATUS_OK;
387 blob = data_blob_const(data, length);
389 ZERO_STRUCT(r);
391 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
392 (ndr_pull_flags_fn_t) ndr_pull_ntprinting_printer);
393 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
394 d_fprintf(stderr, _("printer pull failed: %s\n"),
395 ndr_errstr(ndr_err));
396 return NT_STATUS_NO_MEMORY;
399 d_printf(_("Migrating Printer: %s\n"), key_name);
401 result = rpccli_spoolss_openprinter_ex(pipe_hnd,
402 mem_ctx,
403 key_name,
404 MAXIMUM_ALLOWED_ACCESS,
405 &hnd);
406 if (!W_ERROR_IS_OK(result)) {
407 d_fprintf(stderr, _("OpenPrinter(%s) failed: %s\n"),
408 key_name, win_errstr(result));
409 return werror_to_ntstatus(result);
412 /* Create printer info level 2 */
413 ZERO_STRUCT(info2);
414 ZERO_STRUCT(devmode_ctr);
415 ZERO_STRUCT(secdesc_ctr);
417 info2.attributes = r.info.attributes;
418 info2.averageppm = r.info.averageppm;
419 info2.cjobs = r.info.cjobs;
420 info2.comment = r.info.comment;
421 info2.datatype = r.info.datatype;
422 info2.defaultpriority = r.info.default_priority;
423 info2.drivername = r.info.drivername;
424 info2.location = r.info.location;
425 info2.parameters = r.info.parameters;
426 info2.portname = r.info.portname;
427 info2.printername = r.info.printername;
428 info2.printprocessor = r.info.printprocessor;
429 info2.priority = r.info.priority;
430 info2.sepfile = r.info.sepfile;
431 info2.sharename = r.info.sharename;
432 info2.starttime = r.info.starttime;
433 info2.status = r.info.status;
434 info2.untiltime = r.info.untiltime;
436 /* Create Device Mode */
437 if (r.devmode != NULL) {
438 ZERO_STRUCT(dm);
440 dm.bitsperpel = r.devmode->bitsperpel;
441 dm.collate = r.devmode->collate;
442 dm.color = r.devmode->color;
443 dm.copies = r.devmode->copies;
444 dm.defaultsource = r.devmode->defaultsource;
445 dm.devicename = r.devmode->devicename;
446 dm.displayflags = r.devmode->displayflags;
447 dm.displayfrequency = r.devmode->displayfrequency;
448 dm.dithertype = r.devmode->dithertype;
449 dm.driverversion = r.devmode->driverversion;
450 dm.duplex = r.devmode->duplex;
451 dm.fields = r.devmode->fields;
452 dm.formname = r.devmode->formname;
453 dm.icmintent = r.devmode->icmintent;
454 dm.icmmethod = r.devmode->icmmethod;
455 dm.logpixels = r.devmode->logpixels;
456 dm.mediatype = r.devmode->mediatype;
457 dm.orientation = r.devmode->orientation;
458 dm.panningheight = r.devmode->pelsheight;
459 dm.panningwidth = r.devmode->panningwidth;
460 dm.paperlength = r.devmode->paperlength;
461 dm.papersize = r.devmode->papersize;
462 dm.paperwidth = r.devmode->paperwidth;
463 dm.pelsheight = r.devmode->pelsheight;
464 dm.pelswidth = r.devmode->pelswidth;
465 dm.printquality = r.devmode->printquality;
466 dm.scale = r.devmode->scale;
467 dm.specversion = r.devmode->specversion;
468 dm.ttoption = r.devmode->ttoption;
469 dm.yresolution = r.devmode->yresolution;
471 if (r.devmode->nt_dev_private != NULL) {
472 dm.driverextra_data.data = r.devmode->nt_dev_private->data;
473 dm.driverextra_data.length = r.devmode->nt_dev_private->length;
474 dm.__driverextra_length = r.devmode->nt_dev_private->length;
477 devmode_ctr.devmode = &dm;
479 info2.devmode_ptr = 1;
482 info_ctr.info.info2 = &info2;
483 info_ctr.level = 2;
485 status = dcerpc_spoolss_SetPrinter(b,
486 mem_ctx,
487 &hnd,
488 &info_ctr,
489 &devmode_ctr,
490 &secdesc_ctr,
491 0, /* command */
492 &result);
493 if (!NT_STATUS_IS_OK(status)) {
494 d_printf(_("\tSetPrinter(%s) level 2 refused -- %s.\n"),
495 key_name, nt_errstr(status));
496 goto done;
497 } else if (!W_ERROR_IS_OK(result)) {
498 d_printf(_("\tSetPrinter(%s) level 2 refused -- %s.\n"),
499 key_name, win_errstr(result));
500 status = werror_to_ntstatus(result);
501 goto done;
504 /* migrate printerdata */
505 for (j = 0; j < r.count; j++) {
506 char *valuename;
507 char *keyname;
509 if (r.printer_data[j].type == REG_NONE) {
510 continue;
513 keyname = CONST_DISCARD(char *, r.printer_data[j].name);
514 valuename = strchr(keyname, '\\');
515 if (valuename == NULL) {
516 continue;
517 } else {
518 valuename[0] = '\0';
519 valuename++;
522 printf(" data: %s\\%s\n", keyname, valuename);
524 status = dcerpc_spoolss_SetPrinterDataEx(b,
525 mem_ctx,
526 &hnd,
527 keyname,
528 valuename,
529 r.printer_data[j].type,
530 r.printer_data[j].data.data,
531 r.printer_data[j].data.length,
532 &result);
533 if (!NT_STATUS_IS_OK(status)) {
534 d_printf(_("\tSetPrinterDataEx: printer [%s], keyname [%s], valuename [%s] refused -- %s.\n"),
535 key_name, keyname, valuename, nt_errstr(status));
536 break;
537 } else if (!W_ERROR_IS_OK(result)) {
538 d_printf(_("\tSetPrinterDataEx: printer [%s], keyname [%s], valuename [%s] refused -- %s.\n"),
539 key_name, keyname, valuename, win_errstr(result));
540 status = werror_to_ntstatus(result);
541 break;
545 done:
546 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
548 return status;
551 static NTSTATUS migrate_secdesc(TALLOC_CTX *mem_ctx,
552 struct rpc_pipe_client *pipe_hnd,
553 const char *key_name,
554 unsigned char *data,
555 size_t length)
557 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
558 struct policy_handle hnd;
559 enum ndr_err_code ndr_err;
560 struct sec_desc_buf secdesc_ctr;
561 struct spoolss_SetPrinterInfo3 info3;
562 struct spoolss_SetPrinterInfoCtr info_ctr;
563 struct spoolss_DevmodeContainer devmode_ctr;
564 DATA_BLOB blob;
565 NTSTATUS status;
566 WERROR result;
568 if (strequal(key_name, "printers")) {
569 return NT_STATUS_OK;
572 blob = data_blob_const(data, length);
574 ZERO_STRUCT(secdesc_ctr);
576 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &secdesc_ctr,
577 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
578 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
579 d_fprintf(stderr, _("security descriptor pull failed: %s\n"),
580 ndr_errstr(ndr_err));
581 return NT_STATUS_NO_MEMORY;
584 d_printf(_("Migrating Security Descriptor: %s\n"), key_name);
586 result = rpccli_spoolss_openprinter_ex(pipe_hnd,
587 mem_ctx,
588 key_name,
589 MAXIMUM_ALLOWED_ACCESS,
590 &hnd);
591 if (!W_ERROR_IS_OK(result)) {
592 d_fprintf(stderr, _("\tOpenPrinter(%s) failed: %s\n"),
593 key_name, win_errstr(result));
594 return werror_to_ntstatus(result);
597 ZERO_STRUCT(devmode_ctr);
599 info3.sec_desc_ptr = 1;
601 info_ctr.info.info3 = &info3;
602 info_ctr.level = 3;
604 status = dcerpc_spoolss_SetPrinter(b,
605 mem_ctx,
606 &hnd,
607 &info_ctr,
608 &devmode_ctr,
609 &secdesc_ctr,
610 0, /* command */
611 &result);
612 if (!NT_STATUS_IS_OK(status)) {
613 d_printf(_("\tSetPrinter(%s) level 3 refused -- %s.\n"),
614 key_name, nt_errstr(status));
615 } else if (!W_ERROR_IS_OK(result)) {
616 d_printf(_("\tSetPrinter(%s) level 3 refused -- %s.\n"),
617 key_name, win_errstr(result));
618 status = werror_to_ntstatus(result);
621 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
623 return status;
626 static NTSTATUS printing_migrate_internal(struct net_context *c,
627 const struct dom_sid *domain_sid,
628 const char *domain_name,
629 struct cli_state *cli,
630 struct rpc_pipe_client *pipe_hnd,
631 TALLOC_CTX *mem_ctx,
632 int argc,
633 const char **argv)
635 TALLOC_CTX *tmp_ctx;
636 TDB_CONTEXT *tdb;
637 TDB_DATA kbuf, newkey, dbuf;
638 NTSTATUS status;
640 tmp_ctx = talloc_new(mem_ctx);
641 if (tmp_ctx == NULL) {
642 return NT_STATUS_NO_MEMORY;
645 tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600);
646 if (tdb == NULL) {
647 d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]);
648 status = NT_STATUS_NO_SUCH_FILE;
649 goto done;
652 for (kbuf = tdb_firstkey(tdb);
653 kbuf.dptr;
654 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
656 dbuf = tdb_fetch(tdb, kbuf);
657 if (!dbuf.dptr) {
658 continue;
661 if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
662 migrate_form(tmp_ctx,
663 pipe_hnd,
664 (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
665 dbuf.dptr,
666 dbuf.dsize);
667 SAFE_FREE(dbuf.dptr);
668 continue;
671 if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
672 migrate_driver(tmp_ctx,
673 pipe_hnd,
674 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
675 dbuf.dptr,
676 dbuf.dsize);
677 SAFE_FREE(dbuf.dptr);
678 continue;
681 if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
682 migrate_printer(tmp_ctx,
683 pipe_hnd,
684 (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
685 dbuf.dptr,
686 dbuf.dsize);
687 SAFE_FREE(dbuf.dptr);
688 continue;
691 if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
692 migrate_secdesc(tmp_ctx,
693 pipe_hnd,
694 (const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
695 dbuf.dptr,
696 dbuf.dsize);
697 SAFE_FREE(dbuf.dptr);
698 continue;
703 status = NT_STATUS_OK;
705 done:
706 talloc_free(tmp_ctx);
707 return status;
710 static int net_printing_migrate(struct net_context *c,
711 int argc,
712 const char **argv)
714 if (argc < 1 || c->display_usage) {
715 d_printf( "%s\n"
716 "net printing migrate <file.tdb>\n"
717 " %s\n",
718 _("Usage:"),
719 _("Migrate tdb printing files to new storage"));
720 return 0;
723 return run_rpc_command(c,
724 NULL,
725 &ndr_table_spoolss.syntax_id,
727 printing_migrate_internal,
728 argc,
729 argv);
732 * 'net printing' entrypoint.
733 * @param argc Standard main() style argc.
734 * @param argv Standard main() style argv. Initial components are already
735 * stripped.
738 int net_printing(struct net_context *c, int argc, const char **argv)
740 int ret = -1;
742 struct functable func[] = {
744 "dump",
745 net_printing_dump,
746 NET_TRANSPORT_LOCAL,
747 N_("Dump printer databases"),
748 N_("net printing dump\n"
749 " Dump tdb printing file")
753 "migrate",
754 net_printing_migrate,
755 NET_TRANSPORT_LOCAL | NET_TRANSPORT_RPC,
756 N_("Migrate printer databases"),
757 N_("net printing migrate\n"
758 " Migrate tdb printing files to new storage")
761 { NULL, NULL, 0, NULL, NULL }
764 ret = net_run_function(c, argc, argv, "net printing", func);
766 return ret;