Commit 71bd858d authored by Evan Hunt's avatar Evan Hunt

2989. [func] Added support for writable DLZ zones. (Contributed

			by Andrew Tridgell of the Samba project.) [RT #22629]

2988.	[experimental]	Added a "dlopen" DLZ driver, allowing the creation
			of external DLZ drivers that can be loaded as
			shared objects at runtime rather than linked with
			named.  Currently this is switched on via a
			compile-time option, "configure --with-dlz-dlopen".
			Note: the syntax for configuring DLZ zones
			is likely to be refined in future releases.
			(Contributed by Andrew Tridgell of the Samba
			project.) [RT #22629]

2987.	[func]		Improve ease of configuring TKEY/GSS updates by
			adding a "tkey-gssapi-keytab" option.  If set,
			updates will be allowed with any key matching
			a principal in the specified keytab file.
			"tkey-gssapi-credential" is no longer required
			and is expected to be deprecated.  (Contributed
			by Andrew Tridgell of the Samba project.)
			[RT #22629]
parent 21b13993
2989. [func] Added support for writable DLZ zones. (Contributed
by Andrew Tridgell of the Samba project.) [RT #22629]
2988. [experimental] Added a "dlopen" DLZ driver, allowing the creation
of external DLZ drivers that can be loaded as
shared objects at runtime rather than linked with
named. Currently this is switched on via a
compile-time option, "configure --with-dlz-dlopen".
Note: the syntax for configuring DLZ zones
is likely to be refined in future releases.
(Contributed by Andrew Tridgell of the Samba
project.) [RT #22629]
2987. [func] Improve ease of configuring TKEY/GSS updates by
adding a "tkey-gssapi-keytab" option. If set,
updates will be allowed with any key matching
a principal in the specified keytab file.
"tkey-gssapi-credential" is no longer required
and is expected to be deprecated. (Contributed
by Andrew Tridgell of the Samba project.)
[RT #22629]
2986. [func] Add new zone type "static-stub". It's like a stub
zone, but the nameserver names and/or their IP
addresses are statically configured. [RT #21474]
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: zoneconf.h,v 1.26 2007/06/19 23:46:59 tbox Exp $ */
/* $Id: zoneconf.h,v 1.27 2010/12/18 01:56:19 each Exp $ */
#ifndef NS_ZONECONF_H
#define NS_ZONECONF_H 1
......@@ -58,6 +58,21 @@ ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig);
* and recreated, return ISC_FALSE.
*/
isc_result_t
ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone,
dns_rdataclass_t rdclass, dns_name_t *name);
/*%>
* configure a DLZ zone, setting up the database methods and calling
* postload to load the origin values
*
* Require:
* \li 'dlzdatabase' to be a valid dlz database
* \li 'zone' to be initialized.
* \li 'rdclass' to be a valid rdataclass
* \li 'name' to be a valid zone origin name
*/
ISC_LANG_ENDDECLS
#endif /* NS_ZONECONF_H */
......@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- $Id: named.conf.docbook,v 1.46 2010/05/14 23:50:39 tbox Exp $ -->
<!-- $Id: named.conf.docbook,v 1.47 2010/12/18 01:56:19 each Exp $ -->
<refentry>
<refentryinfo>
<date>Aug 13, 2004</date>
......@@ -225,6 +225,7 @@ options {
tcp-listen-queue <replaceable>integer</replaceable>;
tkey-dhkey <replaceable>quoted_string</replaceable> <replaceable>integer</replaceable>;
tkey-gssapi-credential <replaceable>quoted_string</replaceable>;
tkey-gssapi-keytab <replaceable>quoted_string</replaceable>;
tkey-domain <replaceable>quoted_string</replaceable>;
transfers-per-ns <replaceable>integer</replaceable>;
transfers-in <replaceable>integer</replaceable>;
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.590 2010/12/09 00:54:33 marka Exp $ */
/* $Id: server.c,v 1.591 2010/12/18 01:56:19 each Exp $ */
/*! \file */
......@@ -1290,6 +1290,27 @@ cache_sharable(dns_view_t *originview, dns_view_t *view,
return (ISC_TRUE);
}
#ifdef DLZ
/*
* Callback from DLZ configure when the driver sets up a writeable zone
*/
static isc_result_t
dlzconfigure_callback(dns_view_t *view, dns_zone_t *zone) {
dns_name_t *origin = dns_zone_getorigin(zone);
dns_rdataclass_t zclass = view->rdclass;
isc_result_t result;
result = dns_zonemgr_managezone(ns_g_server->zonemgr, zone);
if (result != ISC_R_SUCCESS)
return result;
dns_zone_setstats(zone, ns_g_server->zonestats);
return ns_zone_configure_writeable_dlz(view->dlzdatabase,
zone, zclass, origin);
}
#endif
/*
* Configure 'view' according to 'vconfig', taking defaults from 'config'
* where values are missing in 'vconfig'.
......@@ -1563,6 +1584,14 @@ configure_view(dns_view_t *view, cfg_parser_t* parser,
isc_mem_put(mctx, dlzargv, dlzargc * sizeof(*dlzargv));
if (result != ISC_R_SUCCESS)
goto cleanup;
/*
* If the dlz backend supports configuration,
* then call its configure method now.
*/
result = dns_dlzconfigure(view, dlzconfigure_callback);
if (result != ISC_R_SUCCESS)
goto cleanup;
}
}
#endif
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: tkeyconf.c,v 1.31 2009/09/02 23:48:01 tbox Exp $ */
/* $Id: tkeyconf.c,v 1.32 2010/12/18 01:56:19 each Exp $ */
/*! \file */
......@@ -114,6 +114,18 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
RETERR(dst_gssapi_acquirecred(name, ISC_FALSE, &tctx->gsscred));
}
obj = NULL;
result = cfg_map_get(options, "tkey-gssapi-keytab", &obj);
if (result == ISC_R_SUCCESS) {
s = cfg_obj_asstring(obj);
tctx->gssapi_keytab = isc_mem_strdup(mctx, s);
if (tctx->gssapi_keytab == NULL) {
result = ISC_R_NOMEMORY;
goto failure;
}
}
*tctxp = tctx;
return (ISC_R_SUCCESS);
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: update.c,v 1.185 2010/12/09 06:17:33 marka Exp $ */
/* $Id: update.c,v 1.186 2010/12/18 01:56:19 each Exp $ */
#include <config.h>
......@@ -46,6 +46,7 @@
#include <dns/rdatatype.h>
#include <dns/soa.h>
#include <dns/ssu.h>
#include <dns/tsig.h>
#include <dns/view.h>
#include <dns/zone.h>
#include <dns/zt.h>
......@@ -851,6 +852,9 @@ typedef struct {
/* The ssu table to check against. */
dns_ssutable_t *table;
/* the key used for TKEY requests */
dst_key_t *key;
} ssu_check_t;
static isc_result_t
......@@ -867,14 +871,14 @@ ssu_checkrule(void *data, dns_rdataset_t *rrset) {
return (ISC_R_SUCCESS);
result = dns_ssutable_checkrules(ssuinfo->table, ssuinfo->signer,
ssuinfo->name, ssuinfo->tcpaddr,
rrset->type);
rrset->type, ssuinfo->key);
return (result == ISC_TRUE ? ISC_R_SUCCESS : ISC_R_FAILURE);
}
static isc_boolean_t
ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
dns_ssutable_t *ssutable, dns_name_t *signer,
isc_netaddr_t *tcpaddr)
isc_netaddr_t *tcpaddr, dst_key_t *key)
{
isc_result_t result;
ssu_check_t ssuinfo;
......@@ -883,6 +887,7 @@ ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
ssuinfo.table = ssutable;
ssuinfo.signer = signer;
ssuinfo.tcpaddr = tcpaddr;
ssuinfo.key = key;
result = foreach_rrset(db, ver, name, ssu_checkrule, &ssuinfo);
return (ISC_TF(result == ISC_R_SUCCESS));
}
......@@ -2719,6 +2724,7 @@ ns_update_start(ns_client_t *client, isc_result_t sigresult) {
switch(dns_zone_gettype(zone)) {
case dns_zone_master:
case dns_zone_dlz:
/*
* We can now fail due to a bad signature as we now know
* that we are the master.
......@@ -3744,6 +3750,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
if (ssutable != NULL) {
isc_netaddr_t *tcpaddr, netaddr;
dst_key_t *tsigkey = NULL;
/*
* If this is a TCP connection then pass the
* address of the client through for tcp-self
......@@ -3756,16 +3763,22 @@ update_action(isc_task_t *task, isc_event_t *event) {
tcpaddr = &netaddr;
} else
tcpaddr = NULL;
if (client->message->tsigkey != NULL)
tsigkey = client->message->tsigkey->key;
if (rdata.type != dns_rdatatype_any) {
if (!dns_ssutable_checkrules(ssutable,
client->signer,
name, tcpaddr,
rdata.type))
rdata.type,
tsigkey))
FAILC(DNS_R_REFUSED,
"rejected by secure update");
} else {
if (!ssu_checkall(db, ver, name, ssutable,
client->signer, tcpaddr))
client->signer, tcpaddr,
tsigkey))
FAILC(DNS_R_REFUSED,
"rejected by secure update");
}
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: xfrout.c,v 1.138 2010/05/27 23:51:08 tbox Exp $ */
/* $Id: xfrout.c,v 1.139 2010/12/18 01:56:19 each Exp $ */
#include <config.h>
......@@ -863,6 +863,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
switch(dns_zone_gettype(zone)) {
case dns_zone_master:
case dns_zone_slave:
case dns_zone_dlz:
break; /* Master and slave zones are OK for transfer. */
default:
FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", question_name, question_class);
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: zoneconf.c,v 1.167 2010/12/16 23:47:08 tbox Exp $ */
/* $Id: zoneconf.c,v 1.168 2010/12/18 01:56:19 each Exp $ */
/*% */
......@@ -39,6 +39,7 @@
#include <dns/rdataset.h>
#include <dns/rdatalist.h>
#include <dns/result.h>
#include <dns/sdlz.h>
#include <dns/ssu.h>
#include <dns/stats.h>
#include <dns/view.h>
......@@ -1429,6 +1430,31 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
return (ISC_R_SUCCESS);
}
#ifdef DLZ
/*
* Set up a DLZ zone as writeable
*/
isc_result_t
ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone,
dns_rdataclass_t rdclass, dns_name_t *name)
{
dns_db_t *db = NULL;
isc_time_t now;
isc_result_t result;
TIME_NOW(&now);
dns_zone_settype(zone, dns_zone_dlz);
result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db);
if (result != ISC_R_SUCCESS)
return result;
result = dns_zone_dlzpostload(zone, db);
dns_db_detach(&db);
return result;
}
#endif
isc_boolean_t
ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) {
const cfg_obj_t *zoptions = NULL;
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: nsupdate.c,v 1.186 2010/12/09 04:31:57 tbox Exp $ */
/* $Id: nsupdate.c,v 1.187 2010/12/18 01:56:19 each Exp $ */
/*! \file */
......@@ -205,7 +205,7 @@ typedef struct nsu_gssinfo {
} nsu_gssinfo_t;
static void
start_gssrequest(dns_name_t *master);
start_gssrequest(dns_name_t *master, dns_name_t *zone);
static void
send_gssrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
dns_message_t *msg, dns_request_t **request,
......@@ -2371,7 +2371,7 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
dns_name_dup(zonename, mctx, &tmpzonename);
dns_name_init(&restart_master, NULL);
dns_name_dup(&master, mctx, &restart_master);
start_gssrequest(&master);
start_gssrequest(&master, zonename);
} else {
send_update(zonename, serveraddr, localaddr);
setzoneclass(dns_rdataclass_none);
......@@ -2432,7 +2432,7 @@ sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
#ifdef GSSAPI
static void
start_gssrequest(dns_name_t *master)
start_gssrequest(dns_name_t *master, dns_name_t *zone)
{
gss_ctx_id_t context;
isc_buffer_t buf;
......@@ -2444,6 +2444,7 @@ start_gssrequest(dns_name_t *master)
dns_fixedname_t fname;
char namestr[DNS_NAME_FORMATSIZE];
char keystr[DNS_NAME_FORMATSIZE];
char *err_message = NULL;
debug("start_gssrequest");
usevc = ISC_TRUE;
......@@ -2512,9 +2513,11 @@ start_gssrequest(dns_name_t *master)
/* Build first request. */
context = GSS_C_NO_CONTEXT;
result = dns_tkey_buildgssquery(rmsg, keyname, servname, NULL, 0,
&context, use_win2k_gsstsig);
&context, use_win2k_gsstsig,
zone, mctx, &err_message);
if (result == ISC_R_FAILURE)
fatal("Check your Kerberos ticket, it may have expired.");
fatal("tkey query failed: %s",
err_message != NULL ? err_message : "unknown error");
if (result != ISC_R_SUCCESS)
fatal("dns_tkey_buildgssquery failed: %s",
isc_result_totext(result));
......@@ -2563,6 +2566,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
isc_buffer_t buf;
dns_name_t *servname;
dns_fixedname_t fname;
char *err_message = NULL;
UNUSED(task);
......@@ -2632,7 +2636,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
else
use_win2k_gsstsig = ISC_TRUE;
tried_other_gsstsig = ISC_TRUE;
start_gssrequest(&restart_master);
start_gssrequest(&restart_master, zonename);
goto done;
}
......@@ -2651,7 +2655,8 @@ recvgss(isc_task_t *task, isc_event_t *event) {
tsigkey = NULL;
result = dns_tkey_gssnegotiate(tsigquery, rcvmsg, servname,
&context, &tsigkey, gssring,
use_win2k_gsstsig);
use_win2k_gsstsig,
&tmpzonename, &err_message);
switch (result) {
case DNS_R_CONTINUE:
......@@ -2694,7 +2699,9 @@ recvgss(isc_task_t *task, isc_event_t *event) {
break;
default:
fatal("dns_tkey_negotiategss: %s", isc_result_totext(result));
fatal("dns_tkey_negotiategss: %s %s",
isc_result_totext(result),
err_message != NULL ? err_message : "");
}
done:
......
......@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: gsstest.c,v 1.8 2009/09/02 23:48:01 tbox Exp $ */
/* $Id: gsstest.c,v 1.9 2010/12/18 01:56:19 each Exp $ */
#include <config.h>
......@@ -304,7 +304,7 @@ initctx2(isc_task_t *task, isc_event_t *event) {
result = dns_tkey_processgssresponse(query, response,
dns_fixedname_name(&gssname),
&gssctx, &outtoken,
&tsigkey, ring);
&tsigkey, ring, NULL);
gssctx = *gssctxp;
CHECK("dns_tkey_processgssresponse", result);
printf("Context accepted\n");
......
......@@ -15,7 +15,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: conf.sh.in,v 1.55 2010/12/16 09:51:27 jinmei Exp $
# $Id: conf.sh.in,v 1.56 2010/12/18 01:56:19 each Exp $
#
# Common configuration data for system tests, to be sourced into
......@@ -53,10 +53,10 @@ JOURNALPRINT=$TOP/bin/tools/named-journalprint
# load on the machine to make it unusable to other users.
# v6synth
SUBDIRS="acl allow_query addzone autosign cacheclean checkconf checknames
dlv @DLZ_SYSTEM_TEST@ dns64 dnssec forward glue ixfr limits lwresd
masterfile masterformat metadata notify nsupdate pending pkcs11
resolver rrsetorder sortlist smartsign staticstub stub tkey unknown upforwd
views xfer xferquota zonechecks"
dlv @DLZ_SYSTEM_TEST@ dlzexternal dns64 dnssec forward glue ixfr limits
lwresd masterfile masterformat metadata notify nsupdate pending pkcs11
resolver rrsetorder sortlist smartsign staticstub stub tkey
tsig tsiggss unknown upforwd views xfer xferquota zonechecks"
# PERL will be an empty string if no perl interpreter was found.
PERL=@PERL@
......
#!/bin/sh
#
# Clean up after dlzexternal tests.
#
rm -f ns1/update.txt
rm -f */named.memstats
rm -f ns1/ddns.key
controls { };
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port 5300;
pid-file "named.pid";
session-keyfile "session.key";
listen-on { 10.53.0.1; 127.0.0.1; };
listen-on-v6 { none; };
recursion no;
notify yes;
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
include "ddns.key";
controls {
inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; };
};
dlz "example zone" {
database "dlopen ../../../../../contrib/dlz/example/dlz_example.so example.nil";
};
#!/bin/sh
TOP=${SYSTEMTESTTOP:=.}/../../../..
# enable the dlzexternal test only if it builds and dlz-dlopen was enabled
$TOP/bin/named/named -V | grep with.dlz.dlopen | grep -v with.dlz.dlopen=no > /dev/null || {
echo "I:not built with --with-dlz-dlopen=yes - skipping dlzexternal test"
exit 1
}
cd ../../../../contrib/dlz/example && make all > /dev/null || {
echo "I:build of dlz_example.so failed - skipping dlzexternal test"
exit 1
}
exit 0
#!/bin/sh
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
../../../tools/genrandom 400 random.data
$DDNSCONFGEN -q -r random.data -z example.nil > ns1/ddns.key
#!/bin/sh
# tests for TSIG-GSS updates
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
status=0
DIGOPTS="@10.53.0.1 -p 5300"
test_update() {
host="$1"
type="$2"
cmd="$3"
digout="$4"
cat <<EOF > ns1/update.txt
server 10.53.0.1 5300
update add $host $cmd
send
EOF
echo "I:testing update for $host $type $cmd"
$NSUPDATE -k ns1/ddns.key ns1/update.txt || {
echo "I:update failed for $host $type $cmd"
return 1
}
out="$($DIG $DIGOPTS -t $type -q $host | egrep ^$host)"
[ $(echo "$out" | grep "$digout" | wc -l) -eq 1 ] || {
echo "I:dig output incorrect for $host $type $cmd: $out"
return 1
}
return 0
}
test_update testdc1.example.nil. A "86400 A 10.53.0.10" "10.53.0.10" || status=1
test_update testdc2.example.nil. A "86400 A 10.53.0.11" "10.53.0.11" || status=1
test_update testdc3.example.nil. A "86400 A 10.53.0.10" "10.53.0.10" || status=1
test_update deny.example.nil. TXT "86400 TXT helloworld" "helloworld" && status=1
[ $status -eq 0 ] && echo "I:dlzexternal tests all OK"
exit $status
#!/bin/sh
#
# Clean up after tsiggss tests.
#
rm -f ns1/*.jnl ns1/update.txt
rm -f */named.memstats
; -*- zone -*-
; this was generated by a Samba4 provision, and is typical
; of a AD DNS zone
$ORIGIN example.nil.
$TTL 1W
@ IN SOA blu hostmaster (
2010113027 ; serial
2D ; refresh
4H ; retry
6W ; expiry
1W ) ; minimum
IN NS blu
IN A 10.53.0.1
;
blu IN A 10.53.0.1
gc._msdcs IN A 10.53.0.1
fb33eb58-5d58-4100-a114-256e0a97ffc1._msdcs IN CNAME blu
;
; global catalog servers
_gc._tcp IN SRV 0 100 3268 blu
_gc._tcp.Default-First-Site-Name._sites IN SRV 0 100 3268 blu
_ldap._tcp.gc._msdcs IN SRV 0 100 3268 blu
_ldap._tcp.Default-First-Site-Name._sites.gc._msdcs IN SRV 0 100 3268 blu
;
; ldap servers
_ldap._tcp IN SRV 0 100 389 blu
_ldap._tcp.dc._msdcs IN SRV 0 100 389 blu
_ldap._tcp.pdc._msdcs IN SRV 0 100 389 blu
_ldap._tcp.d86745b4-f3e0-4af3-be03-2130d1534be8.domains._msdcs IN SRV 0 100 389 blu
_ldap._tcp.Default-First-Site-Name._sites IN SRV 0 100 389 blu
_ldap._tcp.Default-First-Site-Name._sites.dc._msdcs IN SRV 0 100 389 blu
;
; krb5 servers
_kerberos._tcp IN SRV 0 100 88 blu
_kerberos._tcp.dc._msdcs IN SRV 0 100 88 blu
_kerberos._tcp.Default-First-Site-Name._sites IN SRV 0 100 88 blu
_kerberos._tcp.Default-First-Site-Name._sites.dc._msdcs IN SRV 0 100 88 blu
_kerberos._udp IN SRV 0 100 88 blu
; MIT kpasswd likes to lookup this name on password change
_kerberos-master._tcp IN SRV 0 100 88 blu
_kerberos-master._udp IN SRV 0 100 88 blu
;
; kpasswd
_kpasswd._tcp IN SRV 0 100 464 blu
_kpasswd._udp IN SRV 0 100 464 blu
;
; heimdal 'find realm for host' hack
_kerberos IN TXT EXAMPLE.NIL
controls { };
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port 5300;
pid-file "named.pid";
session-keyfile "session.key";
listen-on { 10.53.0.1; 127.0.0.1; };
listen-on-v6 { none; };
recursion no;
notify yes;
tkey-gssapi-keytab "dns.keytab";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; };
};