svn commit: samba r17943 - in branches/SAMBA_3_0/source: include libads libsmb nsswitch

jra at samba.org jra at samba.org
Thu Aug 31 01:20:26 GMT 2006


Author: jra
Date: 2006-08-31 01:20:21 +0000 (Thu, 31 Aug 2006)
New Revision: 17943

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

Log:
The horror, the horror. Add KDC site support by
writing out a custom krb5.conf file containing
the KDC I need. This may suck.... Needs some
testing :-).
Jeremy.

Modified:
   branches/SAMBA_3_0/source/include/ads.h
   branches/SAMBA_3_0/source/libads/cldap.c
   branches/SAMBA_3_0/source/libads/kerberos.c
   branches/SAMBA_3_0/source/libads/ldap.c
   branches/SAMBA_3_0/source/libsmb/namequery_dc.c
   branches/SAMBA_3_0/source/nsswitch/winbindd_cm.c


Changeset:
Modified: branches/SAMBA_3_0/source/include/ads.h
===================================================================
--- branches/SAMBA_3_0/source/include/ads.h	2006-08-31 00:07:24 UTC (rev 17942)
+++ branches/SAMBA_3_0/source/include/ads.h	2006-08-31 01:20:21 UTC (rev 17943)
@@ -42,6 +42,7 @@
 
 	/* info derived from the servers config */
 	struct {
+		uint32 flags; /* cldap flags identifying the services. */
 		char *realm;
 		char *bind_path;
 		char *ldap_server_name;

Modified: branches/SAMBA_3_0/source/libads/cldap.c
===================================================================
--- branches/SAMBA_3_0/source/libads/cldap.c	2006-08-31 00:07:24 UTC (rev 17942)
+++ branches/SAMBA_3_0/source/libads/cldap.c	2006-08-31 01:20:21 UTC (rev 17943)
@@ -306,5 +306,3 @@
 
 	return True;
 }
-
-

Modified: branches/SAMBA_3_0/source/libads/kerberos.c
===================================================================
--- branches/SAMBA_3_0/source/libads/kerberos.c	2006-08-31 00:07:24 UTC (rev 17942)
+++ branches/SAMBA_3_0/source/libads/kerberos.c	2006-08-31 01:20:21 UTC (rev 17943)
@@ -464,4 +464,62 @@
 					   0);
 }
 
+/************************************************************************
+ Create  a specific krb5.conf file in the private directory pointing
+ at a specific kdc for a realm. Keyed off domain name. Sets
+ KRB5_CONFIG environment variable to point to this file. Must be
+ run as root or will fail (which is a good thing :-).
+************************************************************************/
+
+BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, struct in_addr ip)
+{
+	XFILE *xfp = NULL;
+	char *fname = talloc_asprintf(NULL, "%s/smb_krb5.conf.%s", lp_private_dir(), domain);
+	char *file_contents = NULL;
+	size_t flen = 0;
+
+	if (!fname) {
+		return False;
+	}
+
+	file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n"
+				"[realms]\n\t%s = {\n"
+				"\t\tkdc = %s\n]\n",
+				realm, realm, inet_ntoa(ip));
+
+	if (!file_contents) {
+		TALLOC_FREE(fname);
+		return False;
+	}
+
+	flen = strlen(file_contents);
+	xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0600);
+	if (!xfp) {
+		TALLOC_FREE(fname);
+		return False;
+	}
+	/* Lock the file. */
+	if (!fcntl_lock(xfp->fd, F_SETLKW, 0, 1, F_WRLCK)) {
+		unlink(fname);
+		x_fclose(xfp);
+		TALLOC_FREE(fname);
+		return False;
+	}
+
+	if (x_fwrite(file_contents, flen, 1, xfp) != flen) {
+		unlink(fname);
+		x_fclose(xfp);
+		TALLOC_FREE(fname);
+		return False;
+	}
+	if (x_fclose(xfp)==-1) {
+		unlink(fname);
+		TALLOC_FREE(fname);
+		return False;
+	}
+	/* Set the environment variable to this file. */
+	setenv("KRB5_CONFIG", fname, 1);
+	TALLOC_FREE(fname);
+	return True;
+}
 #endif

Modified: branches/SAMBA_3_0/source/libads/ldap.c
===================================================================
--- branches/SAMBA_3_0/source/libads/ldap.c	2006-08-31 00:07:24 UTC (rev 17942)
+++ branches/SAMBA_3_0/source/libads/ldap.c	2006-08-31 01:20:21 UTC (rev 17943)
@@ -159,6 +159,7 @@
 	SAFE_FREE(ads->config.ldap_server_name);
 	SAFE_FREE(ads->server.workgroup);
 
+	ads->config.flags	       = cldap_reply.flags;
 	ads->config.ldap_server_name   = SMB_STRDUP(cldap_reply.hostname);
 	strupper_m(cldap_reply.domain);
 	ads->config.realm              = SMB_STRDUP(cldap_reply.domain);

