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