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"
35 #define FORMS_PREFIX "FORMS/"
36 #define DRIVERS_PREFIX "DRIVERS/"
37 #define PRINTERS_PREFIX "PRINTERS/"
38 #define SECDESC_PREFIX "SECDESC/"
40 #define ARG_ENCODING "encoding="
42 struct printing_opts
{
47 static NTSTATUS
printing_parse_args(TALLOC_CTX
*mem_ctx
,
48 struct printing_opts
**popts
,
49 int argc
, const char **argv
)
52 struct printing_opts
*o
;
55 return NT_STATUS_INVALID_PARAMETER
;
58 o
= talloc_zero(mem_ctx
, struct printing_opts
);
60 return NT_STATUS_INVALID_PARAMETER
;
63 for (c
= 0; c
< argc
; c
++) {
64 if (strnequal(argv
[c
], ARG_ENCODING
, sizeof(ARG_ENCODING
) - 1)) {
65 o
->encoding
= talloc_strdup(o
,
66 argv
[c
] + sizeof(ARG_ENCODING
) - 1);
67 if (o
->encoding
== NULL
) {
68 return NT_STATUS_NO_MEMORY
;
71 o
->tdb
= talloc_strdup(o
, argv
[c
]);
73 return NT_STATUS_NO_MEMORY
;
82 static void dump_form(TALLOC_CTX
*mem_ctx
,
87 enum ndr_err_code ndr_err
;
90 struct ntprinting_form r
;
92 printf("found form: %s\n", key_name
);
94 blob
= data_blob_const(data
, length
);
98 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &r
,
99 (ndr_pull_flags_fn_t
)ndr_pull_ntprinting_form
);
100 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
101 d_fprintf(stderr
, _("form pull failed: %s\n"),
102 ndr_errstr(ndr_err
));
106 s
= NDR_PRINT_STRUCT_STRING(mem_ctx
, ntprinting_form
, &r
);
112 static void dump_driver(TALLOC_CTX
*mem_ctx
,
113 const char *key_name
,
116 bool do_string_conversion
)
118 enum ndr_err_code ndr_err
;
121 struct ntprinting_driver r
;
123 printf("found driver: %s\n", key_name
);
125 blob
= data_blob_const(data
, length
);
129 if (do_string_conversion
) {
130 r
.string_flags
= LIBNDR_FLAG_STR_ASCII
;
133 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &r
,
134 (ndr_pull_flags_fn_t
)ndr_pull_ntprinting_driver
);
135 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
136 d_fprintf(stderr
, _("driver pull failed: %s\n"),
137 ndr_errstr(ndr_err
));
141 s
= NDR_PRINT_STRUCT_STRING(mem_ctx
, ntprinting_driver
, &r
);
147 static void dump_printer(TALLOC_CTX
*mem_ctx
,
148 const char *key_name
,
151 bool do_string_conversion
)
153 enum ndr_err_code ndr_err
;
156 struct ntprinting_printer r
;
158 printf("found printer: %s\n", key_name
);
160 blob
= data_blob_const(data
, length
);
164 if (do_string_conversion
) {
165 r
.info
.string_flags
= LIBNDR_FLAG_STR_ASCII
;
168 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &r
,
169 (ndr_pull_flags_fn_t
)ndr_pull_ntprinting_printer
);
170 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
171 d_fprintf(stderr
, _("printer pull failed: %s\n"),
172 ndr_errstr(ndr_err
));
176 s
= NDR_PRINT_STRUCT_STRING(mem_ctx
, ntprinting_printer
, &r
);
182 static void dump_sd(TALLOC_CTX
*mem_ctx
,
183 const char *key_name
,
187 enum ndr_err_code ndr_err
;
190 struct sec_desc_buf r
;
192 printf("found security descriptor: %s\n", key_name
);
194 blob
= data_blob_const(data
, length
);
198 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &r
,
199 (ndr_pull_flags_fn_t
)ndr_pull_sec_desc_buf
);
200 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
201 d_fprintf(stderr
, _("security descriptor pull failed: %s\n"),
202 ndr_errstr(ndr_err
));
206 s
= NDR_PRINT_STRUCT_STRING(mem_ctx
, sec_desc_buf
, &r
);
213 static int net_printing_dump(struct net_context
*c
, int argc
,
217 TALLOC_CTX
*ctx
= talloc_stackframe();
219 TDB_DATA kbuf
, newkey
, dbuf
;
220 struct printing_opts
*o
;
221 const char *save_dos_charset
= lp_dos_charset();
222 bool do_string_conversion
= false;
225 if (argc
< 1 || c
->display_usage
) {
227 "net printing dump [options] <file.tdb>\n"
230 _("Dump formated printer information of the tdb."));
231 d_printf(_("Valid options:\n"));
232 d_printf(_(" encoding=<CP> Set the Code Page of the tdb file.\n"
233 " See iconv -l for the list of CP values\n"
234 " (CP1252 is Western latin1, CP1251 is Cyrillic).\n"));
238 status
= printing_parse_args(ctx
, &o
, argc
, argv
);
239 if (!NT_STATUS_IS_OK(status
)) {
240 d_fprintf(stderr
, _("failed to parse arguments\n"));
244 tdb
= tdb_open_log(o
->tdb
, 0, TDB_DEFAULT
, O_RDONLY
, 0600);
246 d_fprintf(stderr
, _("failed to open tdb file: %s\n"), o
->tdb
);
250 if (o
->encoding
!= NULL
) {
251 lp_set_cmdline("dos charset", o
->encoding
);
252 d_fprintf(stderr
, _("do string conversion from %s to %s\n"),
253 lp_dos_charset(), lp_unix_charset());
254 do_string_conversion
= true;
257 for (kbuf
= tdb_firstkey(tdb
);
259 newkey
= tdb_nextkey(tdb
, kbuf
), free(kbuf
.dptr
), kbuf
=newkey
)
261 dbuf
= tdb_fetch(tdb
, kbuf
);
266 if (strncmp((const char *)kbuf
.dptr
, FORMS_PREFIX
, strlen(FORMS_PREFIX
)) == 0) {
267 dump_form(ctx
, (const char *)kbuf
.dptr
+strlen(FORMS_PREFIX
), dbuf
.dptr
, dbuf
.dsize
);
268 SAFE_FREE(dbuf
.dptr
);
272 if (strncmp((const char *)kbuf
.dptr
, DRIVERS_PREFIX
, strlen(DRIVERS_PREFIX
)) == 0) {
274 (const char *)kbuf
.dptr
+strlen(DRIVERS_PREFIX
),
277 do_string_conversion
);
278 SAFE_FREE(dbuf
.dptr
);
282 if (strncmp((const char *)kbuf
.dptr
, PRINTERS_PREFIX
, strlen(PRINTERS_PREFIX
)) == 0) {
284 (const char *)kbuf
.dptr
+strlen(PRINTERS_PREFIX
),
287 do_string_conversion
);
288 SAFE_FREE(dbuf
.dptr
);
292 if (strncmp((const char *)kbuf
.dptr
, SECDESC_PREFIX
, strlen(SECDESC_PREFIX
)) == 0) {
293 dump_sd(ctx
, (const char *)kbuf
.dptr
+strlen(SECDESC_PREFIX
), dbuf
.dptr
, dbuf
.dsize
);
294 SAFE_FREE(dbuf
.dptr
);
303 lp_set_cmdline("dos charset", save_dos_charset
);
308 static NTSTATUS
printing_migrate_internal(struct net_context
*c
,
309 const struct dom_sid
*domain_sid
,
310 const char *domain_name
,
311 struct cli_state
*cli
,
312 struct rpc_pipe_client
*winreg_pipe
,
317 struct printing_opts
*o
;
320 TDB_DATA kbuf
, newkey
, dbuf
;
322 const char *save_dos_charset
= lp_dos_charset();
323 bool do_string_conversion
= false;
325 tmp_ctx
= talloc_new(mem_ctx
);
326 if (tmp_ctx
== NULL
) {
327 return NT_STATUS_NO_MEMORY
;
330 status
= printing_parse_args(tmp_ctx
, &o
, argc
, argv
);
331 if (!NT_STATUS_IS_OK(status
)) {
332 d_fprintf(stderr
, _("failed to parse arguments\n"));
336 tdb
= tdb_open_log(o
->tdb
, 0, TDB_DEFAULT
, O_RDONLY
, 0600);
338 d_fprintf(stderr
, _("failed to open tdb file: %s\n"), o
->tdb
);
339 status
= NT_STATUS_NO_SUCH_FILE
;
343 if (o
->encoding
!= NULL
) {
344 lp_set_cmdline("dos charset", o
->encoding
);
345 d_fprintf(stderr
, _("do string conversion from %s to %s\n"),
346 lp_dos_charset(), lp_unix_charset());
347 do_string_conversion
= true;
350 for (kbuf
= tdb_firstkey(tdb
);
352 newkey
= tdb_nextkey(tdb
, kbuf
), free(kbuf
.dptr
), kbuf
= newkey
)
354 dbuf
= tdb_fetch(tdb
, kbuf
);
359 if (strncmp((const char *) kbuf
.dptr
, FORMS_PREFIX
, strlen(FORMS_PREFIX
)) == 0) {
360 printing_tdb_migrate_form(tmp_ctx
,
362 (const char *) kbuf
.dptr
+ strlen(FORMS_PREFIX
),
365 SAFE_FREE(dbuf
.dptr
);
369 if (strncmp((const char *) kbuf
.dptr
, DRIVERS_PREFIX
, strlen(DRIVERS_PREFIX
)) == 0) {
370 printing_tdb_migrate_driver(tmp_ctx
,
372 (const char *) kbuf
.dptr
+ strlen(DRIVERS_PREFIX
),
375 do_string_conversion
);
376 SAFE_FREE(dbuf
.dptr
);
380 if (strncmp((const char *) kbuf
.dptr
, PRINTERS_PREFIX
, strlen(PRINTERS_PREFIX
)) == 0) {
381 printing_tdb_migrate_printer(tmp_ctx
,
383 (const char *) kbuf
.dptr
+ strlen(PRINTERS_PREFIX
),
386 do_string_conversion
);
387 SAFE_FREE(dbuf
.dptr
);
390 SAFE_FREE(dbuf
.dptr
);
393 for (kbuf
= tdb_firstkey(tdb
);
395 newkey
= tdb_nextkey(tdb
, kbuf
), free(kbuf
.dptr
), kbuf
= newkey
)
397 dbuf
= tdb_fetch(tdb
, kbuf
);
402 if (strncmp((const char *) kbuf
.dptr
, SECDESC_PREFIX
, strlen(SECDESC_PREFIX
)) == 0) {
403 printing_tdb_migrate_secdesc(tmp_ctx
,
405 (const char *) kbuf
.dptr
+ strlen(SECDESC_PREFIX
),
408 SAFE_FREE(dbuf
.dptr
);
411 SAFE_FREE(dbuf
.dptr
);
415 status
= NT_STATUS_OK
;
418 lp_set_cmdline("dos charset", save_dos_charset
);
419 talloc_free(tmp_ctx
);
423 static int net_printing_migrate(struct net_context
*c
,
427 if (argc
< 1 || c
->display_usage
) {
429 "net printing migrate [options] <file.tdb>\n"
432 _("Migrate tdb printing files to new storage"));
433 d_printf(_("Valid options:\n"));
434 d_printf(_(" encoding=<CP> Set the Code Page of the tdb file.\n"
435 " See iconv -l for the list of CP values\n"
436 " (CP1252 is Western latin1, CP1251 is Cyrillic).\n"));
440 return run_rpc_command(c
,
444 printing_migrate_internal
,
449 * 'net printing' entrypoint.
450 * @param argc Standard main() style argc.
451 * @param argv Standard main() style argv. Initial components are already
455 int net_printing(struct net_context
*c
, int argc
, const char **argv
)
459 struct functable func
[] = {
464 N_("Dump printer databases"),
465 N_("net printing dump\n"
466 " Dump tdb printing file")
471 net_printing_migrate
,
472 NET_TRANSPORT_LOCAL
| NET_TRANSPORT_RPC
,
473 N_("Migrate printer databases"),
474 N_("net printing migrate\n"
475 " Migrate tdb printing files to new storage")
478 { NULL
, NULL
, 0, NULL
, NULL
}
481 ret
= net_run_function(c
, argc
, argv
, "net printing", func
);