1 /* $NetBSD: log.c,v 1.8 2025/01/26 16:24:33 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 <stdlib.h> 19 20 #include <isc/result.h> 21 #include <isc/util.h> 22 23 #include <dns/log.h> 24 25 #include <isccfg/log.h> 26 27 #include <ns/log.h> 28 29 #include <named/log.h> 30 31 #ifndef ISC_FACILITY 32 #define ISC_FACILITY LOG_DAEMON 33 #endif /* ifndef ISC_FACILITY */ 34 35 /*% 36 * When adding a new category, be sure to add the appropriate 37 * \#define to <named/log.h> and to update the list in 38 * bin/check/check-tool.c. 39 */ 40 static isc_logcategory_t categories[] = { { "", 0 }, 41 { "unmatched", 0 }, 42 { NULL, 0 } }; 43 44 /*% 45 * When adding a new module, be sure to add the appropriate 46 * \#define to <dns/log.h>. 47 */ 48 static isc_logmodule_t modules[] = { 49 { "main", 0 }, { "server", 0 }, { "control", 0 }, { NULL, 0 } 50 }; 51 52 isc_result_t 53 named_log_init(bool safe) { 54 isc_result_t result; 55 isc_logconfig_t *lcfg = NULL; 56 isc_mem_t *log_mctx = NULL; 57 58 named_g_categories = categories; 59 named_g_modules = modules; 60 61 /* 62 * Setup a logging context. 63 */ 64 isc_mem_create(&log_mctx); 65 isc_mem_setname(log_mctx, "named_log"); 66 isc_log_create(log_mctx, &named_g_lctx, &lcfg); 67 isc_mem_detach(&log_mctx); 68 69 /* 70 * named-checktool.c:setup_logging() needs to be kept in sync. 71 */ 72 isc_log_registercategories(named_g_lctx, named_g_categories); 73 isc_log_registermodules(named_g_lctx, named_g_modules); 74 isc_log_setcontext(named_g_lctx); 75 dns_log_init(named_g_lctx); 76 dns_log_setcontext(named_g_lctx); 77 cfg_log_init(named_g_lctx); 78 ns_log_init(named_g_lctx); 79 ns_log_setcontext(named_g_lctx); 80 81 if (safe) { 82 named_log_setsafechannels(lcfg); 83 } else { 84 named_log_setdefaultchannels(lcfg); 85 } 86 87 result = named_log_setdefaultcategory(lcfg); 88 if (result != ISC_R_SUCCESS) { 89 goto cleanup; 90 } 91 92 named_log_setdefaultsslkeylogfile(lcfg); 93 94 return ISC_R_SUCCESS; 95 96 cleanup: 97 isc_log_destroy(&named_g_lctx); 98 isc_log_setcontext(NULL); 99 dns_log_setcontext(NULL); 100 101 return result; 102 } 103 104 void 105 named_log_setdefaultchannels(isc_logconfig_t *lcfg) { 106 isc_logdestination_t destination; 107 108 /* 109 * By default, the logging library makes "default_debug" log to 110 * stderr. In BIND, we want to override this and log to named.run 111 * instead, unless the -g option was given. 112 */ 113 if (!named_g_logstderr) { 114 destination.file.stream = NULL; 115 destination.file.name = "named.run"; 116 destination.file.versions = ISC_LOG_ROLLNEVER; 117 destination.file.maximum_size = 0; 118 isc_log_createchannel(lcfg, "default_debug", ISC_LOG_TOFILE, 119 ISC_LOG_DYNAMIC, &destination, 120 ISC_LOG_PRINTTIME | ISC_LOG_DEBUGONLY); 121 } 122 123 if (named_g_logfile != NULL) { 124 destination.file.stream = NULL; 125 destination.file.name = named_g_logfile; 126 destination.file.versions = ISC_LOG_ROLLNEVER; 127 destination.file.maximum_size = 0; 128 isc_log_createchannel(lcfg, "default_logfile", ISC_LOG_TOFILE, 129 ISC_LOG_DYNAMIC, &destination, 130 ISC_LOG_PRINTTIME | 131 ISC_LOG_PRINTCATEGORY | 132 ISC_LOG_PRINTLEVEL); 133 } 134 135 #if ISC_FACILITY != LOG_DAEMON 136 destination.facility = ISC_FACILITY; 137 isc_log_createchannel(lcfg, "default_syslog", ISC_LOG_TOSYSLOG, 138 ISC_LOG_INFO, &destination, 0); 139 #endif /* if ISC_FACILITY != LOG_DAEMON */ 140 141 /* 142 * Set the initial debug level. 143 */ 144 isc_log_setdebuglevel(named_g_lctx, named_g_debuglevel); 145 } 146 147 void 148 named_log_setsafechannels(isc_logconfig_t *lcfg) { 149 isc_logdestination_t destination; 150 151 if (!named_g_logstderr) { 152 isc_log_createchannel(lcfg, "default_debug", ISC_LOG_TONULL, 153 ISC_LOG_DYNAMIC, NULL, 0); 154 155 /* 156 * Setting the debug level to zero should get the output 157 * discarded a bit faster. 158 */ 159 isc_log_setdebuglevel(named_g_lctx, 0); 160 } else { 161 isc_log_setdebuglevel(named_g_lctx, named_g_debuglevel); 162 } 163 164 if (named_g_logfile != NULL) { 165 destination.file.stream = NULL; 166 destination.file.name = named_g_logfile; 167 destination.file.versions = ISC_LOG_ROLLNEVER; 168 destination.file.maximum_size = 0; 169 isc_log_createchannel(lcfg, "default_logfile", ISC_LOG_TOFILE, 170 ISC_LOG_DYNAMIC, &destination, 171 ISC_LOG_PRINTTIME | 172 ISC_LOG_PRINTCATEGORY | 173 ISC_LOG_PRINTLEVEL); 174 } 175 176 #if ISC_FACILITY != LOG_DAEMON 177 destination.facility = ISC_FACILITY; 178 isc_log_createchannel(lcfg, "default_syslog", ISC_LOG_TOSYSLOG, 179 ISC_LOG_INFO, &destination, 0); 180 #endif /* if ISC_FACILITY != LOG_DAEMON */ 181 } 182 183 /* 184 * If the SSLKEYLOGFILE environment variable is set, TLS pre-master secrets are 185 * logged (for debugging purposes) to the file whose path is provided in that 186 * variable. Set up a default logging channel which maintains up to 10 files 187 * containing TLS pre-master secrets, each up to 100 MB in size. If the 188 * SSLKEYLOGFILE environment variable is set to the string "config", suppress 189 * creation of the default channel, allowing custom logging channel 190 * configuration for TLS pre-master secrets to be provided via the "logging" 191 * stanza in the configuration file. 192 */ 193 void 194 named_log_setdefaultsslkeylogfile(isc_logconfig_t *lcfg) { 195 const char *sslkeylogfile_path = getenv("SSLKEYLOGFILE"); 196 isc_logdestination_t destination = { 197 .file = { 198 .name = sslkeylogfile_path, 199 .versions = 10, 200 .suffix = isc_log_rollsuffix_timestamp, 201 .maximum_size = 100 * 1024 * 1024, 202 }, 203 }; 204 isc_result_t result; 205 206 if (sslkeylogfile_path == NULL || 207 strcmp(sslkeylogfile_path, "config") == 0) 208 { 209 return; 210 } 211 212 isc_log_createchannel(lcfg, "default_sslkeylogfile", ISC_LOG_TOFILE, 213 ISC_LOG_INFO, &destination, 0); 214 result = isc_log_usechannel(lcfg, "default_sslkeylogfile", 215 ISC_LOGCATEGORY_SSLKEYLOG, NULL); 216 RUNTIME_CHECK(result == ISC_R_SUCCESS); 217 } 218 219 isc_result_t 220 named_log_setdefaultcategory(isc_logconfig_t *lcfg) { 221 isc_result_t result = ISC_R_SUCCESS; 222 223 result = isc_log_usechannel(lcfg, "default_debug", 224 ISC_LOGCATEGORY_DEFAULT, NULL); 225 if (result != ISC_R_SUCCESS) { 226 goto cleanup; 227 } 228 229 if (!named_g_logstderr) { 230 if (named_g_logfile != NULL) { 231 result = isc_log_usechannel(lcfg, "default_logfile", 232 ISC_LOGCATEGORY_DEFAULT, 233 NULL); 234 } else if (!named_g_nosyslog) { 235 result = isc_log_usechannel(lcfg, "default_syslog", 236 ISC_LOGCATEGORY_DEFAULT, 237 NULL); 238 } 239 } 240 241 cleanup: 242 return result; 243 } 244 245 isc_result_t 246 named_log_setunmatchedcategory(isc_logconfig_t *lcfg) { 247 isc_result_t result; 248 249 result = isc_log_usechannel(lcfg, "null", NAMED_LOGCATEGORY_UNMATCHED, 250 NULL); 251 return result; 252 } 253 254 void 255 named_log_shutdown(void) { 256 isc_log_destroy(&named_g_lctx); 257 isc_log_setcontext(NULL); 258 dns_log_setcontext(NULL); 259 } 260