svn commit: samba r21194 - in branches/SAMBA_3_0_25/source: libaddns libads utils

jerry at samba.org jerry at samba.org
Tue Feb 6 21:10:48 GMT 2007


Author: jerry
Date: 2007-02-06 21:10:46 +0000 (Tue, 06 Feb 2007)
New Revision: 21194

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

Log:
sync DNS update code from SAMBA_3_0
Modified:
   branches/SAMBA_3_0_25/source/libaddns/dns.h
   branches/SAMBA_3_0_25/source/libaddns/dnsgss.c
   branches/SAMBA_3_0_25/source/libaddns/dnsrecord.c
   branches/SAMBA_3_0_25/source/libads/ads_struct.c
   branches/SAMBA_3_0_25/source/utils/net_ads.c
   branches/SAMBA_3_0_25/source/utils/net_dns.c


Changeset:
Modified: branches/SAMBA_3_0_25/source/libaddns/dns.h
===================================================================
--- branches/SAMBA_3_0_25/source/libaddns/dns.h	2007-02-06 21:10:08 UTC (rev 21193)
+++ branches/SAMBA_3_0_25/source/libaddns/dns.h	2007-02-06 21:10:46 UTC (rev 21194)
@@ -280,6 +280,8 @@
 #endif
 
 
+enum dns_ServerType { DNS_SRV_ANY, DNS_SRV_WIN2000, DNS_SRV_WIN2003 };
+
 struct dns_domain_label {
 	struct dns_domain_label *next;
 	char *label;
@@ -405,9 +407,6 @@
 					const char *name,
 					const in_addr_t *ip,
 					struct dns_rrec **prec);
-DNS_ERROR dns_create_name_not_in_use_record(TALLOC_CTX *mem_ctx,
-					const char *name, uint32 type,
-					struct dns_rrec **prec);
 DNS_ERROR dns_create_delete_record(TALLOC_CTX *mem_ctx, const char *name,
 				   uint16 type, uint16 r_class,
 				   struct dns_rrec **prec);
@@ -484,7 +483,8 @@
 DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm,
 				 const char *servername,
 				 const char *keyname,
-				 gss_ctx_id_t *gss_ctx );
+				 gss_ctx_id_t *gss_ctx,
+				 enum dns_ServerType srv_type );
 DNS_ERROR dns_sign_update(struct dns_update_request *req,
 			  gss_ctx_id_t gss_ctx,
 			  const char *keyname,
@@ -493,7 +493,8 @@
 DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx,
 				    const char *domainname,
 				    const char *hostname,
-				    in_addr_t ip_addr,
+				    const struct in_addr *ip_addr,
+				    size_t num_adds,
 				    struct dns_update_request **preq);
 
 #endif	/* HAVE_GSSAPI_SUPPORT */

Modified: branches/SAMBA_3_0_25/source/libaddns/dnsgss.c
===================================================================
--- branches/SAMBA_3_0_25/source/libaddns/dnsgss.c	2007-02-06 21:10:08 UTC (rev 21193)
+++ branches/SAMBA_3_0_25/source/libaddns/dnsgss.c	2007-02-06 21:10:46 UTC (rev 21194)
@@ -45,6 +45,7 @@
 	return ( 0 );
 }
 
+#if 0
 /*********************************************************************
 *********************************************************************/
 
@@ -76,12 +77,14 @@
 	display_status_1( msg, maj_stat, GSS_C_GSS_CODE );
 	display_status_1( msg, min_stat, GSS_C_MECH_CODE );
 }
+#endif
 
 static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx,
 					    struct dns_connection *conn,
 					    const char *keyname,
 					    const gss_name_t target_name,
-					    gss_ctx_id_t *ctx )
+					    gss_ctx_id_t *ctx, 
+					    enum dns_ServerType srv_type )
 {
 	struct gss_buffer_desc_struct input_desc, *input_ptr, output_desc;
 	OM_uint32 major, minor;
@@ -123,11 +126,21 @@
 				req, keyname, "gss.microsoft.com", t,
 				t + 86400, DNS_TKEY_MODE_GSSAPI, 0,
 				output_desc.length, (uint8 *)output_desc.value,
-				&rec);
+				&rec );
 			if (!ERR_DNS_IS_OK(err)) goto error;
 
