[BACK]Return to control.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / mpl / bind / dist / bin / named

Annotation of src/external/mpl/bind/dist/bin/named/control.c, Revision 1.6

1.6     ! christos    1: /*     $NetBSD: control.c,v 1.1.1.5 2020/08/03 17:07:03 christos Exp $ */
1.1       christos    2:
                      3: /*
                      4:  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
                      5:  *
                      6:  * This Source Code Form is subject to the terms of the Mozilla Public
                      7:  * License, v. 2.0. If a copy of the MPL was not distributed with this
                      8:  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
                      9:  *
                     10:  * See the COPYRIGHT file distributed with this work for additional
                     11:  * information regarding copyright ownership.
                     12:  */
                     13:
                     14: /*! \file */
                     15:
1.3       christos   16: #include <stdbool.h>
1.1       christos   17:
                     18: #include <isc/app.h>
                     19: #include <isc/event.h>
                     20: #include <isc/lex.h>
                     21: #include <isc/mem.h>
                     22: #include <isc/string.h>
                     23: #include <isc/timer.h>
                     24: #include <isc/util.h>
                     25:
                     26: #include <dns/result.h>
                     27:
                     28: #include <isccc/alist.h>
                     29: #include <isccc/cc.h>
                     30: #include <isccc/result.h>
                     31:
                     32: #include <named/control.h>
                     33: #include <named/globals.h>
                     34: #include <named/log.h>
                     35: #include <named/os.h>
                     36: #include <named/server.h>
                     37: #ifdef HAVE_LIBSCF
                     38: #include <named/smf_globals.h>
1.5       christos   39: #endif /* ifdef HAVE_LIBSCF */
1.1       christos   40:
                     41: static isc_result_t
                     42: getcommand(isc_lex_t *lex, char **cmdp) {
                     43:        isc_result_t result;
                     44:        isc_token_t token;
                     45:
                     46:        REQUIRE(cmdp != NULL && *cmdp == NULL);
                     47:
                     48:        result = isc_lex_gettoken(lex, ISC_LEXOPT_EOF, &token);
1.5       christos   49:        if (result != ISC_R_SUCCESS) {
1.1       christos   50:                return (result);
1.5       christos   51:        }
1.1       christos   52:
                     53:        isc_lex_ungettoken(lex, &token);
                     54:
1.5       christos   55:        if (token.type != isc_tokentype_string) {
1.1       christos   56:                return (ISC_R_FAILURE);
1.5       christos   57:        }
1.1       christos   58:
                     59:        *cmdp = token.value.as_textregion.base;
                     60:
                     61:        return (ISC_R_SUCCESS);
                     62: }
                     63:
1.3       christos   64: static inline bool
1.1       christos   65: command_compare(const char *str, const char *command) {
1.3       christos   66:        return (strcasecmp(str, command) == 0);
1.1       christos   67: }
                     68:
                     69: /*%
                     70:  * This function is called to process the incoming command
                     71:  * when a control channel message is received.
                     72:  */
                     73: isc_result_t
