The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
log.c
Go to the documentation of this file.
1/*
2 * This program is is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 43a2fa5c1478a22af7386fe691d4a5f177de3ff1 $
19 * @file rlm_unbound/log.c
20 * @brief Provides interface between libunbound and the FreeRADIUS event loop
21 *
22 * @copyright 2019 The FreeRADIUS server project
23 * @copyright 2019 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 */
25RCSID("$Id: 43a2fa5c1478a22af7386fe691d4a5f177de3ff1 $")
26
27#define LOG_PREFIX "unbound"
28
29#include <freeradius-devel/util/syserror.h>
30#include "log.h"
31
32/** Write libunbound output to the server or request log
33 *
34 * @param[in] cookie The current thread.
35 * @param[in] buf Log message from unbound.
36 * @param[in] size Length of log message.
37 */
38static ssize_t _unbound_log_write(void *cookie, char const *buf, size_t size)
39{
40 unbound_log_t *u_log = talloc_get_type_abort(cookie, unbound_log_t);
41 request_t *request = u_log->request;
42 size_t len = size;
43
44 if (len == 0) return len;
45 if (buf[len - 1] == '\n') len--; /* Trim trailing new line */
46
47 ROPTIONAL(RDEBUG, DEBUG, "%pV", fr_box_strvalue_len(buf, len));
48
49 return size;
50}
51
52/** Set the debug level for a ub_ctx from the request or global debug level
53 *
54 * @param[in] ub Unbound context to set log level for.
55 * @param[in] lvl To set.
56 * @return
57 * - 0 on success.
58 * - -1 on failure.
59 */
60static int unbound_log_lvl_set(struct ub_ctx *ub, fr_log_lvl_t lvl)
61{
62 int ret;
63 int level;
64
65 switch (lvl) {
67 case L_DBG_LVL_OFF:
68 case L_DBG_LVL_1:
69 level = 0;
70 break;
71
72 case L_DBG_LVL_2:
73 level = 1;
74 break;
75
76 case L_DBG_LVL_3:
77 level = 2; /* Mid-to-heavy levels of output */
78 break;
79
80 case L_DBG_LVL_4:
81 level = 3; /* Pretty crazy amounts of output */
82 break;
83
84 case L_DBG_LVL_MAX:
85 default:
86 level = 4; /* Insane amounts of output including crypts */
87 break;
88 }
89
90 ret = ub_ctx_debuglevel(ub, level);
91 if (ret != 0) {
92 ERROR("Failed setting unbound log level to %i", level);
93 return -1;
94 }
95
96 return 0;
97}
98
99/** Switch thread-specific libunbound output to the request log destination(s)
100 *
101 */
102int unbound_log_to_request(unbound_log_t *u_log, struct ub_ctx *ub, request_t *request)
103{
104 u_log->request = request;
105 return unbound_log_lvl_set(ub, request->log.lvl);
106}
107
108/** Switch thread-specific libunbound output to the global log
109 *
110 * Must be called before a function that previously called #unbound_log_to_request
111 * yields, or can no longer be certain that the request_t * set in t->request
112 * is still valid.
113 */
114int unbound_log_to_global(unbound_log_t *u_log, struct ub_ctx *ub)
115{
116 u_log->request = NULL;
118}
119
121{
122 if (u_log->stream) fclose(u_log->stream);
123 return 0;
124}
125
126/** Setup an unbound context for log, and initialise a u_log struct
127 *
128 */
129int unbound_log_init(TALLOC_CTX *ctx, unbound_log_t **u_log_out, struct ub_ctx *ub)
130{
131 char *val;
132 unbound_log_t *u_log;
133 int ret;
134
135 /*
136 * Check if the user tried to configure
137 * a log destination, and disable it
138 * if they did.
139 */
140 ret = ub_ctx_get_option(ub, "use-syslog", &val);
141 if ((ret != 0) || !val) {
142 ERROR("Failed retrieving unbound syslog settings: %s", ub_strerror(ret));
143 return -1;
144 }
145
146 if (strcmp(val, "yes") == 0) {
147 WARN("Disabling unbound syslog output (use-syslog: %s) > (use-syslog: no)", val);
148
149 ret = ub_ctx_set_option(ub, "use-syslog:", "no");
150 if (ret != 0) {
151 ERROR("Failed disabling unbound syslog output: %s", ub_strerror(ret));
152 free(val);
153 return -1;
154 }
155 }
156 free(val);
157
158 ret = ub_ctx_get_option(ub, "logfile", &val);
159 if ((ret != 0) || !val) {
160 ERROR("Failed retrieving unbound logfile settings: %s", ub_strerror(ret));
161 return -1;
162 }
163
164 if (strcmp(val, "yes") == 0) {
165 WARN("Disabling unbound logfile output (logfile: %s) > (logfile: no)", val);
166
167 ret = ub_ctx_set_option(ub, "logfile:", "no");
168 if (ret != 0) {
169 ERROR("Failed disabling unbound logfile output: %s", ub_strerror(ret));
170 free(val);
171 return -1;
172 }
173 }
174 free(val);
175
176 MEM(u_log = talloc_zero(ctx, unbound_log_t));
177
178 /*
179 * Open a FILE stream, and associate a write
180 * function with it, which then call's
181 * FreeRADIUS' log functions.
182 */
183 u_log->stream = fopencookie(u_log, "w", (cookie_io_functions_t){ .write = _unbound_log_write });
184 if (!u_log->stream) {
185 ERROR("Failed creating log stream for unbound: %s", fr_syserror(errno));
186 talloc_free(u_log);
187 return -1;
188 }
189 talloc_set_destructor(u_log, _unbound_log_free); /* Close stream when log struct is freed */
190 setlinebuf(u_log->stream);
191
192 ret = ub_ctx_debugout(ub, u_log->stream);
193 if (ret != 0) {
194 ERROR("Failed setting log stream for unbound: %s", ub_strerror(ret));
195 talloc_free(u_log);
196 return -1;
197 }
198
199 /*
200 * Set the initial log level and destination
201 */
202 ret = unbound_log_to_global(u_log, ub);
203 if (ret < 0) {
204 talloc_free(u_log);
205 return -1;
206 }
207
208 *u_log_out = u_log;
209
210 return 0;
211}
#define RCSID(id)
Definition build.h:483
#define MEM(x)
Definition debug.h:36
#define ERROR(fmt,...)
Definition dhcpclient.c:41
#define DEBUG(fmt,...)
Definition dhcpclient.c:39
FILE * fopencookie(void *cookie, const char *mode, cookie_io_functions_t io_funcs)
Definition fopencookie.c:99
free(array)
#define ROPTIONAL(_l_request, _l_global, _fmt,...)
Use different logging functions depending on whether request is NULL or not.
Definition log.h:528
talloc_free(reap)
int fr_debug_lvl
Definition log.c:43
fr_log_lvl_t
Definition log.h:67
@ L_DBG_LVL_3
3rd highest priority debug messages (-xxx | -Xx).
Definition log.h:72
@ L_DBG_LVL_1
Highest priority debug messages (-x).
Definition log.h:70
@ L_DBG_LVL_DISABLE
Don't print messages.
Definition log.h:68
@ L_DBG_LVL_2
2nd highest priority debug messages (-xx | -X).
Definition log.h:71
@ L_DBG_LVL_OFF
No debug messages.
Definition log.h:69
@ L_DBG_LVL_4
4th highest priority debug messages (-xxxx | -Xxx).
Definition log.h:73
@ L_DBG_LVL_MAX
Lowest priority debug messages (-xxxxx | -Xxxx).
Definition log.h:74
long int ssize_t
int unbound_log_to_global(unbound_log_t *u_log, struct ub_ctx *ub)
Switch thread-specific libunbound output to the global log.
Definition log.c:114
static ssize_t _unbound_log_write(void *cookie, char const *buf, size_t size)
Write libunbound output to the server or request log.
Definition log.c:38
static int _unbound_log_free(unbound_log_t *u_log)
Definition log.c:120
static int unbound_log_lvl_set(struct ub_ctx *ub, fr_log_lvl_t lvl)
Set the debug level for a ub_ctx from the request or global debug level.
Definition log.c:60
int unbound_log_to_request(unbound_log_t *u_log, struct ub_ctx *ub, request_t *request)
Switch thread-specific libunbound output to the request log destination(s)
Definition log.c:102
int unbound_log_init(TALLOC_CTX *ctx, unbound_log_t **u_log_out, struct ub_ctx *ub)
Setup an unbound context for log, and initialise a u_log struct.
Definition log.c:129
Function prototypes and datatypes for the REST (HTTP) transport.
request_t * request
Request we're logging to.
Definition log.h:45
FILE * stream
Stream we use to interface with the FreeRADIUS logging functions.
Definition log.h:46
Logging state.
Definition log.h:44
#define RDEBUG(fmt,...)
Definition radclient.h:53
#define WARN(fmt,...)
Definition radclient.h:47
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition syserror.c:243
#define fr_box_strvalue_len(_val, _len)
Definition value.h:286