1 /*
2  *   This program 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
5  *   (at 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 #ifndef RADIUSD_H
17 #define RADIUSD_H
18 /**
19  * $Id: 094af09c1db2c7c068e6e602798f985c905b07cb $
20  *
21  * @file radiusd.h
22  * @brief Structures, prototypes and global variables for the FreeRADIUS server.
23  *
24  * @copyright 1999-2000,2002-2008  The FreeRADIUS server project
25  */
26 
27 RCSIDH(radiusd_h, "$Id: 094af09c1db2c7c068e6e602798f985c905b07cb $")
28 
29 #include <freeradius-devel/libradius.h>
30 #include <freeradius-devel/radpaths.h>
31 #include <freeradius-devel/conf.h>
32 #include <freeradius-devel/conffile.h>
33 #include <freeradius-devel/event.h>
34 #include <freeradius-devel/connection.h>
35 
36 typedef struct rad_request REQUEST;
37 
38 #include <freeradius-devel/log.h>
39 
40 #ifdef HAVE_PTHREAD_H
41 #  include <pthread.h>
42 #else
43 #  include <sys/wait.h>
44 #endif
45 
46 #ifndef NDEBUG
47 #  define REQUEST_MAGIC (0xdeadbeef)
48 #endif
49 
50 /*
51  *	WITH_VMPS is handled by src/include/features.h
52  */
53 #ifdef WITHOUT_VMPS
54 #  undef WITH_VMPS
55 #endif
56 
57 #ifdef WITH_TLS
58 #  include <freeradius-devel/tls.h>
59 #endif
60 
61 #include <freeradius-devel/stats.h>
62 #include <freeradius-devel/realms.h>
63 #include <freeradius-devel/xlat.h>
64 #include <freeradius-devel/tmpl.h>
65 #include <freeradius-devel/map.h>
66 #include <freeradius-devel/clients.h>
67 #include <freeradius-devel/process.h>
68 /*
69  *	All POSIX systems should have these headers
70  */
71 #include <pwd.h>
72 #include <grp.h>
73 
74 #ifdef __cplusplus
75 extern "C" {
76 #endif
77 
78 /*
79  *	See util.c
80  */
81 typedef struct request_data_t request_data_t;
82 
83 /** Return codes indicating the result of the module call
84  *
85  * All module functions must return one of the codes listed below (apart from
86  * RLM_MODULE_NUMCODES, which is used to check for validity).
87  */
88 typedef enum rlm_rcodes {
89 	RLM_MODULE_REJECT = 0,	//!< Immediately reject the request.
90 	RLM_MODULE_FAIL,	//!< Module failed, don't reply.
91 	RLM_MODULE_OK,		//!< The module is OK, continue.
92 	RLM_MODULE_HANDLED,	//!< The module handled the request, so stop.
93 	RLM_MODULE_INVALID,	//!< The module considers the request invalid.
94 	RLM_MODULE_USERLOCK,	//!< Reject the request (user is locked out).
95 	RLM_MODULE_NOTFOUND,	//!< User not found.
96 	RLM_MODULE_NOOP,	//!< Module succeeded without doing anything.
97 	RLM_MODULE_UPDATED,	//!< OK (pairs modified).
98 	RLM_MODULE_NUMCODES,	//!< How many valid return codes there are.
99 	RLM_MODULE_UNKNOWN	//!< Error resolving rcode (should not be
100 				//!< returned by modules).
101 } rlm_rcode_t;
102 extern const FR_NAME_NUMBER modreturn_table[];
103 
104 /** Main server configuration
105  *
106  * The parsed version of the main server config.
107  */
108 typedef struct main_config {
109 	struct main_config *next;			//!< Next version of the main_config.
110 
111 	char const	*name;				//!< Name of the daemon, usually 'radiusd'.
112 	CONF_SECTION	*config;			//!< Root of the server config.
113 
114 	fr_ipaddr_t	myip;				//!< IP to bind to. Set on command line.
115 	uint16_t	port;				//!< Port to bind to. Set on command line.
116 
117 	bool		suppress_secrets;		//!< for debug levels < 3
118 	bool		log_auth;			//!< Log all authentication attempts.
119 	bool		log_accept;			//!< Log Access-Accept
120 	bool		log_reject;			//!< Log Access-Reject
121 	bool		log_auth_badpass;		//!< Log successful authentications.
122 	bool		log_auth_goodpass;		//!< Log failed authentications.
123 	char const	*auth_badpass_msg;		//!< Additional text to append to successful auth messages.
124 	char const	*auth_goodpass_msg;		//!< Additional text to append to failed auth messages.
125 
126 	char const	*denied_msg;			//!< Additional text to append if the user is already logged
127 							//!< in (simultaneous use check failed).
128 
129 	bool		daemonize;			//!< Should the server daemonize on startup.
130 	char const      *pid_file;			//!< Path to write out PID file.
131 
132 #ifdef WITH_PROXY
133 	bool		proxy_requests;			//!< Toggle to enable/disable proxying globally.
134 #endif
135 	struct timeval	reject_delay;			//!< How long to wait before sending an Access-Reject.
136 	bool		status_server;			//!< Whether to respond to status-server messages.
137 
138 
139 	uint32_t	max_request_time;		//!< How long a request can be processed for before
140 							//!< timing out.
141 	uint32_t	cleanup_delay;			//!< How long before cleaning up cached responses.
142 	uint32_t	max_requests;
143 
144 	bool		postauth_client_lost;		//!< Whether to run Post-Auth-Type Client-Lost section
145 
146 	uint32_t	debug_level;
147 	char const	*log_file;
148 	int		syslog_facility;
149 
150 	char const	*dictionary_dir;		//!< Where to load dictionaries from.
151 
152 	char const	*checkrad;			//!< Script to use to determine if a user is already
153 							//!< connected.
154 
155 	rad_listen_t	*listen;			//!< Head of a linked list of listeners.
156 
157 
158 	char const	*panic_action;			//!< Command to execute if the server receives a fatal
159 							//!< signal.
160 
161 	struct timeval	init_delay;			//!< Initial request processing delay.
162 
163 	uint32_t       	talloc_pool_size;		//!< Size of pool to allocate to hold each #REQUEST.
164 	bool		debug_memory;			//!< Cleanup the server properly on exit, freeing
165 							//!< up any memory we allocated.
166 	bool		memory_report;			//!< Print a memory report on what's left unfreed.
167 							//!< Can only be used when the server is running in single
168 							//!< threaded mode.
169 
170 	bool		allow_core_dumps;		//!< Whether the server is allowed to drop a core when
171 							//!< receiving a fatal signal.
172 
173 	bool		write_pid;			//!< write the PID file
174 
175 	bool		exiting;			//!< are we exiting?
176 
177 
178 #ifdef ENABLE_OPENSSL_VERSION_CHECK
179 	char const	*allow_vulnerable_openssl;	//!< The CVE number of the last security issue acknowledged.
180 #endif
181 } main_config_t;
182 
183 #if defined(WITH_VERIFY_PTR)
184 #  define VERIFY_REQUEST(_x) verify_request(__FILE__, __LINE__, _x)
185 #else
186 /*
187  *  Even if were building without WITH_VERIFY_PTR
188  *  the pointer must not be NULL when these various macros are used
189  *  so we can add some sneaky asserts.
190  */
191 #  define VERIFY_REQUEST(_x) rad_assert(_x)
192 #endif
193 
194 typedef enum {
195 	REQUEST_ACTIVE = 1,
196 	REQUEST_STOP_PROCESSING,
197 	REQUEST_COUNTED
198 } rad_master_state_t;
199 #define REQUEST_MASTER_NUM_STATES (REQUEST_COUNTED + 1)
200 
201 typedef enum {
202 	REQUEST_QUEUED = 1,
203 	REQUEST_RUNNING,
204 	REQUEST_PROXIED,
205 	REQUEST_RESPONSE_DELAY,
206 	REQUEST_CLEANUP_DELAY,
207 	REQUEST_DONE
208 } rad_child_state_t;
209 #define REQUEST_CHILD_NUM_STATES (REQUEST_DONE + 1)
210 
211 struct rad_request {
212 #ifndef NDEBUG
213 	uint32_t		magic; 		//!< Magic number used to detect memory corruption,
214 						//!< or request structs that have not been properly initialised.
215 #endif
216 	unsigned int	       	number; 	//!< Monotonically increasing request number. Reset on server restart.
217 	time_t			timestamp;	//!< When the request was received.
218 
219 	request_data_t		*data;		//!< Request metadata.
220 
221 	rad_listen_t		*listener;	//!< The listener that received the request.
222 	RADCLIENT		*client;	//!< The client that originally sent us the request.
223 
224 	RADIUS_PACKET		*packet;	//!< Incoming request.
225 	VALUE_PAIR		*username;	//!< Cached username #VALUE_PAIR from request #RADIUS_PACKET.
226 	VALUE_PAIR		*password;	//!< Cached password #VALUE_PAIR from request #RADIUS_PACKET.
227 
228 	RADIUS_PACKET		*reply;		//!< Outgoing response.
229 
230 	VALUE_PAIR		*config;	//!< #VALUE_PAIR (s) used to set per request parameters
231 						//!< for modules and the server core at runtime.
232 
233 	TALLOC_CTX		*state_ctx;	//!< for request->state
234 	VALUE_PAIR		*state;		//!< #VALUE_PAIR (s) available over the lifetime of the authentication
235 						//!< attempt. Useful where the attempt involves a sequence of
236 						//!< many request/challenge packets, like OTP, and EAP.
237 
238 #ifdef WITH_PROXY
239 	rad_listen_t		*proxy_listener;//!< Listener for outgoing requests.
240 	RADIUS_PACKET		*proxy;		//!< Outgoing request to proxy server.
241 	RADIUS_PACKET		*proxy_reply;	//!< Incoming response from proxy server.
242 
243 	home_server_t	       	*home_server;
244 	home_pool_t		*home_pool;	//!< For dynamic failover
245 #endif
246 
247 	fr_request_process_t	process;	//!< The function to call to move the request through the state machine.
248 
249 	struct timeval		response_delay;	//!< How long to wait before sending Access-Rejects.
250 	fr_state_action_t	timer_action;	//!< What action to perform when the timer event fires.
251 	fr_event_t		*ev;		//!< Event in event loop tied to this request.
252 
253 	RAD_REQUEST_FUNP	handle;		//!< The function to call to move the request through the
254 						//!< various server configuration sections.
255 	rlm_rcode_t		rcode;		//!< Last rcode returned by a module
256 	char const		*module;	//!< Module the request is currently being processed by.
257 	char const		*component; 	//!< Section the request is in.
258 
259 	int			delay;
260 
261 	rad_master_state_t	master_state;	//!< Set by the master thread to signal the child that's currently
262 						//!< working with the request, to do something.
263 	rad_child_state_t	child_state;
264 
265 #ifdef HAVE_PTHREAD_H
266 	pthread_t    		child_pid;	//!< Current thread handling the request.
267 #endif
268 
269 	main_config_t		*root;		//!< Pointer to the main config hack to try and deal with hup.
270 
271 
272 	int			simul_max;	//!< Maximum number of concurrent sessions for this user.
273 #ifdef WITH_SESSION_MGMT
274 	int			simul_count;	//!< The current number of sessions for this user.
275 	int			simul_mpp; 	//!< WEIRD: 1 is false, 2 is true.
276 #endif
277 
278 	RAD_LISTEN_TYPE		priority;
279 
280 	bool			in_request_hash;
281 #ifdef WITH_PROXY
282 	bool			in_proxy_hash;
283 
284 	uint32_t		num_proxied_requests;	//!< How many times this request was proxied.
285 							//!< Retransmissions are driven by requests from the NAS.
286 	uint32_t		num_proxied_responses;
287 #endif
288 
289 	char const		*server;
290 	REQUEST			*parent;
291 
292 	struct {
293 		radlog_func_t	func;		//!< Function to call to output log messages about this
294 						//!< request.
295 
296 		log_lvl_t	lvl;		//!< Controls the verbosity of debug statements regarding
297 						//!< the request.
298 
299 		uint8_t		indent;		//!< By how much to indent log messages. uin8_t so it's obvious
300 						//!< when a request has been exdented too much.
301 	} log;
302 
303 	uint32_t		options;	//!< mainly for proxying EAP-MSCHAPv2.
304 
305 #ifdef WITH_COA
306 	REQUEST			*coa;		//!< CoA request originated by this request.
307 	uint32_t		num_coa_requests;//!< Counter for number of requests sent including
308 						//!< retransmits.
309 #endif
310 };				/* REQUEST typedef */
311 
312 #define RAD_REQUEST_LVL_NONE	(0)		//!< No debug messages should be printed.
313 #define RAD_REQUEST_LVL_DEBUG	(1)
314 #define RAD_REQUEST_LVL_DEBUG2	(2)
315 #define RAD_REQUEST_LVL_DEBUG3	(3)
316 #define RAD_REQUEST_LVL_DEBUG4	(4)
317 
318 #define RAD_REQUEST_OPTION_COA		(1 << 0)
319 #define RAD_REQUEST_OPTION_CTX 		(1 << 1)
320 #define RAD_REQUEST_OPTION_CANCELLED	(1 << 2)
321 
322 #define SECONDS_PER_DAY		86400
323 #define MAX_REQUEST_TIME	30
324 #define CLEANUP_DELAY		5
325 #define MAX_REQUESTS		256
326 #define RETRY_DELAY		5
327 #define RETRY_COUNT		3
328 #define DEAD_TIME		120
329 #define EXEC_TIMEOUT		10
330 
331 /* for paircompare_register */
332 typedef int (*RAD_COMPARE_FUNC)(void *instance, REQUEST *,VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR **);
333 
334 typedef enum request_fail {
335 	REQUEST_FAIL_UNKNOWN = 0,
336 	REQUEST_FAIL_NO_THREADS,	//!< No threads to handle it.
337 	REQUEST_FAIL_DECODE,		//!< Rad_decode didn't like it.
338 	REQUEST_FAIL_PROXY,		//!< Call to proxy modules failed.
339 	REQUEST_FAIL_PROXY_SEND,	//!< Proxy_send didn't like it.
340 	REQUEST_FAIL_NO_RESPONSE,	//!< We weren't told to respond, so we reject.
341 	REQUEST_FAIL_HOME_SERVER,	//!< The home server didn't respond.
342 	REQUEST_FAIL_HOME_SERVER2,	//!< Another case of the above.
343 	REQUEST_FAIL_HOME_SERVER3,	//!< Another case of the above.
344 	REQUEST_FAIL_NORMAL_REJECT,	//!< Authentication failure.
345 	REQUEST_FAIL_SERVER_TIMEOUT	//!< The server took too long to process the request.
346 } request_fail_t;
347 
348 /*
349  *	Global variables.
350  *
351  *	We really shouldn't have this many.
352  */
353 extern log_lvl_t	rad_debug_lvl;
354 extern char const	*radacct_dir;
355 extern char const	*radlog_dir;
356 extern char const	*radlib_dir;
357 extern bool		log_stripped_names;
358 extern char const	*radiusd_version;
359 extern char const	*radiusd_version_short;
360 void			radius_signal_self(int flag);
361 
362 typedef enum {
363 	RADIUS_SIGNAL_SELF_NONE		= (0),
364 	RADIUS_SIGNAL_SELF_HUP		= (1 << 0),
365 	RADIUS_SIGNAL_SELF_TERM		= (1 << 1),
366 	RADIUS_SIGNAL_SELF_EXIT		= (1 << 2),
367 	RADIUS_SIGNAL_SELF_DETAIL	= (1 << 3),
368 	RADIUS_SIGNAL_SELF_NEW_FD	= (1 << 4),
369 	RADIUS_SIGNAL_SELF_MAX		= (1 << 5)
370 } radius_signal_t;
371 /*
372  *	Function prototypes.
373  */
374 
375 /* acct.c */
376 int		rad_accounting(REQUEST *);
377 
378 int		rad_coa_recv(REQUEST *request);
379 
380 /* session.c */
381 int		rad_check_ts(fr_ipaddr_t const *nas_addr, uint32_t nas_port, char const *user, char const *sessionid);
382 int		session_zap(REQUEST *request, fr_ipaddr_t const *nas_addr,
383 			    uint32_t nas_port, char const *user,
384 			    char const *sessionid, uint32_t cliaddr,
385 			    char proto, int session_time);
386 
387 /* radiusd.c */
388 #undef debug_pair
389 void		debug_pair(VALUE_PAIR *);
390 void		rdebug_pair(log_lvl_t level, REQUEST *, VALUE_PAIR *, char const *);
391 void 		rdebug_pair_list(log_lvl_t level, REQUEST *, VALUE_PAIR *, char const *);
392 void		rdebug_proto_pair_list(log_lvl_t level, REQUEST *, VALUE_PAIR *);
393 int		log_err (char *);
394 
395 /* util.c */
396 #define MEM(x) if (!(x)) { ERROR("%s[%u] OUT OF MEMORY", __FILE__, __LINE__); _fr_exit_now(__FILE__, __LINE__, 1); }
397 void (*reset_signal(int signo, void (*func)(int)))(int);
398 int		rad_mkdir(char *directory, mode_t mode, uid_t uid, gid_t gid);
399 size_t		rad_filename_make_safe(UNUSED REQUEST *request, char *out, size_t outlen,
400 				       char const *in, UNUSED void *arg);
401 size_t		rad_filename_escape(UNUSED REQUEST *request, char *out, size_t outlen,
402 				    char const *in, UNUSED void *arg);
403 ssize_t		rad_filename_unescape(char *out, size_t outlen, char const *in, size_t inlen);
404 void		*rad_malloc(size_t size); /* calls exit(1) on error! */
405 void		rad_const_free(void const *ptr);
406 REQUEST		*request_alloc(TALLOC_CTX *ctx);
407 REQUEST		*request_alloc_fake(REQUEST *oldreq);
408 REQUEST		*request_alloc_coa(REQUEST *request);
409 int		request_data_add(REQUEST *request,
410 				 void *unique_ptr, int unique_int,
411 				 void *opaque, bool free_opaque);
412 void		*request_data_get(REQUEST *request,
413 				  void *unique_ptr, int unique_int);
414 void		*request_data_reference(REQUEST *request,
415 				  void *unique_ptr, int unique_int);
416 int		rad_copy_string(char *dst, char const *src);
417 int		rad_copy_string_bare(char *dst, char const *src);
418 int		rad_copy_variable(char *dst, char const *from);
419 uint32_t	rad_pps(uint32_t *past, uint32_t *present, time_t *then, struct timeval *now);
420 int		rad_expand_xlat(REQUEST *request, char const *cmd,
421 				int max_argc, char const *argv[], bool can_fail,
422 				size_t argv_buflen, char *argv_buf);
423 void		rad_tv_sub(struct timeval const *end, struct timeval const *start, struct timeval *elapsed);
424 
425 void		verify_request(char const *file, int line, REQUEST *request);	/* only for special debug builds */
426 void		rad_mode_to_str(char out[10], mode_t mode);
427 void		rad_mode_to_oct(char out[5], mode_t mode);
428 int		rad_getpwuid(TALLOC_CTX *ctx, struct passwd **out, uid_t uid);
429 int		rad_getpwnam(TALLOC_CTX *ctx, struct passwd **out, char const *name);
430 int		rad_getgrgid(TALLOC_CTX *ctx, struct group **out, gid_t gid);
431 int		rad_getgrnam(TALLOC_CTX *ctx, struct group **out, char const *name);
432 int		rad_getgid(TALLOC_CTX *ctx, gid_t *out, char const *name);
433 int		rad_prints_uid(TALLOC_CTX *ctx, char *out, size_t outlen, uid_t uid);
434 int		rad_prints_gid(TALLOC_CTX *ctx, char *out, size_t outlen, gid_t gid);
435 int		rad_seuid(uid_t uid);
436 int		rad_segid(gid_t gid);
437 
438 void		rad_suid_set_down_uid(uid_t uid);
439 void		rad_suid_down(void);
440 void		rad_suid_up(void);
441 void		rad_suid_down_permanent(void);
442 /* regex.c */
443 
444 #ifdef HAVE_REGEX
445 /*
446  *	Increasing this is essentially free
447  *	It just increases memory usage. 12-16 bytes for each additional subcapture.
448  */
449 #  define REQUEST_MAX_REGEX 32
450 
451 void	regex_sub_to_request(REQUEST *request, regex_t **preg, char const *value,
452 			     size_t len, regmatch_t rxmatch[], size_t nmatch);
453 
454 int	regex_request_to_sub(TALLOC_CTX *ctx, char **out, REQUEST *request, uint32_t num);
455 
456 /*
457  *	Named capture groups only supported by PCRE.
458  */
459 #  ifdef HAVE_PCRE
460 int	regex_request_to_sub_named(TALLOC_CTX *ctx, char **out, REQUEST *request, char const *name);
461 #  endif
462 #endif
463 
464 /* files.c */
465 int		pairlist_read(TALLOC_CTX *ctx, char const *file, PAIR_LIST **list, int complain);
466 void		pairlist_free(PAIR_LIST **);
467 
468 /* version.c */
469 int		rad_check_lib_magic(uint64_t magic);
470 int 		ssl_check_consistency(void);
471 char const	*ssl_version_by_num(uint32_t version);
472 char const	*ssl_version_num(void);
473 char const	*ssl_version_range(uint32_t low, uint32_t high);
474 char const	*ssl_version(void);
475 int		version_add_feature(CONF_SECTION *cs, char const *name, bool enabled);
476 int		version_add_number(CONF_SECTION *cs, char const *name, char const *version);
477 void		version_init_features(CONF_SECTION *cs);
478 void		version_init_numbers(CONF_SECTION *cs);
479 void		version_print(void);
480 
481 /* auth.c */
482 char	*auth_name(char *buf, size_t buflen, REQUEST *request, bool do_cli);
483 int		rad_authenticate (REQUEST *);
484 int		rad_postauth(REQUEST *);
485 int		rad_virtual_server(REQUEST *);
486 
487 /* exec.c */
488 pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait,
489 			   int *input_fd, int *output_fd,
490 			   VALUE_PAIR *input_pairs, bool shell_escape);
491 int radius_readfrom_program(int fd, pid_t pid, int timeout,
492 			    char *answer, int left);
493 int radius_exec_program(TALLOC_CTX *ctx, char *out, size_t outlen, VALUE_PAIR **output_pairs,
494 			REQUEST *request, char const *cmd, VALUE_PAIR *input_pairs,
495 			bool exec_wait, bool shell_escape, int timeout) CC_HINT(nonnull (5, 6));
496 void exec_trigger(REQUEST *request, CONF_SECTION *cs, char const *name, int quench)
497      CC_HINT(nonnull (3));
498 
499 /* valuepair.c */
500 int paircompare_register_byname(char const *name, DICT_ATTR const *from,
501 				bool first_only, RAD_COMPARE_FUNC func, void *instance);
502 int paircompare_register(DICT_ATTR const *attribute, DICT_ATTR const *from,
503 			 bool first_only, RAD_COMPARE_FUNC func, void *instance);
504 void		paircompare_unregister(DICT_ATTR const *attr, RAD_COMPARE_FUNC func);
505 void		paircompare_unregister_instance(void *instance);
506 int		paircompare(REQUEST *request, VALUE_PAIR *req_list,
507 			    VALUE_PAIR *check, VALUE_PAIR **rep_list);
508 vp_tmpl_t	*xlat_to_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_t *xlat);
509 xlat_exp_t		*xlat_from_tmpl_attr(TALLOC_CTX *ctx, vp_tmpl_t *vpt);
510 int		radius_xlat_do(REQUEST *request, VALUE_PAIR *vp);
511 int radius_compare_vps(REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *vp);
512 int radius_callback_compare(REQUEST *request, VALUE_PAIR *req,
513 			    VALUE_PAIR *check, VALUE_PAIR *check_pairs,
514 			    VALUE_PAIR **reply_pairs);
515 int radius_find_compare(DICT_ATTR const *attribute);
516 VALUE_PAIR	*radius_pair_create(TALLOC_CTX *ctx, VALUE_PAIR **vps, unsigned int attribute, unsigned int vendor);
517 
518 void module_failure_msg(REQUEST *request, char const *fmt, ...) CC_HINT(format (printf, 2, 3));
519 void vmodule_failure_msg(REQUEST *request, char const *fmt, va_list ap) CC_HINT(format (printf, 2, 0));
520 
521 int radius_get_vp(VALUE_PAIR **out, REQUEST *request, char const *name);
522 int radius_copy_vp(TALLOC_CTX *ctx, VALUE_PAIR **out, REQUEST *request, char const *name);
523 
524 
525 /*
526  *	Less code == fewer bugs
527  *
528  * @param _a attribute
529  * @param _b value
530  * @param _c op
531  */
532 #define pair_make_request(_a, _b, _c) fr_pair_make(request->packet, &request->packet->vps, _a, _b, _c)
533 #define pair_make_reply(_a, _b, _c) fr_pair_make(request->reply, &request->reply->vps, _a, _b, _c)
534 #define pair_make_config(_a, _b, _c) fr_pair_make(request, &request->config, _a, _b, _c)
535 
536 /* threads.c */
537 int	thread_pool_init(CONF_SECTION *cs, bool *spawn_flag);
538 void	thread_pool_stop(void);
539 int	thread_pool_addrequest(REQUEST *, RAD_REQUEST_FUNP);
540 pid_t	rad_fork(void);
541 pid_t	rad_waitpid(pid_t pid, int *status);
542 int	total_active_threads(void);
543 void	thread_pool_lock(void);
544 void	thread_pool_unlock(void);
545 void	thread_pool_queue_stats(int array[RAD_LISTEN_MAX], int pps[2]);
546 
547 #ifndef HAVE_PTHREAD_H
548 #  define rad_fork(n) fork()
549 #  define rad_waitpid(a,b) waitpid(a,b, 0)
550 #endif
551 
552 /* main_config.c */
553 /* Define a global config structure */
554 extern bool			log_dates_utc;
555 extern main_config_t		main_config;
556 extern bool			event_loop_started;
557 
558 void set_radius_dir(TALLOC_CTX *ctx, char const *path);
559 char const *get_radius_dir(void);
560 int main_config_init(void);
561 int main_config_free(void);
562 void main_config_hup(void);
563 void hup_logfile(void);
564 
565 /* listen.c */
566 void listen_free(rad_listen_t **head);
567 int listen_init(CONF_SECTION *cs, rad_listen_t **head, bool spawn_flag);
568 rad_listen_t *proxy_new_listener(TALLOC_CTX *ctx, home_server_t *home, uint16_t src_port);
569 RADCLIENT *client_listener_find(rad_listen_t *listener, fr_ipaddr_t const *ipaddr, uint16_t src_port);
570 
571 #ifdef WITH_STATS
572 RADCLIENT_LIST *listener_find_client_list(fr_ipaddr_t const *ipaddr, uint16_t port, int proto);
573 #endif
574 rad_listen_t *listener_find_byipaddr(fr_ipaddr_t const *ipaddr, uint16_t port, int proto);
575 int rad_status_server(REQUEST *request);
576 
577 /* event.c */
578 typedef enum event_corral_t {
579 	EVENT_CORRAL_MAIN = 0,	//!< Always main thread event list
580 	EVENT_CORRAL_AUX	//!< Maybe main thread or one shared by modules
581 } event_corral_t;
582 
583 fr_event_list_t *radius_event_list_corral(event_corral_t hint);
584 int radius_event_init(TALLOC_CTX *ctx);
585 int radius_event_start(CONF_SECTION *cs, bool spawn_flag);
586 void radius_event_free(void);
587 int radius_event_process(void);
588 void radius_update_listener(rad_listen_t *listener);
589 void revive_home_server(void *ctx);
590 void mark_home_server_dead(home_server_t *home, struct timeval *when, bool down);
591 
592 /* evaluate.c */
593 typedef struct fr_cond_t fr_cond_t;
594 int radius_evaluate_tmpl(REQUEST *request, int modreturn, int depth,
595 			 vp_tmpl_t const *vpt);
596 int radius_evaluate_map(REQUEST *request, int modreturn, int depth,
597 			fr_cond_t const *c);
598 int radius_evaluate_cond(REQUEST *request, int modreturn, int depth,
599 			 fr_cond_t const *c);
600 void radius_pairmove(REQUEST *request, VALUE_PAIR **to, VALUE_PAIR *from, bool do_xlat) CC_HINT(nonnull);
601 
602 #ifdef WITH_TLS
603 /*
604  *	For run-time patching of which function handles which socket.
605  */
606 int dual_tls_recv(rad_listen_t *listener);
607 int dual_tls_send(rad_listen_t *listener, REQUEST *request);
608 int proxy_tls_recv(rad_listen_t *listener);
609 int proxy_tls_send(rad_listen_t *listener, REQUEST *request);
610 #ifdef WITH_COA_TUNNEL
611 int proxy_tls_send_reply(rad_listen_t *listener, REQUEST *request);
612 int dual_tls_send_coa_request(rad_listen_t *listener, REQUEST *request);
613 void listen_coa_free(void);
614 void listen_coa_add(rad_listen_t *listener, char const *key);
615 int listen_coa_find(REQUEST *request, char const *key);
616 #endif
617 #endif
618 
619 /*
620  *	For radmin over TCP.
621  */
622 #define PW_RADMIN_PORT 18120
623 
624 #ifdef __cplusplus
625 }
626 #endif
627 
628 #endif /*RADIUSD_H*/
629