s3: Use tevent_req_ntstatus properly in a few places
[Samba.git] / source3 / utils / net_printing.c
blob3e70f1a86f599a5fadb1946c02a0d1438045b9d9
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 "librpc/gen_ndr/ndr_ntprinting.h"
27 #include "librpc/gen_ndr/ndr_spoolss_c.h"
28 #include "rpc_client/cli_spoolss.h"
29 #include "../libcli/security/security.h"
30 #include "../librpc/gen_ndr/ndr_security.h"
31 #include "util_tdb.h"
33 #define FORMS_PREFIX "FORMS/"
34 #define DRIVERS_PREFIX "DRIVERS/"
35 #define PRINTERS_PREFIX "PRINTERS/"
36 #define SECDESC_PREFIX "SECDESC/"
38 static void dump_form(TALLOC_CTX *mem_ctx,
39 const char *key_name,
40 unsigned char *data,
41 size_t length)
43 enum ndr_err_code ndr_err;
44 DATA_BLOB blob;
45 char *s;
46 struct ntprinting_form r;
48 printf("found form: %s\n", key_name);
50 blob = data_blob_const(data, length);
52 ZERO_STRUCT(r);
54 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
55 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
56 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
57 d_fprintf(stderr, _("form pull failed: %s\n"),
58 ndr_errstr(ndr_err));
59 return;
62 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_form, &r);
63 if (s) {
64 printf("%s\n", s);
68 static void dump_driver(TALLOC_CTX *mem_ctx,
69 const char *key_name,
70 unsigned char *data,
71 size_t length)
73 enum ndr_err_code ndr_err;
74 DATA_BLOB blob;
75 char *s;
76 struct ntprinting_driver r;
78 printf("found driver: %s\n", key_name);
80 blob = data_blob_const(data, length);
82 ZERO_STRUCT(r);
84 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
85 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
86 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
87 d_fprintf(stderr, _("driver pull failed: %s\n"),
88 ndr_errstr(ndr_err));
89 return;
92 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_driver, &r);
93 if (s) {
94 printf("%s\n", s);
98 static void dump_printer(TALLOC_CTX *mem_ctx,
99 const char *key_name,
100 unsigned char *data,
101 size_t length)
103 enum ndr_err_code ndr_err;
104 DATA_BLOB blob;
105 char *s;
106 struct ntprinting_printer r;
108 printf("found printer: %s\n", key_name);
110 blob = data_blob_const(data, length);
112 ZERO_STRUCT(r);
114 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
115 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_printer);
116 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
117 d_fprintf(stderr, _("printer pull failed: %s\n"),
118 ndr_errstr(ndr_err));
119 return;
122 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_printer, &r);
123 if (s) {
124 printf("%s\n", s);
128 static void dump_sd(TALLOC_CTX *mem_ctx,
129 const char *key_name,
130 unsigned char *data,
131 size_t length)
133 enum ndr_err_code ndr_err;
134 DATA_BLOB blob;
135 char *s;
136 struct sec_desc_buf r;
138 printf("found security descriptor: %s\n", key_name);
140 blob = data_blob_const(data, length);
142 ZERO_STRUCT(r);
144 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
145 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
146 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
147 d_fprintf(stderr, _("security descriptor pull failed: %s\n"),
148 ndr_errstr(ndr_err));
149 return;
152 s = NDR_PRINT_STRUCT_STRING(mem_ctx, sec_desc_buf, &r);
153 if (s) {
154 printf("%s\n", s);
159 static int net_printing_dump(struct net_context *c, int argc,
160 const char **argv)
162 int ret = -1;
163 TALLOC_CTX *ctx = talloc_stackframe();
164 TDB_CONTEXT *tdb;
165 TDB_DATA kbuf, newkey, dbuf;
167 if (argc < 1 || c->display_usage) {
168 d_fprintf(stderr, "%s\nnet printing dump <file.tdb>\n",
169 _("Usage:"));
170 goto done;
173 tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600);
174 if (!tdb) {
175 d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]);
176 goto done;
179 for (kbuf = tdb_firstkey(tdb);
180 kbuf.dptr;
181 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf=newkey)
183 dbuf = tdb_fetch(tdb, kbuf);
184 if (!dbuf.dptr) {
185 continue;
188 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
189 dump_form(ctx, (const char *)kbuf.dptr+strlen(FORMS_PREFIX), dbuf.dptr, dbuf.dsize);
190 SAFE_FREE(dbuf.dptr);
191 continue;
194 if (strncmp((const char *)kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
195 dump_driver(ctx, (const char *)kbuf.dptr+strlen(DRIVERS_PREFIX), dbuf.dptr, dbuf.dsize);
196 SAFE_FREE(dbuf.dptr);
197 continue;
200 if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
201 dump_printer(ctx, (const char *)kbuf.dptr+strlen(PRINTERS_PREFIX), dbuf.dptr, dbuf.dsize);
202 SAFE_FREE(dbuf.dptr);
203 continue;
206 if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
207 dump_sd(ctx, (const char *)kbuf.dptr+strlen(SECDESC_PREFIX), dbuf.dptr, dbuf.dsize);
208 SAFE_FREE(dbuf.dptr);
209 continue;
214 ret = 0;
216 done:
217 talloc_free(ctx);
218 return ret;
221 static NTSTATUS migrate_form(TALLOC_CTX *mem_ctx,
222 struct rpc_pipe_client *pipe_hnd,
223 const char *key_name,
224 unsigned char *data,
225 size_t length)
227 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
228 struct policy_handle hnd;
229 enum ndr_err_code ndr_err;
230 struct ntprinting_form r;
231 union spoolss_AddFormInfo f;
232 struct spoolss_AddFormInfo1 f1;
233 DATA_BLOB blob;
234 NTSTATUS status;
235 WERROR result;
237 blob = data_blob_const(data, length);
239 ZERO_STRUCT(r);
241 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
242 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
243 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
244 d_fprintf(stderr, _("form pull failed: %s\n"),
245 ndr_errstr(ndr_err));
246 return NT_STATUS_NO_MEMORY;
249 /* Don't migrate builtin forms */
250 if (r.flag == SPOOLSS_FORM_BUILTIN) {
251 return NT_STATUS_OK;
254 d_printf(_("Migrating Form: %s\n"), key_name);
256 result = rpccli_spoolss_openprinter_ex(pipe_hnd,
257 mem_ctx,
258 pipe_hnd->srv_name_slash,
259 MAXIMUM_ALLOWED_ACCESS,
260 &hnd);
261 if (!W_ERROR_IS_OK(result)) {
262 d_fprintf(stderr, _("OpenPrinter(%s) failed: %s\n"),
263 pipe_hnd->srv_name_slash, win_errstr(result));
264 return werror_to_ntstatus(result);
267 f1.form_name = key_name;
268 f1.flags = r.flag;
270 f1.size.width = r.width;
271 f1.size.height = r.length;
273 f1.area.top = r.top;
274 f1.area.right = r.right;
275 f1.area.bottom = r.bottom;
276 f1.area.left = r.left;
278 f.info1 = &f1;
280 status = dcerpc_spoolss_AddForm(b,
281 mem_ctx,
282 &hnd,
285 &result);
286 if (!NT_STATUS_IS_OK(status)) {
287 d_printf(_("\tAddForm(%s) refused -- %s.\n"),
288 f.info1->form_name, nt_errstr(status));
289 } else if (!W_ERROR_IS_OK(result)) {
290 d_printf(_("\tAddForm(%s) refused -- %s.\n"),
291 f.info1->form_name, win_errstr(result));
292 status = werror_to_ntstatus(result);
295 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
297 return status;
300 static NTSTATUS migrate_driver(TALLOC_CTX *mem_ctx,
301 struct rpc_pipe_client *pipe_hnd,
302 const char *key_name,
303 unsigned char *data,
304 size_t length)
306 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
307 enum ndr_err_code ndr_err;
308 struct ntprinting_driver r;
309 struct spoolss_AddDriverInfoCtr d;
310 struct spoolss_AddDriverInfo3 d3;
311 struct spoolss_StringArray a;
312 DATA_BLOB blob;
313 NTSTATUS status;
314 WERROR result;
316 blob = data_blob_const(data, length);
318 ZERO_STRUCT(r);
320 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
321 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
322 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
323 d_fprintf(stderr, _("driver pull failed: %s\n"),
324 ndr_errstr(ndr_err));
325 return NT_STATUS_NO_MEMORY;
328 d_printf(_("Migrating Printer Driver: %s\n"), key_name);
330 ZERO_STRUCT(d3);
331 ZERO_STRUCT(a);
333 a.string = r.dependent_files;
335 d3.architecture = r.environment;
336 d3.config_file = r.configfile;
337 d3.data_file = r.datafile;
338 d3.default_datatype = r.defaultdatatype;
339 d3.dependent_files = &a;
340 d3.driver_path = r.driverpath;
341 d3.help_file = r.helpfile;
342 d3.monitor_name = r.monitorname;
343 d3.driver_name = r.name;
344 d3.version = r.version;
346 d.info.info3 = &d3;
347 d.level = 3;
349 status = dcerpc_spoolss_AddPrinterDriver(b,
350 mem_ctx,
351 NULL,
353 &result);
354 if (!NT_STATUS_IS_OK(status)) {
355 d_printf(_("\tAddDriver driver: [%s] refused -- %s.\n"),
356 d3.driver_name, nt_errstr(status));
357 } else if (!W_ERROR_IS_OK(result)) {
358 d_printf(_("\tAddDriver driver: [%s] refused -- %s.\n"),
359 d3.driver_name, win_errstr(result));
360 status = werror_to_ntstatus(result);
363 return status;
366 static NTSTATUS migrate_printer(TALLOC_CTX *mem_ctx,
367 struct rpc_pipe_client *pipe_hnd,
368 const char *key_name,
369 unsigned char *data,
370 size_t length)
372 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
373 struct policy_handle hnd;
374 enum ndr_err_code ndr_err;
375 struct ntprinting_printer r;
376 struct spoolss_SetPrinterInfo2 info2;
377 struct spoolss_DeviceMode dm;
378 struct spoolss_SetPrinterInfoCtr info_ctr;
379 struct spoolss_DevmodeContainer devmode_ctr;
380 struct sec_desc_buf secdesc_ctr;
381 DATA_BLOB blob;
382 NTSTATUS status;
383 WERROR result;
384 int j;
386 if (strequal(key_name, "printers")) {
387 return NT_STATUS_OK;
390 blob = data_blob_const(data, length);
392 ZERO_STRUCT(r);
394 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
395 (ndr_pull_flags_fn_t) ndr_pull_ntprinting_printer);
396 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
397 d_fprintf(stderr, _("printer pull failed: %s\n"),
398 ndr_errstr(ndr_err));
399 return NT_STATUS_NO_MEMORY;
402 d_printf(_("Migrating Printer: %s\n"), key_name);
404 result = rpccli_spoolss_openprinter_ex(pipe_hnd,
405 mem_ctx,
406 key_name,
407 MAXIMUM_ALLOWED_ACCESS,
408 &hnd);
409 if (!W_ERROR_IS_OK(result)) {
410 d_fprintf(stderr, _("OpenPrinter(%s) failed: %s\n"),
411 key_name, win_errstr(result));
412 return werror_to_ntstatus(result);
415 /* Create printer info level 2 */
416 ZERO_STRUCT(info2);
417 ZERO_STRUCT(devmode_ctr);
418 ZERO_STRUCT(secdesc_ctr);
420 info2.attributes = r.info.attributes;
421 info2.averageppm = r.info.averageppm;
422 info2.cjobs = r.info.cjobs;
423 info2.comment = r.info.comment;
424 info2.datatype = r.info.datatype;
425 info2.defaultpriority = r.info.default_priority;
426 info2.drivername = r.info.drivername;
427 info2.location = r.info.location;
428 info2.parameters = r.info.parameters;
429 info2.portname = r.info.portname;
430 info2.printername = r.info.printername;
431 info2.printprocessor = r.info.printprocessor;
432 info2.priority = r.info.priority;
433 info2.sepfile = r.info.sepfile;
434 info2.sharename = r.info.sharename;
435 info2.starttime = r.info.starttime;
436 info2.status = r.info.status;
437 info2.untiltime = r.info.untiltime;
439 /* Create Device Mode */
440 if (r.devmode != NULL) {
441 ZERO_STRUCT(dm);
443 dm.bitsperpel = r.devmode->bitsperpel;
444 dm.collate = r.devmode->collate;
445 dm.color = r.devmode->color;
446 dm.copies = r.devmode->copies;
447 dm.defaultsource = r.devmode->defaultsource;
448 dm.devicename = r.devmode->devicename;
449 dm.displayflags = r.devmode->displayflags;
450 dm.displayfrequency = r.devmode->displayfrequency;
451 dm.dithertype = r.devmode->dithertype;
452 dm.driverversion = r.devmode->driverversion;
453 dm.duplex = r.devmode->duplex;
454 dm.fields = r.devmode->fields;
455 dm.formname = r.devmode->formname;
456 dm.icmintent = r.devmode->icmintent;
457 dm.icmmethod = r.devmode->icmmethod;
458 dm.logpixels = r.devmode->logpixels;
459 dm.mediatype = r.devmode->mediatype;
460 dm.orientation = r.devmode->orientation;
461 dm.panningheight = r.devmode->pelsheight;
462 dm.panningwidth = r.devmode->panningwidth;
463 dm.paperlength = r.devmode->paperlength;
464 dm.papersize = r.devmode->papersize;
465 dm.paperwidth = r.devmode->paperwidth;
466 dm.pelsheight = r.devmode->pelsheight;
467 dm.pelswidth = r.devmode->pelswidth;
468 dm.printquality = r.devmode->printquality;
469 dm.scale = r.devmode->scale;
470 dm.specversion = r.devmode->specversion;
471 dm.ttoption = r.devmode->ttoption;
472 dm.yresolution = r.devmode->yresolution;
474 if (r.devmode->nt_dev_private != NULL) {
475 dm.driverextra_data.data = r.devmode->nt_dev_private->data;
476 dm.driverextra_data.length = r.devmode->nt_dev_private->length;
477 dm.__driverextra_length = r.devmode->nt_dev_private->length;
480 devmode_ctr.devmode = &dm;
482 info2.devmode_ptr = 1;
485 info_ctr.info.info2 = &info2;
486 info_ctr.level = 2;
488 status = dcerpc_spoolss_SetPrinter(b,
489 mem_ctx,
490 &hnd,
491 &info_ctr,
492 &devmode_ctr,
493 &secdesc_ctr,
494 0, /* command */
495 &result);
496 if (!NT_STATUS_IS_OK(status)) {
497 d_printf(_("\tSetPrinter(%s) level 2 refused -- %s.\n"),
498 key_name, nt_errstr(status));
499 goto done;
500 } else if (!W_ERROR_IS_OK(result)) {
501 d_printf(_("\tSetPrinter(%s) level 2 refused -- %s.\n"),
502 key_name, win_errstr(result));
503 status = werror_to_ntstatus(result);
504 goto done;
507 /* migrate printerdata */
508 for (j = 0; j < r.count; j++) {
509 char *valuename;
510 char *keyname;
512 if (r.printer_data[j].type == REG_NONE) {
513 continue;
516 keyname = discard_const_p(char, r.printer_data[j].name);
517 valuename = strchr(keyname, '\\');
518 if (valuename == NULL) {
519 continue;
520 } else {
521 valuename[0] = '\0';
522 valuename++;
525 printf(" data: %s\\%s\n", keyname, valuename);
527 status = dcerpc_spoolss_SetPrinterDataEx(b,
528 mem_ctx,
529 &hnd,
530 keyname,
531 valuename,
532 r.printer_data[j].type,
533 r.printer_data[j].data.data,
534 r.printer_data[j].data.length,
535 &result);
536 if (!NT_STATUS_IS_OK(status)) {
537 d_printf(_("\tSetPrinterDataEx: printer [%s], keyname [%s], valuename [%s] refused -- %s.\n"),
538 key_name, keyname, valuename, nt_errstr(status));
539 break;
540 } else if (!W_ERROR_IS_OK(result)) {
541 d_printf(_("\tSetPrinterDataEx: printer [%s], keyname [%s], valuename [%s] refused -- %s.\n"),
542 key_name, keyname, valuename, win_errstr(result));
543 status = werror_to_ntstatus(result);
544 break;
548 done:
549 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
551 return status;
554 static NTSTATUS migrate_secdesc(TALLOC_CTX *mem_ctx,
555 struct rpc_pipe_client *pipe_hnd,
556 const char *key_name,
557 unsigned char *data,
558 size_t length)
560 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
561 struct policy_handle hnd;
562 enum ndr_err_code ndr_err;
563 struct sec_desc_buf secdesc_ctr;
564 struct spoolss_SetPrinterInfo3 info3;
565 struct spoolss_SetPrinterInfoCtr info_ctr;
566 struct spoolss_DevmodeContainer devmode_ctr;
567 DATA_BLOB blob;
568 NTSTATUS status;
569 WERROR result;
571 if (strequal(key_name, "printers")) {
572 return NT_STATUS_OK;
575 blob = data_blob_const(data, length);
577 ZERO_STRUCT(secdesc_ctr);
579 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &secdesc_ctr,
580 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
581 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
582 d_fprintf(stderr, _("security descriptor pull failed: %s\n"),
583 ndr_errstr(ndr_err));
584 return NT_STATUS_NO_MEMORY;
587 d_printf(_("Migrating Security Descriptor: %s\n"), key_name);
589 result = rpccli_spoolss_openprinter_ex(pipe_hnd,
590 mem_ctx,
591 key_name,
592 MAXIMUM_ALLOWED_ACCESS,
593 &hnd);
594 if (!W_ERROR_IS_OK(result)) {
595 d_fprintf(stderr, _("\tOpenPrinter(%s) failed: %s\n"),
596 key_name, win_errstr(result));
597 return werror_to_ntstatus(result);
600 ZERO_STRUCT(devmode_ctr);
602 info3.sec_desc_ptr = 1;
604 info_ctr.info.info3 = &info3;
605 info_ctr.level = 3;
607 status = dcerpc_spoolss_SetPrinter(b,
608 mem_ctx,
609 &hnd,
610 &info_ctr,
611 &devmode_ctr,
612 &secdesc_ctr,
613 0, /* command */
614 &result);
615 if (!NT_STATUS_IS_OK(status)) {
616 d_printf(_("\tSetPrinter(%s) level 3 refused -- %s.\n"),
617 key_name, nt_errstr(status));
618 } else if (!W_ERROR_IS_OK(result)) {
619 d_printf(_("\tSetPrinter(%s) level 3 refused -- %s.\n"),
620 key_name, win_errstr(result));
621 status = werror_to_ntstatus(result);
624 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
626 return status;
629 static NTSTATUS printing_migrate_internal(struct net_context *c,
630 const struct dom_sid *domain_sid,
631 const char *domain_name,
632 struct cli_state *cli,
633 struct rpc_pipe_client *pipe_hnd,
634 TALLOC_CTX *mem_ctx,
635 int argc,
636 const char **argv)
638 TALLOC_CTX *tmp_ctx;
639 TDB_CONTEXT *tdb;
640 TDB_DATA kbuf, newkey, dbuf;
641 NTSTATUS status;
643 tmp_ctx = talloc_new(mem_ctx);
644 if (tmp_ctx == NULL) {
645 return NT_STATUS_NO_MEMORY;
648 tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600);
649 if (tdb == NULL) {
650 d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]);
651 status = NT_STATUS_NO_SUCH_FILE;
652 goto done;
655 for (kbuf = tdb_firstkey(tdb);
656 kbuf.dptr;
657 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
659 dbuf = tdb_fetch(tdb, kbuf);
660 if (!dbuf.dptr) {
661 continue;
664 if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
665 migrate_form(tmp_ctx,
666 pipe_hnd,
667 (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
668 dbuf.dptr,
669 dbuf.dsize);
670 SAFE_FREE(dbuf.dptr);
671 continue;
674 if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
675 migrate_driver(tmp_ctx,
676 pipe_hnd,
677 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
678 dbuf.dptr,
679 dbuf.dsize);
680 SAFE_FREE(dbuf.dptr);
681 continue;
684 if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
685 migrate_printer(tmp_ctx,
686 pipe_hnd,
687 (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
688 dbuf.dptr,
689 dbuf.dsize);
690 SAFE_FREE(dbuf.dptr);
691 continue;
694 if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
695 migrate_secdesc(tmp_ctx,
696 pipe_hnd,
697 (const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
698 dbuf.dptr,
699 dbuf.dsize);
700 SAFE_FREE(dbuf.dptr);
701 continue;
706 status = NT_STATUS_OK;
708 done:
709 talloc_free(tmp_ctx);
710 return status;
713 static int net_printing_migrate(struct net_context *c,
714 int argc,
715 const char **argv)
717 if (argc < 1 || c->display_usage) {
718 d_printf( "%s\n"
719 "net printing migrate <file.tdb>\n"
720 " %s\n",
721 _("Usage:"),
722 _("Migrate tdb printing files to new storage"));
723 return 0;
726 return run_rpc_command(c,
727 NULL,
728 &ndr_table_spoolss.syntax_id,
730 printing_migrate_internal,
731 argc,
732 argv);
735 * 'net printing' entrypoint.
736 * @param argc Standard main() style argc.
737 * @param argv Standard main() style argv. Initial components are already
738 * stripped.
741 int net_printing(struct net_context *c, int argc, const char **argv)
743 int ret = -1;
745 struct functable func[] = {
747 "dump",
748 net_printing_dump,
749 NET_TRANSPORT_LOCAL,
750 N_("Dump printer databases"),
751 N_("net printing dump\n"
752 " Dump tdb printing file")
756 "migrate",
757 net_printing_migrate,
758 NET_TRANSPORT_LOCAL | NET_TRANSPORT_RPC,
759 N_("Migrate printer databases"),
760 N_("net printing migrate\n"
761 " Migrate tdb printing files to new storage")
764 { NULL, NULL, 0, NULL, NULL }
767 ret = net_run_function(c, argc, argv, "net printing", func);
769 return ret;