* 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>
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;
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;
}
}
+#define CHECK(x) \
+ do { \
+ result = (x); \
+ if (result != ISC_R_SUCCESS) \
+ goto cleanup; \
+ } while (0)
+
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;
+get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
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';
+ 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;
- /*
- * 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));
+ 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));
+
+ 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);
+
+ algstr = cfg_obj_asstring(algobj);
+ secretstr = cfg_obj_asstring(secretobj);
+
+ 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;
}
- 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);
-}
-
-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;
+ isc_buffer_init(&b, secret, sizeof(secret));
+ result = isc_base64_decodestring(secretstr, &b);
- 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) {
+ 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);
}
- 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);
+ 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;
+
+ 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
-finalize_automagic_key(void) {
- unsigned int fsaccess;
- int i;
- FILE *fp;
- isc_result_t result;
-
- (void)isc_file_remove(ns_g_autorndckeyfile);
-
- 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;
-
-
- result = isc_stdio_open(ns_g_autorndckeyfile, "w", &fp);
-
- 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 (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));
- }
-
- 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));
- }
-
- cfg_obj_destroy(automagic_key.parser, &automagic_key.config);
- cfg_parser_destroy(&automagic_key.parser);
- }
-}
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 (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 (!cfg_obj_isvoid(control_keylist) &&
+ cfg_list_first(control_keylist) != NULL)
+ cfg_map_get(config, "key", &global_keylist);
- 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");
+ *global_keylistp = global_keylist;
+ *control_keylistp = control_keylist;
}
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;
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);
* 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);
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);
- listener->keys = keys;
- register_keys(control, global_keylist, &listener->keys,
- listener->mctx, socktext);
-
- if (! explicit_key)
- automagic_key.address = listener->address;
+ result = get_rndckey(listener->mctx, &listener->keys);
+ }
- } 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,
/*
* Now, keep the old access list unless a new one can be made.
*/
- allow = cfg_tuple_get(control, "allow");
- result = ns_acl_fromconfig(allow, config, aclconfctx,
- listener->mctx, &new_acl);
+ 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);
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;
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));
/*
* Make the acl.
*/
- allow = cfg_tuple_get(control, "allow");
- result = ns_acl_fromconfig(allow, config, aclconfctx, mctx,
- &new_acl);
+ if (control != NULL) {
+ allow = cfg_tuple_get(control, "allow");
+ 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,
- listener->mctx, socktext);
-
- if (! explicit_key)
- automagic_key.address = listener->address;
-
+ if (result == ISC_R_SUCCESS)
+ register_keys(control, global_keylist,
+ &listener->keys,
+ listener->mctx, socktext);
} 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",
free_listener(listener);
}
- cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
- "couldn't add command channel %s: %s",
- socktext, isc_result_totext(result));
+ 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;
}
listener, link);
}
}
-
- finalize_automagic_key();
-
- /*
- * ns_control_shutdown() will stop whatever is on the global
- * listeners list, which currently only has whatever sockaddrs
- * were in the previous configuration (if any) that do not
- * remain in the current configuration.
- */
- ns_controls_shutdown(cp);
-
- /*
- * Put all of the valid listeners on the listeners list.
- * Anything already on listeners in the process of shutting
- * down will be taken care of by listen_done().
- */
- ISC_LIST_APPENDLIST(cp->listeners, new_listeners, link);
-
} else {
- isc_result_t result;
+ int i;
+
+ 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);
- result = parse_automagic_key(cp->server->mctx);
+ isc_sockaddr_format(&addr, socktext, sizeof(socktext));
+
+ update_listener(cp, &listener, NULL, NULL,
+ &addr, NULL, socktext);
- if (result == ISC_R_SUCCESS)
- ns_controls_configure(cp, automagic_key.config,
- aclconfctx);
+ 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
+ * listeners list, which currently only has whatever sockaddrs
+ * were in the previous configuration (if any) that do not
+ * remain in the current configuration.
+ */
+ ns_controls_shutdown(cp);
+
+ /*
+ * Put all of the valid listeners on the listeners list.
+ * Anything already on listeners in the process of shutting
+ * down will be taken care of by listen_done().
+ */
+ ISC_LIST_APPENDLIST(cp->listeners, new_listeners, link);
return (ISC_R_SUCCESS);
}
* 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
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"
# 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@
RNDCINCLUDES = ${CINCLUDES} ${ISCCC_INCLUDES} ${ISCCFG_INCLUDES}
-CONFINCLUDES = ${CINCLUDES} ${DNS_INCLUDES}
+CONFINCLUDES = -Iinclude ${CINCLUDES} ${DNS_INCLUDES}
CDEFINES =
CWARNINGS =
CONFLIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
+SUBDIRS = unix
+
TARGETS = rndc rndc-confgen
MANPAGES = rndc.8 rndc.conf.5
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}
--- /dev/null
+/*
+ * 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
* 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>
#include <dns/name.h>
#include <dst/dst.h>
+#include <rndc/os.h>
#include "util.h"
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);
}
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)
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':
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;
*/
printf("\n\n");
- printf("\
+ 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\
algorithm hmac-md5;\n\
# allow { %s; } keys { \"%s\"; };\n\
# };\n\
# End of named.conf\n",
- keyname,
- (int)isc_buffer_usedlength(&key_txtbuffer),
- (char *)isc_buffer_base(&key_txtbuffer),
- keyname, serveraddr, port,
- keyname,
- (int)isc_buffer_usedlength(&key_txtbuffer),
- (char *)isc_buffer_base(&key_txtbuffer),
- serveraddr, port, serveraddr, keyname);
+ keyname,
+ (int)isc_buffer_usedlength(&key_txtbuffer),
+ (char *)isc_buffer_base(&key_txtbuffer),
+ keyname, serveraddr, port,
+ keyname,
+ (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);
* 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
#include <isccc/types.h>
#include <isccc/util.h>
+#if 0
+#define RNDC_MAIN
+#include <rndc/os.h>
+#endif
+
#include "util.h"
#ifdef HAVE_ADDRINFO
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;
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();
}
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));
/*
* 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
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;
- admin_conffile = RNDC_CONFFILE;
- auto_conffile = RNDC_AUTOCONFFILE;
-
- isc_app_start();
-
result = isc_file_progname(*argv, program, sizeof(program));
if (result != ISC_R_SUCCESS)
- memcpy(progname, "rndc", 5);
+ memcpy(program, "rndc", 5);
progname = program;
- while ((ch = isc_commandline_parse(argc, argv, "c:Mmp:s:Vy:"))
+ admin_conffile = RNDC_CONFFILE;
+ admin_keyfile = RNDC_KEYFILE;
+
+ isc_app_start();
+
+ 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;
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':
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();
*p++ = '\0';
INSIST(p == args + argslen);
- notify(command);
+ notify("%s", command);
if (strcmp(command, "restart") == 0)
fatal("'%s' is not implemented", command);
--- /dev/null
+# 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@
--- /dev/null
+/*
+ * 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);
+}
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)
bin/named/Makefile
bin/named/unix/Makefile
bin/rndc/Makefile
+ bin/rndc/unix/Makefile
bin/dig/Makefile
bin/nsupdate/Makefile
bin/tests/Makefile
* 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
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 */
* 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>
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;