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 <k...@samba.org> Date: Thu Sep 6 22:53:32 2012 +0200 s4 dns: Make debug output less noisy Autobuild-User(master): Kai Blin <k...@samba.org> Autobuild-Date(master): Fri Sep 7 00:31:56 CEST 2012 on sn-devel-104 commit 319b239dc4aeb2c6a928a70fc7a7dbad56d273cd Author: Kai Blin <k...@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