along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "system/filesys.h"
#include "utils/net.h"
+#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 "registry/reg_objects.h"
#include "../libcli/security/security.h"
+#include "../libcli/registry/util_reg.h"
+#include "libsmb/libsmb.h"
/* support itanium as well */
static const struct print_architecture_table_node archi_table[]= {
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++) {
+ for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
printf(_("\tDependentfiles: [%s]\n"), r->dependent_files[i]);
}
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;
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;
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) {
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) {
- NTSTATUS status;
-
/* set acls */
- status = cli_set_secdesc(cli_share_dst, fnum_dst, sd);
- if (!NT_STATUS_IS_OK(status)) {
+ 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(status)));
- nt_status = status;
+ 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))) {
+ 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", cli_errstr(cli_share_src));
- nt_status = cli_nt_error(cli_share_src);
+ is_file?"file":"dir", nt_errstr(nt_status));
goto out;
}
- if (!NT_STATUS_IS_OK(cli_close(cli_share_dst, fnum_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", cli_errstr(cli_share_dst));
- nt_status = cli_nt_error(cli_share_dst);
+ is_file?"file":"dir", nt_errstr(nt_status));
goto out;
}
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;
}
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;
}
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,
+ cli_state_remote_name(cli_share_src),
+ cli_share_src->share, src_name,
+ cli_state_remote_name(cli_share_dst),
+ 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"),
+ cli_state_remote_name(cli_share_src),
+ 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"),
+ cli_state_remote_name(cli_share_dst),
+ cli_share_dst->share,
+ dst_name, nt_errstr(nt_status));
goto out;
}
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))) {
+
+ 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, cli_errstr(cli_share_dst));
+ dst_name, nt_errstr(nt_status));
goto out;
}
}
/* closing files */
- if (!NT_STATUS_IS_OK(cli_close(cli_share_src, fnum_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"),
- cli_errstr(cli_share_src));
- nt_status = cli_nt_error(cli_share_src);
+ nt_errstr(nt_status));
goto out;
}
- if (is_file && !NT_STATUS_IS_OK(cli_close(cli_share_dst, fnum_dst))) {
- d_fprintf(stderr,
+ 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"),
- cli_errstr(cli_share_dst));
- nt_status = cli_nt_error(cli_share_dst);
- goto out;
+ nt_errstr(nt_status));
+ goto out;
+ }
}
/* possibly we have to copy some file-attributes / acls / sd */
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))) {
+ nt_status = cli_chkpath(cli_share, dir);
+ if (!NT_STATUS_IS_OK(nt_status)) {
d_fprintf(stderr, _("cannot check %s: %s\n"),
- dir, cli_errstr(cli_share));
+ dir, nt_errstr(nt_status));
goto out;
}
break;
default:
action_str = N_("unknown action");
- printf(_("unkown action: %d\n"), action);
+ printf(_("unknown action: %d\n"), action);
break;
}
sharename);
break;
default:
- printf(_("unkown state: %d\n"), state);
+ printf(_("unknown state: %d\n"), state);
break;
}
}
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,
+ cli_state_remote_sockaddr(cli),
+ cli_state_remote_name(cli),
+ "print$", "A:");
if (!NT_STATUS_IS_OK(nt_status))
goto done;
/* 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,
+ cli_state_remote_sockaddr(cli_dst),
+ cli_state_remote_name(cli_dst),
+ "print$", "A:");
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
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;
/* 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;
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 = dcerpc_spoolss_EnumPrinterData(b_src, 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 = dcerpc_spoolss_EnumPrinterData(b_src, mem_ctx,
- &hnd_src,
- p++,
- value_name,
- value_offered,
- &value_needed,
- &type,
- buffer,
- data_offered,
- &data_needed,
- &result);
+ while (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(r.out.result)) {
+
+ r.in.enum_index++;
+
+ 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(result)) {
+ if (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(r.out.result)) {
/* display_value */
if (c->opt_verbose) {
struct regval_blob *v;
v = regval_compose(talloc_tos(),
- value_name,
- type,
- buffer,
- data_offered);
+ r.out.value_name,
+ *r.out.type,
+ r.out.data,
+ r.in.data_offered);
if (v == NULL) {
nt_status = NT_STATUS_NO_MEMORY;
goto done;
/* set_value */
if (!net_spoolss_setprinterdata(pipe_hnd_dst, mem_ctx,
- &hnd_dst, value_name,
- type, buffer, data_offered))
+ &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",
- value_name));
+ r.out.value_name));
}
}
if (strequal(info[j].value_name, SPOOL_REG_SHORTSERVERNAME)) {
- push_reg_sz(mem_ctx, &blob, global_myname());
+ push_reg_sz(mem_ctx, &blob, lp_netbios_name());
}
value = regval_compose(talloc_tos(),