mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-02 07:35:26 +00:00
rndc.key support
This commit is contained in:
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -100,17 +100,6 @@ struct controllistener {
|
|||||||
ISC_LINK(controllistener_t) link;
|
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 {
|
struct ns_controls {
|
||||||
ns_server_t *server;
|
ns_server_t *server;
|
||||||
controllistenerlist_t listeners;
|
controllistenerlist_t listeners;
|
||||||
@@ -647,7 +636,7 @@ controlkeylist_fromcfg(cfg_obj_t *keylist, isc_mem_t *mctx,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
register_keys(cfg_obj_t *control, cfg_obj_t *keylist,
|
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;
|
controlkey_t *keyid, *next;
|
||||||
cfg_obj_t *keydef;
|
cfg_obj_t *keydef;
|
||||||
@@ -725,288 +714,119 @@ register_keys(cfg_obj_t *control, cfg_obj_t *keylist,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CHECK(x) \
|
||||||
|
do { \
|
||||||
|
result = (x); \
|
||||||
|
if (result != ISC_R_SUCCESS) \
|
||||||
|
goto cleanup; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
make_automagic_key(isc_mem_t *mctx) {
|
get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
|
||||||
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;
|
isc_result_t result;
|
||||||
dst_key_t *key = NULL;
|
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;
|
||||||
|
|
||||||
/*
|
CHECK(cfg_parser_create(mctx, ns_g_lctx, &pctx));
|
||||||
* First generate a secret. The fourth parameter non-zero means
|
CHECK(cfg_parse_file(pctx, ns_g_keyfile, &cfg_type_rndckey, &config));
|
||||||
* that pseudorandom data is ok; good entropy is not required.
|
CHECK(cfg_map_get(config, "key", &key));
|
||||||
*/
|
|
||||||
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) {
|
keyid = isc_mem_get(mctx, sizeof(*keyid));
|
||||||
isc_buffer_init(&key_rawbuffer, &key_rawsecret,
|
if (keyid == NULL)
|
||||||
sizeof(key_rawsecret));
|
CHECK(ISC_R_NOMEMORY);
|
||||||
result = dst_key_tobuffer(key, &key_rawbuffer);
|
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 (result == ISC_R_SUCCESS) {
|
isc_buffer_init(&b, secret, sizeof(secret));
|
||||||
isc_buffer_init(&key_txtbuffer, &key_txtsecret,
|
result = isc_base64_decodestring(secretstr, &b);
|
||||||
sizeof(key_txtsecret));
|
|
||||||
isc_buffer_usedregion(&key_rawbuffer, &key_rawregion);
|
if (result != ISC_R_SUCCESS) {
|
||||||
result = isc_base64_totext(&key_rawregion, -1, "",
|
cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
|
||||||
&key_txtbuffer);
|
"secret for key '%s' on command channel: %s",
|
||||||
|
keyid->keyname, isc_result_totext(result));
|
||||||
|
CHECK(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == ISC_R_SUCCESS) {
|
keyid->secret.length = isc_buffer_usedlength(&b);
|
||||||
unsigned int len = isc_buffer_usedlength(&key_txtbuffer);
|
keyid->secret.base = isc_mem_get(mctx,
|
||||||
|
keyid->secret.length);
|
||||||
INSIST(len < sizeof(automagic_key.secret));
|
if (keyid->secret.base == NULL) {
|
||||||
|
cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
|
||||||
memcpy(automagic_key.secret, isc_buffer_base(&key_txtbuffer),
|
"couldn't register key '%s': "
|
||||||
len);
|
"out of memory", keyid->keyname);
|
||||||
automagic_key.secret[len] = '\0';
|
CHECK(ISC_R_NOMEMORY);
|
||||||
|
|
||||||
/*
|
|
||||||
* 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));
|
|
||||||
}
|
}
|
||||||
|
memcpy(keyid->secret.base, isc_buffer_base(&b),
|
||||||
|
keyid->secret.length);
|
||||||
|
ISC_LIST_APPEND(*keyids, keyid, link);
|
||||||
|
keyid = NULL;
|
||||||
|
result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
if (key != NULL)
|
cleanup:
|
||||||
dst_key_free(&key);
|
if (keyid != NULL)
|
||||||
|
free_controlkey(keyid, mctx);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (config != NULL)
|
||||||
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
cfg_obj_destroy(pctx, &config);
|
||||||
NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
|
if (pctx != NULL)
|
||||||
"could not generate control channel key: %s",
|
cfg_parser_destroy(&pctx);
|
||||||
isc_result_totext(result));
|
|
||||||
|
|
||||||
return (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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
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
|
static void
|
||||||
get_key_info(isc_mem_t *mctx, cfg_obj_t *config, cfg_obj_t *control,
|
get_key_info(cfg_obj_t *config, cfg_obj_t *control,
|
||||||
cfg_obj_t **global_keylistp, cfg_obj_t **control_keylistp,
|
cfg_obj_t **global_keylistp, cfg_obj_t **control_keylistp)
|
||||||
isc_boolean_t *explicit_key)
|
|
||||||
{
|
{
|
||||||
cfg_obj_t *control_keylist = NULL;
|
cfg_obj_t *control_keylist = NULL;
|
||||||
cfg_obj_t *global_keylist = NULL;
|
cfg_obj_t *global_keylist = NULL;
|
||||||
isc_result_t result = ISC_R_SUCCESS;
|
|
||||||
|
|
||||||
REQUIRE(global_keylistp != NULL && *global_keylistp == NULL);
|
REQUIRE(global_keylistp != NULL && *global_keylistp == NULL);
|
||||||
REQUIRE(control_keylistp != NULL && *control_keylistp == NULL);
|
REQUIRE(control_keylistp != NULL && *control_keylistp == NULL);
|
||||||
|
|
||||||
control_keylist = cfg_tuple_get(control, "keys");
|
control_keylist = cfg_tuple_get(control, "keys");
|
||||||
|
|
||||||
if (cfg_obj_isvoid(control_keylist) ||
|
if (!cfg_obj_isvoid(control_keylist) &&
|
||||||
cfg_list_first(control_keylist) == NULL) {
|
cfg_list_first(control_keylist) != NULL)
|
||||||
cfg_obj_t *controls = NULL;
|
cfg_map_get(config, "key", &global_keylist);
|
||||||
cfg_obj_t *inet = NULL;
|
|
||||||
|
|
||||||
if (automagic_key.parser == NULL)
|
*global_keylistp = global_keylist;
|
||||||
result = parse_automagic_key(mctx);
|
*control_keylistp = control_keylist;
|
||||||
|
|
||||||
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
|
static void
|
||||||
update_listener(ns_controls_t *cp,
|
update_listener(ns_controls_t *cp,
|
||||||
controllistener_t **listenerp, cfg_obj_t *control,
|
controllistener_t **listenerp, cfg_obj_t *control,
|
||||||
cfg_obj_t *config, isc_sockaddr_t *addr,
|
cfg_obj_t *config, isc_sockaddr_t *addr,
|
||||||
ns_aclconfctx_t *aclconfctx, char *socktext)
|
ns_aclconfctx_t *aclconfctx, const char *socktext)
|
||||||
{
|
{
|
||||||
controllistener_t *listener;
|
controllistener_t *listener;
|
||||||
cfg_obj_t *allow;
|
cfg_obj_t *allow;
|
||||||
@@ -1014,7 +834,6 @@ update_listener(ns_controls_t *cp,
|
|||||||
cfg_obj_t *control_keylist = NULL;
|
cfg_obj_t *control_keylist = NULL;
|
||||||
dns_acl_t *new_acl = NULL;
|
dns_acl_t *new_acl = NULL;
|
||||||
controlkeylist_t keys;
|
controlkeylist_t keys;
|
||||||
isc_boolean_t explicit_key;
|
|
||||||
isc_result_t result = ISC_R_SUCCESS;
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
for (listener = ISC_LIST_HEAD(cp->listeners);
|
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,
|
* and not able to be decrypted by the client. For this reason,
|
||||||
* the automagic key is not regenerated on each reload.
|
* the automagic key is not regenerated on each reload.
|
||||||
*/
|
*/
|
||||||
get_key_info(listener->mctx, config, control,
|
get_key_info(config, control, &global_keylist, &control_keylist);
|
||||||
&global_keylist, &control_keylist, &explicit_key);
|
|
||||||
|
|
||||||
if (control_keylist != NULL) {
|
if (control_keylist != NULL) {
|
||||||
INSIST(global_keylist != NULL);
|
INSIST(global_keylist != NULL);
|
||||||
@@ -1058,18 +876,18 @@ update_listener(ns_controls_t *cp,
|
|||||||
ISC_LIST_INIT(keys);
|
ISC_LIST_INIT(keys);
|
||||||
result = controlkeylist_fromcfg(control_keylist,
|
result = controlkeylist_fromcfg(control_keylist,
|
||||||
listener->mctx, &keys);
|
listener->mctx, &keys);
|
||||||
|
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 (result == ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS && global_keylist != NULL)
|
||||||
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;
|
|
||||||
|
|
||||||
} else if (global_keylist != NULL)
|
|
||||||
/*
|
/*
|
||||||
* This message might be a little misleading since the
|
* This message might be a little misleading since the
|
||||||
* "new keys" might in fact be identical to the old ones,
|
* "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.
|
* Now, keep the old access list unless a new one can be made.
|
||||||
*/
|
*/
|
||||||
allow = cfg_tuple_get(control, "allow");
|
if (control != NULL) {
|
||||||
result = ns_acl_fromconfig(allow, config, aclconfctx,
|
allow = cfg_tuple_get(control, "allow");
|
||||||
listener->mctx, &new_acl);
|
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) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
dns_acl_detach(&listener->acl);
|
dns_acl_detach(&listener->acl);
|
||||||
dns_acl_attach(new_acl, &listener->acl);
|
dns_acl_attach(new_acl, &listener->acl);
|
||||||
@@ -1105,7 +934,7 @@ update_listener(ns_controls_t *cp,
|
|||||||
static void
|
static void
|
||||||
add_listener(ns_controls_t *cp, controllistener_t **listenerp,
|
add_listener(ns_controls_t *cp, controllistener_t **listenerp,
|
||||||
cfg_obj_t *control, cfg_obj_t *config, isc_sockaddr_t *addr,
|
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;
|
isc_mem_t *mctx = cp->server->mctx;
|
||||||
controllistener_t *listener;
|
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 *global_keylist = NULL;
|
||||||
cfg_obj_t *control_keylist = NULL;
|
cfg_obj_t *control_keylist = NULL;
|
||||||
dns_acl_t *new_acl = NULL;
|
dns_acl_t *new_acl = NULL;
|
||||||
isc_boolean_t explicit_key;
|
|
||||||
isc_result_t result = ISC_R_SUCCESS;
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
listener = isc_mem_get(mctx, sizeof(*listener));
|
listener = isc_mem_get(mctx, sizeof(*listener));
|
||||||
@@ -1136,30 +964,42 @@ add_listener(ns_controls_t *cp, controllistener_t **listenerp,
|
|||||||
/*
|
/*
|
||||||
* Make the acl.
|
* Make the acl.
|
||||||
*/
|
*/
|
||||||
allow = cfg_tuple_get(control, "allow");
|
if (control != NULL) {
|
||||||
result = ns_acl_fromconfig(allow, config, aclconfctx, mctx,
|
allow = cfg_tuple_get(control, "allow");
|
||||||
&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) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
dns_acl_attach(new_acl, &listener->acl);
|
dns_acl_attach(new_acl, &listener->acl);
|
||||||
dns_acl_detach(&new_acl);
|
dns_acl_detach(&new_acl);
|
||||||
|
|
||||||
get_key_info(listener->mctx, config, control,
|
if (config != NULL)
|
||||||
&global_keylist, &control_keylist, &explicit_key);
|
get_key_info(config, control, &global_keylist,
|
||||||
|
&control_keylist);
|
||||||
|
|
||||||
if (control_keylist != NULL)
|
if (control_keylist != NULL) {
|
||||||
result = controlkeylist_fromcfg(control_keylist,
|
result = controlkeylist_fromcfg(control_keylist,
|
||||||
listener->mctx,
|
listener->mctx,
|
||||||
&listener->keys);
|
&listener->keys);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS)
|
||||||
register_keys(control, global_keylist, &listener->keys,
|
register_keys(control, global_keylist,
|
||||||
listener->mctx, socktext);
|
&listener->keys,
|
||||||
|
listener->mctx, socktext);
|
||||||
if (! explicit_key)
|
|
||||||
automagic_key.address = listener->address;
|
|
||||||
|
|
||||||
} else
|
} else
|
||||||
|
result = get_rndckey(mctx, &listener->keys);
|
||||||
|
|
||||||
|
if (result != ISC_R_SUCCESS && control != NULL)
|
||||||
cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
|
cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
|
||||||
"couldn't install keys for "
|
"couldn't install keys for "
|
||||||
"command channel %s: %s",
|
"command channel %s: %s",
|
||||||
@@ -1201,9 +1041,15 @@ add_listener(ns_controls_t *cp, controllistener_t **listenerp,
|
|||||||
free_listener(listener);
|
free_listener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
|
if (control != NULL)
|
||||||
"couldn't add command channel %s: %s",
|
cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
|
||||||
socktext, isc_result_totext(result));
|
"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;
|
*listenerp = NULL;
|
||||||
}
|
}
|
||||||
@@ -1304,34 +1150,62 @@ ns_controls_configure(ns_controls_t *cp, cfg_obj_t *config,
|
|||||||
listener, link);
|
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 {
|
} else {
|
||||||
isc_result_t result;
|
int i;
|
||||||
|
|
||||||
result = parse_automagic_key(cp->server->mctx);
|
for (i = 0 ; i < 2; i++) {
|
||||||
|
isc_sockaddr_t addr;
|
||||||
|
|
||||||
if (result == ISC_R_SUCCESS)
|
if (i == 1) {
|
||||||
ns_controls_configure(cp, automagic_key.config,
|
if (isc_net_probeipv4() != ISC_R_SUCCESS)
|
||||||
aclconfctx);
|
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
|
||||||
|
* 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);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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
|
#ifndef NAMED_GLOBALS_H
|
||||||
#define NAMED_GLOBALS_H 1
|
#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 cfg_obj_t * ns_g_defaults INIT(NULL);
|
||||||
EXTERN const char * ns_g_conffile INIT(NS_SYSCONFDIR
|
EXTERN const char * ns_g_conffile INIT(NS_SYSCONFDIR
|
||||||
"/named.conf");
|
"/named.conf");
|
||||||
|
EXTERN const char * ns_g_keyfile INIT(NS_SYSCONFDIR
|
||||||
|
"/rndc.key");
|
||||||
EXTERN const char * lwresd_g_conffile INIT(NS_SYSCONFDIR
|
EXTERN const char * lwresd_g_conffile INIT(NS_SYSCONFDIR
|
||||||
"/lwresd.conf");
|
"/lwresd.conf");
|
||||||
EXTERN const char * lwresd_g_resolvconffile INIT("/etc"
|
EXTERN const char * lwresd_g_resolvconffile INIT("/etc"
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||||
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
# 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@
|
srcdir = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
@@ -27,7 +27,7 @@ CINCLUDES = ${ISC_INCLUDES}
|
|||||||
|
|
||||||
RNDCINCLUDES = ${CINCLUDES} ${ISCCC_INCLUDES} ${ISCCFG_INCLUDES}
|
RNDCINCLUDES = ${CINCLUDES} ${ISCCC_INCLUDES} ${ISCCFG_INCLUDES}
|
||||||
|
|
||||||
CONFINCLUDES = ${CINCLUDES} ${DNS_INCLUDES}
|
CONFINCLUDES = -Iinclude ${CINCLUDES} ${DNS_INCLUDES}
|
||||||
|
|
||||||
CDEFINES =
|
CDEFINES =
|
||||||
CWARNINGS =
|
CWARNINGS =
|
||||||
@@ -48,6 +48,8 @@ RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${ISCDEPLIBS}
|
|||||||
CONFLIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
|
CONFLIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
|
||||||
CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
|
CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
|
||||||
|
|
||||||
|
SUBDIRS = unix
|
||||||
|
|
||||||
TARGETS = rndc rndc-confgen
|
TARGETS = rndc rndc-confgen
|
||||||
|
|
||||||
MANPAGES = rndc.8 rndc.conf.5
|
MANPAGES = rndc.8 rndc.conf.5
|
||||||
@@ -56,26 +58,29 @@ HTMLPAGES = rndc.html rndc.conf.html
|
|||||||
|
|
||||||
MANOBJS = ${MANPAGES} ${HTMLPAGES}
|
MANOBJS = ${MANPAGES} ${HTMLPAGES}
|
||||||
|
|
||||||
|
UOBJS = unix/os.@O@
|
||||||
|
|
||||||
@BIND9_MAKE_RULES@
|
@BIND9_MAKE_RULES@
|
||||||
|
|
||||||
rndc.@O@: rndc.c
|
rndc.@O@: rndc.c
|
||||||
${LIBTOOL} ${CC} ${ALL_CFLAGS} ${RNDCINCLUDES} \
|
${LIBTOOL} ${CC} ${ALL_CFLAGS} ${RNDCINCLUDES} \
|
||||||
-DVERSION=\"${VERSION}\" \
|
-DVERSION=\"${VERSION}\" \
|
||||||
-DRNDC_CONFFILE=\"${sysconfdir}/rndc.conf\" \
|
-DRNDC_CONFFILE=\"${sysconfdir}/rndc.conf\" \
|
||||||
-DRNDC_AUTOCONFFILE=\"${localstatedir}/run/named.key\" \
|
-DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \
|
||||||
-c ${srcdir}/rndc.c
|
-c ${srcdir}/rndc.c
|
||||||
|
|
||||||
rndc-confgen.@O@: rndc-confgen.c
|
rndc-confgen.@O@: rndc-confgen.c
|
||||||
${LIBTOOL} ${CC} ${ALL_CFLAGS} ${CONFINCLUDES} \
|
${LIBTOOL} ${CC} ${ALL_CFLAGS} ${CONFINCLUDES} \
|
||||||
|
-DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \
|
||||||
-DRNDC_SYSCONFDIR=\"${sysconfdir}\" -c ${srcdir}/rndc-confgen.c
|
-DRNDC_SYSCONFDIR=\"${sysconfdir}\" -c ${srcdir}/rndc-confgen.c
|
||||||
|
|
||||||
rndc: rndc.@O@ util.@O@ ${RNDCDEPLIBS}
|
rndc: rndc.@O@ util.@O@ ${RNDCDEPLIBS}
|
||||||
${LIBTOOL} ${PURIFY} ${CC} ${CFLAGS} -o $@ rndc.@O@ util.@O@ \
|
${LIBTOOL} ${PURIFY} ${CC} ${CFLAGS} -o $@ rndc.@O@ util.@O@ \
|
||||||
${RNDCLIBS}
|
${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@ \
|
${LIBTOOL} ${PURIFY} ${CC} ${CFLAGS} -o $@ rndc-confgen.@O@ util.@O@ \
|
||||||
${CONFLIBS}
|
${UOBJS} ${CONFLIBS}
|
||||||
|
|
||||||
doc man:: ${MANOBJS}
|
doc man:: ${MANOBJS}
|
||||||
|
|
||||||
|
33
bin/rndc/include/rndc/os.h
Normal file
33
bin/rndc/include/rndc/os.h
Normal 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
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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 <config.h>
|
||||||
|
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
#include <dns/name.h>
|
#include <dns/name.h>
|
||||||
|
|
||||||
#include <dst/dst.h>
|
#include <dst/dst.h>
|
||||||
|
#include <rndc/os.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
@@ -51,18 +52,26 @@
|
|||||||
char progname[256];
|
char progname[256];
|
||||||
isc_boolean_t verbose = ISC_FALSE;
|
isc_boolean_t verbose = ISC_FALSE;
|
||||||
|
|
||||||
|
const char *keyfile, *keydef;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(int status) {
|
usage(int status) {
|
||||||
|
|
||||||
fprintf(stderr, "\
|
fprintf(stderr, "\
|
||||||
Usage:\n\
|
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\
|
-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\
|
-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: using pseudorandom data for key generation is ok\n\
|
||||||
-p port: the port named will listen on and rndc will connect to\n\
|
-p port: the port named will listen on and rndc will connect to\n\
|
||||||
-r randomfile: a file containing random data\n\
|
-r randomfile: a file containing random data\n\
|
||||||
-s addr: the address to which rndc should connect\n",
|
-s addr: the address to which rndc should connect\n\
|
||||||
progname, DEFAULT_KEYLENGTH);
|
-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);
|
exit (status);
|
||||||
}
|
}
|
||||||
@@ -91,19 +100,30 @@ main(int argc, char **argv) {
|
|||||||
int entropy_flags = 0;
|
int entropy_flags = 0;
|
||||||
int open_keyboard = ISC_ENTROPY_KEYBOARDMAYBE;
|
int open_keyboard = ISC_ENTROPY_KEYBOARDMAYBE;
|
||||||
struct in_addr addr;
|
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));
|
result = isc_file_progname(*argv, progname, sizeof(progname));
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
memcpy(progname, "rndc", 5);
|
memcpy(progname, "rndc-confgen", 13);
|
||||||
|
|
||||||
keyname = DEFAULT_KEYNAME;
|
keyname = DEFAULT_KEYNAME;
|
||||||
keysize = DEFAULT_KEYLENGTH;
|
keysize = DEFAULT_KEYLENGTH;
|
||||||
serveraddr = DEFAULT_SERVER;
|
serveraddr = DEFAULT_SERVER;
|
||||||
port = DEFAULT_PORT;
|
port = DEFAULT_PORT;
|
||||||
|
|
||||||
while ((ch = isc_commandline_parse(argc, argv, "b:hk:MmPp:r:s:Vy"))
|
while ((ch = isc_commandline_parse(argc, argv,
|
||||||
!= -1) {
|
"ab:c:hk:MmPp:r:s:t:u:Vy")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
|
case 'a':
|
||||||
|
keyonly = ISC_TRUE;
|
||||||
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
keysize = strtol(isc_commandline_argument, &p, 10);
|
keysize = strtol(isc_commandline_argument, &p, 10);
|
||||||
if (*p != '\0' || keysize < 0)
|
if (*p != '\0' || keysize < 0)
|
||||||
@@ -111,6 +131,9 @@ main(int argc, char **argv) {
|
|||||||
if (keysize < 1 || keysize > 512)
|
if (keysize < 1 || keysize > 512)
|
||||||
fatal("-b must be in the range 1 through 512");
|
fatal("-b must be in the range 1 through 512");
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
keyfile = isc_commandline_argument;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(0);
|
usage(0);
|
||||||
case 'k':
|
case 'k':
|
||||||
@@ -142,6 +165,12 @@ main(int argc, char **argv) {
|
|||||||
if (inet_aton(serveraddr, &addr) == 0)
|
if (inet_aton(serveraddr, &addr) == 0)
|
||||||
fatal("-s should be an IPv4 or IPv6 address");
|
fatal("-s should be an IPv4 or IPv6 address");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
chrootdir = isc_commandline_argument;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
user = isc_commandline_argument;
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
verbose = ISC_TRUE;
|
verbose = ISC_TRUE;
|
||||||
@@ -211,7 +240,77 @@ main(int argc, char **argv) {
|
|||||||
*/
|
*/
|
||||||
printf("\n\n");
|
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\
|
# Start of rndc.conf\n\
|
||||||
key \"%s\" {\n\
|
key \"%s\" {\n\
|
||||||
algorithm hmac-md5;\n\
|
algorithm hmac-md5;\n\
|
||||||
@@ -236,15 +335,17 @@ options {\n\
|
|||||||
# allow { %s; } keys { \"%s\"; };\n\
|
# allow { %s; } keys { \"%s\"; };\n\
|
||||||
# };\n\
|
# };\n\
|
||||||
# End of named.conf\n",
|
# End of named.conf\n",
|
||||||
keyname,
|
keyname,
|
||||||
(int)isc_buffer_usedlength(&key_txtbuffer),
|
(int)isc_buffer_usedlength(&key_txtbuffer),
|
||||||
(char *)isc_buffer_base(&key_txtbuffer),
|
(char *)isc_buffer_base(&key_txtbuffer),
|
||||||
keyname, serveraddr, port,
|
keyname, serveraddr, port,
|
||||||
keyname,
|
keyname,
|
||||||
(int)isc_buffer_usedlength(&key_txtbuffer),
|
(int)isc_buffer_usedlength(&key_txtbuffer),
|
||||||
(char *)isc_buffer_base(&key_txtbuffer),
|
(char *)isc_buffer_base(&key_txtbuffer),
|
||||||
serveraddr, port, serveraddr, keyname);
|
serveraddr, port, serveraddr, keyname);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
if (show_final_mem)
|
if (show_final_mem)
|
||||||
isc_mem_stats(mctx, stderr);
|
isc_mem_stats(mctx, stderr);
|
||||||
|
|
||||||
|
276
bin/rndc/rndc.c
276
bin/rndc/rndc.c
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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
|
* Principal Author: DCL
|
||||||
@@ -50,6 +50,11 @@
|
|||||||
#include <isccc/types.h>
|
#include <isccc/types.h>
|
||||||
#include <isccc/util.h>
|
#include <isccc/util.h>
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define RNDC_MAIN
|
||||||
|
#include <rndc/os.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#ifdef HAVE_ADDRINFO
|
#ifdef HAVE_ADDRINFO
|
||||||
@@ -70,10 +75,10 @@ char *progname;
|
|||||||
isc_boolean_t verbose;
|
isc_boolean_t verbose;
|
||||||
|
|
||||||
static const char *admin_conffile;
|
static const char *admin_conffile;
|
||||||
static const char *auto_conffile;
|
static const char *admin_keyfile;
|
||||||
static const char *version = VERSION;
|
static const char *version = VERSION;
|
||||||
static const char *servername = NULL;
|
static const char *servername = NULL;
|
||||||
static unsigned int remoteport = NS_CONTROL_PORT;
|
static unsigned int remoteport = 0;
|
||||||
static isc_socketmgr_t *socketmgr = NULL;
|
static isc_socketmgr_t *socketmgr = NULL;
|
||||||
static unsigned char databuf[2048];
|
static unsigned char databuf[2048];
|
||||||
static isccc_ccmsg_t ccmsg;
|
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;
|
hints.ai_family = PF_INET6;
|
||||||
else
|
else
|
||||||
hints.ai_family = PF_UNSPEC;
|
hints.ai_family = PF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
isc_app_block();
|
isc_app_block();
|
||||||
result = getaddrinfo(host, NULL, &hints, &res);
|
result = getaddrinfo(host, NULL, &hints, &res);
|
||||||
isc_app_unblock();
|
isc_app_unblock();
|
||||||
@@ -313,18 +319,36 @@ rndc_start(isc_task_t *task, isc_event_t *event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_config(isc_mem_t *mctx, isc_log_t *log, cfg_parser_t **pctxp,
|
parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname,
|
||||||
cfg_obj_t **config)
|
cfg_parser_t **pctxp, cfg_obj_t **configp)
|
||||||
{
|
{
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
const char *conffile = admin_conffile;
|
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)) {
|
if (! isc_file_exists(conffile)) {
|
||||||
conffile = auto_conffile;
|
conffile = admin_keyfile;
|
||||||
|
conftype = &cfg_type_rndckey;
|
||||||
|
|
||||||
if (! isc_file_exists(conffile))
|
if (! isc_file_exists(conffile))
|
||||||
fatal("neither %s nor %s was found",
|
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));
|
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.
|
* 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)
|
if (!key_only)
|
||||||
exit(1);
|
(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
|
int
|
||||||
@@ -349,43 +473,33 @@ main(int argc, char **argv) {
|
|||||||
isc_logdestination_t logdest;
|
isc_logdestination_t logdest;
|
||||||
cfg_parser_t *pctx = NULL;
|
cfg_parser_t *pctx = NULL;
|
||||||
cfg_obj_t *config = 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 *keyname = NULL;
|
||||||
const char *secretstr;
|
|
||||||
const char *algorithm;
|
|
||||||
isc_boolean_t portset = ISC_FALSE;
|
|
||||||
char secretarray[1024];
|
|
||||||
char *p;
|
char *p;
|
||||||
size_t argslen;
|
size_t argslen;
|
||||||
int ch;
|
int ch;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
admin_conffile = RNDC_CONFFILE;
|
|
||||||
auto_conffile = RNDC_AUTOCONFFILE;
|
|
||||||
|
|
||||||
isc_app_start();
|
|
||||||
|
|
||||||
result = isc_file_progname(*argv, program, sizeof(program));
|
result = isc_file_progname(*argv, program, sizeof(program));
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
memcpy(progname, "rndc", 5);
|
memcpy(program, "rndc", 5);
|
||||||
progname = program;
|
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) {
|
!= -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'c':
|
case 'c':
|
||||||
admin_conffile = isc_commandline_argument;
|
admin_conffile = isc_commandline_argument;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'k':
|
||||||
|
admin_keyfile = isc_commandline_argument;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
isc_mem_debugging = 1;
|
isc_mem_debugging = 1;
|
||||||
break;
|
break;
|
||||||
@@ -396,10 +510,9 @@ main(int argc, char **argv) {
|
|||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
remoteport = atoi(isc_commandline_argument);
|
remoteport = atoi(isc_commandline_argument);
|
||||||
if (remoteport > 65535)
|
if (remoteport > 65535 || remoteport == 0)
|
||||||
fatal("port '%s' out of range",
|
fatal("port '%s' out of range",
|
||||||
isc_commandline_argument);
|
isc_commandline_argument);
|
||||||
portset = ISC_TRUE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
@@ -446,100 +559,7 @@ main(int argc, char **argv) {
|
|||||||
DO("enabling log channel", isc_log_usechannel(logconfig, "stderr",
|
DO("enabling log channel", isc_log_usechannel(logconfig, "stderr",
|
||||||
NULL, NULL));
|
NULL, NULL));
|
||||||
|
|
||||||
parse_config(mctx, log, &pctx, &config);
|
parse_config(mctx, log, keyname, &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;
|
|
||||||
|
|
||||||
isccc_result_register();
|
isccc_result_register();
|
||||||
|
|
||||||
@@ -570,7 +590,7 @@ main(int argc, char **argv) {
|
|||||||
*p++ = '\0';
|
*p++ = '\0';
|
||||||
INSIST(p == args + argslen);
|
INSIST(p == args + argslen);
|
||||||
|
|
||||||
notify(command);
|
notify("%s", command);
|
||||||
|
|
||||||
if (strcmp(command, "restart") == 0)
|
if (strcmp(command, "restart") == 0)
|
||||||
fatal("'%s' is not implemented", command);
|
fatal("'%s' is not implemented", command);
|
||||||
|
36
bin/rndc/unix/Makefile.in
Normal file
36
bin/rndc/unix/Makefile.in
Normal 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
65
bin/rndc/unix/os.c
Normal 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);
|
||||||
|
}
|
@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)dnl
|
|||||||
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
|
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
|
||||||
AC_DIVERT_POP()dnl
|
AC_DIVERT_POP()dnl
|
||||||
|
|
||||||
AC_REVISION($Revision: 1.285 $)
|
AC_REVISION($Revision: 1.286 $)
|
||||||
|
|
||||||
AC_INIT(lib/dns/name.c)
|
AC_INIT(lib/dns/name.c)
|
||||||
AC_PREREQ(2.13)
|
AC_PREREQ(2.13)
|
||||||
@@ -1670,6 +1670,7 @@ AC_OUTPUT(
|
|||||||
bin/named/Makefile
|
bin/named/Makefile
|
||||||
bin/named/unix/Makefile
|
bin/named/unix/Makefile
|
||||||
bin/rndc/Makefile
|
bin/rndc/Makefile
|
||||||
|
bin/rndc/unix/Makefile
|
||||||
bin/dig/Makefile
|
bin/dig/Makefile
|
||||||
bin/nsupdate/Makefile
|
bin/nsupdate/Makefile
|
||||||
bin/tests/Makefile
|
bin/tests/Makefile
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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
|
#ifndef ISCCFG_CFG_H
|
||||||
#define ISCCFG_CFG_H 1
|
#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;
|
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndcconf;
|
||||||
/* A complete rndc.conf file. */
|
/* 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;
|
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_keyref;
|
||||||
/* A key reference, used as an ACL element */
|
/* A key reference, used as an ACL element */
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -3466,6 +3466,24 @@ LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndcconf = {
|
|||||||
rndcconf_clausesets
|
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
|
static isc_result_t
|
||||||
cfg_gettoken(cfg_parser_t *pctx, int options) {
|
cfg_gettoken(cfg_parser_t *pctx, int options) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
Reference in New Issue
Block a user