-			err = dns_add_rrec(req, rec, &req->num_additionals,
-					   &req->additionals);
+			/* Windows 2000 DNS is broken and requires the
+			   TKEY payload in the Answer section instead
+			   of the Additional seciton like Windows 2003 */
+
+			if ( srv_type == DNS_SRV_WIN2000 ) {
+				err = dns_add_rrec(req, rec, &req->num_answers,
+						   &req->answers);
+			} else {
+				err = dns_add_rrec(req, rec, &req->num_additionals,
+						   &req->additionals);
+			}
+			
 			if (!ERR_DNS_IS_OK(err)) goto error;
 
 			err = dns_marshall_request(req, req, &buf);
@@ -163,6 +176,7 @@
 			 */
 			
 			if ((resp->num_additionals != 1) ||
+			    (resp->num_answers == 0) ||
 			    (resp->answers[0]->type != QTYPE_TKEY)) {
 				err = ERROR_DNS_INVALID_MESSAGE;
 				goto error;
@@ -194,7 +208,8 @@
 DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm,
 				 const char *servername,
 				 const char *keyname,
-				 gss_ctx_id_t *gss_ctx )
+				 gss_ctx_id_t *gss_ctx,
+				 enum dns_ServerType srv_type )
 {
 	OM_uint32 major, minor;
 
@@ -250,12 +265,12 @@
 		goto error;
 	}
 
-	err = dns_negotiate_gss_ctx_int(mem_ctx, conn, keyname, targ_name,
-					gss_ctx);
+	err = dns_negotiate_gss_ctx_int(mem_ctx, conn, keyname, 
+					targ_name, gss_ctx, srv_type );
 
+	gss_release_name( &minor, &targ_name );
 	krb5_free_principal( krb_ctx, host_principal );
 	krb5_free_context( krb_ctx );
-	gss_release_name( &minor, &targ_name );
 
  error:
 	TALLOC_FREE(mem_ctx);

Modified: branches/SAMBA_3_0_25/source/libaddns/dnsrecord.c
===================================================================
--- branches/SAMBA_3_0_25/source/libaddns/dnsrecord.c	2007-02-06 21:10:08 UTC (rev 21193)
+++ branches/SAMBA_3_0_25/source/libaddns/dnsrecord.c	2007-02-06 21:10:46 UTC (rev 21194)
@@ -356,12 +356,14 @@
 DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx,
 				    const char *domainname,
 				    const char *hostname,
-				    in_addr_t ip_addr,
+				    const struct in_addr *ip_addrs,
+				    size_t num_addrs,
 				    struct dns_update_request **preq)
 {
 	struct dns_update_request *req;
 	struct dns_rrec *rec;
 	DNS_ERROR err;
+	size_t i;	
 
 	err = dns_create_update(mem_ctx, domainname, &req);
 	if (!ERR_DNS_IS_OK(err)) return err;
@@ -389,14 +391,18 @@
 	if (!ERR_DNS_IS_OK(err)) goto error;
 
 	/*
-	 * .. and add our IP
+	 * .. and add our IPs
 	 */
 
-	err = dns_create_a_record(req, hostname, 3600, ip_addr, &rec);
-	if (!ERR_DNS_IS_OK(err)) goto error;
+	for ( i=0; i<num_addrs; i++ ) {		
+		err = dns_create_a_record(req, hostname, 3600, ip_addrs[i].s_addr, &rec);
+		if (!ERR_DNS_IS_OK(err)) 
+			goto error;
 
-	err = dns_add_rrec(req, rec, &req->num_updates, &req->updates);
-	if (!ERR_DNS_IS_OK(err)) goto error;
+		err = dns_add_rrec(req, rec, &req->num_updates, &req->updates);
+		if (!ERR_DNS_IS_OK(err)) 
+			goto error;
+	}	
 
 	*preq = req;
 	return ERROR_DNS_SUCCESS;

Modified: branches/SAMBA_3_0_25/source/libads/ads_struct.c
===================================================================
--- branches/SAMBA_3_0_25/source/libads/ads_struct.c	2007-02-06 21:10:08 UTC (rev 21193)
+++ branches/SAMBA_3_0_25/source/libads/ads_struct.c	2007-02-06 21:10:46 UTC (rev 21194)
@@ -75,7 +75,29 @@
 	return ads_build_path(realm, ".", "dc=", 0);
 }
 
