summaryrefslogtreecommitdiff
path: root/source3/utils/net_ads.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/utils/net_ads.c')
-rw-r--r--source3/utils/net_ads.c91
1 files changed, 71 insertions, 20 deletions
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 631e235127..3b955742d8 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -127,9 +127,14 @@ static ADS_STRUCT *ads_startup(void)
ADS_STATUS status;
BOOL need_password = False;
BOOL second_time = False;
- char *cp;
+ char *cp;
- ads = ads_init(NULL, opt_target_workgroup, opt_host);
+ /* lp_realm() should be handled by a command line param,
+ However, the join requires that realm be set in smb.conf
+ and compares our realm with the remote server's so this is
+ ok until someone needs more flexibility */
+
+ ads = ads_init(lp_realm(), opt_target_workgroup, opt_host);
if (!opt_user_name) {
opt_user_name = "administrator";
@@ -579,10 +584,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_target_workgroup, NULL, NULL);
- opt_user_name = user_name;
+ net_use_machine_password();
}
if (!(ads = ads_startup())) {
@@ -603,7 +605,6 @@ static int net_ads_leave(int argc, const char **argv)
static int net_ads_join_ok(void)
{
- char *user_name;
ADS_STRUCT *ads = NULL;
if (!secrets_init()) {
@@ -611,9 +612,7 @@ static int net_ads_join_ok(void)
return -1;
}
- asprintf(&user_name, "%s$", global_myname());
- opt_user_name = user_name;
- opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
+ net_use_machine_password();
if (!(ads = ads_startup())) {
return -1;
@@ -648,6 +647,7 @@ int net_ads_join(int argc, const char **argv)
ADS_STRUCT *ads;
ADS_STATUS rc;
char *password;
+ char *machine_account = NULL;
char *tmp_password;
const char *org_unit = "Computers";
char *dn;
@@ -656,6 +656,8 @@ int net_ads_join(int argc, const char **argv)
char *ou_str;
uint32 sec_channel_type = SEC_CHAN_WKSTA;
uint32 account_type = UF_WORKSTATION_TRUST_ACCOUNT;
+ char *short_domain_name = NULL;
+ TALLOC_CTX *ctx = NULL;
if (argc > 0) org_unit = argv[0];
@@ -669,6 +671,16 @@ int net_ads_join(int argc, const char **argv)
if (!(ads = ads_startup())) return -1;
+ if (!*lp_realm()) {
+ d_printf("realm must be set in in smb.conf for ADS join to succeed.\n");
+ return -1;
+ }
+
+ if (strcmp(ads->config.realm, lp_realm()) != 0) {
+ d_printf("realm of remote server (%s) and realm in smb.conf (%s) DO NOT match. Aborting join\n", ads->config.realm, lp_realm());
+ return -1;
+ }
+
ou_str = ads_ou_string(org_unit);
asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path);
free(ou_str);
@@ -696,16 +708,47 @@ int net_ads_join(int argc, const char **argv)
rc = ads_domain_sid(ads, &dom_sid);
if (!ADS_ERR_OK(rc)) {
- d_printf("ads_domain_sid: %s\n", ads_errstr(rc));
+ d_printf("ads_domain_sid: %s\n", ads_errstr(rc));
+ return -1;
+ }
+
+ if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
+ d_printf("asprintf failed\n");
return -1;
}
- rc = ads_set_machine_password(ads, global_myname(), password);
+ rc = ads_set_machine_password(ads, machine_account, password);
if (!ADS_ERR_OK(rc)) {
d_printf("ads_set_machine_password: %s\n", ads_errstr(rc));
return -1;
}
-
+
+ /* make sure we get the right workgroup */
+
+ if ( !(ctx = talloc_init("net ads join")) ) {
+ d_printf("talloc_init() failed!\n");
+ return -1;
+ }
+
+ rc = ads_workgroup_name(ads, ctx, &short_domain_name);
+ if ( ADS_ERR_OK(rc) ) {
+ if ( !strequal(lp_workgroup(), short_domain_name) ) {
+ d_printf("The workgroup in smb.conf does not match the short\n");
+ d_printf("domain name obtained from the server.\n");
+ d_printf("Using the name [%s] from the server.\n", short_domain_name);
+ d_printf("You should set \"workgroup = %s\" in smb.conf.\n", short_domain_name);
+ }
+ }
+ else
+ short_domain_name = lp_workgroup();
+
+ d_printf("Using short domain name -- %s\n", short_domain_name);
+
+ /* HACK ALRET! Store the sid and password under bother the lp_workgroup()
+ value from smb.conf and the string returned from the server. The former is
+ neede to bootstrap winbindd's first connection to the DC to get the real
+ short domain name --jerry */
+
if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) {
DEBUG(1,("Failed to save domain sid\n"));
return -1;
@@ -716,10 +759,22 @@ int net_ads_join(int argc, const char **argv)
return -1;
}
- d_printf("Joined '%s' to realm '%s'\n", global_myname(), ads->config.realm);
+ if (!secrets_store_domain_sid(short_domain_name, &dom_sid)) {
+ DEBUG(1,("Failed to save domain sid\n"));
+ return -1;
+ }
- free(password);
+ if (!secrets_store_machine_password(password, short_domain_name, sec_channel_type)) {
+ DEBUG(1,("Failed to save machine password\n"));
+ return -1;
+ }
+
+ d_printf("Joined '%s' to realm '%s'\n", global_myname(), ads->config.realm);
+ SAFE_FREE(password);
+ SAFE_FREE(machine_account);
+ if ( ctx )
+ talloc_destroy(ctx);
return 0;
}
@@ -1020,17 +1075,13 @@ int net_ads_changetrustpw(int argc, const char **argv)
char *host_principal;
char *hostname;
ADS_STATUS ret;
- char *user_name;
if (!secrets_init()) {
DEBUG(1,("Failed to initialise secrets database\n"));
return -1;
}
- asprintf(&user_name, "%s$", global_myname());
- opt_user_name = user_name;
-
- opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
+ net_use_machine_password();
use_in_memory_ccache();