summaryrefslogtreecommitdiff
path: root/source3/utils
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2003-04-16 10:20:14 +0000
committerAndrew Bartlett <abartlet@samba.org>2003-04-16 10:20:14 +0000
commit2cb0b91ed19c0fbbc3bfb1b5a35c6af2acf5b5d7 (patch)
tree70203479d0f7bebcbb80e7af48f560715162171a /source3/utils
parentf9cde25fa492e071960e0857f5075222119a0d1c (diff)
downloadsamba-2cb0b91ed19c0fbbc3bfb1b5a35c6af2acf5b5d7.tar.gz
samba-2cb0b91ed19c0fbbc3bfb1b5a35c6af2acf5b5d7.tar.bz2
samba-2cb0b91ed19c0fbbc3bfb1b5a35c6af2acf5b5d7.zip
Store the type of 'sec channel' that we establish to the DC. If we are a
workstation, we have to use the workstation type, if we have a BDC account, we must use the BDC type - even if we are pretending to be a workstation at the moment. Also actually store and retreive the last change time, so we can do periodic password changes again (for RPC at least). And finally, a couple of minor fixes to 'net'. Andrew Bartlett (This used to be commit 6e6b7b79edae3efd0197651e9a8ce6775c001cf2)
Diffstat (limited to 'source3/utils')
-rw-r--r--source3/utils/net.c32
-rw-r--r--source3/utils/net.h2
-rw-r--r--source3/utils/net_ads.c17
-rw-r--r--source3/utils/net_rpc.c83
-rw-r--r--source3/utils/net_rpc_join.c62
-rw-r--r--source3/utils/net_rpc_samsync.c11
6 files changed, 151 insertions, 56 deletions
diff --git a/source3/utils/net.c b/source3/utils/net.c
index 9d8441e649..5d526e22df 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -68,7 +68,7 @@ int opt_force = 0;
int opt_port = 0;
int opt_maxusers = -1;
const char *opt_comment = "";
-char *opt_container = "cn=Users";
+const char *opt_container = "cn=Users";
int opt_flags = -1;
int opt_timeout = 0;
const char *opt_target_workgroup = NULL;
@@ -77,6 +77,27 @@ static int opt_machine_pass = 0;
BOOL opt_have_ip = False;
struct in_addr opt_dest_ip;
+uint32 get_sec_channel_type(const char *param)
+{
+ if (param && *param) {
+ return get_default_sec_channel();
+ } else {
+ if (strcasecmp(param, "PDC")==0) {
+ return SEC_CHAN_BDC;
+ } else if (strcasecmp(param, "BDC")==0) {
+ return SEC_CHAN_BDC;
+ } else if (strcasecmp(param, "MEMBER")==0) {
+ return SEC_CHAN_WKSTA;
+#if 0
+ } else if (strcasecmp(param, "DOMAIN")==0) {
+ return SEC_CHAN_DOMAIN;
+#endif
+ } else {
+ return get_default_sec_channel();
+ }
+ }
+}
+
/*
run a function from a function table. If not found then
call the specified usage function
@@ -602,11 +623,11 @@ static struct functable net_func[] = {
}
if (!opt_workgroup) {
- opt_workgroup = lp_workgroup();
+ opt_workgroup = smb_xstrdup(lp_workgroup());
}
if (!opt_target_workgroup) {
- opt_target_workgroup = strdup(lp_workgroup());
+ opt_target_workgroup = smb_xstrdup(lp_workgroup());
}
if (!init_names())
@@ -615,7 +636,7 @@ static struct functable net_func[] = {
load_interfaces();
if (opt_machine_pass) {
- char *user;
+ char *user = NULL;
/* it is very useful to be able to make ads queries as the
machine account for testing purposes and for domain leave */
@@ -624,9 +645,10 @@ static struct functable net_func[] = {
exit(1);
}
+ opt_password = secrets_fetch_machine_password(opt_workgroup, NULL, NULL);
+
asprintf(&user,"%s$", global_myname());
opt_user_name = user;
- opt_password = secrets_fetch_machine_password();
if (!opt_password) {
d_printf("ERROR: Unable to fetch machine password\n");
exit(1);
diff --git a/source3/utils/net.h b/source3/utils/net.h
index c1b49a919b..f83d0169bf 100644
--- a/source3/utils/net.h
+++ b/source3/utils/net.h
@@ -38,7 +38,7 @@
extern int opt_maxusers;
extern const char *opt_comment;
-extern char *opt_container;
+extern const char *opt_container;
extern int opt_flags;
extern const char *opt_comment;
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 5a8265f0b9..91f82a5dbe 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -575,7 +575,7 @@ static int net_ads_leave(int argc, const char **argv)
if (!opt_password) {
char *user_name;
asprintf(&user_name, "%s$", global_myname());
- opt_password = secrets_fetch_machine_password();
+ opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
opt_user_name = user_name;
}
@@ -607,7 +607,7 @@ static int net_ads_join_ok(void)
asprintf(&user_name, "%s$", global_myname());
opt_user_name = user_name;
- opt_password = secrets_fetch_machine_password();
+ opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
if (!(ads = ads_startup())) {
return -1;
@@ -648,6 +648,8 @@ int net_ads_join(int argc, const char **argv)
void *res;
DOM_SID dom_sid;
char *ou_str;
+ uint32 sec_channel_type;
+ uint32 account_type = UF_WORKSTATION_TRUST_ACCOUNT;
if (argc > 0) org_unit = argv[0];
@@ -656,6 +658,11 @@ int net_ads_join(int argc, const char **argv)
return -1;
}
+ /* check what type of join
+ TODO: make this variable like RPC
+ */
+ account_type = UF_WORKSTATION_TRUST_ACCOUNT;
+
tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
password = strdup(tmp_password);
@@ -680,7 +687,7 @@ int net_ads_join(int argc, const char **argv)
return -1;
}
- rc = ads_join_realm(ads, global_myname(), org_unit);
+ rc = ads_join_realm(ads, global_myname(), account_type, org_unit);
if (!ADS_ERR_OK(rc)) {
d_printf("ads_join_realm: %s\n", ads_errstr(rc));
return -1;
@@ -703,7 +710,7 @@ int net_ads_join(int argc, const char **argv)
return -1;
}
- if (!secrets_store_machine_password(password)) {
+ if (!secrets_store_machine_password(password, lp_workgroup(), sec_channel_type)) {
DEBUG(1,("Failed to save machine password\n"));
return -1;
}
@@ -956,7 +963,7 @@ int net_ads_changetrustpw(int argc, const char **argv)
asprintf(&user_name, "%s$", global_myname());
opt_user_name = user_name;
- opt_password = secrets_fetch_machine_password();
+ opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
use_in_memory_ccache();
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index a35cdd0b5b..9ae50aaf0d 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -235,8 +235,9 @@ int net_rpc_changetrustpw(int argc, const char **argv)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
+static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, const char **argv) {
fstring trust_passwd;
unsigned char orig_trust_passwd_hash[16];
@@ -254,10 +255,22 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl
E_md4hash(trust_passwd, orig_trust_passwd_hash);
- result = trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash);
+ result = trust_pw_change_and_store_it(cli, mem_ctx, opt_target_workgroup,
+ orig_trust_passwd_hash,
+ SEC_CHAN_WKSTA);
+
+ /* SEC_CHAN_WKSTA specified specifically, as you cannot use this
+ to join a BDC to the domain (MS won't allow it, and is *really*
+ insecure) */
if (NT_STATUS_IS_OK(result))
- printf("Joined domain %s.\n",lp_workgroup());
+ printf("Joined domain %s.\n",opt_target_workgroup);
+
+
+ if (!secrets_store_domain_sid(opt_target_workgroup, domain_sid)) {
+ DEBUG(0, ("error storing domain sid for %s\n", opt_target_workgroup));
+ result = NT_STATUS_UNSUCCESSFUL;
+ }
return result;
}
@@ -274,7 +287,38 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl
static int net_rpc_join_oldstyle(int argc, const char **argv)
{
- return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals,
+ uint32 sec_channel_type;
+ /* check what type of join */
+ if (argc >= 0) {
+ sec_channel_type = get_sec_channel_type(argv[0]);
+ } else {
+ sec_channel_type = get_sec_channel_type(NULL);
+ }
+
+ if (sec_channel_type != SEC_CHAN_WKSTA)
+ return 1;
+
+ return run_rpc_command(NULL, PI_NETLOGON,
+ NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
+ rpc_join_oldstyle_internals,
+ argc, argv);
+}
+
+/**
+ * Join a domain, the old way.
+ *
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return A shell status integer (0 for success)
+ **/
+
+static int net_rpc_oldjoin(int argc, const char **argv)
+{
+ return run_rpc_command(NULL, PI_NETLOGON,
+ NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
+ rpc_join_oldstyle_internals,
argc, argv);
}
@@ -287,11 +331,13 @@ static int net_rpc_join_oldstyle(int argc, const char **argv)
static int rpc_join_usage(int argc, const char **argv)
{
- d_printf("net rpc join -U <username>[%%password] [options]\n"\
+ d_printf("net rpc join -U <username>[%%password] <type>[options]\n"\
"\t to join a domain with admin username & password\n"\
- "\t\t password will be prompted if none is specified\n");
- d_printf("net rpc join [options except -U]\n"\
- "\t to join a domain created in server manager\n\n\n");
+ "\t\t password will be prompted if needed and none is specified\n"\
+ "\t <type> can be (default MEMBER)\n"\
+ "\t\t BDC - Join as a BDC\n"\
+ "\t\t PDC - Join as a PDC\n"\
+ "\t\t MEMBER - Join as a MEMBER server\n");
net_common_flags_usage(argc, argv);
return -1;
@@ -311,19 +357,10 @@ static int rpc_join_usage(int argc, const char **argv)
int net_rpc_join(int argc, const char **argv)
{
- struct functable func[] = {
- {"oldstyle", net_rpc_join_oldstyle},
- {NULL, NULL}
- };
-
- if (argc == 0) {
- if ((net_rpc_join_oldstyle(argc, argv) == 0))
- return 0;
-
- return net_rpc_join_newstyle(argc, argv);
- }
-
- return net_run_function(argc, argv, func, rpc_join_usage);
+ if ((net_rpc_join_oldstyle(argc, argv) == 0))
+ return 0;
+
+ return net_rpc_join_newstyle(argc, argv);
}
@@ -2179,6 +2216,7 @@ int net_rpc_usage(int argc, const char **argv)
{
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\n\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 group \t\tto list groups\n");
@@ -2245,6 +2283,7 @@ int net_rpc(int argc, const char **argv)
struct functable func[] = {
{"info", net_rpc_info},
{"join", net_rpc_join},
+ {"oldjoin", net_rpc_oldjoin},
{"testjoin", net_rpc_testjoin},
{"user", net_rpc_user},
{"group", net_rpc_group},
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index e2fd9aa434..35564b1e10 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -62,18 +62,12 @@ int net_rpc_join_ok(const char *domain)
}
if (!secrets_fetch_trust_account_password(domain,
- stored_md4_trust_password, NULL)) {
+ stored_md4_trust_password,
+ NULL, &channel)) {
DEBUG(0,("Could not retreive domain trust secret"));
goto done;
}
- if (lp_server_role() == ROLE_DOMAIN_BDC ||
- lp_server_role() == ROLE_DOMAIN_PDC) {
- channel = SEC_CHAN_BDC;
- } else {
- channel = SEC_CHAN_WKSTA;
- }
-
CHECK_RPC_ERR(cli_nt_setup_creds(cli,
channel,
stored_md4_trust_password, &neg_flags, 2),
@@ -108,7 +102,8 @@ int net_rpc_join_newstyle(int argc, const char **argv)
struct cli_state *cli;
TALLOC_CTX *mem_ctx;
- uint32 acb_info;
+ uint32 acb_info = ACB_WSTRUST;
+ uint32 sec_channel_type;
/* rpc variables */
@@ -121,10 +116,11 @@ int net_rpc_join_newstyle(int argc, const char **argv)
char *clear_trust_password = NULL;
fstring ucs2_trust_password;
int ucs2_pw_len;
- uchar pwbuf[516], sess_key[16];
+ uchar pwbuf[516];
SAM_USERINFO_CTR ctr;
SAM_USER_INFO_24 p24;
SAM_USER_INFO_10 p10;
+ uchar md4_trust_password[16];
/* Misc */
@@ -135,6 +131,25 @@ int net_rpc_join_newstyle(int argc, const char **argv)
uint32 flags = 0x3e8;
char *acct_name;
const char *const_acct_name;
+ uint32 neg_flags = 0x000001ff;
+
+ /* check what type of join */
+ if (argc >= 0) {
+ sec_channel_type = get_sec_channel_type(argv[0]);
+ } else {
+ sec_channel_type = get_sec_channel_type(NULL);
+ }
+
+ switch (sec_channel_type) {
+ case SEC_CHAN_WKSTA:
+ acb_info = ACB_WSTRUST;
+ case SEC_CHAN_BDC:
+ acb_info = ACB_SVRTRUST;
+#if 0
+ case SEC_CHAN_DOMAIN:
+ acb_info = ACB_DOMTRUST;
+#endif
+ }
/* Connect to remote machine */
@@ -189,8 +204,6 @@ int net_rpc_join_newstyle(int argc, const char **argv)
strlower(acct_name);
const_acct_name = acct_name;
- acb_info = ((lp_server_role() == ROLE_DOMAIN_BDC) || lp_server_role() == ROLE_DOMAIN_PDC) ? ACB_SVRTRUST : ACB_WSTRUST;
-
result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
acct_name, acb_info,
0xe005000b, &user_pol,
@@ -245,6 +258,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
char *str;
str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
clear_trust_password = strdup(str);
+ E_md4hash(clear_trust_password, md4_trust_password);
}
ucs2_pw_len = push_ucs2(NULL, ucs2_trust_password,
@@ -287,8 +301,22 @@ int net_rpc_join_newstyle(int argc, const char **argv)
as a normal user with "Add workstation to domain" privilege. */
result = cli_samr_set_userinfo2(cli, mem_ctx, &user_pol, 0x10,
- sess_key, &ctr);
+ cli->user_session_key, &ctr);
+
+ /* Now check the whole process from top-to-bottom */
+ cli_samr_close(cli, mem_ctx, &user_pol);
+ cli_nt_session_close(cli); /* Done with this pipe */
+ if (!cli_nt_session_open(cli, PI_NETLOGON)) {
+ DEBUG(0,("Error connecting to NETLOGON pipe\n"));
+ goto done;
+ }
+
+ CHECK_RPC_ERR(cli_nt_setup_creds(cli,
+ sec_channel_type,
+ md4_trust_password, &neg_flags, 2),
+ "error in domain join verification");
+
/* Now store the secret in the secrets database */
strupper(domain);
@@ -298,14 +326,11 @@ int net_rpc_join_newstyle(int argc, const char **argv)
goto done;
}
- if (!secrets_store_machine_password(clear_trust_password)) {
+ if (!secrets_store_machine_password(clear_trust_password, domain, sec_channel_type)) {
DEBUG(0, ("error storing plaintext domain secrets for %s\n", domain));
}
- /* Now check the whole process from top-to-bottom */
- cli_samr_close(cli, mem_ctx, &user_pol);
- cli_nt_session_close(cli); /* Done with this pipe */
-
+ /* double-check, connection from scratch */
retval = net_rpc_join_ok(domain);
done:
@@ -317,7 +342,6 @@ done:
/* Display success or failure */
if (retval != 0) {
- trust_password_delete(domain);
fprintf(stderr,"Unable to join domain %s.\n",domain);
} else {
printf("Joined domain %s.\n",domain);
diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c
index b886119eef..909ed298cb 100644
--- a/source3/utils/net_rpc_samsync.c
+++ b/source3/utils/net_rpc_samsync.c
@@ -198,6 +198,7 @@ int rpc_samdump(int argc, const char **argv)
struct cli_state *cli = NULL;
uchar trust_password[16];
DOM_CRED ret_creds;
+ uint32 sec_channel;
ZERO_STRUCT(ret_creds);
@@ -210,12 +211,12 @@ int rpc_samdump(int argc, const char **argv)
if (!secrets_fetch_trust_account_password(lp_workgroup(),
trust_password,
- NULL)) {
+ NULL, &sec_channel)) {
DEBUG(0,("Could not fetch trust account password\n"));
goto fail;
}
- if (!cli_nt_open_netlogon(cli, trust_password, SEC_CHAN_BDC)) {
+ if (!cli_nt_open_netlogon(cli, trust_password, sec_channel)) {
DEBUG(0,("Error connecting to NETLOGON pipe\n"));
goto fail;
}
@@ -810,6 +811,7 @@ int rpc_vampire(int argc, const char **argv)
DOM_CRED ret_creds;
uint32 neg_flags = 0x000001ff;
DOM_SID dom_sid;
+ uint32 sec_channel;
ZERO_STRUCT(ret_creds);
@@ -825,12 +827,13 @@ int rpc_vampire(int argc, const char **argv)
}
if (!secrets_fetch_trust_account_password(lp_workgroup(),
- trust_password, NULL)) {
+ trust_password, NULL,
+ &sec_channel)) {
d_printf("Could not retrieve domain trust secret\n");
goto fail;
}
- result = cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_password,
+ result = cli_nt_setup_creds(cli, sec_channel, trust_password,
&neg_flags, 2);
if (!NT_STATUS_IS_OK(result)) {
d_printf("Failed to setup BDC creds\n");