2630. [func] Improved syntax for DDNS autoconfiguration: use

"update-policy local;" to switch on local DDNS in a
			zone.  [RT #19875]
This commit is contained in:
Evan Hunt 2009-07-14 22:54:57 +00:00
parent 38cd4d14cc
commit 08f860f800
17 changed files with 328 additions and 191 deletions

View file

@ -1,3 +1,7 @@
2630. [func] Improved syntax for DDNS autoconfiguration: use
"update-policy local;" to switch on local DDNS in a
zone. [RT #19875]
2629. [port] Check for seteuid()/setegid(), use setresuid()/
setresgid() if not present. [RT #19932]

View file

@ -12,7 +12,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.3 2009/06/11 23:47:55 tbox Exp $
# $Id: Makefile.in,v 1.4 2009/07/14 22:54:56 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@ -68,9 +68,7 @@ rndc-confgen.@O@: rndc-confgen.c
-c ${srcdir}/rndc-confgen.c
ddns-confgen.@O@: ddns-confgen.c
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
-DDDNS_KEYFILE=\"${localstatedir}/run/named/ddns.key\" \
-c ${srcdir}/ddns-confgen.c
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -c ${srcdir}/ddns-confgen.c
rndc-confgen@EXEEXT@: rndc-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS} ${CONFDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rndc-confgen.@O@ util.@O@ keygen.@O@ \

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: config.c,v 1.98 2009/06/30 02:52:32 each Exp $ */
/* $Id: config.c,v 1.99 2009/07/14 22:54:56 each Exp $ */
/*! \file */
@ -59,9 +59,9 @@ options {\n\
files unlimited;\n\
stacksize default;\n"
#endif
"# ddns-keyfile \"" NS_LOCALSTATEDIR "/run/named/ddns.key\";\n\
ddns-keyname local-ddns;\n\
ddns-keyalg hmac-sha256;\n\
"# session-keyfile \"" NS_LOCALSTATEDIR "/run/named/session.key\";\n\
session-keyname local-ddns;\n\
session-keyalg hmac-sha256;\n\
deallocate-on-exit true;\n\
# directory <none>\n\
dump-file \"named_dump.db\";\n\
@ -168,7 +168,6 @@ options {\n\
notify-delay 5;\n\
notify-to-soa no;\n\
dialup no;\n\
ddns-autoconf no;\n\
# forward <none>\n\
# forwarders <none>\n\
maintain-ixfr-base no;\n\

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: globals.h,v 1.83 2009/06/10 00:27:21 each Exp $ */
/* $Id: globals.h,v 1.84 2009/07/14 22:54:56 each Exp $ */
#ifndef NAMED_GLOBALS_H
#define NAMED_GLOBALS_H 1
@ -92,8 +92,8 @@ EXTERN cfg_obj_t * ns_g_bindkeys INIT(NULL);
EXTERN const char * ns_g_keyfile INIT(NS_SYSCONFDIR
"/rndc.key");
EXTERN dns_tsigkey_t * ns_g_ddnskey INIT(NULL);
EXTERN dns_name_t ns_g_ddnskeyname;
EXTERN dns_tsigkey_t * ns_g_sessionkey INIT(NULL);
EXTERN dns_name_t ns_g_sessionkeyname;
EXTERN const char * lwresd_g_conffile INIT(NS_SYSCONFDIR
"/lwresd.conf");
@ -119,9 +119,9 @@ EXTERN const char * ns_g_chrootdir INIT(NULL);
EXTERN isc_boolean_t ns_g_foreground INIT(ISC_FALSE);
EXTERN isc_boolean_t ns_g_logstderr INIT(ISC_FALSE);
EXTERN const char * ns_g_defaultddnskeyfile INIT(NS_LOCALSTATEDIR
"/run/named/"
"ddns.key");
EXTERN const char * ns_g_defaultsessionkeyfile
INIT(NS_LOCALSTATEDIR "/run/named/"
"session.key");
#if NS_RUN_PID_DIR
EXTERN const char * ns_g_defaultpidfile INIT(NS_LOCALSTATEDIR

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.h,v 1.100 2009/07/02 07:39:02 marka Exp $ */
/* $Id: server.h,v 1.101 2009/07/14 22:54:56 each Exp $ */
#ifndef NAMED_SERVER_H
#define NAMED_SERVER_H 1
@ -110,11 +110,11 @@ struct ns_server {
ns_statschannellist_t statschannels;
dns_tsigkey_t *ddnskey;
char *ddns_keyfile;
dns_name_t *ddns_keyname;
unsigned int ddns_keyalg;
isc_uint16_t ddns_keybits;
dns_tsigkey_t *sessionkey;
char *session_keyfile;
dns_name_t *session_keyname;
unsigned int session_keyalg;
isc_uint16_t session_keybits;
};
#define NS_SERVER_MAGIC ISC_MAGIC('S','V','E','R')

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.537 2009/07/02 07:39:02 marka Exp $ */
/* $Id: server.c,v 1.538 2009/07/14 22:54:56 each Exp $ */
/*! \file */
@ -1786,9 +1786,9 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
* Configure the view's TSIG keys.
*/
CHECK(ns_tsigkeyring_fromconfig(config, vconfig, view->mctx, &ring));
if (ns_g_server->ddnskey != NULL) {
CHECK(dns_tsigkeyring_add(ring, ns_g_server->ddns_keyname,
ns_g_server->ddnskey));
if (ns_g_server->sessionkey != NULL) {
CHECK(dns_tsigkeyring_add(ring, ns_g_server->session_keyname,
ns_g_server->sessionkey));
}
dns_view_setkeyring(view, ring);
ring = NULL; /* ownership transferred */
@ -3327,24 +3327,24 @@ removed(dns_zone_t *zone, void *uap) {
static void
cleanup_session_key(ns_server_t *server, isc_mem_t *mctx) {
if (server->ddns_keyfile != NULL) {
isc_file_remove(server->ddns_keyfile);
isc_mem_free(mctx, server->ddns_keyfile);
server->ddns_keyfile = NULL;
if (server->session_keyfile != NULL) {
isc_file_remove(server->session_keyfile);
isc_mem_free(mctx, server->session_keyfile);
server->session_keyfile = NULL;
}
if (server->ddns_keyname != NULL) {
if (dns_name_dynamic(server->ddns_keyname))
dns_name_free(server->ddns_keyname, mctx);
isc_mem_put(mctx, server->ddns_keyname, sizeof(dns_name_t));
server->ddns_keyname = NULL;
if (server->session_keyname != NULL) {
if (dns_name_dynamic(server->session_keyname))
dns_name_free(server->session_keyname, mctx);
isc_mem_put(mctx, server->session_keyname, sizeof(dns_name_t));
server->session_keyname = NULL;
}
if (server->ddnskey != NULL)
dns_tsigkey_detach(&server->ddnskey);
if (server->sessionkey != NULL)
dns_tsigkey_detach(&server->sessionkey);
server->ddns_keyalg = DST_ALG_UNKNOWN;
server->ddns_keybits = 0;
server->session_keyalg = DST_ALG_UNKNOWN;
server->session_keybits = 0;
}
static isc_result_t
@ -3395,7 +3395,13 @@ generate_session_key(const char *filename, const char *keynamestr,
key = NULL; /* ownership of key has been transferred */
/* Dump the key to the key file. */
CHECK(isc_file_safecreate(filename, &fp));
result = isc_file_safecreate(filename, &fp);
if (result != ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"could not create %s", filename);
goto cleanup;
}
fprintf(fp, "key \"%s\" {\n"
"\talgorithm %s;\n"
@ -3439,17 +3445,17 @@ configure_session_key(const cfg_obj_t **maps, ns_server_t *server,
isc_result_t result;
obj = NULL;
result = ns_config_get(maps, "ddns-keyfile", &obj);
result = ns_config_get(maps, "session-keyfile", &obj);
if (result == ISC_R_SUCCESS) {
if (cfg_obj_isvoid(obj))
keyfile = NULL; /* disable it */
else
keyfile = cfg_obj_asstring(obj);
} else
keyfile = ns_g_defaultddnskeyfile;
keyfile = ns_g_defaultsessionkeyfile;
obj = NULL;
result = ns_config_get(maps, "ddns-keyname", &obj);
result = ns_config_get(maps, "session-keyname", &obj);
INSIST(result == ISC_R_SUCCESS);
keynamestr = cfg_obj_asstring(obj);
dns_fixedname_init(&fname);
@ -3462,7 +3468,7 @@ configure_session_key(const cfg_obj_t **maps, ns_server_t *server,
return (result);
obj = NULL;
result = ns_config_get(maps, "ddns-keyalg", &obj);
result = ns_config_get(maps, "session-keyalg", &obj);
INSIST(result == ISC_R_SUCCESS);
algstr = cfg_obj_asstring(obj);
algname = NULL;
@ -3470,58 +3476,58 @@ configure_session_key(const cfg_obj_t **maps, ns_server_t *server,
if (result != ISC_R_SUCCESS) {
const char *s = " (keeping current key)";
cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, "ddns-keyalg: "
cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, "session-keyalg: "
"unsupported or unknown algorithm '%s'%s",
algstr,
server->ddns_keyfile != NULL ? s : "");
server->session_keyfile != NULL ? s : "");
return (result);
}
/* See if we need to (re)generate a new key. */
if (keyfile == NULL) {
if (server->ddns_keyfile != NULL)
if (server->session_keyfile != NULL)
need_deleteold = ISC_TRUE;
} else if (server->ddns_keyfile == NULL)
} else if (server->session_keyfile == NULL)
need_createnew = ISC_TRUE;
else if (strcmp(keyfile, server->ddns_keyfile) != 0 ||
!dns_name_equal(server->ddns_keyname, keyname) ||
server->ddns_keyalg != algtype ||
server->ddns_keybits != bits) {
else if (strcmp(keyfile, server->session_keyfile) != 0 ||
!dns_name_equal(server->session_keyname, keyname) ||
server->session_keyalg != algtype ||
server->session_keybits != bits) {
need_deleteold = ISC_TRUE;
need_createnew = ISC_TRUE;
}
if (need_deleteold) {
INSIST(server->ddns_keyfile != NULL);
INSIST(server->ddns_keyname != NULL);
INSIST(server->ddnskey != NULL);
INSIST(server->session_keyfile != NULL);
INSIST(server->session_keyname != NULL);
INSIST(server->sessionkey != NULL);
cleanup_session_key(server, mctx);
}
if (need_createnew) {
INSIST(server->ddnskey == NULL);
INSIST(server->ddns_keyfile == NULL);
INSIST(server->ddns_keyname == NULL);
INSIST(server->ddns_keyalg == DST_ALG_UNKNOWN);
INSIST(server->ddns_keybits == 0);
INSIST(server->sessionkey == NULL);
INSIST(server->session_keyfile == NULL);
INSIST(server->session_keyname == NULL);
INSIST(server->session_keyalg == DST_ALG_UNKNOWN);
INSIST(server->session_keybits == 0);
server->ddns_keyname = isc_mem_get(mctx, sizeof(dns_name_t));
if (server->ddns_keyname == NULL)
server->session_keyname = isc_mem_get(mctx, sizeof(dns_name_t));
if (server->session_keyname == NULL)
goto cleanup;
dns_name_init(server->ddns_keyname, NULL);
CHECK(dns_name_dup(keyname, mctx, server->ddns_keyname));
dns_name_init(server->session_keyname, NULL);
CHECK(dns_name_dup(keyname, mctx, server->session_keyname));
server->ddns_keyfile = isc_mem_strdup(mctx, keyfile);
if (server->ddns_keyfile == NULL)
server->session_keyfile = isc_mem_strdup(mctx, keyfile);
if (server->session_keyfile == NULL)
goto cleanup;
server->ddns_keyalg = algtype;
server->ddns_keybits = bits;
server->session_keyalg = algtype;
server->session_keybits = bits;
CHECK(generate_session_key(keyfile, keynamestr, keyname, algstr,
algname, algtype, bits, mctx,
&server->ddnskey));
&server->sessionkey));
}
return (result);
@ -3962,9 +3968,25 @@ load_configuration(const char *filename, ns_server_t *server,
CHECK(isc_timer_reset(server->pps_timer, isc_timertype_ticker, NULL,
&interval, ISC_FALSE));
/*
* Write the PID file.
*/
obj = NULL;
if (ns_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS)
if (cfg_obj_isvoid(obj))
ns_os_writepidfile(NULL, first_time);
else
ns_os_writepidfile(cfg_obj_asstring(obj), first_time);
else if (ns_g_lwresdonly)
ns_os_writepidfile(lwresd_g_defaultpidfile, first_time);
else
ns_os_writepidfile(ns_g_defaultpidfile, first_time);
/*
* Configure the server-wide session key. This must be done before
* configure views because zone configuration may require ddns-keyname.
* configure views because zone configuration may need to know
* session-keyname.
*
* Failure of session key generation isn't fatal at this time; if it
* turns out that a session key is really needed but doesn't exist,
* we'll treat it as a fatal error then.
@ -4128,17 +4150,6 @@ load_configuration(const char *filename, ns_server_t *server,
}
}
obj = NULL;
if (ns_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS)
if (cfg_obj_isvoid(obj))
ns_os_writepidfile(NULL, first_time);
else
ns_os_writepidfile(cfg_obj_asstring(obj), first_time);
else if (ns_g_lwresdonly)
ns_os_writepidfile(lwresd_g_defaultpidfile, first_time);
else
ns_os_writepidfile(ns_g_defaultpidfile, first_time);
/*
* Relinquish root privileges.
*/
@ -4557,9 +4568,9 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
dns_zonemgr_shutdown(server->zonemgr);
if (ns_g_ddnskey != NULL) {
dns_tsigkey_detach(&ns_g_ddnskey);
dns_name_free(&ns_g_ddnskeyname, server->mctx);
if (ns_g_sessionkey != NULL) {
dns_tsigkey_detach(&ns_g_sessionkey);
dns_name_free(&ns_g_sessionkeyname, server->mctx);
}
if (server->blackholeacl != NULL)
@ -4719,11 +4730,11 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
ISC_LIST_INIT(server->cachelist);
server->ddnskey = NULL;
server->ddns_keyfile = NULL;
server->ddns_keyname = NULL;
server->ddns_keyalg = DST_ALG_UNKNOWN;
server->ddns_keybits = 0;
server->sessionkey = NULL;
server->session_keyfile = NULL;
server->session_keyname = NULL;
server->session_keyalg = DST_ALG_UNKNOWN;
server->session_keybits = 0;
server->magic = NS_SERVER_MAGIC;
*serverp = server;

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: os.c,v 1.34 2009/06/12 02:33:21 each Exp $ */
/* $Id: os.c,v 1.35 2009/07/14 22:54:56 each Exp $ */
#include <config.h>
#include <stdarg.h>
@ -66,7 +66,7 @@ ns_paths_init() {
ns_g_defaultpidfile = isc_ntpaths_get(NAMED_PID_PATH);
lwresd_g_defaultpidfile = isc_ntpaths_get(LWRESD_PID_PATH);
ns_g_keyfile = isc_ntpaths_get(RNDC_KEY_PATH);
ns_g_defaultddnskeyfile = isc_ntpaths_get(DDNS_KEY_PATH);
ns_g_defaultsessionkeyfile = isc_ntpaths_get(SESSION_KEY_PATH);
Initialized = TRUE;
}

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: zoneconf.c,v 1.151 2009/06/10 23:47:47 tbox Exp $ */
/* $Id: zoneconf.c,v 1.152 2009/07/14 22:54:56 each Exp $ */
/*% */
@ -172,21 +172,27 @@ parse_acl:
*/
static isc_result_t
configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
const char *zname, isc_boolean_t autoddns)
{
const char *zname) {
const cfg_obj_t *updatepolicy = NULL;
const cfg_listelt_t *element, *element2;
dns_ssutable_t *table = NULL;
isc_mem_t *mctx = dns_zone_getmctx(zone);
isc_boolean_t autoddns = ISC_FALSE;
isc_result_t result;
(void)cfg_map_get(zconfig, "update-policy", &updatepolicy);
if (updatepolicy == NULL && !autoddns) {
if (updatepolicy == NULL) {
dns_zone_setssutable(zone, NULL);
return (ISC_R_SUCCESS);
}
if (cfg_obj_isstring(updatepolicy) &&
strcmp("local", cfg_obj_asstring(updatepolicy)) == 0) {
autoddns = ISC_TRUE;
updatepolicy = NULL;
}
result = dns_ssutable_create(mctx, &table);
if (result != ISC_R_SUCCESS)
return (result);
@ -336,14 +342,14 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
}
/*
* If this is a "ddns-autoconf" zone and a DDNS session key exists,
* then use the default policy, equivalent to:
* update-policy { grant <ddns-keyname> zonesub any; };
* If "update-policy local;" and a session key exists,
* then use the default policy, which is equivalent to:
* update-policy { grant <session-keyname> zonesub any; };
*/
if (autoddns) {
dns_rdatatype_t any = dns_rdatatype_any;
if (ns_g_server->ddns_keyname == NULL) {
if (ns_g_server->session_keyname == NULL) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"failed to enable auto DDNS policy "
@ -354,7 +360,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
}
result = dns_ssutable_addrule(table, ISC_TRUE,
ns_g_server->ddns_keyname,
ns_g_server->session_keyname,
DNS_SSUMATCHTYPE_SUBDOMAIN,
dns_zone_getorigin(zone),
1, &any);
@ -480,7 +486,6 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
isc_boolean_t check = ISC_FALSE, fail = ISC_FALSE;
isc_boolean_t warn = ISC_FALSE, ignore = ISC_FALSE;
isc_boolean_t ixfrdiff;
isc_boolean_t autoddns;
dns_masterformat_t masterformat;
isc_stats_t *zoneqrystats;
isc_boolean_t zonestats_on;
@ -795,13 +800,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
"address, which is insecure",
zname);
obj = NULL;
result = ns_config_get(maps, "ddns-autoconf", &obj);
INSIST(result == ISC_R_SUCCESS);
autoddns = cfg_obj_asboolean(obj);
RETERR(configure_zone_ssutable(zoptions, zone, zname,
autoddns));
RETERR(configure_zone_ssutable(zoptions, zone, zname));
obj = NULL;
result = ns_config_get(maps, "sig-validity-interval", &obj);

View file

@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.31 2009/06/11 23:47:55 tbox Exp $
# $Id: Makefile.in,v 1.32 2009/07/14 22:54:56 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@ -65,7 +65,7 @@ MANOBJS = ${MANPAGES} ${HTMLPAGES}
nsupdate.@O@: nsupdate.c
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
-DDDNS_KEYFILE=\"${localstatedir}/run/named/ddns.key\" \
-DSESSION_KEYFILE=\"${localstatedir}/run/named/session.key\" \
-c ${srcdir}/nsupdate.c
nsupdate@EXEEXT@: nsupdate.@O@ ${UOBJS} ${DEPLIBS}

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: nsupdate.c,v 1.168 2009/06/10 01:44:53 each Exp $ */
/* $Id: nsupdate.c,v 1.169 2009/07/14 22:54:56 each Exp $ */
/*! \file */
@ -562,9 +562,9 @@ setup_keystr(void) {
* Get a key from a named.conf format keyfile
*/
static isc_result_t
read_ddnskey(isc_mem_t *mctx, isc_log_t *lctx) {
read_sessionkey(isc_mem_t *mctx, isc_log_t *lctx) {
cfg_parser_t *pctx = NULL;
cfg_obj_t *ddnskey = NULL;
cfg_obj_t *sessionkey = NULL;
const cfg_obj_t *key = NULL;
const cfg_obj_t *secretobj = NULL;
const cfg_obj_t *algorithmobj = NULL;
@ -581,11 +581,12 @@ read_ddnskey(isc_mem_t *mctx, isc_log_t *lctx) {
if (result != ISC_R_SUCCESS)
goto cleanup;
result = cfg_parse_file(pctx, keyfile, &cfg_type_ddnskey, &ddnskey);
result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey,
&sessionkey);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = cfg_map_get(ddnskey, "key", &key);
result = cfg_map_get(sessionkey, "key", &key);
if (result != ISC_R_SUCCESS)
goto cleanup;
@ -605,8 +606,8 @@ read_ddnskey(isc_mem_t *mctx, isc_log_t *lctx) {
cleanup:
if (pctx != NULL) {
if (ddnskey != NULL)
cfg_obj_destroy(pctx, &ddnskey);
if (sessionkey != NULL)
cfg_obj_destroy(pctx, &sessionkey);
cfg_parser_destroy(&pctx);
}
@ -629,9 +630,9 @@ setup_keyfile(isc_mem_t *mctx, isc_log_t *lctx) {
DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx,
&dstkey);
/* If that didn't work, try reading it as a ddns.key keyfile */
/* If that didn't work, try reading it as a session.key keyfile */
if (result != ISC_R_SUCCESS) {
result = read_ddnskey(mctx, lctx);
result = read_sessionkey(mctx, lctx);
if (result == ISC_R_SUCCESS)
return;
}
@ -884,7 +885,7 @@ setup_system(void) {
if (keystr != NULL)
setup_keystr();
else if (local_only)
read_ddnskey(mctx, lctx);
read_sessionkey(mctx, lctx);
else if (keyfile != NULL)
setup_keyfile(mctx, lctx);
}
@ -1043,7 +1044,7 @@ parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) {
struct in_addr localhost;
if (keyfile == NULL)
keyfile = DDNS_KEYFILE;
keyfile = SESSION_KEYFILE;
if (userserver == NULL) {
userserver = isc_mem_get(mctx, sizeof(isc_sockaddr_t));

View file

@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- $Id: nsupdate.docbook,v 1.38 2009/06/10 00:27:21 each Exp $ -->
<!-- $Id: nsupdate.docbook,v 1.39 2009/07/14 22:54:57 each Exp $ -->
<refentry id="man.nsupdate">
<refentryinfo>
<date>Jun 30, 2000</date>
@ -179,9 +179,9 @@
address cannot be overridden). Connections to the local server will
use a TSIG key found in <filename>/var/run/named/ddns.key</filename>,
which is automatically generated by <command>named</command> if any
local master zone has the <command>dynamic</command> zone option set
to yes. The location of this key file can be overridden with
the <option>-k</option> option.
local master zone has set <command>update-policy</command> to
<command>local</command>. The location of this key file can be
overridden with the <option>-k</option> option.
</para>
<para>
By default, <command>nsupdate</command>

View file

@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- File: $Id: Bv9ARM-book.xml,v 1.421 2009/07/14 18:08:26 jreed Exp $ -->
<!-- File: $Id: Bv9ARM-book.xml,v 1.422 2009/07/14 22:54:57 each Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
@ -1651,16 +1651,16 @@ controls {
<para>
Dynamic update is enabled by including an
<command>allow-update</command>, <command>update-policy</command>
clause in the <command>zone</command> statement, or by setting the
<command>ddns-autconf</command> option to <userinput>yes</userinput>.
<command>allow-update</command> or an <command>update-policy</command>
clause in the <command>zone</command> statement.
</para>
<para>
If the zone's <command>ddns-autoconf</command> option is set to
<userinput>yes</userinput>, then updates to the zone
will be permitted for the key <filename>ddns.key</filename>,
If the zone's <command>update-policy</command> is set to
<userinput>local</userinput>, updates to the zone
will be permitted for the key <varname>local-ddns</varname>,
which will be generated by <command>named</command> at startup.
See <xref linkend="dynamic_update_policies"/> for more details.
</para>
<para>
@ -2217,9 +2217,8 @@ allow-update { key host1-host2. ;};
</para>
<para>
You may want to read about the more powerful
<command>update-policy</command> statement in
<xref linkend="dynamic_update_policies"/>.
See <xref linkend="dynamic_update_policies"/> for a discussion of
the more flexible <command>update-policy</command> statement.
</para>
</sect2>
@ -5288,6 +5287,58 @@ badresp:1,adberr:0,findfail:0,valfail:0]
</listitem>
</varlistentry>
<varlistentry>
<term><command>session-keyfile</command></term>
<listitem>
<para>
The pathname of the file into which to write a TSIG
session key generated by <command>named</command> for use by
<command>nsupdate -l</command>. If not specified, the
default is <filename>/var/run/named/session.key</filename>.
(See <xref linkend="dynamic_update_policies"/>, and in
particular the discussion of the
<command>update-policy</command> statement's
<userinput>local</userinput> option for more
information about this feature.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>session-keyname</command></term>
<listitem>
<para>
The key name to use for the TSIG session key.
If not specified, the default is "local-ddns".
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>session-keyalg</command></term>
<listitem>
<para>
The algorithm to use for the TSIG session key.
Valid values are hmac-sha1, hmac-sha224, hmac-sha256,
hmac-sha384, hmac-sha512 and hmac-md5. If not
specified, the default is hmac-sha256.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>session-keyfile</command></term>
<listitem>
<para>
The pathname of the file into which to write a session TSIG
key for use by <command>nsupdate -l</command>. (See the
discussion of the <command>update-policy</command>
statement's <userinput>local</userinput> option for more
details on this feature.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>port</command></term>
<listitem>
@ -9123,7 +9174,7 @@ view "external" {
<optional> allow-query-on { <replaceable>address_match_list</replaceable> }; </optional>
<optional> allow-transfer { <replaceable>address_match_list</replaceable> }; </optional>
<optional> allow-update { <replaceable>address_match_list</replaceable> }; </optional>
<optional> update-policy { <replaceable>update_policy_rule</replaceable> <optional>...</optional> }; </optional>
<optional> update-policy <replaceable>local</replaceable> | { <replaceable>update_policy_rule</replaceable> <optional>...</optional> }; </optional>
<optional> also-notify { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ;
<optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
<optional> check-names (<constant>warn</constant>|<constant>fail</constant>|<constant>ignore</constant>) ; </optional>
@ -9746,19 +9797,6 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
</listitem>
</varlistentry>
<varlistentry>
<term><command>ddns-autoconf</command></term>
<listitem>
<para>
If this flag is set to <userinput>yes</userinput> in
a master zone, the zone will be set to allow dynamic
updates using a TSIG session key generated by
<command>named</command> and stored in a file for use
by <command>nsupdate -l</command> on the local system,
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>forward</command></term>
<listitem>
@ -10115,15 +10153,14 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
record of any name in the zone.
</para>
<para>
The <command>update-policy</command> clause is new
in <acronym>BIND</acronym> 9 and allows more fine-grained
control over what updates are allowed. A set of rules
is specified, where each rule either grants or denies
permissions for one or more names to be updated by
one or more identities. If the dynamic update request
message is signed (that is, it includes either a TSIG
or SIG(0) record), the identity of the signer can be
determined.
The <command>update-policy</command> clause
allows more fine-grained control over what updates are
allowed. A set of rules is specified, where each rule
either grants or denies permissions for one or more
names to be updated by one or more identities. If
the dynamic update request message is signed (that is,
it includes either a TSIG or SIG(0) record), the
identity of the signer can be determined.
</para>
<para>
Rules are specified in the <command>update-policy</command>
@ -10135,9 +10172,39 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
only examines the signer of a message; the source
address is not relevant.
</para>
<para>
There is a pre-defined <command>update-policy</command>
rule which can be switched on with the command
<command>update-policy local;</command>.
Switching on this rule in a zone causes
<command>named</command> to generate a TSIG session
key and place it in a file, and to allow that key
to update the zone. (By default, the file is
<filename>/var/run/named/session.key</filename>, the key
name is "local-ddns" and the key algorithm is HMAC-SHA256,
but these values are configurable with the
<command>session-keyfile</command>,
<command>session-keyname</command> and
<command>session-keyalg</command> options, respectively).
</para>
<para>
A client running on the local system, and with appropriate
permissions, may read that file and use the key to sign update
requests. The zone's update policy will be set to allow that
key to change any record within the zone. Assuming the
key name is "local-ddns", this policy is equivalent to:
</para>
<programlisting>update-policy { grant local-ddns zonesub any; };
</programlisting>
<para>
This is how a rule definition looks:
The command <command>nsupdate -l</command> sends update
requests to localhost, and signs them using the session key.
</para>
<para>
Other rule definitions look like this:
</para>
<programlisting>
@ -10147,12 +10214,11 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
<para>
Each rule grants or denies privileges. Once a message has
successfully matched a rule, the operation is immediately
granted
or denied and no further rules are examined. A rule is matched
when the signer matches the identity field, the name matches the
name field in accordance with the nametype field, and the type
matches
the types specified in the type field.
granted or denied and no further rules are examined. A rule
is matched when the signer matches the identity field, the
name matches the name field in accordance with the nametype
field, and the type matches the types specified in the type
field.
</para>
<para>
No signer is required for <replaceable>tcp-self</replaceable>

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: check.c,v 1.103 2009/06/10 23:47:47 tbox Exp $ */
/* $Id: check.c,v 1.104 2009/07/14 22:54:57 each Exp $ */
/*! \file */
@ -969,6 +969,12 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) {
const char *str;
isc_buffer_t b;
/* Check for "update-policy local;" */
if (cfg_obj_isstring(policy) &&
strcmp("local", cfg_obj_asstring(policy)) == 0)
return (ISC_R_SUCCESS);
/* Now check the grant policy */
for (element = cfg_list_first(policy);
element != NULL;
element = cfg_list_next(element))

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: ntpaths.h,v 1.19 2009/06/12 02:33:21 each Exp $ */
/* $Id: ntpaths.h,v 1.20 2009/07/14 22:54:57 each Exp $ */
/*
* Windows-specific path definitions
@ -41,7 +41,7 @@ enum NtPaths {
LOCAL_STATE_DIR,
SYS_CONF_DIR,
RNDC_KEY_PATH,
DDNS_KEY_PATH
SESSION_KEY_PATH
};
/*
@ -50,7 +50,7 @@ enum NtPaths {
#define NAMED_CONFFILE isc_ntpaths_get(NAMED_CONF_PATH)
#define RNDC_CONFFILE isc_ntpaths_get(RNDC_CONF_PATH)
#define RNDC_KEYFILE isc_ntpaths_get(RNDC_KEY_PATH)
#define DDNS_KEYFILE isc_ntpaths_get(DDNS_KEY_PATH)
#define SESSION_KEYFILE isc_ntpaths_get(SESSION_KEY_PATH)
#define RESOLV_CONF isc_ntpaths_get(RESOLV_CONF_PATH)
/*

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: ntpaths.c,v 1.14 2009/06/12 02:33:21 each Exp $ */
/* $Id: ntpaths.c,v 1.15 2009/07/14 22:54:57 each Exp $ */
/*
* This module fetches the required path information that is specific
@ -44,7 +44,7 @@ static char lwresd_defaultpidfile[MAX_PATH];
static char local_state_dir[MAX_PATH];
static char sys_conf_dir[MAX_PATH];
static char rndc_keyFile[MAX_PATH];
static char ddns_keyFile[MAX_PATH];
static char session_keyFile[MAX_PATH];
static DWORD baseLen = MAX_PATH;
static BOOL Initialized = FALSE;
@ -85,8 +85,8 @@ isc_ntpaths_init() {
strcpy(rndc_keyFile, namedBase);
strcat(rndc_keyFile, "\\etc\\rndc.key");
strcpy(ddns_keyFile, namedBase);
strcat(ddns_keyFile, "\\etc\\ddns.key");
strcpy(session_keyFile, namedBase);
strcat(session_keyFile, "\\etc\\session.key");
strcpy(rndc_confFile, namedBase);
strcat(rndc_confFile, "\\etc\\rndc.conf");
@ -138,8 +138,8 @@ isc_ntpaths_get(int ind) {
case RNDC_KEY_PATH:
return (rndc_keyFile);
break;
case DDNS_KEY_PATH:
return (ddns_keyFile);
case SESSION_KEY_PATH:
return (session_keyFile);
break;
default:
return (NULL);

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: namedconf.h,v 1.13 2009/06/25 05:28:34 marka Exp $ */
/* $Id: namedconf.h,v 1.14 2009/07/14 22:54:57 each Exp $ */
#ifndef ISCCFG_NAMEDCONF_H
#define ISCCFG_NAMEDCONF_H 1
@ -42,7 +42,7 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndcconf;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndckey;
/*%< A complete rndc.key file. */
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ddnskey;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sessionkey;
/*%< A complete ddns.key file. */
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_keyref;

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: namedconf.c,v 1.101 2009/07/10 23:47:58 tbox Exp $ */
/* $Id: namedconf.c,v 1.102 2009/07/14 22:54:57 each Exp $ */
/*! \file */
@ -24,6 +24,7 @@
#include <string.h>
#include <isc/lex.h>
#include <isc/mem.h>
#include <isc/result.h>
#include <isc/string.h>
#include <isc/util.h>
@ -35,9 +36,9 @@
#define TOKEN_STRING(pctx) (pctx->token.value.as_textregion.base)
/*% Check a return value. */
#define CHECK(op) \
do { result = (op); \
if (result != ISC_R_SUCCESS) goto cleanup; \
#define CHECK(op) \
do { result = (op); \
if (result != ISC_R_SUCCESS) goto cleanup; \
} while (0)
/*% Clean up a configuration object if non-NULL. */
@ -57,7 +58,15 @@ static isc_result_t
parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
static isc_result_t
parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret);
static isc_result_t
parse_updatepolicy(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret);
static void
doc_updatepolicy(cfg_printer_t *pctx, const cfg_type_t *type);
static void
print_keyvalue(cfg_printer_t *pctx, const cfg_obj_t *obj);
@ -330,10 +339,51 @@ static cfg_type_t cfg_type_grant = {
};
static cfg_type_t cfg_type_updatepolicy = {
"update_policy", cfg_parse_bracketed_list, cfg_print_bracketed_list,
cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_grant
"update_policy", parse_updatepolicy, NULL, doc_updatepolicy,
&cfg_rep_list, &cfg_type_grant
};
static isc_result_t
parse_updatepolicy(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret) {
isc_result_t result;
CHECK(cfg_gettoken(pctx, 0));
if (pctx->token.type == isc_tokentype_special &&
pctx->token.value.as_char == '{') {
return (cfg_parse_bracketed_list(pctx, type, ret));
}
if (pctx->token.type == isc_tokentype_string &&
strcasecmp(TOKEN_STRING(pctx), "local") == 0) {
cfg_obj_t *obj = NULL;
CHECK(cfg_create_obj(pctx, &cfg_type_ustring, &obj));
obj->value.string.length = strlen("local");
obj->value.string.base = isc_mem_get(pctx->mctx,
obj->value.string.length + 1);
if (obj->value.string.base == NULL) {
isc_mem_put(pctx->mctx, obj, sizeof(*obj));
return (ISC_R_NOMEMORY);
}
memcpy(obj->value.string.base, "local", 5);
obj->value.string.base[5] = '\0';
*ret = obj;
return (ISC_R_SUCCESS);
}
cfg_ungettoken(pctx);
return (ISC_R_UNEXPECTEDTOKEN);
cleanup:
return (result);
}
static void
doc_updatepolicy(cfg_printer_t *pctx, const cfg_type_t *type) {
cfg_print_chars(pctx, "( local | { ", 12);
cfg_doc_obj(pctx, type->of);
cfg_print_chars(pctx, "; ... }", 7);
}
/*%
* A view statement.
*/
@ -534,6 +584,7 @@ parse_qstringornone(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret)
{
isc_result_t result;
CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING));
if (pctx->token.type == isc_tokentype_string &&
strcasecmp(TOKEN_STRING(pctx), "none") == 0)
@ -551,7 +602,9 @@ doc_qstringornone(cfg_printer_t *pctx, const cfg_type_t *type) {
}
static cfg_type_t cfg_type_qstringornone = {
"qstringornone", parse_qstringornone, NULL, doc_qstringornone, NULL, NULL };
"qstringornone", parse_qstringornone, NULL, doc_qstringornone,
NULL, NULL
};
/*%
* keyword hostname
@ -735,9 +788,9 @@ options_clauses[] = {
{ "blackhole", &cfg_type_bracketed_aml, 0 },
{ "coresize", &cfg_type_size, 0 },
{ "datasize", &cfg_type_size, 0 },
{ "ddns-keyfile", &cfg_type_qstringornone, 0 },
{ "ddns-keyname", &cfg_type_astring, 0 },
{ "ddns-keyalg", &cfg_type_astring, 0 },
{ "session-keyfile", &cfg_type_qstringornone, 0 },
{ "session-keyname", &cfg_type_astring, 0 },
{ "session-keyalg", &cfg_type_astring, 0 },
{ "deallocate-on-exit", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "directory", &cfg_type_qstring, CFG_CLAUSEFLAG_CALLBACK },
{ "dump-file", &cfg_type_qstring, 0 },
@ -1027,7 +1080,6 @@ zone_clauses[] = {
{ "check-sibling", &cfg_type_boolean, 0 },
{ "check-srv-cname", &cfg_type_checkmode, 0 },
{ "check-wildcard", &cfg_type_boolean, 0 },
{ "ddns-autoconf", &cfg_type_boolean, 0 },
{ "dialup", &cfg_type_dialuptype, 0 },
{ "forward", &cfg_type_forwardtype, 0 },
{ "forwarders", &cfg_type_portiplist, 0 },
@ -1079,6 +1131,7 @@ zone_only_clauses[] = {
{ "masters", &cfg_type_namesockaddrkeylist, 0 },
{ "pubkey", &cfg_type_pubkey,
CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_OBSOLETE },
{ "ddns-autoconf", &cfg_type_boolean, 0 },
{ "update-policy", &cfg_type_updatepolicy, 0 },
{ "database", &cfg_type_astring, 0 },
{ "delegation-only", &cfg_type_boolean, 0 },
@ -2195,11 +2248,11 @@ LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndckey = {
};
/*
* ddns.key has exactly the same syntax as rndc.key, but it's defined
* session.key has exactly the same syntax as rndc.key, but it's defined
* separately for clarity (and so we can extend it someday, if needed).
*/
LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_ddnskey = {
"ddnskey", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_sessionkey = {
"sessionkey", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
&cfg_rep_map, rndckey_clausesets
};