d6045d747a86e4e04d80865cedc0aec868d52a0f
[freeradius.git] / src / include / radiusd.h
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$
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$")
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 #include <freeradius-devel/map.h>
36
37 typedef struct rad_request REQUEST;
38
39 #include <freeradius-devel/log.h>
40
41 #ifdef HAVE_PTHREAD_H
42 #  include <pthread.h>
43 #else
44 #  include <sys/wait.h>
45 #endif
46
47 #ifndef NDEBUG
48 #  define REQUEST_MAGIC (0xdeadbeef)
49 #endif
50
51 /*
52  *      WITH_VMPS is handled by src/include/features.h
53  */
54 #ifdef WITHOUT_VMPS
55 #  undef WITH_VMPS
56 #endif
57
58 #ifdef WITH_TLS
59 #  include <freeradius-devel/tls.h>
60 #endif
61
62 #include <freeradius-devel/stats.h>
63 #include <freeradius-devel/realms.h>
64
65 #ifdef __cplusplus
66 extern "C" {
67 #endif
68
69 /*
70  *      See util.c
71  */
72 typedef struct request_data_t request_data_t;
73
74 typedef struct radclient {
75         fr_ipaddr_t             ipaddr;
76         fr_ipaddr_t             src_ipaddr;
77         uint32_t                prefix;
78         char const              *longname;
79         char const              *secret;
80         char const              *shortname;
81         bool                    message_authenticator;
82         char const              *nas_type;
83         char const              *login;
84         char const              *password;
85         char const              *server;
86         int                     number; /* internal use only */
87         CONF_SECTION const      *cs;
88 #ifdef WITH_STATS
89         fr_stats_t              auth;
90 #ifdef WITH_ACCOUNTING
91         fr_stats_t              acct;
92 #endif
93 #ifdef WITH_COA
94         fr_stats_t              coa;
95         fr_stats_t              dsc;
96 #endif
97 #endif
98
99         struct timeval          response_window;
100
101         int                     proto;
102 #ifdef WITH_TCP
103         fr_socket_limit_t       limit;
104 #endif
105 #ifdef WITH_TLS
106         bool                    tls_required;
107 #endif
108
109 #ifdef WITH_DYNAMIC_CLIENTS
110         uint32_t                lifetime;
111         uint32_t                dynamic; /* was dynamically defined */
112         time_t                  created;
113         time_t                  last_new_client;
114         char const              *client_server;
115         bool                    rate_limit;
116 #endif
117
118 #ifdef WITH_COA
119         char const              *coa_name;
120         home_server_t           *coa_server;
121         home_pool_t             *coa_pool;
122 #endif
123 } RADCLIENT;
124
125 /*
126  *      Types of listeners.
127  *
128  *      Ordered by priority!
129  */
130 typedef enum RAD_LISTEN_TYPE {
131         RAD_LISTEN_NONE = 0,
132 #ifdef WITH_PROXY
133         RAD_LISTEN_PROXY,
134 #endif
135         RAD_LISTEN_AUTH,
136 #ifdef WITH_ACCOUNTING
137         RAD_LISTEN_ACCT,
138 #endif
139 #ifdef WITH_DETAIL
140         RAD_LISTEN_DETAIL,
141 #endif
142 #ifdef WITH_VMPS
143         RAD_LISTEN_VQP,
144 #endif
145 #ifdef WITH_DHCP
146         RAD_LISTEN_DHCP,
147 #endif
148 #ifdef WITH_COMMAND_SOCKET
149         RAD_LISTEN_COMMAND,
150 #endif
151 #ifdef WITH_COA
152         RAD_LISTEN_COA,
153 #endif
154         RAD_LISTEN_MAX
155 } RAD_LISTEN_TYPE;
156
157 /** Return codes indicating the result of the module call
158  *
159  * All module functions must return one of the codes listed below (apart from
160  * RLM_MODULE_NUMCODES, which is used to check for validity).
161  */
162 typedef enum rlm_rcodes {
163         RLM_MODULE_REJECT = 0,  //!< Immediately reject the request.
164         RLM_MODULE_FAIL,        //!< Module failed, don't reply.
165         RLM_MODULE_OK,          //!< The module is OK, continue.
166         RLM_MODULE_HANDLED,     //!< The module handled the request, so stop.
167         RLM_MODULE_INVALID,     //!< The module considers the request invalid.
168         RLM_MODULE_USERLOCK,    //!< Reject the request (user is locked out).
169         RLM_MODULE_NOTFOUND,    //!< User not found.
170         RLM_MODULE_NOOP,        //!< Module succeeded without doing anything.
171         RLM_MODULE_UPDATED,     //!< OK (pairs modified).
172         RLM_MODULE_NUMCODES,    //!< How many valid return codes there are.
173         RLM_MODULE_UNKNOWN      //!< Error resolving rcode (should not be
174                                 //!< returned by modules).
175 } rlm_rcode_t;
176 extern const FR_NAME_NUMBER modreturn_table[];
177
178 /*
179  *      For listening on multiple IP's and ports.
180  */
181 typedef struct rad_listen_t rad_listen_t;
182
183 typedef         void (*fr_request_process_t)(REQUEST *, int);
184 /*
185  *  Function handler for requests.
186  */
187 typedef         int (*RAD_REQUEST_FUNP)(REQUEST *);
188
189 #define REQUEST_DATA_REGEX (0xadbeef00)
190 #define REQUEST_MAX_REGEX (8)
191
192 #if defined(WITH_VERIFY_PTR)
193 #define VERIFY_REQUEST(_x) (void) talloc_get_type_abort(_x, REQUEST)
194 #else
195 #define VERIFY_REQUEST(_x)
196 #endif
197
198 typedef enum {
199         REQUEST_ACTIVE = 1,
200         REQUEST_STOP_PROCESSING,
201         REQUEST_COUNTED
202 } rad_master_state_t;
203 #define REQUEST_MASTER_NUM_STATES (REQUEST_COUNTED + 1)
204
205 typedef enum {
206         REQUEST_QUEUED = 1,
207         REQUEST_RUNNING,
208         REQUEST_PROXIED,
209         REQUEST_RESPONSE_DELAY,
210         REQUEST_CLEANUP_DELAY,
211         REQUEST_DONE
212 } rad_child_state_t;
213 #define REQUEST_CHILD_NUM_STATES (REQUEST_DONE + 1)
214
215 struct rad_request {
216 #ifndef NDEBUG
217         uint32_t                magic;          //!< Magic number used to detect memory corruption,
218                                                 //!< or request structs that have not been properly initialised.
219 #endif
220         RADIUS_PACKET           *packet;        //!< Incoming request.
221 #ifdef WITH_PROXY
222         RADIUS_PACKET           *proxy;         //!< Outgoing request.
223 #endif
224         RADIUS_PACKET           *reply;         //!< Outgoing response.
225 #ifdef WITH_PROXY
226         RADIUS_PACKET           *proxy_reply;   //!< Incoming response.
227 #endif
228         VALUE_PAIR              *config_items;  //!< VALUE_PAIRs used to set per request parameters
229                                                 //!< for modules and the server core at runtime.
230         VALUE_PAIR              *username;      //!< Cached username VALUE_PAIR.
231         VALUE_PAIR              *password;      //!< Cached password VALUE_PAIR.
232
233         fr_request_process_t    process;        //!< The function to call to move the request through the state machine.
234
235         RAD_REQUEST_FUNP        handle;         //!< The function to call to move the request through the
236                                                 //!< various server configuration sections.
237
238         struct main_config_t    *root;          //!< Pointer to the main config hack to try and deal with hup.
239
240         request_data_t          *data;          //!< Request metadata.
241
242         RADCLIENT               *client;        //!< The client that originally sent us the request.
243
244 #ifdef HAVE_PTHREAD_H
245         pthread_t               child_pid;      //!< Current thread handling the request.
246 #endif
247         time_t                  timestamp;      //!< When the request was received.
248         unsigned int            number;         //!< Monotonically increasing request number. Reset on server restart.
249
250         rad_listen_t            *listener;      //!< The listener that received the request.
251 #ifdef WITH_PROXY
252         rad_listen_t            *proxy_listener;//!< Listener for outgoing requests.
253 #endif
254
255         rlm_rcode_t             rcode;          //!< Last rcode returned by a module
256
257         int                     simul_max;      //!< Maximum number of concurrent sessions for this user.
258 #ifdef WITH_SESSION_MGMT
259         int                     simul_count;    //!< The current number of sessions for this user.
260         int                     simul_mpp;      //!< WEIRD: 1 is false, 2 is true.
261 #endif
262
263         char const              *module;        //!< Module the request is currently being processed by.
264         char const              *component;     //!< Section the request is in.
265
266         int                     delay;
267
268         rad_master_state_t      master_state;
269         rad_child_state_t       child_state;
270         RAD_LISTEN_TYPE         priority;
271
272         int                     response_delay;
273         int                     timer_action;
274         fr_event_t              *ev;
275
276         bool                    in_request_hash;
277 #ifdef WITH_PROXY
278         bool                    in_proxy_hash;
279
280         home_server_t           *home_server;
281         home_pool_t             *home_pool;     //!< For dynamic failover
282
283         struct timeval          proxy_retransmit;
284
285         uint32_t                num_proxied_requests;
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_debug_t     lvl;            //!< Request options, currently just holds the debug level or
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 #ifdef WITH_COA
304         REQUEST                 *coa;           //!< CoA request originated by this request.
305         uint32_t                num_coa_requests;//!< Counter for number of requests sent including
306                                                 //!< retransmits.
307 #endif
308 };                              /* REQUEST typedef */
309
310 #define RAD_REQUEST_OPTION_NONE         (0)
311 #define RAD_REQUEST_OPTION_DEBUG        (1)
312 #define RAD_REQUEST_OPTION_DEBUG2       (2)
313 #define RAD_REQUEST_OPTION_DEBUG3       (3)
314 #define RAD_REQUEST_OPTION_DEBUG4       (4)
315
316 typedef struct radclient_list RADCLIENT_LIST;
317
318 typedef int (*rad_listen_recv_t)(rad_listen_t *);
319 typedef int (*rad_listen_send_t)(rad_listen_t *, REQUEST *);
320 typedef int (*rad_listen_print_t)(rad_listen_t const *, char *, size_t);
321 typedef int (*rad_listen_encode_t)(rad_listen_t *, REQUEST *);
322 typedef int (*rad_listen_decode_t)(rad_listen_t *, REQUEST *);
323
324 struct rad_listen_t {
325         struct rad_listen_t *next; /* should be rbtree stuff */
326
327         /*
328          *      For normal sockets.
329          */
330         RAD_LISTEN_TYPE type;
331         int             fd;
332         char const      *server;
333         int             status;
334 #ifdef WITH_TCP
335         int             count;
336         bool            dual;
337 #endif
338         bool            nodup;
339         bool            synchronous;
340         uint32_t        workers;
341
342 #ifdef WITH_TLS
343         fr_tls_server_conf_t *tls;
344 #endif
345
346         rad_listen_recv_t recv;
347         rad_listen_send_t send;
348         rad_listen_encode_t encode;
349         rad_listen_decode_t decode;
350         rad_listen_print_t print;
351
352         CONF_SECTION const *cs;
353         void            *data;
354
355 #ifdef WITH_STATS
356         fr_stats_t      stats;
357 #endif
358 };
359
360 /*
361  *      This shouldn't really be exposed...
362  */
363 typedef struct listen_socket_t {
364         /*
365          *      For normal sockets.
366          */
367         fr_ipaddr_t     my_ipaddr;
368         uint16_t        my_port;
369
370         char const      *interface;
371 #ifdef SO_BROADCAST
372         int             broadcast;
373 #endif
374         time_t          rate_time;
375         uint32_t        rate_pps_old;
376         uint32_t        rate_pps_now;
377         uint32_t        max_rate;
378
379         /* for outgoing sockets */
380         home_server_t   *home;
381         fr_ipaddr_t     other_ipaddr;
382         uint16_t        other_port;
383
384         int             proto;
385
386 #ifdef WITH_TCP
387         /* for a proxy connecting to home servers */
388         time_t          last_packet;
389         time_t          opened;
390         fr_event_t      *ev;
391
392         fr_socket_limit_t limit;
393
394         struct listen_socket_t *parent;
395         RADCLIENT       *client;
396
397         RADIUS_PACKET   *packet; /* for reading partial packets */
398 #endif
399
400 #ifdef WITH_TLS
401         tls_session_t   *ssn;
402         REQUEST         *request; /* horrible hacks */
403         VALUE_PAIR      *certs;
404         pthread_mutex_t mutex;
405         uint8_t         *data;
406         size_t          partial;
407 #endif
408
409         RADCLIENT_LIST  *clients;
410 } listen_socket_t;
411
412 #define RAD_LISTEN_STATUS_INIT       (0)
413 #define RAD_LISTEN_STATUS_KNOWN      (1)
414 #define RAD_LISTEN_STATUS_EOL        (2)
415 #define RAD_LISTEN_STATUS_REMOVE_NOW (3)
416
417 typedef struct main_config_t {
418         struct main_config *next;
419         fr_ipaddr_t     myip;   /* from the command-line only */
420         uint16_t        port;   /* from the command-line only */
421         bool            log_auth;
422         bool            log_auth_badpass;
423         bool            log_auth_goodpass;
424         bool            allow_core_dumps;
425         uint32_t        debug_level;
426         bool            daemonize;
427 #ifdef WITH_PROXY
428         bool            proxy_requests;
429 #endif
430         uint32_t        reject_delay;
431         bool            status_server;
432         char const      *allow_vulnerable_openssl;
433
434         uint32_t        max_request_time;
435         uint32_t        cleanup_delay;
436         uint32_t        max_requests;
437         char const      *log_file;
438         char const      *dictionary_dir;
439         char const      *checkrad;
440         char const      *pid_file;
441         rad_listen_t    *listen;
442         int             syslog_facility;
443         CONF_SECTION    *config;
444         char const      *name;
445         char const      *auth_badpass_msg;
446         char const      *auth_goodpass_msg;
447         bool            debug_memory;
448         bool            memory_report;
449         char const      *panic_action;
450         char const      *denied_msg;
451         struct timeval  min_response_window; /* for home servers */
452 } MAIN_CONFIG_T;
453
454 #define SECONDS_PER_DAY         86400
455 #define MAX_REQUEST_TIME        30
456 #define CLEANUP_DELAY           5
457 #define MAX_REQUESTS            256
458 #define RETRY_DELAY             5
459 #define RETRY_COUNT             3
460 #define DEAD_TIME               120
461 #define EXEC_TIMEOUT            10
462
463 /* for paircompare_register */
464 typedef int (*RAD_COMPARE_FUNC)(void *instance, REQUEST *,VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR **);
465
466 typedef enum request_fail {
467         REQUEST_FAIL_UNKNOWN = 0,
468         REQUEST_FAIL_NO_THREADS,        //!< No threads to handle it.
469         REQUEST_FAIL_DECODE,            //!< Rad_decode didn't like it.
470         REQUEST_FAIL_PROXY,             //!< Call to proxy modules failed.
471         REQUEST_FAIL_PROXY_SEND,        //!< Proxy_send didn't like it.
472         REQUEST_FAIL_NO_RESPONSE,       //!< We weren't told to respond, so we reject.
473         REQUEST_FAIL_HOME_SERVER,       //!< The home server didn't respond.
474         REQUEST_FAIL_HOME_SERVER2,      //!< Another case of the above.
475         REQUEST_FAIL_HOME_SERVER3,      //!< Another case of the above.
476         REQUEST_FAIL_NORMAL_REJECT,     //!< Authentication failure.
477         REQUEST_FAIL_SERVER_TIMEOUT     //!< The server took too long to process the request.
478 } request_fail_t;
479
480 /*
481  *      Global variables.
482  *
483  *      We really shouldn't have this many.
484  */
485 extern char const       *progname;
486 extern log_debug_t      debug_flag;
487 extern char const       *radacct_dir;
488 extern char const       *radlog_dir;
489 extern char const       *radlib_dir;
490 extern char const       *radius_libdir;
491 extern uint32_t         expiration_seconds;
492 extern bool             log_stripped_names;
493 extern bool             log_auth_detail;
494 extern char const       *radiusd_version;
495 void                    radius_signal_self(int flag);
496
497 typedef enum {
498         RADIUS_SIGNAL_SELF_NONE         = (0),
499         RADIUS_SIGNAL_SELF_HUP          = (1 << 0),
500         RADIUS_SIGNAL_SELF_TERM         = (1 << 1),
501         RADIUS_SIGNAL_SELF_EXIT         = (1 << 2),
502         RADIUS_SIGNAL_SELF_DETAIL       = (1 << 3),
503         RADIUS_SIGNAL_SELF_NEW_FD       = (1 << 4),
504         RADIUS_SIGNAL_SELF_MAX          = (1 << 5)
505 } radius_signal_t;
506 /*
507  *      Function prototypes.
508  */
509
510 /* acct.c */
511 int             rad_accounting(REQUEST *);
512
513 /* session.c */
514 int             rad_check_ts(uint32_t nasaddr, uint32_t nas_port, char const *user, char const *sessionid);
515 int             session_zap(REQUEST *request, uint32_t nasaddr,
516                             uint32_t nas_port, char const *user,
517                             char const *sessionid, uint32_t cliaddr,
518                             char proto, int session_time);
519
520 /* radiusd.c */
521 #undef debug_pair
522 void            debug_pair(VALUE_PAIR *);
523 void            debug_pair_list(VALUE_PAIR *);
524 void            rdebug_pair_list(int, REQUEST *, VALUE_PAIR *);
525 int             log_err (char *);
526
527 /* util.c */
528 #define MEM(x) if (!(x)) { ERROR("Out of memory"); exit(1); }
529 void (*reset_signal(int signo, void (*func)(int)))(int);
530 void            request_free(REQUEST **request);
531 int                     request_opaque_free(REQUEST *request);
532 int             rad_mkdir(char *directory, mode_t mode);
533 void            *rad_malloc(size_t size); /* calls exit(1) on error! */
534 void            rad_const_free(void const *ptr);
535 REQUEST         *request_alloc(TALLOC_CTX *ctx);
536 REQUEST         *request_alloc_fake(REQUEST *oldreq);
537 REQUEST         *request_alloc_coa(REQUEST *request);
538 int             request_data_add(REQUEST *request,
539                                  void *unique_ptr, int unique_int,
540                                  void *opaque, bool free_opaque);
541 void            *request_data_get(REQUEST *request,
542                                   void *unique_ptr, int unique_int);
543 void            *request_data_reference(REQUEST *request,
544                                   void *unique_ptr, int unique_int);
545 int             rad_copy_string(char *dst, char const *src);
546 int             rad_copy_string_bare(char *dst, char const *src);
547 int             rad_copy_variable(char *dst, char const *from);
548 uint32_t        rad_pps(uint32_t *past, uint32_t *present, time_t *then, struct timeval *now);
549 int             rad_expand_xlat(REQUEST *request, char const *cmd,
550                                 int max_argc, char *argv[], bool can_fail,
551                                 size_t argv_buflen, char *argv_buf);
552 void            rad_regcapture(REQUEST *request, int compare, char const *value,
553                                regmatch_t rxmatch[]);
554 void            verify_request(REQUEST *request);                       /* only for special debug builds */
555
556 /* client.c */
557 RADCLIENT_LIST  *clients_init(CONF_SECTION *cs);
558 void            clients_free(RADCLIENT_LIST *clients);
559 RADCLIENT_LIST  *clients_parse_section(CONF_SECTION *section, bool tls_required);
560 void            client_free(RADCLIENT *client);
561 int             client_add(RADCLIENT_LIST *clients, RADCLIENT *client);
562 #ifdef WITH_DYNAMIC_CLIENTS
563 void            client_delete(RADCLIENT_LIST *clients, RADCLIENT *client);
564 RADCLIENT       *client_from_request(RADCLIENT_LIST *clients, REQUEST *request);
565 #endif
566 RADCLIENT       *client_from_query(TALLOC_CTX *ctx, char const *identifier, char const *secret, char const *shortname,
567                                    char const *type, char const *server, bool require_ma);
568 RADCLIENT       *client_find(RADCLIENT_LIST const *clients,
569                              fr_ipaddr_t const *ipaddr, int proto);
570
571 RADCLIENT       *client_findbynumber(RADCLIENT_LIST const *clients,
572                                      int number);
573 RADCLIENT       *client_find_old(fr_ipaddr_t const *ipaddr);
574 bool            client_validate(RADCLIENT_LIST *clients, RADCLIENT *master, RADCLIENT *c);
575 RADCLIENT       *client_read(char const *filename, int in_server, int flag);
576
577
578 /* files.c */
579 int             pairlist_read(TALLOC_CTX *ctx, char const *file, PAIR_LIST **list, int complain);
580 void            pairlist_free(PAIR_LIST **);
581
582 /* version.c */
583 int             rad_check_lib_magic(uint64_t magic);
584 int             ssl_check_consistency(void);
585 char const      *ssl_version_by_num(uint64_t version);
586 char const      *ssl_version_range(uint64_t low, uint64_t high);
587 char const      *ssl_version(void);
588 void            version(void);
589
590 /* auth.c */
591 char    *auth_name(char *buf, size_t buflen, REQUEST *request, bool do_cli);
592 int             rad_authenticate (REQUEST *);
593 int             rad_postauth(REQUEST *);
594 int             rad_virtual_server(REQUEST *);
595
596 /* exec.c */
597 pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait,
598                            int *input_fd, int *output_fd,
599                            VALUE_PAIR *input_pairs, bool shell_escape);
600 int radius_readfrom_program(REQUEST *request, int fd, pid_t pid, int timeout,
601                             char *answer, int left);
602 int radius_exec_program(REQUEST *request, char const *cmd, bool exec_wait, bool shell_escape,
603                         char *user_msg, size_t msg_len, int timeout,
604                         VALUE_PAIR *input_pairs, VALUE_PAIR **output_pairs);
605 void exec_trigger(REQUEST *request, CONF_SECTION *cs, char const *name, int quench)
606      CC_HINT(nonnull (3));
607
608 /* valuepair.c */
609 int paircompare_register(DICT_ATTR const *attribute, DICT_ATTR const *from,
610           bool first_only, RAD_COMPARE_FUNC func, void *instance);
611 void            paircompare_unregister(DICT_ATTR const *attr, RAD_COMPARE_FUNC func);
612 void            paircompare_unregister_instance(void *instance);
613 int             paircompare(REQUEST *request, VALUE_PAIR *req_list,
614                             VALUE_PAIR *check, VALUE_PAIR **rep_list);
615 value_pair_tmpl_t *radius_xlat2tmpl(TALLOC_CTX *ctx, xlat_exp_t *xlat);
616 int             radius_xlat_do(REQUEST *request, VALUE_PAIR *vp);
617 int radius_compare_vps(REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *vp);
618 int radius_callback_compare(REQUEST *request, VALUE_PAIR *req,
619                             VALUE_PAIR *check, VALUE_PAIR *check_pairs,
620                             VALUE_PAIR **reply_pairs);
621 int radius_find_compare(DICT_ATTR const *attribute);
622 VALUE_PAIR      *radius_paircreate(TALLOC_CTX *ctx, VALUE_PAIR **vps, unsigned int attribute, unsigned int vendor);
623
624 void module_failure_msg(REQUEST *request, char const *fmt, ...) CC_HINT(format (printf, 2, 3));
625 void vmodule_failure_msg(REQUEST *request, char const *fmt, va_list ap) CC_HINT(format (printf, 2, 0));
626
627 /*
628  *      Less code == fewer bugs
629  *
630  * @param _a attribute
631  * @param _b value
632  * @param _c op
633  */
634 #define pairmake_packet(_a, _b, _c) pairmake(request->packet, &request->packet->vps, _a, _b, _c)
635 #define pairmake_reply(_a, _b, _c) pairmake(request->reply, &request->reply->vps, _a, _b, _c)
636 #define pairmake_config(_a, _b, _c) pairmake(request, &request->config_items, _a, _b, _c)
637
638
639 /* xlat.c */
640 typedef size_t (*RADIUS_ESCAPE_STRING)(REQUEST *, char *out, size_t outlen, char const *in, void *arg);
641
642 ssize_t radius_xlat(char *out, size_t outlen, REQUEST *request, char const *fmt, RADIUS_ESCAPE_STRING escape,
643                     void *escape_ctx)
644         CC_HINT(nonnull (1 ,3 ,4));
645
646 ssize_t radius_axlat(char **out, REQUEST *request, char const *fmt, RADIUS_ESCAPE_STRING escape, void *escape_ctx)
647         CC_HINT(nonnull (1, 2, 3));
648
649 ssize_t radius_axlat_struct(char **out, REQUEST *request, xlat_exp_t const *xlat, RADIUS_ESCAPE_STRING escape,
650                             void *ctx)
651         CC_HINT(nonnull (1, 2, 3));
652
653 typedef ssize_t (*RAD_XLAT_FUNC)(void *instance, REQUEST *, char const *, char *, size_t);
654 int             xlat_register(char const *module, RAD_XLAT_FUNC func, RADIUS_ESCAPE_STRING escape,
655                               void *instance);
656 void            xlat_unregister(char const *module, RAD_XLAT_FUNC func, void *instance);
657 ssize_t         xlat_fmt_to_ref(uint8_t const **out, REQUEST *request, char const *fmt);
658 void            xlat_free(void);
659
660 /* threads.c */
661 extern int thread_pool_init(CONF_SECTION *cs, bool *spawn_flag);
662 extern void thread_pool_stop(void);
663 extern int thread_pool_addrequest(REQUEST *, RAD_REQUEST_FUNP);
664 extern pid_t rad_fork(void);
665 extern pid_t rad_waitpid(pid_t pid, int *status);
666 extern int total_active_threads(void);
667 extern void thread_pool_lock(void);
668 extern void thread_pool_unlock(void);
669 extern void thread_pool_queue_stats(int array[RAD_LISTEN_MAX], int pps[2]);
670
671 #ifndef HAVE_PTHREAD_H
672 #define rad_fork(n) fork()
673 #define rad_waitpid(a,b) waitpid(a,b, 0)
674 #endif
675
676 /* main_config.c */
677 /* Define a global config structure */
678 extern struct main_config_t main_config;
679
680 void set_radius_dir(TALLOC_CTX *ctx, char const *path);
681 char const *get_radius_dir(void);
682 int main_config_init(void);
683 int main_config_free(void);
684 void main_config_hup(void);
685 void hup_logfile(void);
686 void fr_suid_down(void);
687 void fr_suid_up(void);
688 void fr_suid_down_permanent(void);
689
690 /* listen.c */
691 void listen_free(rad_listen_t **head);
692 int listen_init(CONF_SECTION *cs, rad_listen_t **head, bool spawn_flag);
693 rad_listen_t *proxy_new_listener(home_server_t *home, uint16_t src_port);
694 RADCLIENT *client_listener_find(rad_listen_t *listener, fr_ipaddr_t const *ipaddr, uint16_t src_port);
695
696 #ifdef WITH_STATS
697 RADCLIENT_LIST *listener_find_client_list(fr_ipaddr_t const *ipaddr, uint16_t port);
698 #endif
699 rad_listen_t *listener_find_byipaddr(fr_ipaddr_t const *ipaddr, uint16_t port, int proto);
700 int rad_status_server(REQUEST *request);
701
702 /* event.c */
703 typedef enum event_corral_t {
704         EVENT_CORRAL_MAIN = 0,  //!< Always main thread event list
705         EVENT_CORRAL_AUX        //!< Maybe main thread or one shared by modules
706 } event_corral_t;
707
708 fr_event_list_t *radius_event_list_corral(event_corral_t hint);
709 int radius_event_init(TALLOC_CTX *ctx);
710 int radius_event_start(CONF_SECTION *cs, bool spawn_flag);
711 void radius_event_free(void);
712 int radius_event_process(void);
713 void radius_update_listener(rad_listen_t *listener);
714 void revive_home_server(void *ctx);
715 void mark_home_server_dead(home_server_t *home, struct timeval *when);
716
717 /* evaluate.c */
718 typedef struct fr_cond_t fr_cond_t;
719 typedef int (*radius_tmpl_getvalue_t)(VALUE_PAIR **out, REQUEST *request, value_pair_map_t const *map, void *ctx);
720
721 int radius_evaluate_tmpl(REQUEST *request, int modreturn, int depth,
722                          value_pair_tmpl_t const *vpt);
723 int radius_evaluate_map(REQUEST *request, int modreturn, int depth,
724                         fr_cond_t const *c);
725 int radius_evaluate_cond(REQUEST *request, int modreturn, int depth,
726                          fr_cond_t const *c);
727 void radius_pairmove(REQUEST *request, VALUE_PAIR **to, VALUE_PAIR *from, bool do_xlat) CC_HINT(nonnull);
728
729 VALUE_PAIR **radius_list(REQUEST *request, pair_lists_t list);
730 TALLOC_CTX *radius_list_ctx(REQUEST *request, pair_lists_t list_name);
731 pair_lists_t radius_list_name(char const **name, pair_lists_t unknown);
732 int radius_request(REQUEST **request, request_refs_t name);
733 request_refs_t radius_request_name(char const **name, request_refs_t unknown);
734
735 int radius_mapexec(VALUE_PAIR **out, REQUEST *request, value_pair_map_t const *map);
736 int CC_HINT(nonnull (1,2,3)) radius_map2vp(VALUE_PAIR **out, REQUEST *request, value_pair_map_t const *map, void *ctx);
737 int radius_map2request(REQUEST *request, value_pair_map_t const *map,
738                        char const *src, radius_tmpl_getvalue_t func, void *ctx);
739
740 int radius_strpair2map(value_pair_map_t **out, REQUEST *request, char const *raw,
741                        request_refs_t dst_request_def, pair_lists_t dst_list_def,
742                        request_refs_t src_request_def, pair_lists_t src_list_def);
743 int radius_vpt_get_vp(VALUE_PAIR **out, REQUEST *request, value_pair_tmpl_t const *vpt);
744 int radius_get_vp(VALUE_PAIR **out, REQUEST *request, char const *name);
745 int radius_vpt_copy_vp(VALUE_PAIR **out, REQUEST *request, value_pair_tmpl_t const *vpt);
746 int radius_copy_vp(VALUE_PAIR **out, REQUEST *request, char const *name);
747
748 #ifdef WITH_TLS
749 /*
750  *      For run-time patching of which function handles which socket.
751  */
752 int dual_tls_recv(rad_listen_t *listener);
753 int dual_tls_send(rad_listen_t *listener, REQUEST *request);
754 int proxy_tls_recv(rad_listen_t *listener);
755 int proxy_tls_send(rad_listen_t *listener, REQUEST *request);
756 #endif
757
758 /*
759  *      For radmin over TCP.
760  */
761 #define PW_RADMIN_PORT 18120
762
763 #ifdef __cplusplus
764 }
765 #endif
766
767 #endif /*RADIUSD_H*/