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