1.3       christos   74: named_control_docommand(isccc_sexpr_t *message, bool readonly,
1.5       christos   75:                        isc_buffer_t **text) {
1.1       christos   76:        isccc_sexpr_t *data;
                     77:        char *cmdline = NULL;
                     78:        char *command = NULL;
                     79:        isc_result_t result;
                     80:        int log_level;
                     81:        isc_buffer_t src;
                     82:        isc_lex_t *lex = NULL;
                     83: #ifdef HAVE_LIBSCF
                     84:        named_smf_want_disable = 0;
1.5       christos   85: #endif /* ifdef HAVE_LIBSCF */
1.1       christos   86:
                     87:        data = isccc_alist_lookup(message, "_data");
                     88:        if (!isccc_alist_alistp(data)) {
                     89:                /*
                     90:                 * No data section.
                     91:                 */
                     92:                return (ISC_R_FAILURE);
                     93:        }
                     94:
                     95:        result = isccc_cc_lookupstring(data, "type", &cmdline);
                     96:        if (result != ISC_R_SUCCESS) {
                     97:                /*
                     98:                 * We have no idea what this is.
                     99:                 */
                    100:                return (result);
                    101:        }
                    102:
                    103:        result = isc_lex_create(named_g_mctx, strlen(cmdline), &lex);
1.5       christos  104:        if (result != ISC_R_SUCCESS) {
1.1       christos  105:                return (result);
1.5       christos  106:        }
1.1       christos  107:
                    108:        isc_buffer_init(&src, cmdline, strlen(cmdline));
                    109:        isc_buffer_add(&src, strlen(cmdline));
                    110:        result = isc_lex_openbuffer(lex, &src);
1.5       christos  111:        if (result != ISC_R_SUCCESS) {
1.1       christos  112:                goto cleanup;
1.5       christos  113:        }
1.1       christos  114:
                    115:        result = getcommand(lex, &command);
1.5       christos  116:        if (result != ISC_R_SUCCESS) {
1.1       christos  117:                goto cleanup;
1.5       christos  118:        }
1.1       christos  119:
                    120:        /*
                    121:         * Compare the 'command' parameter against all known control commands.
                    122:         */
                    123:        if ((command_compare(command, NAMED_COMMAND_NULL) &&
                    124:             strlen(cmdline) == 4) ||
                    125:            command_compare(command, NAMED_COMMAND_STATUS))
                    126:        {
                    127:                log_level = ISC_LOG_DEBUG(1);
                    128:        } else {
                    129:                log_level = ISC_LOG_INFO;
                    130:        }
                    131:
                    132:        /*
                    133:         * If this listener should have read-only access, reject
                    134:         * restricted commands here. rndc nta is handled specially
                    135:         * below.
                    136:         */
1.5       christos  137:        if (readonly && !command_compare(command, NAMED_COMMAND_NTA) &&
1.1       christos  138:            !command_compare(command, NAMED_COMMAND_NULL) &&
                    139:            !command_compare(command, NAMED_COMMAND_STATUS) &&
                    140:            !command_compare(command, NAMED_COMMAND_SHOWZONE) &&
                    141:            !command_compare(command, NAMED_COMMAND_TESTGEN) &&
                    142:            !command_compare(command, NAMED_COMMAND_ZONESTATUS))
                    143:        {
                    144:                isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
                    145:                              NAMED_LOGMODULE_CONTROL, log_level,
                    146:                              "rejecting restricted control channel "
1.5       christos  147:                              "command '%s'",
                    148:                              cmdline);
1.1       christos  149:                result = ISC_R_FAILURE;
                    150:                goto cleanup;
                    151:        }
                    152:
                    153:        isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
                    154:                      NAMED_LOGMODULE_CONTROL, log_level,
