1 /* $NetBSD: log.c,v 1.6 2022/09/23 12:15:21 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /*! \file */ 17 18 #include <isc/result.h> 19 20 #include <dns/log.h> 21 22 #include <isccfg/log.h> 23 24 #include <ns/log.h> 25 26 #include <named/log.h> 27 28 #ifndef ISC_FACILITY 29 #define ISC_FACILITY LOG_DAEMON 30 #endif /* ifndef ISC_FACILITY */ 31 32 /*% 33 * When adding a new category, be sure to add the appropriate 34 * \#define to <named/log.h> and to update the list in 35 * bin/check/check-tool.c. 36 */ 37 static isc_logcategory_t categories[] = { { "", 0 }, 38 { "unmatched", 0 }, 39 { NULL, 0 } }; 40 41 /*% 42 * When adding a new module, be sure to add the appropriate 43 * \#define to <dns/log.h>. 44 */ 45 static isc_logmodule_t modules[] = { 46 { "main", 0 }, { "server", 0 }, { "control", 0 }, { NULL, 0 } 47 }; 48 49 isc_result_t 50 named_log_init(bool safe) { 51 isc_result_t result; 52 isc_logconfig_t *lcfg = NULL; 53 54 named_g_categories = categories; 55 named_g_modules = modules; 56 57 /* 58 * Setup a logging context. 59 */ 60 isc_log_create(named_g_mctx, &named_g_lctx, &lcfg); 61 62 /* 63 * named-checktool.c:setup_logging() needs to be kept in sync. 64 */ 65 isc_log_registercategories(named_g_lctx, named_g_categories); 66 isc_log_registermodules(named_g_lctx, named_g_modules); 67 isc_log_setcontext(named_g_lctx); 68 dns_log_init(named_g_lctx); 69 dns_log_setcontext(named_g_lctx); 70 cfg_log_init(named_g_lctx); 71 ns_log_init(named_g_lctx); 72 ns_log_setcontext(named_g_lctx); 73 74 if (safe) { 75 named_log_setsafechannels(lcfg); 76 } else { 77 named_log_setdefaultchannels(lcfg); 78 } 79 80 result = named_log_setdefaultcategory(lcfg); 81 if (result != ISC_R_SUCCESS) { 82 goto cleanup; 83 } 84 85 return (ISC_R_SUCCESS); 86 87 cleanup: 88 isc_log_destroy(&named_g_lctx); 89 isc_log_setcontext(NULL); 90 dns_log_setcontext(NULL); 91 92 return (result); 93 } 94 95 void 96 named_log_setdefaultchannels(isc_logconfig_t *lcfg) { 97 isc_logdestination_t destination; 98 99 /* 100 * By default, the logging library makes "default_debug" log to 101 * stderr. In BIND, we want to override this and log to named.run 102 * instead, unless the -g option was given. 103 */ 104 if (!named_g_logstderr) { 105 destination.file.stream = NULL; 106 destination.file.name = "named.run"; 107 destination.file.versions = ISC_LOG_ROLLNEVER; 108 destination.file.maximum_size = 0; 109 isc_log_createchannel(lcfg, "default_debug", ISC_LOG_TOFILE, 110 ISC_LOG_DYNAMIC, &destination, 111 ISC_LOG_PRINTTIME | ISC_LOG_DEBUGONLY); 112 } 113 114 if (named_g_logfile != NULL) { 115 destination.file.stream = NULL; 116 destination.file.name = named_g_logfile; 117 destination.file.versions = ISC_LOG_ROLLNEVER; 118 destination.file.maximum_size = 0; 119 isc_log_createchannel(lcfg, "default_logfile", ISC_LOG_TOFILE, 120 ISC_LOG_DYNAMIC, &destination, 121 ISC_LOG_PRINTTIME | 122 ISC_LOG_PRINTCATEGORY | 123 ISC_LOG_PRINTLEVEL); 124 } 125 126 #if ISC_FACILITY != LOG_DAEMON 127 destination.facility = ISC_FACILITY; 128 isc_log_createchannel(lcfg, "default_syslog", ISC_LOG_TOSYSLOG, 129 ISC_LOG_INFO, &destination, 0); 130 #endif /* if ISC_FACILITY != LOG_DAEMON */ 131 132 /* 133 * Set the initial debug level. 134 */ 135 isc_log_setdebuglevel(named_g_lctx, named_g_debuglevel); 136 } 137 138 void 139 named_log_setsafechannels(isc_logconfig_t *lcfg) { 140 isc_logdestination_t destination; 141 142 if (!named_g_logstderr) { 143 isc_log_createchannel(lcfg, "default_debug", ISC_LOG_TONULL, 144 ISC_LOG_DYNAMIC, NULL, 0); 145 146 /* 147 * Setting the debug level to zero should get the output 148 * discarded a bit faster. 149 */ 150 isc_log_setdebuglevel(named_g_lctx, 0); 151 } else { 152 isc_log_setdebuglevel(named_g_lctx, named_g_debuglevel); 153 } 154 155 if (named_g_logfile != NULL) { 156 destination.file.stream = NULL; 157 destination.file.name = named_g_logfile; 158 destination.file.versions = ISC_LOG_ROLLNEVER; 159 destination.file.maximum_size = 0; 160 isc_log_createchannel(lcfg, "default_logfile", ISC_LOG_TOFILE, 161 ISC_LOG_DYNAMIC, &destination, 162 ISC_LOG_PRINTTIME | 163 ISC_LOG_PRINTCATEGORY | 164 ISC_LOG_PRINTLEVEL); 165 } 166 167 #if ISC_FACILITY != LOG_DAEMON 168 destination.facility = ISC_FACILITY; 169 isc_log_createchannel(lcfg, "default_syslog", ISC_LOG_TOSYSLOG, 170 ISC_LOG_INFO, &destination, 0); 171 #endif /* if ISC_FACILITY != LOG_DAEMON */ 172 } 173 174 isc_result_t 175 named_log_setdefaultcategory(isc_logconfig_t *lcfg) { 176 isc_result_t result = ISC_R_SUCCESS; 177 178 result = isc_log_usechannel(lcfg, "default_debug", 179 ISC_LOGCATEGORY_DEFAULT, NULL); 180 if (result != ISC_R_SUCCESS) { 181 goto cleanup; 182 } 183 184 if (!named_g_logstderr) { 185 if (named_g_logfile != NULL) { 186 result = isc_log_usechannel(lcfg, "default_logfile", 187 ISC_LOGCATEGORY_DEFAULT, 188 NULL); 189 } else if (!named_g_nosyslog) { 190 result = isc_log_usechannel(lcfg, "default_syslog", 191 ISC_LOGCATEGORY_DEFAULT, 192 NULL); 193 } 194 } 195 196 cleanup: 197 return (result); 198 } 199 200 isc_result_t 201 named_log_setunmatchedcategory(isc_logconfig_t *lcfg) { 202 isc_result_t result; 203 204 result = isc_log_usechannel(lcfg, "null", NAMED_LOGCATEGORY_UNMATCHED, 205 NULL); 206 return (result); 207 } 208 209 void 210 named_log_shutdown(void) { 211 isc_log_destroy(&named_g_lctx); 212 isc_log_setcontext(NULL); 213 dns_log_setcontext(NULL); 214 } 215