2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) 2004,2009 Guenther Deschner (gd@samba.org)
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.
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.
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/>.
20 #include "utils/net.h"
22 /* support itanium as well */
23 static const struct print_architecture_table_node archi_table
[]= {
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 },
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.
42 /****************************************************************************
43 Printer info level 3 display function.
44 ****************************************************************************/
46 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
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
);
63 for (i
=0; r
->dependent_files
[i
] != NULL
; i
++) {
64 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
69 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
70 printf("\tDefaultdatatype: [%s]\n\n", r
->default_datatype
);
73 static void display_reg_value(const char *subkey
, REGISTRY_VALUE value
)
79 d_printf("\t[%s:%s]: REG_DWORD: 0x%08x\n", subkey
, value
.valuename
,
80 *((uint32_t *) value
.data_p
));
84 rpcstr_pull_talloc(talloc_tos(),
92 d_printf("\t[%s:%s]: REG_SZ: %s\n", subkey
, value
.valuename
, text
);
96 d_printf("\t[%s:%s]: REG_BINARY: unknown length value not displayed\n",
97 subkey
, value
.valuename
);
101 uint32_t i
, num_values
;
104 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL
, value
.data_p
,
105 value
.size
, &num_values
,
107 d_printf("reg_pull_multi_sz failed\n");
111 for (i
=0; i
<num_values
; i
++) {
112 d_printf("%s\n", values
[i
]);
119 d_printf("\t%s: unknown type %d\n", value
.valuename
, value
.type
);
125 * Copies ACLs, DOS-attributes and timestamps from one
126 * file or directory from one connected share to another connected share
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
139 * @return Normal NTSTATUS return.
142 NTSTATUS
net_copy_fileattr(struct net_context
*c
,
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
)
150 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
155 time_t f_atime
, f_ctime
, f_mtime
;
158 if (!copy_timestamps
&& !copy_acls
&& !copy_attrs
)
161 /* open file/dir on the originating server */
163 DEBUGADD(3,("opening %s %s on originating server\n",
164 is_file
?"file":"dir", src_name
));
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
);
177 /* get the security descriptor */
178 sd
= cli_query_secdesc(cli_share_src
, fnum_src
, mem_ctx
);
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
);
186 if (c
->opt_verbose
&& DEBUGLEVEL
>= 3)
187 display_sec_desc(sd
);
191 if (copy_attrs
|| copy_timestamps
) {
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
);
204 /* open the file/dir on the destination server */
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
);
214 if (copy_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
);
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
);
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
);
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
);
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
);
265 nt_status
= NT_STATUS_OK
;
271 cli_close(cli_share_src
, fnum_src
);
274 cli_close(cli_share_dst
, fnum_dst
);
280 * Copy a file or directory from a connected share to another connected share
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
293 * @return Normal NTSTATUS return.
296 NTSTATUS
net_copy_file(struct net_context
*c
,
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
)
304 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
307 static int io_bufsize
= 64512;
308 int read_size
= io_bufsize
;
313 if (!src_name
|| !dst_name
)
316 if (cli_share_src
== NULL
|| cli_share_dst
== NULL
)
319 /* open on the originating server */
320 DEBUGADD(3,("opening %s %s on originating server\n",
321 is_file
? "file":"dir", src_name
));
323 fnum_src
= cli_open(cli_share_src
, src_name
, O_RDONLY
, DENY_NONE
);
325 fnum_src
= cli_nt_create(cli_share_src
, src_name
, READ_CONTROL_ACCESS
);
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
);
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
);
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
);
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
;
360 if (c
->opt_verbose
) {
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)" : "" );
376 n
= cli_read(cli_share_src
, fnum_src
, data
, nread
,
382 ret
= cli_write(cli_share_dst
, fnum_dst
, 0, data
,
386 d_fprintf(stderr
, "Error writing file: %s\n",
387 cli_errstr(cli_share_dst
));
388 nt_status
= cli_nt_error(cli_share_dst
);
396 if (!is_file
&& !cli_chkpath(cli_share_dst
, dst_name
)) {
399 DEBUGADD(3,("creating dir %s on the destination server\n",
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
;
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
));
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
);
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
);
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
))
439 nt_status
= NT_STATUS_OK
;
445 cli_close(cli_share_src
, fnum_src
);
448 cli_close(cli_share_dst
, fnum_dst
);
456 * Copy a driverfile from on connected share to another connected share
457 * This silently assumes that a driver-file is picked up from
459 * \\src_server\print$\{arch}\{version}\file
463 * \\dst_server\print$\{arch}\file
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)
473 * @return Normal NTSTATUS return.
476 static NTSTATUS
net_copy_driverfile(struct net_context
*c
,
478 struct cli_state
*cli_share_src
,
479 struct cli_state
*cli_share_dst
,
480 const char *file
, const char *short_archi
) {
482 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
494 /* scroll through the file until we have the part
495 beyond archi_table.short_archi */
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
, "\\");
504 /* build source file name */
505 if (asprintf(&src_name
, "\\%s\\%s\\%s", short_archi
, version
, filename
) < 0 )
506 return NT_STATUS_NO_MEMORY
;
509 /* create destination file name */
510 if (asprintf(&dst_name
, "\\%s\\%s", short_archi
, filename
) < 0 )
511 return NT_STATUS_NO_MEMORY
;
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
))
520 nt_status
= NT_STATUS_OK
;
530 * Check for existing Architecture directory on a given server
532 * @param cli_share A cli_state connected to a print$-share
533 * @param short_archi The Architecture for the print-driver
535 * @return Normal NTSTATUS return.
538 static NTSTATUS
check_arch_dir(struct cli_state
*cli_share
, const char *short_archi
)
541 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
544 if (asprintf(&dir
, "\\%s", short_archi
) < 0) {
545 return NT_STATUS_NO_MEMORY
;
548 DEBUG(10,("creating print-driver dir for architecture: %s\n",
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
;
557 if (!cli_chkpath(cli_share
, dir
)) {
558 d_fprintf(stderr
, "cannot check %s: %s\n",
559 dir
, cli_errstr(cli_share
));
563 nt_status
= NT_STATUS_OK
;
571 * Copy a print-driver (level 3) from one connected print$-share to another
572 * connected print$-share
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
581 * @return Normal NTSTATUS return.
584 static NTSTATUS
copy_print_driver_3(struct net_context
*c
,
586 struct cli_state
*cli_share_src
,
587 struct cli_state
*cli_share_dst
,
588 const char *short_archi
,
589 struct spoolss_DriverInfo3
*r
)
591 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
599 d_printf("copying driver: [%s], for architecture: [%s], version: [%d]\n",
600 r
->driver_name
, short_archi
, r
->version
);
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
))
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
))
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
))
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
))
622 for (i
=0; r
->dependent_files
[i
] != NULL
; i
++) {
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
)) {
636 * net_spoolss-functions
637 * =====================
639 * the net_spoolss-functions aim to simplify spoolss-client-functions
640 * required during the migration-process wrt buffer-sizes, returned
643 * this greatly reduces the complexitiy of the migrate-functions.
647 static bool net_spoolss_enum_printers(struct rpc_pipe_client
*pipe_hnd
,
652 uint32_t *num_printers
,
653 union spoolss_PrinterInfo
**info
)
659 result
= rpccli_spoolss_enumprinters(pipe_hnd
, mem_ctx
,
666 if (!W_ERROR_IS_OK(result
)) {
667 printf("cannot enum printers: %s\n", win_errstr(result
));
674 static bool net_spoolss_open_printer_ex(struct rpc_pipe_client
*pipe_hnd
,
676 const char *printername
,
677 uint32_t access_required
,
678 const char *username
,
679 struct policy_handle
*hnd
)
682 fstring printername2
;
684 fstrcpy(printername2
, pipe_hnd
->srv_name_slash
);
685 fstrcat(printername2
, "\\");
686 fstrcat(printername2
, printername
);
688 DEBUG(10,("connecting to: %s as %s for %s and access: %x\n",
689 pipe_hnd
->srv_name_slash
, username
, printername2
, access_required
));
692 result
= rpccli_spoolss_openprinter_ex(pipe_hnd
, mem_ctx
,
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
);
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
));
710 DEBUG(2,("got printer handle for printer: %s, server: %s\n",
711 printername2
, pipe_hnd
->srv_name_slash
));
716 static bool net_spoolss_getprinter(struct rpc_pipe_client
*pipe_hnd
,
718 struct policy_handle
*hnd
,
720 union spoolss_PrinterInfo
*info
)
724 /* getprinter call */
725 result
= rpccli_spoolss_getprinter(pipe_hnd
, mem_ctx
,
730 if (!W_ERROR_IS_OK(result
)) {
731 printf("cannot get printer-info: %s\n", win_errstr(result
));
738 static bool net_spoolss_setprinter(struct rpc_pipe_client
*pipe_hnd
,
740 struct policy_handle
*hnd
,
742 union spoolss_PrinterInfo
*info
)
746 struct spoolss_SetPrinterInfoCtr info_ctr
;
747 struct spoolss_DevmodeContainer devmode_ctr
;
748 struct sec_desc_buf secdesc_ctr
;
750 ZERO_STRUCT(devmode_ctr
);
751 ZERO_STRUCT(secdesc_ctr
);
753 /* setprinter call */
755 info_ctr
.level
= level
;
758 info_ctr
.info
.info0
= (struct spoolss_SetPrinterInfo0
*)&info
->info0
;
761 info_ctr
.info
.info1
= (struct spoolss_SetPrinterInfo1
*)&info
->info1
;
764 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info
->info2
;
767 info_ctr
.info
.info3
= (struct spoolss_SetPrinterInfo3
*)&info
->info3
;
770 info_ctr
.info
.info4
= (struct spoolss_SetPrinterInfo4
*)&info
->info4
;
773 info_ctr
.info
.info5
= (struct spoolss_SetPrinterInfo5
*)&info
->info5
;
776 info_ctr
.info
.info6
= (struct spoolss_SetPrinterInfo6
*)&info
->info6
;
779 info_ctr
.info
.info7
= (struct spoolss_SetPrinterInfo7
*)&info
->info7
;
783 info_ctr
.info
.info8
= (struct spoolss_SetPrinterInfo8
*)&info
->info8
;
786 info_ctr
.info
.info9
= (struct spoolss_SetPrinterInfo9
*)&info
->info9
;
793 status
= rpccli_spoolss_SetPrinter(pipe_hnd
, mem_ctx
,
801 if (!W_ERROR_IS_OK(result
)) {
802 printf("cannot set printer-info: %s\n", win_errstr(result
));
810 static bool net_spoolss_setprinterdata(struct rpc_pipe_client
*pipe_hnd
,
812 struct policy_handle
*hnd
,
813 const char *value_name
,
814 enum winreg_Type type
,
815 union spoolss_PrinterData data
)
820 /* setprinterdata call */
821 status
= rpccli_spoolss_SetPrinterData(pipe_hnd
, mem_ctx
,
826 0, /* autocalculated */
829 if (!W_ERROR_IS_OK(result
)) {
830 printf ("unable to set printerdata: %s\n", win_errstr(result
));
838 static bool net_spoolss_enumprinterkey(struct rpc_pipe_client
*pipe_hnd
,
840 struct policy_handle
*hnd
,
842 const char ***keylist
)
846 /* enumprinterkey call */
847 result
= rpccli_spoolss_enumprinterkey(pipe_hnd
, mem_ctx
, hnd
, keyname
, keylist
, 0);
849 if (!W_ERROR_IS_OK(result
)) {
850 printf("enumprinterkey failed: %s\n", win_errstr(result
));
857 static bool net_spoolss_enumprinterdataex(struct rpc_pipe_client
*pipe_hnd
,
860 struct policy_handle
*hnd
,
863 struct spoolss_PrinterEnumValues
**info
)
867 /* enumprinterdataex call */
868 result
= rpccli_spoolss_enumprinterdataex(pipe_hnd
, mem_ctx
,
875 if (!W_ERROR_IS_OK(result
)) {
876 printf("enumprinterdataex failed: %s\n", win_errstr(result
));
884 static bool net_spoolss_setprinterdataex(struct rpc_pipe_client
*pipe_hnd
,
886 struct policy_handle
*hnd
,
888 REGISTRY_VALUE
*value
)
893 /* setprinterdataex call */
894 status
= rpccli_spoolss_SetPrinterDataEx(pipe_hnd
, mem_ctx
,
903 if (!W_ERROR_IS_OK(result
)) {
904 printf("could not set printerdataex: %s\n", win_errstr(result
));
911 static bool net_spoolss_enumforms(struct rpc_pipe_client
*pipe_hnd
,
913 struct policy_handle
*hnd
,
916 union spoolss_FormInfo
**forms
)
921 result
= rpccli_spoolss_enumforms(pipe_hnd
, mem_ctx
,
927 if (!W_ERROR_IS_OK(result
)) {
928 printf("could not enum forms: %s\n", win_errstr(result
));
935 static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client
*pipe_hnd
,
937 uint32_t level
, const char *env
,
939 union spoolss_DriverInfo
**info
)
943 /* enumprinterdrivers call */
944 result
= rpccli_spoolss_enumprinterdrivers(pipe_hnd
, mem_ctx
,
945 pipe_hnd
->srv_name_slash
,
951 if (!W_ERROR_IS_OK(result
)) {
952 printf("cannot enum drivers: %s\n", win_errstr(result
));
959 static bool net_spoolss_getprinterdriver(struct rpc_pipe_client
*pipe_hnd
,
961 struct policy_handle
*hnd
, uint32_t level
,
962 const char *env
, int version
,
963 union spoolss_DriverInfo
*info
)
966 uint32_t server_major_version
;
967 uint32_t server_minor_version
;
969 /* getprinterdriver call */
970 result
= rpccli_spoolss_getprinterdriver2(pipe_hnd
, mem_ctx
,
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
));
994 static bool net_spoolss_addprinterdriver(struct rpc_pipe_client
*pipe_hnd
,
995 TALLOC_CTX
*mem_ctx
, uint32_t level
,
996 union spoolss_DriverInfo
*info
)
1000 struct spoolss_AddDriverInfoCtr info_ctr
;
1002 info_ctr
.level
= level
;
1006 info_ctr
.info
.info2
= (struct spoolss_AddDriverInfo2
*)&info
->info2
;
1009 info_ctr
.info
.info3
= (struct spoolss_AddDriverInfo3
*)&info
->info3
;
1012 printf("unsupported info level: %d\n", level
);
1016 /* addprinterdriver call */
1017 status
= rpccli_spoolss_AddPrinterDriver(pipe_hnd
, mem_ctx
,
1018 pipe_hnd
->srv_name_slash
,
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");
1026 if (!W_ERROR_IS_OK(result
)) {
1027 printf("cannot add driver: %s\n", win_errstr(result
));
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
1039 static bool get_printer_info(struct rpc_pipe_client
*pipe_hnd
,
1040 TALLOC_CTX
*mem_ctx
,
1044 uint32_t *num_printers
,
1045 union spoolss_PrinterInfo
**info_p
)
1047 struct policy_handle hnd
;
1049 /* no arguments given, enumerate all printers */
1052 if (!net_spoolss_enum_printers(pipe_hnd
, mem_ctx
, NULL
,
1053 PRINTER_ENUM_LOCAL
|PRINTER_ENUM_SHARED
,
1054 level
, num_printers
, info_p
))
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
,
1067 if (!net_spoolss_getprinter(pipe_hnd
, mem_ctx
, &hnd
, level
, *info_p
)) {
1068 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd
, NULL
);
1072 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd
, NULL
);
1077 DEBUG(3,("got %d printers\n", *num_printers
));
1084 * List print-queues (including local printers that are not shared)
1086 * All parameters are provided by the run_rpc_command function, except for
1087 * argc, argv which are passed through.
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
1097 * @return Normal NTSTATUS return.
1100 NTSTATUS
rpc_printer_list_internals(struct net_context
*c
,
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
,
1109 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
1110 uint32_t i
, num_printers
;
1112 const char *printername
, *sharename
;
1113 union spoolss_PrinterInfo
*info
;
1115 printf("listing printers\n");
1117 if (!get_printer_info(pipe_hnd
, mem_ctx
, level
, argc
, argv
, &num_printers
, &info
))
1120 for (i
= 0; i
< num_printers
; i
++) {
1122 /* do some initialization */
1123 printername
= info
[i
].info2
.printername
;
1124 sharename
= info
[i
].info2
.sharename
;
1126 if (printername
&& sharename
) {
1127 d_printf("printer %d: %s, shared as: %s\n",
1128 i
+1, printername
, sharename
);
1132 return NT_STATUS_OK
;
1136 * List printer-drivers from a server
1138 * All parameters are provided by the run_rpc_command function, except for
1139 * argc, argv which are passed through.
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
1149 * @return Normal NTSTATUS return.
1152 NTSTATUS
rpc_printer_driver_list_internals(struct net_context
*c
,
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
,
1161 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
1164 union spoolss_DriverInfo
*info
;
1167 printf("listing printer-drivers\n");
1169 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1171 uint32_t num_drivers
;
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
;
1181 if (num_drivers
== 0) {
1182 d_printf ("no drivers found on server for architecture: [%s].\n",
1183 archi_table
[i
].long_archi
);
1187 d_printf("got %d printer-drivers for architecture: [%s]\n",
1188 num_drivers
, archi_table
[i
].long_archi
);
1191 /* do something for all drivers for architecture */
1192 for (d
= 0; d
< num_drivers
; d
++) {
1193 display_print_driver3(&info
[d
].info3
);
1197 nt_status
= NT_STATUS_OK
;
1205 * Publish print-queues with args-wrapper
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
1214 * @return Normal NTSTATUS return.
1217 static NTSTATUS
rpc_printer_publish_internals_args(struct rpc_pipe_client
*pipe_hnd
,
1218 TALLOC_CTX
*mem_ctx
,
1223 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
1224 uint32_t i
, num_printers
;
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
;
1234 const char *action_str
;
1236 if (!get_printer_info(pipe_hnd
, mem_ctx
, 2, argc
, argv
, &num_printers
, &info_enum
))
1239 for (i
= 0; i
< num_printers
; i
++) {
1241 /* do some initialization */
1242 printername
= info_enum
[i
].info2
.printername
;
1243 sharename
= info_enum
[i
].info2
.sharename
;
1244 if (!printername
|| !sharename
) {
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
))
1253 /* check for existing dst printer */
1254 if (!net_spoolss_getprinter(pipe_hnd
, mem_ctx
, &hnd
, level
, &info
))
1257 /* check action and set string */
1259 case DSPRINT_PUBLISH
:
1260 action_str
= "published";
1262 case DSPRINT_UPDATE
:
1263 action_str
= "updated";
1265 case DSPRINT_UNPUBLISH
:
1266 action_str
= "unpublished";
1269 action_str
= "unknown action";
1270 printf("unkown action: %d\n", action
);
1274 info
.info7
.action
= action
;
1276 info_ctr
.info
.info7
= (struct spoolss_SetPrinterInfo7
*)&info
.info7
;
1278 ZERO_STRUCT(devmode_ctr
);
1279 ZERO_STRUCT(secdesc_ctr
);
1281 nt_status
= rpccli_spoolss_SetPrinter(pipe_hnd
, mem_ctx
,
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
));
1294 printf("successfully %s printer %s in Active Directory\n", action_str
, sharename
);
1297 nt_status
= NT_STATUS_OK
;
1300 if (is_valid_policy_hnd(&hnd
))
1301 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd
, NULL
);
1306 NTSTATUS
rpc_printer_publish_publish_internals(struct net_context
*c
,
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
,
1315 return rpc_printer_publish_internals_args(pipe_hnd
, mem_ctx
, argc
, argv
, DSPRINT_PUBLISH
);
1318 NTSTATUS
rpc_printer_publish_unpublish_internals(struct net_context
*c
,
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
,
1327 return rpc_printer_publish_internals_args(pipe_hnd
, mem_ctx
, argc
, argv
, DSPRINT_UNPUBLISH
);
1330 NTSTATUS
rpc_printer_publish_update_internals(struct net_context
*c
,
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
,
1339 return rpc_printer_publish_internals_args(pipe_hnd
, mem_ctx
, argc
, argv
, DSPRINT_UPDATE
);
1343 * List print-queues w.r.t. their publishing state
1345 * All parameters are provided by the run_rpc_command function, except for
1346 * argc, argv which are passed through.
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
1356 * @return Normal NTSTATUS return.
1359 NTSTATUS
rpc_printer_publish_list_internals(struct net_context
*c
,
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
,
1368 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
1369 uint32_t i
, num_printers
;
1371 const char *printername
, *sharename
;
1372 union spoolss_PrinterInfo
*info_enum
;
1373 union spoolss_PrinterInfo info
;
1374 struct policy_handle hnd
;
1377 if (!get_printer_info(pipe_hnd
, mem_ctx
, 2, argc
, argv
, &num_printers
, &info_enum
))
1380 for (i
= 0; i
< num_printers
; i
++) {
1382 /* do some initialization */
1383 printername
= info_enum
[i
].info2
.printername
;
1384 sharename
= info_enum
[i
].info2
.sharename
;
1386 if (!printername
|| !sharename
) {
1390 /* open printer handle */
1391 if (!net_spoolss_open_printer_ex(pipe_hnd
, mem_ctx
, sharename
,
1392 PRINTER_ALL_ACCESS
, cli
->user_name
, &hnd
))
1395 /* check for existing dst printer */
1396 if (!net_spoolss_getprinter(pipe_hnd
, mem_ctx
, &hnd
, level
, &info
))
1399 if (!info
.info7
.guid
) {
1402 state
= info
.info7
.action
;
1404 case DSPRINT_PUBLISH
:
1405 printf("printer [%s] is published", sharename
);
1407 printf(", guid: %s", info
.info7
.guid
);
1410 case DSPRINT_UNPUBLISH
:
1411 printf("printer [%s] is unpublished\n", sharename
);
1413 case DSPRINT_UPDATE
:
1414 printf("printer [%s] is currently updating\n", sharename
);
1417 printf("unkown state: %d\n", state
);
1422 nt_status
= NT_STATUS_OK
;
1425 if (is_valid_policy_hnd(&hnd
))
1426 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd
, NULL
);
1432 * Migrate Printer-ACLs from a source server to the destination server
1434 * All parameters are provided by the run_rpc_command function, except for
1435 * argc, argv which are passed through.
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
1445 * @return Normal NTSTATUS return.
1448 NTSTATUS
rpc_printer_migrate_security_internals(struct net_context
*c
,
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
,
1457 /* TODO: what now, info2 or info3 ?
1458 convince jerry that we should add clientside setacls level 3 at least
1460 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
1462 uint32_t num_printers
;
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
;
1471 DEBUG(3,("copying printer ACLs\n"));
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
))
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
;
1486 if (!num_printers
) {
1487 printf ("no printers found on server.\n");
1488 nt_status
= NT_STATUS_OK
;
1492 /* do something for all printers */
1493 for (i
= 0; i
< num_printers
; i
++) {
1495 /* do some initialization */
1496 printername
= info_enum
[i
].info2
.printername
;
1497 sharename
= info_enum
[i
].info2
.sharename
;
1499 if (!printername
|| !sharename
) {
1500 nt_status
= NT_STATUS_UNSUCCESSFUL
;
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
;
1508 d_printf("migrating printer ACLs for: [%s] / [%s]\n",
1509 printername
, sharename
);
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)
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
))
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
))
1527 /* check for existing dst printer */
1528 if (!net_spoolss_getprinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, level
, &info_dst
))
1531 /* check for existing src printer */
1532 if (!net_spoolss_getprinter(pipe_hnd
, mem_ctx
, &hnd_src
, 3, &info_src
))
1535 /* Copy Security Descriptor */
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
);
1542 display_sec_desc(info_dst
.info2
.secdesc
);
1544 if (!net_spoolss_setprinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, 2, &info_dst
))
1547 DEBUGADD(1,("\tSetPrinter of SECDESC succeeded\n"));
1550 /* close printer handles here */
1551 if (is_valid_policy_hnd(&hnd_src
)) {
1552 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd_src
, NULL
);
1555 if (is_valid_policy_hnd(&hnd_dst
)) {
1556 rpccli_spoolss_ClosePrinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, NULL
);
1561 nt_status
= NT_STATUS_OK
;
1565 if (is_valid_policy_hnd(&hnd_src
)) {
1566 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd_src
, NULL
);
1569 if (is_valid_policy_hnd(&hnd_dst
)) {
1570 rpccli_spoolss_ClosePrinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, NULL
);
1574 cli_shutdown(cli_dst
);
1580 * Migrate printer-forms from a src server to the dst server
1582 * All parameters are provided by the run_rpc_command function, except for
1583 * argc, argv which are passed through.
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
1593 * @return Normal NTSTATUS return.
1596 NTSTATUS
rpc_printer_migrate_forms_internals(struct net_context
*c
,
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
,
1605 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
1608 uint32_t num_printers
;
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
;
1616 union spoolss_FormInfo
*forms
;
1617 struct cli_state
*cli_dst
= NULL
;
1619 DEBUG(3,("copying forms\n"));
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
))
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
;
1633 if (!num_printers
) {
1634 printf ("no printers found on server.\n");
1635 nt_status
= NT_STATUS_OK
;
1639 /* do something for all printers */
1640 for (i
= 0; i
< num_printers
; i
++) {
1642 /* do some initialization */
1643 printername
= info_enum
[i
].info2
.printername
;
1644 sharename
= info_enum
[i
].info2
.sharename
;
1646 if (!printername
|| !sharename
) {
1647 nt_status
= NT_STATUS_UNSUCCESSFUL
;
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
;
1654 d_printf("migrating printer forms for: [%s] / [%s]\n",
1655 printername
, sharename
);
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
))
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
))
1668 /* check for existing dst printer */
1669 if (!net_spoolss_getprinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, level
, &info_dst
))
1672 /* finally migrate forms */
1673 if (!net_spoolss_enumforms(pipe_hnd
, mem_ctx
, &hnd_src
, level
, &num_forms
, &forms
))
1676 DEBUG(1,("got %d forms for printer\n", num_forms
));
1679 for (f
= 0; f
< num_forms
; f
++) {
1681 union spoolss_AddFormInfo info
;
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
)
1690 d_printf("\tmigrating form # %d [%s] of type [%d]\n",
1691 f
, forms
[f
].info1
.form_name
,
1692 forms
[f
].info1
.flags
);
1694 info
.info1
= (struct spoolss_AddFormInfo1
*)&forms
[f
].info1
;
1696 /* FIXME: there might be something wrong with samba's
1698 status
= rpccli_spoolss_AddForm(pipe_hnd_dst
, mem_ctx
,
1703 if (!W_ERROR_IS_OK(result
)) {
1704 d_printf("\tAddForm form %d: [%s] refused.\n",
1705 f
, forms
[f
].info1
.form_name
);
1709 DEBUGADD(1,("\tAddForm of [%s] succeeded\n",
1710 forms
[f
].info1
.form_name
));
1714 /* close printer handles here */
1715 if (is_valid_policy_hnd(&hnd_src
)) {
1716 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd_src
, NULL
);
1719 if (is_valid_policy_hnd(&hnd_dst
)) {
1720 rpccli_spoolss_ClosePrinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, NULL
);
1724 nt_status
= NT_STATUS_OK
;
1728 if (is_valid_policy_hnd(&hnd_src
))
1729 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd_src
, NULL
);
1731 if (is_valid_policy_hnd(&hnd_dst
))
1732 rpccli_spoolss_ClosePrinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, NULL
);
1735 cli_shutdown(cli_dst
);
1741 * Migrate printer-drivers from a src server to the dst server
1743 * All parameters are provided by the run_rpc_command function, except for
1744 * argc, argv which are passed through.
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
1754 * @return Normal NTSTATUS return.
1757 NTSTATUS
rpc_printer_migrate_drivers_internals(struct net_context
*c
,
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
,
1766 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
1768 uint32_t num_printers
;
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
;
1783 DEBUG(3,("copying printer-drivers\n"));
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
))
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
))
1796 got_src_driver_share
= true;
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
))
1805 got_dst_driver_share
= true;
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
;
1814 if (num_printers
== 0) {
1815 printf ("no printers found on server.\n");
1816 nt_status
= NT_STATUS_OK
;
1821 /* do something for all printers */
1822 for (p
= 0; p
< num_printers
; p
++) {
1824 /* do some initialization */
1825 printername
= info_enum
[p
].info2
.printername
;
1826 sharename
= info_enum
[p
].info2
.sharename
;
1828 if (!printername
|| !sharename
) {
1829 nt_status
= NT_STATUS_UNSUCCESSFUL
;
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
;
1837 d_printf("migrating printer driver for: [%s] / [%s]\n",
1838 printername
, sharename
);
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
))
1845 /* check for existing dst printer */
1846 if (!net_spoolss_getprinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, 2, &info_dst
))
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
,
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 */
1860 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
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
))
1868 drivername
= drv_info_src
.info3
.driver_name
;
1871 display_print_driver3(&drv_info_src
.info3
);
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
))
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
))
1888 if (!net_spoolss_addprinterdriver(pipe_hnd_dst
, mem_ctx
, level
, &drv_info_src
)) {
1889 nt_status
= NT_STATUS_UNSUCCESSFUL
;
1893 DEBUGADD(1,("Sucessfully added driver [%s] for printer [%s]\n",
1894 drivername
, printername
));
1898 if (!drivername
|| strlen(drivername
) == 0) {
1899 DEBUGADD(1,("Did not get driver for printer %s\n",
1905 info_dst
.info2
.drivername
= drivername
;
1907 if (!net_spoolss_setprinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, 2, &info_dst
)) {
1908 nt_status
= NT_STATUS_UNSUCCESSFUL
;
1912 DEBUGADD(1,("Sucessfully set driver %s for printer %s\n",
1913 drivername
, printername
));
1916 if (is_valid_policy_hnd(&hnd_dst
)) {
1917 rpccli_spoolss_ClosePrinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, NULL
);
1921 if (is_valid_policy_hnd(&hnd_src
)) {
1922 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd_src
, NULL
);
1926 nt_status
= NT_STATUS_OK
;
1930 if (is_valid_policy_hnd(&hnd_src
))
1931 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd_src
, NULL
);
1933 if (is_valid_policy_hnd(&hnd_dst
))
1934 rpccli_spoolss_ClosePrinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, NULL
);
1937 cli_shutdown(cli_dst
);
1940 if (got_src_driver_share
)
1941 cli_shutdown(cli_share_src
);
1943 if (got_dst_driver_share
)
1944 cli_shutdown(cli_share_dst
);
1951 * Migrate printer-queues from a src to the dst server
1952 * (requires a working "addprinter command" to be installed for the local smbd)
1954 * All parameters are provided by the run_rpc_command function, except for
1955 * argc, argv which are passed through.
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
1965 * @return Normal NTSTATUS return.
1968 NTSTATUS
rpc_printer_migrate_printers_internals(struct net_context
*c
,
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
,
1978 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
1979 uint32_t i
= 0, num_printers
;
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
;
1989 DEBUG(3,("copying printers\n"));
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
))
1998 if (!get_printer_info(pipe_hnd
, mem_ctx
, level
, argc
, argv
, &num_printers
, &info_enum
)) {
1999 nt_status
= NT_STATUS_UNSUCCESSFUL
;
2003 if (!num_printers
) {
2004 printf ("no printers found on server.\n");
2005 nt_status
= NT_STATUS_OK
;
2009 /* do something for all printers */
2010 for (i
= 0; i
< num_printers
; i
++) {
2012 /* do some initialization */
2013 printername
= info_enum
[i
].info2
.printername
;
2014 sharename
= info_enum
[i
].info2
.sharename
;
2016 if (!printername
|| !sharename
) {
2017 nt_status
= NT_STATUS_UNSUCCESSFUL
;
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
;
2024 d_printf("migrating printer queue for: [%s] / [%s]\n",
2025 printername
, sharename
);
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
)) {
2031 DEBUG(1,("could not open printer: %s\n", sharename
));
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");
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
);
2046 /* now get again src printer ctr via getprinter,
2047 we first need a handle for that */
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
))
2054 /* getprinter on the src server */
2055 if (!net_spoolss_getprinter(pipe_hnd
, mem_ctx
, &hnd_src
, level
, &info_src
))
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
);
2062 info_ctr
.level
= level
;
2063 info_ctr
.info
.info2
= (struct spoolss_SetPrinterInfo2
*)&info_src
.info2
;
2065 result
= rpccli_spoolss_addprinterex(pipe_hnd_dst
,
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
);
2074 d_fprintf (stderr
, "could not create printer [%s]\n", printername
);
2078 /* close printer handles here */
2079 if (is_valid_policy_hnd(&hnd_src
)) {
2080 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd_src
, NULL
);
2083 if (is_valid_policy_hnd(&hnd_dst
)) {
2084 rpccli_spoolss_ClosePrinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, NULL
);
2088 nt_status
= NT_STATUS_OK
;
2091 if (is_valid_policy_hnd(&hnd_src
))
2092 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd_src
, NULL
);
2094 if (is_valid_policy_hnd(&hnd_dst
))
2095 rpccli_spoolss_ClosePrinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, NULL
);
2098 cli_shutdown(cli_dst
);
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)
2107 * All parameters are provided by the run_rpc_command function, except for
2108 * argc, argv which are passed through.
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
2118 * @return Normal NTSTATUS return.
2121 NTSTATUS
rpc_printer_migrate_settings_internals(struct net_context
*c
,
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
,
2131 /* FIXME: Here the nightmare begins */
2134 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
2135 uint32_t i
= 0, p
= 0, j
= 0;
2136 uint32_t num_printers
;
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
;
2150 ZERO_STRUCT(info_dst_publish
);
2152 DEBUG(3,("copying printer settings\n"));
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
))
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
;
2166 if (!num_printers
) {
2167 printf ("no printers found on server.\n");
2168 nt_status
= NT_STATUS_OK
;
2173 /* needed for dns-strings in regkeys */
2174 longname
= get_mydnsfullname();
2176 nt_status
= NT_STATUS_UNSUCCESSFUL
;
2180 /* do something for all printers */
2181 for (i
= 0; i
< num_printers
; i
++) {
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
;
2189 /* do some initialization */
2190 printername
= info_enum
[i
].info2
.printername
;
2191 sharename
= info_enum
[i
].info2
.sharename
;
2193 if (!printername
|| !sharename
) {
2194 nt_status
= NT_STATUS_UNSUCCESSFUL
;
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
;
2201 d_printf("migrating printer settings for: [%s] / [%s]\n",
2202 printername
, sharename
);
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
))
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
))
2215 /* check for existing dst printer */
2216 if (!net_spoolss_getprinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
,
2221 /* STEP 1: COPY DEVICE-MODE and other
2222 PRINTER_INFO_2-attributes
2225 info_dst
.info2
= info_enum
[i
].info2
;
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
;
2231 /* check if printer is published */
2232 if (info_enum
[i
].info2
.attributes
& PRINTER_ATTRIBUTE_PUBLISHED
) {
2234 /* check for existing dst printer */
2235 if (!net_spoolss_getprinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, 7, &info_dst_publish
))
2238 info_dst_publish
.info7
.action
= DSPRINT_PUBLISH
;
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
);
2243 DEBUG(3,("republished printer\n"));
2246 if (info_enum
[i
].info2
.devmode
!= NULL
) {
2248 /* copy devmode (info level 2) */
2249 info_dst
.info2
.devmode
= info_enum
[i
].info2
.devmode
;
2251 /* do not copy security descriptor (we have another
2252 * command for that) */
2253 info_dst
.info2
.secdesc
= NULL
;
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
;
2264 if (!net_spoolss_setprinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
,
2268 DEBUGADD(1,("\tSetPrinter of DEVICEMODE succeeded\n"));
2271 /* STEP 2: COPY REGISTRY VALUES */
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
2279 /* enumerate data on src handle */
2280 nt_status
= rpccli_spoolss_EnumPrinterData(pipe_hnd
, mem_ctx
,
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
);
2297 /* loop for all printerdata of "PrinterDriverData" */
2298 while (NT_STATUS_IS_OK(nt_status
) && W_ERROR_IS_OK(result
)) {
2300 nt_status
= rpccli_spoolss_EnumPrinterData(pipe_hnd
, mem_ctx
,
2311 /* loop for all reg_keys */
2312 if (NT_STATUS_IS_OK(nt_status
) && W_ERROR_IS_OK(result
)) {
2316 union spoolss_PrinterData printer_data
;
2319 if (c
->opt_verbose
) {
2320 fstrcpy(v
.valuename
, value_name
);
2322 v
.size
= data_offered
;
2324 display_reg_value(SPOOL_PRINTERDATA_KEY
, v
);
2327 result
= pull_spoolss_PrinterData(mem_ctx
,
2331 if (!W_ERROR_IS_OK(result
)) {
2336 if (!net_spoolss_setprinterdata(pipe_hnd_dst
, mem_ctx
,
2337 &hnd_dst
, value_name
,
2338 type
, printer_data
))
2341 DEBUGADD(1,("\tSetPrinterData of [%s] succeeded\n",
2346 /* STEP 3: COPY SUBKEY VALUES */
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 */
2353 if (!net_spoolss_enumprinterkey(pipe_hnd
, mem_ctx
, &hnd_src
, "", &keylist
)) {
2354 printf("got no key-data\n");
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 */
2363 if (keylist
== NULL
)
2366 for (i
=0; keylist
&& keylist
[i
] != NULL
; i
++) {
2368 const char *subkey
= keylist
[i
];
2370 struct spoolss_PrinterEnumValues
*info
;
2372 /* enumerate all src subkeys */
2373 if (!net_spoolss_enumprinterdataex(pipe_hnd
, mem_ctx
, 0,
2379 for (j
=0; j
< count
; j
++) {
2381 REGISTRY_VALUE value
;
2384 /* although samba replies with sane data in most cases we
2385 should try to avoid writing wrong registry data */
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
)) {
2393 if (strequal(info
[j
].value_name
, SPOOL_REG_PORTNAME
)) {
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
);
2400 if (strequal(info
[j
].value_name
, SPOOL_REG_UNCNAME
)) {
2402 if (asprintf(&unc_name
, "\\\\%s\\%s", longname
, sharename
) < 0) {
2403 nt_status
= NT_STATUS_NO_MEMORY
;
2406 init_unistr2(&data
, unc_name
, UNI_STR_TERMINATE
);
2407 fstrcpy(value
.valuename
, SPOOL_REG_UNCNAME
);
2410 if (strequal(info
[j
].value_name
, SPOOL_REG_URL
)) {
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
;
2420 init_unistr2(&data
, url
, UNI_STR_TERMINATE
);
2421 fstrcpy(value
.valuename
, SPOOL_REG_URL
);
2425 if (strequal(info
[j
].value_name
, SPOOL_REG_SERVERNAME
)) {
2427 init_unistr2(&data
, longname
, UNI_STR_TERMINATE
);
2428 fstrcpy(value
.valuename
, SPOOL_REG_SERVERNAME
);
2431 if (strequal(info
[j
].value_name
, SPOOL_REG_SHORTSERVERNAME
)) {
2433 init_unistr2(&data
, global_myname(), UNI_STR_TERMINATE
);
2434 fstrcpy(value
.valuename
, SPOOL_REG_SHORTSERVERNAME
);
2437 value
.type
= REG_SZ
;
2438 value
.size
= data
.uni_str_len
* 2;
2440 value
.data_p
= (uint8_t *)TALLOC_MEMDUP(mem_ctx
, data
.buffer
, value
.size
);
2442 value
.data_p
= NULL
;
2446 display_reg_value(subkey
, value
);
2448 /* here we have to set all subkeys on the dst server */
2449 if (!net_spoolss_setprinterdataex(pipe_hnd_dst
, mem_ctx
, &hnd_dst
,
2458 result
= push_spoolss_PrinterData(mem_ctx
, &blob
,
2461 if (!W_ERROR_IS_OK(result
)) {
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
;
2470 if (c
->opt_verbose
) {
2471 display_reg_value(subkey
, v
);
2474 /* here we have to set all subkeys on the dst server */
2475 if (!net_spoolss_setprinterdataex(pipe_hnd_dst
, mem_ctx
, &hnd_dst
,
2482 DEBUGADD(1,("\tSetPrinterDataEx of key [%s\\%s] succeeded\n",
2483 subkey
, info
[j
].value_name
));
2488 TALLOC_FREE(keylist
);
2490 /* close printer handles here */
2491 if (is_valid_policy_hnd(&hnd_src
)) {
2492 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd_src
, NULL
);
2495 if (is_valid_policy_hnd(&hnd_dst
)) {
2496 rpccli_spoolss_ClosePrinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, NULL
);
2501 nt_status
= NT_STATUS_OK
;
2504 SAFE_FREE(devicename
);
2506 SAFE_FREE(unc_name
);
2508 if (is_valid_policy_hnd(&hnd_src
))
2509 rpccli_spoolss_ClosePrinter(pipe_hnd
, mem_ctx
, &hnd_src
, NULL
);
2511 if (is_valid_policy_hnd(&hnd_dst
))
2512 rpccli_spoolss_ClosePrinter(pipe_hnd_dst
, mem_ctx
, &hnd_dst
, NULL
);
2515 cli_shutdown(cli_dst
);