Modified: branches/SAMBA_3_0/source/libsmb/namequery_dc.c
===================================================================
--- branches/SAMBA_3_0/source/libsmb/namequery_dc.c	2006-08-31 00:07:24 UTC (rev 17942)
+++ branches/SAMBA_3_0/source/libsmb/namequery_dc.c	2006-08-31 01:20:21 UTC (rev 17943)
@@ -38,8 +38,9 @@
 	char *sitename = sitename_fetch();
 	int i;
 
-	if (!realm && strequal(domain, lp_workgroup()))
+	if (!realm && strequal(domain, lp_workgroup())) {
 		realm = lp_realm();
+	}
 
 	/* Try this 3 times then give up. */
 	for( i =0 ; i < 3; i++) {
@@ -64,22 +65,34 @@
 		}
 
 		/* Now we've found a server, see if our sitename
-		   has changed. If so, we need to re-do the query
+		   has changed. If so, we need to re-do the DNS query
 		   to ensure we only find servers in our site. */
 
-		if (!sitename_changed(sitename)) {
-			break;
+		if (sitename_changed(sitename)) {
+			SAFE_FREE(sitename);
+			sitename = sitename_fetch();
+			ads_destroy(&ads);
+			continue;
 		}
 
-		ads_destroy(&ads);
+#ifdef HAVE_KRB5
+		if ((ads->config.flags & ADS_KDC) && sitename) {
+			/* We're going to use this KDC for this realm/domain.
+			   If we are using sites, then force the krb5 libs
+			   to use this KDC. */
+
+			create_local_private_krb5_conf_for_domain(realm,
+								domain,
+								ads->ldap_ip);
+		}
+#endif
+		break;
 	}
 
-
 	if (i == 3) {
 		DEBUG(1,("ads_dc_name: sitename (now \"%s\") keeps changing ???\n",
 			sitename ? sitename : ""));
 		SAFE_FREE(sitename);
-		ads_destroy(&ads);
 		return False;
 	}
 

Modified: branches/SAMBA_3_0/source/nsswitch/winbindd_cm.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbindd_cm.c	2006-08-31 00:07:24 UTC (rev 17942)
+++ branches/SAMBA_3_0/source/nsswitch/winbindd_cm.c	2006-08-31 01:20:21 UTC (rev 17943)
@@ -590,7 +590,43 @@
 	ip_list.ip = ip;
 	ip_list.port = 0;
 
-	/* try GETDC requests first */
+#ifdef WITH_ADS
+	/* For active directory servers, try to get the ldap server name.
+	   None of these failures should be considered critical for now */
+
+	if ( lp_security() == SEC_ADS ) {
+		ADS_STRUCT *ads;
+
+		ads = ads_init(realm, domainname, NULL);
+		ads->auth.flags |= ADS_AUTH_NO_BIND;
+
+		if (ads_try_connect( ads, inet_ntoa(ip) ) )  {
+			const char *sitename = sitename_fetch();
+			/* We got a cldap packet. */
+			fstrcpy(name, ads->config.ldap_server_name);
+			namecache_store(name, 0x20, 1, &ip_list);
+
+#ifdef HAVE_KRB5
+			if ((ads->config.flags & ADS_KDC) && sitename) {
+				/* We're going to use this KDC for this realm/domain.
+				   If we are using sites, then force the krb5 libs
+				   to use this KDC. */
+
+				create_local_private_krb5_conf_for_domain(realm,
+								domainname,
+								ip);
+			}
+#endif
+			SAFE_FREE(sitename);
+			ads_destroy( &ads );
+			return True;
+		}
+
+		ads_destroy( &ads );
+	}
+#endif
+
+	/* try GETDC requests next */
 	
 	if (send_getdc_request(ip, domainname, sid)) {
 		int i;
@@ -610,31 +646,6 @@
 		namecache_store(name, 0x20, 1, &ip_list);
 		return True;
 	}
-
-#ifdef WITH_ADS
-	/* for active directory servers, try to get the ldap server name.
-	   None of these failure should be considered critical for now */
-
-	if ( lp_security() == SEC_ADS ) 
-	{
-		ADS_STRUCT *ads;
-
-		ads = ads_init( realm, domainname, NULL );
-		ads->auth.flags |= ADS_AUTH_NO_BIND;
-
-		if ( !ads_try_connect( ads, inet_ntoa(ip) ) )  {
-			ads_destroy( &ads );
-			return False;
-		}
-
-		fstrcpy(name, ads->config.ldap_server_name);
-		namecache_store(name, 0x20, 1, &ip_list);
-
-		ads_destroy( &ads );
-		return True;
-	}
-#endif
-
 	return False;
 }
 



More information about the samba-cvs mailing list