[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Wed Dec 15 04:37:02 MST 2010


The branch, master has been updated
       via  4a1ce3b s4-dns: implemented parsing and storing of DNS records from bind
       via  74f8c9c s4-dns: added basic DLZ writeable support to dlz_bind9
       via  6f6aa5f waf: fixed re-running of build rules
      from  af99f0a s3-waf: use shared libwbclient wscript_build.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 4a1ce3b4b9173ebce7982e675b9f68fe58455ea0
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Dec 15 21:46:05 2010 +1100

    s4-dns: implemented parsing and storing of DNS records from bind
    
    DNS updates from nsupdate against our ldb SAM now work
    
    Autobuild-User: Andrew Tridgell <tridge at samba.org>
    Autobuild-Date: Wed Dec 15 12:36:46 CET 2010 on sn-devel-104

commit 74f8c9ccf854ab7853ff18a605737acf85541a73
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Dec 15 15:02:09 2010 +1100

    s4-dns: added basic DLZ writeable support to dlz_bind9
    
    this implements the expanded DLZ update driver API, allowing for bind9
    to send dynamic updates to the Samba DLZ driver.
    
    This change also adds support for exporting all DNS zones in the SAM
    database, which also means we now correctly separate the _msdcs zone
    from the main zone.

commit 6f6aa5f775baae6c921ceb5b9ac4fb0bc790f697
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Dec 15 14:59:47 2010 +1100

    waf: fixed re-running of build rules
    
    the addition of ldflags deps caused us to re-run the build rules every
    time.

-----------------------------------------------------------------------

Summary of changes:
 buildtools/wafsamba/samba_deps.py |    4 +-
 buildtools/wafsamba/wafsamba.py   |    5 +-
 source4/dns_server/dlz_bind9.c    |  973 ++++++++++++++++++++++++++++++++++---
 source4/dns_server/dlz_bind9.h    |   52 --
 source4/dns_server/dlz_minimal.h  |  140 ++++++
 5 files changed, 1059 insertions(+), 115 deletions(-)
 delete mode 100644 source4/dns_server/dlz_bind9.h
 create mode 100644 source4/dns_server/dlz_minimal.h


Changeset truncated at 500 lines:

diff --git a/buildtools/wafsamba/samba_deps.py b/buildtools/wafsamba/samba_deps.py
index 0ea9660..1f27026 100644
--- a/buildtools/wafsamba/samba_deps.py
+++ b/buildtools/wafsamba/samba_deps.py
@@ -81,7 +81,7 @@ def build_dependencies(self):
         libs = self.final_syslibs.copy()
 
         (ccflags, ldflags) = library_flags(self, list(libs))
-        new_ldflags        = getattr(self, 'ldflags', [])
+        new_ldflags        = getattr(self, 'samba_ldflags', [])[:]
         new_ldflags.extend(ldflags)
         self.ldflags       = new_ldflags
 
@@ -953,7 +953,7 @@ def show_object_duplicates(bld, tgt_list):
 # this provides a way to save our dependency calculations between runs
 savedeps_version = 3
 savedeps_inputs  = ['samba_deps', 'samba_includes', 'local_include', 'local_include_first', 'samba_cflags',
-                    'source', 'grouping_library', 'ldflags']
+                    'source', 'grouping_library', 'samba_ldflags']
 savedeps_outputs = ['uselib', 'uselib_local', 'add_objects', 'includes', 'ccflags', 'ldflags', 'samba_deps_extended']
 savedeps_outenv  = ['INC_PATHS']
 savedeps_envvars = ['NONSHARED_BINARIES', 'GLOBAL_DEPENDENCIES', 'EXTRA_CFLAGS', 'EXTRA_LDFLAGS' ]