1.5       christos  155:                      "received control channel command '%s'", cmdline);
1.1       christos  156:
1.4       christos  157:        /*
                    158:         * After the lengthy "halt" and "stop", the commands are
                    159:         * handled in alphabetical order of the NAMED_COMMAND_ macros.
                    160:         */
                    161:        if (command_compare(command, NAMED_COMMAND_HALT)) {
1.1       christos  162: #ifdef HAVE_LIBSCF
                    163:                /*
                    164:                 * If we are managed by smf(5), AND in chroot, then
                    165:                 * we cannot connect to the smf repository, so just
                    166:                 * return with an appropriate message back to rndc.
                    167:                 */
                    168:                if (named_smf_got_instance == 1 && named_smf_chroot == 1) {
                    169:                        result = named_smf_add_message(text);
                    170:                        goto cleanup;
                    171:                }
                    172:                /*
                    173:                 * If we are managed by smf(5) but not in chroot,
                    174:                 * try to disable ourselves the smf way.
                    175:                 */
1.5       christos  176:                if (named_smf_got_instance == 1 && named_smf_chroot == 0) {
1.1       christos  177:                        named_smf_want_disable = 1;
1.5       christos  178:                }
1.1       christos  179:                /*
                    180:                 * If named_smf_got_instance = 0, named_smf_chroot
                    181:                 * is not relevant and we fall through to
                    182:                 * isc_app_shutdown below.
                    183:                 */
1.5       christos  184: #endif /* ifdef HAVE_LIBSCF */
1.1       christos  185:                /* Do not flush master files */
1.3       christos  186:                named_server_flushonshutdown(named_g_server, false);
1.1       christos  187:                named_os_shutdownmsg(cmdline, *text);
                    188:                isc_app_shutdown();
                    189:                result = ISC_R_SUCCESS;
                    190:        } else if (command_compare(command, NAMED_COMMAND_STOP)) {
                    191:                /*
                    192:                 * "stop" is the same as "halt" except it does
                    193:                 * flush master files.
                    194:                 */
                    195: #ifdef HAVE_LIBSCF
                    196:                if (named_smf_got_instance == 1 && named_smf_chroot == 1) {
                    197:                        result = named_smf_add_message(text);
                    198:                        goto cleanup;
                    199:                }
1.5       christos  200:                if (named_smf_got_instance == 1 && named_smf_chroot == 0) {
1.1       christos  201:                        named_smf_want_disable = 1;
1.5       christos  202:                }
                    203: #endif /* ifdef HAVE_LIBSCF */
1.3       christos  204:                named_server_flushonshutdown(named_g_server, true);
1.1       christos  205:                named_os_shutdownmsg(cmdline, *text);
                    206:                isc_app_shutdown();
                    207:                result = ISC_R_SUCCESS;
1.4       christos  208:        } else if (command_compare(command, NAMED_COMMAND_ADDZONE) ||
1.5       christos  209:                   command_compare(command, NAMED_COMMAND_MODZONE))
                    210:        {
1.4       christos  211:                result = named_server_changezone(named_g_server, cmdline, text);
                    212:        } else if (command_compare(command, NAMED_COMMAND_DELZONE)) {
                    213:                result = named_server_delzone(named_g_server, lex, text);
1.6     ! christos  214:        } else if (command_compare(command, NAMED_COMMAND_DNSSEC)) {
        !           215:                result = named_server_dnssec(named_g_server, lex, text);
1.4       christos  216:        } else if (command_compare(command, NAMED_COMMAND_DNSTAP) ||
1.5       christos  217:                   command_compare(command, NAMED_COMMAND_DNSTAPREOPEN))
                    218:        {
1.4       christos  219:                result = named_server_dnstap(named_g_server, lex, text);
1.1       christos  220:        } else if (command_compare(command, NAMED_COMMAND_DUMPDB)) {
                    221:                named_server_dumpdb(named_g_server, lex, text);
                    222:                result = ISC_R_SUCCESS;
1.4       christos  223:        } else if (command_compare(command, NAMED_COMMAND_DUMPSTATS)) {
                    224:                result = named_server_dumpstats(named_g_server);
1.1       christos  225:        } else if (command_compare(command, NAMED_COMMAND_FLUSH)) {
                    226:                result = named_server_flushcache(named_g_server, lex);
                    227:        } else if (command_compare(command, NAMED_COMMAND_FLUSHNAME)) {
1.3       christos  228:                result = named_server_flushnode(named_g_server, lex, false);
1.1       christos  229:        } else if (command_compare(command, NAMED_COMMAND_FLUSHTREE)) {
1.3       christos  230:                result = named_server_flushnode(named_g_server, lex, true);
1.1       christos  231:        } else if (command_compare(command, NAMED_COMMAND_FREEZE)) {
1.4       christos  232:                result = named_server_freeze(named_g_server, true, lex, text);
                    233:        } else if (command_compare(command, NAMED_COMMAND_LOADKEYS) ||
1.5       christos  234:                   command_compare(command, NAMED_COMMAND_SIGN))
                    235:        {
1.4       christos  236:                result = named_server_rekey(named_g_server, lex, text);
                    237:        } else if (command_compare(command, NAMED_COMMAND_MKEYS)) {
                    238:                result = named_server_mkeys(named_g_server, lex, text);
                    239:        } else if (command_compare(command, NAMED_COMMAND_NOTIFY)) {
                    240:                result = named_server_notifycommand(named_g_server, lex, text);
                    241:        } else if (command_compare(command, NAMED_COMMAND_NOTRACE)) {
                    242:                named_g_debuglevel = 0;
                    243:                isc_log_setdebuglevel(named_g_lctx, named_g_debuglevel);
                    244:                result = ISC_R_SUCCESS;
                    245:        } else if (command_compare(command, NAMED_COMMAND_NTA)) {
                    246:                result = named_server_nta(named_g_server, lex, readonly, text);
                    247:        } else if (command_compare(command, NAMED_COMMAND_NULL)) {
                    248:                result = ISC_R_SUCCESS;
                    249:        } else if (command_compare(command, NAMED_COMMAND_QUERYLOG)) {
                    250:                result = named_server_togglequerylog(named_g_server, lex);
                    251:        } else if (command_compare(command, NAMED_COMMAND_RECONFIG)) {
                    252:                result = named_server_reconfigcommand(named_g_server);
                    253:        } else if (command_compare(command, NAMED_COMMAND_RECURSING)) {
                    254:                result = named_server_dumprecursing(named_g_server);
                    255:        } else if (command_compare(command, NAMED_COMMAND_REFRESH)) {
                    256:                result = named_server_refreshcommand(named_g_server, lex, text);
                    257:        } else if (command_compare(command, NAMED_COMMAND_RELOAD)) {
                    258:                result = named_server_reloadcommand(named_g_server, lex, text);
                    259:        } else if (command_compare(command, NAMED_COMMAND_RETRANSFER)) {
1.5       christos  260:                result = named_server_retransfercommand(named_g_server, lex,
                    261:                                                        text);
1.1       christos  262:        } else if (command_compare(command, NAMED_COMMAND_SCAN)) {
1.4       christos  263:                named_server_scan_interfaces(named_g_server);
1.1       christos  264:                result = ISC_R_SUCCESS;
1.4       christos  265:        } else if (command_compare(command, NAMED_COMMAND_SECROOTS)) {
                    266:                result = named_server_dumpsecroots(named_g_server, lex, text);
                    267:        } else if (command_compare(command, NAMED_COMMAND_SERVESTALE)) {
                    268:                result = named_server_servestale(named_g_server, lex, text);
                    269:        } else if (command_compare(command, NAMED_COMMAND_SHOWZONE)) {
                    270:                result = named_server_showzone(named_g_server, lex, text);
                    271:        } else if (command_compare(command, NAMED_COMMAND_SIGNING)) {
                    272:                result = named_server_signing(named_g_server, lex, text);
                    273:        } else if (command_compare(command, NAMED_COMMAND_STATUS)) {
                    274:                result = named_server_status(named_g_server, text);
1.1       christos  275:        } else if (command_compare(command, NAMED_COMMAND_SYNC)) {
                    276:                result = named_server_sync(named_g_server, lex, text);
1.4       christos  277:        } else if (command_compare(command, NAMED_COMMAND_TCPTIMEOUTS)) {
                    278:                result = named_server_tcptimeouts(lex, text);
                    279:        } else if (command_compare(command, NAMED_COMMAND_TESTGEN)) {
                    280:                result = named_server_testgen(lex, text);
                    281:        } else if (command_compare(command, NAMED_COMMAND_THAW) ||
1.5       christos  282:                   command_compare(command, NAMED_COMMAND_UNFREEZE))
                    283:        {
1.4       christos  284:                result = named_server_freeze(named_g_server, false, lex, text);
1.1       christos  285:        } else if (command_compare(command, NAMED_COMMAND_TIMERPOKE)) {
                    286:                isc_timermgr_poke(named_g_timermgr);
                    287:                result = ISC_R_SUCCESS;
1.4       christos  288:        } else if (command_compare(command, NAMED_COMMAND_TRACE)) {
                    289:                result = named_server_setdebuglevel(named_g_server, lex);
                    290:        } else if (command_compare(command, NAMED_COMMAND_TSIGDELETE)) {
                    291:                result = named_server_tsigdelete(named_g_server, lex, text);
                    292:        } else if (command_compare(command, NAMED_COMMAND_TSIGLIST)) {
                    293:                result = named_server_tsiglist(named_g_server, text);
1.1       christos  294:        } else if (command_compare(command, NAMED_COMMAND_VALIDATION)) {
                    295:                result = named_server_validation(named_g_server, lex, text);
                    296:        } else if (command_compare(command, NAMED_COMMAND_ZONESTATUS)) {
                    297:                result = named_server_zonestatus(named_g_server, lex, text);
                    298:        } else {
                    299:                isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
                    300:                              NAMED_LOGMODULE_CONTROL, ISC_LOG_WARNING,
1.5       christos  301:                              "unknown control channel command '%s'", command);
1.1       christos  302:                result = DNS_R_UNKNOWNCOMMAND;
                    303:        }
                    304:
1.5       christos  305: cleanup:
                    306:        if (lex != NULL) {
1.1       christos  307:                isc_lex_destroy(&lex);
1.5       christos  308:        }
1.1       christos  309:
                    310:        return (result);
                    311: }

CVSweb <webmaster@jp.NetBSD.org>