control.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004-2007, 2009-2015  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 2001-2003  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /* $Id: control.c,v 1.49 2012/01/31 23:47:31 tbox Exp $ */
00019 
00020 /*! \file */
00021 
00022 #include <config.h>
00023 
00024 
00025 #include <isc/app.h>
00026 #include <isc/event.h>
00027 #include <isc/mem.h>
00028 #include <isc/string.h>
00029 #include <isc/timer.h>
00030 #include <isc/util.h>
00031 
00032 #include <dns/result.h>
00033 
00034 #include <isccc/alist.h>
00035 #include <isccc/cc.h>
00036 #include <isccc/result.h>
00037 
00038 #include <named/control.h>
00039 #include <named/log.h>
00040 #include <named/os.h>
00041 #include <named/server.h>
00042 #ifdef HAVE_LIBSCF
00043 #include <named/ns_smf_globals.h>
00044 #endif
00045 
00046 static isc_boolean_t
00047 command_compare(const char *text, const char *command) {
00048         unsigned int commandlen = strlen(command);
00049         if (strncasecmp(text, command, commandlen) == 0 &&
00050             (text[commandlen] == '\0' ||
00051              text[commandlen] == ' ' ||
00052              text[commandlen] == '\t'))
00053                 return (ISC_TRUE);
00054         return (ISC_FALSE);
00055 }
00056 
00057 /*%
00058  * This function is called to process the incoming command
00059  * when a control channel message is received.
00060  */
00061 isc_result_t
00062 ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t **text) {
00063         isccc_sexpr_t *data;
00064         char *command = NULL;
00065         isc_result_t result;
00066         int log_level;
00067 #ifdef HAVE_LIBSCF
00068         ns_smf_want_disable = 0;
00069 #endif
00070 
00071         data = isccc_alist_lookup(message, "_data");
00072         if (data == NULL) {
00073                 /*
00074                  * No data section.
00075                  */
00076                 return (ISC_R_FAILURE);
00077         }
00078 
00079         result = isccc_cc_lookupstring(data, "type", &command);
00080         if (result != ISC_R_SUCCESS) {
00081                 /*
00082                  * We have no idea what this is.
00083                  */
00084                 return (result);
00085         }
00086 
00087         /*
00088          * Compare the 'command' parameter against all known control commands.
00089          */
00090         if (command_compare(command, NS_COMMAND_NULL) ||
00091             command_compare(command, NS_COMMAND_STATUS)) {
00092                 log_level = ISC_LOG_DEBUG(1);
00093         } else {
00094                 log_level = ISC_LOG_INFO;
00095         }
00096         isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
00097                       NS_LOGMODULE_CONTROL, log_level,
00098                       "received control channel command '%s'",
00099                       command);
00100 
00101         if (command_compare(command, NS_COMMAND_RELOAD)) {
00102                 result = ns_server_reloadcommand(ns_g_server, command, text);
00103         } else if (command_compare(command, NS_COMMAND_RECONFIG)) {
00104                 result = ns_server_reconfigcommand(ns_g_server, command);
00105         } else if (command_compare(command, NS_COMMAND_REFRESH)) {
00106                 result = ns_server_refreshcommand(ns_g_server, command, text);
00107         } else if (command_compare(command, NS_COMMAND_RETRANSFER)) {
00108                 result = ns_server_retransfercommand(ns_g_server,
00109                                                      command, text);
00110         } else if (command_compare(command, NS_COMMAND_HALT)) {
00111 #ifdef HAVE_LIBSCF
00112                 /*
00113                  * If we are managed by smf(5), AND in chroot, then
00114                  * we cannot connect to the smf repository, so just
00115                  * return with an appropriate message back to rndc.
00116                  */
00117                 if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) {
00118                         result = ns_smf_add_message(text);
00119                         return (result);
00120                 }
00121                 /*
00122                  * If we are managed by smf(5) but not in chroot,
00123                  * try to disable ourselves the smf way.
00124                  */
00125                 if (ns_smf_got_instance == 1 && ns_smf_chroot == 0)
00126                         ns_smf_want_disable = 1;
00127                 /*
00128                  * If ns_smf_got_instance = 0, ns_smf_chroot
00129                  * is not relevant and we fall through to
00130                  * isc_app_shutdown below.
00131                  */
00132 #endif
00133                 /* Do not flush master files */
00134                 ns_server_flushonshutdown(ns_g_server, ISC_FALSE);
00135                 ns_os_shutdownmsg(command, *text);
00136                 isc_app_shutdown();
00137                 result = ISC_R_SUCCESS;
00138         } else if (command_compare(command, NS_COMMAND_STOP)) {
00139                 /*
00140                  * "stop" is the same as "halt" except it does
00141                  * flush master files.
00142                  */
00143 #ifdef HAVE_LIBSCF
00144                 if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) {
00145                         result = ns_smf_add_message(text);
00146                         return (result);
00147                 }
00148                 if (ns_smf_got_instance == 1 && ns_smf_chroot == 0)
00149                         ns_smf_want_disable = 1;
00150 #endif
00151                 ns_server_flushonshutdown(ns_g_server, ISC_TRUE);
00152                 ns_os_shutdownmsg(command, *text);
00153                 isc_app_shutdown();
00154                 result = ISC_R_SUCCESS;
00155         } else if (command_compare(command, NS_COMMAND_DUMPSTATS)) {
00156                 result = ns_server_dumpstats(ns_g_server);
00157         } else if (command_compare(command, NS_COMMAND_QUERYLOG)) {
00158                 result = ns_server_togglequerylog(ns_g_server, command);
00159         } else if (command_compare(command, NS_COMMAND_DUMPDB)) {
00160                 ns_server_dumpdb(ns_g_server, command);
00161                 result = ISC_R_SUCCESS;
00162         } else if (command_compare(command, NS_COMMAND_SECROOTS)) {
00163                 result = ns_server_dumpsecroots(ns_g_server, command, text);
00164         } else if (command_compare(command, NS_COMMAND_TRACE)) {
00165                 result = ns_server_setdebuglevel(ns_g_server, command);
00166         } else if (command_compare(command, NS_COMMAND_NOTRACE)) {
00167                 ns_g_debuglevel = 0;
00168                 isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel);
00169                 result = ISC_R_SUCCESS;
00170         } else if (command_compare(command, NS_COMMAND_FLUSH)) {
00171                 result = ns_server_flushcache(ns_g_server, command);
00172         } else if (command_compare(command, NS_COMMAND_FLUSHNAME)) {
00173                 result = ns_server_flushnode(ns_g_server, command, ISC_FALSE);
00174         } else if (command_compare(command, NS_COMMAND_FLUSHTREE)) {
00175                 result = ns_server_flushnode(ns_g_server, command, ISC_TRUE);
00176         } else if (command_compare(command, NS_COMMAND_STATUS)) {
00177                 result = ns_server_status(ns_g_server, text);
00178         } else if (command_compare(command, NS_COMMAND_TSIGLIST)) {
00179                 result = ns_server_tsiglist(ns_g_server, text);
00180         } else if (command_compare(command, NS_COMMAND_TSIGDELETE)) {
00181                 result = ns_server_tsigdelete(ns_g_server, command, text);
00182         } else if (command_compare(command, NS_COMMAND_FREEZE)) {
00183                 result = ns_server_freeze(ns_g_server, ISC_TRUE, command,
00184                                           text);
00185         } else if (command_compare(command, NS_COMMAND_UNFREEZE) ||
00186                    command_compare(command, NS_COMMAND_THAW)) {
00187                 result = ns_server_freeze(ns_g_server, ISC_FALSE, command,
00188                                           text);
00189         } else if (command_compare(command, NS_COMMAND_SCAN)) {
00190                 result = ISC_R_SUCCESS;
00191                 ns_server_scan_interfaces(ns_g_server);
00192         } else if (command_compare(command, NS_COMMAND_SYNC)) {
00193                 result = ns_server_sync(ns_g_server, command, text);
00194         } else if (command_compare(command, NS_COMMAND_RECURSING)) {
00195                 result = ns_server_dumprecursing(ns_g_server);
00196         } else if (command_compare(command, NS_COMMAND_TIMERPOKE)) {
00197                 result = ISC_R_SUCCESS;
00198                 isc_timermgr_poke(ns_g_timermgr);
00199         } else if (command_compare(command, NS_COMMAND_NULL)) {
00200                 result = ISC_R_SUCCESS;
00201         } else if (command_compare(command, NS_COMMAND_NOTIFY)) {
00202                 result = ns_server_notifycommand(ns_g_server, command, text);
00203         } else if (command_compare(command, NS_COMMAND_VALIDATION)) {
00204                 result = ns_server_validation(ns_g_server, command, text);
00205         } else if (command_compare(command, NS_COMMAND_SIGN) ||
00206                    command_compare(command, NS_COMMAND_LOADKEYS)) {
00207                 result = ns_server_rekey(ns_g_server, command, text);
00208         } else if (command_compare(command, NS_COMMAND_ADDZONE) ||
00209                    command_compare(command, NS_COMMAND_MODZONE)) {
00210                 result = ns_server_changezone(ns_g_server, command, text);
00211         } else if (command_compare(command, NS_COMMAND_DELZONE)) {
00212                 result = ns_server_delzone(ns_g_server, command, text);
00213         } else if (command_compare(command, NS_COMMAND_SHOWZONE)) {
00214                 result = ns_server_showzone(ns_g_server, command, text);
00215         } else if (command_compare(command, NS_COMMAND_SIGNING)) {
00216                 result = ns_server_signing(ns_g_server, command, text);
00217         } else if (command_compare(command, NS_COMMAND_ZONESTATUS)) {
00218                 result = ns_server_zonestatus(ns_g_server, command, text);
00219         } else if (command_compare(command, NS_COMMAND_NTA)) {
00220                 result = ns_server_nta(ns_g_server, command, text);
00221         } else if (command_compare(command, NS_COMMAND_TESTGEN)) {
00222                 result = ns_server_testgen(command, text);
00223         } else if (command_compare(command, NS_COMMAND_MKEYS)) {
00224                 result = ns_server_mkeys(ns_g_server, command, text);
00225         } else {
00226                 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
00227                               NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
00228                               "unknown control channel command '%s'",
00229                               command);
00230                 result = DNS_R_UNKNOWNCOMMAND;
00231         }
00232 
00233         return (result);
00234 }

Generated on Tue Apr 28 17:40:54 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha