mirror of
https://github.com/samba-team/samba.git
synced 2025-01-22 22:04:08 +03:00
r7632: Cleanup "net share migrate"-code.
* Allow to copy share security descriptors to already existing shares separatly. * Added abstraction function to enum all or a single share info Guenther (This used to be commit 97097497ae42d7a03286bbe16bcffb8224137688)
This commit is contained in:
parent
b162a396fe
commit
75545d578e
@ -267,6 +267,63 @@ WERROR cli_srvsvc_net_share_get_info(struct cli_state *cli,
|
||||
info->switch_value = info_level;
|
||||
|
||||
switch(info_level) {
|
||||
case 1:
|
||||
{
|
||||
SRV_SHARE_INFO_1 *info1 = &info->share.info1;
|
||||
SH_INFO_1_STR *info1_str = &info1->info_1_str;
|
||||
|
||||
char *s;
|
||||
|
||||
info->share.info1 = r.info.share.info1;
|
||||
|
||||
/* Duplicate strings */
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info1_str->uni_netname);
|
||||
if (s)
|
||||
init_unistr2(&info1_str->uni_netname,
|
||||
s, UNI_STR_TERMINATE);
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info1_str->uni_remark);
|
||||
if (s)
|
||||
init_unistr2(&info1_str->uni_remark,
|
||||
s, UNI_STR_TERMINATE);
|
||||
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
SRV_SHARE_INFO_2 *info2 = &info->share.info2;
|
||||
SH_INFO_2_STR *info2_str = &info2->info_2_str;
|
||||
|
||||
char *s;
|
||||
|
||||
info->share.info2 = r.info.share.info2;
|
||||
|
||||
/* Duplicate strings */
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info2_str->uni_netname);
|
||||
if (s)
|
||||
init_unistr2(&info2_str->uni_netname,
|
||||
s, UNI_STR_TERMINATE);
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info2_str->uni_remark);
|
||||
if (s)
|
||||
init_unistr2(&info2_str->uni_remark,
|
||||
s, UNI_STR_TERMINATE);
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info2_str->uni_path);
|
||||
if (s)
|
||||
init_unistr2(&info2_str->uni_path,
|
||||
s, UNI_STR_TERMINATE);
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info2_str->uni_passwd);
|
||||
if (s)
|
||||
init_unistr2(&info2_str->uni_passwd,
|
||||
s, UNI_STR_TERMINATE);
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case 502:
|
||||
{
|
||||
SRV_SHARE_INFO_502 *info502 = &info->share.info502;
|
||||
|
@ -260,6 +260,11 @@ static void display_share_info_502(SRV_SHARE_INFO_502 *info502)
|
||||
printf("\tpath:\t%s\n", path);
|
||||
printf("\tpassword:\t%s\n", passwd);
|
||||
|
||||
printf("\ttype:\t0x%x\n", info502->info_502.type);
|
||||
printf("\tperms:\t%d\n", info502->info_502.perms);
|
||||
printf("\tmax_uses:\t%d\n", info502->info_502.max_uses);
|
||||
printf("\tnum_uses:\t%d\n", info502->info_502.num_uses);
|
||||
|
||||
if (info502->info_502_str.sd)
|
||||
display_sec_desc(info502->info_502_str.sd);
|
||||
|
||||
|
@ -708,7 +708,7 @@ static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char
|
||||
SAM_USER_INFO_7 info7;
|
||||
|
||||
if (argc != 2) {
|
||||
d_printf("New and old username must be specified\n");
|
||||
d_printf("Old and new username must be specified\n");
|
||||
rpc_user_usage(argc, argv);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@ -1151,12 +1151,9 @@ int net_rpc_user(int argc, const char **argv)
|
||||
};
|
||||
|
||||
if (argc == 0) {
|
||||
if (opt_long_list_entries) {
|
||||
} else {
|
||||
}
|
||||
return run_rpc_command(NULL,PI_SAMR, 0,
|
||||
rpc_user_list_internals,
|
||||
argc, argv);
|
||||
return run_rpc_command(NULL,PI_SAMR, 0,
|
||||
rpc_user_list_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
return net_run_function(argc, argv, func, rpc_user_usage);
|
||||
@ -2436,9 +2433,6 @@ int net_rpc_group(int argc, const char **argv)
|
||||
};
|
||||
|
||||
if (argc == 0) {
|
||||
if (opt_long_list_entries) {
|
||||
} else {
|
||||
}
|
||||
return run_rpc_command(NULL, PI_SAMR, 0,
|
||||
rpc_group_list_internals,
|
||||
argc, argv);
|
||||
@ -2477,7 +2471,7 @@ rpc_share_add_internals(const DOM_SID *domain_sid, const char *domain_name,
|
||||
WERROR result;
|
||||
char *sharename=talloc_strdup(mem_ctx, argv[0]);
|
||||
char *path;
|
||||
uint32 type=0; /* only allow disk shares to be added */
|
||||
uint32 type = STYPE_DISKTREE; /* 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;
|
||||
@ -2574,6 +2568,139 @@ static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
|
||||
|
||||
}
|
||||
|
||||
|
||||
static WERROR get_share_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
uint32 level, int argc, const char **argv,
|
||||
SRV_SHARE_INFO_CTR *ctr)
|
||||
{
|
||||
WERROR result;
|
||||
SRV_SHARE_INFO info;
|
||||
|
||||
/* no specific share requested, enumerate all */
|
||||
if (argc == 0) {
|
||||
|
||||
ENUM_HND hnd;
|
||||
uint32 preferred_len = 0xffffffff;
|
||||
|
||||
init_enum_hnd(&hnd, 0);
|
||||
|
||||
result = cli_srvsvc_net_share_enum(cli, mem_ctx, level, ctr,
|
||||
preferred_len, &hnd);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* request just one share */
|
||||
result = cli_srvsvc_net_share_get_info(cli, mem_ctx, argv[0], level, &info);
|
||||
|
||||
if (!W_ERROR_IS_OK(result))
|
||||
goto done;
|
||||
|
||||
/* construct ctr */
|
||||
ZERO_STRUCTP(ctr);
|
||||
|
||||
ctr->info_level = ctr->switch_value = level;
|
||||
ctr->ptr_share_info = ctr->ptr_entries = 1;
|
||||
ctr->num_entries = ctr->num_entries2 = 1;
|
||||
|
||||
switch (level) {
|
||||
case 1:
|
||||
{
|
||||
char *s;
|
||||
SRV_SHARE_INFO_1 *info1;
|
||||
|
||||
ctr->share.info1 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_1, 1);
|
||||
info1 = ctr->share.info1;
|
||||
|
||||
memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
|
||||
|
||||
/* Copy pointer crap */
|
||||
|
||||
memcpy(&info1->info_1, &info.share.info1.info_1, sizeof(SH_INFO_1));
|
||||
|
||||
/* Duplicate strings */
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info.share.info1.info_1_str.uni_netname);
|
||||
if (s)
|
||||
init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info.share.info1.info_1_str.uni_remark);
|
||||
if (s)
|
||||
init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
char *s;
|
||||
SRV_SHARE_INFO_2 *info2;
|
||||
|
||||
ctr->share.info2 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_2, 1);
|
||||
info2 = ctr->share.info2;
|
||||
|
||||
memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
|
||||
|
||||
/* Copy pointer crap */
|
||||
|
||||
memcpy(&info2->info_2, &info.share.info2.info_2, sizeof(SH_INFO_2));
|
||||
|
||||
/* Duplicate strings */
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info.share.info2.info_2_str.uni_netname);
|
||||
if (s)
|
||||
init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info.share.info2.info_2_str.uni_remark);
|
||||
if (s)
|
||||
init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info.share.info2.info_2_str.uni_path);
|
||||
if (s)
|
||||
init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info.share.info2.info_2_str.uni_passwd);
|
||||
if (s)
|
||||
init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
|
||||
}
|
||||
case 502:
|
||||
{
|
||||
char *s;
|
||||
SRV_SHARE_INFO_502 *info502;
|
||||
|
||||
ctr->share.info502 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_502, 1);
|
||||
info502 = ctr->share.info502;
|
||||
|
||||
memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502));
|
||||
|
||||
/* Copy pointer crap */
|
||||
|
||||
memcpy(&info502->info_502, &info.share.info502.info_502, sizeof(SH_INFO_502));
|
||||
|
||||
/* Duplicate strings */
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info.share.info502.info_502_str.uni_netname);
|
||||
if (s)
|
||||
init_unistr2(&info502->info_502_str.uni_netname, s, UNI_STR_TERMINATE);
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info.share.info502.info_502_str.uni_remark);
|
||||
if (s)
|
||||
init_unistr2(&info502->info_502_str.uni_remark, s, UNI_STR_TERMINATE);
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info.share.info502.info_502_str.uni_path);
|
||||
if (s)
|
||||
init_unistr2(&info502->info_502_str.uni_path, s, UNI_STR_TERMINATE);
|
||||
|
||||
s = unistr2_tdup(mem_ctx, &info.share.info502.info_502_str.uni_passwd);
|
||||
if (s)
|
||||
init_unistr2(&info502->info_502_str.uni_passwd, s, UNI_STR_TERMINATE);
|
||||
|
||||
info502->info_502_str.sd = dup_sec_desc(mem_ctx, info.share.info502.info_502_str.sd);
|
||||
|
||||
}
|
||||
|
||||
} /* switch */
|
||||
|
||||
done:
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* List shares on a remote RPC server
|
||||
*
|
||||
@ -2597,14 +2724,9 @@ rpc_share_list_internals(const DOM_SID *domain_sid, const char *domain_name,
|
||||
{
|
||||
SRV_SHARE_INFO_CTR ctr;
|
||||
WERROR result;
|
||||
ENUM_HND hnd;
|
||||
uint32 preferred_len = 0xffffffff, i;
|
||||
|
||||
init_enum_hnd(&hnd, 0);
|
||||
|
||||
result = cli_srvsvc_net_share_enum(
|
||||
cli, mem_ctx, 1, &ctr, preferred_len, &hnd);
|
||||
uint32 i, level = 1;
|
||||
|
||||
result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr);
|
||||
if (!W_ERROR_IS_OK(result))
|
||||
goto done;
|
||||
|
||||
@ -2622,6 +2744,52 @@ 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;
|
||||
}
|
||||
|
||||
/***
|
||||
* 'net rpc share list' entrypoint.
|
||||
* @param argc Standard main() style argc
|
||||
* @param argv Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
**/
|
||||
static int rpc_share_list(int argc, const char **argv)
|
||||
{
|
||||
return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_list_internals, argc, argv);
|
||||
}
|
||||
|
||||
static BOOL check_share_availability(struct cli_state *cli, const char *netname)
|
||||
{
|
||||
if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
|
||||
d_printf("skipping [%s]: not a file share.\n", netname);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!cli_tdis(cli))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL check_share_sanity(struct cli_state *cli, fstring netname, uint32 type)
|
||||
{
|
||||
/* only support disk shares */
|
||||
if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
|
||||
printf("share [%s] is not a diskshare (type: %x)\n", netname, type);
|
||||
return False;
|
||||
}
|
||||
|
||||
/* skip builtin shares */
|
||||
/* FIXME: should print$ be added too ? */
|
||||
if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
|
||||
strequal(netname,"global"))
|
||||
return False;
|
||||
|
||||
if (opt_exclude && in_list(netname, opt_exclude, False)) {
|
||||
printf("excluding [%s]\n", netname);
|
||||
return False;
|
||||
}
|
||||
|
||||
return check_share_availability(cli, netname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate shares from a remote RPC server to the local RPC srever
|
||||
*
|
||||
@ -2645,24 +2813,18 @@ rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain
|
||||
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;
|
||||
uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
|
||||
char *password = NULL; /* don't allow a share password */
|
||||
uint32 preferred_len = 0xffffffff, i;
|
||||
uint32 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);
|
||||
result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr_src);
|
||||
if (!W_ERROR_IS_OK(result))
|
||||
goto done;
|
||||
|
||||
/* connect local PI_SRVSVC */
|
||||
/* connect destination PI_SRVSVC */
|
||||
nt_status = connect_pipe(&cli_dst, PI_SRVSVC, &got_dst_srvsvc_pipe);
|
||||
if (!NT_STATUS_IS_OK(nt_status))
|
||||
return nt_status;
|
||||
@ -2680,58 +2842,24 @@ rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain
|
||||
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"))
|
||||
if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
|
||||
continue;
|
||||
|
||||
if (opt_exclude && in_list(netname, 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))
|
||||
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 */
|
||||
/* finally add the share on the dst server */
|
||||
|
||||
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);
|
||||
display_sec_desc(ctr_src.share.info502[i].info_502_str.sd);
|
||||
|
||||
result = cli_srvsvc_net_share_add(cli_dst, mem_ctx, netname, type,
|
||||
remark, perms, max_uses,
|
||||
num_uses, path, password,
|
||||
level, share_sd);
|
||||
result = cli_srvsvc_net_share_add(cli_dst, mem_ctx, netname, type, remark,
|
||||
ctr_src.share.info502[i].info_502.perms,
|
||||
ctr_src.share.info502[i].info_502.max_uses,
|
||||
ctr_src.share.info502[i].info_502.num_uses,
|
||||
path, password, level,
|
||||
opt_acls? ctr_src.share.info502[i].info_502_str.sd : NULL);
|
||||
|
||||
if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) {
|
||||
printf(" [%s] does already exist\n", netname);
|
||||
@ -2962,13 +3090,12 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_
|
||||
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;
|
||||
uint32 i;
|
||||
uint32 level = 502;
|
||||
struct copy_clistate cp_clistate;
|
||||
BOOL got_src_share = False;
|
||||
BOOL got_dst_share = False;
|
||||
pstring mask;
|
||||
pstring mask = "\\*";
|
||||
char *dst = NULL;
|
||||
|
||||
/* decrese argc and safe mode */
|
||||
@ -2976,57 +3103,27 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_
|
||||
|
||||
dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1");
|
||||
|
||||
init_enum_hnd(&hnd, 0);
|
||||
|
||||
result = cli_srvsvc_net_share_enum(
|
||||
cli, mem_ctx, level, &ctr_src, preferred_len, &hnd);
|
||||
result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr_src);
|
||||
|
||||
if (!W_ERROR_IS_OK(result))
|
||||
goto done;
|
||||
|
||||
for (i = 0; i < ctr_src.num_entries; i++) {
|
||||
|
||||
fstring netname = "", remark = "", path = "";
|
||||
fstring netname = "";
|
||||
|
||||
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);
|
||||
netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
|
||||
|
||||
/* 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$"))
|
||||
if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
|
||||
continue;
|
||||
|
||||
|
||||
/* one might not want to mirror whole discs :) */
|
||||
if (strequal(netname, "print$") || netname[1] == '$') {
|
||||
d_printf("skipping [%s]: builtin/hidden share\n", netname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (opt_exclude && in_list(netname, 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;
|
||||
|
||||
switch (cp_clistate.mode)
|
||||
{
|
||||
case NET_MODE_SHARE_MIGRATE:
|
||||
@ -3073,10 +3170,6 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* now call the filesync */
|
||||
pstrcpy(mask, "\\*");
|
||||
|
||||
|
||||
if (!sync_files(&cp_clistate, mask)) {
|
||||
d_printf("could not handle files for share: %s\n", netname);
|
||||
nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
@ -3111,6 +3204,121 @@ static int rpc_share_migrate_files(int argc, const char **argv)
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate share-ACLs 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_security_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;
|
||||
SRV_SHARE_INFO info;
|
||||
uint32 i;
|
||||
BOOL got_dst_srvsvc_pipe = False;
|
||||
struct cli_state *cli_dst = NULL;
|
||||
uint32 level = 502; /* includes secdesc */
|
||||
|
||||
result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr_src);
|
||||
|
||||
if (!W_ERROR_IS_OK(result))
|
||||
goto done;
|
||||
|
||||
/* connect destination PI_SRVSVC */
|
||||
nt_status = connect_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);
|
||||
|
||||
if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
|
||||
continue;
|
||||
|
||||
printf("migrating: [%s], path: %s, comment: %s, including share-ACLs\n",
|
||||
netname, path, remark);
|
||||
|
||||
if (opt_verbose)
|
||||
display_sec_desc(ctr_src.share.info502[i].info_502_str.sd);
|
||||
|
||||
/* init info */
|
||||
ZERO_STRUCT(info);
|
||||
|
||||
info.switch_value = level;
|
||||
info.ptr_share_ctr = 1;
|
||||
|
||||
/* FIXME: shouldn't we be able to just set the security descriptor ? */
|
||||
info.share.info502 = ctr_src.share.info502[i];
|
||||
|
||||
/* finally modify the share on the dst server */
|
||||
result = cli_srvsvc_net_share_set_info(cli_dst, mem_ctx, netname, level, &info);
|
||||
|
||||
if (!W_ERROR_IS_OK(result)) {
|
||||
printf("cannot set share-acl: %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 share-acls 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_security(int argc, const char **argv)
|
||||
{
|
||||
|
||||
if (!opt_host) {
|
||||
printf("no server to migrate\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return run_rpc_command(NULL, PI_SRVSVC, 0,
|
||||
rpc_share_migrate_security_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate shares (including share-definitions, share-acls and files with acls/attrs)
|
||||
* from one server to another
|
||||
@ -3131,15 +3339,18 @@ static int rpc_share_migrate_all(int argc, const char **argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* order is important. we don't want to be locked out by the share-acl
|
||||
* before copying files - gd */
|
||||
|
||||
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);
|
||||
|
||||
ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_files_internals, argc, argv);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_files_internals, argc, argv);
|
||||
|
||||
return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_security_internals, argc, argv);
|
||||
}
|
||||
|
||||
|
||||
@ -3156,7 +3367,7 @@ static int rpc_share_migrate(int argc, const char **argv)
|
||||
{"all", rpc_share_migrate_all},
|
||||
{"files", rpc_share_migrate_files},
|
||||
{"help", rpc_share_usage},
|
||||
/* {"security", rpc_share_migrate_security},*/
|
||||
{"security", rpc_share_migrate_security},
|
||||
{"shares", rpc_share_migrate_shares},
|
||||
{NULL, NULL}
|
||||
};
|
||||
@ -3169,7 +3380,7 @@ static int rpc_share_migrate(int argc, const char **argv)
|
||||
|
||||
struct full_alias {
|
||||
DOM_SID sid;
|
||||
int num_members;
|
||||
uint32 num_members;
|
||||
DOM_SID *members;
|
||||
};
|
||||
|
||||
@ -3951,6 +4162,7 @@ int net_rpc_share(int argc, const char **argv)
|
||||
{"delete", rpc_share_delete},
|
||||
{"allowedusers", rpc_share_allowedusers},
|
||||
{"migrate", rpc_share_migrate},
|
||||
{"list", rpc_share_list},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user