[PATCH] Internal DNS, RPC server & samba-tool tests & fixes

Jeremy Allison jra at samba.org
Thu Dec 8 22:31:24 UTC 2016


On Fri, Dec 09, 2016 at 10:44:05AM +1300, Bob Campbell wrote:
> Hi,
> 
> Here are a bunch of patches to test "samba-tool dns", extend testing for
> DNS over RPC directly, and fix some problems found through the tests.
> 
> *samba-tool issues found:*
> 
> - There is unnecessary input validation, which means that DNS records
> marked with DNS_RANK_NONE can't be deleted, even though they can on the
> RPC server. Since we've now proved input validation on the RPC server,
> we don't need this validation, so we removed it where possible.
> 
> - Error catching is generic (it just catches runtime errors and gives
> the same message), so we made it more specific and changes some messages
> to allow for easier debugging.
> 
> *backend issues found:*
> 
> - There is no validation of DNS names over RPC on Samba, but there is on
> Windows. We've fixed this by adding a simple check whenever doing
> anything to a record except deleting it (as we don't want deletes to
> fail against existing entries, even if their DN is invalid). We also
> added this check on DNS, and when converting a string to an ldb_dn
> structure.
> 
> - ACLs on some zones, in particular default ones, are weird and
> inconsistent with Windows in places, but this is mostly because the
> default owners are different. We've marked these tests as knownfails,
> because we're not sure that there's actually a problem here.
> 
> - DNS records in the _msdcs zone wouldn't have the dNSProperty attribute
> (which may have been a root cause of entries with DNS_RANK_NONE).
> 
> These patches are applied at:
> http://git.catalyst.net.nz/gw?p=samba.git;a=shortlog;h=refs/heads/dnscmdtest
> 
> Please review.

