2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 15:05:23 +00:00

rndc.key support

This commit is contained in:
Mark Andrews
2001-08-03 05:56:22 +00:00
parent faf2b80fe3
commit 326bcfa0e2
11 changed files with 633 additions and 475 deletions

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: controlconf.c,v 1.17 2001/07/23 01:01:31 bwelling Exp $ */
/* $Id: controlconf.c,v 1.18 2001/08/03 05:56:19 marka Exp $ */
#include <config.h>
@@ -100,17 +100,6 @@ struct controllistener {
ISC_LINK(controllistener_t) link;
};
static struct {
char name[64];
char secret[192];
cfg_parser_t *parser;
cfg_obj_t *config;
isc_sockaddr_t address; /* Last channel that needed automagic. */
} automagic_key;
#define NS_AUTOKEY_BITS 128
#define NS_AUTOKEY_NAME "control_autokey"
struct ns_controls {
ns_server_t *server;
controllistenerlist_t listeners;
@@ -647,7 +636,7 @@ controlkeylist_fromcfg(cfg_obj_t *keylist, isc_mem_t *mctx,
static void
register_keys(cfg_obj_t *control, cfg_obj_t *keylist,
controlkeylist_t *keyids, isc_mem_t *mctx, char *socktext)
controlkeylist_t *keyids, isc_mem_t *mctx, const char *socktext)
{
controlkey_t *keyid, *next;
cfg_obj_t *keydef;
@@ -725,288 +714,119 @@ register_keys(cfg_obj_t *control, cfg_obj_t *keylist,
}
}
static isc_result_t
make_automagic_key(isc_mem_t *mctx) {
unsigned char key_rawsecret[32];
unsigned char key_txtsecret[32];
isc_buffer_t key_rawbuffer;
isc_buffer_t key_txtbuffer;
isc_region_t key_rawregion;
isc_uint32_t key_id;
isc_result_t result;
dst_key_t *key = NULL;
/*
* First generate a secret. The fourth parameter non-zero means
* that pseudorandom data is ok; good entropy is not required.
*/
result = dst_key_generate(dns_rootname, DST_ALG_HMACMD5,
NS_AUTOKEY_BITS, 1, 0, DNS_KEYPROTO_ANY,
dns_rdataclass_in, mctx, &key);
if (result == ISC_R_SUCCESS) {
isc_buffer_init(&key_rawbuffer, &key_rawsecret,
sizeof(key_rawsecret));
result = dst_key_tobuffer(key, &key_rawbuffer);
}
if (result == ISC_R_SUCCESS) {
isc_buffer_init(&key_txtbuffer, &key_txtsecret,
sizeof(key_txtsecret));
isc_buffer_usedregion(&key_rawbuffer, &key_rawregion);
result = isc_base64_totext(&key_rawregion, -1, "",
&key_txtbuffer);
}
if (result == ISC_R_SUCCESS) {
unsigned int len = isc_buffer_usedlength(&key_txtbuffer);
INSIST(len < sizeof(automagic_key.secret));
memcpy(automagic_key.secret, isc_buffer_base(&key_txtbuffer),
len);
automagic_key.secret[len] = '\0';
/*
* Make a random name for the key and generate the config
* file statement for it.
*/
isc_random_get(&key_id);
len = snprintf(automagic_key.name, sizeof(automagic_key.name),
NS_AUTOKEY_NAME ".%u", key_id);
INSIST(len < sizeof(automagic_key.name));
}
if (key != NULL)
dst_key_free(&key);
if (result != ISC_R_SUCCESS)
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
"could not generate control channel key: %s",
isc_result_totext(result));
return (result);
}
static void
format_automagic_keycfg(isc_buffer_t *conf) {
unsigned int len;
len = snprintf(isc_buffer_base(conf), isc_buffer_length(conf),
"key \"%s\" {\n"
"\talgorithm hmac-md5;\n"
"\tsecret \"%s\";\n"
"};\n",
automagic_key.name, automagic_key.secret);
INSIST(len < isc_buffer_length(conf));
isc_buffer_add(conf, len);
}
#define CHECK(x) \
do { \
result = (x); \
if (result != ISC_R_SUCCESS) \
goto cleanup; \
} while (0)
static isc_result_t
parse_automagic_key(isc_mem_t *mctx) {
unsigned int len;
char cfg_data[512];
isc_buffer_t cfg_buffer;
isc_result_t result = ISC_R_SUCCESS;
cfg_obj_t *cfg = NULL;
cfg_parser_t *parser = NULL;
if (automagic_key.name[0] == '\0')
result = make_automagic_key(mctx);
if (result == ISC_R_SUCCESS) {
/*
* Fake up a configuration with a dummy inet control
* to grab the keylist tuple.
*/
isc_buffer_init(&cfg_buffer, cfg_data, sizeof(cfg_data));
format_automagic_keycfg(&cfg_buffer);
len = snprintf(isc_buffer_used(&cfg_buffer),
isc_buffer_availablelength(&cfg_buffer),
"controls { inet 127.0.0.1 allow { localhost; }"
" keys { %s; }; };",
automagic_key.name);
INSIST(len < isc_buffer_availablelength(&cfg_buffer));
isc_buffer_add(&cfg_buffer, len);
result = cfg_parser_create(mctx, ns_g_lctx, &parser);
}
if (result == ISC_R_SUCCESS)
result = cfg_parse_buffer(parser, &cfg_buffer,
&cfg_type_namedconf, &cfg);
if (result == ISC_R_SUCCESS) {
automagic_key.parser = parser;
automagic_key.config = cfg;
} else {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
"could not parse autogenerated "
"control channel key: %s",
isc_result_totext(result));
if (parser != NULL)
cfg_parser_destroy(&parser);
}
return (result);
}
static void
finalize_automagic_key(void) {
unsigned int fsaccess;
int i;
FILE *fp;
get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
isc_result_t result;
cfg_parser_t *pctx = NULL;
cfg_obj_t *config = NULL;
cfg_obj_t *key = NULL;
cfg_obj_t *algobj = NULL;
cfg_obj_t *secretobj = NULL;
char *algstr = NULL;
char *secretstr = NULL;
controlkey_t *keyid = NULL;
char secret[1024];
isc_buffer_t b;
(void)isc_file_remove(ns_g_autorndckeyfile);
CHECK(cfg_parser_create(mctx, ns_g_lctx, &pctx));
CHECK(cfg_parse_file(pctx, ns_g_keyfile, &cfg_type_rndckey, &config));
CHECK(cfg_map_get(config, "key", &key));
if (automagic_key.parser != NULL) {
/*
* An automagic key was parsed, so some channel needed it.
* Try to write the rndc.conf file.
*/
char cfg_data[512];
char nettext[ISC_NETADDR_FORMATSIZE];
isc_buffer_t cfg_buffer;
isc_netaddr_t netaddr;
keyid = isc_mem_get(mctx, sizeof(*keyid));
if (keyid == NULL)
CHECK(ISC_R_NOMEMORY);
keyid->keyname = isc_mem_strdup(mctx,
cfg_obj_asstring(cfg_map_getname(key)));
keyid->secret.base = NULL;
keyid->secret.length = 0;
ISC_LINK_INIT(keyid, link);
if (keyid->keyname == NULL)
CHECK(ISC_R_NOMEMORY);
(void)cfg_map_get(key, "algorithm", &algobj);
(void)cfg_map_get(key, "secret", &secretobj);
INSIST(algobj != NULL && secretobj != NULL);
result = isc_stdio_open(ns_g_autorndckeyfile, "w", &fp);
algstr = cfg_obj_asstring(algobj);
secretstr = cfg_obj_asstring(secretobj);
if (result == ISC_R_SUCCESS) {
fsaccess = 0;
isc_fsaccess_add(ISC_FSACCESS_OWNER, ISC_FSACCESS_READ,
&fsaccess);
result = isc_fsaccess_set(ns_g_autorndckeyfile,
fsaccess);
if (strcasecmp(algstr, "hmac-md5") != 0) {
cfg_obj_log(key, ns_g_lctx,
ISC_LOG_WARNING,
"unsupported algorithm '%s' in "
"key '%s' for use with command "
"channel",
algstr, keyid->keyname);
goto cleanup;
}
isc_buffer_init(&b, secret, sizeof(secret));
result = isc_base64_decodestring(secretstr, &b);
if (result != ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx,
NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_CONTROL,
ISC_LOG_WARNING,
"could not set owner-only "
"access on %s: %s: "
"server control key might be "
"exposed to local users",
ns_g_autorndckeyfile,
isc_result_totext(result));
cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
"secret for key '%s' on command channel: %s",
keyid->keyname, isc_result_totext(result));
CHECK(result);
}
isc_buffer_init(&cfg_buffer, cfg_data,
sizeof(cfg_data));
format_automagic_keycfg(&cfg_buffer);
isc_netaddr_fromsockaddr(&netaddr,
&automagic_key.address);
isc_netaddr_format(&netaddr, nettext, sizeof(nettext));
i = fputs(isc_buffer_base(&cfg_buffer), fp);
if (i != EOF)
i = fprintf(fp, "options {\n"
"\tdefault-server %s;\n"
"\tdefault-port %hu;\n"
"\tdefault-key \"%s\";\n"
"};\n",
nettext,
isc_sockaddr_getport(
&automagic_key.address),
automagic_key.name);
if (i == EOF)
isc_log_write(ns_g_lctx,
NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_CONTROL,
ISC_LOG_WARNING,
"could not write %s",
ns_g_autorndckeyfile);
result = isc_stdio_close(fp);
if (result != ISC_R_SUCCESS)
isc_log_write(ns_g_lctx,
NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_CONTROL,
ISC_LOG_WARNING,
"error closing %s: %s",
ns_g_autorndckeyfile,
isc_result_totext(result));
keyid->secret.length = isc_buffer_usedlength(&b);
keyid->secret.base = isc_mem_get(mctx,
keyid->secret.length);
if (keyid->secret.base == NULL) {
cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
"couldn't register key '%s': "
"out of memory", keyid->keyname);
CHECK(ISC_R_NOMEMORY);
}
memcpy(keyid->secret.base, isc_buffer_base(&b),
keyid->secret.length);
ISC_LIST_APPEND(*keyids, keyid, link);
keyid = NULL;
result = ISC_R_SUCCESS;
cfg_obj_destroy(automagic_key.parser, &automagic_key.config);
cfg_parser_destroy(&automagic_key.parser);
}
cleanup:
if (keyid != NULL)
free_controlkey(keyid, mctx);
if (config != NULL)
cfg_obj_destroy(pctx, &config);
if (pctx != NULL)
cfg_parser_destroy(&pctx);
return (result);
}
static void
get_key_info(isc_mem_t *mctx, cfg_obj_t *config, cfg_obj_t *control,
cfg_obj_t **global_keylistp, cfg_obj_t **control_keylistp,
isc_boolean_t *explicit_key)
get_key_info(cfg_obj_t *config, cfg_obj_t *control,
cfg_obj_t **global_keylistp, cfg_obj_t **control_keylistp)
{
cfg_obj_t *control_keylist = NULL;
cfg_obj_t *global_keylist = NULL;
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(global_keylistp != NULL && *global_keylistp == NULL);
REQUIRE(control_keylistp != NULL && *control_keylistp == NULL);
control_keylist = cfg_tuple_get(control, "keys");
if (cfg_obj_isvoid(control_keylist) ||
cfg_list_first(control_keylist) == NULL) {
cfg_obj_t *controls = NULL;
cfg_obj_t *inet = NULL;
if (!cfg_obj_isvoid(control_keylist) &&
cfg_list_first(control_keylist) != NULL)
cfg_map_get(config, "key", &global_keylist);
if (automagic_key.parser == NULL)
result = parse_automagic_key(mctx);
if (result == ISC_R_SUCCESS) {
config = automagic_key.config;
/*
* All of these should succeed.
*/
(void)cfg_map_get(config, "key", &global_keylist);
INSIST(global_keylist != NULL);
(void)cfg_map_get(config, "controls", &controls);
INSIST(controls != NULL);
(void)cfg_map_get(cfg_listelt_value
(cfg_list_first(controls)),
"inet", &inet);
INSIST(inet != NULL);
control_keylist =
cfg_tuple_get(cfg_listelt_value
(cfg_list_first(inet)), "keys");
INSIST(control_keylist != NULL);
}
*explicit_key = ISC_FALSE;
} else {
result = cfg_map_get(config, "key", &global_keylist);
*explicit_key = config != automagic_key.config
? ISC_TRUE : ISC_FALSE;
}
if (result == ISC_R_SUCCESS) {
*global_keylistp = global_keylist;
*control_keylistp = control_keylist;
} else
cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
"no key statements for use by control channel");
}
static void
update_listener(ns_controls_t *cp,
controllistener_t **listenerp, cfg_obj_t *control,
cfg_obj_t *config, isc_sockaddr_t *addr,
ns_aclconfctx_t *aclconfctx, char *socktext)
ns_aclconfctx_t *aclconfctx, const char *socktext)
{
controllistener_t *listener;
cfg_obj_t *allow;
@@ -1014,7 +834,6 @@ update_listener(ns_controls_t *cp,
cfg_obj_t *control_keylist = NULL;
dns_acl_t *new_acl = NULL;
controlkeylist_t keys;
isc_boolean_t explicit_key;
isc_result_t result = ISC_R_SUCCESS;
for (listener = ISC_LIST_HEAD(cp->listeners);
@@ -1049,8 +868,7 @@ update_listener(ns_controls_t *cp,
* and not able to be decrypted by the client. For this reason,
* the automagic key is not regenerated on each reload.
*/
get_key_info(listener->mctx, config, control,
&global_keylist, &control_keylist, &explicit_key);
get_key_info(config, control, &global_keylist, &control_keylist);
if (control_keylist != NULL) {
INSIST(global_keylist != NULL);
@@ -1058,18 +876,18 @@ update_listener(ns_controls_t *cp,
ISC_LIST_INIT(keys);
result = controlkeylist_fromcfg(control_keylist,
listener->mctx, &keys);
}
if (result == ISC_R_SUCCESS) {
if (result) {
free_controlkeylist(&listener->keys, listener->mctx);
listener->keys = keys;
register_keys(control, global_keylist, &listener->keys,
listener->mctx, socktext);
}
} else {
free_controlkeylist(&listener->keys, listener->mctx);
result = get_rndckey(listener->mctx, &listener->keys);
}
if (! explicit_key)
automagic_key.address = listener->address;
} else if (global_keylist != NULL)
if (result != ISC_R_SUCCESS && global_keylist != NULL)
/*
* This message might be a little misleading since the
* "new keys" might in fact be identical to the old ones,
@@ -1085,9 +903,20 @@ update_listener(ns_controls_t *cp,
/*
* Now, keep the old access list unless a new one can be made.
*/
if (control != NULL) {
allow = cfg_tuple_get(control, "allow");
result = ns_acl_fromconfig(allow, config, aclconfctx,
listener->mctx, &new_acl);
} else {
/* allow { any; } */
result = dns_acl_create(listener->mctx, 1, &new_acl);
if (result == ISC_R_SUCCESS) {
new_acl->elements->type = dns_aclelementtype_any;
new_acl->elements->negative = ISC_FALSE;
new_acl->length = 1;
}
}
if (result == ISC_R_SUCCESS) {
dns_acl_detach(&listener->acl);
dns_acl_attach(new_acl, &listener->acl);
@@ -1105,7 +934,7 @@ update_listener(ns_controls_t *cp,
static void
add_listener(ns_controls_t *cp, controllistener_t **listenerp,
cfg_obj_t *control, cfg_obj_t *config, isc_sockaddr_t *addr,
ns_aclconfctx_t *aclconfctx, char *socktext)
ns_aclconfctx_t *aclconfctx, const char *socktext)
{
isc_mem_t *mctx = cp->server->mctx;
controllistener_t *listener;
@@ -1113,7 +942,6 @@ add_listener(ns_controls_t *cp, controllistener_t **listenerp,
cfg_obj_t *global_keylist = NULL;
cfg_obj_t *control_keylist = NULL;
dns_acl_t *new_acl = NULL;
isc_boolean_t explicit_key;
isc_result_t result = ISC_R_SUCCESS;
listener = isc_mem_get(mctx, sizeof(*listener));
@@ -1136,30 +964,42 @@ add_listener(ns_controls_t *cp, controllistener_t **listenerp,
/*
* Make the acl.
*/
if (control != NULL) {
allow = cfg_tuple_get(control, "allow");
result = ns_acl_fromconfig(allow, config, aclconfctx, mctx,
&new_acl);
result = ns_acl_fromconfig(allow, config, aclconfctx,
mctx, &new_acl);
} else {
/* allow { any; } */
result = dns_acl_create(mctx, 1, &new_acl);
if (result == ISC_R_SUCCESS) {
new_acl->elements->type =
dns_aclelementtype_any;
new_acl->elements->negative = ISC_FALSE;
new_acl->length = 1;
}
}
}
if (result == ISC_R_SUCCESS) {
dns_acl_attach(new_acl, &listener->acl);
dns_acl_detach(&new_acl);
get_key_info(listener->mctx, config, control,
&global_keylist, &control_keylist, &explicit_key);
if (config != NULL)
get_key_info(config, control, &global_keylist,
&control_keylist);
if (control_keylist != NULL)
if (control_keylist != NULL) {
result = controlkeylist_fromcfg(control_keylist,
listener->mctx,
&listener->keys);
if (result == ISC_R_SUCCESS) {
register_keys(control, global_keylist, &listener->keys,
if (result == ISC_R_SUCCESS)
register_keys(control, global_keylist,
&listener->keys,
listener->mctx, socktext);
if (! explicit_key)
automagic_key.address = listener->address;
} else
result = get_rndckey(mctx, &listener->keys);
if (result != ISC_R_SUCCESS && control != NULL)
cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
"couldn't install keys for "
"command channel %s: %s",
@@ -1201,9 +1041,15 @@ add_listener(ns_controls_t *cp, controllistener_t **listenerp,
free_listener(listener);
}
if (control != NULL)
cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
"couldn't add command channel %s: %s",
socktext, isc_result_totext(result));
else
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE,
"couldn't add command channel %s: %s",
socktext, isc_result_totext(result));
*listenerp = NULL;
}
@@ -1304,8 +1150,47 @@ ns_controls_configure(ns_controls_t *cp, cfg_obj_t *config,
listener, link);
}
}
} else {
int i;
finalize_automagic_key();
for (i = 0 ; i < 2; i++) {
isc_sockaddr_t addr;
if (i == 1) {
if (isc_net_probeipv4() != ISC_R_SUCCESS)
continue;
isc_sockaddr_any(&addr);
} else {
if (isc_net_probeipv6() != ISC_R_SUCCESS)
continue;
isc_sockaddr_any6(&addr);
}
isc_sockaddr_setport(&addr, NS_CONTROL_PORT);
isc_sockaddr_format(&addr, socktext, sizeof(socktext));
update_listener(cp, &listener, NULL, NULL,
&addr, NULL, socktext);
if (listener != NULL)
/*
* Remove the listener from the old
* list, so it won't be shut down.
*/
ISC_LIST_UNLINK(cp->listeners,
listener, link);
else
/*
* This is a new listener.
*/
add_listener(cp, &listener, NULL, NULL,
&addr, NULL, socktext);
if (listener != NULL)
ISC_LIST_APPEND(new_listeners,
listener, link);
}
}
/*
* ns_control_shutdown() will stop whatever is on the global
@@ -1321,17 +1206,6 @@ ns_controls_configure(ns_controls_t *cp, cfg_obj_t *config,
* down will be taken care of by listen_done().
*/
ISC_LIST_APPENDLIST(cp->listeners, new_listeners, link);
} else {
isc_result_t result;
result = parse_automagic_key(cp->server->mctx);
if (result == ISC_R_SUCCESS)
ns_controls_configure(cp, automagic_key.config,
aclconfctx);
}
return (ISC_R_SUCCESS);
}

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: globals.h,v 1.57 2001/05/31 10:38:56 tale Exp $ */
/* $Id: globals.h,v 1.58 2001/08/03 05:56:17 marka Exp $ */
#ifndef NAMED_GLOBALS_H
#define NAMED_GLOBALS_H 1
@@ -76,6 +76,8 @@ EXTERN cfg_obj_t * ns_g_config INIT(NULL);
EXTERN cfg_obj_t * ns_g_defaults INIT(NULL);
EXTERN const char * ns_g_conffile INIT(NS_SYSCONFDIR
"/named.conf");
EXTERN const char * ns_g_keyfile INIT(NS_SYSCONFDIR
"/rndc.key");
EXTERN const char * lwresd_g_conffile INIT(NS_SYSCONFDIR
"/lwresd.conf");
EXTERN const char * lwresd_g_resolvconffile INIT("/etc"

View File

@@ -13,7 +13,7 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.29 2001/07/26 20:14:45 gson Exp $
# $Id: Makefile.in,v 1.30 2001/08/03 05:56:16 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -27,7 +27,7 @@ CINCLUDES = ${ISC_INCLUDES}
RNDCINCLUDES = ${CINCLUDES} ${ISCCC_INCLUDES} ${ISCCFG_INCLUDES}
CONFINCLUDES = ${CINCLUDES} ${DNS_INCLUDES}
CONFINCLUDES = -Iinclude ${CINCLUDES} ${DNS_INCLUDES}
CDEFINES =
CWARNINGS =
@@ -48,6 +48,8 @@ RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${ISCDEPLIBS}
CONFLIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
SUBDIRS = unix
TARGETS = rndc rndc-confgen
MANPAGES = rndc.8 rndc.conf.5
@@ -56,26 +58,29 @@ HTMLPAGES = rndc.html rndc.conf.html
MANOBJS = ${MANPAGES} ${HTMLPAGES}
UOBJS = unix/os.@O@
@BIND9_MAKE_RULES@
rndc.@O@: rndc.c
${LIBTOOL} ${CC} ${ALL_CFLAGS} ${RNDCINCLUDES} \
-DVERSION=\"${VERSION}\" \
-DRNDC_CONFFILE=\"${sysconfdir}/rndc.conf\" \
-DRNDC_AUTOCONFFILE=\"${localstatedir}/run/named.key\" \
-DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \
-c ${srcdir}/rndc.c
rndc-confgen.@O@: rndc-confgen.c
${LIBTOOL} ${CC} ${ALL_CFLAGS} ${CONFINCLUDES} \
-DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \
-DRNDC_SYSCONFDIR=\"${sysconfdir}\" -c ${srcdir}/rndc-confgen.c
rndc: rndc.@O@ util.@O@ ${RNDCDEPLIBS}
${LIBTOOL} ${PURIFY} ${CC} ${CFLAGS} -o $@ rndc.@O@ util.@O@ \
${RNDCLIBS}
rndc-confgen: rndc-confgen.@O@ util.@O@ ${CONFDEPLIBS}
rndc-confgen: rndc-confgen.@O@ util.@O@ ${UOBJS} ${CONFDEPLIBS}
${LIBTOOL} ${PURIFY} ${CC} ${CFLAGS} -o $@ rndc-confgen.@O@ util.@O@ \
${CONFLIBS}
${UOBJS} ${CONFLIBS}
doc man:: ${MANOBJS}

View File

@@ -0,0 +1,33 @@
/*
* Copyright
*/
/* $Id: os.h,v 1.1 2001/08/03 05:56:22 marka Exp $ */
#ifndef RNDC_OS_H
#define RNDC_OS_H 1
#include <isc/lang.h>
#include <stdio.h>
/*
* OS specific paths that may be overriden at runtime by rndc_os_init().
*/
ISC_LANG_BEGINDECLS
FILE *safe_create(const char *filename);
/*
* Create and open 'filename' for writing. Fail if 'filename' exist.
*/
int set_user(FILE *fd, const char *user);
/*
* Set the owner of the file refernced by 'fd' to 'user'.
* Fail is insufficient permissions or 'user' does not exist.
*/
ISC_LANG_ENDDECLS
#endif

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rndc-confgen.c,v 1.2 2001/06/29 23:32:09 gson Exp $ */
/* $Id: rndc-confgen.c,v 1.3 2001/08/03 05:56:15 marka Exp $ */
#include <config.h>
@@ -40,6 +40,7 @@
#include <dns/name.h>
#include <dst/dst.h>
#include <rndc/os.h>
#include "util.h"
@@ -51,18 +52,26 @@
char progname[256];
isc_boolean_t verbose = ISC_FALSE;
const char *keyfile, *keydef;
static void
usage(int status) {
fprintf(stderr, "\
Usage:\n\
%s [-b bits] [-k keyname] [-P] [-p port] [-r randomfile] [-s addr]\n\
%s [-a] [-b bits] [-c keyfile] [-k keyname] [-P] [-p port] [-r randomfile] \
[-s addr] [-t chrootdir] [-u user]\n\
-a: generate just the key clause and write it to keyfile (%s)\n\
-b bits: from 1 through 512, default %d; total length of the secret\n\
-c keyfile: specify a alterate keyfile (requires -a)\n\
-k keyname: the name as it will be used in named.conf and rndc.conf\n\
-P: using pseudorandom data for key generation is ok\n\
-p port: the port named will listen on and rndc will connect to\n\
-r randomfile: a file containing random data\n\
-s addr: the address to which rndc should connect\n",
progname, DEFAULT_KEYLENGTH);
-s addr: the address to which rndc should connect\n\
-t chrootdir: write a keyfile in chrootdir as well (requires -a)\n\
-u user: set the keyfile owner to \"user\" (requires -a)\n",
progname, keydef, DEFAULT_KEYLENGTH);
exit (status);
}
@@ -91,19 +100,30 @@ main(int argc, char **argv) {
int entropy_flags = 0;
int open_keyboard = ISC_ENTROPY_KEYBOARDMAYBE;
struct in_addr addr;
char *chrootdir = NULL;
char *user = NULL;
isc_boolean_t keyonly = ISC_FALSE;
int len;
FILE *fd;
char *buf;
keydef = keyfile = RNDC_KEYFILE;
result = isc_file_progname(*argv, progname, sizeof(progname));
if (result != ISC_R_SUCCESS)
memcpy(progname, "rndc", 5);
memcpy(progname, "rndc-confgen", 13);
keyname = DEFAULT_KEYNAME;
keysize = DEFAULT_KEYLENGTH;
serveraddr = DEFAULT_SERVER;
port = DEFAULT_PORT;
while ((ch = isc_commandline_parse(argc, argv, "b:hk:MmPp:r:s:Vy"))
!= -1) {
while ((ch = isc_commandline_parse(argc, argv,
"ab:c:hk:MmPp:r:s:t:u:Vy")) != -1) {
switch (ch) {
case 'a':
keyonly = ISC_TRUE;
break;
case 'b':
keysize = strtol(isc_commandline_argument, &p, 10);
if (*p != '\0' || keysize < 0)
@@ -111,6 +131,9 @@ main(int argc, char **argv) {
if (keysize < 1 || keysize > 512)
fatal("-b must be in the range 1 through 512");
break;
case 'c':
keyfile = isc_commandline_argument;
break;
case 'h':
usage(0);
case 'k':
@@ -142,6 +165,12 @@ main(int argc, char **argv) {
if (inet_aton(serveraddr, &addr) == 0)
fatal("-s should be an IPv4 or IPv6 address");
break;
case 't':
chrootdir = isc_commandline_argument;
break;
case 'u':
user = isc_commandline_argument;
break;
case 'V':
verbose = ISC_TRUE;
@@ -211,6 +240,76 @@ main(int argc, char **argv) {
*/
printf("\n\n");
if (keyonly) {
fd = safe_create(keyfile);
if (fd == NULL) {
fprintf(stderr, "unable to create \"%s\"\n", keyfile);
goto cleanup;
}
if (user != NULL && chrootdir == NULL) {
if (set_user(fd, user) == -1) {
fprintf(stderr, "unable to set file owner\n");
fclose(fd);
goto cleanup;
}
}
fprintf(fd, "key \"%s\" {\n\talgorithm hmac-md5;\n"
"\tsecret \"%.*s\";\n};\n", keyname,
(int)isc_buffer_usedlength(&key_txtbuffer),
(char *)isc_buffer_base(&key_txtbuffer));
fflush(fd);
if (ferror(fd)) {
fprintf(stderr, "write to %s failed\n", keyfile);
fclose(fd);
goto cleanup;
}
if (fclose(fd)) {
fprintf(stderr, "fclose(%s) failed\n", keyfile);
goto cleanup;
}
if (chrootdir == NULL)
goto cleanup;
len = strlen(chrootdir) + strlen(keyfile) + 2;
buf = isc_mem_get(mctx, len);
if (buf != NULL) {
fprintf(stderr, "isc_mem_get(%d) failed\n", len);
goto cleanup;
}
snprintf(buf, len, "%s" "/" "%s", chrootdir, keyfile);
fd = safe_create(buf);
if (fd == NULL) {
fprintf(stderr, "unable to create \"%s\"\n",
buf);
isc_mem_put(mctx, buf, len);
goto cleanup;
}
if (user != NULL) {
if (set_user(fd, user) == -1) {
fprintf(stderr, "unable to set file owner\n");
fclose(fd);
isc_mem_put(mctx, buf, len);
goto cleanup;
}
}
fprintf(fd, "key \"%s\" {\n\talgorithm hmac-md5;\n"
"\tsecret \"%.*s\";\n};\n", keyname,
(int)isc_buffer_usedlength(&key_txtbuffer),
(char *)isc_buffer_base(&key_txtbuffer));
fflush(fd);
if (ferror(fd)) {
fprintf(stderr, "write to %s failed\n", buf);
fclose(fd);
isc_mem_put(mctx, buf, len);
goto cleanup;
}
if (fclose(fd)) {
fprintf(stderr, "fclose(%s) failed\n", buf);
isc_mem_put(mctx, buf, len);
goto cleanup;
}
isc_mem_put(mctx, buf, len);
} else {
printf("\
# Start of rndc.conf\n\
key \"%s\" {\n\
@@ -244,7 +343,9 @@ options {\n\
(int)isc_buffer_usedlength(&key_txtbuffer),
(char *)isc_buffer_base(&key_txtbuffer),
serveraddr, port, serveraddr, keyname);
}
cleanup:
if (show_final_mem)
isc_mem_stats(mctx, stderr);

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rndc.c,v 1.74 2001/07/26 20:37:26 gson Exp $ */
/* $Id: rndc.c,v 1.75 2001/08/03 05:56:13 marka Exp $ */
/*
* Principal Author: DCL
@@ -50,6 +50,11 @@
#include <isccc/types.h>
#include <isccc/util.h>
#if 0
#define RNDC_MAIN
#include <rndc/os.h>
#endif
#include "util.h"
#ifdef HAVE_ADDRINFO
@@ -70,10 +75,10 @@ char *progname;
isc_boolean_t verbose;
static const char *admin_conffile;
static const char *auto_conffile;
static const char *admin_keyfile;
static const char *version = VERSION;
static const char *servername = NULL;
static unsigned int remoteport = NS_CONTROL_PORT;
static unsigned int remoteport = 0;
static isc_socketmgr_t *socketmgr = NULL;
static unsigned char databuf[2048];
static isccc_ccmsg_t ccmsg;
@@ -149,6 +154,7 @@ get_address(const char *host, in_port_t port, isc_sockaddr_t *sockaddr) {
hints.ai_family = PF_INET6;
else
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
isc_app_block();
result = getaddrinfo(host, NULL, &hints, &res);
isc_app_unblock();
@@ -313,18 +319,36 @@ rndc_start(isc_task_t *task, isc_event_t *event) {
}
static void
parse_config(isc_mem_t *mctx, isc_log_t *log, cfg_parser_t **pctxp,
cfg_obj_t **config)
parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname,
cfg_parser_t **pctxp, cfg_obj_t **configp)
{
isc_result_t result;
const char *conffile = admin_conffile;
cfg_obj_t *defkey = NULL;
cfg_obj_t *options = NULL;
cfg_obj_t *servers = NULL;
cfg_obj_t *server = NULL;
cfg_obj_t *keys = NULL;
cfg_obj_t *key = NULL;
cfg_obj_t *defport = NULL;
cfg_obj_t *secretobj = NULL;
cfg_obj_t *algorithmobj = NULL;
cfg_obj_t *config = NULL;
cfg_listelt_t *elt;
const char *secretstr;
const char *algorithm;
static char secretarray[1024];
const cfg_type_t *conftype = &cfg_type_rndcconf;
isc_boolean_t key_only = ISC_FALSE;
if (! isc_file_exists(conffile)) {
conffile = auto_conffile;
conffile = admin_keyfile;
conftype = &cfg_type_rndckey;
if (! isc_file_exists(conffile))
fatal("neither %s nor %s was found",
admin_conffile, auto_conffile);
admin_conffile, admin_keyfile);
key_only = ISC_TRUE;
}
DO("create parser", cfg_parser_create(mctx, log, pctxp));
@@ -332,10 +356,110 @@ parse_config(isc_mem_t *mctx, isc_log_t *log, cfg_parser_t **pctxp,
/*
* The parser will output its own errors, so DO() is not used.
*/
result = cfg_parse_file(*pctxp, conffile, &cfg_type_rndcconf, config);
result = cfg_parse_file(*pctxp, conffile, conftype, &config);
if (result != ISC_R_SUCCESS)
exit(1);
if (!key_only)
(void)cfg_map_get(config, "options", &options);
if (key_only && servername == NULL)
servername = "localhost";
else if (servername == NULL && options != NULL) {
cfg_obj_t *defserverobj = NULL;
(void)cfg_map_get(options, "default-server", &defserverobj);
if (defserverobj != NULL)
servername = cfg_obj_asstring(defserverobj);
}
if (servername == NULL)
fatal("no server specified and no default");
if (!key_only) {
cfg_map_get(config, "server", &servers);
if (servers != NULL) {
for (elt = cfg_list_first(servers);
elt != NULL;
elt = cfg_list_next(elt))
{
const char *name;
server = cfg_listelt_value(elt);
name = cfg_obj_asstring(cfg_map_getname(server));
if (strcasecmp(name, servername) == 0)
break;
server = NULL;
}
}
}
/*
* Look for the name of the key to use.
*/
if (keyname != NULL)
; /* Was set on command line, do nothing. */
else if (server != NULL) {
DO("get key for server", cfg_map_get(server, "key", &defkey));
keyname = cfg_obj_asstring(defkey);
} else if (options != NULL) {
DO("get default key", cfg_map_get(options, "default-key",
&defkey));
keyname = cfg_obj_asstring(defkey);
} else if (!key_only)
fatal("no key for server and no default");
/*
* Get the key's definition.
*/
if (key_only)
DO("get key", cfg_map_get(config, "key", &key));
else {
DO("get config key list", cfg_map_get(config, "key", &keys));
for (elt = cfg_list_first(keys);
elt != NULL;
elt = cfg_list_next(elt))
{
key = cfg_listelt_value(elt);
if (strcasecmp(cfg_obj_asstring(cfg_map_getname(key)),
keyname) == 0)
break;
}
if (elt == NULL)
fatal("no key definition for name %s", keyname);
}
(void)cfg_map_get(key, "secret", &secretobj);
(void)cfg_map_get(key, "algorithm", &algorithmobj);
if (secretobj == NULL || algorithmobj == NULL)
fatal("key must have algorithm and secret");
secretstr = cfg_obj_asstring(secretobj);
algorithm = cfg_obj_asstring(algorithmobj);
if (strcasecmp(algorithm, "hmac-md5") != 0)
fatal("unsupported algorithm: %s", algorithm);
secret.rstart = (unsigned char *)secretarray;
secret.rend = (unsigned char *)secretarray + sizeof(secretarray);
DO("decode base64 secret", isccc_base64_decode(secretstr, &secret));
secret.rend = secret.rstart;
secret.rstart = (unsigned char *)secretarray;
/*
* Find the port to connect to.
*/
if (remoteport != 0)
; /* Was set on command line, do nothing. */
else {
if (server != NULL)
(void)cfg_map_get(server, "port", &defport);
if (defport == NULL && options != NULL)
cfg_map_get(options, "default-port", &defport);
}
if (defport != NULL) {
remoteport = cfg_obj_asuint32(defport);
if (remoteport > 65535 || remoteport == 0)
fatal("port %d out of range", remoteport);
} else if (remoteport == 0)
remoteport = NS_CONTROL_PORT;
*configp = config;
}
int
@@ -349,43 +473,33 @@ main(int argc, char **argv) {
isc_logdestination_t logdest;
cfg_parser_t *pctx = NULL;
cfg_obj_t *config = NULL;
cfg_obj_t *options = NULL;
cfg_obj_t *servers = NULL;
cfg_obj_t *server = NULL;
cfg_obj_t *defkey = NULL;
cfg_obj_t *keys = NULL;
cfg_obj_t *key = NULL;
cfg_obj_t *defport = NULL;
cfg_obj_t *secretobj = NULL;
cfg_obj_t *algorithmobj = NULL;
cfg_listelt_t *elt;
const char *keyname = NULL;
const char *secretstr;
const char *algorithm;
isc_boolean_t portset = ISC_FALSE;
char secretarray[1024];
char *p;
size_t argslen;
int ch;
int i;
result = isc_file_progname(*argv, program, sizeof(program));
if (result != ISC_R_SUCCESS)
memcpy(program, "rndc", 5);
progname = program;
admin_conffile = RNDC_CONFFILE;
auto_conffile = RNDC_AUTOCONFFILE;
admin_keyfile = RNDC_KEYFILE;
isc_app_start();
result = isc_file_progname(*argv, program, sizeof(program));
if (result != ISC_R_SUCCESS)
memcpy(progname, "rndc", 5);
progname = program;
while ((ch = isc_commandline_parse(argc, argv, "c:Mmp:s:Vy:"))
while ((ch = isc_commandline_parse(argc, argv, "c:k:Mmp:s:Vy:"))
!= -1) {
switch (ch) {
case 'c':
admin_conffile = isc_commandline_argument;
break;
case 'k':
admin_keyfile = isc_commandline_argument;
break;
case 'M':
isc_mem_debugging = 1;
break;
@@ -396,10 +510,9 @@ main(int argc, char **argv) {
case 'p':
remoteport = atoi(isc_commandline_argument);
if (remoteport > 65535)
if (remoteport > 65535 || remoteport == 0)
fatal("port '%s' out of range",
isc_commandline_argument);
portset = ISC_TRUE;
break;
case 's':
@@ -446,100 +559,7 @@ main(int argc, char **argv) {
DO("enabling log channel", isc_log_usechannel(logconfig, "stderr",
NULL, NULL));
parse_config(mctx, log, &pctx, &config);
(void)cfg_map_get(config, "options", &options);
if (servername == NULL && options != NULL) {
cfg_obj_t *defserverobj = NULL;
(void)cfg_map_get(options, "default-server", &defserverobj);
if (defserverobj != NULL)
servername = cfg_obj_asstring(defserverobj);
}
if (servername == NULL)
fatal("no server specified and no default");
cfg_map_get(config, "server", &servers);
if (servers != NULL) {
for (elt = cfg_list_first(servers);
elt != NULL;
elt = cfg_list_next(elt))
{
const char *name;
server = cfg_listelt_value(elt);
name = cfg_obj_asstring(cfg_map_getname(server));
if (strcasecmp(name, servername) == 0)
break;
server = NULL;
}
}
/*
* Look for the name of the key to use.
*/
if (keyname != NULL)
; /* Was set on command line, do nothing. */
else if (server != NULL) {
DO("get key for server", cfg_map_get(server, "key", &defkey));
keyname = cfg_obj_asstring(defkey);
} else if (options != NULL) {
DO("get default key", cfg_map_get(options, "default-key",
&defkey));
keyname = cfg_obj_asstring(defkey);
} else
fatal("no key for server and no default");
/*
* Get the key's definition.
*/
DO("get config key list", cfg_map_get(config, "key", &keys));
for (elt = cfg_list_first(keys);
elt != NULL;
elt = cfg_list_next(elt))
{
key = cfg_listelt_value(elt);
if (strcasecmp(cfg_obj_asstring(cfg_map_getname(key)),
keyname) == 0)
break;
}
if (elt == NULL)
fatal("no key definition for name %s", keyname);
(void)cfg_map_get(key, "secret", &secretobj);
(void)cfg_map_get(key, "algorithm", &algorithmobj);
if (secretobj == NULL || algorithmobj == NULL)
fatal("key must have algorithm and secret");
secretstr = cfg_obj_asstring(secretobj);
algorithm = cfg_obj_asstring(algorithmobj);
if (strcasecmp(algorithm, "hmac-md5") != 0)
fatal("unsupported algorithm: %s", algorithm);
secret.rstart = (unsigned char *)secretarray;
secret.rend = (unsigned char *)secretarray + sizeof(secretarray);
DO("decode base64 secret", isccc_base64_decode(secretstr, &secret));
secret.rend = secret.rstart;
secret.rstart = (unsigned char *)secretarray;
/*
* Find the port to connect to.
*/
if (portset)
; /* Was set on command line, do nothing. */
else {
if (server != NULL)
(void)cfg_map_get(server, "port", &defport);
if (defport == NULL && options != NULL)
cfg_map_get(options, "default-port", &defport);
}
if (defport != NULL) {
remoteport = cfg_obj_asuint32(defport);
if (remoteport > 65535)
fatal("port %d out of range", remoteport);
} else if (!portset)
remoteport = NS_CONTROL_PORT;
parse_config(mctx, log, keyname, &pctx, &config);
isccc_result_register();
@@ -570,7 +590,7 @@ main(int argc, char **argv) {
*p++ = '\0';
INSIST(p == args + argslen);
notify(command);
notify("%s", command);
if (strcmp(command, "restart") == 0)
fatal("'%s' is not implemented", command);

36
bin/rndc/unix/Makefile.in Normal file
View File

@@ -0,0 +1,36 @@
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.1 2001/08/03 05:56:22 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
@BIND9_INCLUDES@
CINCLUDES = -I${srcdir}/include -I${srcdir}/../include \
${DNS_INCLUDES} ${ISC_INCLUDES}
CDEFINES =
CWARNINGS =
OBJS = os.@O@
SRCS = os.c
TARGETS = ${OBJS}
@BIND9_MAKE_RULES@

65
bin/rndc/unix/os.c Normal file
View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: os.c,v 1.1 2001/08/03 05:56:22 marka Exp $ */
#include <config.h>
#include <rndc/os.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
int
set_user(FILE *fd, const char *user) {
struct passwd *pw;
pw = getpwnam(user);
if (pw == NULL) {
errno = EINVAL;
return (-1);
}
return (fchown(fileno(fd), pw->pw_uid, -1));
}
FILE *
safe_create(const char *filename) {
int fd;
FILE *f;
struct stat sb;
if (stat(filename, &sb) == -1) {
if (errno != ENOENT)
return (NULL);
} else if ((sb.st_mode & S_IFREG) == 0) {
errno = EOPNOTSUPP;
return (NULL);
}
fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
if (fd == -1)
return (NULL);
f = fdopen(fd, "w");
if (f == NULL)
close(fd);
return (f);
}

View File

@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)dnl
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
AC_DIVERT_POP()dnl
AC_REVISION($Revision: 1.285 $)
AC_REVISION($Revision: 1.286 $)
AC_INIT(lib/dns/name.c)
AC_PREREQ(2.13)
@@ -1670,6 +1670,7 @@ AC_OUTPUT(
bin/named/Makefile
bin/named/unix/Makefile
bin/rndc/Makefile
bin/rndc/unix/Makefile
bin/dig/Makefile
bin/nsupdate/Makefile
bin/tests/Makefile

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: cfg.h,v 1.28 2001/07/23 16:58:18 gson Exp $ */
/* $Id: cfg.h,v 1.29 2001/08/03 05:56:11 marka Exp $ */
#ifndef ISCCFG_CFG_H
#define ISCCFG_CFG_H 1
@@ -407,6 +407,9 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_namedconf;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndcconf;
/* A complete rndc.conf file. */
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndckey;
/* A complete rndc.conf file. */
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_keyref;
/* A key reference, used as an ACL element */

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: parser.c,v 1.68 2001/08/02 23:36:23 gson Exp $ */
/* $Id: parser.c,v 1.69 2001/08/03 05:56:12 marka Exp $ */
#include <config.h>
@@ -3466,6 +3466,24 @@ LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndcconf = {
rndcconf_clausesets
};
static cfg_clausedef_t
rndckey_clauses[] = {
{ "key", &cfg_type_key, 0 },
{ NULL, NULL, 0 }
};
static cfg_clausedef_t *
rndckey_clausesets[] = {
rndckey_clauses,
NULL
};
LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndckey = {
"rndckey", parse_mapbody, print_mapbody, &cfg_rep_map,
rndckey_clausesets
};
static isc_result_t
cfg_gettoken(cfg_parser_t *pctx, int options) {
isc_result_t result;