source: vendor/current/source3/utils/net_printing.c

Last change on this file was 989, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.7

File size: 13.2 KB
Line 
1/*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Local printing tdb migration interface
5
6 Copyright (C) Guenther Deschner 2010
7
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.
12
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.
17
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/>.
20 */
21
22#include "includes.h"
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"
32#include "util_tdb.h"
33#include "printing/nt_printing_migrate.h"
34
35#define FORMS_PREFIX "FORMS/"
36#define DRIVERS_PREFIX "DRIVERS/"
37#define PRINTERS_PREFIX "PRINTERS/"
38#define SECDESC_PREFIX "SECDESC/"
39
40#define ARG_ENCODING "encoding="
41
42struct printing_opts {
43 const char *encoding;
44 const char *tdb;
45};
46
47static NTSTATUS printing_parse_args(TALLOC_CTX *mem_ctx,
48 struct printing_opts **popts,
49 int argc, const char **argv)
50{
51 size_t c;
52 struct printing_opts *o;
53
54 if (argc == 0) {
55 return NT_STATUS_INVALID_PARAMETER;
56 }
57
58 o = talloc_zero(mem_ctx, struct printing_opts);
59 if (o == NULL) {
60 return NT_STATUS_INVALID_PARAMETER;
61 }
62
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;
69 }
70 } else {
71 o->tdb = talloc_strdup(o, argv[c]);
72 if (o->tdb == NULL) {
73 return NT_STATUS_NO_MEMORY;
74 }
75 }
76 }
77
78 *popts = o;
79 return NT_STATUS_OK;
80}
81
82static void dump_form(TALLOC_CTX *mem_ctx,
83 const char *key_name,
84 unsigned char *data,
85 size_t length)
86{
87 enum ndr_err_code ndr_err;
88 DATA_BLOB blob;
89 char *s;
90 struct ntprinting_form r;
91
92 printf("found form: %s\n", key_name);
93
94 blob = data_blob_const(data, length);
95
96 ZERO_STRUCT(r);
97
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));
103 return;
104 }
105
106 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_form, &r);
107 if (s) {
108 printf("%s\n", s);
109 }
110}
111
112static void dump_driver(TALLOC_CTX *mem_ctx,
113 const char *key_name,
114 unsigned char *data,
115 size_t length,
116 bool do_string_conversion)
117{
118 enum ndr_err_code ndr_err;
119 DATA_BLOB blob;
120 char *s;
121 struct ntprinting_driver r;
122
123 printf("found driver: %s\n", key_name);
124
125 blob = data_blob_const(data, length);
126
127 ZERO_STRUCT(r);
128
129 if (do_string_conversion) {
130 r.string_flags = LIBNDR_FLAG_STR_ASCII;
131 }
132
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));
138 return;
139 }
140
141 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_driver, &r);
142 if (s) {
143 printf("%s\n", s);
144 }
145}
146
147static void dump_printer(TALLOC_CTX *mem_ctx,
148 const char *key_name,
149 unsigned char *data,
150 size_t length,
151 bool do_string_conversion)
152{
153 enum ndr_err_code ndr_err;
154 DATA_BLOB blob;
155 char *s;
156 struct ntprinting_printer r;
157
158 printf("found printer: %s\n", key_name);
159
160 blob = data_blob_const(data, length);
161
162 ZERO_STRUCT(r);
163
164 if (do_string_conversion) {
165 r.info.string_flags = LIBNDR_FLAG_STR_ASCII;
166 }
167
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));
173 return;
174 }
175
176 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_printer, &r);
177 if (s) {
178 printf("%s\n", s);
179 }
180}
181
182static void dump_sd(TALLOC_CTX *mem_ctx,
183 const char *key_name,
184 unsigned char *data,
185 size_t length)
186{
187 enum ndr_err_code ndr_err;
188 DATA_BLOB blob;
189 char *s;
190 struct sec_desc_buf r;
191
192 printf("found security descriptor: %s\n", key_name);
193
194 blob = data_blob_const(data, length);
195
196 ZERO_STRUCT(r);
197
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));
203 return;
204 }
205
206 s = NDR_PRINT_STRUCT_STRING(mem_ctx, sec_desc_buf, &r);
207 if (s) {
208 printf("%s\n", s);
209 }
210}
211
212
213static int net_printing_dump(struct net_context *c, int argc,
214 const char **argv)
215{
216 int ret = -1;
217 TALLOC_CTX *ctx = talloc_stackframe();
218 TDB_CONTEXT *tdb;
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;
223 NTSTATUS status;
224
225 if (argc < 1 || c->display_usage) {
226 d_printf( "%s\n"
227 "net printing dump [options] <file.tdb>\n"
228 " %s\n",
229 _("Usage:"),
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"));
235 goto done;
236 }
237
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"));
241 goto done;
242 }
243
244 tdb = tdb_open_log(o->tdb, 0, TDB_DEFAULT, O_RDONLY, 0600);
245 if (!tdb) {
246 d_fprintf(stderr, _("failed to open tdb file: %s\n"), o->tdb);
247 goto done;
248 }
249
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;
255 }
256
257 for (kbuf = tdb_firstkey(tdb);
258 kbuf.dptr;
259 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf=newkey)
260 {
261 dbuf = tdb_fetch(tdb, kbuf);
262 if (!dbuf.dptr) {
263 continue;
264 }
265
266 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
267 char *key_name = NULL;
268 size_t converted_size = 0;
269 bool ok;
270
271 ok = pull_ascii_talloc(ctx,
272 &key_name,
273 (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
274 &converted_size);
275 if (!ok) {
276 continue;
277 }
278
279 dump_form(ctx, key_name, dbuf.dptr, dbuf.dsize);
280 TALLOC_FREE(key_name);
281 SAFE_FREE(dbuf.dptr);
282 continue;
283 }
284
285 if (strncmp((const char *)kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
286 char *key_name = NULL;
287 size_t converted_size = 0;
288 bool ok;
289
290 ok = pull_ascii_talloc(ctx,
291 &key_name,
292 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
293 &converted_size);
294 if (!ok) {
295 continue;
296 }
297
298 dump_driver(ctx,
299 key_name,
300 dbuf.dptr,
301 dbuf.dsize,
302 do_string_conversion);
303 TALLOC_FREE(key_name);
304 SAFE_FREE(dbuf.dptr);
305 continue;
306 }
307
308 if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
309 char *key_name = NULL;
310 size_t converted_size = 0;
311 bool ok;
312
313 ok = pull_ascii_talloc(ctx,
314 &key_name,
315 (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
316 &converted_size);
317 if (!ok) {
318 continue;
319 }
320
321 dump_printer(ctx,
322 key_name,
323 dbuf.dptr,
324 dbuf.dsize,
325 do_string_conversion);
326 TALLOC_FREE(key_name);
327 SAFE_FREE(dbuf.dptr);
328 continue;
329 }
330
331 if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
332 dump_sd(ctx, (const char *)kbuf.dptr+strlen(SECDESC_PREFIX), dbuf.dptr, dbuf.dsize);
333 SAFE_FREE(dbuf.dptr);
334 continue;
335 }
336
337 }
338
339 ret = 0;
340
341 done:
342 lp_set_cmdline("dos charset", save_dos_charset);
343 talloc_free(ctx);
344 return ret;
345}
346
347static NTSTATUS printing_migrate_internal(struct net_context *c,
348 const struct dom_sid *domain_sid,
349 const char *domain_name,
350 struct cli_state *cli,
351 struct rpc_pipe_client *winreg_pipe,
352 TALLOC_CTX *mem_ctx,
353 int argc,
354 const char **argv)
355{
356 struct printing_opts *o;
357 TALLOC_CTX *tmp_ctx;
358 TDB_CONTEXT *tdb;
359 TDB_DATA kbuf, newkey, dbuf;
360 NTSTATUS status;
361 const char *save_dos_charset = lp_dos_charset();
362 bool do_string_conversion = false;
363
364 tmp_ctx = talloc_new(mem_ctx);
365 if (tmp_ctx == NULL) {
366 return NT_STATUS_NO_MEMORY;
367 }
368
369 status = printing_parse_args(tmp_ctx, &o, argc, argv);
370 if (!NT_STATUS_IS_OK(status)) {
371 d_fprintf(stderr, _("failed to parse arguments\n"));
372 goto done;
373 }
374
375 tdb = tdb_open_log(o->tdb, 0, TDB_DEFAULT, O_RDONLY, 0600);
376 if (tdb == NULL) {
377 d_fprintf(stderr, _("failed to open tdb file: %s\n"), o->tdb);
378 status = NT_STATUS_NO_SUCH_FILE;
379 goto done;
380 }
381
382 if (o->encoding != NULL) {
383 lp_set_cmdline("dos charset", o->encoding);
384 d_fprintf(stderr, _("do string conversion from %s to %s\n"),
385 lp_dos_charset(), lp_unix_charset());
386 do_string_conversion = true;
387 }
388
389 for (kbuf = tdb_firstkey(tdb);
390 kbuf.dptr;
391 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
392 {
393 dbuf = tdb_fetch(tdb, kbuf);
394 if (!dbuf.dptr) {
395 continue;
396 }
397
398 if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
399 char *key_name = NULL;
400 size_t converted_size = 0;
401 bool ok;
402
403 ok = pull_ascii_talloc(tmp_ctx,
404 &key_name,
405 (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
406 &converted_size);
407 if (!ok) {
408 continue;
409 }
410
411 printing_tdb_migrate_form(tmp_ctx,
412 winreg_pipe,
413 key_name,
414 dbuf.dptr,
415 dbuf.dsize);
416 TALLOC_FREE(key_name);
417 SAFE_FREE(dbuf.dptr);
418 continue;
419 }
420
421 if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
422 char *key_name = NULL;
423 size_t converted_size = 0;
424 bool ok;
425
426 ok = pull_ascii_talloc(tmp_ctx,
427 &key_name,
428 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
429 &converted_size);
430 if (!ok) {
431 continue;
432 }
433
434 printing_tdb_migrate_driver(tmp_ctx,
435 winreg_pipe,
436 key_name,
437 dbuf.dptr,
438 dbuf.dsize,
439 do_string_conversion);
440 TALLOC_FREE(key_name);
441 SAFE_FREE(dbuf.dptr);
442 continue;
443 }
444
445 if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
446 char *key_name = NULL;
447 size_t converted_size = 0;
448 bool ok;
449
450 ok = pull_ascii_talloc(tmp_ctx,
451 &key_name,
452 (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
453 &converted_size);
454 if (!ok) {
455 continue;
456 }
457
458 printing_tdb_migrate_printer(tmp_ctx,
459 winreg_pipe,
460 key_name,
461 dbuf.dptr,
462 dbuf.dsize,
463 do_string_conversion);
464 TALLOC_FREE(key_name);
465 SAFE_FREE(dbuf.dptr);
466 continue;
467 }
468 SAFE_FREE(dbuf.dptr);
469 }
470
471 for (kbuf = tdb_firstkey(tdb);
472 kbuf.dptr;
473 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
474 {
475 dbuf = tdb_fetch(tdb, kbuf);
476 if (!dbuf.dptr) {
477 continue;
478 }
479
480 if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
481 printing_tdb_migrate_secdesc(tmp_ctx,
482 winreg_pipe,
483 (const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
484 dbuf.dptr,
485 dbuf.dsize);
486 SAFE_FREE(dbuf.dptr);
487 continue;
488 }
489 SAFE_FREE(dbuf.dptr);
490
491 }
492
493 status = NT_STATUS_OK;
494
495 done:
496 lp_set_cmdline("dos charset", save_dos_charset);
497 talloc_free(tmp_ctx);
498 return status;
499}
500
501static int net_printing_migrate(struct net_context *c,
502 int argc,
503 const char **argv)
504{
505 if (argc < 1 || c->display_usage) {
506 d_printf( "%s\n"
507 "net printing migrate [options] <file.tdb>\n"
508 " %s\n",
509 _("Usage:"),
510 _("Migrate tdb printing files to new storage"));
511 d_printf(_("Valid options:\n"));
512 d_printf(_(" encoding=<CP> Set the Code Page of the tdb file.\n"
513 " See iconv -l for the list of CP values\n"
514 " (CP1252 is Western latin1, CP1251 is Cyrillic).\n"));
515 return 0;
516 }
517
518 return run_rpc_command(c,
519 NULL,
520 &ndr_table_winreg,
521 0,
522 printing_migrate_internal,
523 argc,
524 argv);
525}
526/**
527 * 'net printing' entrypoint.
528 * @param argc Standard main() style argc.
529 * @param argv Standard main() style argv. Initial components are already
530 * stripped.
531 **/
532
533int net_printing(struct net_context *c, int argc, const char **argv)
534{
535 int ret = -1;
536
537 struct functable func[] = {
538 {
539 "dump",
540 net_printing_dump,
541 NET_TRANSPORT_LOCAL,
542 N_("Dump printer databases"),
543 N_("net printing dump\n"
544 " Dump tdb printing file")
545 },
546
547 {
548 "migrate",
549 net_printing_migrate,
550 NET_TRANSPORT_LOCAL | NET_TRANSPORT_RPC,
551 N_("Migrate printer databases"),
552 N_("net printing migrate\n"
553 " Migrate tdb printing files to new storage")
554 },
555
556 { NULL, NULL, 0, NULL, NULL }
557 };
558
559 ret = net_run_function(c, argc, argv, "net printing", func);
560
561 return ret;
562}
Note: See TracBrowser for help on using the repository browser.