/contrib/bind9/bin/named/control.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 213 lines · 148 code · 15 blank · 50 comment · 81 complexity · 799d504e46bbb364d75beb5575b5f8bc MD5 · raw file

  1. /*
  2. * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 2001-2003 Internet Software Consortium.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  10. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  11. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  12. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  13. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  14. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15. * PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. /* $Id: control.c,v 1.41 2010/12/03 22:05:19 each Exp $ */
  18. /*! \file */
  19. #include <config.h>
  20. #include <isc/app.h>
  21. #include <isc/event.h>
  22. #include <isc/mem.h>
  23. #include <isc/string.h>
  24. #include <isc/timer.h>
  25. #include <isc/util.h>
  26. #include <dns/result.h>
  27. #include <isccc/alist.h>
  28. #include <isccc/cc.h>
  29. #include <isccc/result.h>
  30. #include <named/control.h>
  31. #include <named/log.h>
  32. #include <named/os.h>
  33. #include <named/server.h>
  34. #ifdef HAVE_LIBSCF
  35. #include <named/ns_smf_globals.h>
  36. #endif
  37. static isc_boolean_t
  38. command_compare(const char *text, const char *command) {
  39. unsigned int commandlen = strlen(command);
  40. if (strncasecmp(text, command, commandlen) == 0 &&
  41. (text[commandlen] == '\0' ||
  42. text[commandlen] == ' ' ||
  43. text[commandlen] == '\t'))
  44. return (ISC_TRUE);
  45. return (ISC_FALSE);
  46. }
  47. /*%
  48. * This function is called to process the incoming command
  49. * when a control channel message is received.
  50. */
  51. isc_result_t
  52. ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
  53. isccc_sexpr_t *data;
  54. char *command;
  55. isc_result_t result;
  56. int log_level;
  57. #ifdef HAVE_LIBSCF
  58. ns_smf_want_disable = 0;
  59. #endif
  60. data = isccc_alist_lookup(message, "_data");
  61. if (data == NULL) {
  62. /*
  63. * No data section.
  64. */
  65. return (ISC_R_FAILURE);
  66. }
  67. result = isccc_cc_lookupstring(data, "type", &command);
  68. if (result != ISC_R_SUCCESS) {
  69. /*
  70. * We have no idea what this is.
  71. */
  72. return (result);
  73. }
  74. /*
  75. * Compare the 'command' parameter against all known control commands.
  76. */
  77. if (command_compare(command, NS_COMMAND_NULL) ||
  78. command_compare(command, NS_COMMAND_STATUS)) {
  79. log_level = ISC_LOG_DEBUG(1);
  80. } else {
  81. log_level = ISC_LOG_INFO;
  82. }
  83. isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
  84. NS_LOGMODULE_CONTROL, log_level,
  85. "received control channel command '%s'",
  86. command);
  87. if (command_compare(command, NS_COMMAND_RELOAD)) {
  88. result = ns_server_reloadcommand(ns_g_server, command, text);
  89. } else if (command_compare(command, NS_COMMAND_RECONFIG)) {
  90. result = ns_server_reconfigcommand(ns_g_server, command);
  91. } else if (command_compare(command, NS_COMMAND_REFRESH)) {
  92. result = ns_server_refreshcommand(ns_g_server, command, text);
  93. } else if (command_compare(command, NS_COMMAND_RETRANSFER)) {
  94. result = ns_server_retransfercommand(ns_g_server, command);
  95. } else if (command_compare(command, NS_COMMAND_HALT)) {
  96. #ifdef HAVE_LIBSCF
  97. /*
  98. * If we are managed by smf(5), AND in chroot, then
  99. * we cannot connect to the smf repository, so just
  100. * return with an appropriate message back to rndc.
  101. */
  102. if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) {
  103. result = ns_smf_add_message(text);
  104. return (result);
  105. }
  106. /*
  107. * If we are managed by smf(5) but not in chroot,
  108. * try to disable ourselves the smf way.
  109. */
  110. if (ns_smf_got_instance == 1 && ns_smf_chroot == 0)
  111. ns_smf_want_disable = 1;
  112. /*
  113. * If ns_smf_got_instance = 0, ns_smf_chroot
  114. * is not relevant and we fall through to
  115. * isc_app_shutdown below.
  116. */
  117. #endif
  118. /* Do not flush master files */
  119. ns_server_flushonshutdown(ns_g_server, ISC_FALSE);
  120. ns_os_shutdownmsg(command, text);
  121. isc_app_shutdown();
  122. result = ISC_R_SUCCESS;
  123. } else if (command_compare(command, NS_COMMAND_STOP)) {
  124. /*
  125. * "stop" is the same as "halt" except it does
  126. * flush master files.
  127. */
  128. #ifdef HAVE_LIBSCF
  129. if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) {
  130. result = ns_smf_add_message(text);
  131. return (result);
  132. }
  133. if (ns_smf_got_instance == 1 && ns_smf_chroot == 0)
  134. ns_smf_want_disable = 1;
  135. #endif
  136. ns_server_flushonshutdown(ns_g_server, ISC_TRUE);
  137. ns_os_shutdownmsg(command, text);
  138. isc_app_shutdown();
  139. result = ISC_R_SUCCESS;
  140. } else if (command_compare(command, NS_COMMAND_DUMPSTATS)) {
  141. result = ns_server_dumpstats(ns_g_server);
  142. } else if (command_compare(command, NS_COMMAND_QUERYLOG)) {
  143. result = ns_server_togglequerylog(ns_g_server);
  144. } else if (command_compare(command, NS_COMMAND_DUMPDB)) {
  145. ns_server_dumpdb(ns_g_server, command);
  146. result = ISC_R_SUCCESS;
  147. } else if (command_compare(command, NS_COMMAND_SECROOTS)) {
  148. result = ns_server_dumpsecroots(ns_g_server, command);
  149. } else if (command_compare(command, NS_COMMAND_TRACE)) {
  150. result = ns_server_setdebuglevel(ns_g_server, command);
  151. } else if (command_compare(command, NS_COMMAND_NOTRACE)) {
  152. ns_g_debuglevel = 0;
  153. isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel);
  154. result = ISC_R_SUCCESS;
  155. } else if (command_compare(command, NS_COMMAND_FLUSH)) {
  156. result = ns_server_flushcache(ns_g_server, command);
  157. } else if (command_compare(command, NS_COMMAND_FLUSHNAME)) {
  158. result = ns_server_flushname(ns_g_server, command);
  159. } else if (command_compare(command, NS_COMMAND_STATUS)) {
  160. result = ns_server_status(ns_g_server, text);
  161. } else if (command_compare(command, NS_COMMAND_TSIGLIST)) {
  162. result = ns_server_tsiglist(ns_g_server, text);
  163. } else if (command_compare(command, NS_COMMAND_TSIGDELETE)) {
  164. result = ns_server_tsigdelete(ns_g_server, command, text);
  165. } else if (command_compare(command, NS_COMMAND_FREEZE)) {
  166. result = ns_server_freeze(ns_g_server, ISC_TRUE, command,
  167. text);
  168. } else if (command_compare(command, NS_COMMAND_UNFREEZE) ||
  169. command_compare(command, NS_COMMAND_THAW)) {
  170. result = ns_server_freeze(ns_g_server, ISC_FALSE, command,
  171. text);
  172. } else if (command_compare(command, NS_COMMAND_RECURSING)) {
  173. result = ns_server_dumprecursing(ns_g_server);
  174. } else if (command_compare(command, NS_COMMAND_TIMERPOKE)) {
  175. result = ISC_R_SUCCESS;
  176. isc_timermgr_poke(ns_g_timermgr);
  177. } else if (command_compare(command, NS_COMMAND_NULL)) {
  178. result = ISC_R_SUCCESS;
  179. } else if (command_compare(command, NS_COMMAND_NOTIFY)) {
  180. result = ns_server_notifycommand(ns_g_server, command, text);
  181. } else if (command_compare(command, NS_COMMAND_VALIDATION)) {
  182. result = ns_server_validation(ns_g_server, command);
  183. } else if (command_compare(command, NS_COMMAND_SIGN) ||
  184. command_compare(command, NS_COMMAND_LOADKEYS)) {
  185. result = ns_server_rekey(ns_g_server, command);
  186. } else if (command_compare(command, NS_COMMAND_ADDZONE)) {
  187. result = ns_server_add_zone(ns_g_server, command);
  188. } else if (command_compare(command, NS_COMMAND_DELZONE)) {
  189. result = ns_server_del_zone(ns_g_server, command);
  190. } else {
  191. isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
  192. NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
  193. "unknown control channel command '%s'",
  194. command);
  195. result = DNS_R_UNKNOWNCOMMAND;
  196. }
  197. return (result);
  198. }