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

Last change on this file was 860, checked in by Silvan Scherrer, 11 years ago

Samba 3.6: updated vendor to latest version

File size: 11.8 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 dump_form(ctx, (const char *)kbuf.dptr+strlen(FORMS_PREFIX), dbuf.dptr, dbuf.dsize);
268 SAFE_FREE(dbuf.dptr);
269 continue;
270 }
271
272 if (strncmp((const char *)kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
273 dump_driver(ctx,
274 (const char *)kbuf.dptr+strlen(DRIVERS_PREFIX),
275 dbuf.dptr,
276 dbuf.dsize,
277 do_string_conversion);
278 SAFE_FREE(dbuf.dptr);
279 continue;
280 }
281
282 if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
283 dump_printer(ctx,
284 (const char *)kbuf.dptr+strlen(PRINTERS_PREFIX),
285 dbuf.dptr,
286 dbuf.dsize,
287 do_string_conversion);
288 SAFE_FREE(dbuf.dptr);
289 continue;
290 }
291
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);
295 continue;
296 }
297
298 }
299
300 ret = 0;
301
302 done:
303 lp_set_cmdline("dos charset", save_dos_charset);
304 talloc_free(ctx);
305 return ret;
306}
307
308static 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,
313 TALLOC_CTX *mem_ctx,
314 int argc,
315 const char **argv)
316{
317 struct printing_opts *o;
318 TALLOC_CTX *tmp_ctx;
319 TDB_CONTEXT *tdb;
320 TDB_DATA kbuf, newkey, dbuf;
321 NTSTATUS status;
322 const char *save_dos_charset = lp_dos_charset();
323 bool do_string_conversion = false;
324
325 tmp_ctx = talloc_new(mem_ctx);
326 if (tmp_ctx == NULL) {
327 return NT_STATUS_NO_MEMORY;
328 }
329
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"));
333 goto done;
334 }
335
336 tdb = tdb_open_log(o->tdb, 0, TDB_DEFAULT, O_RDONLY, 0600);
337 if (tdb == NULL) {
338 d_fprintf(stderr, _("failed to open tdb file: %s\n"), o->tdb);
339 status = NT_STATUS_NO_SUCH_FILE;
340 goto done;
341 }
342
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;
348 }
349
350 for (kbuf = tdb_firstkey(tdb);
351 kbuf.dptr;
352 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
353 {
354 dbuf = tdb_fetch(tdb, kbuf);
355 if (!dbuf.dptr) {
356 continue;
357 }
358
359 if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
360 printing_tdb_migrate_form(tmp_ctx,
361 winreg_pipe,
362 (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
363 dbuf.dptr,
364 dbuf.dsize);
365 SAFE_FREE(dbuf.dptr);
366 continue;
367 }
368
369 if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
370 printing_tdb_migrate_driver(tmp_ctx,
371 winreg_pipe,
372 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
373 dbuf.dptr,
374 dbuf.dsize,
375 do_string_conversion);
376 SAFE_FREE(dbuf.dptr);
377 continue;
378 }
379
380 if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
381 printing_tdb_migrate_printer(tmp_ctx,
382 winreg_pipe,
383 (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
384 dbuf.dptr,
385 dbuf.dsize,
386 do_string_conversion);
387 SAFE_FREE(dbuf.dptr);
388 continue;
389 }
390 SAFE_FREE(dbuf.dptr);
391 }
392
393 for (kbuf = tdb_firstkey(tdb);
394 kbuf.dptr;
395 newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
396 {
397 dbuf = tdb_fetch(tdb, kbuf);
398 if (!dbuf.dptr) {
399 continue;
400 }
401
402 if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
403 printing_tdb_migrate_secdesc(tmp_ctx,
404 winreg_pipe,
405 (const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
406 dbuf.dptr,
407 dbuf.dsize);
408 SAFE_FREE(dbuf.dptr);
409 continue;
410 }
411 SAFE_FREE(dbuf.dptr);
412
413 }
414
415 status = NT_STATUS_OK;
416
417 done:
418 lp_set_cmdline("dos charset", save_dos_charset);
419 talloc_free(tmp_ctx);
420 return status;
421}
422
423static int net_printing_migrate(struct net_context *c,
424 int argc,
425 const char **argv)
426{
427 if (argc < 1 || c->display_usage) {
428 d_printf( "%s\n"
429 "net printing migrate [options] <file.tdb>\n"
430 " %s\n",
431 _("Usage:"),
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"));
437 return 0;
438 }
439
440 return run_rpc_command(c,
441 NULL,
442 &ndr_table_winreg.syntax_id,
443 0,
444 printing_migrate_internal,
445 argc,
446 argv);
447}
448/**
449 * 'net printing' entrypoint.
450 * @param argc Standard main() style argc.
451 * @param argv Standard main() style argv. Initial components are already
452 * stripped.
453 **/
454
455int net_printing(struct net_context *c, int argc, const char **argv)
456{
457 int ret = -1;
458
459 struct functable func[] = {
460 {
461 "dump",
462 net_printing_dump,
463 NET_TRANSPORT_LOCAL,
464 N_("Dump printer databases"),
465 N_("net printing dump\n"
466 " Dump tdb printing file")
467 },
468
469 {
470 "migrate",
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")
476 },
477
478 { NULL, NULL, 0, NULL, NULL }
479 };
480
481 ret = net_run_function(c, argc, argv, "net printing", func);
482
483 return ret;
484}
Note: See TracBrowser for help on using the repository browser.