Skip to content
GitLab
Menu
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
84f4e4a6
Commit
84f4e4a6
authored
Jul 10, 2000
by
David Lawrence
Browse files
319. [func] The named.conf "controls" statement is now used
to configure the OMAPI command channel. [RT #145]
parent
d4868faf
Changes
7
Hide whitespace changes
Inline
Side-by-side
CHANGES
View file @
84f4e4a6
319. [func] The named.conf "controls" statement is now used
to configure the OMAPI command channel.
318. [func] dns_c_ndcctx_destroy() could never return anything
except ISC_R_SUCCESS; made it have void return instead.
...
...
bin/named/Makefile.in
View file @
84f4e4a6
...
...
@@ -13,7 +13,7 @@
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
# SOFTWARE.
# $Id: Makefile.in,v 1.5
0
2000/0
6/28 02:5
4:55 tale Exp $
# $Id: Makefile.in,v 1.5
1
2000/0
7/10 11:3
4:55 tale Exp $
srcdir
=
@srcdir@
VPATH
=
@srcdir@
...
...
@@ -50,7 +50,7 @@ TARGETS = named lwresd
OBJS
=
client.@O@ interfacemgr.@O@ listenlist.@O@
\
log.@O@ logconf.@O@ main.@O@ notify.@O@ omapi.@O@
\
query.@O@ server.@O@ update.@O@ xfrout.@O@
\
omapiconf.@O@
query.@O@ server.@O@ update.@O@ xfrout.@O@
\
lwresd.@O@ lwdclient.@O@ lwderror.@O@ lwdgabn.@O@
\
lwdgnba.@O@ lwdnoop.@O@
...
...
@@ -58,7 +58,7 @@ UOBJS = unix/os.@O@
SRCS
=
client.c interfacemgr.c listenlist.c
\
log.c logconf.c main.c notify.c omapi.c
\
query.c server.c update.c xfrout.c
\
omapiconf.c
query.c server.c update.c xfrout.c
\
lwresd.c lwdclient.c lwderror.c lwdgabn.c
\
lwdgnba.c lwdnoop.c
...
...
bin/named/include/named/omapi.h
View file @
84f4e4a6
...
...
@@ -15,11 +15,14 @@
* SOFTWARE.
*/
/* $Id: omapi.h,v 1.
7
2000/0
6/22 21:49:49
tale Exp $ */
/* $Id: omapi.h,v 1.
8
2000/0
7/10 11:35:02
tale Exp $ */
#ifndef NAMED_OMAPI_H
#define NAMED_OMAPI_H 1
#include <dns/aclconf.h>
#include <dns/confctx.h>
#include <omapi/omapi.h>
#define NS_OMAPI_PORT 953
...
...
@@ -37,6 +40,10 @@ isc_result_t
ns_omapi_init
(
void
);
isc_result_t
ns_omapi_listen
(
omapi_object_t
**
managerp
);
ns_omapi_configure
(
isc_mem_t
*
mctx
,
dns_c_ctx_t
*
cctx
,
dns_aclconfctx_t
*
aclconfctx
);
void
ns_omapi_shutdown
(
isc_boolean_t
exiting
);
#endif
/* NAMED_OMAPI_H */
bin/named/main.c
View file @
84f4e4a6
...
...
@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: main.c,v 1.7
2
2000/07/
01 00:48:02
tale Exp $ */
/* $Id: main.c,v 1.7
3
2000/07/
10 11:34:56
tale Exp $ */
#include <config.h>
...
...
@@ -385,12 +385,12 @@ create_managers(void) {
static
void
destroy_managers
(
void
)
{
if
(
!
lwresd_only
)
{
if
(
ns_g_omapimgr
!=
NULL
)
omapi
_
listener
_shutdown
(
ns_g_omapimgr
);
else
omapi_lib_destroy
();
}
if
(
!
lwresd_only
)
/*
* The
omapi
listener
s need to be stopped here so that
* isc_taskmgr_destroy() won't block on the omapi task.
*/
ns_omapi_shutdown
(
ISC_TRUE
);
isc_entropy_detach
(
&
ns_g_entropy
);
/*
...
...
@@ -455,29 +455,20 @@ setup(void) {
if
(
!
lwresd_only
)
{
result
=
ns_omapi_init
();
if
(
result
!=
ISC_R_SUCCESS
)
ns_main_earlyfatal
(
"omapi_
lib_
init() failed: %s"
,
ns_main_earlyfatal
(
"
ns_
omapi_init() failed: %s"
,
isc_result_totext
(
result
));
result
=
ns_omapi_listen
(
&
ns_g_omapimgr
);
if
(
result
==
ISC_R_SUCCESS
)
isc_log_write
(
ns_g_lctx
,
NS_LOGCATEGORY_GENERAL
,
NS_LOGMODULE_MAIN
,
ISC_LOG_DEBUG
(
3
),
"OMAPI started"
);
else
isc_log_write
(
ns_g_lctx
,
NS_LOGCATEGORY_GENERAL
,
NS_LOGMODULE_MAIN
,
ISC_LOG_WARNING
,
"OMAPI failed to start: %s"
,
isc_result_totext
(
result
));
}
}
static
void
cleanup
(
void
)
{
destroy_managers
();
if
(
lwresd_only
)
ns_lwresd_destroy
(
&
ns_g_lwresd
);
else
ns_server_destroy
(
&
ns_g_server
);
isc_log_write
(
ns_g_lctx
,
NS_LOGCATEGORY_GENERAL
,
NS_LOGMODULE_MAIN
,
ISC_LOG_NOTICE
,
"exiting"
);
ns_log_shutdown
();
...
...
@@ -543,5 +534,3 @@ main(int argc, char *argv[]) {
return
(
0
);
}
bin/named/omapi.c
View file @
84f4e4a6
...
...
@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: omapi.c,v 1.1
3
2000/0
5/08
1
4
:3
2
:57 tale Exp $ */
/* $Id: omapi.c,v 1.1
4
2000/0
7/10
1
1
:3
4
:57 tale Exp $ */
/*
* Principal Author: DCL
...
...
@@ -42,9 +42,6 @@ typedef struct control_object {
static
control_object_t
control
;
static
omapi_objecttype_t
*
control_type
;
static
void
listen_done
(
isc_task_t
*
task
,
isc_event_t
*
event
);
#undef REGION_FMT
/*
* Ok, kind of gross. Sorry. A little.
...
...
@@ -172,74 +169,3 @@ ns_omapi_init(void) {
return
(
result
);
}
isc_result_t
ns_omapi_listen
(
omapi_object_t
**
managerp
)
{
omapi_object_t
*
manager
=
NULL
;
isc_result_t
result
;
isc_sockaddr_t
sockaddr
;
isc_netaddr_t
netaddr
;
dns_acl_t
*
acl
;
/* XXXDCL make a parameter */
dns_aclelement_t
elt
;
struct
in_addr
inaddr4
;
REQUIRE
(
managerp
!=
NULL
&&
*
managerp
==
NULL
);
/*
* Listen on localhost (127.0.0.1).
* XXXDCL should be configurable.
*/
inaddr4
.
s_addr
=
htonl
(
0x7F000001
);
isc_sockaddr_fromin
(
&
sockaddr
,
&
inaddr4
,
NS_OMAPI_PORT
);
/*
* XXXDCL this is not right either
*/
isc_netaddr_fromsockaddr
(
&
netaddr
,
&
sockaddr
);
elt
.
type
=
dns_aclelementtype_ipprefix
;
elt
.
negative
=
ISC_FALSE
;
elt
.
u
.
ip_prefix
.
address
=
netaddr
;
elt
.
u
.
ip_prefix
.
prefixlen
=
32
;
result
=
dns_acl_create
(
ns_g_mctx
,
1
,
&
acl
);
if
(
result
==
ISC_R_SUCCESS
)
result
=
dns_acl_appendelement
(
acl
,
&
elt
);
if
(
result
==
ISC_R_SUCCESS
)
/*
* Create a generic object to be the manager for handling
* incoming server connections.
*/
result
=
omapi_object_create
(
&
manager
,
NULL
,
0
);
if
(
result
==
ISC_R_SUCCESS
)
{
/*
* Start listening for connections.
*/
result
=
omapi_protocol_listen
(
manager
,
&
sockaddr
,
acl
,
1
,
listen_done
,
ns_g_omapimgr
);
dns_acl_detach
(
&
acl
);
}
if
(
result
==
ISC_R_SUCCESS
)
*
managerp
=
manager
;
else
if
(
manager
!=
NULL
)
omapi_object_dereference
(
&
manager
);
return
(
result
);
}
static
void
listen_done
(
isc_task_t
*
task
,
isc_event_t
*
event
)
{
isc_event_free
(
&
event
);
UNUSED
(
task
);
if
(
ns_g_omapimgr
!=
NULL
)
omapi_object_dereference
(
&
ns_g_omapimgr
);
omapi_lib_destroy
();
}
bin/named/omapiconf.c
0 → 100644
View file @
84f4e4a6
/*
* Copyright (C) 2000 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: omapiconf.c,v 1.1 2000/07/10 11:34:59 tale Exp $ */
/*
* Principal Author: DCL
*/
#include <config.h>
#include <isc/event.h>
#include <isc/mem.h>
#include <isc/once.h>
#include <isc/string.h>
#include <isc/util.h>
#include <named/log.h>
#include <named/omapi.h>
#include <named/server.h>
typedef
struct
ns_omapilistener
ns_omapilistener_t
;
struct
ns_omapilistener
{
/* XXXDCL magic */
isc_mem_t
*
mctx
;
omapi_object_t
*
manager
;
isc_sockaddr_t
address
;
dns_acl_t
*
acl
;
dns_c_kidlist_t
*
keyids
;
LINK
(
ns_omapilistener_t
)
link
;
};
static
ISC_LIST
(
ns_omapilistener_t
)
listeners
;
static
isc_mutex_t
listeners_lock
;
static
isc_once_t
once
=
ISC_ONCE_INIT
;
static
isc_boolean_t
server_exiting
=
ISC_FALSE
;
static
void
initialize_mutex
(
void
)
{
RUNTIME_CHECK
(
isc_mutex_init
(
&
listeners_lock
)
==
ISC_R_SUCCESS
);
}
static
void
free_listener
(
ns_omapilistener_t
*
listener
)
{
if
(
listener
->
keyids
!=
NULL
)
dns_c_kidlist_delete
(
&
listener
->
keyids
);
if
(
listener
->
acl
!=
NULL
)
dns_acl_detach
(
&
listener
->
acl
);
if
(
listener
->
manager
!=
NULL
)
omapi_object_dereference
(
&
listener
->
manager
);
isc_mem_put
(
listener
->
mctx
,
listener
,
sizeof
(
*
listener
));
}
static
void
listen_done
(
isc_task_t
*
task
,
isc_event_t
*
event
)
{
ns_omapilistener_t
*
listener
;
UNUSED
(
task
);
listener
=
event
->
ev_arg
;
LOCK
(
&
listeners_lock
);
ISC_LIST_UNLINK
(
listeners
,
listener
,
link
);
free_listener
(
listener
);
if
(
server_exiting
&&
ISC_LIST_EMPTY
(
listeners
))
omapi_lib_destroy
();
UNLOCK
(
&
listeners_lock
);
isc_event_free
(
&
event
);
}
void
ns_omapi_shutdown
(
isc_boolean_t
exiting
)
{
ns_omapilistener_t
*
listener
;
if
(
exiting
)
{
/*
* When not exiting, this function is called from
* ns_omapi_configure(), which already holds the lock.
*/
LOCK
(
&
listeners_lock
);
if
(
ISC_LIST_EMPTY
(
listeners
))
omapi_lib_destroy
();
else
server_exiting
=
exiting
;
}
for
(
listener
=
ISC_LIST_HEAD
(
listeners
);
listener
!=
NULL
;
listener
=
ISC_LIST_NEXT
(
listener
,
link
))
/*
* This is asynchronous. As listeners shut down, they will
* call listen_done().
*/
omapi_listener_shutdown
(
listener
->
manager
);
if
(
exiting
)
UNLOCK
(
&
listeners_lock
);
}
static
isc_boolean_t
verify_connection
(
isc_sockaddr_t
*
sockaddr
,
void
*
arg
)
{
ns_omapilistener_t
*
listener
;
isc_netaddr_t
netaddr
;
isc_result_t
result
;
int
match
;
isc_netaddr_fromsockaddr
(
&
netaddr
,
sockaddr
);
listener
=
arg
;
result
=
dns_acl_match
(
&
netaddr
,
NULL
,
listener
->
acl
,
NULL
,
&
match
,
NULL
);
if
(
result
!=
ISC_R_SUCCESS
||
match
<=
0
)
return
(
ISC_FALSE
);
else
return
(
ISC_TRUE
);
}
static
isc_boolean_t
verify_key
(
const
char
*
name
,
unsigned
int
algorithm
,
void
*
arg
)
{
ns_omapilistener_t
*
listener
;
dns_c_kid_t
*
keyid
=
NULL
;
/*
* XXXDCL Ideally algorithm would be checked, too, but the current
* config API makes this moderately hard, and omapi will check it
* anyway.
*/
UNUSED
(
algorithm
);
listener
=
arg
;
(
void
)
dns_c_kidlist_find
(
listener
->
keyids
,
name
,
&
keyid
);
if
(
keyid
!=
NULL
)
return
(
ISC_TRUE
);
else
return
(
ISC_FALSE
);
}
static
isc_result_t
ns_omapi_listen
(
ns_omapilistener_t
*
listener
)
{
isc_result_t
result
;
REQUIRE
(
listener
->
manager
==
NULL
);
/*
* Create a generic object to be the manager for handling
* incoming server connections.
*/
result
=
omapi_object_create
(
&
listener
->
manager
,
NULL
,
0
);
if
(
result
==
ISC_R_SUCCESS
)
/*
* Start listening for connections.
*/
result
=
omapi_protocol_listen
(
listener
->
manager
,
&
listener
->
address
,
verify_connection
,
verify_key
,
listen_done
,
listener
);
if
(
result
!=
ISC_R_SUCCESS
&&
listener
->
manager
!=
NULL
)
omapi_object_dereference
(
&
listener
->
manager
);
return
(
result
);
}
static
void
register_keys
(
dns_c_ctrl_t
*
control
,
dns_c_kdeflist_t
*
keydeflist
,
char
*
socktext
)
{
dns_c_kid_t
*
keyid
;
dns_c_kdef_t
*
keydef
;
isc_result_t
result
;
/*
* Register the keys used by this listener. omapi_auth_deregister()
* is used to delete any existing key in case its secret or algorithm
* changed.
*
* XXXDCL but this means a little extra work overall when nothing
* changed. In fact, the same key will be register/deregistered/
* reregistered if it appears more than once in the controls statement.
*
* XXXDCL a separate problem is that keys that have been removed
* from the controls statement in a reconfiguration are not deleted
* until the server shuts down.
*
* XXXDCL confparser.y currently allows the keys clause to be absent,
* which is pointless. it needs to be required.
*/
for
(
keyid
=
ISC_LIST_HEAD
(
control
->
keyidlist
->
keyids
);
keyid
!=
NULL
;
keyid
=
ISC_LIST_NEXT
(
keyid
,
next
))
{
omapi_auth_deregister
(
keyid
->
keyid
);
/*
* XXXDCL confparser.y apparently allows any keyid
* in the list even if it has not been defined with
* the keys statement.
*/
keydef
=
NULL
;
(
void
)
dns_c_kdeflist_find
(
keydeflist
,
keyid
->
keyid
,
&
keydef
);
if
(
keydef
==
NULL
)
isc_log_write
(
ns_g_lctx
,
ISC_LOGCATEGORY_GENERAL
,
NS_LOGMODULE_OMAPI
,
ISC_LOG_WARNING
,
"couldn't find key %s for"
"use with command channel %s"
,
keydef
->
keyid
,
socktext
);
else
if
(
strcasecmp
(
keydef
->
algorithm
,
"hmac-md5"
)
!=
0
)
{
isc_log_write
(
ns_g_lctx
,
ISC_LOGCATEGORY_GENERAL
,
NS_LOGMODULE_OMAPI
,
ISC_LOG_WARNING
,
"unsupported algorithm %s in "
"key %s for use with "
"command channel %s"
,
keydef
->
algorithm
,
keydef
->
keyid
,
socktext
);
keydef
=
NULL
;
}
if
(
keydef
!=
NULL
)
result
=
omapi_auth_register
(
keydef
->
keyid
,
keydef
->
secret
,
OMAPI_AUTH_HMACMD5
);
if
(
keydef
!=
NULL
&&
result
!=
ISC_R_SUCCESS
)
isc_log_write
(
ns_g_lctx
,
ISC_LOGCATEGORY_GENERAL
,
NS_LOGMODULE_OMAPI
,
ISC_LOG_WARNING
,
"couldn't register key %s for"
"use with command channel %s: %s"
,
keydef
->
keyid
,
socktext
,
isc_result_totext
(
result
));
}
}
static
void
update_listener
(
ns_omapilistener_t
**
listenerp
,
dns_c_ctrl_t
*
control
,
dns_c_ctx_t
*
cctx
,
dns_aclconfctx_t
*
aclconfctx
,
char
*
socktext
)
{
ns_omapilistener_t
*
listener
;
dns_acl_t
*
new_acl
=
NULL
;
isc_result_t
result
;
for
(
listener
=
ISC_LIST_HEAD
(
listeners
);
listener
!=
NULL
;
listener
=
ISC_LIST_NEXT
(
listener
,
link
))
{
if
(
isc_sockaddr_equal
(
&
control
->
u
.
inet_v
.
addr
,
&
listener
->
address
))
{
/*
* There is already a listener for this sockaddr.
* Update the access list and key information.
*
* First, keep the old access list unless
* a new one can be made.
*/
result
=
dns_acl_fromconfig
(
control
->
u
.
inet_v
.
matchlist
,
cctx
,
aclconfctx
,
listener
->
mctx
,
&
new_acl
);
if
(
result
==
ISC_R_SUCCESS
)
{
dns_acl_detach
(
&
listener
->
acl
);
dns_acl_attach
(
new_acl
,
&
listener
->
acl
);
dns_acl_detach
(
&
new_acl
);
}
else
/* XXXDCL say the old acl is still used? */
isc_log_write
(
ns_g_lctx
,
ISC_LOGCATEGORY_GENERAL
,
NS_LOGMODULE_OMAPI
,
ISC_LOG_WARNING
,
"couldn't install new acl for "
"command channel %s: %s"
,
socktext
,
isc_result_totext
(
result
));
/*
* Now update the key id list.
* XXXDCL the API for this seems incomplete. For now,
* I just reassign the pointer and set the control
* keyidlist to NULL so dns_c_ctrl_delete will not
* free it.
*/
if
(
listener
->
keyids
!=
NULL
)
dns_c_kidlist_delete
(
&
listener
->
keyids
);
listener
->
keyids
=
control
->
keyidlist
;
control
->
keyidlist
=
NULL
;
break
;
}
}
*
listenerp
=
listener
;
}
static
void
add_listener
(
isc_mem_t
*
mctx
,
ns_omapilistener_t
**
listenerp
,
dns_c_ctrl_t
*
control
,
dns_c_ctx_t
*
cctx
,
dns_aclconfctx_t
*
aclconfctx
,
char
*
socktext
)
{
ns_omapilistener_t
*
listener
;
dns_acl_t
*
new_acl
=
NULL
;
isc_result_t
result
=
ISC_R_SUCCESS
;
listener
=
isc_mem_get
(
mctx
,
sizeof
(
ns_omapilistener_t
));
if
(
listener
==
NULL
)
result
=
ISC_R_NOMEMORY
;
if
(
result
==
ISC_R_SUCCESS
)
{
listener
->
mctx
=
mctx
;
listener
->
manager
=
NULL
;
listener
->
address
=
control
->
u
.
inet_v
.
addr
;
/*
* Make the acl.
*/
result
=
dns_acl_fromconfig
(
control
->
u
.
inet_v
.
matchlist
,
cctx
,
aclconfctx
,
mctx
,
&
new_acl
);
}
if
(
result
==
ISC_R_SUCCESS
)
{
dns_acl_attach
(
new_acl
,
&
listener
->
acl
);
dns_acl_detach
(
&
new_acl
);
/*
* Now update the key id list.
* XXXDCL the API for this seems incomplete. For now,
* I just reassign the pointer and set it to NULL so
* dns_c_ctrl_delete will not free it.
*/
listener
->
keyids
=
control
->
keyidlist
;
control
->
keyidlist
=
NULL
;
result
=
ns_omapi_listen
(
listener
);
}
if
(
result
==
ISC_R_SUCCESS
)
{
isc_log_write
(
ns_g_lctx
,
ISC_LOGCATEGORY_GENERAL
,
NS_LOGMODULE_OMAPI
,
ISC_LOG_NOTICE
,
"command channel listening on %s"
,
socktext
);
*
listenerp
=
listener
;
}
else
{
if
(
listener
!=
NULL
)
free_listener
(
listener
);
isc_log_write
(
ns_g_lctx
,
ISC_LOGCATEGORY_GENERAL
,
NS_LOGMODULE_OMAPI
,
ISC_LOG_WARNING
,
"couldn't add command channel %s: %s"
,
socktext
,
isc_result_totext
(
result
));
*
listenerp
=
NULL
;
}
/* XXXDCL return error results? fail hard? */
}
isc_result_t
ns_omapi_configure
(
isc_mem_t
*
mctx
,
dns_c_ctx_t
*
cctx
,
dns_aclconfctx_t
*
aclconfctx
)
{
ns_omapilistener_t
*
listener
;
ISC_LIST
(
ns_omapilistener_t
)
new_listeners
;
dns_c_ctrllist_t
*
controls
=
NULL
;
dns_c_ctrl_t
*
control
;
dns_c_kdeflist_t
*
keydeflist
=
NULL
;
char
socktext
[
ISC_SOCKADDR_FORMATSIZE
];
isc_result_t
result
;
RUNTIME_CHECK
(
isc_once_do
(
&
once
,
initialize_mutex
)
==
ISC_R_SUCCESS
);
ISC_LIST_INIT
(
new_listeners
);
/*
* Get a pointer to the named.conf ``controls'' statement information.
*/
result
=
dns_c_ctx_getcontrols
(
cctx
,
&
controls
);
LOCK
(
&
listeners_lock
);
/*
* Run through the new control channel list, noting sockets that
* are already being listened on and moving them to the new list.
*
* Identifying duplicates addr/port combinations is left to either
* the underlying config code, or to the bind attempt getting an
* address-in-use error.
*/
if
(
result
==
ISC_R_SUCCESS
)
{
(
void
)
dns_c_ctx_getkdeflist
(
cctx
,
&
keydeflist
);