Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
BIND
Commits
326bcfa0
Commit
326bcfa0
authored
Aug 03, 2001
by
Mark Andrews
Browse files
rndc.key support
parent
faf2b80f
Changes
11
Hide whitespace changes
Inline
Side-by-side
bin/named/controlconf.c
View file @
326bcfa0
...
...
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: controlconf.c,v 1.1
7
2001/0
7/23 01:01:31 bwelling
Exp $ */
/* $Id: controlconf.c,v 1.1
8
2001/0
8/03 05:56:19 marka
Exp $ */
#include
<config.h>
...
...
@@ -100,17 +100,6 @@ struct controllistener {
ISC_LINK
(
controllistener_t
)
link
;
};
static
struct
{
char
name
[
64
];
char
secret
[
192
];
cfg_parser_t
*
parser
;
cfg_obj_t
*
config
;
isc_sockaddr_t
address
;
/* Last channel that needed automagic. */
}
automagic_key
;
#define NS_AUTOKEY_BITS 128
#define NS_AUTOKEY_NAME "control_autokey"
struct
ns_controls
{
ns_server_t
*
server
;
controllistenerlist_t
listeners
;
...
...
@@ -647,7 +636,7 @@ controlkeylist_fromcfg(cfg_obj_t *keylist, isc_mem_t *mctx,
static
void
register_keys
(
cfg_obj_t
*
control
,
cfg_obj_t
*
keylist
,
controlkeylist_t
*
keyids
,
isc_mem_t
*
mctx
,
char
*
socktext
)
controlkeylist_t
*
keyids
,
isc_mem_t
*
mctx
,
const
char
*
socktext
)
{
controlkey_t
*
keyid
,
*
next
;
cfg_obj_t
*
keydef
;
...
...
@@ -725,288 +714,119 @@ register_keys(cfg_obj_t *control, cfg_obj_t *keylist,
}
}
#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
"
"
\t
algorithm hmac-md5;
\n
"
"
\t
secret
\"
%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
"
"
\t
default-server %s;
\n
"
"
\t
default-port %hu;
\n
"
"
\t
default-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
;
...
...
@@ -1014,7 +834,6 @@ update_listener(ns_controls_t *cp,
cfg_obj_t
*
control_keylist
=
NULL
;
dns_acl_t
*
new_acl
=
NULL
;
controlkeylist_t
keys
;
isc_boolean_t
explicit_key
;
isc_result_t
result
=
ISC_R_SUCCESS
;
for
(
listener
=
ISC_LIST_HEAD
(
cp
->
listeners
);
...
...
@@ -1049,8 +868,7 @@ update_listener(ns_controls_t *cp,
* and not able to be decrypted by the client. For this reason,
* the automagic key is not regenerated on each reload.
*/
get_key_info
(
listener
->
mctx
,
config
,
control
,
&
global_keylist
,
&
control_keylist
,
&
explicit_key
);
get_key_info
(
config
,
control
,
&
global_keylist
,
&
control_keylist
);
if
(
control_keylist
!=
NULL
)
{
INSIST
(
global_keylist
!=
NULL
);
...
...
@@ -1058,18 +876,18 @@ update_listener(ns_controls_t *cp,
ISC_LIST_INIT
(
keys
);
result
=
controlkeylist_fromcfg
(
control_keylist
,
listener
->
mctx
,
&
keys
);
}
if
(
result
==
ISC_R_SUCCESS
)
{
if
(
result
)
{
free_controlkeylist
(
&
listener
->
keys
,
listener
->
mctx
);
listener
->
keys
=
keys
;
register_keys
(
control
,
global_keylist
,
&
listener
->
keys
,
listener
->
mctx
,
socktext
);
}
}
else
{
free_controlkeylist
(
&
listener
->
keys
,
listener
->
mctx
);
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,
...
...
@@ -1085,9 +903,20 @@ update_listener(ns_controls_t *cp,
/*
* 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
);
...
...
@@ -1105,7 +934,7 @@ update_listener(ns_controls_t *cp,
static
void
add_listener
(
ns_controls_t
*
cp
,
controllistener_t
**
listenerp
,
cfg_obj_t
*
control
,
cfg_obj_t
*
config
,
isc_sockaddr_t
*
addr
,
ns_aclconfctx_t
*
aclconfctx
,
char
*
socktext
)
ns_aclconfctx_t
*
aclconfctx
,
const
char
*
socktext
)
{
isc_mem_t
*
mctx
=
cp
->
server
->
mctx
;
controllistener_t
*
listener
;
...
...
@@ -1113,7 +942,6 @@ add_listener(ns_controls_t *cp, controllistener_t **listenerp,
cfg_obj_t
*
global_keylist
=
NULL
;
cfg_obj_t
*
control_keylist
=
NULL
;
dns_acl_t
*
new_acl
=
NULL
;
isc_boolean_t
explicit_key
;
isc_result_t
result
=
ISC_R_SUCCESS
;
listener
=
isc_mem_get
(
mctx
,
sizeof
(
*
listener
));
...
...
@@ -1136,30 +964,42 @@ add_listener(ns_controls_t *cp, controllistener_t **listenerp,
/*
* Make the acl.
*/
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"
,
...
...
@@ -1201,9 +1041,15 @@ add_listener(ns_controls_t *cp, controllistener_t **listenerp,
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
;
}
...
...
@@ -1304,34 +1150,62 @@ ns_controls_configure(ns_controls_t *cp, cfg_obj_t *config,
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
)
/*