+/* return a DNS name in the for aa.bb.cc from the DN  
+   "dc=AA,dc=BB,dc=CC".  caller must free
+*/
+char *ads_build_domain(const char *dn)
+{
+	char *dnsdomain = NULL;
+	
+	/* result should always be shorter than the DN */
 
+	if ( (dnsdomain = SMB_STRDUP( dn )) == NULL ) {
+		DEBUG(0,("ads_build_domain: malloc() failed!\n"));		
+		return NULL;		
+	}	
+
+	strlower_m( dnsdomain );	
+	all_string_sub( dnsdomain, "dc=", "", 0);
+	all_string_sub( dnsdomain, ",", ".", 0 );
+
+	return dnsdomain;	
+}
+
+
+
 #ifndef LDAP_PORT
 #define LDAP_PORT 389
 #endif

Modified: branches/SAMBA_3_0_25/source/utils/net_ads.c
===================================================================
--- branches/SAMBA_3_0_25/source/utils/net_ads.c	2007-02-06 21:10:08 UTC (rev 21193)
+++ branches/SAMBA_3_0_25/source/utils/net_ads.c	2007-02-06 21:10:46 UTC (rev 21194)
@@ -1213,7 +1213,7 @@
 
 #if defined(WITH_DNS_UPDATES)
 #include "dns.h"
