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