/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- display_print_driver3
- display_reg_value
- net_copy_fileattr
- net_copy_file
- net_copy_driverfile
- check_arch_dir
- copy_print_driver_3
- net_spoolss_enum_printers
- net_spoolss_open_printer_ex
- net_spoolss_getprinter
- net_spoolss_setprinter
- net_spoolss_setprinterdata
- net_spoolss_enumprinterkey
- net_spoolss_enumprinterdataex
- net_spoolss_setprinterdataex
- net_spoolss_enumforms
- net_spoolss_enumprinterdrivers
- net_spoolss_getprinterdriver
- net_spoolss_addprinterdriver
- get_printer_info
- rpc_printer_list_internals
- rpc_printer_driver_list_internals
- rpc_printer_publish_internals_args
- rpc_printer_publish_publish_internals
- rpc_printer_publish_unpublish_internals
- rpc_printer_publish_update_internals
- rpc_printer_publish_list_internals
- rpc_printer_migrate_security_internals
- rpc_printer_migrate_forms_internals
- rpc_printer_migrate_drivers_internals
- rpc_printer_migrate_printers_internals
- rpc_printer_migrate_settings_internals
1 /*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) 2004,2009 Guenther Deschner (gd@samba.org)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "includes.h"
20 #include "utils/net.h"
21
22 /* support itanium as well */
23 static const struct print_architecture_table_node archi_table[]= {
24
25 {"Windows 4.0", "WIN40", 0 },
26 {"Windows NT x86", "W32X86", 2 },
27 {"Windows NT x86", "W32X86", 3 },
28 {"Windows NT R4000", "W32MIPS", 2 },
29 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
30 {"Windows NT PowerPC", "W32PPC", 2 },
31 {"Windows IA64", "IA64", 3 },
32 {"Windows x64", "x64", 3 },
33 {NULL, "", -1 }
34 };
35
36
37 /**
38 * This display-printdriver-functions was borrowed from rpcclient/cmd_spoolss.c.
39 * It is here for debugging purpose and should be removed later on.
40 **/
41
42 /****************************************************************************
43 Printer info level 3 display function.
44 ****************************************************************************/
45
46 static void display_print_driver3(struct spoolss_DriverInfo3 *r)
/* [<][>][^][v][top][bottom][index][help] */
47 {
48 int i;
49
50 if (!r) {
51 return;
52 }
53
54 printf("Printer Driver Info 3:\n");
55 printf("\tVersion: [%x]\n", r->version);
56 printf("\tDriver Name: [%s]\n", r->driver_name);
57 printf("\tArchitecture: [%s]\n", r->architecture);
58 printf("\tDriver Path: [%s]\n", r->driver_path);
59 printf("\tDatafile: [%s]\n", r->data_file);
60 printf("\tConfigfile: [%s]\n\n", r->config_file);
61 printf("\tHelpfile: [%s]\n\n", r->help_file);
62
63 for (i=0; r->dependent_files[i] != NULL; i++) {
64 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
65 }
66
67 printf("\n");
68
69 printf("\tMonitorname: [%s]\n", r->monitor_name);
70 printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype);
71 }
72
73 static void display_reg_value(const char *subkey, REGISTRY_VALUE value)
/* [<][>][^][v][top][bottom][index][help] */
74 {
75 char *text;
76
77 switch(value.type) {
78 case REG_DWORD:
79 d_printf("\t[%s:%s]: REG_DWORD: 0x%08x\n", subkey, value.valuename,
80 *((uint32_t *) value.data_p));
81 break;
82
83 case REG_SZ:
84 rpcstr_pull_talloc(talloc_tos(),
85 &text,
86 value.data_p,
87 value.size,
88 STR_TERMINATE);
89 if (!text) {
90 break;
91 }
92 d_printf("\t[%s:%s]: REG_SZ: %s\n", subkey, value.valuename, text);
93 break;
94
95 case REG_BINARY:
96 d_printf("\t[%s:%s]: REG_BINARY: unknown length value not displayed\n",
97 subkey, value.valuename);
98 break;
99
100 case REG_MULTI_SZ: {
101 uint32_t i, num_values;
102 char **values;
103
104 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p,
105 value.size, &num_values,
106 &values))) {
107 d_printf("reg_pull_multi_sz failed\n");
108 break;
109 }
110
111 for (i=0; i<num_values; i++) {
112 d_printf("%s\n", values[i]);
113 }
114 TALLOC_FREE(values);
115 break;
116 }
117
118 default:
119 d_printf("\t%s: unknown type %d\n", value.valuename, value.type);
120 }
121
122 }
123
124 /**
125 * Copies ACLs, DOS-attributes and timestamps from one
126 * file or directory from one connected share to another connected share
127 *
128 * @param c A net_context structure
129 * @param mem_ctx A talloc-context
130 * @param cli_share_src A connected cli_state
131 * @param cli_share_dst A connected cli_state
132 * @param src_file The source file-name
133 * @param dst_file The destination file-name
134 * @param copy_acls Whether to copy acls
135 * @param copy_attrs Whether to copy DOS attributes
136 * @param copy_timestamps Whether to preserve timestamps
137 * @param is_file Whether this file is a file or a dir
138 *
139 * @return Normal NTSTATUS return.
140 **/
141
142 NTSTATUS net_copy_fileattr(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
143 TALLOC_CTX *mem_ctx,
144 struct cli_state *cli_share_src,
145 struct cli_state *cli_share_dst,
146 const char *src_name, const char *dst_name,
147 bool copy_acls, bool copy_attrs,
148 bool copy_timestamps, bool is_file)
149 {
150 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
151 int fnum_src = 0;
152 int fnum_dst = 0;
153 SEC_DESC *sd = NULL;
154 uint16_t attr;
155 time_t f_atime, f_ctime, f_mtime;
156
157
158 if (!copy_timestamps && !copy_acls && !copy_attrs)
159 return NT_STATUS_OK;
160
161 /* open file/dir on the originating server */
162
163 DEBUGADD(3,("opening %s %s on originating server\n",
164 is_file?"file":"dir", src_name));
165
166 fnum_src = cli_nt_create(cli_share_src, src_name, READ_CONTROL_ACCESS);
167 if (fnum_src == -1) {
168 DEBUGADD(0,("cannot open %s %s on originating server %s\n",
169 is_file?"file":"dir", src_name, cli_errstr(cli_share_src)));
170 nt_status = cli_nt_error(cli_share_src);
171 goto out;
172 }
173
174
175 if (copy_acls) {
176
177 /* get the security descriptor */
178 sd = cli_query_secdesc(cli_share_src, fnum_src, mem_ctx);
179 if (!sd) {
180 DEBUG(0,("failed to get security descriptor: %s\n",
181 cli_errstr(cli_share_src)));
182 nt_status = cli_nt_error(cli_share_src);
183 goto out;
184 }
185
186 if (c->opt_verbose && DEBUGLEVEL >= 3)
187 display_sec_desc(sd);
188 }
189
190
191 if (copy_attrs || copy_timestamps) {
192
193 /* get file attributes */
194 if (!cli_getattrE(cli_share_src, fnum_src, &attr, NULL,
195 &f_ctime, &f_atime, &f_mtime)) {
196 DEBUG(0,("failed to get file-attrs: %s\n",
197 cli_errstr(cli_share_src)));
198 nt_status = cli_nt_error(cli_share_src);
199 goto out;
200 }
201 }
202
203
204 /* open the file/dir on the destination server */
205
206 fnum_dst = cli_nt_create(cli_share_dst, dst_name, WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS);
207 if (fnum_dst == -1) {
208 DEBUG(0,("failed to open %s on the destination server: %s: %s\n",
209 is_file?"file":"dir", dst_name, cli_errstr(cli_share_dst)));
210 nt_status = cli_nt_error(cli_share_dst);
211 goto out;
212 }
213
214 if (copy_timestamps) {
215
216 /* set timestamps */
217 if (!cli_setattrE(cli_share_dst, fnum_dst, f_ctime, f_atime, f_mtime)) {
218 DEBUG(0,("failed to set file-attrs (timestamps): %s\n",
219 cli_errstr(cli_share_dst)));
220 nt_status = cli_nt_error(cli_share_dst);
221 goto out;
222 }
223 }
224
225 if (copy_acls) {
226
227 /* set acls */
228 if (!cli_set_secdesc(cli_share_dst, fnum_dst, sd)) {
229 DEBUG(0,("could not set secdesc on %s: %s\n",
230 dst_name, cli_errstr(cli_share_dst)));
231 nt_status = cli_nt_error(cli_share_dst);
232 goto out;
233 }
234 }
235
236 if (copy_attrs) {
237
238 /* set attrs */
239 if (!cli_setatr(cli_share_dst, dst_name, attr, 0)) {
240 DEBUG(0,("failed to set file-attrs: %s\n",
241 cli_errstr(cli_share_dst)));
242 nt_status = cli_nt_error(cli_share_dst);
243 goto out;
244 }
245 }
246
247
248 /* closing files */
249
250 if (!cli_close(cli_share_src, fnum_src)) {
251 d_fprintf(stderr, "could not close %s on originating server: %s\n",
252 is_file?"file":"dir", cli_errstr(cli_share_src));
253 nt_status = cli_nt_error(cli_share_src);
254 goto out;
255 }
256
257 if (!cli_close(cli_share_dst, fnum_dst)) {
258 d_fprintf(stderr, "could not close %s on destination server: %s\n",
259 is_file?"file":"dir", cli_errstr(cli_share_dst));
260 nt_status = cli_nt_error(cli_share_dst);
261 goto out;
262 }
263
264
265 nt_status = NT_STATUS_OK;
266
267 out:
268
269 /* cleaning up */
270 if (fnum_src)
271 cli_close(cli_share_src, fnum_src);
272
273 if (fnum_dst)
274 cli_close(cli_share_dst, fnum_dst);
275
276 return nt_status;
277 }
278
279 /**
280 * Copy a file or directory from a connected share to another connected share
281 *
282 * @param c A net_context structure
283 * @param mem_ctx A talloc-context
284 * @param cli_share_src A connected cli_state
285 * @param cli_share_dst A connected cli_state
286 * @param src_file The source file-name
287 * @param dst_file The destination file-name
288 * @param copy_acls Whether to copy acls
289 * @param copy_attrs Whether to copy DOS attributes
290 * @param copy_timestamps Whether to preserve timestamps
291 * @param is_file Whether this file is a file or a dir
292 *
293 * @return Normal NTSTATUS return.
294 **/
295
296 NTSTATUS net_copy_file(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
297 TALLOC_CTX *mem_ctx,
298 struct cli_state *cli_share_src,
299 struct cli_state *cli_share_dst,
300 const char *src_name, const char *dst_name,
301 bool copy_acls, bool copy_attrs,
302 bool copy_timestamps, bool is_file)
303 {
304 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
305 int fnum_src = 0;
306 int fnum_dst = 0;
307 static int io_bufsize = 64512;
308 int read_size = io_bufsize;
309 char *data = NULL;
310 off_t nread = 0;
311
312
313 if (!src_name || !dst_name)
314 goto out;
315
316 if (cli_share_src == NULL || cli_share_dst == NULL)
317 goto out;
318
319 /* open on the originating server */
320 DEBUGADD(3,("opening %s %s on originating server\n",
321 is_file ? "file":"dir", src_name));
322 if (is_file)
323 fnum_src = cli_open(cli_share_src, src_name, O_RDONLY, DENY_NONE);
324 else
325 fnum_src = cli_nt_create(cli_share_src, src_name, READ_CONTROL_ACCESS);
326
327 if (fnum_src == -1) {
328 DEBUGADD(0,("cannot open %s %s on originating server %s\n",
329 is_file ? "file":"dir",
330 src_name, cli_errstr(cli_share_src)));
331 nt_status = cli_nt_error(cli_share_src);
332 goto out;
333 }
334
335
336 if (is_file) {
337
338 /* open file on the destination server */
339 DEBUGADD(3,("opening file %s on destination server\n", dst_name));
340 fnum_dst = cli_open(cli_share_dst, dst_name,
341 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
342
343 if (fnum_dst == -1) {
344 DEBUGADD(1,("cannot create file %s on destination server: %s\n",
345 dst_name, cli_errstr(cli_share_dst)));
346 nt_status = cli_nt_error(cli_share_dst);
347 goto out;
348 }
349
350 /* allocate memory */
351 if (!(data = (char *)SMB_MALLOC(read_size))) {
352 d_fprintf(stderr, "malloc fail for size %d\n", read_size);
353 nt_status = NT_STATUS_NO_MEMORY;
354 goto out;
355 }
356
357 }
358
359
360 if (c->opt_verbose) {
361
362 d_printf("copying [\\\\%s\\%s%s] => [\\\\%s\\%s%s] "
363 "%s ACLs and %s DOS Attributes %s\n",
364 cli_share_src->desthost, cli_share_src->share, src_name,
365 cli_share_dst->desthost, cli_share_dst->share, dst_name,
366 copy_acls ? "with" : "without",
367 copy_attrs ? "with" : "without",
368 copy_timestamps ? "(preserving timestamps)" : "" );
369 }
370
371
372 while (is_file) {
373
374 /* copying file */
375 int n, ret;
376 n = cli_read(cli_share_src, fnum_src, data, nread,
377 read_size);
378
379 if (n <= 0)
380 break;
381
382 ret = cli_write(cli_share_dst, fnum_dst, 0, data,
383 nread, n);
384
385 if (n != ret) {
386 d_fprintf(stderr, "Error writing file: %s\n",
387 cli_errstr(cli_share_dst));
388 nt_status = cli_nt_error(cli_share_dst);
389 goto out;
390 }
391
392 nread += n;
393 }
394
395
396 if (!is_file && !cli_chkpath(cli_share_dst, dst_name)) {
397
398 /* creating dir */
399 DEBUGADD(3,("creating dir %s on the destination server\n",
400 dst_name));
401
402 if (!cli_mkdir(cli_share_dst, dst_name)) {
403 DEBUG(0,("cannot create directory %s: %s\n",
404 dst_name, cli_errstr(cli_share_dst)));
405 nt_status = NT_STATUS_NO_SUCH_FILE;
406 }
407
408 if (!cli_chkpath(cli_share_dst, dst_name)) {
409 d_fprintf(stderr, "cannot check for directory %s: %s\n",
410 dst_name, cli_errstr(cli_share_dst));
411 goto out;
412 }
413 }
414
415
416 /* closing files */
417 if (!cli_close(cli_share_src, fnum_src)) {
418 d_fprintf(stderr, "could not close file on originating server: %s\n",
419 cli_errstr(cli_share_src));
420 nt_status = cli_nt_error(cli_share_src);
421 goto out;
422 }
423
424 if (is_file && !cli_close(cli_share_dst, fnum_dst)) {
425 d_fprintf(stderr, "could not close file on destination server: %s\n",
426 cli_errstr(cli_share_dst));
427 nt_status = cli_nt_error(cli_share_dst);
428 goto out;
429 }
430
431 /* possibly we have to copy some file-attributes / acls / sd */
432 nt_status = net_copy_fileattr(c, mem_ctx, cli_share_src, cli_share_dst,
433 src_name, dst_name, copy_acls,
434 copy_attrs, copy_timestamps, is_file);
435 if (!NT_STATUS_IS_OK(nt_status))
436 goto out;
437
438
439 nt_status = NT_STATUS_OK;
440
441 out:
442
443 /* cleaning up */
444 if (fnum_src)
445 cli_close(cli_share_src, fnum_src);
446
447 if (fnum_dst)
448 cli_close(cli_share_dst, fnum_dst);
449
450 SAFE_FREE(data);
451
452 return nt_status;
453 }
454
455 /**
456 * Copy a driverfile from on connected share to another connected share
457 * This silently assumes that a driver-file is picked up from
458 *
459 * \\src_server\print$\{arch}\{version}\file
460 *
461 * and copied to
462 *
463 * \\dst_server\print$\{arch}\file
464 *
465 * to be added via setdriver-calls later.
466 * @param c A net_context structure
467 * @param mem_ctx A talloc-context
468 * @param cli_share_src A cli_state connected to source print$-share
469 * @param cli_share_dst A cli_state connected to destination print$-share
470 * @param file The file-name to be copied
471 * @param short_archi The name of the driver-architecture (short form)
472 *
473 * @return Normal NTSTATUS return.
474 **/
475
476 static NTSTATUS net_copy_driverfile(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
477 TALLOC_CTX *mem_ctx,
478 struct cli_state *cli_share_src,
479 struct cli_state *cli_share_dst,
480 const char *file, const char *short_archi) {
481
482 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
483 const char *p;
484 char *src_name;
485 char *dst_name;
486 char *version;
487 char *filename;
488 char *tok;
489
490 if (!file) {
491 return NT_STATUS_OK;
492 }
493
494 /* scroll through the file until we have the part
495 beyond archi_table.short_archi */
496 p = file;
497 while (next_token_talloc(mem_ctx, &p, &tok, "\\")) {
498 if (strequal(tok, short_archi)) {
499 next_token_talloc(mem_ctx, &p, &version, "\\");
500 next_token_talloc(mem_ctx, &p, &filename, "\\");
501 }
502 }
503
504 /* build source file name */
505 if (asprintf(&src_name, "\\%s\\%s\\%s", short_archi, version, filename) < 0 )
506 return NT_STATUS_NO_MEMORY;
507
508
509 /* create destination file name */
510 if (asprintf(&dst_name, "\\%s\\%s", short_archi, filename) < 0 )
511 return NT_STATUS_NO_MEMORY;
512
513
514 /* finally copy the file */
515 nt_status = net_copy_file(c, mem_ctx, cli_share_src, cli_share_dst,
516 src_name, dst_name, false, false, false, true);
517 if (!NT_STATUS_IS_OK(nt_status))
518 goto out;
519
520 nt_status = NT_STATUS_OK;
521
522 out:
523 SAFE_FREE(src_name);
524 SAFE_FREE(dst_name);
525
526 return nt_status;
527 }
528
529 /**
530 * Check for existing Architecture directory on a given server
531 *
532 * @param cli_share A cli_state connected to a print$-share
533 * @param short_archi The Architecture for the print-driver
534 *
535 * @return Normal NTSTATUS return.
536 **/
537
538 static NTSTATUS check_arch_dir(struct cli_state *cli_share, const char *short_archi)
/* [<][>][^][v][top][bottom][index][help] */
539 {
540
541 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
542 char *dir;
543
544 if (asprintf(&dir, "\\%s", short_archi) < 0) {
545 return NT_STATUS_NO_MEMORY;
546 }
547
548 DEBUG(10,("creating print-driver dir for architecture: %s\n",
549 short_archi));
550
551 if (!cli_mkdir(cli_share, dir)) {
552 DEBUG(1,("cannot create directory %s: %s\n",
553 dir, cli_errstr(cli_share)));
554 nt_status = NT_STATUS_NO_SUCH_FILE;
555 }
556
557 if (!cli_chkpath(cli_share, dir)) {
558 d_fprintf(stderr, "cannot check %s: %s\n",
559 dir, cli_errstr(cli_share));
560 goto out;
561 }
562
563 nt_status = NT_STATUS_OK;
564
565 out:
566 SAFE_FREE(dir);
567 return nt_status;
568 }
569
570 /**
571 * Copy a print-driver (level 3) from one connected print$-share to another
572 * connected print$-share
573 *
574 * @param c A net_context structure
575 * @param mem_ctx A talloc-context
576 * @param cli_share_src A cli_state connected to a print$-share
577 * @param cli_share_dst A cli_state connected to a print$-share
578 * @param short_archi The Architecture for the print-driver
579 * @param i1 The DRIVER_INFO_3-struct
580 *
581 * @return Normal NTSTATUS return.
582 **/
583
584 static NTSTATUS copy_print_driver_3(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
585 TALLOC_CTX *mem_ctx,
586 struct cli_state *cli_share_src,
587 struct cli_state *cli_share_dst,
588 const char *short_archi,
589 struct spoolss_DriverInfo3 *r)
590 {
591 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
592 int i;
593
594 if (r == NULL) {
595 return nt_status;
596 }
597
598 if (c->opt_verbose)
599 d_printf("copying driver: [%s], for architecture: [%s], version: [%d]\n",
600 r->driver_name, short_archi, r->version);
601
602 nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst,
603 r->driver_path, short_archi);
604 if (!NT_STATUS_IS_OK(nt_status))
605 return nt_status;
606
607 nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst,
608 r->data_file, short_archi);
609 if (!NT_STATUS_IS_OK(nt_status))
610 return nt_status;
611
612 nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst,
613 r->config_file, short_archi);
614 if (!NT_STATUS_IS_OK(nt_status))
615 return nt_status;
616
617 nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst,
618 r->help_file, short_archi);
619 if (!NT_STATUS_IS_OK(nt_status))
620 return nt_status;
621
622 for (i=0; r->dependent_files[i] != NULL; i++) {
623
624 nt_status = net_copy_driverfile(c, mem_ctx,
625 cli_share_src, cli_share_dst,
626 r->dependent_files[i], short_archi);
627 if (!NT_STATUS_IS_OK(nt_status)) {
628 return nt_status;
629 }
630 }
631
632 return NT_STATUS_OK;
633 }
634
635 /**
636 * net_spoolss-functions
637 * =====================
638 *
639 * the net_spoolss-functions aim to simplify spoolss-client-functions
640 * required during the migration-process wrt buffer-sizes, returned
641 * error-codes, etc.
642 *
643 * this greatly reduces the complexitiy of the migrate-functions.
644 *
645 **/
646
647 static bool net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
648 TALLOC_CTX *mem_ctx,
649 char *name,
650 uint32_t flags,
651 uint32_t level,
652 uint32_t *num_printers,
653 union spoolss_PrinterInfo **info)
654 {
655 WERROR result;
656
657 /* enum printers */
658
659 result = rpccli_spoolss_enumprinters(pipe_hnd, mem_ctx,
660 flags,
661 name,
662 level,
663 0,
664 num_printers,
665 info);
666 if (!W_ERROR_IS_OK(result)) {
667 printf("cannot enum printers: %s\n", win_errstr(result));
668 return false;
669 }
670
671 return true;
672 }
673
674 static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
675 TALLOC_CTX *mem_ctx,
676 const char *printername,
677 uint32_t access_required,
678 const char *username,
679 struct policy_handle *hnd)
680 {
681 WERROR result;
682 fstring printername2;
683
684 fstrcpy(printername2, pipe_hnd->srv_name_slash);
685 fstrcat(printername2, "\\");
686 fstrcat(printername2, printername);
687
688 DEBUG(10,("connecting to: %s as %s for %s and access: %x\n",
689 pipe_hnd->srv_name_slash, username, printername2, access_required));
690
691 /* open printer */
692 result = rpccli_spoolss_openprinter_ex(pipe_hnd, mem_ctx,
693 printername2,
694 access_required,
695 hnd);
696
697 /* be more verbose */
698 if (W_ERROR_V(result) == W_ERROR_V(WERR_ACCESS_DENIED)) {
699 d_fprintf(stderr, "no access to printer [%s] on [%s] for user [%s] granted\n",
700 printername2, pipe_hnd->srv_name_slash, username);
701 return false;
702 }
703
704 if (!W_ERROR_IS_OK(result)) {
705 d_fprintf(stderr, "cannot open printer %s on server %s: %s\n",
706 printername2, pipe_hnd->srv_name_slash, win_errstr(result));
707 return false;
708 }
709
710 DEBUG(2,("got printer handle for printer: %s, server: %s\n",
711 printername2, pipe_hnd->srv_name_slash));
712
713 return true;
714 }
715
716 static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
717 TALLOC_CTX *mem_ctx,
718 struct policy_handle *hnd,
719 uint32_t level,
720 union spoolss_PrinterInfo *info)
721 {
722 WERROR result;
723
724 /* getprinter call */
725 result = rpccli_spoolss_getprinter(pipe_hnd, mem_ctx,
726 hnd,
727 level,
728 0, /* offered */
729 info);
730 if (!W_ERROR_IS_OK(result)) {
731 printf("cannot get printer-info: %s\n", win_errstr(result));
732 return false;
733 }
734
735 return true;
736 }
737
738 static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
739 TALLOC_CTX *mem_ctx,
740 struct policy_handle *hnd,
741 uint32_t level,
742 union spoolss_PrinterInfo *info)
743 {
744 WERROR result;
745 NTSTATUS status;
746 struct spoolss_SetPrinterInfoCtr info_ctr;
747 struct spoolss_DevmodeContainer devmode_ctr;
748 struct sec_desc_buf secdesc_ctr;
749
750 ZERO_STRUCT(devmode_ctr);
751 ZERO_STRUCT(secdesc_ctr);
752
753 /* setprinter call */
754
755 info_ctr.level = level;
756 switch (level) {
757 case 0:
758 info_ctr.info.info0 = (struct spoolss_SetPrinterInfo0 *)&info->info0;
759 break;
760 case 1:
761 info_ctr.info.info1 = (struct spoolss_SetPrinterInfo1 *)&info->info1;
762 break;
763 case 2:
764 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info->info2;
765 break;
766 case 3:
767 info_ctr.info.info3 = (struct spoolss_SetPrinterInfo3 *)&info->info3;
768 break;
769 case 4:
770 info_ctr.info.info4 = (struct spoolss_SetPrinterInfo4 *)&info->info4;
771 break;
772 case 5:
773 info_ctr.info.info5 = (struct spoolss_SetPrinterInfo5 *)&info->info5;
774 break;
775 case 6:
776 info_ctr.info.info6 = (struct spoolss_SetPrinterInfo6 *)&info->info6;
777 break;
778 case 7:
779 info_ctr.info.info7 = (struct spoolss_SetPrinterInfo7 *)&info->info7;
780 break;
781 #if 0 /* FIXME GD */
782 case 8:
783 info_ctr.info.info8 = (struct spoolss_SetPrinterInfo8 *)&info->info8;
784 break;
785 case 9:
786 info_ctr.info.info9 = (struct spoolss_SetPrinterInfo9 *)&info->info9;
787 break;
788 #endif
789 default:
790 break; /* FIXME */
791 }
792
793 status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx,
794 hnd,
795 &info_ctr,
796 &devmode_ctr,
797 &secdesc_ctr,
798 0, /* command */
799 &result);
800
801 if (!W_ERROR_IS_OK(result)) {
802 printf("cannot set printer-info: %s\n", win_errstr(result));
803 return false;
804 }
805
806 return true;
807 }
808
809
810 static bool net_spoolss_setprinterdata(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
811 TALLOC_CTX *mem_ctx,
812 struct policy_handle *hnd,
813 const char *value_name,
814 enum winreg_Type type,
815 union spoolss_PrinterData data)
816 {
817 WERROR result;
818 NTSTATUS status;
819
820 /* setprinterdata call */
821 status = rpccli_spoolss_SetPrinterData(pipe_hnd, mem_ctx,
822 hnd,
823 value_name,
824 type,
825 data,
826 0, /* autocalculated */
827 &result);
828
829 if (!W_ERROR_IS_OK(result)) {
830 printf ("unable to set printerdata: %s\n", win_errstr(result));
831 return false;
832 }
833
834 return true;
835 }
836
837
838 static bool net_spoolss_enumprinterkey(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
839 TALLOC_CTX *mem_ctx,
840 struct policy_handle *hnd,
841 const char *keyname,
842 const char ***keylist)
843 {
844 WERROR result;
845
846 /* enumprinterkey call */
847 result = rpccli_spoolss_enumprinterkey(pipe_hnd, mem_ctx, hnd, keyname, keylist, 0);
848
849 if (!W_ERROR_IS_OK(result)) {
850 printf("enumprinterkey failed: %s\n", win_errstr(result));
851 return false;
852 }
853
854 return true;
855 }
856
857 static bool net_spoolss_enumprinterdataex(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
858 TALLOC_CTX *mem_ctx,
859 uint32_t offered,
860 struct policy_handle *hnd,
861 const char *keyname,
862 uint32_t *count,
863 struct spoolss_PrinterEnumValues **info)
864 {
865 WERROR result;
866
867 /* enumprinterdataex call */
868 result = rpccli_spoolss_enumprinterdataex(pipe_hnd, mem_ctx,
869 hnd,
870 keyname,
871 0, /* offered */
872 count,
873 info);
874
875 if (!W_ERROR_IS_OK(result)) {
876 printf("enumprinterdataex failed: %s\n", win_errstr(result));
877 return false;
878 }
879
880 return true;
881 }
882
883
884 static bool net_spoolss_setprinterdataex(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
885 TALLOC_CTX *mem_ctx,
886 struct policy_handle *hnd,
887 const char *keyname,
888 REGISTRY_VALUE *value)
889 {
890 WERROR result;
891 NTSTATUS status;
892
893 /* setprinterdataex call */
894 status = rpccli_spoolss_SetPrinterDataEx(pipe_hnd, mem_ctx,
895 hnd,
896 keyname,
897 value->valuename,
898 value->type,
899 value->data_p,
900 value->size,
901 &result);
902
903 if (!W_ERROR_IS_OK(result)) {
904 printf("could not set printerdataex: %s\n", win_errstr(result));
905 return false;
906 }
907
908 return true;
909 }
910
911 static bool net_spoolss_enumforms(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
912 TALLOC_CTX *mem_ctx,
913 struct policy_handle *hnd,
914 int level,
915 uint32_t *num_forms,
916 union spoolss_FormInfo **forms)
917 {
918 WERROR result;
919
920 /* enumforms call */
921 result = rpccli_spoolss_enumforms(pipe_hnd, mem_ctx,
922 hnd,
923 level,
924 0,
925 num_forms,
926 forms);
927 if (!W_ERROR_IS_OK(result)) {
928 printf("could not enum forms: %s\n", win_errstr(result));
929 return false;
930 }
931
932 return true;
933 }
934
935 static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
936 TALLOC_CTX *mem_ctx,
937 uint32_t level, const char *env,
938 uint32_t *count,
939 union spoolss_DriverInfo **info)
940 {
941 WERROR result;
942
943 /* enumprinterdrivers call */
944 result = rpccli_spoolss_enumprinterdrivers(pipe_hnd, mem_ctx,
945 pipe_hnd->srv_name_slash,
946 env,
947 level,
948 0,
949 count,
950 info);
951 if (!W_ERROR_IS_OK(result)) {
952 printf("cannot enum drivers: %s\n", win_errstr(result));
953 return false;
954 }
955
956 return true;
957 }
958
959 static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
960 TALLOC_CTX *mem_ctx,
961 struct policy_handle *hnd, uint32_t level,
962 const char *env, int version,
963 union spoolss_DriverInfo *info)
964 {
965 WERROR result;
966 uint32_t server_major_version;
967 uint32_t server_minor_version;
968
969 /* getprinterdriver call */
970 result = rpccli_spoolss_getprinterdriver2(pipe_hnd, mem_ctx,
971 hnd,
972 env,
973 level,
974 0,
975 version,
976 2,
977 info,
978 &server_major_version,
979 &server_minor_version);
980 if (!W_ERROR_IS_OK(result)) {
981 DEBUG(1,("cannot get driver (for architecture: %s): %s\n",
982 env, win_errstr(result)));
983 if (W_ERROR_V(result) != W_ERROR_V(WERR_UNKNOWN_PRINTER_DRIVER) &&
984 W_ERROR_V(result) != W_ERROR_V(WERR_INVALID_ENVIRONMENT)) {
985 printf("cannot get driver: %s\n", win_errstr(result));
986 }
987 return false;
988 }
989
990 return true;
991 }
992
993
994 static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
995 TALLOC_CTX *mem_ctx, uint32_t level,
996 union spoolss_DriverInfo *info)
997 {
998 WERROR result;
999 NTSTATUS status;
1000 struct spoolss_AddDriverInfoCtr info_ctr;
1001
1002 info_ctr.level = level;
1003
1004 switch (level) {
1005 case 2:
1006 info_ctr.info.info2 = (struct spoolss_AddDriverInfo2 *)&info->info2;
1007 break;
1008 case 3:
1009 info_ctr.info.info3 = (struct spoolss_AddDriverInfo3 *)&info->info3;
1010 break;
1011 default:
1012 printf("unsupported info level: %d\n", level);
1013 return false;
1014 }
1015
1016 /* addprinterdriver call */
1017 status = rpccli_spoolss_AddPrinterDriver(pipe_hnd, mem_ctx,
1018 pipe_hnd->srv_name_slash,
1019 &info_ctr,
1020 &result);
1021 /* be more verbose */
1022 if (W_ERROR_V(result) == W_ERROR_V(WERR_ACCESS_DENIED)) {
1023 printf("You are not allowed to add drivers\n");
1024 return false;
1025 }
1026 if (!W_ERROR_IS_OK(result)) {
1027 printf("cannot add driver: %s\n", win_errstr(result));
1028 return false;
1029 }
1030
1031 return true;
1032 }
1033
1034 /**
1035 * abstraction function to get uint32_t num_printers and PRINTER_INFO_CTR ctr
1036 * for a single printer or for all printers depending on argc/argv
1037 **/
1038
1039 static bool get_printer_info(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
1040 TALLOC_CTX *mem_ctx,
1041 int level,
1042 int argc,
1043 const char **argv,
1044 uint32_t *num_printers,
1045 union spoolss_PrinterInfo **info_p)
1046 {
1047 struct policy_handle hnd;
1048
1049 /* no arguments given, enumerate all printers */
1050 if (argc == 0) {
1051
1052 if (!net_spoolss_enum_printers(pipe_hnd, mem_ctx, NULL,
1053 PRINTER_ENUM_LOCAL|PRINTER_ENUM_SHARED,
1054 level, num_printers, info_p))
1055 return false;
1056
1057 goto out;
1058 }
1059
1060 /* argument given, get a single printer by name */
1061 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, argv[0],
1062 MAXIMUM_ALLOWED_ACCESS,
1063 pipe_hnd->auth->user_name,
1064 &hnd))
1065 return false;
1066
1067 if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, *info_p)) {
1068 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL);
1069 return false;
1070 }
1071
1072 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL);
1073
1074 *num_printers = 1;
1075
1076 out:
1077 DEBUG(3,("got %d printers\n", *num_printers));
1078
1079 return true;
1080
1081 }
1082
1083 /**
1084 * List print-queues (including local printers that are not shared)
1085 *
1086 * All parameters are provided by the run_rpc_command function, except for
1087 * argc, argv which are passed through.
1088 *
1089 * @param c A net_context structure
1090 * @param domain_sid The domain sid aquired from the remote server
1091 * @param cli A cli_state connected to the server.
1092 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1093 * @param argc Standard main() style argc
1094 * @param argv Standard main() style argv. Initial components are already
1095 * stripped
1096 *
1097 * @return Normal NTSTATUS return.
1098 **/
1099
1100 NTSTATUS rpc_printer_list_internals(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
1101 const DOM_SID *domain_sid,
1102 const char *domain_name,
1103 struct cli_state *cli,
1104 struct rpc_pipe_client *pipe_hnd,
1105 TALLOC_CTX *mem_ctx,
1106 int argc,
1107 const char **argv)
1108 {
1109 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1110 uint32_t i, num_printers;
1111 uint32_t level = 2;
1112 const char *printername, *sharename;
1113 union spoolss_PrinterInfo *info;
1114
1115 printf("listing printers\n");
1116
1117 if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info))
1118 return nt_status;
1119
1120 for (i = 0; i < num_printers; i++) {
1121
1122 /* do some initialization */
1123 printername = info[i].info2.printername;
1124 sharename = info[i].info2.sharename;
1125
1126 if (printername && sharename) {
1127 d_printf("printer %d: %s, shared as: %s\n",
1128 i+1, printername, sharename);
1129 }
1130 }
1131
1132 return NT_STATUS_OK;
1133 }
1134
1135 /**
1136 * List printer-drivers from a server
1137 *
1138 * All parameters are provided by the run_rpc_command function, except for
1139 * argc, argv which are passed through.
1140 *
1141 * @param c A net_context structure
1142 * @param domain_sid The domain sid aquired from the remote server
1143 * @param cli A cli_state connected to the server.
1144 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1145 * @param argc Standard main() style argc
1146 * @param argv Standard main() style argv. Initial components are already
1147 * stripped
1148 *
1149 * @return Normal NTSTATUS return.
1150 **/
1151
1152 NTSTATUS rpc_printer_driver_list_internals(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
1153 const DOM_SID *domain_sid,
1154 const char *domain_name,
1155 struct cli_state *cli,
1156 struct rpc_pipe_client *pipe_hnd,
1157 TALLOC_CTX *mem_ctx,
1158 int argc,
1159 const char **argv)
1160 {
1161 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1162 uint32_t i;
1163 uint32_t level = 3;
1164 union spoolss_DriverInfo *info;
1165 int d;
1166
1167 printf("listing printer-drivers\n");
1168
1169 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1170
1171 uint32_t num_drivers;
1172
1173 /* enum remote drivers */
1174 if (!net_spoolss_enumprinterdrivers(pipe_hnd, mem_ctx, level,
1175 archi_table[i].long_archi,
1176 &num_drivers, &info)) {
1177 nt_status = NT_STATUS_UNSUCCESSFUL;
1178 goto done;
1179 }
1180
1181 if (num_drivers == 0) {
1182 d_printf ("no drivers found on server for architecture: [%s].\n",
1183 archi_table[i].long_archi);
1184 continue;
1185 }
1186
1187 d_printf("got %d printer-drivers for architecture: [%s]\n",
1188 num_drivers, archi_table[i].long_archi);
1189
1190
1191 /* do something for all drivers for architecture */
1192 for (d = 0; d < num_drivers; d++) {
1193 display_print_driver3(&info[d].info3);
1194 }
1195 }
1196
1197 nt_status = NT_STATUS_OK;
1198
1199 done:
1200 return nt_status;
1201
1202 }
1203
1204 /**
1205 * Publish print-queues with args-wrapper
1206 *
1207 * @param cli A cli_state connected to the server.
1208 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1209 * @param argc Standard main() style argc
1210 * @param argv Standard main() style argv. Initial components are already
1211 * stripped
1212 * @param action
1213 *
1214 * @return Normal NTSTATUS return.
1215 **/
1216
1217 static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_hnd,
/* [<][>][^][v][top][bottom][index][help] */
1218 TALLOC_CTX *mem_ctx,
1219 int argc,
1220 const char **argv,
1221 uint32_t action)
1222 {
1223 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1224 uint32_t i, num_printers;
1225 uint32_t level = 7;
1226 const char *printername, *sharename;
1227 union spoolss_PrinterInfo *info_enum;
1228 union spoolss_PrinterInfo info;
1229 struct spoolss_SetPrinterInfoCtr info_ctr;
1230 struct spoolss_DevmodeContainer devmode_ctr;
1231 struct sec_desc_buf secdesc_ctr;
1232 struct policy_handle hnd;
1233 WERROR result;
1234 const char *action_str;
1235
1236 if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum))
1237 return nt_status;
1238
1239 for (i = 0; i < num_printers; i++) {
1240
1241 /* do some initialization */
1242 printername = info_enum[i].info2.printername;
1243 sharename = info_enum[i].info2.sharename;
1244 if (!printername || !sharename) {
1245 goto done;
1246 }
1247
1248 /* open printer handle */
1249 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
1250 PRINTER_ALL_ACCESS, pipe_hnd->auth->user_name, &hnd))
1251 goto done;
1252
1253 /* check for existing dst printer */
1254 if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info))
1255 goto done;
1256
1257 /* check action and set string */
1258 switch (action) {
1259 case DSPRINT_PUBLISH:
1260 action_str = "published";
1261 break;
1262 case DSPRINT_UPDATE:
1263 action_str = "updated";
1264 break;
1265 case DSPRINT_UNPUBLISH:
1266 action_str = "unpublished";
1267 break;
1268 default:
1269 action_str = "unknown action";
1270 printf("unkown action: %d\n", action);
1271 break;
1272 }
1273
1274 info.info7.action = action;
1275 info_ctr.level = 7;
1276 info_ctr.info.info7 = (struct spoolss_SetPrinterInfo7 *)&info.info7;
1277
1278 ZERO_STRUCT(devmode_ctr);
1279 ZERO_STRUCT(secdesc_ctr);
1280
1281 nt_status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx,
1282 &hnd,
1283 &info_ctr,
1284 &devmode_ctr,
1285 &secdesc_ctr,
1286 0, /* command */
1287 &result);
1288
1289 if (!W_ERROR_IS_OK(result) && (W_ERROR_V(result) != W_ERROR_V(WERR_IO_PENDING))) {
1290 printf("cannot set printer-info: %s\n", win_errstr(result));
1291 goto done;
1292 }
1293
1294 printf("successfully %s printer %s in Active Directory\n", action_str, sharename);
1295 }
1296
1297 nt_status = NT_STATUS_OK;
1298
1299 done:
1300 if (is_valid_policy_hnd(&hnd))
1301 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL);
1302
1303 return nt_status;
1304 }
1305
1306 NTSTATUS rpc_printer_publish_publish_internals(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
1307 const DOM_SID *domain_sid,
1308 const char *domain_name,
1309 struct cli_state *cli,
1310 struct rpc_pipe_client *pipe_hnd,
1311 TALLOC_CTX *mem_ctx,
1312 int argc,
1313 const char **argv)
1314 {
1315 return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_PUBLISH);
1316 }
1317
1318 NTSTATUS rpc_printer_publish_unpublish_internals(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
1319 const DOM_SID *domain_sid,
1320 const char *domain_name,
1321 struct cli_state *cli,
1322 struct rpc_pipe_client *pipe_hnd,
1323 TALLOC_CTX *mem_ctx,
1324 int argc,
1325 const char **argv)
1326 {
1327 return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_UNPUBLISH);
1328 }
1329
1330 NTSTATUS rpc_printer_publish_update_internals(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
1331 const DOM_SID *domain_sid,
1332 const char *domain_name,
1333 struct cli_state *cli,
1334 struct rpc_pipe_client *pipe_hnd,
1335 TALLOC_CTX *mem_ctx,
1336 int argc,
1337 const char **argv)
1338 {
1339 return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_UPDATE);
1340 }
1341
1342 /**
1343 * List print-queues w.r.t. their publishing state
1344 *
1345 * All parameters are provided by the run_rpc_command function, except for
1346 * argc, argv which are passed through.
1347 *
1348 * @param c A net_context structure
1349 * @param domain_sid The domain sid aquired from the remote server
1350 * @param cli A cli_state connected to the server.
1351 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1352 * @param argc Standard main() style argc
1353 * @param argv Standard main() style argv. Initial components are already
1354 * stripped
1355 *
1356 * @return Normal NTSTATUS return.
1357 **/
1358
1359 NTSTATUS rpc_printer_publish_list_internals(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
1360 const DOM_SID *domain_sid,
1361 const char *domain_name,
1362 struct cli_state *cli,
1363 struct rpc_pipe_client *pipe_hnd,
1364 TALLOC_CTX *mem_ctx,
1365 int argc,
1366 const char **argv)
1367 {
1368 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1369 uint32_t i, num_printers;
1370 uint32_t level = 7;
1371 const char *printername, *sharename;
1372 union spoolss_PrinterInfo *info_enum;
1373 union spoolss_PrinterInfo info;
1374 struct policy_handle hnd;
1375 int state;
1376
1377 if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum))
1378 return nt_status;
1379
1380 for (i = 0; i < num_printers; i++) {
1381
1382 /* do some initialization */
1383 printername = info_enum[i].info2.printername;
1384 sharename = info_enum[i].info2.sharename;
1385
1386 if (!printername || !sharename) {
1387 goto done;
1388 }
1389
1390 /* open printer handle */
1391 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
1392 PRINTER_ALL_ACCESS, cli->user_name, &hnd))
1393 goto done;
1394
1395 /* check for existing dst printer */
1396 if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info))
1397 goto done;
1398
1399 if (!info.info7.guid) {
1400 goto done;
1401 }
1402 state = info.info7.action;
1403 switch (state) {
1404 case DSPRINT_PUBLISH:
1405 printf("printer [%s] is published", sharename);
1406 if (c->opt_verbose)
1407 printf(", guid: %s", info.info7.guid);
1408 printf("\n");
1409 break;
1410 case DSPRINT_UNPUBLISH:
1411 printf("printer [%s] is unpublished\n", sharename);
1412 break;
1413 case DSPRINT_UPDATE:
1414 printf("printer [%s] is currently updating\n", sharename);
1415 break;
1416 default:
1417 printf("unkown state: %d\n", state);
1418 break;
1419 }
1420 }
1421
1422 nt_status = NT_STATUS_OK;
1423
1424 done:
1425 if (is_valid_policy_hnd(&hnd))
1426 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL);
1427
1428 return nt_status;
1429 }
1430
1431 /**
1432 * Migrate Printer-ACLs from a source server to the destination server
1433 *
1434 * All parameters are provided by the run_rpc_command function, except for
1435 * argc, argv which are passed through.
1436 *
1437 * @param c A net_context structure
1438 * @param domain_sid The domain sid aquired from the remote server
1439 * @param cli A cli_state connected to the server.
1440 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1441 * @param argc Standard main() style argc
1442 * @param argv Standard main() style argv. Initial components are already
1443 * stripped
1444 *
1445 * @return Normal NTSTATUS return.
1446 **/
1447
1448 NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
1449 const DOM_SID *domain_sid,
1450 const char *domain_name,
1451 struct cli_state *cli,
1452 struct rpc_pipe_client *pipe_hnd,
1453 TALLOC_CTX *mem_ctx,
1454 int argc,
1455 const char **argv)
1456 {
1457 /* TODO: what now, info2 or info3 ?
1458 convince jerry that we should add clientside setacls level 3 at least
1459 */
1460 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1461 uint32_t i = 0;
1462 uint32_t num_printers;
1463 uint32_t level = 2;
1464 const char *printername, *sharename;
1465 struct rpc_pipe_client *pipe_hnd_dst = NULL;
1466 struct policy_handle hnd_src, hnd_dst;
1467 union spoolss_PrinterInfo *info_enum;
1468 struct cli_state *cli_dst = NULL;
1469 union spoolss_PrinterInfo info_src, info_dst;
1470
1471 DEBUG(3,("copying printer ACLs\n"));
1472
1473 /* connect destination PI_SPOOLSS */
1474 nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
1475 &ndr_table_spoolss.syntax_id);
1476 if (!NT_STATUS_IS_OK(nt_status))
1477 return nt_status;
1478
1479
1480 /* enum source printers */
1481 if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) {
1482 nt_status = NT_STATUS_UNSUCCESSFUL;
1483 goto done;
1484 }
1485
1486 if (!num_printers) {
1487 printf ("no printers found on server.\n");
1488 nt_status = NT_STATUS_OK;
1489 goto done;
1490 }
1491
1492 /* do something for all printers */
1493 for (i = 0; i < num_printers; i++) {
1494
1495 /* do some initialization */
1496 printername = info_enum[i].info2.printername;
1497 sharename = info_enum[i].info2.sharename;
1498
1499 if (!printername || !sharename) {
1500 nt_status = NT_STATUS_UNSUCCESSFUL;
1501 goto done;
1502 }
1503
1504 /* we can reset NT_STATUS here because we do not
1505 get any real NT_STATUS-codes anymore from now on */
1506 nt_status = NT_STATUS_UNSUCCESSFUL;
1507
1508 d_printf("migrating printer ACLs for: [%s] / [%s]\n",
1509 printername, sharename);
1510
1511 /* according to msdn you have specify these access-rights
1512 to see the security descriptor
1513 - READ_CONTROL (DACL)
1514 - ACCESS_SYSTEM_SECURITY (SACL)
1515 */
1516
1517 /* open src printer handle */
1518 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
1519 MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
1520 goto done;
1521
1522 /* open dst printer handle */
1523 if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
1524 PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst))
1525 goto done;
1526
1527 /* check for existing dst printer */
1528 if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst))
1529 goto done;
1530
1531 /* check for existing src printer */
1532 if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, 3, &info_src))
1533 goto done;
1534
1535 /* Copy Security Descriptor */
1536
1537 /* copy secdesc (info level 2) */
1538 info_dst.info2.devmode = NULL;
1539 info_dst.info2.secdesc = dup_sec_desc(mem_ctx, info_src.info3.secdesc);
1540
1541 if (c->opt_verbose)
1542 display_sec_desc(info_dst.info2.secdesc);
1543
1544 if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst))
1545 goto done;
1546
1547 DEBUGADD(1,("\tSetPrinter of SECDESC succeeded\n"));
1548
1549
1550 /* close printer handles here */
1551 if (is_valid_policy_hnd(&hnd_src)) {
1552 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
1553 }
1554
1555 if (is_valid_policy_hnd(&hnd_dst)) {
1556 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
1557 }
1558
1559 }
1560
1561 nt_status = NT_STATUS_OK;
1562
1563 done:
1564
1565 if (is_valid_policy_hnd(&hnd_src)) {
1566 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
1567 }
1568
1569 if (is_valid_policy_hnd(&hnd_dst)) {
1570 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
1571 }
1572
1573 if (cli_dst) {
1574 cli_shutdown(cli_dst);
1575 }
1576 return nt_status;
1577 }
1578
1579 /**
1580 * Migrate printer-forms from a src server to the dst server
1581 *
1582 * All parameters are provided by the run_rpc_command function, except for
1583 * argc, argv which are passed through.
1584 *
1585 * @param c A net_context structure
1586 * @param domain_sid The domain sid aquired from the remote server
1587 * @param cli A cli_state connected to the server.
1588 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1589 * @param argc Standard main() style argc
1590 * @param argv Standard main() style argv. Initial components are already
1591 * stripped
1592 *
1593 * @return Normal NTSTATUS return.
1594 **/
1595
1596 NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
1597 const DOM_SID *domain_sid,
1598 const char *domain_name,
1599 struct cli_state *cli,
1600 struct rpc_pipe_client *pipe_hnd,
1601 TALLOC_CTX *mem_ctx,
1602 int argc,
1603 const char **argv)
1604 {
1605 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1606 WERROR result;
1607 uint32_t i, f;
1608 uint32_t num_printers;
1609 uint32_t level = 1;
1610 const char *printername, *sharename;
1611 struct rpc_pipe_client *pipe_hnd_dst = NULL;
1612 struct policy_handle hnd_src, hnd_dst;
1613 union spoolss_PrinterInfo *info_enum;
1614 union spoolss_PrinterInfo info_dst;
1615 uint32_t num_forms;
1616 union spoolss_FormInfo *forms;
1617 struct cli_state *cli_dst = NULL;
1618
1619 DEBUG(3,("copying forms\n"));
1620
1621 /* connect destination PI_SPOOLSS */
1622 nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
1623 &ndr_table_spoolss.syntax_id);
1624 if (!NT_STATUS_IS_OK(nt_status))
1625 return nt_status;
1626
1627 /* enum src printers */
1628 if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum)) {
1629 nt_status = NT_STATUS_UNSUCCESSFUL;
1630 goto done;
1631 }
1632
1633 if (!num_printers) {
1634 printf ("no printers found on server.\n");
1635 nt_status = NT_STATUS_OK;
1636 goto done;
1637 }
1638
1639 /* do something for all printers */
1640 for (i = 0; i < num_printers; i++) {
1641
1642 /* do some initialization */
1643 printername = info_enum[i].info2.printername;
1644 sharename = info_enum[i].info2.sharename;
1645
1646 if (!printername || !sharename) {
1647 nt_status = NT_STATUS_UNSUCCESSFUL;
1648 goto done;
1649 }
1650 /* we can reset NT_STATUS here because we do not
1651 get any real NT_STATUS-codes anymore from now on */
1652 nt_status = NT_STATUS_UNSUCCESSFUL;
1653
1654 d_printf("migrating printer forms for: [%s] / [%s]\n",
1655 printername, sharename);
1656
1657
1658 /* open src printer handle */
1659 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
1660 MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
1661 goto done;
1662
1663 /* open dst printer handle */
1664 if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
1665 PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst))
1666 goto done;
1667
1668 /* check for existing dst printer */
1669 if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst))
1670 goto done;
1671
1672 /* finally migrate forms */
1673 if (!net_spoolss_enumforms(pipe_hnd, mem_ctx, &hnd_src, level, &num_forms, &forms))
1674 goto done;
1675
1676 DEBUG(1,("got %d forms for printer\n", num_forms));
1677
1678
1679 for (f = 0; f < num_forms; f++) {
1680
1681 union spoolss_AddFormInfo info;
1682 NTSTATUS status;
1683
1684 /* only migrate FORM_PRINTER types, according to jerry
1685 FORM_BUILTIN-types are hard-coded in samba */
1686 if (forms[f].info1.flags != SPOOLSS_FORM_PRINTER)
1687 continue;
1688
1689 if (c->opt_verbose)
1690 d_printf("\tmigrating form # %d [%s] of type [%d]\n",
1691 f, forms[f].info1.form_name,
1692 forms[f].info1.flags);
1693
1694 info.info1 = (struct spoolss_AddFormInfo1 *)&forms[f].info1;
1695
1696 /* FIXME: there might be something wrong with samba's
1697 builtin-forms */
1698 status = rpccli_spoolss_AddForm(pipe_hnd_dst, mem_ctx,
1699 &hnd_dst,
1700 1,
1701 info,
1702 &result);
1703 if (!W_ERROR_IS_OK(result)) {
1704 d_printf("\tAddForm form %d: [%s] refused.\n",
1705 f, forms[f].info1.form_name);
1706 continue;
1707 }
1708
1709 DEBUGADD(1,("\tAddForm of [%s] succeeded\n",
1710 forms[f].info1.form_name));
1711 }
1712
1713
1714 /* close printer handles here */
1715 if (is_valid_policy_hnd(&hnd_src)) {
1716 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
1717 }
1718
1719 if (is_valid_policy_hnd(&hnd_dst)) {
1720 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
1721 }
1722 }
1723
1724 nt_status = NT_STATUS_OK;
1725
1726 done:
1727
1728 if (is_valid_policy_hnd(&hnd_src))
1729 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
1730
1731 if (is_valid_policy_hnd(&hnd_dst))
1732 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
1733
1734 if (cli_dst) {
1735 cli_shutdown(cli_dst);
1736 }
1737 return nt_status;
1738 }
1739
1740 /**
1741 * Migrate printer-drivers from a src server to the dst server
1742 *
1743 * All parameters are provided by the run_rpc_command function, except for
1744 * argc, argv which are passed through.
1745 *
1746 * @param c A net_context structure
1747 * @param domain_sid The domain sid aquired from the remote server
1748 * @param cli A cli_state connected to the server.
1749 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1750 * @param argc Standard main() style argc
1751 * @param argv Standard main() style argv. Initial components are already
1752 * stripped
1753 *
1754 * @return Normal NTSTATUS return.
1755 **/
1756
1757 NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
1758 const DOM_SID *domain_sid,
1759 const char *domain_name,
1760 struct cli_state *cli,
1761 struct rpc_pipe_client *pipe_hnd,
1762 TALLOC_CTX *mem_ctx,
1763 int argc,
1764 const char **argv)
1765 {
1766 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1767 uint32_t i, p;
1768 uint32_t num_printers;
1769 uint32_t level = 3;
1770 const char *printername, *sharename;
1771 bool got_src_driver_share = false;
1772 bool got_dst_driver_share = false;
1773 struct rpc_pipe_client *pipe_hnd_dst = NULL;
1774 struct policy_handle hnd_src, hnd_dst;
1775 union spoolss_DriverInfo drv_info_src;
1776 union spoolss_PrinterInfo *info_enum;
1777 union spoolss_PrinterInfo info_dst;
1778 struct cli_state *cli_dst = NULL;
1779 struct cli_state *cli_share_src = NULL;
1780 struct cli_state *cli_share_dst = NULL;
1781 const char *drivername = NULL;
1782
1783 DEBUG(3,("copying printer-drivers\n"));
1784
1785 nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
1786 &ndr_table_spoolss.syntax_id);
1787 if (!NT_STATUS_IS_OK(nt_status))
1788 return nt_status;
1789
1790 /* open print$-share on the src server */
1791 nt_status = connect_to_service(c, &cli_share_src, &cli->dest_ss,
1792 cli->desthost, "print$", "A:");
1793 if (!NT_STATUS_IS_OK(nt_status))
1794 goto done;
1795
1796 got_src_driver_share = true;
1797
1798
1799 /* open print$-share on the dst server */
1800 nt_status = connect_to_service(c, &cli_share_dst, &cli_dst->dest_ss,
1801 cli_dst->desthost, "print$", "A:");
1802 if (!NT_STATUS_IS_OK(nt_status))
1803 return nt_status;
1804
1805 got_dst_driver_share = true;
1806
1807
1808 /* enum src printers */
1809 if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum)) {
1810 nt_status = NT_STATUS_UNSUCCESSFUL;
1811 goto done;
1812 }
1813
1814 if (num_printers == 0) {
1815 printf ("no printers found on server.\n");
1816 nt_status = NT_STATUS_OK;
1817 goto done;
1818 }
1819
1820
1821 /* do something for all printers */
1822 for (p = 0; p < num_printers; p++) {
1823
1824 /* do some initialization */
1825 printername = info_enum[p].info2.printername;
1826 sharename = info_enum[p].info2.sharename;
1827
1828 if (!printername || !sharename) {
1829 nt_status = NT_STATUS_UNSUCCESSFUL;
1830 goto done;
1831 }
1832
1833 /* we can reset NT_STATUS here because we do not
1834 get any real NT_STATUS-codes anymore from now on */
1835 nt_status = NT_STATUS_UNSUCCESSFUL;
1836
1837 d_printf("migrating printer driver for: [%s] / [%s]\n",
1838 printername, sharename);
1839
1840 /* open dst printer handle */
1841 if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
1842 PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst))
1843 goto done;
1844
1845 /* check for existing dst printer */
1846 if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst))
1847 goto done;
1848
1849
1850 /* open src printer handle */
1851 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
1852 MAXIMUM_ALLOWED_ACCESS,
1853 pipe_hnd->auth->user_name,
1854 &hnd_src))
1855 goto done;
1856
1857 /* in a first step call getdriver for each shared printer (per arch)
1858 to get a list of all files that have to be copied */
1859
1860 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1861
1862 /* getdriver src */
1863 if (!net_spoolss_getprinterdriver(pipe_hnd, mem_ctx, &hnd_src,
1864 level, archi_table[i].long_archi,
1865 archi_table[i].version, &drv_info_src))
1866 continue;
1867
1868 drivername = drv_info_src.info3.driver_name;
1869
1870 if (c->opt_verbose)
1871 display_print_driver3(&drv_info_src.info3);
1872
1873 /* check arch dir */
1874 nt_status = check_arch_dir(cli_share_dst, archi_table[i].short_archi);
1875 if (!NT_STATUS_IS_OK(nt_status))
1876 goto done;
1877
1878
1879 /* copy driver-files */
1880 nt_status = copy_print_driver_3(c, mem_ctx, cli_share_src, cli_share_dst,
1881 archi_table[i].short_archi,
1882 &drv_info_src.info3);
1883 if (!NT_STATUS_IS_OK(nt_status))
1884 goto done;
1885
1886
1887 /* adddriver dst */
1888 if (!net_spoolss_addprinterdriver(pipe_hnd_dst, mem_ctx, level, &drv_info_src)) {
1889 nt_status = NT_STATUS_UNSUCCESSFUL;
1890 goto done;
1891 }
1892
1893 DEBUGADD(1,("Sucessfully added driver [%s] for printer [%s]\n",
1894 drivername, printername));
1895
1896 }
1897
1898 if (!drivername || strlen(drivername) == 0) {
1899 DEBUGADD(1,("Did not get driver for printer %s\n",
1900 printername));
1901 goto done;
1902 }
1903
1904 /* setdriver dst */
1905 info_dst.info2.drivername = drivername;
1906
1907 if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) {
1908 nt_status = NT_STATUS_UNSUCCESSFUL;
1909 goto done;
1910 }
1911
1912 DEBUGADD(1,("Sucessfully set driver %s for printer %s\n",
1913 drivername, printername));
1914
1915 /* close dst */
1916 if (is_valid_policy_hnd(&hnd_dst)) {
1917 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
1918 }
1919
1920 /* close src */
1921 if (is_valid_policy_hnd(&hnd_src)) {
1922 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
1923 }
1924 }
1925
1926 nt_status = NT_STATUS_OK;
1927
1928 done:
1929
1930 if (is_valid_policy_hnd(&hnd_src))
1931 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
1932
1933 if (is_valid_policy_hnd(&hnd_dst))
1934 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
1935
1936 if (cli_dst) {
1937 cli_shutdown(cli_dst);
1938 }
1939
1940 if (got_src_driver_share)
1941 cli_shutdown(cli_share_src);
1942
1943 if (got_dst_driver_share)
1944 cli_shutdown(cli_share_dst);
1945
1946 return nt_status;
1947
1948 }
1949
1950 /**
1951 * Migrate printer-queues from a src to the dst server
1952 * (requires a working "addprinter command" to be installed for the local smbd)
1953 *
1954 * All parameters are provided by the run_rpc_command function, except for
1955 * argc, argv which are passed through.
1956 *
1957 * @param c A net_context structure
1958 * @param domain_sid The domain sid aquired from the remote server
1959 * @param cli A cli_state connected to the server.
1960 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1961 * @param argc Standard main() style argc
1962 * @param argv Standard main() style argv. Initial components are already
1963 * stripped
1964 *
1965 * @return Normal NTSTATUS return.
1966 **/
1967
1968 NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
1969 const DOM_SID *domain_sid,
1970 const char *domain_name,
1971 struct cli_state *cli,
1972 struct rpc_pipe_client *pipe_hnd,
1973 TALLOC_CTX *mem_ctx,
1974 int argc,
1975 const char **argv)
1976 {
1977 WERROR result;
1978 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1979 uint32_t i = 0, num_printers;
1980 uint32_t level = 2;
1981 union spoolss_PrinterInfo info_dst, info_src;
1982 union spoolss_PrinterInfo *info_enum;
1983 struct cli_state *cli_dst = NULL;
1984 struct policy_handle hnd_dst, hnd_src;
1985 const char *printername, *sharename;
1986 struct rpc_pipe_client *pipe_hnd_dst = NULL;
1987 struct spoolss_SetPrinterInfoCtr info_ctr;
1988
1989 DEBUG(3,("copying printers\n"));
1990
1991 /* connect destination PI_SPOOLSS */
1992 nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
1993 &ndr_table_spoolss.syntax_id);
1994 if (!NT_STATUS_IS_OK(nt_status))
1995 return nt_status;
1996
1997 /* enum printers */
1998 if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) {
1999 nt_status = NT_STATUS_UNSUCCESSFUL;
2000 goto done;
2001 }
2002
2003 if (!num_printers) {
2004 printf ("no printers found on server.\n");
2005 nt_status = NT_STATUS_OK;
2006 goto done;
2007 }
2008
2009 /* do something for all printers */
2010 for (i = 0; i < num_printers; i++) {
2011
2012 /* do some initialization */
2013 printername = info_enum[i].info2.printername;
2014 sharename = info_enum[i].info2.sharename;
2015
2016 if (!printername || !sharename) {
2017 nt_status = NT_STATUS_UNSUCCESSFUL;
2018 goto done;
2019 }
2020 /* we can reset NT_STATUS here because we do not
2021 get any real NT_STATUS-codes anymore from now on */
2022 nt_status = NT_STATUS_UNSUCCESSFUL;
2023
2024 d_printf("migrating printer queue for: [%s] / [%s]\n",
2025 printername, sharename);
2026
2027 /* open dst printer handle */
2028 if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
2029 PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) {
2030
2031 DEBUG(1,("could not open printer: %s\n", sharename));
2032 }
2033
2034 /* check for existing dst printer */
2035 if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) {
2036 printf ("could not get printer, creating printer.\n");
2037 } else {
2038 DEBUG(1,("printer already exists: %s\n", sharename));
2039 /* close printer handle here - dst only, not got src yet. */
2040 if (is_valid_policy_hnd(&hnd_dst)) {
2041 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
2042 }
2043 continue;
2044 }
2045
2046 /* now get again src printer ctr via getprinter,
2047 we first need a handle for that */
2048
2049 /* open src printer handle */
2050 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
2051 MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
2052 goto done;
2053
2054 /* getprinter on the src server */
2055 if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &info_src))
2056 goto done;
2057
2058 /* copy each src printer to a dst printer 1:1,
2059 maybe some values have to be changed though */
2060 d_printf("creating printer: %s\n", printername);
2061
2062 info_ctr.level = level;
2063 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info_src.info2;
2064
2065 result = rpccli_spoolss_addprinterex(pipe_hnd_dst,
2066 mem_ctx,
2067 &info_ctr);
2068
2069 if (W_ERROR_IS_OK(result))
2070 d_printf ("printer [%s] successfully added.\n", printername);
2071 else if (W_ERROR_V(result) == W_ERROR_V(WERR_PRINTER_ALREADY_EXISTS))
2072 d_fprintf (stderr, "printer [%s] already exists.\n", printername);
2073 else {
2074 d_fprintf (stderr, "could not create printer [%s]\n", printername);
2075 goto done;
2076 }
2077
2078 /* close printer handles here */
2079 if (is_valid_policy_hnd(&hnd_src)) {
2080 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
2081 }
2082
2083 if (is_valid_policy_hnd(&hnd_dst)) {
2084 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
2085 }
2086 }
2087
2088 nt_status = NT_STATUS_OK;
2089
2090 done:
2091 if (is_valid_policy_hnd(&hnd_src))
2092 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
2093
2094 if (is_valid_policy_hnd(&hnd_dst))
2095 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
2096
2097 if (cli_dst) {
2098 cli_shutdown(cli_dst);
2099 }
2100 return nt_status;
2101 }
2102
2103 /**
2104 * Migrate Printer-Settings from a src server to the dst server
2105 * (for this to work, printers and drivers already have to be migrated earlier)
2106 *
2107 * All parameters are provided by the run_rpc_command function, except for
2108 * argc, argv which are passed through.
2109 *
2110 * @param c A net_context structure
2111 * @param domain_sid The domain sid aquired from the remote server
2112 * @param cli A cli_state connected to the server.
2113 * @param mem_ctx Talloc context, destoyed on compleation of the function.
2114 * @param argc Standard main() style argc
2115 * @param argv Standard main() style argv. Initial components are already
2116 * stripped
2117 *
2118 * @return Normal NTSTATUS return.
2119 **/
2120
2121 NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
/* [<][>][^][v][top][bottom][index][help] */
2122 const DOM_SID *domain_sid,
2123 const char *domain_name,
2124 struct cli_state *cli,
2125 struct rpc_pipe_client *pipe_hnd,
2126 TALLOC_CTX *mem_ctx,
2127 int argc,
2128 const char **argv)
2129 {
2130
2131 /* FIXME: Here the nightmare begins */
2132
2133 WERROR result;
2134 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
2135 uint32_t i = 0, p = 0, j = 0;
2136 uint32_t num_printers;
2137 uint32_t level = 2;
2138 const char *printername, *sharename;
2139 struct rpc_pipe_client *pipe_hnd_dst = NULL;
2140 struct policy_handle hnd_src, hnd_dst;
2141 union spoolss_PrinterInfo *info_enum;
2142 union spoolss_PrinterInfo info_dst_publish;
2143 union spoolss_PrinterInfo info_dst;
2144 struct cli_state *cli_dst = NULL;
2145 char *devicename = NULL, *unc_name = NULL, *url = NULL;
2146 const char *longname;
2147 const char **keylist = NULL;
2148
2149 /* FIXME GD */
2150 ZERO_STRUCT(info_dst_publish);
2151
2152 DEBUG(3,("copying printer settings\n"));
2153
2154 /* connect destination PI_SPOOLSS */
2155 nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
2156 &ndr_table_spoolss.syntax_id);
2157 if (!NT_STATUS_IS_OK(nt_status))
2158 return nt_status;
2159
2160 /* enum src printers */
2161 if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) {
2162 nt_status = NT_STATUS_UNSUCCESSFUL;
2163 goto done;
2164 }
2165
2166 if (!num_printers) {
2167 printf ("no printers found on server.\n");
2168 nt_status = NT_STATUS_OK;
2169 goto done;
2170 }
2171
2172
2173 /* needed for dns-strings in regkeys */
2174 longname = get_mydnsfullname();
2175 if (!longname) {
2176 nt_status = NT_STATUS_UNSUCCESSFUL;
2177 goto done;
2178 }
2179
2180 /* do something for all printers */
2181 for (i = 0; i < num_printers; i++) {
2182
2183 uint32_t value_offered = 0, value_needed;
2184 uint32_t data_offered = 0, data_needed;
2185 enum winreg_Type type;
2186 uint8_t *buffer = NULL;
2187 const char *value_name = NULL;
2188
2189 /* do some initialization */
2190 printername = info_enum[i].info2.printername;
2191 sharename = info_enum[i].info2.sharename;
2192
2193 if (!printername || !sharename) {
2194 nt_status = NT_STATUS_UNSUCCESSFUL;
2195 goto done;
2196 }
2197 /* we can reset NT_STATUS here because we do not
2198 get any real NT_STATUS-codes anymore from now on */
2199 nt_status = NT_STATUS_UNSUCCESSFUL;
2200
2201 d_printf("migrating printer settings for: [%s] / [%s]\n",
2202 printername, sharename);
2203
2204
2205 /* open src printer handle */
2206 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
2207 MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
2208 goto done;
2209
2210 /* open dst printer handle */
2211 if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
2212 PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst))
2213 goto done;
2214
2215 /* check for existing dst printer */
2216 if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst,
2217 level, &info_dst))
2218 goto done;
2219
2220
2221 /* STEP 1: COPY DEVICE-MODE and other
2222 PRINTER_INFO_2-attributes
2223 */
2224
2225 info_dst.info2 = info_enum[i].info2;
2226
2227 /* why is the port always disconnected when the printer
2228 is correctly installed (incl. driver ???) */
2229 info_dst.info2.portname = SAMBA_PRINTER_PORT_NAME;
2230
2231 /* check if printer is published */
2232 if (info_enum[i].info2.attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
2233
2234 /* check for existing dst printer */
2235 if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish))
2236 goto done;
2237
2238 info_dst_publish.info7.action = DSPRINT_PUBLISH;
2239
2240 /* ignore false from setprinter due to WERR_IO_PENDING */
2241 net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish);
2242
2243 DEBUG(3,("republished printer\n"));
2244 }
2245
2246 if (info_enum[i].info2.devmode != NULL) {
2247
2248 /* copy devmode (info level 2) */
2249 info_dst.info2.devmode = info_enum[i].info2.devmode;
2250
2251 /* do not copy security descriptor (we have another
2252 * command for that) */
2253 info_dst.info2.secdesc = NULL;
2254
2255 #if 0
2256 info_dst.info2.devmode.devicename =
2257 talloc_asprintf(mem_ctx, "\\\\%s\\%s",
2258 longname, printername);
2259 if (!info_dst.info2.devmode.devicename) {
2260 nt_status = NT_STATUS_NO_MEMORY;
2261 goto done;
2262 }
2263 #endif
2264 if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst,
2265 level, &info_dst))
2266 goto done;
2267
2268 DEBUGADD(1,("\tSetPrinter of DEVICEMODE succeeded\n"));
2269 }
2270
2271 /* STEP 2: COPY REGISTRY VALUES */
2272
2273 /* please keep in mind that samba parse_spools gives horribly
2274 crippled results when used to rpccli_spoolss_enumprinterdataex
2275 a win2k3-server. (Bugzilla #1851)
2276 FIXME: IIRC I've seen it too on a win2k-server
2277 */
2278
2279 /* enumerate data on src handle */
2280 nt_status = rpccli_spoolss_EnumPrinterData(pipe_hnd, mem_ctx,
2281 &hnd_src,
2282 p,
2283 value_name,
2284 value_offered,
2285 &value_needed,
2286 &type,
2287 buffer,
2288 data_offered,
2289 &data_needed,
2290 &result);
2291
2292 data_offered = data_needed;
2293 value_offered = value_needed;
2294 buffer = talloc_zero_array(mem_ctx, uint8_t, data_needed);
2295 value_name = talloc_zero_array(mem_ctx, char, value_needed);
2296
2297 /* loop for all printerdata of "PrinterDriverData" */
2298 while (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(result)) {
2299
2300 nt_status = rpccli_spoolss_EnumPrinterData(pipe_hnd, mem_ctx,
2301 &hnd_src,
2302 p++,
2303 value_name,
2304 value_offered,
2305 &value_needed,
2306 &type,
2307 buffer,
2308 data_offered,
2309 &data_needed,
2310 &result);
2311 /* loop for all reg_keys */
2312 if (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(result)) {
2313
2314 REGISTRY_VALUE v;
2315 DATA_BLOB blob;
2316 union spoolss_PrinterData printer_data;
2317
2318 /* display_value */
2319 if (c->opt_verbose) {
2320 fstrcpy(v.valuename, value_name);
2321 v.type = type;
2322 v.size = data_offered;
2323 v.data_p = buffer;
2324 display_reg_value(SPOOL_PRINTERDATA_KEY, v);
2325 }
2326
2327 result = pull_spoolss_PrinterData(mem_ctx,
2328 &blob,
2329 &printer_data,
2330 type);
2331 if (!W_ERROR_IS_OK(result)) {
2332 goto done;
2333 }
2334
2335 /* set_value */
2336 if (!net_spoolss_setprinterdata(pipe_hnd_dst, mem_ctx,
2337 &hnd_dst, value_name,
2338 type, printer_data))
2339 goto done;
2340
2341 DEBUGADD(1,("\tSetPrinterData of [%s] succeeded\n",
2342 v.valuename));
2343 }
2344 }
2345
2346 /* STEP 3: COPY SUBKEY VALUES */
2347
2348 /* here we need to enum all printer_keys and then work
2349 on the result with enum_printer_key_ex. nt4 does not
2350 respond to enumprinterkey, win2k does, so continue
2351 in case of an error */
2352
2353 if (!net_spoolss_enumprinterkey(pipe_hnd, mem_ctx, &hnd_src, "", &keylist)) {
2354 printf("got no key-data\n");
2355 continue;
2356 }
2357
2358
2359 /* work on a list of printer keys
2360 each key has to be enumerated to get all required
2361 information. information is then set via setprinterdataex-calls */
2362
2363 if (keylist == NULL)
2364 continue;
2365
2366 for (i=0; keylist && keylist[i] != NULL; i++) {
2367
2368 const char *subkey = keylist[i];
2369 uint32_t count;
2370 struct spoolss_PrinterEnumValues *info;
2371
2372 /* enumerate all src subkeys */
2373 if (!net_spoolss_enumprinterdataex(pipe_hnd, mem_ctx, 0,
2374 &hnd_src, subkey,
2375 &count, &info)) {
2376 goto done;
2377 }
2378
2379 for (j=0; j < count; j++) {
2380
2381 REGISTRY_VALUE value;
2382 UNISTR2 data;
2383
2384 /* although samba replies with sane data in most cases we
2385 should try to avoid writing wrong registry data */
2386
2387 if (strequal(info[j].value_name, SPOOL_REG_PORTNAME) ||
2388 strequal(info[j].value_name, SPOOL_REG_UNCNAME) ||
2389 strequal(info[j].value_name, SPOOL_REG_URL) ||
2390 strequal(info[j].value_name, SPOOL_REG_SHORTSERVERNAME) ||
2391 strequal(info[j].value_name, SPOOL_REG_SERVERNAME)) {
2392
2393 if (strequal(info[j].value_name, SPOOL_REG_PORTNAME)) {
2394
2395 /* although windows uses a multi-sz, we use a sz */
2396 init_unistr2(&data, SAMBA_PRINTER_PORT_NAME, UNI_STR_TERMINATE);
2397 fstrcpy(value.valuename, SPOOL_REG_PORTNAME);
2398 }
2399
2400 if (strequal(info[j].value_name, SPOOL_REG_UNCNAME)) {
2401
2402 if (asprintf(&unc_name, "\\\\%s\\%s", longname, sharename) < 0) {
2403 nt_status = NT_STATUS_NO_MEMORY;
2404 goto done;
2405 }
2406 init_unistr2(&data, unc_name, UNI_STR_TERMINATE);
2407 fstrcpy(value.valuename, SPOOL_REG_UNCNAME);
2408 }
2409
2410 if (strequal(info[j].value_name, SPOOL_REG_URL)) {
2411
2412 continue;
2413
2414 #if 0
2415 /* FIXME: should we really do that ??? */
2416 if (asprintf(&url, "http://%s:631/printers/%s", longname, sharename) < 0) {
2417 nt_status = NT_STATUS_NO_MEMORY;
2418 goto done;
2419 }
2420 init_unistr2(&data, url, UNI_STR_TERMINATE);
2421 fstrcpy(value.valuename, SPOOL_REG_URL);
2422 #endif
2423 }
2424
2425 if (strequal(info[j].value_name, SPOOL_REG_SERVERNAME)) {
2426
2427 init_unistr2(&data, longname, UNI_STR_TERMINATE);
2428 fstrcpy(value.valuename, SPOOL_REG_SERVERNAME);
2429 }
2430
2431 if (strequal(info[j].value_name, SPOOL_REG_SHORTSERVERNAME)) {
2432
2433 init_unistr2(&data, global_myname(), UNI_STR_TERMINATE);
2434 fstrcpy(value.valuename, SPOOL_REG_SHORTSERVERNAME);
2435 }
2436
2437 value.type = REG_SZ;
2438 value.size = data.uni_str_len * 2;
2439 if (value.size) {
2440 value.data_p = (uint8_t *)TALLOC_MEMDUP(mem_ctx, data.buffer, value.size);
2441 } else {
2442 value.data_p = NULL;
2443 }
2444
2445 if (c->opt_verbose)
2446 display_reg_value(subkey, value);
2447
2448 /* here we have to set all subkeys on the dst server */
2449 if (!net_spoolss_setprinterdataex(pipe_hnd_dst, mem_ctx, &hnd_dst,
2450 subkey, &value))
2451 goto done;
2452
2453 } else {
2454
2455 REGISTRY_VALUE v;
2456 DATA_BLOB blob;
2457
2458 result = push_spoolss_PrinterData(mem_ctx, &blob,
2459 info[j].type,
2460 info[j].data);
2461 if (!W_ERROR_IS_OK(result)) {
2462 goto done;
2463 }
2464
2465 fstrcpy(v.valuename, info[j].value_name);
2466 v.type = info[j].type;
2467 v.data_p = blob.data;
2468 v.size = blob.length;
2469
2470 if (c->opt_verbose) {
2471 display_reg_value(subkey, v);
2472 }
2473
2474 /* here we have to set all subkeys on the dst server */
2475 if (!net_spoolss_setprinterdataex(pipe_hnd_dst, mem_ctx, &hnd_dst,
2476 subkey, &v)) {
2477 goto done;
2478 }
2479
2480 }
2481
2482 DEBUGADD(1,("\tSetPrinterDataEx of key [%s\\%s] succeeded\n",
2483 subkey, info[j].value_name));
2484
2485 }
2486 }
2487
2488 TALLOC_FREE(keylist);
2489
2490 /* close printer handles here */
2491 if (is_valid_policy_hnd(&hnd_src)) {
2492 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
2493 }
2494
2495 if (is_valid_policy_hnd(&hnd_dst)) {
2496 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
2497 }
2498
2499 }
2500
2501 nt_status = NT_STATUS_OK;
2502
2503 done:
2504 SAFE_FREE(devicename);
2505 SAFE_FREE(url);
2506 SAFE_FREE(unc_name);
2507
2508 if (is_valid_policy_hnd(&hnd_src))
2509 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
2510
2511 if (is_valid_policy_hnd(&hnd_dst))
2512 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
2513
2514 if (cli_dst) {
2515 cli_shutdown(cli_dst);
2516 }
2517 return nt_status;
2518 }