mirror of
https://github.com/samba-team/samba.git
synced 2025-02-22 05:57:43 +03:00
r1692: first commit :)
* add IA64 to the architecture table of printer-drivers * add new "net"-subcommands: net rpc printer migrate {drivers|printers|forms|security|settings|all} [printer] net rpc share migrate {shares|files|all} [share] this is the first part of the migration suite. this will will (once feature-complete) allow to do 1:1 server-cloning in the best possible way by making heavy use of samba's rpc_client-functions. all migration-steps are implemented as rpc/smb-client-calls; net communicates via rpc/smb with two servers at the same time (a remote, source server and a destination server that currently defaults to the local smbd). this allows e. g. printer-driver migration including driverfiles, recursive mirroring of file-shares including file-acls, etc. almost any migration step can be called with a migrate-subcommand to provide more flexibility during a migration process (at the cost of quite some redundancy :) ). "net rpc printer migrate settings" is still in a bad condition (many open questions that hopefully can be adressed soon). "net rpc share migrate security" as an isolated call to just migrate share-ACLs will be added later. Before playing with it, make sure to use a test-server. Migration is a serious business and this tool-set can perfectly overwrite your existing file/print-shares. * along with the migration functions had to make I the following changes: - implement setprinter level 3 client-side - implement net_add_share level 502 client-side - allow security descriptor to be set in setprinterdata level 2 serverside guenther (This used to be commit 8f1716a29b7e85baf738bc14df7dabf03762f723)
This commit is contained in:
parent
16de9d9711
commit
60727acc3b
@ -533,7 +533,7 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \
|
||||
utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \
|
||||
utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \
|
||||
utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \
|
||||
utils/net_status.o
|
||||
utils/net_status.o utils/net_rpc_printer.o
|
||||
|
||||
NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
|
||||
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
|
||||
|
@ -209,6 +209,7 @@ struct table_node {
|
||||
#define SPL_ARCH_W32MIPS "W32MIPS"
|
||||
#define SPL_ARCH_W32ALPHA "W32ALPHA"
|
||||
#define SPL_ARCH_W32PPC "W32PPC"
|
||||
#define SPL_ARCH_IA64 "IA64"
|
||||
|
||||
static const struct table_node archi_table[]= {
|
||||
|
||||
@ -217,6 +218,7 @@ static const struct table_node archi_table[]= {
|
||||
{"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
|
||||
{"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
|
||||
{"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
|
||||
{"Windows IA64", SPL_ARCH_IA64, 3 },
|
||||
{NULL, "", -1 }
|
||||
};
|
||||
|
||||
|
@ -269,7 +269,8 @@ WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
const char *netname, uint32 type,
|
||||
const char *remark, uint32 perms,
|
||||
uint32 max_uses, uint32 num_uses,
|
||||
const char *path, const char *passwd)
|
||||
const char *path, const char *passwd,
|
||||
int level, SEC_DESC *sd)
|
||||
{
|
||||
prs_struct qbuf, rbuf;
|
||||
SRV_Q_NET_SHARE_ADD q;
|
||||
@ -285,7 +286,8 @@ WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
|
||||
|
||||
init_srv_q_net_share_add(&q,cli->srv_name_slash, netname, type, remark,
|
||||
perms, max_uses, num_uses, path, passwd);
|
||||
perms, max_uses, num_uses, path, passwd,
|
||||
level, sd);
|
||||
|
||||
/* Marshall data and send request */
|
||||
|
||||
|
@ -1053,6 +1053,28 @@ BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct
|
||||
*******************************************************************/
|
||||
|
||||
BOOL make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3,
|
||||
PRINTER_INFO_3 *info)
|
||||
{
|
||||
|
||||
SPOOL_PRINTER_INFO_LEVEL_3 *inf;
|
||||
|
||||
/* allocate the necessary memory */
|
||||
if (!(inf=(SPOOL_PRINTER_INFO_LEVEL_3*)talloc(mem_ctx, sizeof(SPOOL_PRINTER_INFO_LEVEL_3)))) {
|
||||
DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
inf->secdesc_ptr = (info->secdesc!=NULL)?1:0;
|
||||
|
||||
*spool_info3 = inf;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* read a structure.
|
||||
@ -4112,6 +4134,20 @@ BOOL make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u,
|
||||
q_u->devmode_ctr.size = 0;
|
||||
q_u->devmode_ctr.devmode = NULL;
|
||||
#endif
|
||||
break;
|
||||
case 3:
|
||||
secdesc = info->printers_3->secdesc;
|
||||
|
||||
make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3);
|
||||
|
||||
q_u->secdesc_ctr = (SEC_DESC_BUF*)malloc(sizeof(SEC_DESC_BUF));
|
||||
if (!q_u->secdesc_ctr)
|
||||
return False;
|
||||
q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
|
||||
q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
|
||||
q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
|
||||
q_u->secdesc_ctr->sec = secdesc;
|
||||
|
||||
break;
|
||||
default:
|
||||
DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
|
||||
@ -7358,7 +7394,7 @@ BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX
|
||||
|
||||
if (!prs_set_offset(ps, end_offset))
|
||||
return False;
|
||||
return True;
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -1456,19 +1456,38 @@ BOOL srv_io_q_net_share_add(const char *desc, SRV_Q_NET_SHARE_ADD *q_n, prs_stru
|
||||
void init_srv_q_net_share_add(SRV_Q_NET_SHARE_ADD *q, const char *srvname,
|
||||
const char *netname, uint32 type, const char *remark,
|
||||
uint32 perms, uint32 max_uses, uint32 num_uses,
|
||||
const char *path, const char *passwd)
|
||||
const char *path, const char *passwd,
|
||||
int level, SEC_DESC *sd)
|
||||
{
|
||||
q->ptr_srv_name = 1;
|
||||
init_unistr2(&q->uni_srv_name, srvname, UNI_STR_TERMINATE);
|
||||
q->info.switch_value = q->info_level = 2;
|
||||
|
||||
q->info.ptr_share_ctr = 1;
|
||||
init_srv_share_info2(&q->info.share.info2.info_2, netname, type,
|
||||
remark, perms, max_uses, num_uses, path, passwd);
|
||||
init_srv_share_info2_str(&q->info.share.info2.info_2_str, netname,
|
||||
remark, path, passwd);
|
||||
q->ptr_err_index = 1;
|
||||
q->err_index = 0;
|
||||
switch(level) {
|
||||
case 502: {
|
||||
size_t sd_size = sec_desc_size(sd);
|
||||
q->ptr_srv_name = 1;
|
||||
init_unistr2(&q->uni_srv_name, srvname, UNI_STR_TERMINATE);
|
||||
q->info.switch_value = q->info_level = level;
|
||||
q->info.ptr_share_ctr = 1;
|
||||
init_srv_share_info502(&q->info.share.info502.info_502, netname, type,
|
||||
remark, perms, max_uses, num_uses, path, passwd, sd, sd_size);
|
||||
init_srv_share_info502_str(&q->info.share.info502.info_502_str, netname,
|
||||
remark, path, passwd, sd, sd_size);
|
||||
q->ptr_err_index = 1;
|
||||
q->err_index = 0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
q->ptr_srv_name = 1;
|
||||
init_unistr2(&q->uni_srv_name, srvname, UNI_STR_TERMINATE);
|
||||
q->info.switch_value = q->info_level = level;
|
||||
q->info.ptr_share_ctr = 1;
|
||||
init_srv_share_info2(&q->info.share.info2.info_2, netname, type,
|
||||
remark, perms, max_uses, num_uses, path, passwd);
|
||||
init_srv_share_info2_str(&q->info.share.info2.info_2_str, netname,
|
||||
remark, path, passwd);
|
||||
q->ptr_err_index = 1;
|
||||
q->err_index = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1972,6 +1972,7 @@ static int get_version_id (char * arch)
|
||||
{"Windows NT R4000", "W32MIPS", 2 },
|
||||
{"Windows NT Alpha_AXP", "W32ALPHA", 2 },
|
||||
{"Windows NT PowerPC", "W32PPC", 2 },
|
||||
{"Windows IA64", "IA64", 3 },
|
||||
{NULL, "", -1 }
|
||||
};
|
||||
|
||||
@ -6220,6 +6221,7 @@ WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SET
|
||||
DEVMODE_CTR devmode_ctr = q_u->devmode_ctr;
|
||||
SEC_DESC_BUF *secdesc_ctr = q_u->secdesc_ctr;
|
||||
uint32 command = q_u->command;
|
||||
WERROR result;
|
||||
|
||||
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
|
||||
|
||||
@ -6233,7 +6235,12 @@ WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SET
|
||||
case 0:
|
||||
return control_printer(handle, command, p);
|
||||
case 2:
|
||||
return update_printer(p, handle, level, info, devmode_ctr.devmode);
|
||||
result = update_printer(p, handle, level, info, devmode_ctr.devmode);
|
||||
if (!W_ERROR_IS_OK(result))
|
||||
return result;
|
||||
if (secdesc_ctr)
|
||||
result = update_printer_sec(handle, level, info, p, secdesc_ctr);
|
||||
return result;
|
||||
case 3:
|
||||
return update_printer_sec(handle, level, info, p,
|
||||
secdesc_ctr);
|
||||
|
@ -39,6 +39,7 @@ static const struct table_node archi_table[]= {
|
||||
{"Windows NT R4000", "W32MIPS", 2 },
|
||||
{"Windows NT Alpha_AXP", "W32ALPHA", 2 },
|
||||
{"Windows NT PowerPC", "W32PPC", 2 },
|
||||
{"Windows IA64", "IA64", 3 },
|
||||
{NULL, "", -1 }
|
||||
};
|
||||
|
||||
@ -1126,6 +1127,13 @@ static WERROR cmd_spoolss_enum_drivers(struct cli_state *cli,
|
||||
cli, mem_ctx, needed, NULL, info_level,
|
||||
archi_table[i].long_archi, &returned, &ctr);
|
||||
|
||||
if (W_ERROR_V(werror) == W_ERROR_V(WERR_INVALID_ENVIRONMENT)) {
|
||||
printf ("Server does not support environment [%s]\n",
|
||||
archi_table[i].long_archi);
|
||||
werror = WERR_OK;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (returned == 0)
|
||||
continue;
|
||||
|
||||
|
@ -78,6 +78,8 @@ BOOL opt_localgroup = False;
|
||||
BOOL opt_domaingroup = False;
|
||||
const char *opt_newntname = "";
|
||||
int opt_rid = 0;
|
||||
int opt_acls = 0;
|
||||
const char *opt_exclude = NULL;
|
||||
|
||||
BOOL opt_have_ip = False;
|
||||
struct in_addr opt_dest_ip;
|
||||
@ -126,12 +128,13 @@ int net_run_function(int argc, const char **argv, struct functable *table,
|
||||
return usage_fn(argc, argv);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
connect to \\server\ipc$
|
||||
connect to \\server\service
|
||||
****************************************************************************/
|
||||
NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
|
||||
const char *server_name)
|
||||
NTSTATUS connect_to_service(struct cli_state **c, struct in_addr *server_ip,
|
||||
const char *server_name,
|
||||
const char *service_name,
|
||||
const char *service_type)
|
||||
{
|
||||
NTSTATUS nt_status;
|
||||
|
||||
@ -144,7 +147,7 @@ NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
|
||||
|
||||
nt_status = cli_full_connection(c, NULL, server_name,
|
||||
server_ip, opt_port,
|
||||
"IPC$", "IPC",
|
||||
service_name, service_type,
|
||||
opt_user_name, opt_workgroup,
|
||||
opt_password, 0, Undefined, NULL);
|
||||
|
||||
@ -171,6 +174,16 @@ NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
connect to \\server\ipc$
|
||||
****************************************************************************/
|
||||
NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
|
||||
const char *server_name)
|
||||
{
|
||||
return connect_to_service(c, server_ip, server_name, "IPC$", "IPC");
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
connect to \\server\ipc$ anonymously
|
||||
****************************************************************************/
|
||||
@ -193,6 +206,40 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect the local server and open a given pipe
|
||||
*
|
||||
* @param cli_local A cli_state to the local spoolss-server
|
||||
* @param pipe The pipe to open
|
||||
* @param got_pipe boolean to that stores if got a pipe
|
||||
*
|
||||
* @return Normal NTSTATUS return.
|
||||
**/
|
||||
NTSTATUS connect_local_pipe(struct cli_state **cli_local, int pipe, BOOL *got_pipe)
|
||||
{
|
||||
NTSTATUS nt_status;
|
||||
extern struct in_addr loopback_ip;
|
||||
char *server_name = strdup("127.0.0.1");
|
||||
struct cli_state *cli_tmp = NULL;
|
||||
|
||||
/* make a connection to smbd via loopback */
|
||||
nt_status = connect_to_ipc(&cli_tmp, &loopback_ip, server_name);
|
||||
if (!NT_STATUS_IS_OK(nt_status))
|
||||
return nt_status;
|
||||
|
||||
if (!cli_nt_session_open(cli_tmp, pipe)) {
|
||||
DEBUG(0, ("couldn't not initialise spoolss pipe\n"));
|
||||
cli_shutdown(cli_tmp);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
*cli_local = cli_tmp;
|
||||
*got_pipe = True;
|
||||
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Use the local machine's password for this session
|
||||
****************************************************************************/
|
||||
@ -690,6 +737,9 @@ static struct functable net_func[] = {
|
||||
{"domain", 'D', POPT_ARG_NONE, &opt_domaingroup},
|
||||
{"ntname", 'N', POPT_ARG_STRING, &opt_newntname},
|
||||
{"rid", 'R', POPT_ARG_INT, &opt_rid},
|
||||
/* Options for 'net rpc share migrate' */
|
||||
{"acls", 'a', POPT_ARG_NONE, &opt_acls},
|
||||
{"exclude", 'e', POPT_ARG_STRING, &opt_exclude},
|
||||
|
||||
POPT_COMMON_SAMBA
|
||||
{ 0, 0, 0, 0}
|
||||
|
@ -62,6 +62,8 @@ extern BOOL opt_localgroup;
|
||||
extern BOOL opt_domaingroup;
|
||||
extern const char *opt_newntname;
|
||||
extern int opt_rid;
|
||||
extern int opt_acls;
|
||||
extern const char *opt_exclude;
|
||||
|
||||
extern BOOL opt_have_ip;
|
||||
extern struct in_addr opt_dest_ip;
|
||||
|
@ -122,13 +122,25 @@ int net_help_share(int argc, const char **argv)
|
||||
"on target server\n\n"
|
||||
"net [<method>] share ADD <name=serverpath> [misc. options] [targets]"
|
||||
"\n\tAdds a share from a server (makes the export active)\n\n"
|
||||
"net [<method>] share DELETE <sharename> [misc. options] [targets]\n"
|
||||
"\n\tDeletes a share from a server (makes the export inactive)\n");
|
||||
"net [<method>] share DELETE <sharename> [misc. options] [targets]"
|
||||
"\n\tDeletes a share from a server (makes the export inactive)\n\n"
|
||||
"net [<method>] share MIGRATE FILES <sharename> [misc. options] [targets]"
|
||||
"\n\tMigrates files from remote to local server\n\n"
|
||||
"net [<method>] share MIGRATE SHARES <sharename> [misc. options] [targets]"
|
||||
"\n\tMigrates shares from remote to local server\n\n"
|
||||
/* "net [<method>] share MIGRATE SECURITY <sharename> [misc. options] [targets]"
|
||||
"\n\tMigrates share-ACLs from remote to local server\n\n" */
|
||||
"net [<method>] share MIGRATE ALL <sharename> [misc. options] [targets]"
|
||||
"\n\tMigrates shares (including directories, files) from remote\n"
|
||||
"\tto local server\n\n"
|
||||
);
|
||||
net_common_methods_usage(argc, argv);
|
||||
net_common_flags_usage(argc, argv);
|
||||
d_printf(
|
||||
"\t-C or --comment=<comment>\tdescriptive comment (for add only)\n"
|
||||
"\t-M or --maxusers=<num>\t\tmax users allowed for share\n");
|
||||
"\t-M or --maxusers=<num>\t\tmax users allowed for share\n"
|
||||
"\t-a or --acls\t\t\tcopies ACLs as well\n"
|
||||
"\t-e or --exclude\t\t\tlist of shares to be excluded from mirroring\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -149,6 +161,31 @@ int net_help_file(int argc, const char **argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_help_printer(int argc, const char **argv)
|
||||
{
|
||||
d_printf("net rpc printer LIST [printer]\n"\
|
||||
"\tlists all printers on print-server\n\n");
|
||||
d_printf("net rpc printer DRIVER [printer]\n"\
|
||||
"\tlists all printer-drivers on print-server\n\n");
|
||||
d_printf("net rpc printer MIGRATE PRINTERS [printer]"\
|
||||
"\n\tmigrates printers from remote to local server\n\n");
|
||||
d_printf("net rpc printer MIGRATE SETTINGS [printer]"\
|
||||
"\n\tmigrates printer-settings from remote to local server\n\n");
|
||||
d_printf("net rpc printer MIGRATE DRIVERS [printer]"\
|
||||
"\n\tmigrates printer-drivers from remote to local server\n\n");
|
||||
d_printf("net rpc printer MIGRATE FORMS [printer]"\
|
||||
"\n\tmigrates printer-forms from remote to local server\n\n");
|
||||
d_printf("net rpc printer MIGRATE SECURITY [printer]"\
|
||||
"\n\tmigrates printer-ACLs from remote to local server\n\n");
|
||||
d_printf("net rpc printer MIGRATE ALL [printer]\n"\
|
||||
"\tmigrates drivers, forms, queues, settings and acls from\n"\
|
||||
"\tremote to local print-server\n\n");
|
||||
net_common_methods_usage(argc, argv);
|
||||
net_common_flags_usage(argc, argv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int net_help_status(int argc, const char **argv)
|
||||
{
|
||||
d_printf(" net status sessions [parseable] "
|
||||
|
@ -2351,6 +2351,7 @@ rpc_share_add_internals(const DOM_SID *domain_sid, const char *domain_name,
|
||||
uint32 type=0; /* only allow disk shares to be added */
|
||||
uint32 num_users=0, perms=0;
|
||||
char *password=NULL; /* don't allow a share password */
|
||||
uint32 level = 2;
|
||||
|
||||
path = strchr(sharename, '=');
|
||||
if (!path)
|
||||
@ -2359,7 +2360,8 @@ rpc_share_add_internals(const DOM_SID *domain_sid, const char *domain_name,
|
||||
|
||||
result = cli_srvsvc_net_share_add(cli, mem_ctx, sharename, type,
|
||||
opt_comment, perms, opt_maxusers,
|
||||
num_users, path, password);
|
||||
num_users, path, password,
|
||||
level, NULL);
|
||||
return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
@ -2491,6 +2493,458 @@ rpc_share_list_internals(const DOM_SID *domain_sid, const char *domain_name,
|
||||
return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate shares from a remote RPC server to the local RPC srever
|
||||
*
|
||||
* All parameters are provided by the run_rpc_command function, except for
|
||||
* argc, argv which are passes through.
|
||||
*
|
||||
* @param domain_sid The domain sid acquired from the remote server
|
||||
* @param cli A cli_state connected to the server.
|
||||
* @param mem_ctx Talloc context, destoyed on completion of the function.
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return Normal NTSTATUS return.
|
||||
**/
|
||||
static NTSTATUS
|
||||
rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain_name,
|
||||
struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
WERROR result;
|
||||
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
SRV_SHARE_INFO_CTR ctr_src;
|
||||
ENUM_HND hnd;
|
||||
uint32 type = 0; /* only allow disk shares to be added */
|
||||
uint32 num_uses = 0, perms = 0, max_uses = 0;
|
||||
char *password = NULL; /* don't allow a share password */
|
||||
uint32 preferred_len = 0xffffffff, i;
|
||||
BOOL got_dst_srvsvc_pipe = False;
|
||||
struct cli_state *cli_dst = NULL;
|
||||
uint32 level = 502; /* includes secdesc */
|
||||
SEC_DESC *share_sd = NULL;
|
||||
|
||||
init_enum_hnd(&hnd, 0);
|
||||
|
||||
result = cli_srvsvc_net_share_enum(
|
||||
cli, mem_ctx, level, &ctr_src, preferred_len, &hnd);
|
||||
if (!W_ERROR_IS_OK(result))
|
||||
goto done;
|
||||
|
||||
/* connect local PI_SRVSVC */
|
||||
nt_status = connect_local_pipe(&cli_dst, PI_SRVSVC, &got_dst_srvsvc_pipe);
|
||||
if (!NT_STATUS_IS_OK(nt_status))
|
||||
return nt_status;
|
||||
|
||||
|
||||
for (i = 0; i < ctr_src.num_entries; i++) {
|
||||
|
||||
fstring netname = "", remark = "", path = "";
|
||||
/* reset error-code */
|
||||
nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
rpcstr_pull_unistr2_fstring(
|
||||
netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
|
||||
rpcstr_pull_unistr2_fstring(
|
||||
remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
|
||||
rpcstr_pull_unistr2_fstring(
|
||||
path, &ctr_src.share.info502[i].info_502_str.uni_path);
|
||||
num_uses = ctr_src.share.info502[i].info_502.num_uses;
|
||||
max_uses = ctr_src.share.info502[i].info_502.max_uses;
|
||||
perms = ctr_src.share.info502[i].info_502.perms;
|
||||
|
||||
|
||||
if (opt_acls)
|
||||
share_sd = dup_sec_desc(
|
||||
mem_ctx, ctr_src.share.info502[i].info_502_str.sd);
|
||||
|
||||
/* since we do not have NetShareGetInfo implemented in samba3 we
|
||||
only can skip inside the enum-ctr_src */
|
||||
if (argc == 1) {
|
||||
char *one_share = talloc_strdup(mem_ctx, argv[0]);
|
||||
if (!strequal(netname, one_share))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip builtin shares */
|
||||
/* FIXME: should print$ be added too ? */
|
||||
if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
|
||||
strequal(netname,"global"))
|
||||
continue;
|
||||
|
||||
/* only work with file-shares */
|
||||
if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
|
||||
d_printf("skipping [%s]. not a file share.\n", netname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!cli_tdis(cli))
|
||||
goto done;
|
||||
|
||||
|
||||
/* finallly add the share on the dst server
|
||||
please note that samba currently does not allow to
|
||||
add a share without existing directory */
|
||||
|
||||
printf("migrating: [%s], path: %s, comment: %s, %s share-ACLs\n",
|
||||
netname, path, remark, opt_acls ? "including" : "without" );
|
||||
|
||||
if (opt_verbose && opt_acls)
|
||||
display_sec_desc(share_sd);
|
||||
|
||||
result = cli_srvsvc_net_share_add(cli_dst, mem_ctx, netname, type,
|
||||
remark, perms, max_uses,
|
||||
num_uses, path, password,
|
||||
level, share_sd);
|
||||
|
||||
if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) {
|
||||
printf("share does already exist\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!W_ERROR_IS_OK(result)) {
|
||||
printf("cannot add share: %s\n", dos_errstr(result));
|
||||
goto done;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nt_status = NT_STATUS_OK;
|
||||
|
||||
done:
|
||||
if (got_dst_srvsvc_pipe) {
|
||||
cli_nt_session_close(cli_dst);
|
||||
cli_shutdown(cli_dst);
|
||||
}
|
||||
|
||||
return nt_status;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate shares from a rpc-server to another
|
||||
*
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return A shell status integer (0 for success)
|
||||
**/
|
||||
static int rpc_share_migrate_shares(int argc, const char **argv)
|
||||
{
|
||||
|
||||
return run_rpc_command(NULL, PI_SRVSVC, 0,
|
||||
rpc_share_migrate_shares_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
typedef struct copy_clistate {
|
||||
TALLOC_CTX *mem_ctx;
|
||||
struct cli_state *cli_share_src;
|
||||
struct cli_state *cli_share_dst;
|
||||
const char *cwd;
|
||||
} copy_clistate;
|
||||
|
||||
|
||||
/**
|
||||
* Copy a file/dir
|
||||
*
|
||||
* @param f file_info
|
||||
* @param mask current search mask
|
||||
* @param state arg-pointer
|
||||
*
|
||||
**/
|
||||
static void copy_fn(file_info *f, const char *mask, void *state)
|
||||
{
|
||||
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
struct copy_clistate *local_state = (struct copy_clistate *)state;
|
||||
fstring filename, new_mask, dir;
|
||||
|
||||
if (strequal(f->name, ".") || strequal(f->name, ".."))
|
||||
return;
|
||||
|
||||
DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
|
||||
|
||||
/* DIRECTORY */
|
||||
if (f->mode & aDIR) {
|
||||
|
||||
DEBUG(3,("got dir: %s\n", f->name));
|
||||
|
||||
fstrcpy(dir, local_state->cwd);
|
||||
fstrcat(dir, "\\");
|
||||
fstrcat(dir, f->name);
|
||||
|
||||
/* create that directory */
|
||||
nt_status = net_copy_file(local_state->mem_ctx,
|
||||
local_state->cli_share_src,
|
||||
local_state->cli_share_dst,
|
||||
dir, dir,
|
||||
opt_acls? True : False, False);
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status))
|
||||
printf("could not copy dir %s: %s\n",
|
||||
dir, nt_errstr(nt_status));
|
||||
|
||||
/* search below that directory */
|
||||
fstrcpy(new_mask, dir);
|
||||
fstrcat(new_mask, "\\*");
|
||||
|
||||
if (!sync_files(local_state->mem_ctx,
|
||||
local_state->cli_share_src,
|
||||
local_state->cli_share_dst,
|
||||
new_mask, dir))
|
||||
|
||||
printf("could not sync files\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* FILE */
|
||||
fstrcpy(filename, local_state->cwd);
|
||||
fstrcat(filename, "\\");
|
||||
fstrcat(filename, f->name);
|
||||
|
||||
DEBUG(3,("got file: %s\n", filename));
|
||||
|
||||
nt_status = net_copy_file(local_state->mem_ctx,
|
||||
local_state->cli_share_src,
|
||||
local_state->cli_share_dst,
|
||||
filename, filename,
|
||||
opt_acls? True : False, True);
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status))
|
||||
printf("could not copy file %s: %s\n",
|
||||
filename, nt_errstr(nt_status));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* sync files, can be called recursivly to list files
|
||||
* and then call copy_fn for each file
|
||||
*
|
||||
* @param mem_ctx TALLOC_CTX
|
||||
* @param cli_share_src a connected share on the originating server
|
||||
* @param cli_share_dst a connected share on the destination server
|
||||
* @param mask the current search mask
|
||||
* @param cwd the current path
|
||||
*
|
||||
* @return Boolean result
|
||||
**/
|
||||
BOOL sync_files(TALLOC_CTX *mem_ctx,
|
||||
struct cli_state *cli_share_src,
|
||||
struct cli_state *cli_share_dst,
|
||||
pstring mask, fstring cwd)
|
||||
|
||||
{
|
||||
|
||||
uint16 attribute = aSYSTEM | aHIDDEN | aDIR;
|
||||
struct copy_clistate clistate;
|
||||
|
||||
clistate.mem_ctx = mem_ctx;
|
||||
clistate.cli_share_src = cli_share_src;
|
||||
clistate.cli_share_dst = cli_share_dst;
|
||||
clistate.cwd = cwd;
|
||||
|
||||
DEBUG(3,("calling cli_list with mask: %s\n", mask));
|
||||
|
||||
if (cli_list(cli_share_src, mask, attribute, copy_fn, &clistate) == -1) {
|
||||
d_printf("listing %s failed with error: %s\n",
|
||||
mask, cli_errstr(cli_share_src));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sync all files inside a remote share to another share (over smb)
|
||||
*
|
||||
* All parameters are provided by the run_rpc_command function, except for
|
||||
* argc, argv which are passes through.
|
||||
*
|
||||
* @param domain_sid The domain sid acquired from the remote server
|
||||
* @param cli A cli_state connected to the server.
|
||||
* @param mem_ctx Talloc context, destoyed on completion of the function.
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return Normal NTSTATUS return.
|
||||
**/
|
||||
static NTSTATUS
|
||||
rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_name,
|
||||
struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
WERROR result;
|
||||
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
SRV_SHARE_INFO_CTR ctr_src;
|
||||
ENUM_HND hnd;
|
||||
uint32 preferred_len = 0xffffffff, i;
|
||||
uint32 level = 2;
|
||||
struct cli_state *cli_share_src = NULL;
|
||||
struct cli_state *cli_share_dst = NULL;
|
||||
BOOL got_src_share = False;
|
||||
BOOL got_dst_share = False;
|
||||
pstring mask;
|
||||
extern struct in_addr loopback_ip;
|
||||
|
||||
init_enum_hnd(&hnd, 0);
|
||||
|
||||
result = cli_srvsvc_net_share_enum(
|
||||
cli, mem_ctx, level, &ctr_src, preferred_len, &hnd);
|
||||
|
||||
if (!W_ERROR_IS_OK(result))
|
||||
goto done;
|
||||
|
||||
for (i = 0; i < ctr_src.num_entries; i++) {
|
||||
|
||||
fstring netname = "", remark = "", path = "";
|
||||
|
||||
rpcstr_pull_unistr2_fstring(
|
||||
netname, &ctr_src.share.info2[i].info_2_str.uni_netname);
|
||||
rpcstr_pull_unistr2_fstring(
|
||||
remark, &ctr_src.share.info2[i].info_2_str.uni_remark);
|
||||
rpcstr_pull_unistr2_fstring(
|
||||
path, &ctr_src.share.info2[i].info_2_str.uni_path);
|
||||
|
||||
/* since we do not have NetShareGetInfo implemented in samba3 we
|
||||
only can skip inside the enum-ctr_src */
|
||||
if (argc == 1) {
|
||||
char *one_share = talloc_strdup(mem_ctx, argv[0]);
|
||||
if (!strequal(netname, one_share))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip builtin and hidden shares
|
||||
In particular, one might not want to mirror whole discs :) */
|
||||
if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$"))
|
||||
continue;
|
||||
|
||||
if (strequal(netname, "print$") || netname[1] == '$') {
|
||||
d_printf("skipping [%s]: builtin/hidden share\n", netname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (opt_exclude && in_list(netname, (char *)opt_exclude, False)) {
|
||||
printf("excluding [%s]\n", netname);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only work with file-shares */
|
||||
if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
|
||||
d_printf("skipping [%s]: not a file share.\n", netname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!cli_tdis(cli))
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
printf("syncing [%s] files and directories %s ACLs\n",
|
||||
netname, opt_acls ? "including" : "without");
|
||||
|
||||
|
||||
/* open share source */
|
||||
nt_status = connect_to_service(&cli_share_src, &cli->dest_ip,
|
||||
cli->desthost, netname, "A:");
|
||||
if (!NT_STATUS_IS_OK(nt_status))
|
||||
goto done;
|
||||
|
||||
got_src_share = True;
|
||||
|
||||
|
||||
/* open share destination */
|
||||
nt_status = connect_to_service(&cli_share_dst, &loopback_ip,
|
||||
"127.0.0.1", netname, "A:");
|
||||
if (!NT_STATUS_IS_OK(nt_status))
|
||||
goto done;
|
||||
|
||||
got_dst_share = True;
|
||||
|
||||
|
||||
/* now call the filesync */
|
||||
pstrcpy(mask, "\\*");
|
||||
|
||||
if (!sync_files(mem_ctx, cli_share_src, cli_share_dst, mask, NULL)) {
|
||||
d_printf("could not sync files for share: %s\n", netname);
|
||||
nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nt_status = NT_STATUS_OK;
|
||||
|
||||
done:
|
||||
|
||||
if (got_src_share)
|
||||
cli_shutdown(cli_share_src);
|
||||
|
||||
if (got_dst_share)
|
||||
cli_shutdown(cli_share_dst);
|
||||
|
||||
return nt_status;
|
||||
|
||||
}
|
||||
|
||||
static int rpc_share_migrate_files(int argc, const char **argv)
|
||||
{
|
||||
return run_rpc_command(NULL, PI_SRVSVC, 0,
|
||||
rpc_share_migrate_files_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate shares (including share-definitions, share-acls and files with acls)
|
||||
* from one server to another
|
||||
*
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return A shell status integer (0 for success)
|
||||
*
|
||||
**/
|
||||
static int rpc_share_migrate_all(int argc, const char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_shares_internals, argc, argv);
|
||||
if (ret)
|
||||
return ret;
|
||||
#if 0
|
||||
ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_shares_security_internals, argc, argv);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_files_internals, argc, argv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 'net rpc share migrate' entrypoint.
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
**/
|
||||
static int rpc_share_migrate(int argc, const char **argv)
|
||||
{
|
||||
|
||||
struct functable func[] = {
|
||||
{"all", rpc_share_migrate_all},
|
||||
{"files", rpc_share_migrate_files},
|
||||
/* {"security", rpc_share_migrate_security},*/
|
||||
{"shares", rpc_share_migrate_shares},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
return net_run_function(argc, argv, func, rpc_share_usage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 'net rpc share' entrypoint.
|
||||
* @param argc Standard main() style argc
|
||||
@ -2503,6 +2957,7 @@ int net_rpc_share(int argc, const char **argv)
|
||||
struct functable func[] = {
|
||||
{"add", rpc_share_add},
|
||||
{"delete", rpc_share_delete},
|
||||
{"migrate", rpc_share_migrate},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@ -3570,6 +4025,227 @@ static int rpc_vampire(int argc, const char **argv) {
|
||||
return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_vampire_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate everything from a print-server
|
||||
*
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return A shell status integer (0 for success)
|
||||
*
|
||||
* The order is important !
|
||||
* To successfully add drivers the print-queues have to exist !
|
||||
* Applying ACLs should be the last step, because you're easily locked out
|
||||
*
|
||||
**/
|
||||
static int rpc_printer_migrate_all(int argc, const char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_printers_internals, argc, argv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_drivers_internals, argc, argv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_forms_internals, argc, argv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_settings_internals, argc, argv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_security_internals, argc, argv);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate print-drivers from a print-server
|
||||
*
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return A shell status integer (0 for success)
|
||||
**/
|
||||
static int rpc_printer_migrate_drivers(int argc, const char **argv)
|
||||
{
|
||||
|
||||
return run_rpc_command(NULL, PI_SPOOLSS, 0,
|
||||
rpc_printer_migrate_drivers_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate print-forms from a print-server
|
||||
*
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return A shell status integer (0 for success)
|
||||
**/
|
||||
static int rpc_printer_migrate_forms(int argc, const char **argv)
|
||||
{
|
||||
|
||||
return run_rpc_command(NULL, PI_SPOOLSS, 0,
|
||||
rpc_printer_migrate_forms_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate printers from a print-server
|
||||
*
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return A shell status integer (0 for success)
|
||||
**/
|
||||
static int rpc_printer_migrate_printers(int argc, const char **argv)
|
||||
{
|
||||
|
||||
return run_rpc_command(NULL, PI_SPOOLSS, 0,
|
||||
rpc_printer_migrate_printers_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate printer-ACLs from a print-server
|
||||
*
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return A shell status integer (0 for success)
|
||||
**/
|
||||
static int rpc_printer_migrate_security(int argc, const char **argv)
|
||||
{
|
||||
|
||||
return run_rpc_command(NULL, PI_SPOOLSS, 0,
|
||||
rpc_printer_migrate_security_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate printer-settings from a print-server
|
||||
*
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return A shell status integer (0 for success)
|
||||
**/
|
||||
static int rpc_printer_migrate_settings(int argc, const char **argv)
|
||||
{
|
||||
|
||||
return run_rpc_command(NULL, PI_SPOOLSS, 0,
|
||||
rpc_printer_migrate_settings_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* 'net rpc printer' entrypoint.
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
**/
|
||||
|
||||
int rpc_printer_migrate(int argc, const char **argv)
|
||||
{
|
||||
|
||||
/* ouch: when addriver and setdriver are called from within
|
||||
rpc_printer_migrate_drivers_internals, the printer-queue already
|
||||
*has* to exist */
|
||||
|
||||
struct functable func[] = {
|
||||
{"all", rpc_printer_migrate_all},
|
||||
{"drivers", rpc_printer_migrate_drivers},
|
||||
{"forms", rpc_printer_migrate_forms},
|
||||
{"help", rpc_printer_usage},
|
||||
{"printers", rpc_printer_migrate_printers},
|
||||
{"security", rpc_printer_migrate_security},
|
||||
{"settings", rpc_printer_migrate_settings},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
return net_run_function(argc, argv, func, rpc_printer_usage);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List printers on a remote RPC server
|
||||
*
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return A shell status integer (0 for success)
|
||||
**/
|
||||
static int rpc_printer_list(int argc, const char **argv)
|
||||
{
|
||||
|
||||
return run_rpc_command(NULL, PI_SPOOLSS, 0,
|
||||
rpc_printer_list_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* List printer-drivers on a remote RPC server
|
||||
*
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return A shell status integer (0 for success)
|
||||
**/
|
||||
static int rpc_printer_driver_list(int argc, const char **argv)
|
||||
{
|
||||
|
||||
return run_rpc_command(NULL, PI_SPOOLSS, 0,
|
||||
rpc_printer_driver_list_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display rpc printer help page.
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
**/
|
||||
int rpc_printer_usage(int argc, const char **argv)
|
||||
{
|
||||
return net_help_printer(argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* 'net rpc printer' entrypoint.
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
**/
|
||||
int net_rpc_printer(int argc, const char **argv)
|
||||
{
|
||||
struct functable func[] = {
|
||||
{"list", rpc_printer_list},
|
||||
{"migrate", rpc_printer_migrate},
|
||||
{"driver", rpc_printer_driver_list},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
if (argc == 0)
|
||||
return run_rpc_command(NULL, PI_SPOOLSS, 0,
|
||||
rpc_printer_list_internals,
|
||||
argc, argv);
|
||||
|
||||
return net_run_function(argc, argv, func, rpc_printer_usage);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
@ -3590,6 +4266,7 @@ int net_rpc_usage(int argc, const char **argv)
|
||||
d_printf(" net rpc password <username> [<password>] -Uadmin_username%%admin_pass");
|
||||
d_printf(" net rpc group \t\tto list groups\n");
|
||||
d_printf(" net rpc share \t\tto add, delete, and list shares\n");
|
||||
d_printf(" net rpc printer \t\tto list and migrate printers\n");
|
||||
d_printf(" net rpc file \t\t\tto list open files\n");
|
||||
d_printf(" net rpc changetrustpw \tto change the trust account password\n");
|
||||
d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
|
||||
@ -3659,6 +4336,7 @@ int net_rpc(int argc, const char **argv)
|
||||
{"group", net_rpc_group},
|
||||
{"share", net_rpc_share},
|
||||
{"file", net_rpc_file},
|
||||
{"printer", net_rpc_printer},
|
||||
{"changetrustpw", net_rpc_changetrustpw},
|
||||
{"trustdom", rpc_trustdom},
|
||||
{"abortshutdown", rpc_shutdown_abort},
|
||||
|
2185
source3/utils/net_rpc_printer.c
Normal file
2185
source3/utils/net_rpc_printer.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user