svn commit: samba r19257 - in branches/SAMBA_3_0/source/utils: .

jra at samba.org jra at samba.org
Thu Oct 12 21:03:28 GMT 2006


Author: jra
Date: 2006-10-12 21:03:28 +0000 (Thu, 12 Oct 2006)
New Revision: 19257

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=19257

Log:
Janitor for Guenther - as well as a little massaging to make
his patch fit SAMBA_3_0. (This is guenthers code). Make
site support work correctly in net ads join.
Jeremy.

Modified:
   branches/SAMBA_3_0/source/utils/net_ads.c


Changeset:
Modified: branches/SAMBA_3_0/source/utils/net_ads.c
===================================================================
--- branches/SAMBA_3_0/source/utils/net_ads.c	2006-10-12 20:21:46 UTC (rev 19256)
+++ branches/SAMBA_3_0/source/utils/net_ads.c	2006-10-12 21:03:28 UTC (rev 19257)
@@ -153,20 +153,12 @@
 static int net_ads_lookup(int argc, const char **argv)
 {
 	ADS_STRUCT *ads;
-	ADS_STATUS status;
-	const char *realm = assume_own_realm();
 
-	ads = ads_init(realm, opt_target_workgroup, opt_host);
-	if (ads) {
-		ads->auth.flags |= ADS_AUTH_NO_BIND;
-	}
-
-	status = ads_connect(ads);
-	if (!ADS_ERR_OK(status) || !ads) {
+	if (!ADS_ERR_OK(ads_startup_nobind(False, &ads))) {
 		d_fprintf(stderr, "Didn't find the cldap server!\n");
 		return -1;
 	}
-	
+
 	if (!ads->config.realm) {
 		ads->config.realm = CONST_DISCARD(char *, opt_target_workgroup);
 		ads->ldap_port = 389;
@@ -180,14 +172,12 @@
 static int net_ads_info(int argc, const char **argv)
 {
 	ADS_STRUCT *ads;
-	const char *realm = assume_own_realm();
 
-	if ( (ads = ads_init(realm, opt_target_workgroup, opt_host)) != NULL ) {
-		ads->auth.flags |= ADS_AUTH_NO_BIND;
+	if (!ADS_ERR_OK(ads_startup_nobind(False, &ads))) {
+		d_fprintf(stderr, "Didn't find the ldap server!\n");
+		return -1;
 	}
 
-	ads_connect(ads);
-
 	if (!ads || !ads->config.realm) {
 		d_fprintf(stderr, "Didn't find the ldap server!\n");
 		return -1;
@@ -219,25 +209,34 @@
 	setenv(KRB5_ENV_CCNAME, "MEMORY:net_ads", 1);
 }
 
-ADS_STATUS ads_startup(BOOL only_own_domain, ADS_STRUCT **ads)
+static ADS_STATUS ads_startup_int(BOOL only_own_domain, uint32 auth_flags, ADS_STRUCT **ads_ret)
 {
+	ADS_STRUCT *ads = NULL;
 	ADS_STATUS status;
 	BOOL need_password = False;
 	BOOL second_time = False;
 	char *cp;
 	const char *realm = NULL;
-	
+	BOOL tried_closest_dc = False;
+	BOOL closest_dc = False;
+	BOOL site_matches = False;
+
 	/* 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_ret = NULL;
+
+retry_connect:
  	if (only_own_domain) {
 		realm = lp_realm();
+	} else {
+		realm = assume_own_realm();
 	}
-   
-	*ads = ads_init(realm, opt_target_workgroup, opt_host);
 
+	ads = ads_init(realm, opt_target_workgroup, opt_host);
+
 	if (!opt_user_name) {
 		opt_user_name = "administrator";
 	}
@@ -248,31 +247,39 @@
 
 retry:
 	if (!opt_password && need_password && !opt_machine_pass) {
-		char *prompt;
+		char *prompt = NULL;
 		asprintf(&prompt,"%s's password: ", opt_user_name);
+		if (!prompt) {
+			ads_destroy(&ads);
+			return ADS_ERROR(LDAP_NO_MEMORY);
+		}
 		opt_password = getpass(prompt);
 		free(prompt);
 	}
 
 	if (opt_password) {
 		use_in_memory_ccache();
-		(*ads)->auth.password = smb_xstrdup(opt_password);
+		SAFE_FREE(ads->auth.password);
+		ads->auth.password = smb_xstrdup(opt_password);
 	}
 
-	(*ads)->auth.user_name = smb_xstrdup(opt_user_name);
+	ads->auth.flags |= auth_flags;
+	SAFE_FREE(ads->auth.user_name);
+	ads->auth.user_name = smb_xstrdup(opt_user_name);
 
        /*
         * If the username is of the form "name at realm", 
         * extract the realm and convert to upper case.
         * This is only used to establish the connection.
         */
-       if ((cp = strchr_m((*ads)->auth.user_name, '@'))!=0) {
-               *cp++ = '\0';
-               (*ads)->auth.realm = smb_xstrdup(cp);
-               strupper_m((*ads)->auth.realm);
+       if ((cp = strchr_m(ads->auth.user_name, '@'))!=0) {
+		*cp++ = '\0';
+		SAFE_FREE(ads->auth.realm);
+		ads->auth.realm = smb_xstrdup(cp);
+		strupper_m(ads->auth.realm);
        }
 
-	status = ads_connect(*ads);
+	status = ads_connect(ads);
 
 	if (!ADS_ERR_OK(status)) {
 		if (!need_password && !second_time) {
@@ -280,13 +287,51 @@
 			second_time = True;
 			goto retry;
 		} else {
-			ads_destroy(ads);
+			ads_destroy(&ads);
+			return status;
 		}
 	}
+
+	/* when contacting our own domain, make sure we use the closest DC.
+	 * This is done by reconnecting to ADS because only the first call to
+	 * ads_connect will give us our own sitename */
+
+	closest_dc = (ads->config.flags & ADS_CLOSEST);
+	site_matches = ads_sitename_match(ads);
+
+	DEBUG(10,("ads_startup_int: DC %s closest DC\n", closest_dc ? "is":"is *NOT*"));
+	DEBUG(10,("ads_startup_int: sitenames %s match\n", site_matches ? "do":"do *NOT*"));
+
+	if ((only_own_domain || !opt_host) && !tried_closest_dc) {
+
+		tried_closest_dc = True; /* avoid loop */
+
+		if (!closest_dc || !site_matches) {
+
+			namecache_delete(ads->server.realm, 0x1C);
+			namecache_delete(ads->server.workgroup, 0x1C);
+
+			ads_destroy(&ads);
+			ads = NULL;
+
+			goto retry_connect;
+		}
+	}
+
+	*ads_ret = ads;
 	return status;
 }
 
+ADS_STATUS ads_startup(BOOL only_own_domain, ADS_STRUCT **ads)
+{
+	return ads_startup_int(only_own_domain, 0, ads);
+}
 
+ADS_STATUS ads_startup_nobind(BOOL only_own_domain, ADS_STRUCT **ads)
+{
+	return ads_startup_int(only_own_domain, ADS_AUTH_NO_BIND, ads);
+}
+
 /*
   Check to see if connection can be made via ads.
   ads_startup() stores the password in opt_password if it needs to so
@@ -327,17 +372,9 @@
 static int net_ads_workgroup(int argc, const char **argv)
 {
 	ADS_STRUCT *ads;
-	ADS_STATUS status;
-	const char *realm = assume_own_realm();
 	struct cldap_netlogon_reply reply;
 
-	ads = ads_init(realm, opt_target_workgroup, opt_host);
-	if (ads) {
-		ads->auth.flags |= ADS_AUTH_NO_BIND;
-	}
-
-	status = ads_connect(ads);
-	if (!ADS_ERR_OK(status) || !ads) {
+	if (!ADS_ERR_OK(ads_startup_nobind(False, &ads))) {
 		d_fprintf(stderr, "Didn't find the cldap server!\n");
 		return -1;
 	}



More information about the samba-cvs mailing list