This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "includes.h"
#include "utils/net.h"
static int net_mode_share;
+static bool sync_files(struct copy_clistate *cp_clistate, const char *mask);
/**
* @file net_rpc.c
/* make use of cli_state handed over as an argument, if possible */
if (!cli_arg) {
- cli = net_make_ipc_connection(conn_flags);
+ nt_status = net_make_ipc_connection(conn_flags, &cli);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(1, ("failed to make ipc connection: %s\n",
+ nt_errstr(nt_status)));
+ return -1;
+ }
} else {
cli = cli_arg;
}
2, &ctr);
if (NT_STATUS_IS_OK(result)) {
TALLOC_CTX *ctx = talloc_init("rpc_info_internals");
- d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain));
+ d_printf("Domain Name: %s\n", unistr2_to_ascii_talloc(ctx, &ctr.info.inf2.uni_domain));
d_printf("Domain SID: %s\n", sid_str);
d_printf("Sequence number: %llu\n", (unsigned long long)ctr.info.inf2.seq_num);
d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
const char *acct_name;
uint32 acb_info;
- uint32 unknown, user_rid;
+ uint32 access_mask, user_rid;
if (argc < 1) {
d_printf("User must be specified\n");
/* Create domain user */
acb_info = ACB_NORMAL;
- unknown = 0xe005000b; /* No idea what this is - a permission mask? */
+ access_mask = 0xe005000b;
result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
- acct_name, acb_info, unknown,
+ acct_name, acb_info, access_mask,
&user_pol, &user_rid);
if (!NT_STATUS_IS_OK(result)) {
goto done;
loop_count++;
for (i = 0; i < num_entries; i++) {
- unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user)-1);
+ unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user));
if (opt_long_list_entries)
- unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1);
+ unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc));
if (opt_long_list_entries)
printf("%-21.21s %s\n", user, desc);
const char *username;
const char *oldval = "unknown";
uint32 oldflags, newflags;
- BOOL newval;
+ bool newval;
if ((argc > 1) ||
((argc == 1) && !strequal(argv[0], "yes") &&
const char **argv)
{
POLICY_HND connect_pol, domain_pol, group_pol, user_pol;
- BOOL group_is_primary = False;
+ bool group_is_primary = False;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 *group_rids, num_rids, *name_types, num_members,
if (user_ctr->info.id21->group_rid == group_rid) {
unistr2_to_ascii(temp, &(user_ctr->info.id21)->uni_user_name,
- sizeof(temp)-1);
+ sizeof(temp));
if (opt_verbose)
d_printf("Group is primary group of %s\n",temp);
group_is_primary = True;
}
result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
- &name, NULL, &sids, &types);
+ &name, NULL, 1, &sids, &types);
if (NT_STATUS_IS_OK(result)) {
sid_copy(sid, &sids[0]);
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
struct acct_info *groups;
- BOOL global = False;
- BOOL local = False;
- BOOL builtin = False;
+ bool global = False;
+ bool local = False;
+ bool builtin = False;
if (argc == 0) {
global = True;
fstring group, desc;
- unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group)-1);
- unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc)-1);
+ unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group));
+ unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc));
if (opt_long_list_entries)
printf("%-21.21s %-50.50s\n",
&ctr))) &&
(NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
&alias_pol)))) {
- description = unistr2_tdup(mem_ctx,
+ description = unistr2_to_ascii_talloc(mem_ctx,
ctr.alias.info3.description.string);
}
}
&ctr))) &&
(NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
&alias_pol)))) {
- description = unistr2_tdup(mem_ctx,
+ description = unistr2_to_ascii_talloc(mem_ctx,
ctr.alias.info3.description.string);
}
}
TALLOC_CTX *mem_ctx,int argc,
const char **argv)
{
- NTSTATUS result;
+ WERROR result;
char *sharename;
char *path;
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;
- uint32 parm_error;
- union srvsvc_NetShareInfo info;
- struct srvsvc_NetShareInfo2 info2;
if ((sharename = talloc_strdup(mem_ctx, argv[0])) == NULL) {
return NT_STATUS_NO_MEMORY;
return NT_STATUS_UNSUCCESSFUL;
*path++ = '\0';
- info.info2 = &info2;
-
- info2.type = type;
- info2.comment = opt_comment;
- info2.permissions = perms;
- info2.max_users = opt_maxusers;
- info2.current_users = num_users;
- info2.path = path;
- info2.password = password;
- info2.name = sharename;
-
- result = rpccli_srvsvc_NetShareAdd(pipe_hnd, mem_ctx, NULL, level,
- info, &parm_error);
- return result;
+ result = rpccli_srvsvc_net_share_add(pipe_hnd, mem_ctx, sharename, type,
+ opt_comment, perms, opt_maxusers,
+ num_users, path, password,
+ level, NULL);
+ return werror_to_ntstatus(result);
}
static int rpc_share_add(int argc, const char **argv)
int argc,
const char **argv)
{
- return rpccli_srvsvc_NetShareDel(pipe_hnd, mem_ctx, NULL, argv[0], 0);
+ WERROR result;
+
+ result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/**
/**
* Formatted print of share info
*
- * @param info1 pointer to struct srvsvc_NetShareInfo1 to format
+ * @param info1 pointer to SRV_SHARE_INFO_1 to format
**/
-static void display_share_info_1(struct srvsvc_NetShareInfo1 *info1)
+static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
{
+ fstring netname = "", remark = "";
+
+ rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
+ rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
+
if (opt_long_list_entries) {
d_printf("%-12s %-8.8s %-50s\n",
- info1->name, share_type[info1->type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)],
- info1->comment ? info1->comment : "");
+ netname, share_type[info1->info_1.type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)], remark);
} else {
- d_printf("%s\n", info1->name);
+ d_printf("%s\n", netname);
}
}
-static NTSTATUS get_share_info(struct rpc_pipe_client *pipe_hnd,
+static WERROR get_share_info(struct rpc_pipe_client *pipe_hnd,
TALLOC_CTX *mem_ctx,
uint32 level,
int argc,
const char **argv,
- union srvsvc_NetShareCtr *ctr,
- uint32 *numentries)
+ SRV_SHARE_INFO_CTR *ctr)
{
- union srvsvc_NetShareInfo info;
- NTSTATUS status;
-
- switch(level) {
- case 1:
- if (!(ctr->ctr1 = TALLOC_ZERO_P(
- mem_ctx, struct srvsvc_NetShareCtr1))) {
- return NT_STATUS_NO_MEMORY;
- }
- break;
- case 502:
- if (!(ctr->ctr502 = TALLOC_ZERO_P(
- mem_ctx, struct srvsvc_NetShareCtr502))) {
- return NT_STATUS_NO_MEMORY;
- }
- break;
- default:
- return NT_STATUS_INVALID_LEVEL;
- break;
- }
+ WERROR result;
+ SRV_SHARE_INFO info;
/* no specific share requested, enumerate all */
if (argc == 0) {
- uint32 hnd = 0;
- return rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, NULL,
- &level, ctr, 0xffffffff,
- numentries, &hnd);
+ ENUM_HND hnd;
+ uint32 preferred_len = 0xffffffff;
+
+ init_enum_hnd(&hnd, 0);
+
+ return rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, level, ctr,
+ preferred_len, &hnd);
}
/* request just one share */
- status = rpccli_srvsvc_NetShareGetInfo(pipe_hnd, mem_ctx, NULL,
- argv[0], level, &info);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, argv[0], level, &info);
- *numentries = 1;
+ if (!W_ERROR_IS_OK(result))
+ goto done;
+
+ /* construct ctr */
+ ZERO_STRUCTP(ctr);
- switch(level) {
+ 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:
- ctr->ctr1->count = 1;
- ctr->ctr1->array = info.info1;
- break;
+ {
+ char *s;
+ SRV_SHARE_INFO_1 *info1;
+
+ ctr->share.info1 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_1, 1);
+ if (ctr->share.info1 == NULL) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+ 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_to_ascii_talloc(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_to_ascii_talloc(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);
+ if (ctr->share.info2 == NULL) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+ 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_to_ascii_talloc(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_to_ascii_talloc(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_to_ascii_talloc(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_to_ascii_talloc(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:
- ctr->ctr501->count = 1;
- ctr->ctr502->array = info.info502;
- break;
- default:
- return NT_STATUS_INTERNAL_ERROR;
- break;
+ {
+ char *s;
+ SRV_SHARE_INFO_502 *info502;
+
+ ctr->share.info502 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_502, 1);
+ if (ctr->share.info502 == NULL) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+ 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_to_ascii_talloc(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_to_ascii_talloc(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_to_ascii_talloc(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_to_ascii_talloc(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);
+
}
- return NT_STATUS_OK;
+ } /* switch */
+
+done:
+ return result;
}
/**
int argc,
const char **argv)
{
- union srvsvc_NetShareCtr ctr;
- NTSTATUS result;
+ SRV_SHARE_INFO_CTR ctr;
+ WERROR result;
uint32 i, level = 1;
- uint32 numentries;
- result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr,
- &numentries);
- if (!NT_STATUS_IS_OK(result))
+ result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr);
+ if (!W_ERROR_IS_OK(result))
goto done;
/* Display results */
"\nShare name Type Description\n"\
"---------- ---- -----------\n");
}
- for (i = 0; i < numentries; i++)
- display_share_info_1(&ctr.ctr1->array[i]);
+ for (i = 0; i < ctr.num_entries; i++)
+ display_share_info_1(&ctr.share.info1[i]);
done:
- return NT_STATUS_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/***
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)
+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 True;
}
-static BOOL check_share_sanity(struct cli_state *cli, const char *netname, uint32 type)
+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)) ) {
int argc,
const char **argv)
{
- NTSTATUS result;
+ WERROR result;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- union srvsvc_NetShareCtr ctr_src;
+ SRV_SHARE_INFO_CTR ctr_src;
+ uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
+ char *password = NULL; /* don't allow a share password */
uint32 i;
struct rpc_pipe_client *srvsvc_pipe = NULL;
struct cli_state *cli_dst = NULL;
uint32 level = 502; /* includes secdesc */
- uint32 numentries;
- result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src,
- &numentries);
- if (!NT_STATUS_IS_OK(result))
+ result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
+ if (!W_ERROR_IS_OK(result))
goto done;
/* connect destination PI_SRVSVC */
return nt_status;
- for (i = 0; i < numentries; i++) {
- uint32 parm_error = 0;
- union srvsvc_NetShareInfo info;
+ for (i = 0; i < ctr_src.num_entries; i++) {
+ fstring netname = "", remark = "", path = "";
/* reset error-code */
nt_status = NT_STATUS_UNSUCCESSFUL;
- if (!check_share_sanity(cli, ctr_src.ctr502->array[i].name,
- ctr_src.ctr502->array[i].type))
-
+ 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;
/* finally add the share on the dst server */
printf("migrating: [%s], path: %s, comment: %s, without share-ACLs\n",
- ctr_src.ctr502->array[i].name,
- ctr_src.ctr502->array[i].path,
- ctr_src.ctr502->array[i].comment);
-
- info.info502 = &ctr_src.ctr502->array[i];
-
- result = rpccli_srvsvc_NetShareAdd(srvsvc_pipe, mem_ctx, NULL,
- 502, info, &parm_error);
+ netname, path, remark);
+
+ result = rpccli_srvsvc_net_share_add(srvsvc_pipe, 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,
+ NULL);
- if (NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_COLLISION)) {
- printf(" [%s] does already exist\n", ctr_src.ctr502->array[i].name);
+ if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) {
+ printf(" [%s] does already exist\n", netname);
continue;
}
- if (!NT_STATUS_IS_OK(result)) {
- printf("cannot add share: %s\n", nt_errstr(result));
+ if (!W_ERROR_IS_OK(result)) {
+ printf("cannot add share: %s\n", dos_errstr(result));
goto done;
}
*
* @return Boolean result
**/
-BOOL sync_files(struct copy_clistate *cp_clistate, pstring mask)
+static bool sync_files(struct copy_clistate *cp_clistate, const char *mask)
{
struct cli_state *targetcli;
- pstring targetpath;
+ char *targetpath = NULL;
DEBUG(3,("calling cli_list with mask: %s\n", mask));
- if ( !cli_resolve_path( "", cp_clistate->cli_share_src, mask, &targetcli, targetpath ) ) {
+ if ( !cli_resolve_path(talloc_tos(), "", cp_clistate->cli_share_src,
+ mask, &targetcli, &targetpath ) ) {
d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n",
mask, cli_errstr(cp_clistate->cli_share_src));
return False;
* Should set up ACL inheritance.
**/
-BOOL copy_top_level_perms(struct copy_clistate *cp_clistate,
+bool copy_top_level_perms(struct copy_clistate *cp_clistate,
const char *sharename)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
int argc,
const char **argv)
{
- NTSTATUS result;
+ WERROR result;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- union srvsvc_NetShareCtr ctr_src;
+ SRV_SHARE_INFO_CTR ctr_src;
uint32 i;
uint32 level = 502;
struct copy_clistate cp_clistate;
- BOOL got_src_share = False;
- BOOL got_dst_share = False;
- pstring mask = "\\*";
+ bool got_src_share = False;
+ bool got_dst_share = False;
+ const char *mask = "\\*";
char *dst = NULL;
- uint32 numentries;
dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1");
- result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src,
- &numentries);
+ result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
- if (!NT_STATUS_IS_OK(result))
+ if (!W_ERROR_IS_OK(result))
goto done;
- for (i = 0; i < numentries; i++) {
- if (!check_share_sanity(cli, ctr_src.ctr502->array[i].name,
- ctr_src.ctr502->array[i].type))
+ for (i = 0; i < ctr_src.num_entries; i++) {
+
+ fstring netname = "";
+
+ rpcstr_pull_unistr2_fstring(
+ netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
+
+ 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(ctr_src.ctr502->array[i].name, "print$") || ctr_src.ctr502->array[i].name[1] == '$') {
- d_printf("skipping [%s]: builtin/hidden share\n", ctr_src.ctr502->array[i].name);
+ if (strequal(netname, "print$") || netname[1] == '$') {
+ d_printf("skipping [%s]: builtin/hidden share\n", netname);
continue;
}
break;
}
printf(" [%s] files and directories %s ACLs, %s DOS Attributes %s\n",
- ctr_src.ctr502->array[i].name,
+ netname,
opt_acls ? "including" : "without",
opt_attrs ? "including" : "without",
opt_timestamps ? "(preserving timestamps)" : "");
/* open share source */
nt_status = connect_to_service(&cp_clistate.cli_share_src,
- &cli->dest_ip, cli->desthost,
- ctr_src.ctr502->array[i].name, "A:");
+ &cli->dest_ss, cli->desthost,
+ netname, "A:");
if (!NT_STATUS_IS_OK(nt_status))
goto done;
if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
/* open share destination */
nt_status = connect_to_service(&cp_clistate.cli_share_dst,
- NULL, dst, ctr_src.ctr502->array[i].name, "A:");
+ NULL, dst, netname, "A:");
if (!NT_STATUS_IS_OK(nt_status))
goto done;
got_dst_share = True;
}
- if (!copy_top_level_perms(&cp_clistate, ctr_src.ctr502->array[i].name)) {
- d_fprintf(stderr, "Could not handle the top level directory permissions for the share: %s\n", ctr_src.ctr502->array[i].name);
+ if (!copy_top_level_perms(&cp_clistate, netname)) {
+ d_fprintf(stderr, "Could not handle the top level directory permissions for the share: %s\n", netname);
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (!sync_files(&cp_clistate, mask)) {
- d_fprintf(stderr, "could not handle files for share: %s\n",
- ctr_src.ctr502->array[i].name);
+ d_fprintf(stderr, "could not handle files for share: %s\n", netname);
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
int argc,
const char **argv)
{
- NTSTATUS result;
+ WERROR result;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- union srvsvc_NetShareCtr ctr_src;
- union srvsvc_NetShareInfo info;
+ SRV_SHARE_INFO_CTR ctr_src;
+ SRV_SHARE_INFO info;
uint32 i;
struct rpc_pipe_client *srvsvc_pipe = NULL;
struct cli_state *cli_dst = NULL;
uint32 level = 502; /* includes secdesc */
- uint32 numentries;
- uint32 parm_error = 0;
- result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src,
- &numentries);
+ result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
- if (!NT_STATUS_IS_OK(result))
+ if (!W_ERROR_IS_OK(result))
goto done;
/* connect destination PI_SRVSVC */
return nt_status;
- for (i = 0; i < numentries; i++) {
+ for (i = 0; i < ctr_src.num_entries; i++) {
+
+ fstring netname = "", remark = "", path = "";
/* reset error-code */
nt_status = NT_STATUS_UNSUCCESSFUL;
- if (!check_share_sanity(cli, ctr_src.ctr502->array[i].name, ctr_src.ctr502->array[i].type))
+ 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",
- ctr_src.ctr502->array[i].name,
- ctr_src.ctr502->array[i].path,
- ctr_src.ctr502->array[i].comment);
+ netname, path, remark);
if (opt_verbose)
- display_sec_desc(ctr_src.ctr502->array[i].sd);
+ 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 = rpccli_srvsvc_NetShareSetInfo(
- srvsvc_pipe, mem_ctx, NULL, argv[0], level, info,
- &parm_error);
+ result = rpccli_srvsvc_net_share_set_info(srvsvc_pipe, mem_ctx, netname, level, &info);
- if (!NT_STATUS_IS_OK(result)) {
- printf("cannot set share-acl: %s\n", nt_errstr(result));
+ if (!W_ERROR_IS_OK(result)) {
+ printf("cannot set share-acl: %s\n", dos_errstr(result));
goto done;
}
{
token->num_sids = 4;
- token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4);
+ if (!(token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4))) {
+ d_fprintf(stderr, "malloc failed\n");
+ token->num_sids = 0;
+ return;
+ }
token->user_sids[0] = *user_sid;
sid_copy(&token->user_sids[1], &global_sid_World);
SAFE_FREE(token->user_sids);
}
-static BOOL is_sid_in_token(NT_USER_TOKEN *token, DOM_SID *sid)
+static bool is_sid_in_token(NT_USER_TOKEN *token, DOM_SID *sid)
{
int i;
}
}
-static BOOL is_alias_member(DOM_SID *sid, struct full_alias *alias)
+static bool is_alias_member(DOM_SID *sid, struct full_alias *alias)
{
int i;
}
}
-static BOOL get_user_sids(const char *domain, const char *user, NT_USER_TOKEN *token)
+static bool get_user_sids(const char *domain, const char *user, NT_USER_TOKEN *token)
{
struct winbindd_request request;
struct winbindd_response response;
* Get a list of all user tokens we want to look at
**/
-static BOOL get_user_tokens(int *num_tokens, struct user_token **user_tokens)
+static bool get_user_tokens(int *num_tokens, struct user_token **user_tokens)
{
struct winbindd_request request;
struct winbindd_response response;
const char *extra_data;
- fstring name;
+ char *name;
int i;
struct user_token *result;
+ TALLOC_CTX *frame = NULL;
if (lp_winbind_use_default_domain() &&
(opt_target_workgroup == NULL)) {
ZERO_STRUCT(request);
ZERO_STRUCT(response);
-
+
if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) !=
NSS_STATUS_SUCCESS)
return False;
extra_data = (const char *)response.extra_data.data;
*num_tokens = 0;
- while(next_token(&extra_data, name, ",", sizeof(fstring))) {
+ frame = talloc_stackframe();
+ while(next_token_talloc(frame, &extra_data, &name, ",")) {
*num_tokens += 1;
}
if (result == NULL) {
DEBUG(1, ("Could not malloc sid array\n"));
+ TALLOC_FREE(frame);
return False;
}
extra_data = (const char *)response.extra_data.data;
i=0;
- while(next_token(&extra_data, name, ",", sizeof(fstring))) {
-
+ while(next_token_talloc(frame, &extra_data, &name, ",")) {
fstring domain, user;
char *p;
get_user_sids(domain, user, &(result[i].token));
i+=1;
}
-
+ TALLOC_FREE(frame);
SAFE_FREE(response.extra_data.data);
*user_tokens = result;
return True;
}
-static BOOL get_user_tokens_from_file(FILE *f,
+static bool get_user_tokens_from_file(FILE *f,
int *num_tokens,
struct user_token **tokens)
{
SEC_DESC *root_sd = NULL;
struct cli_state *cli = pipe_hnd->cli;
int i;
- union srvsvc_NetShareInfo info;
- NTSTATUS result;
+ SRV_SHARE_INFO info;
+ WERROR result;
uint16 cnum;
- result = rpccli_srvsvc_NetShareGetInfo(pipe_hnd, mem_ctx, NULL, netname,
+ result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, netname,
502, &info);
- if (!NT_STATUS_IS_OK(result)) {
+ if (!W_ERROR_IS_OK(result)) {
DEBUG(1, ("Coult not query secdesc for share %s\n",
netname));
return;
}
- share_sd = info.info502->sd;
+ share_sd = info.share.info502.info_502_str.sd;
if (share_sd == NULL) {
DEBUG(1, ("Got no secdesc for share %s\n",
netname));
const char **argv)
{
int ret;
- BOOL r;
- uint32 hnd;
+ bool r;
+ ENUM_HND hnd;
uint32 i;
FILE *f;
for (i=0; i<num_tokens; i++)
collect_alias_memberships(&tokens[i].token);
- hnd = 0;
+ init_enum_hnd(&hnd, 0);
+
share_list.num_shares = 0;
share_list.shares = NULL;
struct rpc_pipe_client *pipe_hnd,
int argc, const char **argv)
{
- union srvsvc_NetShareInfo info;
- struct srvsvc_NetShareInfo2 info2;
- NTSTATUS result;
- uint32 parm_error = 0;
+ WERROR result;
if ((argc < 2) || (argc > 3)) {
d_fprintf(stderr, "usage: %s <share> <path> [comment]\n",
return NT_STATUS_INVALID_PARAMETER;
}
- info.info2 = &info2;
- info2.name = argv[0];
- info2.type = STYPE_DISKTREE;
- info2.comment = (argc == 3) ? argv[2] : "";
-
- result = rpccli_srvsvc_NetShareAdd(
- pipe_hnd, mem_ctx, NULL, 2, info, &parm_error);
+ result = rpccli_srvsvc_net_share_add(
+ pipe_hnd, mem_ctx, argv[0], STYPE_DISKTREE,
+ (argc == 3) ? argv[2] : "",
+ 0, 0, 0, argv[1], NULL, 2, NULL);
- return result;
+ return werror_to_ntstatus(result);
}
static NTSTATUS rpc_sh_share_delete(TALLOC_CTX *mem_ctx,
struct rpc_pipe_client *pipe_hnd,
int argc, const char **argv)
{
- NTSTATUS result;
+ WERROR result;
if (argc != 1) {
d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
return NT_STATUS_INVALID_PARAMETER;
}
- result = rpccli_srvsvc_NetShareDel(pipe_hnd, mem_ctx, NULL, argv[0], 0);
- return result;
+ result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
+ return werror_to_ntstatus(result);
}
static NTSTATUS rpc_sh_share_info(TALLOC_CTX *mem_ctx,
struct rpc_pipe_client *pipe_hnd,
int argc, const char **argv)
{
- union srvsvc_NetShareInfo info;
- NTSTATUS result;
+ SRV_SHARE_INFO info;
+ SRV_SHARE_INFO_2 *info2 = &info.share.info2;
+ WERROR result;
if (argc != 1) {
d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
return NT_STATUS_INVALID_PARAMETER;
}
- result = rpccli_srvsvc_NetShareGetInfo(
- pipe_hnd, mem_ctx, NULL, argv[0], 2, &info);
- if (!NT_STATUS_IS_OK(result)) {
+ result = rpccli_srvsvc_net_share_get_info(
+ pipe_hnd, mem_ctx, argv[0], 2, &info);
+ if (!W_ERROR_IS_OK(result)) {
goto done;
}
- d_printf("Name: %s\n", info.info2->name);
- d_printf("Comment: %s\n", info.info2->comment);
- d_printf("Path: %s\n", info.info2->path);
- d_printf("Password: %s\n", info.info2->password);
+ d_printf("Name: %s\n",
+ rpcstr_pull_unistr2_talloc(mem_ctx,
+ &info2->info_2_str.uni_netname));
+ d_printf("Comment: %s\n",
+ rpcstr_pull_unistr2_talloc(mem_ctx,
+ &info2->info_2_str.uni_remark));
+
+ d_printf("Path: %s\n",
+ rpcstr_pull_unistr2_talloc(mem_ctx,
+ &info2->info_2_str.uni_path));
+ d_printf("Password: %s\n",
+ rpcstr_pull_unistr2_talloc(mem_ctx,
+ &info2->info_2_str.uni_passwd));
done:
- return result;
+ return werror_to_ntstatus(result);
}
struct rpc_sh_cmd *net_rpc_share_cmds(TALLOC_CTX *mem_ctx,
int argc,
const char **argv)
{
- NTSTATUS result;
- result = rpccli_srvsvc_NetFileClose(pipe_hnd, mem_ctx, NULL, atoi(argv[0]));
- return NT_STATUS_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ return rpccli_srvsvc_NetFileClose(pipe_hnd, mem_ctx,
+ pipe_hnd->cli->desthost,
+ atoi(argv[0]), NULL);
}
/**
* @param str3 strings for FILE_INFO_3
**/
-static void display_file_info_3( struct srvsvc_NetFileInfo3 *info3 )
+static void display_file_info_3( FILE_INFO_3 *info3 )
{
+ fstring user = "", path = "";
+
+ rpcstr_pull_unistr2_fstring(user, info3->user);
+ rpcstr_pull_unistr2_fstring(path, info3->path);
+
d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
- info3->fid, info3->user, info3->permissions, info3->num_locks, info3->path);
+ info3->id, user, info3->perms, info3->num_locks, path);
}
/**
int argc,
const char **argv)
{
- union srvsvc_NetFileCtr ctr;
- NTSTATUS result;
- uint32 hnd;
+ SRV_FILE_INFO_CTR ctr;
+ WERROR result;
+ ENUM_HND hnd;
uint32 preferred_len = 0xffffffff, i;
const char *username=NULL;
- uint32 level = 3;
- uint32 numentries;
- hnd = 0;
+ init_enum_hnd(&hnd, 0);
/* if argc > 0, must be user command */
if (argc > 0)
username = smb_xstrdup(argv[0]);
- result = rpccli_srvsvc_NetFileEnum(pipe_hnd, mem_ctx, NULL, NULL,
- username, &level, &ctr,
- preferred_len, &numentries, &hnd);
+ result = rpccli_srvsvc_net_file_enum(pipe_hnd,
+ mem_ctx, 3, username, &ctr, preferred_len, &hnd);
- if (!NT_STATUS_IS_OK(result))
+ if (!W_ERROR_IS_OK(result))
goto done;
/* Display results */
"\nEnumerating open files on remote server:\n\n"\
"\nFileId Opened by Perms Locks Path"\
"\n------ --------- ----- ----- ---- \n");
- for (i = 0; i < numentries; i++)
- display_file_info_3(&ctr.ctr3->array[i]);
+ for (i = 0; i < ctr.num_entries; i++)
+ display_file_info_3(&ctr.file.info3[i]);
done:
- return NT_STATUS_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
/**
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- result = rpccli_initshutdown_Abort(pipe_hnd, mem_ctx, NULL);
+ result = rpccli_initshutdown_Abort(pipe_hnd, mem_ctx, NULL, NULL);
if (NT_STATUS_IS_OK(result)) {
d_printf("\nShutdown successfully aborted\n");
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- result = rpccli_winreg_AbortSystemShutdown(pipe_hnd, mem_ctx, NULL);
+ result = rpccli_winreg_AbortSystemShutdown(pipe_hnd, mem_ctx, NULL, NULL);
if (NT_STATUS_IS_OK(result)) {
d_printf("\nShutdown successfully aborted\n");
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
+NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
const char *domain_name,
struct cli_state *cli,
struct rpc_pipe_client *pipe_hnd,
/* create an entry */
result = rpccli_initshutdown_Init(pipe_hnd, mem_ctx, NULL,
- &msg_string, timeout, opt_force, opt_reboot);
+ &msg_string, timeout, opt_force, opt_reboot, NULL);
if (NT_STATUS_IS_OK(result)) {
d_printf("\nShutdown of remote machine succeeded\n");
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
+NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
const char *domain_name,
struct cli_state *cli,
struct rpc_pipe_client *pipe_hnd,
struct initshutdown_String msg_string;
struct initshutdown_String_sub s;
NTSTATUS result;
+ WERROR werr;
if (opt_comment) {
msg = opt_comment;
/* create an entry */
result = rpccli_winreg_InitiateSystemShutdown(pipe_hnd, mem_ctx, NULL,
- &msg_string, timeout, opt_force, opt_reboot);
+ &msg_string, timeout, opt_force, opt_reboot, &werr);
if (NT_STATUS_IS_OK(result)) {
d_printf("\nShutdown of remote machine succeeded\n");
} else {
d_fprintf(stderr, "\nShutdown of remote machine failed\n");
- if ( W_ERROR_EQUAL(ntstatus_to_werror(result),WERR_MACHINE_LOCKED) )
+ if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
else
- d_fprintf(stderr, "\nresult was: %s\n", nt_errstr(result));
+ d_fprintf(stderr, "\nresult was: %s\n", dos_errstr(werr));
}
return result;
static int rpc_trustdom_establish(int argc, const char **argv)
{
struct cli_state *cli = NULL;
- struct in_addr server_ip;
+ struct sockaddr_storage server_ss;
struct rpc_pipe_client *pipe_hnd = NULL;
POLICY_HND connect_hnd;
TALLOC_CTX *mem_ctx;
NTSTATUS nt_status;
DOM_SID *domain_sid;
-
+
char* domain_name;
char* domain_name_pol;
char* acct_name;
fstring pdc_name;
+ char *dc_name;
/*
* Connect to \\server\ipc$ as 'our domain' account with password
/* account name used at first is our domain's name with '$' */
asprintf(&acct_name, "%s$", lp_workgroup());
strupper_m(acct_name);
-
+
/*
* opt_workgroup will be used by connection functions further,
* hence it should be set to remote domain name instead of ours
if (opt_workgroup) {
opt_workgroup = smb_xstrdup(domain_name);
};
-
+
opt_user_name = acct_name;
/* find the domain controller */
- if (!net_find_pdc(&server_ip, pdc_name, domain_name)) {
+ if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
return -1;
}
/* connect to ipc$ as username/password */
- nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
+ nt_status = connect_to_ipc(&cli, &server_ss, pdc_name);
if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
/* Is it trusting domain account for sure ? */
/* store who we connected to */
saf_store( domain_name, pdc_name );
-
+
/*
* Connect to \\server\ipc$ again (this time anonymously)
*/
-
- nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
-
+
+ nt_status = connect_to_ipc_anonymous(&cli, &server_ss, (char*)pdc_name);
+
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
domain_name, nt_errstr(nt_status)));
/*
* Use NetServerEnum2 to make sure we're talking to a proper server
*/
-
- if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) {
+
+ if (!cli_get_pdc_name(cli, domain_name, &dc_name)) {
DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
for domain %s\n", domain_name));
cli_shutdown(cli);
return -1;
}
+ SAFE_FREE(dc_name);
if (!(mem_ctx = talloc_init("establishing trust relationship to "
"domain %s", domain_name))) {
}
#ifdef DEBUG_PASSWORD
- DEBUG(100,("sucessfully vampired trusted domain [%s], sid: [%s], password: [%s]\n",
- trusted_dom_name, sid_string_static(&dom_sid), cleartextpwd));
+ DEBUG(100,("sucessfully vampired trusted domain [%s], sid: [%s], "
+ "password: [%s]\n", trusted_dom_name,
+ sid_string_dbg(&dom_sid), cleartextpwd));
#endif
done:
};
/* open \PIPE\lsarpc and open policy handle */
- if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
- DEBUG(0, ("Couldn't connect to domain controller\n"));
+ nt_status = net_make_ipc_connection(NET_FLAGS_PDC, &cli);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0, ("Couldn't connect to domain controller: %s\n",
+ nt_errstr(nt_status)));
talloc_destroy(mem_ctx);
return -1;
};
};
/* open \PIPE\lsarpc and open policy handle */
- if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
- DEBUG(0, ("Couldn't connect to domain controller\n"));
+ nt_status = net_make_ipc_connection(NET_FLAGS_PDC, &cli);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0, ("Couldn't connect to domain controller: %s\n",
+ nt_errstr(nt_status)));
talloc_destroy(mem_ctx);
return -1;
};
d_printf("%s%s", trusting_dom_names[i], padding);
/* connect to remote domain controller */
- remote_cli = net_make_ipc_connection(NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS);
- if (remote_cli) {
+ nt_status = net_make_ipc_connection(
+ NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
+ &remote_cli);
+ if (NT_STATUS_IS_OK(nt_status)) {
/* query for domain's sid */
if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
d_fprintf(stderr, "couldn't get domain's sid\n");
cli_shutdown(remote_cli);
} else {
- d_fprintf(stderr, "domain controller is not responding\n");
+ d_fprintf(stderr, "domain controller is not "
+ "responding: %s\n",
+ nt_errstr(nt_status));
};
};
* Check if a server will take rpc commands
* @param flags Type of server to connect to (PDC, DMB, localhost)
* if the host is not explicitly specified
- * @return BOOL (true means rpc supported)
+ * @return bool (true means rpc supported)
*/
-BOOL net_rpc_check(unsigned flags)
+bool net_rpc_check(unsigned flags)
{
struct cli_state *cli;
- BOOL ret = False;
- struct in_addr server_ip;
+ bool ret = False;
+ struct sockaddr_storage server_ss;
char *server_name = NULL;
NTSTATUS status;
/* flags (i.e. server type) may depend on command */
- if (!net_find_server(NULL, flags, &server_ip, &server_name))
+ if (!net_find_server(NULL, flags, &server_ss, &server_name))
return False;
if ((cli = cli_initialise()) == NULL) {
return False;
}
- status = cli_connect(cli, server_name, &server_ip);
+ status = cli_connect(cli, server_name, &server_ss);
if (!NT_STATUS_IS_OK(status))
goto done;
- if (!attempt_netbios_session_request(&cli, global_myname(),
- server_name, &server_ip))
+ if (!attempt_netbios_session_request(&cli, global_myname(),
+ server_name, &server_ss))
goto done;
if (!cli_negprot(cli))
goto done;
{
d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
d_printf(" net rpc join \t\t\tto join a domain \n");
- d_printf(" net rpc oldjoin \t\t\tto join a domain created in server manager\n");
+ d_printf(" net rpc oldjoin \t\tto join a domain created in server manager\n");
d_printf(" net rpc testjoin \t\ttests that a join is valid\n");
d_printf(" net rpc user \t\t\tto add, delete and list users\n");
d_printf(" net rpc password <username> [<password>] -Uadmin_username%%admin_pass\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");
d_printf(" net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
- d_printf(" net rpc samdump \t\tdiplay an NT PDC's users, groups and other data\n");
+ d_printf(" net rpc samdump \t\tdisplay an NT PDC's users, groups and other data\n");
d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n");
d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");