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"
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
{
52 static NTSTATUS
printing_parse_args(TALLOC_CTX
*mem_ctx
,
53 struct printing_opts
**popts
,
54 int argc
, const char **argv
)
57 struct printing_opts
*o
;
60 return NT_STATUS_INVALID_PARAMETER
;
63 o
= talloc_zero(mem_ctx
, struct printing_opts
);
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
;
76 o
->tdb
= talloc_strdup(o
, argv
[c
]);
78 return NT_STATUS_NO_MEMORY
;
87 static void dump_form(TALLOC_CTX
*mem_ctx
,
92 enum ndr_err_code ndr_err
;
95 struct ntprinting_form r
;
97 printf("found form: %s\n", key_name
);
99 blob
= data_blob_const(data
, length
);
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
));
111 s
= NDR_PRINT_STRUCT_STRING(mem_ctx
, ntprinting_form
, &r
);
117 static void dump_driver(TALLOC_CTX
*mem_ctx
,
118 const char *key_name
,
121 bool do_string_conversion
)
123 enum ndr_err_code ndr_err
;
126 struct ntprinting_driver r
;
128 printf("found driver: %s\n", key_name
);
130 blob
= data_blob_const(data
, length
);
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
));
146 s
= NDR_PRINT_STRUCT_STRING(mem_ctx
, ntprinting_driver
, &r
);
152 static void dump_printer(TALLOC_CTX
*mem_ctx
,
153 const char *key_name
,
156 bool do_string_conversion
)
158 enum ndr_err_code ndr_err
;
161 struct ntprinting_printer r
;
163 printf("found printer: %s\n", key_name
);
165 blob
= data_blob_const(data
, length
);
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
));
181 s
= NDR_PRINT_STRUCT_STRING(mem_ctx
, ntprinting_printer
, &r
);
187 static void dump_sd(TALLOC_CTX
*mem_ctx
,
188 const char *key_name
,
192 enum ndr_err_code ndr_err
;
195 struct sec_desc_buf r
;
197 printf("found security descriptor: %s\n", key_name
);
199 blob
= data_blob_const(data
, length
);
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
));
211 s
= NDR_PRINT_STRUCT_STRING(mem_ctx
, sec_desc_buf
, &r
);
218 static int net_printing_dump(struct net_context
*c
, int argc
,
222 TALLOC_CTX
*ctx
= talloc_stackframe();
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;
230 if (argc
< 1 || c
->display_usage
) {
232 "net printing dump [options] <file.tdb>\n"
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"));
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"));
249 tdb
= tdb_open_log(o
->tdb
, 0, TDB_DEFAULT
, O_RDONLY
, 0600);
251 d_fprintf(stderr
, _("failed to open tdb file: %s\n"), o
->tdb
);
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
);
264 newkey
= tdb_nextkey(tdb
, kbuf
), free(kbuf
.dptr
), kbuf
=newkey
)
268 dbuf
= tdb_fetch(tdb
, kbuf
);
273 cmp
= strncmp((const char *)kbuf
.dptr
,
277 char *key_name
= NULL
;
278 size_t converted_size
= 0;
281 ok
= pull_ascii_talloc(ctx
,
283 (const char *) kbuf
.dptr
+ strlen(FORMS_PREFIX
),
289 dump_form(ctx
, key_name
, dbuf
.dptr
, dbuf
.dsize
);
290 TALLOC_FREE(key_name
);
291 SAFE_FREE(dbuf
.dptr
);
295 cmp
= strncmp((const char *)kbuf
.dptr
,
299 char *key_name
= NULL
;
300 size_t converted_size
= 0;
303 ok
= pull_ascii_talloc(ctx
,
305 (const char *) kbuf
.dptr
+ strlen(DRIVERS_PREFIX
),
315 do_string_conversion
);
316 TALLOC_FREE(key_name
);
317 SAFE_FREE(dbuf
.dptr
);
321 cmp
= strncmp((const char *)kbuf
.dptr
,
323 PRINTERS_PREFIX_LEN
);
325 char *key_name
= NULL
;
326 size_t converted_size
= 0;
329 ok
= pull_ascii_talloc(ctx
,
331 (const char *) kbuf
.dptr
+ strlen(PRINTERS_PREFIX
),
341 do_string_conversion
);
342 TALLOC_FREE(key_name
);
343 SAFE_FREE(dbuf
.dptr
);
347 cmp
= strncmp((const char *)kbuf
.dptr
,
351 dump_sd(ctx
, (const char *)kbuf
.dptr
+strlen(SECDESC_PREFIX
), dbuf
.dptr
, dbuf
.dsize
);
352 SAFE_FREE(dbuf
.dptr
);
361 lpcfg_set_cmdline(c
->lp_ctx
, "dos charset", save_dos_charset
);
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
,
375 struct printing_opts
*o
;
378 TDB_DATA kbuf
, newkey
, dbuf
;
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"));
394 tdb
= tdb_open_log(o
->tdb
, 0, TDB_DEFAULT
, O_RDONLY
, 0600);
396 d_fprintf(stderr
, _("failed to open tdb file: %s\n"), o
->tdb
);
397 status
= NT_STATUS_NO_SUCH_FILE
;
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
);
410 newkey
= tdb_nextkey(tdb
, kbuf
), free(kbuf
.dptr
), kbuf
= newkey
)
414 dbuf
= tdb_fetch(tdb
, kbuf
);
419 cmp
= strncmp((const char *) kbuf
.dptr
,
423 char *key_name
= NULL
;
424 size_t converted_size
= 0;
427 ok
= pull_ascii_talloc(tmp_ctx
,
429 (const char *) kbuf
.dptr
+ strlen(FORMS_PREFIX
),
435 printing_tdb_migrate_form(tmp_ctx
,
440 TALLOC_FREE(key_name
);
441 SAFE_FREE(dbuf
.dptr
);
445 cmp
= strncmp((const char *) kbuf
.dptr
,
449 char *key_name
= NULL
;
450 size_t converted_size
= 0;
453 ok
= pull_ascii_talloc(tmp_ctx
,
455 (const char *) kbuf
.dptr
+ strlen(DRIVERS_PREFIX
),
461 printing_tdb_migrate_driver(tmp_ctx
,
466 do_string_conversion
);
467 TALLOC_FREE(key_name
);
468 SAFE_FREE(dbuf
.dptr
);
472 cmp
= strncmp((const char *) kbuf
.dptr
,
474 PRINTERS_PREFIX_LEN
);
476 char *key_name
= NULL
;
477 size_t converted_size
= 0;
480 ok
= pull_ascii_talloc(tmp_ctx
,
482 (const char *) kbuf
.dptr
+ strlen(PRINTERS_PREFIX
),
488 printing_tdb_migrate_printer(tmp_ctx
,
493 do_string_conversion
);
494 TALLOC_FREE(key_name
);
495 SAFE_FREE(dbuf
.dptr
);
498 SAFE_FREE(dbuf
.dptr
);
501 for (kbuf
= tdb_firstkey(tdb
);
503 newkey
= tdb_nextkey(tdb
, kbuf
), free(kbuf
.dptr
), kbuf
= newkey
)
505 dbuf
= tdb_fetch(tdb
, kbuf
);
510 if (strncmp((const char *) kbuf
.dptr
, SECDESC_PREFIX
, strlen(SECDESC_PREFIX
)) == 0) {
511 printing_tdb_migrate_secdesc(tmp_ctx
,
513 (const char *) kbuf
.dptr
+ strlen(SECDESC_PREFIX
),
516 SAFE_FREE(dbuf
.dptr
);
519 SAFE_FREE(dbuf
.dptr
);
523 status
= NT_STATUS_OK
;
526 lpcfg_set_cmdline(c
->lp_ctx
, "dos charset", save_dos_charset
);
527 talloc_free(tmp_ctx
);
531 static int net_printing_migrate(struct net_context
*c
,
535 if (argc
< 1 || c
->display_usage
) {
537 "net printing migrate [options] <file.tdb>\n"
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"));
548 return run_rpc_command(c
,
552 printing_migrate_internal
,
557 * 'net printing' entrypoint.
558 * @param argc Standard main() style argc.
559 * @param argv Standard main() style argv. Initial components are already
563 int net_printing(struct net_context
*c
, int argc
, const char **argv
)
567 struct functable func
[] = {
572 N_("Dump printer databases"),
573 N_("net printing dump\n"
574 " Dump tdb printing file")
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
);