s3-printing: fill devicemode size in migrate_printer()
[Samba.git] / source3 / utils / net_printing.c
blob6e82c55afe40e14a5138429ee3bcd661636f3581
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, 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_compat(tdb);
180 kbuf.dptr;
181 kbuf = tdb_nextkey_compat(tdb, kbuf))
183 dbuf = tdb_fetch_compat(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.size = r.devmode->size;
470 dm.scale = r.devmode->scale;
471 dm.specversion = r.devmode->specversion;
472 dm.ttoption = r.devmode->ttoption;
473 dm.yresolution = r.devmode->yresolution;
475 if (r.devmode->nt_dev_private != NULL) {
476 dm.driverextra_data.data = r.devmode->nt_dev_private->data;
477 dm.driverextra_data.length = r.devmode->nt_dev_private->length;
478 dm.__driverextra_length = r.devmode->nt_dev_private->length;
481 devmode_ctr.devmode = &dm;
483 info2.devmode_ptr = 1;
486 info_ctr.info.info2 = &info2;
487 info_ctr.level = 2;
489 status = dcerpc_spoolss_SetPrinter(b,
490 mem_ctx,
491 &hnd,
492 &info_ctr,
493 &devmode_ctr,
494 &secdesc_ctr,
495 0, /* command */
496 &result);
497 if (!NT_STATUS_IS_OK(status)) {
498 d_printf(_("\tSetPrinter(%s) level 2 refused -- %s.\n"),
499 key_name, nt_errstr(status));
500 goto done;
501 } else if (!W_ERROR_IS_OK(result)) {
502 d_printf(_("\tSetPrinter(%s) level 2 refused -- %s.\n"),
503 key_name, win_errstr(result));
504 status = werror_to_ntstatus(result);
505 goto done;
508 /* migrate printerdata */
509 for (j = 0; j < r.count; j++) {
510 char *valuename;
511 char *keyname;
513 if (r.printer_data[j].type == REG_NONE) {
514 continue;
517 keyname = discard_const_p(char, r.printer_data[j].name);
518 valuename = strchr(keyname, '\\');
519 if (valuename == NULL) {
520 continue;
521 } else {
522 valuename[0] = '\0';
523 valuename++;
526 printf(" data: %s\\%s\n", keyname, valuename);
528 status = dcerpc_spoolss_SetPrinterDataEx(b,
529 mem_ctx,
530 &hnd,
531 keyname,
532 valuename,
533 r.printer_data[j].type,
534 r.printer_data[j].data.data,
535 r.printer_data[j].data.length,
536 &result);
537 if (!NT_STATUS_IS_OK(status)) {
538 d_printf(_("\tSetPrinterDataEx: printer [%s], keyname [%s], valuename [%s] refused -- %s.\n"),
539 key_name, keyname, valuename, nt_errstr(status));
540 break;
541 } else if (!W_ERROR_IS_OK(result)) {
542 d_printf(_("\tSetPrinterDataEx: printer [%s], keyname [%s], valuename [%s] refused -- %s.\n"),
543 key_name, keyname, valuename, win_errstr(result));
544 status = werror_to_ntstatus(result);
545 break;
549 done:
550 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
552 return status;
555 static NTSTATUS migrate_secdesc(TALLOC_CTX *mem_ctx,
556 struct rpc_pipe_client *pipe_hnd,
557 const char *key_name,
558 unsigned char *data,
559 size_t length)
561 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
562 struct policy_handle hnd;
563 enum ndr_err_code ndr_err;
564 struct sec_desc_buf secdesc_ctr;
565 struct spoolss_SetPrinterInfo3 info3;
566 struct spoolss_SetPrinterInfoCtr info_ctr;
567 struct spoolss_DevmodeContainer devmode_ctr;
568 DATA_BLOB blob;
569 NTSTATUS status;
570 WERROR result;
572 if (strequal(key_name, "printers")) {
573 return NT_STATUS_OK;
576 blob = data_blob_const(data, length);
578 ZERO_STRUCT(secdesc_ctr);
580 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &secdesc_ctr,
581 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
582 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
583 d_fprintf(stderr, _("security descriptor pull failed: %s\n"),
584 ndr_errstr(ndr_err));
585 return NT_STATUS_NO_MEMORY;
588 d_printf(_("Migrating Security Descriptor: %s\n"), key_name);
590 result = rpccli_spoolss_openprinter_ex(pipe_hnd,
591 mem_ctx,
592 key_name,
593 MAXIMUM_ALLOWED_ACCESS,
594 &hnd);
595 if (!W_ERROR_IS_OK(result)) {
596 d_fprintf(stderr, _("\tOpenPrinter(%s) failed: %s\n"),
597 key_name, win_errstr(result));
598 return werror_to_ntstatus(result);
601 ZERO_STRUCT(devmode_ctr);
603 info3.sec_desc_ptr = 1;
605 info_ctr.info.info3 = &info3;
606 info_ctr.level = 3;
608 status = dcerpc_spoolss_SetPrinter(b,
609 mem_ctx,
610 &hnd,
611 &info_ctr,
612 &devmode_ctr,
613 &secdesc_ctr,
614 0, /* command */
615 &result);
616 if (!NT_STATUS_IS_OK(status)) {
617 d_printf(_("\tSetPrinter(%s) level 3 refused -- %s.\n"),
618 key_name, nt_errstr(status));
619 } else if (!W_ERROR_IS_OK(result)) {
620 d_printf(_("\tSetPrinter(%s) level 3 refused -- %s.\n"),
621 key_name, win_errstr(result));
622 status = werror_to_ntstatus(result);
625 dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
627 return status;
630 static NTSTATUS printing_migrate_internal(struct net_context *c,
631 const struct dom_sid *domain_sid,
632 const char *domain_name,
633 struct cli_state *cli,
634 struct rpc_pipe_client *pipe_hnd,
635 TALLOC_CTX *mem_ctx,
636 int argc,
637 const char **argv)
639 TALLOC_CTX *tmp_ctx;
640 TDB_CONTEXT *tdb;
641 TDB_DATA kbuf, dbuf;
642 NTSTATUS status;
644 tmp_ctx = talloc_new(mem_ctx);
645 if (tmp_ctx == NULL) {
646 return NT_STATUS_NO_MEMORY;
649 tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600);
650 if (tdb == NULL) {
651 d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]);
652 status = NT_STATUS_NO_SUCH_FILE;
653 goto done;
656 for (kbuf = tdb_firstkey_compat(tdb);
657 kbuf.dptr;
658 kbuf = tdb_nextkey_compat(tdb, kbuf))
660 dbuf = tdb_fetch_compat(tdb, kbuf);
661 if (!dbuf.dptr) {
662 continue;
665 if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
666 migrate_form(tmp_ctx,
667 pipe_hnd,
668 (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
669 dbuf.dptr,
670 dbuf.dsize);
671 SAFE_FREE(dbuf.dptr);
672 continue;
675 if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
676 migrate_driver(tmp_ctx,
677 pipe_hnd,
678 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
679 dbuf.dptr,
680 dbuf.dsize);
681 SAFE_FREE(dbuf.dptr);
682 continue;
685 if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
686 migrate_printer(tmp_ctx,
687 pipe_hnd,
688 (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
689 dbuf.dptr,
690 dbuf.dsize);
691 SAFE_FREE(dbuf.dptr);
692 continue;
695 if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
696 migrate_secdesc(tmp_ctx,
697 pipe_hnd,
698 (const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
699 dbuf.dptr,
700 dbuf.dsize);
701 SAFE_FREE(dbuf.dptr);
702 continue;
707 status = NT_STATUS_OK;
709 done:
710 talloc_free(tmp_ctx);
711 return status;
714 static int net_printing_migrate(struct net_context *c,
715 int argc,
716 const char **argv)
718 if (argc < 1 || c->display_usage) {
719 d_printf( "%s\n"
720 "net printing migrate <file.tdb>\n"
721 " %s\n",
722 _("Usage:"),
723 _("Migrate tdb printing files to new storage"));
724 return 0;
727 return run_rpc_command(c,
728 NULL,
729 &ndr_table_spoolss.syntax_id,
731 printing_migrate_internal,
732 argc,
733 argv);
736 * 'net printing' entrypoint.
737 * @param argc Standard main() style argc.
738 * @param argv Standard main() style argv. Initial components are already
739 * stripped.
742 int net_printing(struct net_context *c, int argc, const char **argv)
744 int ret = -1;
746 struct functable func[] = {
748 "dump",
749 net_printing_dump,
750 NET_TRANSPORT_LOCAL,
751 N_("Dump printer databases"),
752 N_("net printing dump\n"
753 " Dump tdb printing file")
757 "migrate",
758 net_printing_migrate,
759 NET_TRANSPORT_LOCAL | NET_TRANSPORT_RPC,
760 N_("Migrate printer databases"),
761 N_("net printing migrate\n"
762 " Migrate tdb printing files to new storage")
765 { NULL, NULL, 0, NULL, NULL }
768 ret = net_run_function(c, argc, argv, "net printing", func);
770 return ret;