X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=source3%2Futils%2Fnet_rpc_printer.c;h=0ab08efcc0a1981e575c3d4ea1aab684eb11f5ac;hp=3914a42aded14dc06b9c25cd846f788f21119ccb;hb=4f6f4ea93c83fa5154f450e2e43649467e4c2b32;hpb=606edf0f350000978a437ddfb7c23525a16d9854 diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index 3914a42aded..0ab08efcc0a 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -17,17 +17,21 @@ along with this program. If not, see . */ #include "includes.h" +#include "system/filesys.h" #include "utils/net.h" - -struct table_node { - const char *long_archi; - const char *short_archi; - int version; -}; - +#include "rpc_client/rpc_client.h" +#include "../librpc/gen_ndr/ndr_spoolss_c.h" +#include "rpc_client/cli_spoolss.h" +#include "rpc_client/init_spoolss.h" +#include "nt_printing.h" +#include "registry.h" +#include "../libcli/security/security.h" +#include "../libcli/registry/util_reg.h" +#include "libsmb/libsmb.h" +#include "../libcli/smb/smbXcli_base.h" /* support itanium as well */ -static const struct table_node archi_table[]= { +static const struct print_architecture_table_node archi_table[]= { {"Windows 4.0", "WIN40", 0 }, {"Windows NT x86", "W32X86", 2 }, @@ -58,64 +62,65 @@ static void display_print_driver3(struct spoolss_DriverInfo3 *r) return; } - printf("Printer Driver Info 3:\n"); - printf("\tVersion: [%x]\n", r->version); - printf("\tDriver Name: [%s]\n", r->driver_name); - printf("\tArchitecture: [%s]\n", r->architecture); - printf("\tDriver Path: [%s]\n", r->driver_path); - printf("\tDatafile: [%s]\n", r->data_file); - printf("\tConfigfile: [%s]\n\n", r->config_file); - printf("\tHelpfile: [%s]\n\n", r->help_file); + printf(_("Printer Driver Info 3:\n")); + printf(_("\tVersion: [%x]\n"), r->version); + printf(_("\tDriver Name: [%s]\n"), r->driver_name); + printf(_("\tArchitecture: [%s]\n"), r->architecture); + printf(_("\tDriver Path: [%s]\n"), r->driver_path); + printf(_("\tDatafile: [%s]\n"), r->data_file); + printf(_("\tConfigfile: [%s]\n\n"), r->config_file); + printf(_("\tHelpfile: [%s]\n\n"), r->help_file); - for (i=0; r->dependent_files[i] != NULL; i++) { - printf("\tDependentfiles: [%s]\n", r->dependent_files[i]); + for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) { + printf(_("\tDependentfiles: [%s]\n"), r->dependent_files[i]); } printf("\n"); - printf("\tMonitorname: [%s]\n", r->monitor_name); - printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype); + printf(_("\tMonitorname: [%s]\n"), r->monitor_name); + printf(_("\tDefaultdatatype: [%s]\n\n"), r->default_datatype); } -static void display_reg_value(const char *subkey, struct regval_blob value) +static void display_reg_value(const char *subkey, const char *name, struct registry_value *value) { - char *text; + const char *text; - switch(value.type) { + switch(value->type) { case REG_DWORD: - d_printf("\t[%s:%s]: REG_DWORD: 0x%08x\n", subkey, value.valuename, - *((uint32_t *) value.data_p)); + if (value->data.length == sizeof(uint32)) { + d_printf(_("\t[%s:%s]: REG_DWORD: 0x%08x\n"), subkey, + name, IVAL(value->data.data,0)); + } else { + d_printf(_("\t[%s:%s]: REG_DWORD: \n"), subkey, + name); + } break; case REG_SZ: - rpcstr_pull_talloc(talloc_tos(), - &text, - value.data_p, - value.size, - STR_TERMINATE); + pull_reg_sz(talloc_tos(), &value->data, &text); if (!text) { break; } - d_printf("\t[%s:%s]: REG_SZ: %s\n", subkey, value.valuename, text); + d_printf(_("\t[%s:%s]: REG_SZ: %s\n"), subkey, name, text); break; case REG_BINARY: - d_printf("\t[%s:%s]: REG_BINARY: unknown length value not displayed\n", - subkey, value.valuename); + d_printf(_("\t[%s:%s]: REG_BINARY: unknown length value not " + "displayed\n"), + subkey, name); break; case REG_MULTI_SZ: { - uint32_t i, num_values; - char **values; + uint32_t i; + const char **values; - if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p, - value.size, &num_values, - &values))) { - d_printf("reg_pull_multi_sz failed\n"); + if (!pull_reg_multi_sz(NULL, &value->data, &values)) { + d_printf("pull_reg_multi_sz failed\n"); break; } - for (i=0; itype); } } @@ -154,14 +159,13 @@ NTSTATUS net_copy_fileattr(struct net_context *c, bool copy_acls, bool copy_attrs, bool copy_timestamps, bool is_file) { - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + NTSTATUS nt_status; uint16_t fnum_src = 0; uint16_t fnum_dst = 0; - SEC_DESC *sd = NULL; + struct security_descriptor *sd = NULL; uint16_t attr; time_t f_atime, f_ctime, f_mtime; - if (!copy_timestamps && !copy_acls && !copy_attrs) return NT_STATUS_OK; @@ -170,23 +174,23 @@ NTSTATUS net_copy_fileattr(struct net_context *c, DEBUGADD(3,("opening %s %s on originating server\n", is_file?"file":"dir", src_name)); - if (!NT_STATUS_IS_OK(cli_ntcreate(cli_share_src, src_name, 0, READ_CONTROL_ACCESS, 0, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum_src))) { + nt_status = cli_ntcreate(cli_share_src, src_name, 0, + READ_CONTROL_ACCESS, 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, + 0x0, 0x0, &fnum_src); + if (!NT_STATUS_IS_OK(nt_status)) { DEBUGADD(0,("cannot open %s %s on originating server %s\n", - is_file?"file":"dir", src_name, cli_errstr(cli_share_src))); - nt_status = cli_nt_error(cli_share_src); + is_file?"file":"dir", src_name, nt_errstr(nt_status))); goto out; } - if (copy_acls) { - /* get the security descriptor */ - sd = cli_query_secdesc(cli_share_src, fnum_src, mem_ctx); - if (!sd) { + nt_status = cli_query_secdesc(cli_share_src, fnum_src, + mem_ctx, &sd); + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("failed to get security descriptor: %s\n", - cli_errstr(cli_share_src))); - nt_status = cli_nt_error(cli_share_src); + nt_errstr(nt_status))); goto out; } @@ -194,77 +198,74 @@ NTSTATUS net_copy_fileattr(struct net_context *c, display_sec_desc(sd); } - if (copy_attrs || copy_timestamps) { /* get file attributes */ - if (!NT_STATUS_IS_OK(cli_getattrE(cli_share_src, fnum_src, &attr, NULL, - &f_ctime, &f_atime, &f_mtime))) { + nt_status = cli_getattrE(cli_share_src, fnum_src, &attr, NULL, + &f_ctime, &f_atime, &f_mtime); + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("failed to get file-attrs: %s\n", - cli_errstr(cli_share_src))); - nt_status = cli_nt_error(cli_share_src); + nt_errstr(nt_status))); goto out; } } - /* open the file/dir on the destination server */ - - if (!NT_STATUS_IS_OK(cli_ntcreate(cli_share_dst, dst_name, 0, WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS, 0, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum_dst))) { + nt_status = cli_ntcreate(cli_share_dst, dst_name, 0, + WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS, 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, + 0x0, 0x0, &fnum_dst); + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("failed to open %s on the destination server: %s: %s\n", - is_file?"file":"dir", dst_name, cli_errstr(cli_share_dst))); - nt_status = cli_nt_error(cli_share_dst); + is_file?"file":"dir", dst_name, nt_errstr(nt_status))); goto out; } if (copy_timestamps) { - /* set timestamps */ - if (!NT_STATUS_IS_OK(cli_setattrE(cli_share_dst, fnum_dst, f_ctime, f_atime, f_mtime))) { + nt_status = cli_setattrE(cli_share_dst, fnum_dst, f_ctime, f_atime, f_mtime); + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("failed to set file-attrs (timestamps): %s\n", - cli_errstr(cli_share_dst))); - nt_status = cli_nt_error(cli_share_dst); + nt_errstr(nt_status))); goto out; } } if (copy_acls) { - /* set acls */ - if (!cli_set_secdesc(cli_share_dst, fnum_dst, sd)) { - DEBUG(0,("could not set secdesc on %s: %s\n", - dst_name, cli_errstr(cli_share_dst))); - nt_status = cli_nt_error(cli_share_dst); + nt_status = cli_set_secdesc(cli_share_dst, fnum_dst, sd); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("could not set secdesc on %s: %s\n", + dst_name, nt_errstr(nt_status))); goto out; } } if (copy_attrs) { - /* set attrs */ - if (!NT_STATUS_IS_OK(cli_setatr(cli_share_dst, dst_name, attr, 0))) { + nt_status = cli_setatr(cli_share_dst, dst_name, attr, 0); + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("failed to set file-attrs: %s\n", - cli_errstr(cli_share_dst))); - nt_status = cli_nt_error(cli_share_dst); + nt_errstr(nt_status))); goto out; } } /* closing files */ - - if (!NT_STATUS_IS_OK(cli_close(cli_share_src, fnum_src))) { - d_fprintf(stderr, "could not close %s on originating server: %s\n", - is_file?"file":"dir", cli_errstr(cli_share_src)); - nt_status = cli_nt_error(cli_share_src); + nt_status = cli_close(cli_share_src, fnum_src); + if (!NT_STATUS_IS_OK(nt_status)) { + d_fprintf(stderr, + _("could not close %s on originating server: %s\n"), + is_file?"file":"dir", nt_errstr(nt_status)); goto out; } - if (!NT_STATUS_IS_OK(cli_close(cli_share_dst, fnum_dst))) { - d_fprintf(stderr, "could not close %s on destination server: %s\n", - is_file?"file":"dir", cli_errstr(cli_share_dst)); - nt_status = cli_nt_error(cli_share_dst); + nt_status = cli_close(cli_share_dst, fnum_dst); + if (!NT_STATUS_IS_OK(nt_status)) { + d_fprintf(stderr, + _("could not close %s on destination server: %s\n"), + is_file?"file":"dir", nt_errstr(nt_status)); goto out; } @@ -335,7 +336,7 @@ NTSTATUS net_copy_file(struct net_context *c, if (!NT_STATUS_IS_OK(nt_status)) { DEBUGADD(0,("cannot open %s %s on originating server %s\n", is_file ? "file":"dir", - src_name, cli_errstr(cli_share_src))); + src_name, nt_errstr(nt_status))); goto out; } @@ -349,13 +350,14 @@ NTSTATUS net_copy_file(struct net_context *c, if (!NT_STATUS_IS_OK(nt_status)) { DEBUGADD(1,("cannot create file %s on destination server: %s\n", - dst_name, cli_errstr(cli_share_dst))); + dst_name, nt_errstr(nt_status))); goto out; } /* allocate memory */ if (!(data = (char *)SMB_MALLOC(read_size))) { - d_fprintf(stderr, "malloc fail for size %d\n", read_size); + d_fprintf(stderr, _("malloc fail for size %d\n"), + read_size); nt_status = NT_STATUS_NO_MEMORY; goto out; } @@ -365,33 +367,46 @@ NTSTATUS net_copy_file(struct net_context *c, if (c->opt_verbose) { - d_printf("copying [\\\\%s\\%s%s] => [\\\\%s\\%s%s] " - "%s ACLs and %s DOS Attributes %s\n", - cli_share_src->desthost, cli_share_src->share, src_name, - cli_share_dst->desthost, cli_share_dst->share, dst_name, - copy_acls ? "with" : "without", - copy_attrs ? "with" : "without", - copy_timestamps ? "(preserving timestamps)" : "" ); + d_printf(_("copying [\\\\%s\\%s%s] => [\\\\%s\\%s%s] " + "%s ACLs and %s DOS Attributes %s\n"), + smbXcli_conn_remote_name(cli_share_src->conn), + cli_share_src->share, src_name, + smbXcli_conn_remote_name(cli_share_dst->conn), + cli_share_dst->share, dst_name, + copy_acls ? _("with") : _("without"), + copy_attrs ? _("with") : _("without"), + copy_timestamps ? _("(preserving timestamps)") : "" ); } while (is_file) { /* copying file */ - int n, ret; - n = cli_read(cli_share_src, fnum_src, data, nread, - read_size); + size_t n; - if (n <= 0) + nt_status = cli_read(cli_share_src, fnum_src, data, nread, + read_size, &n); + if (!NT_STATUS_IS_OK(nt_status)) { + d_fprintf(stderr, + _("Error reading file [\\\\%s\\%s%s]: %s\n"), + smbXcli_conn_remote_name(cli_share_src->conn), + cli_share_src->share, + src_name, nt_errstr(nt_status)); + goto out; + } + + if (n == 0) break; - ret = cli_write(cli_share_dst, fnum_dst, 0, data, - nread, n); + nt_status = cli_writeall(cli_share_dst, fnum_dst, 0, + (uint8_t *)data, nread, n, NULL); - if (n != ret) { - d_fprintf(stderr, "Error writing file: %s\n", - cli_errstr(cli_share_dst)); - nt_status = cli_nt_error(cli_share_dst); + if (!NT_STATUS_IS_OK(nt_status)) { + d_fprintf(stderr, + _("Error writing file: [\\\\%s\\%s%s]: %s\n"), + smbXcli_conn_remote_name(cli_share_dst->conn), + cli_share_dst->share, + dst_name, nt_errstr(nt_status)); goto out; } @@ -405,33 +420,41 @@ NTSTATUS net_copy_file(struct net_context *c, DEBUGADD(3,("creating dir %s on the destination server\n", dst_name)); - if (!NT_STATUS_IS_OK(cli_mkdir(cli_share_dst, dst_name))) { + nt_status = cli_mkdir(cli_share_dst, dst_name); + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("cannot create directory %s: %s\n", - dst_name, cli_errstr(cli_share_dst))); + dst_name, nt_errstr(nt_status))); nt_status = NT_STATUS_NO_SUCH_FILE; } - if (!NT_STATUS_IS_OK(cli_chkpath(cli_share_dst, dst_name))) { - d_fprintf(stderr, "cannot check for directory %s: %s\n", - dst_name, cli_errstr(cli_share_dst)); + + nt_status = cli_chkpath(cli_share_dst, dst_name); + if (!NT_STATUS_IS_OK(nt_status)) { + d_fprintf(stderr, + _("cannot check for directory %s: %s\n"), + dst_name, nt_errstr(nt_status)); goto out; } } /* closing files */ - if (!NT_STATUS_IS_OK(cli_close(cli_share_src, fnum_src))) { - d_fprintf(stderr, "could not close file on originating server: %s\n", - cli_errstr(cli_share_src)); - nt_status = cli_nt_error(cli_share_src); + nt_status = cli_close(cli_share_src, fnum_src); + if (!NT_STATUS_IS_OK(nt_status)) { + d_fprintf(stderr, + _("could not close file on originating server: %s\n"), + nt_errstr(nt_status)); goto out; } - if (is_file && !NT_STATUS_IS_OK(cli_close(cli_share_dst, fnum_dst))) { - d_fprintf(stderr, "could not close file on destination server: %s\n", - cli_errstr(cli_share_dst)); - nt_status = cli_nt_error(cli_share_dst); - goto out; + if (is_file) { + nt_status = cli_close(cli_share_dst, fnum_dst); + if (!NT_STATUS_IS_OK(nt_status)) { + d_fprintf(stderr, + _("could not close file on destination server: %s\n"), + nt_errstr(nt_status)); + goto out; + } } /* possibly we have to copy some file-attributes / acls / sd */ @@ -485,12 +508,11 @@ static NTSTATUS net_copy_driverfile(struct net_context *c, struct cli_state *cli_share_dst, const char *file, const char *short_archi) { - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; const char *p; char *src_name; char *dst_name; - char *version; - char *filename; + char *version = NULL; + char *filename = NULL; char *tok; if (!file) { @@ -507,29 +529,27 @@ static NTSTATUS net_copy_driverfile(struct net_context *c, } } + if (version == NULL || filename == NULL) { + return NT_STATUS_UNSUCCESSFUL; + } + /* build source file name */ - if (asprintf(&src_name, "\\%s\\%s\\%s", short_archi, version, filename) < 0 ) + src_name = talloc_asprintf(mem_ctx, "\\%s\\%s\\%s", + short_archi, version, filename); + if (src_name == NULL) { return NT_STATUS_NO_MEMORY; - + } /* create destination file name */ - if (asprintf(&dst_name, "\\%s\\%s", short_archi, filename) < 0 ) - return NT_STATUS_NO_MEMORY; + dst_name = talloc_asprintf(mem_ctx, "\\%s\\%s", short_archi, filename); + if (dst_name == NULL) { + return NT_STATUS_NO_MEMORY; + } /* finally copy the file */ - nt_status = net_copy_file(c, mem_ctx, cli_share_src, cli_share_dst, - src_name, dst_name, false, false, false, true); - if (!NT_STATUS_IS_OK(nt_status)) - goto out; - - nt_status = NT_STATUS_OK; - -out: - SAFE_FREE(src_name); - SAFE_FREE(dst_name); - - return nt_status; + return net_copy_file(c, mem_ctx, cli_share_src, cli_share_dst, + src_name, dst_name, false, false, false, true); } /** @@ -554,15 +574,16 @@ static NTSTATUS check_arch_dir(struct cli_state *cli_share, const char *short_ar DEBUG(10,("creating print-driver dir for architecture: %s\n", short_archi)); - if (!NT_STATUS_IS_OK(cli_mkdir(cli_share, dir))) { + nt_status = cli_mkdir(cli_share, dir); + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1,("cannot create directory %s: %s\n", - dir, cli_errstr(cli_share))); - nt_status = NT_STATUS_NO_SUCH_FILE; + dir, nt_errstr(nt_status))); } - if (!NT_STATUS_IS_OK(cli_chkpath(cli_share, dir))) { - d_fprintf(stderr, "cannot check %s: %s\n", - dir, cli_errstr(cli_share)); + nt_status = cli_chkpath(cli_share, dir); + if (!NT_STATUS_IS_OK(nt_status)) { + d_fprintf(stderr, _("cannot check %s: %s\n"), + dir, nt_errstr(nt_status)); goto out; } @@ -602,7 +623,8 @@ static NTSTATUS copy_print_driver_3(struct net_context *c, } if (c->opt_verbose) - d_printf("copying driver: [%s], for architecture: [%s], version: [%d]\n", + d_printf(_("copying driver: [%s], for architecture: [%s], " + "version: [%d]\n"), r->driver_name, short_archi, r->version); nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst, @@ -670,7 +692,7 @@ static bool net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd, num_printers, info); if (!W_ERROR_IS_OK(result)) { - printf("cannot enum printers: %s\n", win_errstr(result)); + printf(_("cannot enum printers: %s\n"), win_errstr(result)); return false; } @@ -702,13 +724,15 @@ static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd, /* be more verbose */ if (W_ERROR_V(result) == W_ERROR_V(WERR_ACCESS_DENIED)) { - d_fprintf(stderr, "no access to printer [%s] on [%s] for user [%s] granted\n", + d_fprintf(stderr, + _("no access to printer [%s] on [%s] for user [%s] " + "granted\n"), printername2, pipe_hnd->srv_name_slash, username); return false; } if (!W_ERROR_IS_OK(result)) { - d_fprintf(stderr, "cannot open printer %s on server %s: %s\n", + d_fprintf(stderr,_("cannot open printer %s on server %s: %s\n"), printername2, pipe_hnd->srv_name_slash, win_errstr(result)); return false; } @@ -734,7 +758,7 @@ static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd, 0, /* offered */ info); if (!W_ERROR_IS_OK(result)) { - printf("cannot get printer-info: %s\n", win_errstr(result)); + printf(_("cannot get printer-info: %s\n"), win_errstr(result)); return false; } @@ -747,9 +771,11 @@ static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd, uint32_t level, union spoolss_PrinterInfo *info) { + struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; WERROR result; NTSTATUS status; struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_SetPrinterInfo2 info2; struct spoolss_DevmodeContainer devmode_ctr; struct sec_desc_buf secdesc_ctr; @@ -769,8 +795,8 @@ static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd, (void *)&info->info1; break; case 2: - info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *) - (void *)&info->info2; + spoolss_printerinfo2_to_setprinterinfo2(&info->info2, &info2); + info_ctr.info.info2 = &info2; break; case 3: info_ctr.info.info3 = (struct spoolss_SetPrinterInfo3 *) @@ -806,16 +832,19 @@ static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd, break; /* FIXME */ } - status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx, + status = dcerpc_spoolss_SetPrinter(b, mem_ctx, hnd, &info_ctr, &devmode_ctr, &secdesc_ctr, 0, /* command */ &result); - + if (!NT_STATUS_IS_OK(status)) { + printf(_("cannot set printer-info: %s\n"), nt_errstr(status)); + return false; + } if (!W_ERROR_IS_OK(result)) { - printf("cannot set printer-info: %s\n", win_errstr(result)); + printf(_("cannot set printer-info: %s\n"), win_errstr(result)); return false; } @@ -828,22 +857,29 @@ static bool net_spoolss_setprinterdata(struct rpc_pipe_client *pipe_hnd, struct policy_handle *hnd, const char *value_name, enum winreg_Type type, - union spoolss_PrinterData data) + uint8_t *data, + uint32_t offered) { + struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; WERROR result; NTSTATUS status; /* setprinterdata call */ - status = rpccli_spoolss_SetPrinterData(pipe_hnd, mem_ctx, + status = dcerpc_spoolss_SetPrinterData(b, mem_ctx, hnd, value_name, type, data, - 0, /* autocalculated */ + offered, &result); - + if (!NT_STATUS_IS_OK(status)) { + printf (_("unable to set printerdata: %s\n"), + nt_errstr(status)); + return false; + } if (!W_ERROR_IS_OK(result)) { - printf ("unable to set printerdata: %s\n", win_errstr(result)); + printf (_("unable to set printerdata: %s\n"), + win_errstr(result)); return false; } @@ -863,7 +899,7 @@ static bool net_spoolss_enumprinterkey(struct rpc_pipe_client *pipe_hnd, result = rpccli_spoolss_enumprinterkey(pipe_hnd, mem_ctx, hnd, keyname, keylist, 0); if (!W_ERROR_IS_OK(result)) { - printf("enumprinterkey failed: %s\n", win_errstr(result)); + printf(_("enumprinterkey failed: %s\n"), win_errstr(result)); return false; } @@ -889,7 +925,7 @@ static bool net_spoolss_enumprinterdataex(struct rpc_pipe_client *pipe_hnd, info); if (!W_ERROR_IS_OK(result)) { - printf("enumprinterdataex failed: %s\n", win_errstr(result)); + printf(_("enumprinterdataex failed: %s\n"), win_errstr(result)); return false; } @@ -898,26 +934,33 @@ static bool net_spoolss_enumprinterdataex(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_setprinterdataex(struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, - struct policy_handle *hnd, - const char *keyname, - struct regval_blob *value) + TALLOC_CTX *mem_ctx, + struct policy_handle *hnd, + const char *keyname, + const char *name, + struct registry_value *value) { + struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; WERROR result; NTSTATUS status; /* setprinterdataex call */ - status = rpccli_spoolss_SetPrinterDataEx(pipe_hnd, mem_ctx, + status = dcerpc_spoolss_SetPrinterDataEx(b, mem_ctx, hnd, keyname, - value->valuename, + name, value->type, - value->data_p, - value->size, + value->data.data, + value->data.length, &result); - + if (!NT_STATUS_IS_OK(status)) { + printf(_("could not set printerdataex: %s\n"), + nt_errstr(status)); + return false; + } if (!W_ERROR_IS_OK(result)) { - printf("could not set printerdataex: %s\n", win_errstr(result)); + printf(_("could not set printerdataex: %s\n"), + win_errstr(result)); return false; } @@ -941,7 +984,7 @@ static bool net_spoolss_enumforms(struct rpc_pipe_client *pipe_hnd, num_forms, forms); if (!W_ERROR_IS_OK(result)) { - printf("could not enum forms: %s\n", win_errstr(result)); + printf(_("could not enum forms: %s\n"), win_errstr(result)); return false; } @@ -965,8 +1008,14 @@ static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd, count, info); if (!W_ERROR_IS_OK(result)) { - printf("cannot enum drivers: %s\n", win_errstr(result)); - return false; + if (W_ERROR_V(result) != W_ERROR_V(WERR_INVALID_ENVIRONMENT)) { + printf(_("cannot enum drivers for environment %s: %s\n"), env, + win_errstr(result)); + return false; + } else { + printf(_("Server does not support environment [%s]\n"), + env); + } } return true; @@ -998,7 +1047,8 @@ static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd, env, win_errstr(result))); if (W_ERROR_V(result) != W_ERROR_V(WERR_UNKNOWN_PRINTER_DRIVER) && W_ERROR_V(result) != W_ERROR_V(WERR_INVALID_ENVIRONMENT)) { - printf("cannot get driver: %s\n", win_errstr(result)); + printf(_("cannot get driver: %s\n"), + win_errstr(result)); } return false; } @@ -1011,6 +1061,7 @@ static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, uint32_t level, union spoolss_DriverInfo *info) { + struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; WERROR result; NTSTATUS status; struct spoolss_AddDriverInfoCtr info_ctr; @@ -1027,22 +1078,26 @@ static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd, (void *)&info->info3; break; default: - printf("unsupported info level: %d\n", level); + printf(_("unsupported info level: %d\n"), level); return false; } /* addprinterdriver call */ - status = rpccli_spoolss_AddPrinterDriver(pipe_hnd, mem_ctx, + status = dcerpc_spoolss_AddPrinterDriver(b, mem_ctx, pipe_hnd->srv_name_slash, &info_ctr, &result); + if (!NT_STATUS_IS_OK(status)) { + printf(_("cannot add driver: %s\n"), nt_errstr(status)); + return false; + } /* be more verbose */ if (W_ERROR_V(result) == W_ERROR_V(WERR_ACCESS_DENIED)) { - printf("You are not allowed to add drivers\n"); + printf(_("You are not allowed to add drivers\n")); return false; } if (!W_ERROR_IS_OK(result)) { - printf("cannot add driver: %s\n", win_errstr(result)); + printf(_("cannot add driver: %s\n"), win_errstr(result)); return false; } @@ -1062,7 +1117,9 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, uint32_t *num_printers, union spoolss_PrinterInfo **info_p) { + struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; struct policy_handle hnd; + WERROR werr; /* no arguments given, enumerate all printers */ if (argc == 0) { @@ -1082,12 +1139,17 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, &hnd)) return false; + *info_p = talloc_zero(mem_ctx, union spoolss_PrinterInfo); + if (*info_p == NULL) { + return false; + } + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, *info_p)) { - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); + dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &werr); return false; } - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); + dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &werr); *num_printers = 1; @@ -1116,7 +1178,7 @@ out: **/ NTSTATUS rpc_printer_list_internals(struct net_context *c, - const DOM_SID *domain_sid, + const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, @@ -1142,7 +1204,7 @@ NTSTATUS rpc_printer_list_internals(struct net_context *c, sharename = info[i].info2.sharename; if (printername && sharename) { - d_printf("printer %d: %s, shared as: %s\n", + d_printf(_("printer %d: %s, shared as: %s\n"), i+1, printername, sharename); } } @@ -1168,7 +1230,7 @@ NTSTATUS rpc_printer_list_internals(struct net_context *c, **/ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c, - const DOM_SID *domain_sid, + const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, @@ -1182,7 +1244,7 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c, union spoolss_DriverInfo *info; int d; - printf("listing printer-drivers\n"); + printf(_("listing printer-drivers\n")); for (i=0; archi_table[i].long_archi!=NULL; i++) { @@ -1197,12 +1259,13 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c, } if (num_drivers == 0) { - d_printf ("no drivers found on server for architecture: [%s].\n", + d_printf(_("no drivers found on server for " + "architecture: [%s].\n"), archi_table[i].long_archi); continue; } - d_printf("got %d printer-drivers for architecture: [%s]\n", + d_printf(_("got %d printer-drivers for architecture: [%s]\n"), num_drivers, archi_table[i].long_archi); @@ -1238,6 +1301,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ const char **argv, uint32_t action) { + struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32_t i, num_printers; uint32_t level = 7; @@ -1247,7 +1311,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ struct spoolss_SetPrinterInfoCtr info_ctr; struct spoolss_DevmodeContainer devmode_ctr; struct sec_desc_buf secdesc_ctr; - struct policy_handle hnd; + struct policy_handle hnd = { 0, }; WERROR result; const char *action_str; @@ -1275,17 +1339,17 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ /* check action and set string */ switch (action) { case DSPRINT_PUBLISH: - action_str = "published"; + action_str = N_("published"); break; case DSPRINT_UPDATE: - action_str = "updated"; + action_str = N_("updated"); break; case DSPRINT_UNPUBLISH: - action_str = "unpublished"; + action_str = N_("unpublished"); break; default: - action_str = "unknown action"; - printf("unkown action: %d\n", action); + action_str = N_("unknown action"); + printf(_("unknown action: %d\n"), action); break; } @@ -1297,33 +1361,45 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ ZERO_STRUCT(devmode_ctr); ZERO_STRUCT(secdesc_ctr); - nt_status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx, + nt_status = dcerpc_spoolss_SetPrinter(b, mem_ctx, &hnd, &info_ctr, &devmode_ctr, &secdesc_ctr, 0, /* command */ &result); - - if (!W_ERROR_IS_OK(result) && (W_ERROR_V(result) != W_ERROR_V(WERR_IO_PENDING))) { - printf("cannot set printer-info: %s\n", win_errstr(result)); + if (!NT_STATUS_IS_OK(nt_status)) { + printf(_("cannot set printer-info: %s\n"), + nt_errstr(nt_status)); + goto done; + } + if (!W_ERROR_IS_OK(result) && !W_ERROR_EQUAL(result, WERR_IO_PENDING)) { + if ((action == DSPRINT_UPDATE) && W_ERROR_EQUAL(result, W_ERROR(0x80070002))) { + printf(_("printer not published yet\n")); + } else { + printf(_("cannot set printer-info: %s\n"), + win_errstr(result)); + } + nt_status = werror_to_ntstatus(result); goto done; } - printf("successfully %s printer %s in Active Directory\n", action_str, sharename); + printf(_("successfully %s printer %s in Active Directory\n"), + action_str, sharename); } nt_status = NT_STATUS_OK; done: - if (is_valid_policy_hnd(&hnd)) - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); + if (is_valid_policy_hnd(&hnd)) { + dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result); + } return nt_status; } NTSTATUS rpc_printer_publish_publish_internals(struct net_context *c, - const DOM_SID *domain_sid, + const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, @@ -1335,7 +1411,7 @@ NTSTATUS rpc_printer_publish_publish_internals(struct net_context *c, } NTSTATUS rpc_printer_publish_unpublish_internals(struct net_context *c, - const DOM_SID *domain_sid, + const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, @@ -1347,7 +1423,7 @@ NTSTATUS rpc_printer_publish_unpublish_internals(struct net_context *c, } NTSTATUS rpc_printer_publish_update_internals(struct net_context *c, - const DOM_SID *domain_sid, + const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, @@ -1376,7 +1452,7 @@ NTSTATUS rpc_printer_publish_update_internals(struct net_context *c, **/ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, - const DOM_SID *domain_sid, + const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, @@ -1384,14 +1460,16 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, int argc, const char **argv) { + struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32_t i, num_printers; uint32_t level = 7; const char *printername, *sharename; union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info; - struct policy_handle hnd; + struct policy_handle hnd = { 0, }; int state; + WERROR werr; if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum)) return nt_status; @@ -1421,19 +1499,22 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, state = info.info7.action; switch (state) { case DSPRINT_PUBLISH: - printf("printer [%s] is published", sharename); + printf(_("printer [%s] is published"), + sharename); if (c->opt_verbose) - printf(", guid: %s", info.info7.guid); + printf(_(", guid: %s"),info.info7.guid); printf("\n"); break; case DSPRINT_UNPUBLISH: - printf("printer [%s] is unpublished\n", sharename); + printf(_("printer [%s] is unpublished\n"), + sharename); break; case DSPRINT_UPDATE: - printf("printer [%s] is currently updating\n", sharename); + printf(_("printer [%s] is currently updating\n"), + sharename); break; default: - printf("unkown state: %d\n", state); + printf(_("unknown state: %d\n"), state); break; } } @@ -1441,8 +1522,9 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, nt_status = NT_STATUS_OK; done: - if (is_valid_policy_hnd(&hnd)) - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); + if (is_valid_policy_hnd(&hnd)) { + dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &werr); + } return nt_status; } @@ -1465,7 +1547,7 @@ done: **/ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, - const DOM_SID *domain_sid, + const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, @@ -1473,6 +1555,7 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, int argc, const char **argv) { + struct dcerpc_binding_handle *b_src = pipe_hnd->binding_handle; /* TODO: what now, info2 or info3 ? convince jerry that we should add clientside setacls level 3 at least */ @@ -1482,19 +1565,23 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, uint32_t level = 2; const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; - struct policy_handle hnd_src, hnd_dst; + struct dcerpc_binding_handle *b_dst = NULL; + struct policy_handle hnd_src = { 0, }; + struct policy_handle hnd_dst = { 0, }; union spoolss_PrinterInfo *info_enum; struct cli_state *cli_dst = NULL; union spoolss_PrinterInfo info_src, info_dst; + WERROR werr; DEBUG(3,("copying printer ACLs\n")); /* connect destination PI_SPOOLSS */ nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst, &ndr_table_spoolss.syntax_id); - if (!NT_STATUS_IS_OK(nt_status)) + if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; - + } + b_dst = pipe_hnd_dst->binding_handle; /* enum source printers */ if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) { @@ -1503,7 +1590,7 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, } if (!num_printers) { - printf ("no printers found on server.\n"); + printf (_("no printers found on server.\n")); nt_status = NT_STATUS_OK; goto done; } @@ -1524,7 +1611,7 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, get any real NT_STATUS-codes anymore from now on */ nt_status = NT_STATUS_UNSUCCESSFUL; - d_printf("migrating printer ACLs for: [%s] / [%s]\n", + d_printf(_("migrating printer ACLs for: [%s] / [%s]\n"), printername, sharename); /* according to msdn you have specify these access-rights @@ -1568,11 +1655,11 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, /* close printer handles here */ if (is_valid_policy_hnd(&hnd_src)) { - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); + dcerpc_spoolss_ClosePrinter(b_src, mem_ctx, &hnd_src, &werr); } if (is_valid_policy_hnd(&hnd_dst)) { - rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); + dcerpc_spoolss_ClosePrinter(b_dst, mem_ctx, &hnd_dst, &werr); } } @@ -1582,11 +1669,11 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, done: if (is_valid_policy_hnd(&hnd_src)) { - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); + dcerpc_spoolss_ClosePrinter(b_src, mem_ctx, &hnd_src, &werr); } if (is_valid_policy_hnd(&hnd_dst)) { - rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); + dcerpc_spoolss_ClosePrinter(b_dst, mem_ctx, &hnd_dst, &werr); } if (cli_dst) { @@ -1613,7 +1700,7 @@ done: **/ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, - const DOM_SID *domain_sid, + const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, @@ -1621,6 +1708,7 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, int argc, const char **argv) { + struct dcerpc_binding_handle *b_src = pipe_hnd->binding_handle; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; WERROR result; uint32_t i, f; @@ -1628,7 +1716,9 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, uint32_t level = 1; const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; - struct policy_handle hnd_src, hnd_dst; + struct dcerpc_binding_handle *b_dst = NULL; + struct policy_handle hnd_src = { 0, }; + struct policy_handle hnd_dst = { 0, }; union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info_dst; uint32_t num_forms; @@ -1640,8 +1730,10 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, /* connect destination PI_SPOOLSS */ nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst, &ndr_table_spoolss.syntax_id); - if (!NT_STATUS_IS_OK(nt_status)) + if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; + } + b_dst = pipe_hnd_dst->binding_handle; /* enum src printers */ if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum)) { @@ -1650,7 +1742,7 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, } if (!num_printers) { - printf ("no printers found on server.\n"); + printf (_("no printers found on server.\n")); nt_status = NT_STATUS_OK; goto done; } @@ -1670,7 +1762,7 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, get any real NT_STATUS-codes anymore from now on */ nt_status = NT_STATUS_UNSUCCESSFUL; - d_printf("migrating printer forms for: [%s] / [%s]\n", + d_printf(_("migrating printer forms for: [%s] / [%s]\n"), printername, sharename); @@ -1706,7 +1798,8 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, continue; if (c->opt_verbose) - d_printf("\tmigrating form # %d [%s] of type [%d]\n", + d_printf(_("\tmigrating form # %d [%s] of type " + "[%d]\n"), f, forms[f].info1.form_name, forms[f].info1.flags); @@ -1715,13 +1808,18 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, /* FIXME: there might be something wrong with samba's builtin-forms */ - status = rpccli_spoolss_AddForm(pipe_hnd_dst, mem_ctx, + status = dcerpc_spoolss_AddForm(b_dst, mem_ctx, &hnd_dst, 1, info, &result); + if (!NT_STATUS_IS_OK(status)) { + d_printf(_("\tdcerpc_spoolss_AddForm form %d: [%s] - %s\n"), + f, forms[f].info1.form_name, nt_errstr(status)); + continue; + } if (!W_ERROR_IS_OK(result)) { - d_printf("\tAddForm form %d: [%s] refused.\n", + d_printf(_("\tAddForm form %d: [%s] refused.\n"), f, forms[f].info1.form_name); continue; } @@ -1733,11 +1831,11 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, /* close printer handles here */ if (is_valid_policy_hnd(&hnd_src)) { - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); + dcerpc_spoolss_ClosePrinter(b_src, mem_ctx, &hnd_src, &result); } if (is_valid_policy_hnd(&hnd_dst)) { - rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); + dcerpc_spoolss_ClosePrinter(b_dst, mem_ctx, &hnd_dst, &result); } } @@ -1745,11 +1843,13 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, done: - if (is_valid_policy_hnd(&hnd_src)) - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); + if (is_valid_policy_hnd(&hnd_src)) { + dcerpc_spoolss_ClosePrinter(b_src, mem_ctx, &hnd_src, &result); + } - if (is_valid_policy_hnd(&hnd_dst)) - rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); + if (is_valid_policy_hnd(&hnd_dst)) { + dcerpc_spoolss_ClosePrinter(b_dst, mem_ctx, &hnd_dst, &result); + } if (cli_dst) { cli_shutdown(cli_dst); @@ -1775,7 +1875,7 @@ done: **/ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, - const DOM_SID *domain_sid, + const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, @@ -1783,6 +1883,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, int argc, const char **argv) { + struct dcerpc_binding_handle *b_src = pipe_hnd->binding_handle; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32_t i, p; uint32_t num_printers; @@ -1791,7 +1892,9 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, bool got_src_driver_share = false; bool got_dst_driver_share = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; - struct policy_handle hnd_src, hnd_dst; + struct dcerpc_binding_handle *b_dst = NULL; + struct policy_handle hnd_src = { 0, }; + struct policy_handle hnd_dst = { 0, }; union spoolss_DriverInfo drv_info_src; union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info_dst; @@ -1799,17 +1902,22 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, struct cli_state *cli_share_src = NULL; struct cli_state *cli_share_dst = NULL; const char *drivername = NULL; + WERROR werr; DEBUG(3,("copying printer-drivers\n")); nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst, &ndr_table_spoolss.syntax_id); - if (!NT_STATUS_IS_OK(nt_status)) + if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; + } + b_dst = pipe_hnd_dst->binding_handle; /* open print$-share on the src server */ - nt_status = connect_to_service(c, &cli_share_src, &cli->dest_ss, - cli->desthost, "print$", "A:"); + nt_status = connect_to_service(c, &cli_share_src, + smbXcli_conn_remote_sockaddr(cli->conn), + smbXcli_conn_remote_name(cli->conn), + "print$", "A:"); if (!NT_STATUS_IS_OK(nt_status)) goto done; @@ -1817,8 +1925,10 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, /* open print$-share on the dst server */ - nt_status = connect_to_service(c, &cli_share_dst, &cli_dst->dest_ss, - cli_dst->desthost, "print$", "A:"); + nt_status = connect_to_service(c, &cli_share_dst, + smbXcli_conn_remote_sockaddr(cli_dst->conn), + smbXcli_conn_remote_name(cli_dst->conn), + "print$", "A:"); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; @@ -1832,7 +1942,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, } if (num_printers == 0) { - printf ("no printers found on server.\n"); + printf (_("no printers found on server.\n")); nt_status = NT_STATUS_OK; goto done; } @@ -1854,7 +1964,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, get any real NT_STATUS-codes anymore from now on */ nt_status = NT_STATUS_UNSUCCESSFUL; - d_printf("migrating printer driver for: [%s] / [%s]\n", + d_printf(_("migrating printer driver for: [%s] / [%s]\n"), printername, sharename); /* open dst printer handle */ @@ -1934,12 +2044,12 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, /* close dst */ if (is_valid_policy_hnd(&hnd_dst)) { - rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); + dcerpc_spoolss_ClosePrinter(b_dst, mem_ctx, &hnd_dst, &werr); } /* close src */ if (is_valid_policy_hnd(&hnd_src)) { - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); + dcerpc_spoolss_ClosePrinter(b_src, mem_ctx, &hnd_src, &werr); } } @@ -1947,11 +2057,14 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, done: - if (is_valid_policy_hnd(&hnd_src)) - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); + if (is_valid_policy_hnd(&hnd_dst)) { + dcerpc_spoolss_ClosePrinter(b_dst, mem_ctx, &hnd_dst, &werr); + } - if (is_valid_policy_hnd(&hnd_dst)) - rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); + /* close src */ + if (is_valid_policy_hnd(&hnd_src)) { + dcerpc_spoolss_ClosePrinter(b_src, mem_ctx, &hnd_src, &werr); + } if (cli_dst) { cli_shutdown(cli_dst); @@ -1986,7 +2099,7 @@ done: **/ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, - const DOM_SID *domain_sid, + const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, @@ -1994,6 +2107,7 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, int argc, const char **argv) { + struct dcerpc_binding_handle *b_src = pipe_hnd->binding_handle; WERROR result; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32_t i = 0, num_printers; @@ -2001,9 +2115,11 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, union spoolss_PrinterInfo info_dst, info_src; union spoolss_PrinterInfo *info_enum; struct cli_state *cli_dst = NULL; - struct policy_handle hnd_dst, hnd_src; + struct policy_handle hnd_src = { 0, }; + struct policy_handle hnd_dst = { 0, }; const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; + struct dcerpc_binding_handle *b_dst = NULL; struct spoolss_SetPrinterInfoCtr info_ctr; DEBUG(3,("copying printers\n")); @@ -2011,8 +2127,10 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, /* connect destination PI_SPOOLSS */ nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst, &ndr_table_spoolss.syntax_id); - if (!NT_STATUS_IS_OK(nt_status)) + if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; + } + b_dst = pipe_hnd_dst->binding_handle; /* enum printers */ if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) { @@ -2021,7 +2139,7 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, } if (!num_printers) { - printf ("no printers found on server.\n"); + printf (_("no printers found on server.\n")); nt_status = NT_STATUS_OK; goto done; } @@ -2029,6 +2147,8 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, /* do something for all printers */ for (i = 0; i < num_printers; i++) { + struct spoolss_SetPrinterInfo2 info2; + /* do some initialization */ printername = info_enum[i].info2.printername; sharename = info_enum[i].info2.sharename; @@ -2041,7 +2161,7 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, get any real NT_STATUS-codes anymore from now on */ nt_status = NT_STATUS_UNSUCCESSFUL; - d_printf("migrating printer queue for: [%s] / [%s]\n", + d_printf(_("migrating printer queue for: [%s] / [%s]\n"), printername, sharename); /* open dst printer handle */ @@ -2053,12 +2173,12 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) { - printf ("could not get printer, creating printer.\n"); + printf (_("could not get printer, creating printer.\n")); } else { DEBUG(1,("printer already exists: %s\n", sharename)); /* close printer handle here - dst only, not got src yet. */ if (is_valid_policy_hnd(&hnd_dst)) { - rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); + dcerpc_spoolss_ClosePrinter(b_dst, mem_ctx, &hnd_dst, &result); } continue; } @@ -2077,43 +2197,48 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, /* copy each src printer to a dst printer 1:1, maybe some values have to be changed though */ - d_printf("creating printer: %s\n", printername); + d_printf(_("creating printer: %s\n"), printername); info_ctr.level = level; - info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *) - (void *)&info_src.info2; + spoolss_printerinfo2_to_setprinterinfo2(&info_src.info2, &info2); + info_ctr.info.info2 = &info2; result = rpccli_spoolss_addprinterex(pipe_hnd_dst, mem_ctx, &info_ctr); if (W_ERROR_IS_OK(result)) - d_printf ("printer [%s] successfully added.\n", printername); + d_printf (_("printer [%s] successfully added.\n"), + printername); else if (W_ERROR_V(result) == W_ERROR_V(WERR_PRINTER_ALREADY_EXISTS)) - d_fprintf (stderr, "printer [%s] already exists.\n", printername); + d_fprintf (stderr, _("printer [%s] already exists.\n"), + printername); else { - d_fprintf (stderr, "could not create printer [%s]\n", printername); + d_fprintf (stderr, _("could not create printer [%s]\n"), + printername); goto done; } /* close printer handles here */ if (is_valid_policy_hnd(&hnd_src)) { - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); + dcerpc_spoolss_ClosePrinter(b_src, mem_ctx, &hnd_src, &result); } if (is_valid_policy_hnd(&hnd_dst)) { - rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); + dcerpc_spoolss_ClosePrinter(b_dst, mem_ctx, &hnd_dst, &result); } } nt_status = NT_STATUS_OK; done: - if (is_valid_policy_hnd(&hnd_src)) - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); + if (is_valid_policy_hnd(&hnd_src)) { + dcerpc_spoolss_ClosePrinter(b_src, mem_ctx, &hnd_src, &result); + } - if (is_valid_policy_hnd(&hnd_dst)) - rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); + if (is_valid_policy_hnd(&hnd_dst)) { + dcerpc_spoolss_ClosePrinter(b_dst, mem_ctx, &hnd_dst, &result); + } if (cli_dst) { cli_shutdown(cli_dst); @@ -2140,7 +2265,7 @@ done: **/ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, - const DOM_SID *domain_sid, + const struct dom_sid *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, @@ -2148,22 +2273,24 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, int argc, const char **argv) { + struct dcerpc_binding_handle *b_src = pipe_hnd->binding_handle; /* FIXME: Here the nightmare begins */ WERROR result; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32_t i = 0, p = 0, j = 0; + uint32_t i = 0, j = 0; uint32_t num_printers; uint32_t level = 2; const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; - struct policy_handle hnd_src, hnd_dst; + struct dcerpc_binding_handle *b_dst = NULL; + struct policy_handle hnd_src = { 0, }; + struct policy_handle hnd_dst = { 0, }; union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info_dst_publish; union spoolss_PrinterInfo info_dst; struct cli_state *cli_dst = NULL; - char *devicename = NULL, *unc_name = NULL, *url = NULL; const char *longname; const char **keylist = NULL; @@ -2175,8 +2302,10 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, /* connect destination PI_SPOOLSS */ nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst, &ndr_table_spoolss.syntax_id); - if (!NT_STATUS_IS_OK(nt_status)) + if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; + } + b_dst = pipe_hnd_dst->binding_handle; /* enum src printers */ if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) { @@ -2185,7 +2314,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, } if (!num_printers) { - printf ("no printers found on server.\n"); + printf (_("no printers found on server.\n")); nt_status = NT_STATUS_OK; goto done; } @@ -2201,11 +2330,10 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, /* do something for all printers */ for (i = 0; i < num_printers; i++) { - uint32_t value_offered = 0, value_needed; - uint32_t data_offered = 0, data_needed; + uint32_t value_needed; + uint32_t data_needed; enum winreg_Type type; - uint8_t *buffer = NULL; - const char *value_name = NULL; + struct spoolss_EnumPrinterData r; /* do some initialization */ printername = info_enum[i].info2.printername; @@ -2219,7 +2347,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, get any real NT_STATUS-codes anymore from now on */ nt_status = NT_STATUS_UNSUCCESSFUL; - d_printf("migrating printer settings for: [%s] / [%s]\n", + d_printf(_("migrating printer settings for: [%s] / [%s]\n"), printername, sharename); @@ -2297,70 +2425,53 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, FIXME: IIRC I've seen it too on a win2k-server */ + r.in.handle = &hnd_src; + r.in.enum_index = 0; + r.in.value_offered = 0; + r.in.data_offered = 0; + r.out.value_name = NULL; + r.out.value_needed = &value_needed; + r.out.type = &type; + r.out.data = NULL; + r.out.data_needed = &data_needed; + /* enumerate data on src handle */ - nt_status = rpccli_spoolss_EnumPrinterData(pipe_hnd, mem_ctx, - &hnd_src, - p, - value_name, - value_offered, - &value_needed, - &type, - buffer, - data_offered, - &data_needed, - &result); - - data_offered = data_needed; - value_offered = value_needed; - buffer = talloc_zero_array(mem_ctx, uint8_t, data_needed); - value_name = talloc_zero_array(mem_ctx, char, value_needed); + nt_status = dcerpc_spoolss_EnumPrinterData_r(b_src, mem_ctx, &r); + + r.in.data_offered = *r.out.data_needed; + r.in.value_offered = *r.out.value_needed; + r.out.data = talloc_zero_array(mem_ctx, uint8_t, r.in.data_offered); + r.out.value_name = talloc_zero_array(mem_ctx, char, r.in.value_offered); /* loop for all printerdata of "PrinterDriverData" */ - while (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(result)) { - - nt_status = rpccli_spoolss_EnumPrinterData(pipe_hnd, mem_ctx, - &hnd_src, - p++, - value_name, - value_offered, - &value_needed, - &type, - buffer, - data_offered, - &data_needed, - &result); - /* loop for all reg_keys */ - if (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(result)) { + while (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(r.out.result)) { + + r.in.enum_index++; - struct regval_blob v; - DATA_BLOB blob; - union spoolss_PrinterData printer_data; + nt_status = dcerpc_spoolss_EnumPrinterData_r(b_src, mem_ctx, &r); + + /* loop for all reg_keys */ + if (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(r.out.result)) { /* display_value */ if (c->opt_verbose) { - fstrcpy(v.valuename, value_name); - v.type = type; - v.size = data_offered; - v.data_p = buffer; - display_reg_value(SPOOL_PRINTERDATA_KEY, v); - } + struct registry_value v; + v.type = *r.out.type; + v.data = data_blob_const( + r.out.data, r.in.data_offered); - result = pull_spoolss_PrinterData(mem_ctx, - &blob, - &printer_data, - type); - if (!W_ERROR_IS_OK(result)) { - goto done; + display_reg_value(SPOOL_PRINTERDATA_KEY, + r.out.value_name, &v); } /* set_value */ if (!net_spoolss_setprinterdata(pipe_hnd_dst, mem_ctx, - &hnd_dst, value_name, - type, printer_data)) + &hnd_dst, r.out.value_name, + *r.out.type, r.out.data, r.in.data_offered)) goto done; DEBUGADD(1,("\tSetPrinterData of [%s] succeeded\n", - v.valuename)); + r.out.value_name)); } } @@ -2372,7 +2483,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, in case of an error */ if (!net_spoolss_enumprinterkey(pipe_hnd, mem_ctx, &hnd_src, "", &keylist)) { - printf("got no key-data\n"); + printf(_("got no key-data\n")); continue; } @@ -2399,105 +2510,58 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, for (j=0; j < count; j++) { - struct regval_blob value; - UNISTR2 data; + struct registry_value value; + const char *value_name = info[j].value_name; + value.type = REG_SZ; /* although samba replies with sane data in most cases we should try to avoid writing wrong registry data */ - if (strequal(info[j].value_name, SPOOL_REG_PORTNAME) || - strequal(info[j].value_name, SPOOL_REG_UNCNAME) || - strequal(info[j].value_name, SPOOL_REG_URL) || - strequal(info[j].value_name, SPOOL_REG_SHORTSERVERNAME) || - strequal(info[j].value_name, SPOOL_REG_SERVERNAME)) { - - if (strequal(info[j].value_name, SPOOL_REG_PORTNAME)) { - - /* although windows uses a multi-sz, we use a sz */ - init_unistr2(&data, SAMBA_PRINTER_PORT_NAME, UNI_STR_TERMINATE); - fstrcpy(value.valuename, SPOOL_REG_PORTNAME); - } - - if (strequal(info[j].value_name, SPOOL_REG_UNCNAME)) { - - if (asprintf(&unc_name, "\\\\%s\\%s", longname, sharename) < 0) { - nt_status = NT_STATUS_NO_MEMORY; - goto done; - } - init_unistr2(&data, unc_name, UNI_STR_TERMINATE); - fstrcpy(value.valuename, SPOOL_REG_UNCNAME); + if (strequal(value_name, SPOOL_REG_PORTNAME)) { + /* although windows uses a multi-sz, we use a sz */ + push_reg_sz(mem_ctx, &value.data, SAMBA_PRINTER_PORT_NAME); + } + else if (strequal(value_name, SPOOL_REG_UNCNAME)) { + char *unc_name; + if (asprintf(&unc_name, "\\\\%s\\%s", longname, sharename) < 0) { + nt_status = NT_STATUS_NO_MEMORY; + goto done; } - - if (strequal(info[j].value_name, SPOOL_REG_URL)) { - - continue; - + push_reg_sz(mem_ctx, &value.data, unc_name); + free(unc_name); + } + else if (strequal(value_name, SPOOL_REG_URL)) { + continue; #if 0 - /* FIXME: should we really do that ??? */ - if (asprintf(&url, "http://%s:631/printers/%s", longname, sharename) < 0) { - nt_status = NT_STATUS_NO_MEMORY; - goto done; - } - init_unistr2(&data, url, UNI_STR_TERMINATE); - fstrcpy(value.valuename, SPOOL_REG_URL); -#endif - } - - if (strequal(info[j].value_name, SPOOL_REG_SERVERNAME)) { - - init_unistr2(&data, longname, UNI_STR_TERMINATE); - fstrcpy(value.valuename, SPOOL_REG_SERVERNAME); - } - - if (strequal(info[j].value_name, SPOOL_REG_SHORTSERVERNAME)) { - - init_unistr2(&data, global_myname(), UNI_STR_TERMINATE); - fstrcpy(value.valuename, SPOOL_REG_SHORTSERVERNAME); - } - - value.type = REG_SZ; - value.size = data.uni_str_len * 2; - if (value.size) { - value.data_p = (uint8_t *)TALLOC_MEMDUP(mem_ctx, data.buffer, value.size); - } else { - value.data_p = NULL; - } - - if (c->opt_verbose) - display_reg_value(subkey, value); - - /* here we have to set all subkeys on the dst server */ - if (!net_spoolss_setprinterdataex(pipe_hnd_dst, mem_ctx, &hnd_dst, - subkey, &value)) + /* FIXME: should we really do that ??? */ + if (asprintf(&url, "http://%s:631/printers/%s", longname, sharename) < 0) { + nt_status = NT_STATUS_NO_MEMORY; goto done; - - } else { - - struct regval_blob v; - DATA_BLOB blob; - - result = push_spoolss_PrinterData(mem_ctx, &blob, - info[j].type, - info[j].data); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - fstrcpy(v.valuename, info[j].value_name); - v.type = info[j].type; - v.data_p = blob.data; - v.size = blob.length; - - if (c->opt_verbose) { - display_reg_value(subkey, v); } + push_reg_sz(mem_ctx, NULL, &value.data, url); + free(url); +#endif + } + else if (strequal(value_name, SPOOL_REG_SERVERNAME)) { + push_reg_sz(mem_ctx, &value.data, longname); + } + else if (strequal(value_name, SPOOL_REG_SHORTSERVERNAME)) { + push_reg_sz(mem_ctx, &value.data, lp_netbios_name()); + } + else { + value.type = info[j].type; + value.data = *info[j].data; + } - /* here we have to set all subkeys on the dst server */ - if (!net_spoolss_setprinterdataex(pipe_hnd_dst, mem_ctx, &hnd_dst, - subkey, &v)) { - goto done; - } + if (c->opt_verbose) { + display_reg_value(subkey, value_name, &value); + } + /* here we have to set all subkeys on the dst server */ + if (!net_spoolss_setprinterdataex(pipe_hnd_dst, mem_ctx, &hnd_dst, + subkey, value_name, &value)) + { + goto done; } DEBUGADD(1,("\tSetPrinterDataEx of key [%s\\%s] succeeded\n", @@ -2510,27 +2574,24 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, /* close printer handles here */ if (is_valid_policy_hnd(&hnd_src)) { - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); + dcerpc_spoolss_ClosePrinter(b_src, mem_ctx, &hnd_src, &result); } if (is_valid_policy_hnd(&hnd_dst)) { - rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); + dcerpc_spoolss_ClosePrinter(b_dst, mem_ctx, &hnd_dst, &result); } - } nt_status = NT_STATUS_OK; done: - SAFE_FREE(devicename); - SAFE_FREE(url); - SAFE_FREE(unc_name); - - if (is_valid_policy_hnd(&hnd_src)) - rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); + if (is_valid_policy_hnd(&hnd_src)) { + dcerpc_spoolss_ClosePrinter(b_src, mem_ctx, &hnd_src, &result); + } - if (is_valid_policy_hnd(&hnd_dst)) - rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); + if (is_valid_policy_hnd(&hnd_dst)) { + dcerpc_spoolss_ClosePrinter(b_dst, mem_ctx, &hnd_dst, &result); + } if (cli_dst) { cli_shutdown(cli_dst);