[SCM] Samba Shared Repository - branch master updated
Kai Blin
kai at samba.org
Fri Dec 16 20:20:02 MST 2011
The branch, master has been updated
via b1fdf40 s4 dns: Allow updates based on smb.conf setting
via afa98bd s4 dns: Add some debug output
via d8a499a s4 dns: Actually handle the update request
via c191ad7 s4 dns: Implement RFC-compatible update prescan
via 02c9e18 s4 dns: Update prerequisite checking conforming to RFC
via 589d995 s4 dns: Give better test output on RCODE mismatch
via 8b82bad s4 dns: Move record lookup to dns_utils.c
via 0922953 s4 dns: Implement dns record comparison function
via db2573e s4 dns: Implement dns name equality check
via a00709e s4 dns: Fix some typos in comments and a whitespace
from b939144 check_name() not needed in mkdir.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit b1fdf4065e4569e58ffceb44e9f4105fa1f8740e
Author: Kai Blin <kai at samba.org>
Date: Fri Dec 16 14:25:57 2011 +0100
s4 dns: Allow updates based on smb.conf setting
Autobuild-User: Kai Blin <kai at samba.org>
Autobuild-Date: Sat Dec 17 04:19:40 CET 2011 on sn-devel-104
commit afa98bdc51c635cb7d7cc8c63497598e522610fd
Author: Kai Blin <kai at samba.org>
Date: Fri Dec 16 14:22:51 2011 +0100
s4 dns: Add some debug output
commit d8a499a27b1cc19189be7cf51f01888389346950
Author: Kai Blin <kai at samba.org>
Date: Fri Dec 16 14:21:52 2011 +0100
s4 dns: Actually handle the update request
commit c191ad7e130c637faef23e7cec9d37c097da5a8b
Author: Kai Blin <kai at samba.org>
Date: Fri Dec 16 14:07:11 2011 +0100
s4 dns: Implement RFC-compatible update prescan
commit 02c9e18094f68d9014fe56c4d1b1c51fd22bd1b5
Author: Kai Blin <kai at samba.org>
Date: Fri Dec 16 13:45:22 2011 +0100
s4 dns: Update prerequisite checking conforming to RFC
commit 589d995276f4868a1801d5d41f9a527a6323dbb9
Author: Kai Blin <kai at samba.org>
Date: Fri Dec 16 11:36:47 2011 +0100
s4 dns: Give better test output on RCODE mismatch
commit 8b82bad0065895e0417f095c6b9ed2ada31fbdaa
Author: Kai Blin <kai at samba.org>
Date: Fri Dec 16 09:43:47 2011 +0100
s4 dns: Move record lookup to dns_utils.c
commit 0922953b10f3495e5d62867025e7e99ebc3e6613
Author: Kai Blin <kai at samba.org>
Date: Fri Dec 16 09:24:18 2011 +0100
s4 dns: Implement dns record comparison function
commit db2573eadfd9389391f6daf73432de7f73b46e81
Author: Kai Blin <kai at samba.org>
Date: Fri Dec 16 09:21:51 2011 +0100
s4 dns: Implement dns name equality check
commit a00709eff1c3f9e53fcfbbc93ac498cb182c9ac7
Author: Kai Blin <kai at samba.org>
Date: Fri Dec 16 09:13:31 2011 +0100
s4 dns: Fix some typos in comments and a whitespace
-----------------------------------------------------------------------
Summary of changes:
lib/param/loadparm.c | 12 +
lib/param/param.h | 1 +
lib/param/param_enums.c | 8 +
librpc/idl/dns.idl | 7 +-
source3/param/loadparm.c | 1 +
source4/dns_server/dns_query.c | 43 +--
source4/dns_server/dns_server.c | 8 +-
source4/dns_server/dns_server.h | 17 +-
source4/dns_server/dns_update.c | 624 ++++++++++++++++++--
.../libnet/grouptest.h => dns_server/dns_update.h} | 11 +-
source4/dns_server/dns_utils.c | 183 ++++++
source4/scripting/python/samba/tests/dns.py | 100 +++-
12 files changed, 922 insertions(+), 93 deletions(-)
copy source4/{torture/libnet/grouptest.h => dns_server/dns_update.h} (81%)
Changeset truncated at 500 lines:
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index 8ed9ced..2c59a3e 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -65,6 +65,7 @@
#include "s3_param.h"
#include "lib/util/bitmap.h"
#include "libcli/smb/smb_constants.h"
+#include "source4/dns_server/dns_update.h"
#define standard_sub_basic talloc_strdup
@@ -1223,6 +1224,14 @@ static struct parm_struct parm_table[] = {
.special = NULL,
.enum_list = NULL
},
+ {
+ .label = "allow dns updates",
+ .type = P_ENUM,
+ .p_class = P_GLOBAL,
+ .offset = GLOBAL_VAR(allow_dns_updates),
+ .special = NULL,
+ .enum_list = enum_dns_update_settings
+ },
{NULL, P_BOOL, P_NONE, 0, NULL, NULL, 0}
};
@@ -1503,6 +1512,7 @@ FN_GLOBAL_INTEGER(srv_minprotocol, srv_minprotocol)
FN_GLOBAL_INTEGER(cli_maxprotocol, cli_maxprotocol)
FN_GLOBAL_INTEGER(cli_minprotocol, cli_minprotocol)
FN_GLOBAL_BOOL(paranoid_server_security, paranoid_server_security)
+FN_GLOBAL_INTEGER(allow_dns_updates, allow_dns_updates)
FN_GLOBAL_INTEGER(server_signing, server_signing)
FN_GLOBAL_INTEGER(client_signing, client_signing)
@@ -3362,6 +3372,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
lpcfg_do_global_parameter(lp_ctx, "rndc command", "/usr/sbin/rndc");
lpcfg_do_global_parameter(lp_ctx, "nsupdate command", "/usr/bin/nsupdate -g");
+ lpcfg_do_global_parameter(lp_ctx, "allow dns updates", "False");
+
for (i = 0; parm_table[i].label; i++) {
if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
lp_ctx->flags[i] |= FLAG_DEFAULT;
diff --git a/lib/param/param.h b/lib/param/param.h
index f682385..079ef8b 100644
--- a/lib/param/param.h
+++ b/lib/param/param.h
@@ -56,6 +56,7 @@ const char *lpcfg_realm(struct loadparm_context *);
const char *lpcfg_netbios_name(struct loadparm_context *);
const char *lpcfg_private_dir(struct loadparm_context *);
int lpcfg_server_role(struct loadparm_context *);
+int lpcfg_allow_dns_updates(struct loadparm_context *);
void reload_charcnv(struct loadparm_context *lp_ctx);
diff --git a/lib/param/param_enums.c b/lib/param/param_enums.c
index 9307a0c..d30458f 100644
--- a/lib/param/param_enums.c
+++ b/lib/param/param_enums.c
@@ -107,3 +107,11 @@ static const struct enum_list enum_smb_signing_vals[] = {
{SMB_SIGNING_REQUIRED, "enforced"},
{-1, NULL}
};
+
+/* DNS update options. */
+static const struct enum_list enum_dns_update_settings[] = {
+ {DNS_UPDATE_OFF, "False"},
+ {DNS_UPDATE_ON, "True"},
+ {DNS_UPDATE_SIGNED, "signed"},
+ {-1, NULL}
+};
diff --git a/librpc/idl/dns.idl b/librpc/idl/dns.idl
index a60c314..e012162 100644
--- a/librpc/idl/dns.idl
+++ b/librpc/idl/dns.idl
@@ -105,9 +105,10 @@ interface dns
DNS_QTYPE_NSEC = 0x002F,
DNS_QTYPE_DNSKEY = 0x0030,
DNS_QTYPE_DHCID = 0x0031,
- DNS_QTYPE_ALL = 0x00FF,
- DNS_QTYPE_WINS = 0xFF01,
- DNS_QTYPE_WINSR = 0xFF02
+ DNS_QTYPE_AXFR = 0x00FC,
+ DNS_QTYPE_MAILB = 0x00FD,
+ DNS_QTYPE_MAILA = 0x00FE,
+ DNS_QTYPE_ALL = 0x00FF
} dns_qtype;
typedef [public] struct {
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index e0da6fd..1bd2733 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -68,6 +68,7 @@
#include "dbwrap/dbwrap.h"
#include "dbwrap/dbwrap_rbt.h"
#include "../lib/util/bitmap.h"
+#include "../source4/dns_server/dns_update.h"
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c
index b233b25..5320e21 100644
--- a/source4/dns_server/dns_query.c
+++ b/source4/dns_server/dns_query.c
@@ -89,48 +89,22 @@ static WERROR handle_question(struct dns_server *dns,
struct dns_res_rec **answers, uint16_t *ancount)
{
struct dns_res_rec *ans;
- struct ldb_dn *dn = NULL;
WERROR werror;
- static const char * const attrs[] = { "dnsRecord", NULL};
- int ret;
- uint16_t ai = *ancount;
unsigned int ri;
- struct ldb_message *msg = NULL;
struct dnsp_DnssrvRpcRecord *recs;
- struct ldb_message_element *el;
+ uint16_t rec_count, ai = 0;
+ struct ldb_dn *dn = NULL;
werror = dns_name2dn(dns, mem_ctx, question->name, &dn);
W_ERROR_NOT_OK_RETURN(werror);
- ret = dsdb_search_one(dns->samdb, mem_ctx, &msg, dn,
- LDB_SCOPE_BASE, attrs, 0, "%s", "(objectClass=dnsNode)");
- if (ret != LDB_SUCCESS) {
- return DNS_ERR(NAME_ERROR);
- }
-
- el = ldb_msg_find_element(msg, attrs[0]);
- if (el == NULL) {
- return DNS_ERR(NAME_ERROR);
- }
-
- recs = talloc_array(mem_ctx, struct dnsp_DnssrvRpcRecord, el->num_values);
- for (ri = 0; ri < el->num_values; ri++) {
- struct ldb_val *v = &el->values[ri];
- enum ndr_err_code ndr_err;
-
- ndr_err = ndr_pull_struct_blob(v, recs, &recs[ri],
- (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(0, ("Failed to grab dnsp_DnssrvRpcRecord\n"));
- return DNS_ERR(SERVER_FAILURE);
- }
- }
+ werror = dns_lookup_records(dns, mem_ctx, dn, &recs, &rec_count);
+ W_ERROR_NOT_OK_RETURN(werror);
- ans = talloc_realloc(mem_ctx, *answers, struct dns_res_rec,
- ai + el->num_values);
+ ans = talloc_zero_array(mem_ctx, struct dns_res_rec, rec_count);
W_ERROR_HAVE_NO_MEMORY(ans);
- for (ri = 0; ri < el->num_values; ri++) {
+ for (ri = 0; ri < rec_count; ri++) {
if ((question->question_type != DNS_QTYPE_ALL) &&
(recs[ri].wType != question->question_type)) {
continue;
@@ -138,7 +112,7 @@ static WERROR handle_question(struct dns_server *dns,
create_response_rr(question, &recs[ri], &ans, &ai);
}
- if (*ancount == ai) {
+ if (ai == 0) {
return DNS_ERR(NAME_ERROR);
}
@@ -169,9 +143,6 @@ WERROR dns_server_process_query(struct dns_server *dns,
return DNS_ERR(NOT_IMPLEMENTED);
}
- ans = talloc_array(mem_ctx, struct dns_res_rec, 0);
- W_ERROR_HAVE_NO_MEMORY(ans);
-
werror = handle_question(dns, mem_ctx, &in->questions[0], &ans, &num_answers);
W_ERROR_NOT_OK_GOTO(werror, query_failed);
diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c
index 4aecc87..25873c2 100644
--- a/source4/dns_server/dns_server.c
+++ b/source4/dns_server/dns_server.c
@@ -147,7 +147,7 @@ static NTSTATUS dns_process(struct dns_server *dns,
break;
case DNS_OPCODE_UPDATE:
ret = dns_server_process_update(dns, out_packet, in_packet,
- answers, num_answers,
+ &answers, &num_answers,
&nsrecs, &num_nsrecs,
&additional, &num_additional);
break;
@@ -238,7 +238,7 @@ static void dns_tcp_call_loop(struct tevent_req *subreq)
tsocket_address_string(dns_conn->conn->remote_address, call)));
/* skip length header */
- call->in.data +=4;
+ call->in.data += 4;
call->in.length -= 4;
/* Call dns */
@@ -417,11 +417,11 @@ static void dns_udp_call_loop(struct tevent_req *subreq)
call->in.data = buf;
call->in.length = len;
- DEBUG(10,("Received krb5 UDP packet of length %lu from %s\n",
+ DEBUG(10,("Received DNS UDP packet of length %lu from %s\n",
(long)call->in.length,
tsocket_address_string(call->src, call)));
- /* Call krb5 */
+ /* Call dns_process */
status = dns_process(sock->dns_socket->dns, call, &call->in, &call->out);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(call);
diff --git a/source4/dns_server/dns_server.h b/source4/dns_server/dns_server.h
index d658b2a..53d6306 100644
--- a/source4/dns_server/dns_server.h
+++ b/source4/dns_server/dns_server.h
@@ -23,6 +23,7 @@
#define __DNS_SERVER_H__
#include "librpc/gen_ndr/dns.h"
+#include "librpc/gen_ndr/ndr_dnsp.h"
struct tsocket_address;
@@ -49,12 +50,26 @@ WERROR dns_server_process_query(struct dns_server *dns,
WERROR dns_server_process_update(struct dns_server *dns,
TALLOC_CTX *mem_ctx,
struct dns_name_packet *in,
- struct dns_res_rec *prereqs, uint16_t prereq_count,
+ struct dns_res_rec **prereqs, uint16_t *prereq_count,
struct dns_res_rec **updates, uint16_t *update_count,
struct dns_res_rec **additional, uint16_t *arcount);
uint8_t werr_to_dns_err(WERROR werror);
bool dns_name_match(const char *zone, const char *name, size_t *host_part_len);
+bool dns_name_equal(const char *name1, const char *name2);
+bool dns_records_match(struct dnsp_DnssrvRpcRecord *rec1,
+ struct dnsp_DnssrvRpcRecord *rec2);
+WERROR dns_lookup_records(struct dns_server *dns,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_dn *dn,
+ struct dnsp_DnssrvRpcRecord **records,
+ uint16_t *rec_count);
+WERROR dns_replace_records(struct dns_server *dns,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_dn *dn,
+ bool needs_add,
+ const struct dnsp_DnssrvRpcRecord *records,
+ uint16_t rec_count);
WERROR dns_name2dn(struct dns_server *dns,
TALLOC_CTX *mem_ctx,
const char *name,
diff --git a/source4/dns_server/dns_update.c b/source4/dns_server/dns_update.c
index 55589d2..3fd612c 100644
--- a/source4/dns_server/dns_update.c
+++ b/source4/dns_server/dns_update.c
@@ -25,66 +25,192 @@
#include "librpc/gen_ndr/ndr_dns.h"
#include "librpc/gen_ndr/ndr_dnsp.h"
#include <ldb.h>
+#include "param/param.h"
#include "dsdb/samdb/samdb.h"
#include "dsdb/common/util.h"
+#include "smbd/service_task.h"
#include "dns_server/dns_server.h"
+#include "dns_server/dns_update.h"
-static WERROR check_prerequsites(struct dns_server *dns,
- TALLOC_CTX *mem_ctx,
- const struct dns_name_packet *in,
- const struct dns_res_rec *prereqs, uint16_t count)
+static WERROR dns_rr_to_dnsp(TALLOC_CTX *mem_ctx,
+ const struct dns_res_rec *rrec,
+ struct dnsp_DnssrvRpcRecord *r);
+
+static WERROR check_one_prerequisite(struct dns_server *dns,
+ TALLOC_CTX *mem_ctx,
+ const struct dns_name_question *zone,
+ const struct dns_res_rec *pr,
+ bool *final_result)
{
- const struct dns_name_question *zone;
- size_t host_part_len = 0;
+ bool match;
+ WERROR werror;
+ struct ldb_dn *dn;
uint16_t i;
+ bool found = false;
+ struct dnsp_DnssrvRpcRecord *rec = NULL;
+ struct dnsp_DnssrvRpcRecord *ans;
+ uint16_t acount;
- zone = in->questions;
+ size_t host_part_len = 0;
- for (i = 0; i < count; i++) {
- const struct dns_res_rec *r = &prereqs[i];
- bool match;
+ *final_result = true;
+
+ if (pr->ttl != 0) {
+ return DNS_ERR(FORMAT_ERROR);
+ }
+
+ match = dns_name_match(zone->name, pr->name, &host_part_len);
+ if (!match) {
+ return DNS_ERR(NOTZONE);
+ }
+
+ werror = dns_name2dn(dns, mem_ctx, pr->name, &dn);
+ W_ERROR_NOT_OK_RETURN(werror);
- if (r->ttl != 0) {
+ if (pr->rr_class == DNS_QCLASS_ANY) {
+
+ if (pr->length != 0) {
return DNS_ERR(FORMAT_ERROR);
}
- match = dns_name_match(zone->name, r->name, &host_part_len);
- if (!match) {
- /* TODO: check if we need to echo all prereqs if the
- * first fails */
- return DNS_ERR(NOTZONE);
- }
- if (r->rr_class == DNS_QCLASS_ANY) {
- if (r->length != 0) {
- return DNS_ERR(FORMAT_ERROR);
- }
- if (r->rr_type == DNS_QTYPE_ALL) {
- /* TODO: Check if zone has at least one RR */
+
+
+ if (pr->rr_type == DNS_QTYPE_ALL) {
+ /*
+ */
+ werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount);
+ W_ERROR_NOT_OK_RETURN(werror);
+
+ if (acount == 0) {
return DNS_ERR(NAME_ERROR);
- } else {
- /* TODO: Check if RR exists of the specified type */
+ }
+ } else {
+ /*
+ */
+ werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount);
+ if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) {
return DNS_ERR(NXRRSET);
}
- }
- if (r->rr_class == DNS_QCLASS_NONE) {
- if (r->length != 0) {
- return DNS_ERR(FORMAT_ERROR);
+ W_ERROR_NOT_OK_RETURN(werror);
+
+ for (i = 0; i < acount; i++) {
+ if (ans[i].wType == pr->rr_type) {
+ found = true;
+ break;
+ }
}
- if (r->rr_type == DNS_QTYPE_ALL) {
- /* TODO: Return this error if the given name exits in this zone */
+ if (!found) {
+ return DNS_ERR(NXRRSET);
+ }
+ }
+
+ /*
+ * RFC2136 3.2.5 doesn't actually mention the need to return
+ * OK here, but otherwise we'd always return a FORMAT_ERROR
+ * later on. This also matches Microsoft DNS behavior.
+ */
+ return WERR_OK;
+ }
+
+ if (pr->rr_class == DNS_QCLASS_NONE) {
+ if (pr->length != 0) {
+ return DNS_ERR(FORMAT_ERROR);
+ }
+
+ if (pr->rr_type == DNS_QTYPE_ALL) {
+ /*
+ */
+ werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount);
+ if (W_ERROR_EQUAL(werror, WERR_OK)) {
return DNS_ERR(YXDOMAIN);
- } else {
- /* TODO: Return error if there's an RRset of this type in the zone */
+ }
+ } else {
+ /*
+ */
+ werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount);
+ if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) {
+ werror = WERR_OK;
+ ans = NULL;
+ acount = 0;
+ }
+
+ for (i = 0; i < acount; i++) {
+ if (ans[i].wType == pr->rr_type) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
return DNS_ERR(YXRRSET);
}
}
- if (r->rr_class == zone->question_class) {
- /* Check if there's a RR with this */
- return DNS_ERR(NOT_IMPLEMENTED);
- } else {
- return DNS_ERR(FORMAT_ERROR);
+
+ /*
+ * RFC2136 3.2.5 doesn't actually mention the need to return
+ * OK here, but otherwise we'd always return a FORMAT_ERROR
+ * later on. This also matches Microsoft DNS behavior.
+ */
+ return WERR_OK;
+ }
+
+ if (pr->rr_class != zone->question_class) {
+ return DNS_ERR(FORMAT_ERROR);
+ }
+
+ *final_result = false;
+
+ werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount);
+ if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) {
+ return DNS_ERR(NXRRSET);
+ }
+ W_ERROR_NOT_OK_RETURN(werror);
+
+ rec = talloc_zero(mem_ctx, struct dnsp_DnssrvRpcRecord);
+ W_ERROR_HAVE_NO_MEMORY(rec);
+
+ werror = dns_rr_to_dnsp(rec, pr, rec);
+ W_ERROR_NOT_OK_RETURN(werror);
+
+ for (i = 0; i < acount; i++) {
+ if (dns_records_match(rec, &ans[i])) {
+ found = true;
+ break;
}
}
+ if (!found) {
+ return DNS_ERR(NXRRSET);
+ }
+
+ return WERR_OK;
+}
+
+static WERROR check_prerequisites(struct dns_server *dns,
+ TALLOC_CTX *mem_ctx,
+ const struct dns_name_question *zone,
+ const struct dns_res_rec *prereqs, uint16_t count)
+{
+ uint16_t i;
+ WERROR final_error = WERR_OK;
+
+ for (i = 0; i < count; i++) {
+ bool final;
+ WERROR werror;
+
+ werror = check_one_prerequisite(dns, mem_ctx, zone,
+ &prereqs[i], &final);
+ if (!W_ERROR_IS_OK(werror)) {
+ if (final) {
+ return werror;
+ }
+ if (W_ERROR_IS_OK(final_error)) {
+ final_error = werror;
+ }
+ }
+ }
+
+ if (!W_ERROR_IS_OK(final_error)) {
+ return final_error;
+ }
return WERR_OK;
}
@@ -104,16 +230,48 @@ static WERROR update_prescan(const struct dns_name_question *zone,
return DNS_ERR(NOTZONE);
}
if (zone->question_class == r->rr_class) {
- /*TODO: also check for AXFR,MAILA,MAILB */
if (r->rr_type == DNS_QTYPE_ALL) {
return DNS_ERR(FORMAT_ERROR);
}
+ if (r->rr_type == DNS_QTYPE_AXFR) {
--
Samba Shared Repository
More information about the samba-cvs
mailing list