Not commenting much on the python (sorry, I'm still learning), but
a few C comments follow inline.

Cheers,

Jeremy.

> From 020c77cc6bf279d969641e8af533107d7b94e3b7 Mon Sep 17 00:00:00 2001
> From: Bob Campbell <bobcampbell at catalyst.net.nz>
> Date: Tue, 6 Dec 2016 15:34:23 +1300
> Subject: [PATCH 07/12] dnsserver: add dns name checking
> 
> This may also prevent deletion of existing corrupted records through
> DNS, but should be resolvable through RPC, or at worst LDAP.
> 
> Signed-off-by: Bob Campbell <bobcampbell at catalyst.net.nz>
> Peer-programmed-with: Garming Sam <garming at catalyst.net.nz>
> Reviewed-by: Garming Sam <garming at catalyst.net.nz>
> ---
>  selftest/knownfail                       |   2 -
>  source4/dns_server/dnsserver_common.c    |  87 ++++++++++++++++++++++
>  source4/dns_server/dnsserver_common.h    |   4 +-
>  source4/rpc_server/dnsserver/dnsdata.c   | 122 ++++++++++++++++++++++++-------
>  source4/rpc_server/dnsserver/dnsdb.c     |  33 ++++++---
>  source4/rpc_server/dnsserver/dnsserver.h |   4 +-
>  source4/rpc_server/wscript_build         |   2 +-
>  7 files changed, 212 insertions(+), 42 deletions(-)
> 
> diff --git a/selftest/knownfail b/selftest/knownfail
> index 7141f43..97ec6ef 100644
> --- a/selftest/knownfail
> +++ b/selftest/knownfail
> @@ -309,5 +309,3 @@
>  ^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_add_duplicate_different_type.*
>  ^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_rank_none.*
>  ^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_security_descriptor.*
> -^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_reject_invalid_commands
> -^samba.tests.samba_tool.dnscmd.samba.tests.samba_tool.dnscmd.DnsCmdTestCase.test_reject_invalid_commands
> diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c
> index db42bcb..e6534c3 100644
> --- a/source4/dns_server/dnsserver_common.c
> +++ b/source4/dns_server/dnsserver_common.c
> @@ -214,6 +214,87 @@ static int rec_cmp(const struct dnsp_DnssrvRpcRecord *r1,
>  	return r1->dwTimeStamp - r2->dwTimeStamp;
>  }
>  
> +/*
> + * Check for valid DNS names. These are names which are non-empty, do not
> + * start with a dot and do not have any empty segments.
> + */
> +WERROR dns_name_check(TALLOC_CTX *mem_ctx, int len, const char *name)

len here should be size_t, not int. It comes from a strlen() which
returns size_t.

> +{
> +	int i;

i should also be size_t.

> +	if (len == 0) {
> +		return WERR_DS_INVALID_DN_SYNTAX;
> +	}
> +
> +	for (i = 0; i < len - 1; i++) {
> +		if (name[i] == '.' && name[i+1] == '.') {
> +			return WERR_DS_INVALID_DN_SYNTAX;
> +		}
> +	}
> +
> +	if (len > 1 && name[0] == '.') {
> +		return WERR_DS_INVALID_DN_SYNTAX;
> +	}
> +
> +	return WERR_OK;
> +}
> +
> +static WERROR check_name_list(TALLOC_CTX *mem_ctx, uint16_t rec_count,
> +			      struct dnsp_DnssrvRpcRecord *records)
> +{
> +	WERROR werr;
> +	int i, len;

i should be uint16_t, as that's the type of rec_count.
len should be size_t as it comes from strlen().

> +	struct dnsp_DnssrvRpcRecord record;
> +
> +	werr = WERR_OK;
> +	for(i=0; i<rec_count; i++){
> +		record = records[i];
> +
> +		switch (record.wType) {
> +
> +		case DNS_TYPE_NS:
> +			len = strlen(record.data.ns);
> +			werr = dns_name_check(mem_ctx, len, record.data.ns);
> +			break;
> +		case DNS_TYPE_CNAME:
> +			len = strlen(record.data.cname);
> +			werr = dns_name_check(mem_ctx, len, record.data.cname);
> +			break;
> +		case DNS_TYPE_SOA:
> +			len = strlen(record.data.soa.mname);
> +			werr = dns_name_check(mem_ctx, len, record.data.soa.mname);
> +			if (!W_ERROR_IS_OK(werr)) {
> +				break;
> +			}
> +			len = strlen(record.data.soa.rname);
> +			werr = dns_name_check(mem_ctx, len, record.data.soa.rname);
> +			break;
> +		case DNS_TYPE_PTR:
> +			len = strlen(record.data.ptr);
> +			werr = dns_name_check(mem_ctx, len, record.data.ptr);
> +			break;
> +		case DNS_TYPE_MX:
> +			len = strlen(record.data.mx.nameTarget);
> +			werr = dns_name_check(mem_ctx, len, record.data.mx.nameTarget);
> +			break;
> +		case DNS_TYPE_SRV:
> +			len = strlen(record.data.srv.nameTarget);
> +			werr = dns_name_check(mem_ctx, len,
> +					      record.data.srv.nameTarget);
> +			break;
> +		// In the default case, the record doesn't have a DN, so it must be ok.

Use C style comments, not C++.

> +		default:
> +			break;
> +		}
> +
> +		if (!W_ERROR_IS_OK(werr)) {
> +			return werr;
> +		}
> +	}
> +
> +	return WERR_OK;
> +}
> +
>  WERROR dns_common_replace(struct ldb_context *samdb,
>  			  TALLOC_CTX *mem_ctx,
>  			  struct ldb_dn *dn,
> @@ -225,6 +306,7 @@ WERROR dns_common_replace(struct ldb_context *samdb,
>  	struct ldb_message_element *el;
>  	uint16_t i;
>  	int ret;
> +	WERROR werr;
>  	struct ldb_message *msg = NULL;
>  	bool was_tombstoned = false;
>  	bool become_tombstoned = false;
> @@ -234,6 +316,11 @@ WERROR dns_common_replace(struct ldb_context *samdb,
>  
>  	msg->dn = dn;
>  
> +	werr = check_name_list(mem_ctx, rec_count, records);
> +	if (!W_ERROR_IS_OK(werr)) {
> +		return werr;
> +	}
> +
>  	ret = ldb_msg_add_empty(msg, "dnsRecord", LDB_FLAG_MOD_REPLACE, &el);
>  	if (ret != LDB_SUCCESS) {
>  		return DNS_ERR(SERVER_FAILURE);
> diff --git a/source4/dns_server/dnsserver_common.h b/source4/dns_server/dnsserver_common.h
> index ad91f61..bea3019 100644
> --- a/source4/dns_server/dnsserver_common.h
> +++ b/source4/dns_server/dnsserver_common.h
> @@ -46,7 +46,9 @@ WERROR dns_common_lookup(struct ldb_context *samdb,
>  			 struct dnsp_DnssrvRpcRecord **records,
>  			 uint16_t *num_records,
>  			 bool *tombstoned);
> -
> +WERROR dns_name_check(TALLOC_CTX *mem_ctx,
> +		      int len,
> +		      const char *name);
>  WERROR dns_common_replace(struct ldb_context *samdb,
>  			  TALLOC_CTX *mem_ctx,
>  			  struct ldb_dn *dn,
> diff --git a/source4/rpc_server/dnsserver/dnsdata.c b/source4/rpc_server/dnsserver/dnsdata.c
> index ccea0d7..c2ca56e 100644
> --- a/source4/rpc_server/dnsserver/dnsdata.c
> +++ b/source4/rpc_server/dnsserver/dnsdata.c
> @@ -21,6 +21,7 @@
>  
>  #include "includes.h"
>  #include "dnsserver.h"
> +#include "dns_server/dnsserver_common.h"
>  #include "lib/replace/system/network.h"
>  #include "librpc/gen_ndr/ndr_dnsp.h"
>  #include "librpc/gen_ndr/ndr_dnsserver.h"
> @@ -412,15 +413,17 @@ void dnsp_to_dns_copy(TALLOC_CTX *mem_ctx, struct dnsp_DnssrvRpcRecord *dnsp,
>  
>  }
>  
> -
> -struct dnsp_DnssrvRpcRecord *dns_to_dnsp_copy(TALLOC_CTX *mem_ctx, struct DNS_RPC_RECORD *dns)
> +WERROR dns_to_dnsp_convert(TALLOC_CTX *mem_ctx, struct DNS_RPC_RECORD *dns,
> +			   struct dnsp_DnssrvRpcRecord **out_dnsp, bool check_name)
>  {
> +	WERROR res;
>  	int i, len;
> -	struct dnsp_DnssrvRpcRecord *dnsp;
> +	const char *name;
> +	struct dnsp_DnssrvRpcRecord *dnsp = NULL;
>  
>  	dnsp = talloc_zero(mem_ctx, struct dnsp_DnssrvRpcRecord);
>  	if (dnsp == NULL) {
> -		return NULL;
> +		return WERR_NOT_ENOUGH_MEMORY;
>  	}
>  
>  	dnsp->wDataLength = dns->wDataLength;
> @@ -442,21 +445,41 @@ struct dnsp_DnssrvRpcRecord *dns_to_dnsp_copy(TALLOC_CTX *mem_ctx, struct DNS_RP
>  		break;
>  
>  	case DNS_TYPE_NS:
> +		name = dns->data.name.str;
>  		len = dns->data.name.len;

Where does dns->data.name.len come from ?
If it comes from a remote source then there
must be range checks around any arithmetic
(len - 1) etc.

> -		if (dns->data.name.str[len-1] == '.') {
> -			dnsp->data.ns = talloc_strndup(mem_ctx, dns->data.name.str, len-1);
> +
> +		if (check_name) {
> +			res = dns_name_check(mem_ctx, len, name);
> +			if (!W_ERROR_IS_OK(res)) {
> +				return res;
> +			}
> +		}
> +
> +		if (name[len-1] == '.') {
> +			dnsp->data.ns = talloc_strndup(mem_ctx, name, len-1);
>  		} else {
> -			dnsp->data.ns = talloc_strdup(mem_ctx, dns->data.name.str);
> +			dnsp->data.ns = talloc_strdup(mem_ctx, name);
>  		}

Error check on talloc returns please.

> +
>  		break;
>  
>  	case DNS_TYPE_CNAME:
> +		name = dns->data.name.str;
>  		len = dns->data.name.len;
> -		if (dns->data.name.str[len-1] == '.') {
> -			dnsp->data.cname = talloc_strndup(mem_ctx, dns->data.name.str, len-1);
> +
> +		if (check_name) {
> +			res = dns_name_check(mem_ctx, len, name);
> +			if (!W_ERROR_IS_OK(res)) {
> +				return res;
> +			}
> +		}
> +
> +		if (name[len-1] == '.') {
> +			dnsp->data.cname = talloc_strndup(mem_ctx, name, len-1);
>  		} else {
> -			dnsp->data.cname = talloc_strdup(mem_ctx, dns->data.name.str);
> +			dnsp->data.cname = talloc_strdup(mem_ctx, name);
>  		}

Error check on talloc returns please.

> +
>  		break;
>  
>  	case DNS_TYPE_SOA:
> @@ -466,33 +489,71 @@ struct dnsp_DnssrvRpcRecord *dns_to_dnsp_copy(TALLOC_CTX *mem_ctx, struct DNS_RP
>  		dnsp->data.soa.expire = dns->data.soa.dwExpire;
>  		dnsp->data.soa.minimum = dns->data.soa.dwMinimumTtl;
>  
> +		name = dns->data.soa.NamePrimaryServer.str;
>  		len = dns->data.soa.NamePrimaryServer.len;
> -		if (dns->data.soa.NamePrimaryServer.str[len-1] == '.') {
> -			dnsp->data.soa.mname = talloc_strndup(mem_ctx, dns->data.soa.NamePrimaryServer.str, len-1);
> +
> +		if (check_name) {
> +			res = dns_name_check(mem_ctx, len, name);
> +			if (!W_ERROR_IS_OK(res)) {
> +				return res;
> +			}
> +		}
> +
> +		if (name[len-1] == '.') {
> +			dnsp->data.soa.mname = talloc_strndup(mem_ctx, name, len-1);
>  		} else {
> -			dnsp->data.soa.mname = talloc_strdup(mem_ctx, dns->data.soa.NamePrimaryServer.str);
> +			dnsp->data.soa.mname = talloc_strdup(mem_ctx, name);

Error check on talloc returns please.

>  		}
>  
> +		name = dns->data.soa.ZoneAdministratorEmail.str;
>  		len = dns->data.soa.ZoneAdministratorEmail.len;
> -		if (dns->data.soa.ZoneAdministratorEmail.str[len-1] == '.') {
> -			dnsp->data.soa.rname = talloc_strndup(mem_ctx, dns->data.soa.ZoneAdministratorEmail.str, len-1);
> +
> +		res = dns_name_check(mem_ctx, len, name);
> +		if (!W_ERROR_IS_OK(res)) {
> +			return res;
> +		}
> +
> +		if (name[len-1] == '.') {
> +			dnsp->data.soa.rname = talloc_strndup(mem_ctx, name, len-1);
>  		} else {
> -			dnsp->data.soa.rname = talloc_strdup(mem_ctx, dns->data.soa.ZoneAdministratorEmail.str);
> +			dnsp->data.soa.rname = talloc_strdup(mem_ctx, name);

Error check on talloc returns please.

>  		}
> +
>  		break;
>  
>  	case DNS_TYPE_PTR:
> -		dnsp->data.ptr = talloc_strdup(mem_ctx, dns->data.ptr.str);
> +		name = dns->data.ptr.str;
> +		len = dns->data.ptr.len;
> +
> +		if (check_name) {
> +			res = dns_name_check(mem_ctx, len, name);
> +			if (!W_ERROR_IS_OK(res)) {
> +				return res;
> +			}
> +		}
> +
> +		dnsp->data.ptr = talloc_strdup(mem_ctx, name);

Error check on talloc returns please.

>  		break;
>  
>  	case DNS_TYPE_MX:
>  		dnsp->data.mx.wPriority = dns->data.mx.wPreference;
> +
> +		name = dns->data.mx.nameExchange.str;
>  		len = dns->data.mx.nameExchange.len;
> -		if (dns->data.mx.nameExchange.str[len-1] == '.') {
> -			dnsp->data.mx.nameTarget = talloc_strndup(mem_ctx, dns->data.mx.nameExchange.str, len-1);
> +
> +		if (check_name) {
> +			res = dns_name_check(mem_ctx, len, name);
> +			if (!W_ERROR_IS_OK(res)) {
> +				return res;
> +			}
> +		}
> +
> +		if (name[len-1] == '.') {
> +			dnsp->data.mx.nameTarget = talloc_strndup(mem_ctx, name, len-1);
>  		} else {
> -			dnsp->data.mx.nameTarget = talloc_strdup(mem_ctx, dns->data.mx.nameExchange.str);
> +			dnsp->data.mx.nameTarget = talloc_strdup(mem_ctx, name);

Error check on talloc returns please.
>  		}
> +
>  		break;
>  
>  	case DNS_TYPE_TXT:
> @@ -512,24 +573,33 @@ struct dnsp_DnssrvRpcRecord *dns_to_dnsp_copy(TALLOC_CTX *mem_ctx, struct DNS_RP
>  		dnsp->data.srv.wWeight = dns->data.srv.wWeight;
>  		dnsp->data.srv.wPort = dns->data.srv.wPort;
>  
> +		name = dns->data.srv.nameTarget.str;
>  		len = dns->data.srv.nameTarget.len;
> -		if (dns->data.srv.nameTarget.str[len-1] == '.') {
> -			dnsp->data.srv.nameTarget = talloc_strndup(mem_ctx, dns->data.srv.nameTarget.str, len-1);
> +
> +		if (check_name) {
> +			res = dns_name_check(mem_ctx, len, name);
> +			if (!W_ERROR_IS_OK(res)) {
> +				return res;
> +			}
> +		}
> +
> +		if (name[len-1] == '.') {
> +			dnsp->data.srv.nameTarget = talloc_strndup(mem_ctx, name, len-1);
>  		} else {
> -			dnsp->data.srv.nameTarget = talloc_strdup(mem_ctx, dns->data.srv.nameTarget.str);
> +			dnsp->data.srv.nameTarget = talloc_strdup(mem_ctx, name);

Error check on talloc returns please.
>  		}
> +
>  		break;
>  
>  	default:
>  		memcpy(&dnsp->data, &dns->data, sizeof(union dnsRecordData));
>  		DEBUG(0, ("dnsserver: Found Unhandled DNS record type=%d", dns->wType));
> -
>  	}
>  
> -	return dnsp;
> +	*out_dnsp = dnsp;
> +	return WERR_OK;
>  }
>  
> -
>  /* Intialize tree with given name as the root */
>  static struct dns_tree *dns_tree_init(TALLOC_CTX *mem_ctx, const char *name, void *data)
>  {
> diff --git a/source4/rpc_server/dnsserver/dnsdb.c b/source4/rpc_server/dnsserver/dnsdb.c
> index 949a8b9..da37878 100644
> --- a/source4/rpc_server/dnsserver/dnsdb.c
> +++ b/source4/rpc_server/dnsserver/dnsdb.c
> @@ -397,17 +397,20 @@ WERROR dnsserver_db_add_record(TALLOC_CTX *mem_ctx,
>  {
>  	const char * const attrs[] = { "dnsRecord", "dNSTombstoned", NULL };
>  	struct ldb_result *res;
> -	struct dnsp_DnssrvRpcRecord *rec;
> +	struct dnsp_DnssrvRpcRecord *rec = NULL;
>  	struct ldb_message_element *el;
>  	struct ldb_dn *dn;
>  	enum ndr_err_code ndr_err;
>  	NTTIME t;
>  	int ret, i;
>  	int serial;
> +	WERROR werr;
>  	bool was_tombstoned = false;
>  
> -	rec = dns_to_dnsp_copy(mem_ctx, add_record);
> -	W_ERROR_HAVE_NO_MEMORY(rec);
> +	werr = dns_to_dnsp_convert(mem_ctx, add_record, &rec, true);
> +	if (!W_ERROR_IS_OK(werr)) {
> +		return werr;
> +	}
>  
>  	/* Set the correct rank for the record. */
>  	if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_PRIMARY) {
> @@ -514,18 +517,23 @@ WERROR dnsserver_db_update_record(TALLOC_CTX *mem_ctx,
>  {
>  	const char * const attrs[] = { "dnsRecord", NULL };
>  	struct ldb_result *res;
> -	struct dnsp_DnssrvRpcRecord *arec, *drec;
> +	struct dnsp_DnssrvRpcRecord *arec = NULL, *drec = NULL;
>  	struct ldb_message_element *el;
>  	enum ndr_err_code ndr_err;
>  	NTTIME t;
>  	int ret, i;
>  	int serial;
> +	WERROR werr;
>  
> -	arec = dns_to_dnsp_copy(mem_ctx, add_record);
> -	W_ERROR_HAVE_NO_MEMORY(arec);
> +	werr = dns_to_dnsp_convert(mem_ctx, add_record, &arec, true);
> +	if (!W_ERROR_IS_OK(werr)) {
> +		return werr;
> +	}
>  
> -	drec = dns_to_dnsp_copy(mem_ctx, del_record);
> -	W_ERROR_HAVE_NO_MEMORY(drec);
> +	werr = dns_to_dnsp_convert(mem_ctx, del_record, &drec, true);
> +	if (!W_ERROR_IS_OK(werr)) {
> +		return werr;
> +	}
>  
>  	unix_to_nt_time(&t, time(NULL));
>  	t /= 10*1000*1000;
> @@ -616,19 +624,22 @@ WERROR dnsserver_db_delete_record(TALLOC_CTX *mem_ctx,
>  {
>  	const char * const attrs[] = { "dnsRecord", NULL };
>  	struct ldb_result *res;
> -	struct dnsp_DnssrvRpcRecord *rec;
> +	struct dnsp_DnssrvRpcRecord *rec = NULL;
>  	struct ldb_message_element *el;
>  	enum ndr_err_code ndr_err;
>  	int ret, i;
>  	int serial;
> +	WERROR werr;
>  
>  	serial = dnsserver_update_soa(mem_ctx, samdb, z);
>  	if (serial < 0) {
>  		return WERR_INTERNAL_DB_ERROR;
>  	}
>  
> -	rec = dns_to_dnsp_copy(mem_ctx, del_record);
> -	W_ERROR_HAVE_NO_MEMORY(rec);
> +	werr = dns_to_dnsp_convert(mem_ctx, del_record, &rec, false);
> +	if (!W_ERROR_IS_OK(werr)) {
> +		return werr;
> +	}
>  
>  	ret = ldb_search(samdb, mem_ctx, &res, z->zone_dn, LDB_SCOPE_ONELEVEL, attrs,
>  			"(&(objectClass=dnsNode)(name=%s))", name);
> diff --git a/source4/rpc_server/dnsserver/dnsserver.h b/source4/rpc_server/dnsserver/dnsserver.h
> index cfe6d4e..0b08f08 100644
> --- a/source4/rpc_server/dnsserver/dnsserver.h
> +++ b/source4/rpc_server/dnsserver/dnsserver.h
> @@ -193,7 +193,9 @@ bool dns_record_match(struct dnsp_DnssrvRpcRecord *rec1, struct dnsp_DnssrvRpcRe
>  
>  void dnsp_to_dns_copy(TALLOC_CTX *mem_ctx, struct dnsp_DnssrvRpcRecord *dnsp,
>  			struct DNS_RPC_RECORD *dns);
> -struct dnsp_DnssrvRpcRecord *dns_to_dnsp_copy(TALLOC_CTX *mem_ctx, struct DNS_RPC_RECORD *dns);
> +WERROR dns_to_dnsp_convert(TALLOC_CTX *mem_ctx, struct DNS_RPC_RECORD *dns,
> +			   struct dnsp_DnssrvRpcRecord **out_dnsp,
> +			   bool check_name);
>  
>  struct dns_tree *dns_build_tree(TALLOC_CTX *mem_ctx, const char *name, struct ldb_result *res);
>  WERROR dns_fill_records_array(TALLOC_CTX *mem_ctx, struct dnsserver_zone *z,
> diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build
> index ed7dbf6..f1b1f19 100755
> --- a/source4/rpc_server/wscript_build
> +++ b/source4/rpc_server/wscript_build
> @@ -155,7 +155,7 @@ bld.SAMBA_MODULE('dcerpc_dnsserver',
>      source='dnsserver/dcerpc_dnsserver.c dnsserver/dnsutils.c dnsserver/dnsdata.c dnsserver/dnsdb.c',
>      subsystem='dcerpc_server',
>      init_function='dcerpc_server_dnsserver_init',
> -    deps='DCERPC_COMMON'
> +    deps='DCERPC_COMMON dnsserver_common'
>      )
>  
>  
> -- 
> 1.9.1



More information about the samba-technical mailing list