2000-01-31 15:17:59 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2000-03-18 02:38:20 +00:00
|
|
|
/* $Id: omapi.c,v 1.10 2000/03/18 02:38:20 tale Exp $ */
|
2000-01-31 15:17:59 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Principal Author: DCL
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
#include <isc/assertions.h>
|
|
|
|
#include <isc/util.h>
|
|
|
|
|
|
|
|
#include <named/globals.h>
|
|
|
|
#include <named/log.h>
|
|
|
|
#include <named/omapi.h>
|
|
|
|
#include <named/server.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The control_object structure is used for receiving commands that
|
|
|
|
* request the server to perform some action, but that do not set or
|
|
|
|
* get any state.
|
|
|
|
*/
|
|
|
|
typedef struct control_object {
|
|
|
|
OMAPI_OBJECT_PREAMBLE;
|
|
|
|
} control_object_t;
|
|
|
|
|
|
|
|
static control_object_t control;
|
|
|
|
static omapi_objecttype_t *control_type;
|
|
|
|
|
2000-03-14 19:48:48 +00:00
|
|
|
static void
|
2000-03-18 00:49:54 +00:00
|
|
|
listen_done(isc_task_t *task, isc_event_t *event);
|
2000-03-14 19:48:48 +00:00
|
|
|
|
2000-01-31 15:17:59 +00:00
|
|
|
#undef REGION_FMT
|
|
|
|
/*
|
|
|
|
* Ok, kind of gross. Sorry. A little.
|
|
|
|
*/
|
|
|
|
#define REGION_FMT(r) (int)(r)->length, (r)->base
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This is the function that is called when an incoming OMAPI_OP_OPEN
|
|
|
|
* message is received with either the create or update option set.
|
|
|
|
* It is called once for each name/value pair in the message's object
|
|
|
|
* value list.
|
|
|
|
*/
|
|
|
|
static isc_result_t
|
|
|
|
control_setvalue(omapi_object_t *handle, omapi_string_t *name,
|
|
|
|
omapi_data_t *value)
|
|
|
|
{
|
|
|
|
isc_region_t region;
|
|
|
|
isc_result_t result;
|
|
|
|
|
|
|
|
INSIST(handle == (omapi_object_t *)&control);
|
|
|
|
|
|
|
|
omapi_string_totext(name, ®ion);
|
|
|
|
|
|
|
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
|
|
|
NS_LOGMODULE_OMAPI, ISC_LOG_DEBUG(1),
|
2000-02-17 20:06:32 +00:00
|
|
|
"control_setvalue: '%.*s' control command received",
|
2000-01-31 15:17:59 +00:00
|
|
|
REGION_FMT(®ion));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Compare the 'name' parameter against all known control commands.
|
|
|
|
*/
|
|
|
|
if (omapi_string_strcmp(name, NS_OMAPI_COMMAND_RELOAD) == 0) {
|
|
|
|
if (omapi_data_getint(value) != 0)
|
|
|
|
ns_server_reloadwanted(ns_g_server);
|
|
|
|
|
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
|
|
|
|
} else if (omapi_string_strcmp(name,
|
|
|
|
NS_OMAPI_COMMAND_RELOADCONFIG) == 0 ||
|
|
|
|
omapi_string_strcmp(name,
|
|
|
|
NS_OMAPI_COMMAND_RELOADZONES) == 0) {
|
|
|
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
|
|
|
NS_LOGMODULE_OMAPI, ISC_LOG_WARNING,
|
2000-02-17 20:06:32 +00:00
|
|
|
"control_setvalue: '%.*s' not yet implemented",
|
2000-01-31 15:17:59 +00:00
|
|
|
REGION_FMT(®ion));
|
|
|
|
result = ISC_R_NOTIMPLEMENTED;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
|
|
|
NS_LOGMODULE_OMAPI, ISC_LOG_WARNING,
|
2000-02-17 20:06:32 +00:00
|
|
|
"control_setvalue: unknown name: '%.*s'",
|
2000-01-31 15:17:59 +00:00
|
|
|
REGION_FMT(®ion));
|
|
|
|
result = omapi_object_passsetvalue(handle, name, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This is the function that is called by the library's internal
|
|
|
|
* message_process function when an incoming OMAPI_OP_OPEN message is received.
|
|
|
|
* It is supposed to look up the object in the server that corresponds to the
|
|
|
|
* key data (name/value pair(s)) in 'key'.
|
|
|
|
*/
|
|
|
|
static isc_result_t
|
|
|
|
control_lookup(omapi_object_t **control_object, omapi_object_t *key) {
|
|
|
|
/*
|
|
|
|
* There is only one control object so no key is needed to look it up.
|
|
|
|
*/
|
|
|
|
UNUSED(key);
|
|
|
|
|
|
|
|
omapi_object_reference(control_object, (omapi_object_t *)&control);
|
|
|
|
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function is called when the server is sending a reply to a client
|
|
|
|
* that opened an object of its type. It needs to output all published
|
|
|
|
* name/value pairs for the object, and will typically also put the data
|
|
|
|
* for any inner objects (but in this program, there will be no inner
|
|
|
|
* objects). The handle parameter is an object of the type registered
|
|
|
|
* in ns_omapi_listen.
|
|
|
|
*/
|
|
|
|
static isc_result_t
|
|
|
|
control_stuffvalues(omapi_object_t *connection, omapi_object_t *handle) {
|
|
|
|
/*
|
|
|
|
* Currently the server has no values to publish, but it needs
|
|
|
|
* to publish something for its OMAPI_OP_UPDATE function to work
|
|
|
|
* when received by the client.
|
|
|
|
*/
|
|
|
|
return (omapi_object_passstuffvalues(connection, handle));
|
|
|
|
}
|
|
|
|
|
2000-03-14 04:07:26 +00:00
|
|
|
isc_result_t
|
2000-03-18 00:49:54 +00:00
|
|
|
ns_omapi_init(void) {
|
2000-03-14 04:07:26 +00:00
|
|
|
isc_result_t result;
|
|
|
|
|
2000-03-18 00:49:54 +00:00
|
|
|
result = omapi_lib_init(ns_g_mctx, ns_g_taskmgr, ns_g_socketmgr);
|
2000-03-14 04:07:26 +00:00
|
|
|
|
|
|
|
if (result == ISC_R_SUCCESS)
|
|
|
|
/*
|
|
|
|
* Register the control_object. NS_OMAPI_CONTROL is
|
|
|
|
* what a client would need to specify as a value for
|
|
|
|
* the value of "type" in a message when contacting
|
|
|
|
* the server to perform a control function.
|
|
|
|
*/
|
|
|
|
result = omapi_object_register(&control_type, NS_OMAPI_CONTROL,
|
|
|
|
control_setvalue,
|
|
|
|
NULL, /* getvalue */
|
|
|
|
NULL, /* destroy */
|
|
|
|
NULL, /* signalhandler */
|
|
|
|
control_stuffvalues,
|
|
|
|
control_lookup,
|
|
|
|
NULL, /* create */
|
|
|
|
NULL); /* remove */
|
|
|
|
|
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
/*
|
|
|
|
* Initialize the static control object.
|
|
|
|
*/
|
|
|
|
control.refcnt = 1;
|
|
|
|
control.type = control_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2000-01-31 15:17:59 +00:00
|
|
|
isc_result_t
|
2000-02-02 02:16:59 +00:00
|
|
|
ns_omapi_listen(omapi_object_t **managerp) {
|
2000-01-31 15:17:59 +00:00
|
|
|
omapi_object_t *manager = NULL;
|
|
|
|
isc_result_t result;
|
2000-02-01 15:18:28 +00:00
|
|
|
isc_sockaddr_t sockaddr;
|
2000-03-14 04:07:26 +00:00
|
|
|
isc_netaddr_t netaddr;
|
|
|
|
dns_acl_t *acl; /* XXXDCL make a parameter */
|
|
|
|
dns_aclelement_t elt;
|
2000-02-01 15:18:28 +00:00
|
|
|
struct in_addr inaddr4;
|
2000-01-31 15:17:59 +00:00
|
|
|
|
|
|
|
REQUIRE(managerp != NULL && *managerp == NULL);
|
|
|
|
|
2000-02-01 15:18:28 +00:00
|
|
|
/*
|
|
|
|
* Listen on localhost (127.0.0.1).
|
|
|
|
* XXXDCL should be configurable.
|
|
|
|
*/
|
|
|
|
inaddr4.s_addr = htonl(0x7F000001);
|
|
|
|
isc_sockaddr_fromin(&sockaddr, &inaddr4, NS_OMAPI_PORT);
|
|
|
|
|
2000-01-31 15:17:59 +00:00
|
|
|
/*
|
2000-03-14 04:07:26 +00:00
|
|
|
* XXXDCL this is not right either
|
2000-01-31 15:17:59 +00:00
|
|
|
*/
|
2000-03-14 04:07:26 +00:00
|
|
|
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;
|
2000-02-01 15:18:28 +00:00
|
|
|
|
2000-03-14 04:07:26 +00:00
|
|
|
result = dns_acl_create(ns_g_mctx, 1, &acl);
|
2000-02-01 15:18:28 +00:00
|
|
|
|
2000-03-14 04:07:26 +00:00
|
|
|
if (result == ISC_R_SUCCESS)
|
|
|
|
result = dns_acl_appendelement(acl, &elt);
|
|
|
|
|
|
|
|
if (result == ISC_R_SUCCESS)
|
2000-02-01 15:18:28 +00:00
|
|
|
/*
|
|
|
|
* Create a generic object to be the manager for handling
|
|
|
|
* incoming server connections.
|
|
|
|
*/
|
|
|
|
result = omapi_object_create(&manager, NULL, 0);
|
2000-01-31 15:17:59 +00:00
|
|
|
|
2000-03-18 02:38:20 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2000-02-01 15:18:28 +00:00
|
|
|
/*
|
|
|
|
* Start listening for connections.
|
|
|
|
*/
|
2000-03-14 19:48:48 +00:00
|
|
|
result = omapi_protocol_listen(manager, &sockaddr, acl, 1,
|
|
|
|
listen_done, ns_g_omapimgr);
|
2000-03-18 02:38:20 +00:00
|
|
|
dns_acl_detach(&acl);
|
|
|
|
}
|
2000-01-31 15:17:59 +00:00
|
|
|
|
2000-02-01 15:18:28 +00:00
|
|
|
if (result == ISC_R_SUCCESS)
|
|
|
|
*managerp = manager;
|
2000-01-31 15:17:59 +00:00
|
|
|
|
2000-03-16 20:04:47 +00:00
|
|
|
else
|
2000-02-01 15:18:28 +00:00
|
|
|
if (manager != NULL)
|
|
|
|
omapi_object_dereference(&manager);
|
2000-01-31 15:17:59 +00:00
|
|
|
|
|
|
|
return (result);
|
|
|
|
}
|
2000-03-14 19:48:48 +00:00
|
|
|
|
|
|
|
static void
|
2000-03-18 00:49:54 +00:00
|
|
|
listen_done(isc_task_t *task, isc_event_t *event) {
|
|
|
|
isc_event_free(&event);
|
|
|
|
|
|
|
|
UNUSED(task);
|
2000-03-14 19:48:48 +00:00
|
|
|
|
2000-03-16 20:04:47 +00:00
|
|
|
if (ns_g_omapimgr != NULL)
|
|
|
|
omapi_object_dereference(&ns_g_omapimgr);
|
|
|
|
|
2000-03-14 19:55:26 +00:00
|
|
|
omapi_lib_destroy();
|
2000-03-14 19:48:48 +00:00
|
|
|
}
|