[SCM] Samba Shared Repository - branch master updated

Kai Blin kai at samba.org
Thu Sep 6 16:32:02 MDT 2012


The branch, master has been updated
       via  8ba8020 s4 dns: Make debug output less noisy
       via  319b239 s4 dns: Check if signing user is allowed to update records
      from  44fd8e7 fileserver:sysquotas: remove wrong cast

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


- Log -----------------------------------------------------------------
commit 8ba802058644910741dc80940420781450a924b7
Author: Kai Blin <kai at samba.org>
Date:   Thu Sep 6 22:53:32 2012 +0200

    s4 dns: Make debug output less noisy
    
    Autobuild-User(master): Kai Blin <kai at samba.org>
    Autobuild-Date(master): Fri Sep  7 00:31:56 CEST 2012 on sn-devel-104

commit 319b239dc4aeb2c6a928a70fc7a7dbad56d273cd
Author: Kai Blin <kai at samba.org>
Date:   Thu Sep 6 22:40:56 2012 +0200

    s4 dns: Check if signing user is allowed to update records
    
    This should fix bug #9142

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

Summary of changes:
 source4/dns_server/dns_crypto.c |    4 +-
 source4/dns_server/dns_query.c  |    2 +-
 source4/dns_server/dns_server.c |    2 +-
 source4/dns_server/dns_update.c |   86 ++++++++++++++++++++++++++++----------
 4 files changed, 67 insertions(+), 27 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dns_server/dns_crypto.c b/source4/dns_server/dns_crypto.c
index 7362adc..7604a05 100644
--- a/source4/dns_server/dns_crypto.c
+++ b/source4/dns_server/dns_crypto.c
@@ -121,7 +121,7 @@ WERROR dns_verify_tsig(struct dns_server *dns,
 
 	/* The TSIG record needs to be the last additional record */
 	if (found_tsig && i + 1 != packet->arcount) {
-		DEBUG(0, ("TSIG record not the last additional record!\n"));
+		DEBUG(1, ("TSIG record not the last additional record!\n"));
 		return DNS_ERR(FORMAT_ERROR);
 	}
 
@@ -218,7 +218,7 @@ WERROR dns_verify_tsig(struct dns_server *dns,
 	}
 
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("Verifying tsig failed: %s\n", nt_errstr(status)));
+		DEBUG(1, ("Verifying tsig failed: %s\n", nt_errstr(status)));
 		return ntstatus_to_werror(status);
 	}
 
diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c
index 98ebc63..54e0c7f 100644
--- a/source4/dns_server/dns_query.c
+++ b/source4/dns_server/dns_query.c
@@ -509,7 +509,7 @@ static WERROR handle_tkey(struct dns_server *dns,
 				return WERR_NOMEM;
 			}
 		} else {
-			DEBUG(0, ("GSS key negotiation returned %s\n", nt_errstr(status)));
+			DEBUG(1, ("GSS key negotiation returned %s\n", nt_errstr(status)));
 			ret_tkey->rdata.tkey_record.error = DNS_RCODE_BADKEY;
 		}
 
diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c
index d9851b1..be1fecc 100644
--- a/source4/dns_server/dns_server.c
+++ b/source4/dns_server/dns_server.c
@@ -147,7 +147,7 @@ static struct tevent_req *dns_process_send(TALLOC_CTX *mem_ctx,
 
 	ret = dns_verify_tsig(dns, state, &state->state, &state->in_packet, in);
 	if (!W_ERROR_IS_OK(ret)) {
-		DEBUG(0, ("Bailing out early!\n"));
+		DEBUG(1, ("Failed to verify TSIG!\n"));
 		state->dns_err = werr_to_dns_err(ret);
 		tevent_req_done(req);
 		return tevent_req_post(req, ev);
diff --git a/source4/dns_server/dns_update.c b/source4/dns_server/dns_update.c
index 61850a1..2df0b58 100644
--- a/source4/dns_server/dns_update.c
+++ b/source4/dns_server/dns_update.c
@@ -31,6 +31,7 @@
 #include "dsdb/common/util.h"
 #include "smbd/service_task.h"
 #include "dns_server/dns_server.h"
+#include "auth/auth.h"
 
 static WERROR dns_rr_to_dnsp(TALLOC_CTX *mem_ctx,
 			     const struct dns_res_rec *rrec,
@@ -381,7 +382,8 @@ done:
 static WERROR handle_one_update(struct dns_server *dns,
 				TALLOC_CTX *mem_ctx,
 				const struct dns_name_question *zone,
-				const struct dns_res_rec *update)
+				const struct dns_res_rec *update,
+				const struct dns_server_tkey *tkey)
 {
 	struct dnsp_DnssrvRpcRecord *recs = NULL;
 	uint16_t rcount = 0;
@@ -389,6 +391,7 @@ static WERROR handle_one_update(struct dns_server *dns,
 	uint16_t i;
 	WERROR werror;
 	bool needs_add = false;
+	uint32_t access_mask = 0;
 
 	DEBUG(2, ("Looking at record: \n"));
 	if (DEBUGLVL(2)) {
@@ -421,9 +424,24 @@ static WERROR handle_one_update(struct dns_server *dns,
 		rcount = 0;
 		needs_add = true;
 		werror = WERR_OK;
+		access_mask = SEC_ADS_CREATE_CHILD;
 	}
 	W_ERROR_NOT_OK_RETURN(werror);
 
+	access_mask = SEC_STD_REQUIRED | SEC_ADS_SELF_WRITE;
+
+	if (tkey != NULL) {
+		int ldb_ret;
+		ldb_ret = dsdb_check_access_on_dn(dns->samdb, mem_ctx, dn,
+						  tkey->session_info->security_token,
+						  access_mask, NULL);
+		if (ldb_ret != LDB_SUCCESS) {
+			DEBUG(5, ("Disallowing update: %s\n", ldb_strerror(ldb_ret)));
+			return DNS_ERR(REFUSED);
+		}
+		DEBUG(5, ("Allowing signed update\n"));
+	}
+
 	if (update->rr_class == zone->question_class) {
 		if (update->rr_type == DNS_QTYPE_CNAME) {
 			/*
@@ -432,7 +450,7 @@ static WERROR handle_one_update(struct dns_server *dns,
 			 */
 			for (i = 0; i < rcount; i++) {
 				if (recs[i].wType != DNS_TYPE_CNAME) {
-					DEBUG(0, ("Skipping update\n"));
+					DEBUG(5, ("Skipping update\n"));
 					return WERR_OK;
 				}
 				break;
@@ -463,7 +481,7 @@ static WERROR handle_one_update(struct dns_server *dns,
 			 */
 			for (i = 0; i < rcount; i++) {
 				if (recs[i].wType == DNS_TYPE_CNAME) {
-					DEBUG(0, ("Skipping update\n"));
+					DEBUG(5, ("Skipping update\n"));
 					return WERR_OK;
 				}
 			}
@@ -487,7 +505,7 @@ static WERROR handle_one_update(struct dns_server *dns,
 					 * logic for RFC2136
 					 */
 					if (n <= o) {
-						DEBUG(0, ("Skipping update\n"));
+						DEBUG(5, ("Skipping update\n"));
 						return WERR_OK;
 					}
 					found = true;
@@ -495,7 +513,7 @@ static WERROR handle_one_update(struct dns_server *dns,
 				}
 			}
 			if (!found) {
-				DEBUG(0, ("Skipping update\n"));
+				DEBUG(5, ("Skipping update\n"));
 				return WERR_OK;
 			}
 
@@ -637,7 +655,8 @@ static WERROR handle_updates(struct dns_server *dns,
 			     TALLOC_CTX *mem_ctx,
 			     const struct dns_name_question *zone,
 			     const struct dns_res_rec *prereqs, uint16_t pcount,
-			     struct dns_res_rec *updates, uint16_t upd_count)
+			     struct dns_res_rec *updates, uint16_t upd_count,
+			     struct dns_server_tkey *tkey)
 {
 	struct ldb_dn *zone_dn = NULL;
 	WERROR werror = WERR_OK;
@@ -656,11 +675,11 @@ static WERROR handle_updates(struct dns_server *dns,
 	werror = check_prerequisites(dns, tmp_ctx, zone, prereqs, pcount);
 	W_ERROR_NOT_OK_GOTO(werror, failed);
 
-	DEBUG(0, ("update count is %u\n", upd_count));
+	DEBUG(1, ("update count is %u\n", upd_count));
 
 	for (ri = 0; ri < upd_count; ri++) {
 		werror = handle_one_update(dns, tmp_ctx, zone,
-					   &updates[ri]);
+					   &updates[ri], tkey);
 		W_ERROR_NOT_OK_GOTO(werror, failed);
 	}
 
@@ -675,6 +694,35 @@ failed:
 
 }
 
+static WERROR dns_update_allowed(struct dns_server *dns,
+				 struct dns_request_state *state,
+				 struct dns_server_tkey **tkey)
+{
+	if (lpcfg_allow_dns_updates(dns->task->lp_ctx) == DNS_UPDATE_ON) {
+		DEBUG(2, ("All updates allowed.\n"));
+		return WERR_OK;
+	}
+
+	if (lpcfg_allow_dns_updates(dns->task->lp_ctx) == DNS_UPDATE_OFF) {
+		DEBUG(2, ("Updates disabled.\n"));
+		return DNS_ERR(REFUSED);
+	}
+
+	if (state->authenticated == false ) {
+		DEBUG(2, ("Update not allowed for unsigned packet.\n"));
+		return DNS_ERR(REFUSED);
+	}
+
+        *tkey = dns_find_tkey(dns->tkeys, state->key_name);
+	if (*tkey == NULL) {
+		DEBUG(0, ("Authenticated, but key not found. Something is wrong.\n"));
+		return DNS_ERR(REFUSED);
+	}
+
+	return WERR_OK;
+}
+
+
 WERROR dns_server_process_update(struct dns_server *dns,
 				 struct dns_request_state *state,
 				 TALLOC_CTX *mem_ctx,
@@ -687,6 +735,7 @@ WERROR dns_server_process_update(struct dns_server *dns,
 	const struct dns_server_zone *z;
 	size_t host_part_len = 0;
 	WERROR werror = DNS_ERR(NOT_IMPLEMENTED);
+	struct dns_server_tkey *tkey = NULL;
 
 	if (in->qdcount != 1) {
 		return DNS_ERR(FORMAT_ERROR);
@@ -715,13 +764,13 @@ WERROR dns_server_process_update(struct dns_server *dns,
 	}
 
 	if (z == NULL) {
-		DEBUG(0, ("We're not authoritative for this zone\n"));
+		DEBUG(1, ("We're not authoritative for this zone\n"));
 		return DNS_ERR(NOTAUTH);
 	}
 
 	if (host_part_len != 0) {
 		/* TODO: We need to delegate this one */
-		DEBUG(0, ("Would have to delegate zones.\n"));
+		DEBUG(1, ("Would have to delegate zones.\n"));
 		return DNS_ERR(NOT_IMPLEMENTED);
 	}
 
@@ -731,17 +780,9 @@ WERROR dns_server_process_update(struct dns_server *dns,
 				     *prereq_count);
 	W_ERROR_NOT_OK_RETURN(werror);
 
-	/* TODO: Check if update is allowed, we probably want "always",
-	 * key-based GSSAPI, key-based bind-style TSIG and "never" as
-	 * smb.conf options. */
-	if (lpcfg_allow_dns_updates(dns->task->lp_ctx) == DNS_UPDATE_OFF) {
-		DEBUG(0, ("Update not allowed.\n"));
-		return DNS_ERR(REFUSED);
-	}
-	if (lpcfg_allow_dns_updates(dns->task->lp_ctx) == DNS_UPDATE_SIGNED &&
-	    state->authenticated == false ) {
-		DEBUG(0, ("Update not allowed for unsigned packet.\n"));
-		return DNS_ERR(REFUSED);
+	werror = dns_update_allowed(dns, state, &tkey);
+	if (!W_ERROR_IS_OK(werror)) {
+		return werror;
 	}
 
 	*update_count = in->nscount;
@@ -749,9 +790,8 @@ WERROR dns_server_process_update(struct dns_server *dns,
 	werror = update_prescan(in->questions, *updates, *update_count);
 	W_ERROR_NOT_OK_RETURN(werror);
 
-
 	werror = handle_updates(dns, mem_ctx, in->questions, *prereqs,
-			        *prereq_count, *updates, *update_count);
+			        *prereq_count, *updates, *update_count, tkey);
 	W_ERROR_NOT_OK_RETURN(werror);
 
 	return werror;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list