-DNS_ERROR DoDNSUpdate(ADS_STRUCT *ads, char *pszServerName,
+DNS_ERROR DoDNSUpdate(char *pszServerName,
 		      const char *pszDomainName,
 		      const char *pszHostName,
 		      const struct in_addr *iplist, int num_addrs );
@@ -1229,7 +1229,8 @@
 	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
 	DNS_ERROR dns_err;
 	fstring dns_server;
-	const char *dnsdomain;
+	const char *dnsdomain = NULL;	
+	char *root_domain = NULL;	
 
 	if ( (dnsdomain = strchr_m( machine_name, '.')) == NULL ) {
 		d_printf("No DNS domain configured for %s. "
@@ -1241,24 +1242,70 @@
 
 	status = ads_dns_lookup_ns( ctx, dnsdomain, &nameservers, &ns_count );
 	if ( !NT_STATUS_IS_OK(status) || (ns_count == 0)) {
+		/* Child domains often do not have NS records.  Look
+		   for the NS record for the forest root domain 
+		   (rootDomainNamingContext in therootDSE) */
+
+		const char *rootname_attrs[] = 	{ "rootDomainNamingContext", NULL };
+		LDAPMessage *msg = NULL;
+		char *root_dn;
+		ADS_STATUS ads_status;
+		
+		if ( !ads->ld ) {
+			ads_status = ads_connect( ads );
+			if ( !ADS_ERR_OK(ads_status) ) {
+				DEBUG(0,("net_update_dns_internal: Failed to connect to our DC!\n"));
+				goto done;				
+			}			
+		}
+		
+		ads_status = ads_do_search(ads, "", LDAP_SCOPE_BASE, 
+				       "(objectclass=*)", rootname_attrs, &msg);
+		if (!ADS_ERR_OK(ads_status)) {
+			goto done;
+		}
+
+		root_dn = ads_pull_string(ads, ctx, msg,  "rootDomainNamingContext");
+		if ( !root_dn ) {
+			ads_msgfree( ads, msg );			
+			goto done;
+		}
+
+		root_domain = ads_build_domain( root_dn );
+
+		/* cleanup */
+		ads_msgfree( ads, msg );
+
+		/* try again for NS servers */
+
+		status = ads_dns_lookup_ns( ctx, root_domain, &nameservers, &ns_count );
+		
+		if ( !NT_STATUS_IS_OK(status) || (ns_count == 0)) {			
 		DEBUG(3,("net_ads_join: Failed to find name server for the %s "
 			 "realm\n", ads->config.realm));
 		goto done;
 	}
 
+		dnsdomain = root_domain;		
+		
+	}
+
 	/* Now perform the dns update - we'll try non-secure and if we fail,
 	   we'll follow it up with a secure update */
 
 	fstrcpy( dns_server, nameservers[0].hostname );
 
-	dns_err = DoDNSUpdate(ads, dns_server, dnsdomain, machine_name, addrs, num_addrs);
+	dns_err = DoDNSUpdate(dns_server, dnsdomain, machine_name, addrs, num_addrs);
 	if (!ERR_DNS_IS_OK(dns_err)) {
 		status = NT_STATUS_UNSUCCESSFUL;
 	}
 
 done:
+
+	SAFE_FREE( root_domain );
+	
 	return status;
-	}
+}
 
 static NTSTATUS net_update_dns(TALLOC_CTX *mem_ctx, ADS_STRUCT *ads)
 {
@@ -1337,6 +1384,8 @@
 	const char *machineupn = NULL;
 	const char *create_in_ou = NULL;
 	int i;
+	fstring dc_name;
+	struct in_addr dcip;
 	
 	nt_status = check_ads_config();
 	if (!NT_STATUS_IS_OK(nt_status)) {
@@ -1344,6 +1393,10 @@
 		goto fail;
 	}
 
+	/* find a DC to initialize the server affinity cache */
+
+	get_dc_name( lp_workgroup(), lp_realm(), dc_name, &dcip );
+
 	status = ads_startup(True, &ads);
 	if (!ADS_ERR_OK(status)) {
 		DEBUG(1, ("error on ads_startup: %s\n", ads_errstr(status)));
@@ -1568,15 +1621,12 @@
 	ADS_STRUCT *ads;
 	ADS_STATUS status;
 	TALLOC_CTX *ctx;
-	fstring name;
-	int num_addrs;
-	struct in_addr *iplist = NULL;
 	
 #ifdef DEVELOPER
 	talloc_enable_leak_report();
 #endif
 	
-	if (argc > 2) {
+	if (argc > 0) {
 		d_fprintf(stderr, "net ads dns register <name> <ip>\n");
 		return -1;
 	}
@@ -1586,48 +1636,17 @@
 		return -1;
 	}
 
-	if (argc > 0) {
-		fstrcpy(name, argv[0]);
-	} else {
-		name_to_fqdn(name, global_myname());
-	}
-	strlower_m(name);
-	
-	if (argc > 1) {
-		if (!(iplist = SMB_MALLOC_ARRAY(struct in_addr, 1))) {
-			d_fprintf(stderr, "net_ads_dns_register: malloc "
-				  "failed\n");
-			return -1;
-		}
-		if (inet_aton(argv[1], iplist) == 0) {
-			d_fprintf(stderr, "net_ads_dns_register: %s is not "
-				  "a valid IP address\n", argv[1]);
-			SAFE_FREE(iplist);
-			return -1;
-		}
-		num_addrs = 1;
-	} else {
-		num_addrs = get_my_ip_address( &iplist );
-		if ( num_addrs <= 0 ) {
-			d_fprintf(stderr, "net_ads_dns_regiser: Failed to "
-				  "find my non-loopback IP addresses!\n");
-			return -1;
-		}
-	}
-	
-	status = ads_startup_nobind(True, &ads);
+	status = ads_startup(True, &ads);
 	if ( !ADS_ERR_OK(status) ) {
 		DEBUG(1, ("error on ads_startup: %s\n", ads_errstr(status)));
 		TALLOC_FREE(ctx);
 		return -1;
 	}
 
-	if ( !NT_STATUS_IS_OK(net_update_dns_internal(ctx, ads, name,
-						      iplist, num_addrs)) ) {
+	if ( !NT_STATUS_IS_OK(net_update_dns(ctx, ads)) ) {		
 		d_fprintf( stderr, "DNS update failed!\n" );
 		ads_destroy( &ads );
 		TALLOC_FREE( ctx );
-		SAFE_FREE(iplist);
 		return -1;
 	}
 	
@@ -1635,7 +1654,6 @@
 
 	ads_destroy(&ads);
 	TALLOC_FREE( ctx );
-	SAFE_FREE(iplist);
 	
 	return 0;
 #else

Modified: branches/SAMBA_3_0_25/source/utils/net_dns.c
===================================================================
--- branches/SAMBA_3_0_25/source/utils/net_dns.c	2007-02-06 21:10:08 UTC (rev 21193)
+++ branches/SAMBA_3_0_25/source/utils/net_dns.c	2007-02-06 21:10:46 UTC (rev 21194)
@@ -30,9 +30,9 @@
 /*********************************************************************
 *********************************************************************/
 
-DNS_ERROR DoDNSUpdate(ADS_STRUCT *ads, char *pszServerName,
+DNS_ERROR DoDNSUpdate(char *pszServerName,
 		      const char *pszDomainName, const char *pszHostName,
-		      const struct in_addr *iplist, int num_addrs )
+		      const struct in_addr *iplist, size_t num_addrs )
 {
 	DNS_ERROR err;
 	struct dns_connection *conn;
@@ -74,7 +74,7 @@
 	 */
 
 	err = dns_create_update_request(mem_ctx, pszDomainName, pszHostName,
-					iplist[0].s_addr, &req);
+					iplist, num_addrs, &req);
 	if (!ERR_DNS_IS_OK(err)) goto error;
 
 	err = dns_update_transaction(mem_ctx, conn, req, &resp);
@@ -89,9 +89,7 @@
 	 * Okay, we have to try with signing
 	 */
 	{
-		ADS_STRUCT *ads_s;
 		gss_ctx_id_t gss_context;
-		int res;
 		char *keyname;
 
 		if (!(keyname = dns_generate_keyname( mem_ctx ))) {
@@ -99,28 +97,20 @@
 			goto error;
 		}
 
-		if (!(ads_s = ads_init(ads->server.realm, ads->server.workgroup,
-				       ads->server.ldap_server))) {
-			return ERROR_DNS_NO_MEMORY;
+		err = dns_negotiate_sec_ctx( pszDomainName, pszServerName,
+					     keyname, &gss_context, DNS_SRV_ANY );
+
+		/* retry using the Windows 2000 DNS hack */
+		if (!ERR_DNS_IS_OK(err)) {
+			err = dns_negotiate_sec_ctx( pszDomainName, pszServerName,
+						     keyname, &gss_context, 
+						     DNS_SRV_WIN2000 );
 		}
 		
-		/* kinit with the machine password */
-		setenv(KRB5_ENV_CCNAME, "MEMORY:net_ads", 1);
-		asprintf( &ads_s->auth.user_name, "%s$", global_myname() );
-		ads_s->auth.password = secrets_fetch_machine_password(
-			lp_workgroup(), NULL, NULL );
-		ads_s->auth.realm = SMB_STRDUP( lp_realm() );
-		res = ads_kinit_password( ads_s );
-		ads_destroy(&ads_s);
-		if (res) {
-			err = ERROR_DNS_GSS_ERROR;
+		if (!ERR_DNS_IS_OK(err))
 			goto error;
-		}
+		
 
-		err = dns_negotiate_sec_ctx( pszDomainName, pszServerName,
-					     keyname, &gss_context );
-		if (!ERR_DNS_IS_OK(err)) goto error;
-
 		err = dns_sign_update(req, gss_context, keyname,
 				      "gss.microsoft.com", time(NULL), 3600);
 



More information about the samba-cvs mailing list