diff --git a/buildtools/wafsamba/wafsamba.py b/buildtools/wafsamba/wafsamba.py
index 7758aff..19ebe23 100644
--- a/buildtools/wafsamba/wafsamba.py
+++ b/buildtools/wafsamba/wafsamba.py
@@ -226,7 +226,7 @@ def SAMBA_LIBRARY(bld, libname, source,
         source          = [],
         target          = bundled_name,
         depends_on      = depends_on,
-        ldflags		= ldflags,
+        samba_ldflags	= ldflags,
         samba_deps      = deps,
         samba_includes  = includes,
         local_include   = local_include,
@@ -338,7 +338,8 @@ def SAMBA_BINARY(bld, binname, source,
         samba_subsystem= subsystem_name,
         install_path   = None,
         samba_inst_path= install_path,
-        samba_install  = install
+        samba_install  = install,
+        samba_ldflags  = TO_LIST(ldflags)
         )
 
     if manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']:
diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c
index 573a0e8..7e18165 100644
--- a/source4/dns_server/dlz_bind9.c
+++ b/source4/dns_server/dlz_bind9.c
@@ -31,12 +31,13 @@
 #include "lib/cmdline/popt_common.h"
 #include "lib/cmdline/popt_credentials.h"
 #include "ldb_module.h"
-#include "dlz_bind9.h"
+#include "dlz_minimal.h"
 
 struct dlz_bind9_data {
 	struct ldb_context *samdb;
 	struct tevent_context *ev_ctx;
 	struct loadparm_context *lp;
+	int *transaction_token;
 
 	/* helper functions from the dlz_dlopen driver */
 	void (*log)(int level, const char *fmt, ...);
@@ -44,6 +45,14 @@ struct dlz_bind9_data {
 			      dns_ttl_t ttl, const char *data);
 	isc_result_t (*putnamedrr)(dns_sdlzlookup_t *handle, const char *name,
 				   const char *type, dns_ttl_t ttl, const char *data);
+	isc_result_t (*writeable_zone)(dns_view_t *view, const char *zone_name);
+};
+
+
+static const char *zone_prefixes[] = {
+	"CN=MicrosoftDNS,DC=DomainDnsZones",
+	"CN=MicrosoftDNS,DC=ForestDnsZones",
+	NULL
 };
 
 /*
@@ -68,6 +77,9 @@ static void b9_add_helper(struct dlz_bind9_data *state, const char *helper_name,
 	if (strcmp(helper_name, "putnamedrr") == 0) {
 		state->putnamedrr = ptr;
 	}
+	if (strcmp(helper_name, "writeable_zone") == 0) {
+		state->writeable_zone = ptr;
+	}
 }
 
 /*
@@ -116,8 +128,8 @@ static bool b9_format(struct dlz_bind9_data *state,
 	case DNS_TYPE_MX:
 		*type = "mx";
 		*data = talloc_asprintf(mem_ctx, "%u %s",
-					rec->data.srv.wPriority,
-					rec->data.srv.nameTarget);
+					rec->data.mx.wPriority,
+					rec->data.mx.nameTarget);
 		break;
 
 	case DNS_TYPE_HINFO:
@@ -153,6 +165,166 @@ static bool b9_format(struct dlz_bind9_data *state,
 	return true;
 }
 
+static const struct {
+	enum dns_record_type dns_type;
+	const char *typestr;
+	bool single_valued;
+} dns_typemap[] = {
+	{ DNS_TYPE_A,     "A"     , false},
+	{ DNS_TYPE_AAAA,  "AAAA"  , false},
+	{ DNS_TYPE_CNAME, "CNAME" , true},
+	{ DNS_TYPE_TXT,   "TXT"   , false},
+	{ DNS_TYPE_PTR,   "PTR"   , false},
+	{ DNS_TYPE_SRV,   "SRV"   , false},
+	{ DNS_TYPE_MX,    "MX"    , false},
+	{ DNS_TYPE_HINFO, "HINFO" , false},
+	{ DNS_TYPE_NS,    "NS"    , false},
+	{ DNS_TYPE_SOA,   "SOA"   , true},
+};
+
+
+/*
+  see if a DNS type is single valued
+ */
+static bool b9_single_valued(enum dns_record_type dns_type)
+{
+	int i;
+	for (i=0; i<ARRAY_SIZE(dns_typemap); i++) {
+		if (dns_typemap[i].dns_type == dns_type) {
+			return dns_typemap[i].single_valued;
+		}
+	}
+	return false;
+}
+
+/*
+  see if a DNS type is single valued
+ */
+static enum dns_record_type b9_dns_type(const char *type)
+{
+	int i;
+	for (i=0; i<ARRAY_SIZE(dns_typemap); i++) {
+		if (strcasecmp(dns_typemap[i].typestr, type) == 0) {
+			return dns_typemap[i].dns_type;
+		}
+	}
+	return DNS_TYPE_ZERO;
+}
+
+
+#define DNS_PARSE_STR(ret, str, sep, saveptr) do {	\
+	(ret) = strtok_r(str, sep, &saveptr); \
+	if ((ret) == NULL) return false; \
+	} while (0)
+
+#define DNS_PARSE_UINT(ret, str, sep, saveptr) do {  \
+	char *istr = strtok_r(str, sep, &saveptr); \
+	if ((istr) == NULL) return false; \
+	(ret) = strtoul(istr, NULL, 10); \
+	} while (0)
+
+/*
+  parse a record from bind9
+ */
+static bool b9_parse(struct dlz_bind9_data *state,
+		     const char *rdatastr,
+		     struct dnsp_DnssrvRpcRecord *rec)
+{
+	char *full_name, *dclass, *type;
+	char *str, *saveptr=NULL;
+	int i;
+
+	str = talloc_strdup(rec, rdatastr);
+	if (str == NULL) {
+		return false;
+	}
+
+	/* parse the SDLZ string form */
+	DNS_PARSE_STR(full_name, str, "\t", saveptr);
+	DNS_PARSE_UINT(rec->dwTtlSeconds, NULL, "\t", saveptr);
+	DNS_PARSE_STR(dclass, NULL, "\t", saveptr);
+	DNS_PARSE_STR(type, NULL, "\t", saveptr);
+
+	/* construct the record */
+	for (i=0; i<ARRAY_SIZE(dns_typemap); i++) {
+		if (strcasecmp(type, dns_typemap[i].typestr) == 0) {
+			rec->wType = dns_typemap[i].dns_type;
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(dns_typemap)) {
+		state->log(ISC_LOG_ERROR, "samba_dlz: unsupported record type '%s' for '%s'",
+			   type, full_name);
+		return false;
+	}
+
+	switch (rec->wType) {
+	case DNS_TYPE_A:
+		DNS_PARSE_STR(rec->data.ipv4, NULL, " ", saveptr);
+		break;
+
+	case DNS_TYPE_AAAA:
+		DNS_PARSE_STR(rec->data.ipv6, NULL, " ", saveptr);
+		break;
+
+	case DNS_TYPE_CNAME:
+		DNS_PARSE_STR(rec->data.cname, NULL, " ", saveptr);
+		break;
+
+	case DNS_TYPE_TXT:
+		DNS_PARSE_STR(rec->data.txt, NULL, "\t", saveptr);
+		break;
+
+	case DNS_TYPE_PTR:
+		DNS_PARSE_STR(rec->data.ptr, NULL, " ", saveptr);
+		break;
+
+	case DNS_TYPE_SRV:
+		DNS_PARSE_UINT(rec->data.srv.wPriority, NULL, " ", saveptr);
+		DNS_PARSE_UINT(rec->data.srv.wWeight, NULL, " ", saveptr);
+		DNS_PARSE_UINT(rec->data.srv.wPort, NULL, " ", saveptr);
+		DNS_PARSE_STR(rec->data.srv.nameTarget, NULL, " ", saveptr);
+		break;
+
+	case DNS_TYPE_MX:
+		DNS_PARSE_UINT(rec->data.mx.wPriority, NULL, " ", saveptr);
+		DNS_PARSE_STR(rec->data.mx.nameTarget, NULL, " ", saveptr);
+		break;
+
+	case DNS_TYPE_HINFO:
+		DNS_PARSE_STR(rec->data.hinfo.cpu, NULL, " ", saveptr);
+		DNS_PARSE_STR(rec->data.hinfo.os, NULL, " ", saveptr);
+		break;
+
+	case DNS_TYPE_NS:
+		DNS_PARSE_STR(rec->data.ns, NULL, " ", saveptr);
+		break;
+
+	case DNS_TYPE_SOA:
+		DNS_PARSE_STR(rec->data.soa.mname, NULL, " ", saveptr);
+		DNS_PARSE_STR(rec->data.soa.rname, NULL, " ", saveptr);
+		DNS_PARSE_UINT(rec->data.soa.serial, NULL, " ", saveptr);
+		DNS_PARSE_UINT(rec->data.soa.refresh, NULL, " ", saveptr);
+		DNS_PARSE_UINT(rec->data.soa.retry, NULL, " ", saveptr);
+		DNS_PARSE_UINT(rec->data.soa.expire, NULL, " ", saveptr);
+		DNS_PARSE_UINT(rec->data.soa.minimum, NULL, " ", saveptr);
+		break;
+
+	default:
+		state->log(ISC_LOG_ERROR, "samba b9_parse: unhandled record type %u",
+			   rec->wType);
+		return false;
+	}
+
+	/* we should be at the end of the buffer now */
+	if (strtok_r(NULL, "\t ", &saveptr) != NULL) {
+		state->log(ISC_LOG_ERROR, "samba b9_parse: expected data at end of string for '%s'");
+		return false;
+	}
+
+	return true;
+}
+
 /*
   send a resource recond to bind9
  */
@@ -277,7 +449,7 @@ static isc_result_t parse_options(struct dlz_bind9_data *state,
  */
 _PUBLIC_ isc_result_t dlz_create(const char *dlzname,
 				 unsigned int argc, char *argv[],
-				 void *driverarg, void **dbdata, ...)
+				 void **dbdata, ...)
 {
 	struct dlz_bind9_data *state;
 	const char *helper_name;
@@ -312,7 +484,7 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname,
 
 	state->samdb = ldb_init(state, state->ev_ctx);
 	if (state->samdb == NULL) {
-		state->log(ISC_LOG_ERROR, "samba dlz_bind9: Failed to create ldb");
+		state->log(ISC_LOG_ERROR, "samba_dlz: Failed to create ldb");
 		result = ISC_R_FAILURE;
 		goto failed;
 	}
@@ -339,7 +511,7 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname,
 
 	ret = ldb_connect(state->samdb, options.url, 0, NULL);
 	if (ret == -1) {
-		state->log(ISC_LOG_ERROR, "samba dlz_bind9: Failed to connect to %s - %s",
+		state->log(ISC_LOG_ERROR, "samba_dlz: Failed to connect to %s - %s",
 			   options.url, ldb_errstring(state->samdb));
 		result = ISC_R_FAILURE;
 		goto failed;
@@ -347,7 +519,7 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname,
 
 	ret = ldb_modules_hook(state->samdb, LDB_MODULE_HOOK_CMDLINE_POSTCONNECT);
 	if (ret != LDB_SUCCESS) {
-		state->log(ISC_LOG_ERROR, "samba dlz_bind9: Failed postconnect for %s - %s",
+		state->log(ISC_LOG_ERROR, "samba_dlz: Failed postconnect for %s - %s",
 			   options.url, ldb_errstring(state->samdb));
 		result = ISC_R_FAILURE;
 		goto failed;
@@ -355,13 +527,13 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname,
 
 	dn = ldb_get_default_basedn(state->samdb);
 	if (dn == NULL) {
-		state->log(ISC_LOG_ERROR, "samba dlz_bind9: Unable to get basedn for %s - %s",
+		state->log(ISC_LOG_ERROR, "samba_dlz: Unable to get basedn for %s - %s",
 			   options.url, ldb_errstring(state->samdb));
 		result = ISC_R_FAILURE;
 		goto failed;
 	}
 
-	state->log(ISC_LOG_INFO, "samba dlz_bind9: started for DN %s",
+	state->log(ISC_LOG_INFO, "samba_dlz: started for DN %s",
 		   ldb_dn_get_linearized(dn));
 
 	*dbdata = state;
@@ -377,56 +549,138 @@ failed:
 /*
   shutdown the backend
  */
-_PUBLIC_ void dlz_destroy(void *driverarg, void *dbdata)
+_PUBLIC_ void dlz_destroy(void *dbdata)
 {
 	struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
-	state->log(ISC_LOG_INFO, "samba dlz_bind9: shutting down");
+	state->log(ISC_LOG_INFO, "samba_dlz: shutting down");
 	talloc_free(state);
 }
 
 
 /*
-  see if we handle a given zone
+  return the base DN for a zone
  */
-_PUBLIC_ isc_result_t dlz_findzonedb(void *driverarg, void *dbdata, const char *name)
+static isc_result_t b9_find_zone_dn(struct dlz_bind9_data *state, const char *zone_name,
+				    TALLOC_CTX *mem_ctx, struct ldb_dn **zone_dn)
 {
-	struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
-	if (strcasecmp(lpcfg_dnsdomain(state->lp), name) == 0) {
-		return ISC_R_SUCCESS;
+	int ret;
+	TALLOC_CTX *tmp_ctx = talloc_new(state);
+	const char *attrs[] = { NULL };
+	int i;
+
+	for (i=0; zone_prefixes[i]; i++) {
+		struct ldb_dn *dn;
+		struct ldb_result *res;
+
+		dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(state->samdb));
+		if (dn == NULL) {
+			talloc_free(tmp_ctx);
+			return ISC_R_NOMEMORY;
+		}
+
+		if (!ldb_dn_add_child_fmt(dn, "DC=%s,%s", zone_name, zone_prefixes[i])) {
+			talloc_free(tmp_ctx);
+			return ISC_R_NOMEMORY;
+		}
+
+		ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, "objectClass=dnsZone");
+		if (ret == LDB_SUCCESS) {
+			if (zone_dn != NULL) {
+				*zone_dn = talloc_steal(mem_ctx, dn);
+			}
+			talloc_free(tmp_ctx);
+			return ISC_R_SUCCESS;
+		}
+		talloc_free(dn);
+	}
+
+	talloc_free(tmp_ctx);
+	return ISC_R_NOTFOUND;
+}
+
+
+/*
+  return the DN for a name. The record does not need to exist, but the
+  zone must exist
+ */
+static isc_result_t b9_find_name_dn(struct dlz_bind9_data *state, const char *name,
+				    TALLOC_CTX *mem_ctx, struct ldb_dn **dn)
+{
+	const char *p;
+
+	/* work through the name piece by piece, until we find a zone */
+	for (p=name; p; ) {
+		isc_result_t result;
+		result = b9_find_zone_dn(state, p, mem_ctx, dn);
+		if (result == ISC_R_SUCCESS) {
+			/* we found a zone, now extend the DN to get
+			 * the full DN
+			 */
+			bool ret;
+			if (p == name) {
+				ret = ldb_dn_add_child_fmt(*dn, "DC=@");
+			} else {
+				ret = ldb_dn_add_child_fmt(*dn, "DC=%.*s", (int)(p-name)-1, name);
+			}
+			if (!ret) {
+				talloc_free(*dn);
+				return ISC_R_NOMEMORY;
+			}
+			return ISC_R_SUCCESS;
+		}
+		p = strchr(p, '.');
+		if (p == NULL) {
+			break;
+		}
+		p++;
 	}
 	return ISC_R_NOTFOUND;
 }
 
 
 /*
+  see if we handle a given zone
+ */
+_PUBLIC_ isc_result_t dlz_findzonedb(void *dbdata, const char *name)
+{
+	struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
+	return b9_find_zone_dn(state, name, NULL, NULL);
+}
+
+
+/*
   lookup one record
  */
 static isc_result_t dlz_lookup_types(struct dlz_bind9_data *state,
 				     const char *zone, const char *name,
-				     void *driverarg, dns_sdlzlookup_t *lookup,
+				     dns_sdlzlookup_t *lookup,
 				     const char **types)
 {
-	struct ldb_dn *dn;
 	TALLOC_CTX *tmp_ctx = talloc_new(state);
 	const char *attrs[] = { "dnsRecord", NULL };
 	int ret, i;
 	struct ldb_result *res;
 	struct ldb_message_element *el;
+	struct ldb_dn *dn;
 
-	dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(state->samdb));
-	if (dn == NULL) {
-		talloc_free(tmp_ctx);
-		return ISC_R_NOMEMORY;
-	}
+	for (i=0; zone_prefixes[i]; i++) {
+		dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(state->samdb));
+		if (dn == NULL) {
+			talloc_free(tmp_ctx);
+			return ISC_R_NOMEMORY;
+		}
 
-	if (!ldb_dn_add_child_fmt(dn, "DC=%s,DC=%s,CN=MicrosoftDNS,DC=DomainDnsZones",
-				  name, zone)) {
-		talloc_free(tmp_ctx);
-		return ISC_R_NOMEMORY;
-	}
+		if (!ldb_dn_add_child_fmt(dn, "DC=%s,DC=%s,%s", name, zone, zone_prefixes[i])) {
+			talloc_free(tmp_ctx);
+			return ISC_R_NOMEMORY;
+		}
 
-	ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
-			 attrs, "objectClass=dnsNode");
+		ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
+				 attrs, "objectClass=dnsNode");
+		if (ret == LDB_SUCCESS) {
+			break;
+		}
+	}
 	if (ret != LDB_SUCCESS) {
 		talloc_free(tmp_ctx);
 		return ISC_R_NOTFOUND;
@@ -434,8 +688,6 @@ static isc_result_t dlz_lookup_types(struct dlz_bind9_data *state,
 
 	el = ldb_msg_find_element(res->msgs[0], "dnsRecord");
 	if (el == NULL || el->num_values == 0) {
-		state->log(ISC_LOG_INFO, "failed to find %s",
-			   ldb_dn_get_linearized(dn));
 		talloc_free(tmp_ctx);
 		return ISC_R_NOTFOUND;
 	}
@@ -448,7 +700,7 @@ static isc_result_t dlz_lookup_types(struct dlz_bind9_data *state,
 		ndr_err = ndr_pull_struct_blob(&el->values[i], tmp_ctx, &rec,
 					       (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord);
 		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-			state->log(ISC_LOG_ERROR, "samba dlz_bind9: failed to parse dnsRecord for %s",
+			state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s",
 				   ldb_dn_get_linearized(dn));
 			talloc_free(tmp_ctx);
 			return ISC_R_FAILURE;
@@ -468,35 +720,27 @@ static isc_result_t dlz_lookup_types(struct dlz_bind9_data *state,
 /*
   lookup one record


-- 
Samba Shared Repository


More information about the samba-cvs mailing list