The FreeRADIUS server $Id: a4e7f8c94e8038b7627bcf52356b7ed15955c1d7 $
Loading...
Searching...
No Matches
proto_control_unix.c
Go to the documentation of this file.
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
17/**
18 * $Id: 7f29f99b343559350a7f2cc66f42fc809d4b6db0 $
19 * @file proto_control_unix.c
20 * @brief Control handler for Unix sockets.
21 *
22 * @copyright 2018 The FreeRADIUS server project.
23 * @copyright 2018 Alan DeKok (aland@deployingradius.com)
24 */
25#include <freeradius-devel/server/main_config.h>
26
27#include <freeradius-devel/io/application.h>
28#include <freeradius-devel/io/listen.h>
29#include <freeradius-devel/io/schedule.h>
30#include <freeradius-devel/util/perm.h>
31#include <freeradius-devel/util/trie.h>
32#include <freeradius-devel/util/file.h>
33#include <freeradius-devel/util/nbo.h>
34
35#include <netdb.h>
36
37#include "proto_control.h"
38
39#include <freeradius-devel/bio/fd.h>
40
41#ifdef HAVE_SYS_STAT_H
42#endif
43
44#include <libgen.h>
45
46typedef struct {
47 char const *name; //!< socket name
48
49 int sockfd;
50
52
53 fr_stats_t stats; //!< statistics for this socket
54
55 fr_io_address_t *connection; //!< for connected sockets.
56
57
58 fr_io_data_read_t read; //!< function to process data *after* reading
59 FILE *stdout_fp;
60 FILE *stderr_fp;
61
63 FILE *misc;
64 fr_cmd_info_t *info; //!< for running commands
65
66 fr_client_t radclient; //!< for faking out clients
68
69typedef struct {
70 CONF_SECTION *cs; //!< our configuration
71
72 char const *filename; //!< filename of control socket
73 char const *uid_name; //!< name of UID to require
74 char const *gid_name; //!< name of GID to require
75 uid_t uid; //!< UID value
76 gid_t gid; //!< GID value
77
78 uint32_t recv_buff; //!< How big the kernel's receive buffer should be.
79
80 uint32_t max_packet_size; //!< for message ring buffer.
81
82 char const *mode_name;
84
85 bool recv_buff_is_set; //!< Whether we were provided with a receive
86 //!< buffer value.
87 char const *peer_uid_name; //!< name of UID to require
88 char const *peer_gid_name; //!< name of GID to require
89 uid_t peer_uid; //!< UID value
90 gid_t peer_gid; //!< GID value
91
92 fr_bio_fd_config_t fd_config; //!< FD BIO configuration
94
96 { FR_CONF_OFFSET("uid", proto_control_unix_t, peer_uid_name) },
97 { FR_CONF_OFFSET("gid", proto_control_unix_t, peer_gid_name) },
98
100};
101
104 .dflt = "${run_dir}/radiusd.sock" },
105 { FR_CONF_OFFSET("uid", proto_control_unix_t, uid_name) },
106 { FR_CONF_OFFSET("gid", proto_control_unix_t, gid_name) },
107 { FR_CONF_OFFSET("mode", proto_control_unix_t, mode_name) },
108
109 { FR_CONF_OFFSET_IS_SET("recv_buff", FR_TYPE_UINT32, 0, proto_control_unix_t, recv_buff) },
110
111 { FR_CONF_OFFSET("max_packet_size", proto_control_unix_t, max_packet_size), .dflt = "4096" } ,
112
113 { FR_CONF_POINTER("peercred", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) peercred_config },
114
116};
117
118#define FR_READ (1)
119#define FR_WRITE (2)
120
122 { L("read-only"), FR_READ },
123 { L("read-write"), FR_READ | FR_WRITE },
124 { L("ro"), FR_READ },
125 { L("rw"), FR_READ | FR_WRITE }
126};
128
129#undef INT
130#define INT size_t
131#define SINT ssize_t
132
133static SINT write_stdout(void *instance, char const *buffer, INT buffer_size)
134{
135 proto_control_unix_thread_t *thread = talloc_get_type_abort(instance, proto_control_unix_thread_t);
136
137 return fr_conduit_write(thread->sockfd, FR_CONDUIT_STDOUT, buffer, buffer_size);
138}
139
140static SINT write_stderr(void *instance, char const *buffer, INT buffer_size)
141{
142 proto_control_unix_thread_t *thread = talloc_get_type_abort(instance, proto_control_unix_thread_t)
143;
144 return fr_conduit_write(thread->sockfd, FR_CONDUIT_STDERR, buffer, buffer_size);
145}
146
147static SINT write_misc(void *instance, char const *buffer, INT buffer_size)
148{
149 proto_control_unix_thread_t *thread = talloc_get_type_abort(instance, proto_control_unix_thread_t);
150
151 return fr_conduit_write(thread->sockfd, thread->misc_conduit, buffer, buffer_size);
152}
153
154
155/*
156 * Run a command.
157 */
158static ssize_t mod_read_command(fr_listen_t *li, UNUSED void **packet_ctx, UNUSED fr_time_t *recv_time_p, uint8_t *buffer, UNUSED size_t buffer_len, UNUSED size_t *leftover)
159{
161 proto_control_unix_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_control_unix_thread_t);
163 uint32_t status;
164 uint8_t *cmd = buffer + sizeof(*hdr);
165 int rcode;
166 char string[1024];
167
168 hdr->length = ntohl(hdr->length);
169 if (hdr->length >= sizeof(string)) goto fail;
170
171 /*
172 * If the write gives us nothing, send an empty SUCCESS back.
173 */
174 if (!hdr->length) {
175 status = FR_CONDUIT_SUCCESS;
176 goto done;
177 }
178
179 /*
180 * fr_command_run() expects a zero-terminated string...
181 */
182 memcpy(string, cmd, hdr->length);
183 string[hdr->length] = '\0';
184
185 /*
186 * Content is the string we need help for.
187 */
188 if (htons(hdr->conduit) == FR_CONDUIT_HELP) {
189 fr_radmin_help(thread->stdout_fp, string);
190 // @todo - have in-band signalling saying that the help is done?
191 // we want to be able to say that *this* help is done.
192 // the best way to do that is to have a token, and every command
193 // from the other end sends a token, and we echo it back here...
194 // Or, since we currently can't do streaming commands, it's OK?
195 // Or, we assume that origin 0 is for interactive commands,
196 // and that the other origins are for streaming output...
197 status = FR_CONDUIT_SUCCESS;
198 goto done;
199 }
200
201 if (htons(hdr->conduit) == FR_CONDUIT_COMPLETE) {
202 uint16_t start;
203
204 if (hdr->length < 2) goto fail;
205
206 start = fr_nbo_to_uint16((uint8_t const *) string);
207
209
210 fr_radmin_complete(thread->misc, string + 2, start);
212 status = FR_CONDUIT_SUCCESS;
213 goto done;
214 }
215
216 if (htons(hdr->conduit) != FR_CONDUIT_STDIN) {
217 DEBUG("ERROR: Ignoring data which is from wrong input");
218 return 0;
219 }
220
221 DEBUG("radmin-remote> %.*s", (int) hdr->length, cmd);
222
223 rcode = fr_radmin_run(thread->info, thread->stdout_fp, thread->stderr_fp, string, inst->read_only);
224 if (rcode < 0) {
225fail:
226 status = FR_CONDUIT_FAIL;
227
228 } else if (rcode == 0) {
229 /*
230 * The other end should keep track of it's
231 * context, and send us full lines.
232 */
233 (void) fr_command_clear(0, thread->info);
234 status = FR_CONDUIT_PARTIAL;
235 } else {
236 status = FR_CONDUIT_SUCCESS;
237 }
238
239done:
240 status = htonl(status);
241 (void) fr_conduit_write(thread->sockfd, FR_CONDUIT_CMD_STATUS, &status, sizeof(status));
242
243 return 0;
244}
245
246/*
247 * Process an initial connection request.
248 */
249static ssize_t mod_read_init(fr_listen_t *li, UNUSED void **packet_ctx, UNUSED fr_time_t *recv_time_p, uint8_t *buffer, size_t buffer_len, UNUSED size_t *leftover)
250{
251 proto_control_unix_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_control_unix_thread_t);
253 uint32_t magic;
254
255 if (htons(hdr->conduit) != FR_CONDUIT_INIT_ACK) {
256 DEBUG("ERROR: Connection is missing initial ACK packet.");
257 return -1;
258 }
259
260 if (buffer_len < sizeof(*hdr)) {
261 DEBUG("ERROR: Initial ACK is malformed");
262 return -1;
263 }
264
265 if (htonl(hdr->length) != 8) {
266 DEBUG("ERROR: Initial ACK has wrong length (%lu).", (size_t) htonl(hdr->length));
267 return -1;
268 }
269
270 memcpy(&magic, buffer + sizeof(*hdr), sizeof(magic));
271 magic = htonl(magic);
272 if (magic != FR_CONDUIT_MAGIC) {
273 DEBUG("ERROR: Connection from incompatible version of radmin.");
274 return -1;
275 }
276
277 /*
278 * Next 4 bytes are zero, we ignore them.
279 */
280 if (write(thread->sockfd, buffer, buffer_len) < (ssize_t) buffer_len) {
281 DEBUG("ERROR: Blocking write to socket... oops");
282 return -1;
283 }
284
285 thread->read = mod_read_command;
286
287 return 0;
288}
289
290static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time_p, uint8_t *buffer, size_t buffer_len, size_t *leftover)
291{
292 proto_control_unix_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_control_unix_thread_t);
293 ssize_t data_size;
294
295 fr_conduit_type_t conduit;
296 bool want_more;
297
298 /*
299 * Read data into the buffer.
300 */
301 data_size = fr_conduit_read_async(thread->sockfd, &conduit, buffer, buffer_len, leftover, &want_more);
302 if (data_size < 0) {
303 DEBUG2("proto_control_unix got read error %zd: %s", data_size, fr_syserror(errno));
304 return data_size;
305 }
306
307 /*
308 * Note that we return ERROR for all bad packets, as
309 * there's no point in reading packets from a TCP
310 * connection which isn't sending us properly formatted
311 * packets.
312 */
313
314 /*
315 * Not enough for a full packet, ask the caller to read more.
316 */
317 if (want_more) {
318 return 0;
319 }
320
321 // @todo - maybe convert timestamp?
322 *recv_time_p = fr_time();
323 *leftover = 0;
324
325 /*
326 * Print out what we received.
327 */
328 DEBUG3("proto_control_unix - Received command packet length %d on %s",
329 (int) data_size, thread->name);
330
331 /*
332 * Run the state machine to process the rest of the packet.
333 */
334 return thread->read(li, packet_ctx, recv_time_p, buffer, (size_t) data_size, leftover);
335}
336
337
339 uint8_t *buffer, size_t buffer_len, size_t written)
340{
341 proto_control_unix_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_control_unix_thread_t);
342 ssize_t data_size;
343 ssize_t total;
344
345 /*
346 * @todo - share a stats interface with the parent? or
347 * put the stats in the listener, so that proto_control
348 * can update them, too.. <sigh>
349 */
350 thread->stats.total_responses++;
351
352 /*
353 * Only write replies if they're RADIUS packets.
354 * sometimes we want to NOT send a reply...
355 */
356 data_size = write(thread->sockfd, buffer + written, buffer_len - written);
357
358 /*
359 * This socket is dead. That's an error...
360 */
361 if (data_size <= 0) return data_size;
362
363 /*
364 * The total never exceeds buffer_len, which is far below
365 * SSIZE_MAX.
366 */
367 if (!fr_cond_assert(fr_add(&total, data_size, written))) return -1;
368
369 return total;
370}
371
372
374{
375 proto_control_unix_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_control_unix_thread_t);
376
377 thread->connection = connection;
378
379 // @todo - set name to path + peer ID of other end?
380
381 return 0;
382}
383
384static void mod_network_get(int *ipproto, bool *dynamic_clients, fr_trie_t const **trie, UNUSED void *instance)
385{
386 *ipproto = IPPROTO_TCP;
387 *dynamic_clients = false;
388 *trie = NULL;
389}
390
391/** Open a UNIX listener for control sockets
392 *
393 */
394static int mod_open(fr_listen_t *li)
395{
397 proto_control_unix_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_control_unix_thread_t);
398
399 CONF_ITEM *ci;
400 CONF_SECTION *server_cs;
401
402 fr_bio_fd_info_t const *info;
403
404 fr_assert(!thread->connection);
405
406 /*
407 * Point the FD BIO to out long-lived configuration structure.
408 */
409 thread->fd_bio = fr_bio_fd_alloc(thread, &inst->fd_config, 0);
410 if (!thread->fd_bio) {
411 cf_log_err(li->cs, "Failed opening UNIX path %s - %s", inst->filename, fr_strerror());
412 return -1;
413 }
414
415 info = fr_bio_fd_info(thread->fd_bio);
416 fr_assert(info != NULL);
417
418 li->fd = thread->sockfd = info->socket.fd;
419
420 ci = cf_parent(inst->cs); /* listen { ... } */
421 fr_assert(ci != NULL);
422 ci = cf_parent(ci);
423 fr_assert(ci != NULL);
424
425 server_cs = cf_item_to_section(ci);
426
427 thread->name = talloc_typed_asprintf(thread, "control_unix from filename %s", inst->filename);
428
429 /*
430 * Set up the fake client
431 */
432 thread->radclient.longname = inst->filename;
433 thread->radclient.ipaddr.af = AF_INET;
434 thread->radclient.src_ipaddr.af = AF_INET;
435
436 thread->radclient.server_cs = server_cs;
437 fr_assert(thread->radclient.server_cs != NULL);
439
440 return 0;
441}
442
443#if !defined(HAVE_GETPEEREID) && defined(SO_PEERCRED)
444static int getpeereid(int s, uid_t *euid, gid_t *egid)
445{
446 struct ucred cr;
447 socklen_t cl = sizeof(cr);
448
449 if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cl) < 0) {
450 return -1;
451 }
452
453 *euid = cr.uid;
454 *egid = cr.gid;
455 return 0;
456}
457
458/* we now have getpeereid() in this file */
459#define HAVE_GETPEEREID (1)
460
461#endif /* HAVE_GETPEEREID */
462
464{
465 if (thread->stdout_fp) fclose(thread->stdout_fp);
466 if (thread->stderr_fp) fclose(thread->stderr_fp);
467 if (thread->misc) fclose(thread->misc);
468
469 return 0;
470}
471
472/** Set the file descriptor for this socket.
473 *
474 */
475static int mod_fd_set(fr_listen_t *li, int fd)
476{
478 proto_control_unix_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_control_unix_thread_t);
479
481
482#ifdef HAVE_GETPEEREID
483 /*
484 * Perform user authentication.
485 *
486 * @todo - this really belongs in the accept() callback,
487 * so that we don't create an entirely new listener and
488 * then close it.
489 */
490 if (inst->peer_uid || inst->peer_gid) {
491 uid_t uid;
492 gid_t gid;
493
494 if (getpeereid(fd, &uid, &gid) < 0) {
495 ERROR("Failed getting peer credentials for %s: %s",
496 inst->filename, fr_syserror(errno));
497 return -1;
498 }
499
500 /*
501 * Only do UID checking if the caller is
502 * non-root. The superuser can do anything, so
503 * we might as well let them do anything.
504 */
505 if (uid != 0) do {
506 /*
507 * Allow entry if UID or GID matches.
508 */
509 if (inst->peer_uid_name && (inst->peer_uid == uid)) break;
510 if (inst->peer_gid_name && (inst->peer_gid == gid)) break;
511
512 if (inst->peer_uid_name && (inst->peer_uid != uid)) {
513 ERROR("Unauthorized connection to %s from uid %ld",
514 inst->filename, (long int) uid);
515 return -1;
516 }
517
518 if (inst->peer_gid_name && (inst->peer_gid != gid)) {
519 ERROR("Unauthorized connection to %s from gid %ld",
520 inst->filename, (long int) gid);
521 return -1;
522 }
523
524 } while (0);
525
526 thread->name = talloc_typed_asprintf(thread, "proto unix filename %s from peer UID %u GID %u",
527 inst->filename,
528 (unsigned int) uid, (unsigned int) gid);
529 } else
530#endif
531
532
533 thread->name = talloc_typed_asprintf(thread, "proto unix filename %s", inst->filename);
534
535 thread->sockfd = fd;
536 thread->read = mod_read_init;
537
538 /*
539 * These must be set separately as they have different prototypes.
540 */
541 io.read = NULL;
542 io.seek = NULL;
543 io.close = NULL;
544 io.write = write_stdout;
545
546 thread->stdout_fp = fopencookie(thread, "w", io);
547 if (!thread->stdout_fp) {
548 fr_strerror_printf("Failed to open stdout cookie: %s", fr_syserror(errno));
549 return -1;
550 }
551
552 io.write = write_stderr;
553 thread->stderr_fp = fopencookie(thread, "w", io);
554 if (!thread->stderr_fp) {
555 fr_strerror_printf("Failed to open stderr cookie: %s", fr_syserror(errno));
556 return -1;
557 }
558
559 io.write = write_misc;
560 thread->misc = fopencookie(thread, "w", io);
561 if (!thread->misc) {
562 fr_strerror_printf("Failed to open misc cookie: %s", fr_syserror(errno));
563 return -1;
564 }
565
566 talloc_set_destructor(thread, _close_cookies);
567
568 /*
569 * @todo - if we move to a binary protocol, then we
570 * should change this to a small (i.e. 1K) buffer. The
571 * data should be sent over to the remote side as quickly
572 * as possible.
573 */
574 (void) setvbuf(thread->stdout_fp, NULL, _IOLBF, 0);
575 (void) setvbuf(thread->stderr_fp, NULL, _IOLBF, 0);
576 (void) setvbuf(thread->misc, NULL, _IOLBF, 0);
577
578 thread->info = talloc_zero(thread, fr_cmd_info_t);
579 fr_command_info_init(thread, thread->info);
580
581 return 0;
582}
583
584static char const *mod_name(fr_listen_t *li)
585{
586 proto_control_unix_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_control_unix_thread_t);
587
588 return thread->name;
589}
590
591
592static int mod_instantiate(module_inst_ctx_t const *mctx)
593{
594 proto_control_unix_t *inst = talloc_get_type_abort(mctx->mi->data, proto_control_unix_t);
595 CONF_SECTION *conf = mctx->mi->conf;
596
597 inst->cs = conf;
598
599 if (inst->recv_buff_is_set) {
600 FR_INTEGER_BOUND_CHECK("recv_buff", inst->recv_buff, >=, 32);
601 FR_INTEGER_BOUND_CHECK("recv_buff", inst->recv_buff, <=, INT_MAX);
602 }
603
604 if (inst->uid_name) {
605 struct passwd *pwd;
606
607 if (fr_perm_getpwnam(conf, &pwd, inst->uid_name) < 0) {
608 PERROR("Failed getting uid for %s", inst->uid_name);
609 return -1;
610 }
611 inst->uid = pwd->pw_uid;
612 talloc_free(pwd);
613
614 } else if (main_config->server_uid) {
615 inst->uid = main_config->server_uid;
616
617 } else {
618 inst->uid = getuid();
619 }
620
621 if (inst->gid_name) {
622 if (fr_perm_gid_from_str(conf, &inst->gid, inst->gid_name) < 0) {
623 PERROR("Failed getting gid for %s", inst->gid_name);
624 return -1;
625 }
626
627 } else if (main_config->server_gid) {
628 inst->gid = main_config->server_gid;
629
630 } else {
631 inst->gid = getgid();
632 }
633
634 /*
635 * And for peer creds
636 */
637 if (inst->peer_uid_name) {
638 struct passwd *pwd;
639
640 if (fr_perm_getpwnam(conf, &pwd, inst->peer_uid_name) < 0) {
641 PERROR("Failed getting peer uid for %s", inst->peer_uid_name);
642 return -1;
643 }
644 inst->peer_uid = pwd->pw_uid;
645 talloc_free(pwd);
646 }
647
648 if (inst->peer_gid_name) {
649 if (fr_perm_gid_from_str(conf, &inst->peer_gid, inst->peer_gid_name) < 0) {
650 PERROR("Failed getting peer gid for %s", inst->peer_gid_name);
651 return -1;
652 }
653 }
654
655 if (!inst->mode_name) {
656 inst->read_only = true;
657 } else {
658 int mode;
659
660 mode = fr_table_value_by_str(mode_names, inst->mode_name, 0);
661 if (!mode) {
662 ERROR("Invalid mode name \"%s\"",
663 inst->mode_name);
664 return -1;
665 }
666
667 if ((mode & FR_WRITE) == 0) {
668 inst->read_only = true;
669 } else {
670 inst->read_only = false;
671 }
672 }
673
674 FR_INTEGER_BOUND_CHECK("max_packet_size", inst->max_packet_size, >=, 20);
675 FR_INTEGER_BOUND_CHECK("max_packet_size", inst->max_packet_size, <=, 65536);
676
677 /*
678 * Initialize the configuration from static information we know now. It will be used across
679 * multiple connections.
680 */
681 inst->fd_config = (fr_bio_fd_config_t) {
683 .socket_type = SOCK_STREAM,
684 .transport_type = FR_BIO_FD_TRANSPORT_UNIX,
685 .path = inst->filename,
686 .uid = inst->uid,
687 .gid = inst->gid,
688 .perm = 0600,
689 .async = true,
690 .backlog = SOMAXCONN,
691 .backlog_is_set = true,
692 };
693
694 return 0;
695}
696
698{
699 proto_control_unix_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_control_unix_thread_t);
700
701 return &thread->radclient;
702}
703
706 .common = {
707 .magic = MODULE_MAGIC_INIT,
708 .name = "control_unix",
710 .inst_size = sizeof(proto_control_unix_t),
711 .thread_inst_size = sizeof(proto_control_unix_thread_t),
712 .instantiate = mod_instantiate
713 },
714 .default_message_size = 4096,
715
716 .open = mod_open,
717 .read = mod_read,
718 .write = mod_write,
719 .fd_set = mod_fd_set,
720 .connection_set = mod_connection_set,
721 .network_get = mod_network_get,
722 .client_find = mod_client_find,
723 .get_name = mod_name,
724};
static int const char char buffer[256]
Definition acutest.h:641
module_t common
Common fields to all loadable modules.
Definition app_io.h:34
Public structure describing an I/O path for a protocol.
Definition app_io.h:33
int fr_radmin_run(fr_cmd_info_t *info, FILE *fp, FILE *fp_err, char *str, bool read_only)
Run a command from an input string.
Definition radmin.c:1184
void fr_radmin_complete(FILE *fp, const char *text, int start)
Definition radmin.c:1220
void fr_radmin_help(FILE *fp, char const *text)
Definition radmin.c:1215
static int packet_ctx
the tests pass only the address of packet_ctx
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:245
#define UNUSED
Definition build.h:415
#define NUM_ELEMENTS(_t)
Definition build.h:437
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:712
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
Definition cf_parse.h:572
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:280
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition cf_parse.h:466
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition cf_parse.h:460
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
Definition cf_parse.h:350
#define FR_CONF_OFFSET_IS_SET(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct,...
Definition cf_parse.h:294
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:268
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:649
Common header for all CONF_* types.
Definition cf_priv.h:54
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:106
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition cf_util.c:1405
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition cf_util.c:671
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:340
#define cf_parent(_cf)
Definition cf_util.h:115
int fr_command_clear(int new_argc, fr_cmd_info_t *info)
Clear out any value boxes etc.
Definition command.c:2377
void fr_command_info_init(TALLOC_CTX *ctx, fr_cmd_info_t *info)
Initialize an fr_cmd_info_t structure.
Definition command.c:2405
ssize_t fr_conduit_write(int fd, fr_conduit_type_t conduit, void const *out, size_t outlen)
Definition conduit.c:234
ssize_t fr_conduit_read_async(int fd, fr_conduit_type_t *pconduit, void *out, size_t outlen, size_t *leftover, bool *want_more)
Definition conduit.c:78
#define FR_CONDUIT_MAGIC
Definition conduit.h:32
@ FR_CONDUIT_FAIL
Definition conduit.h:54
@ FR_CONDUIT_PARTIAL
Definition conduit.h:55
@ FR_CONDUIT_SUCCESS
Definition conduit.h:56
uint16_t conduit
Definition conduit.h:77
fr_conduit_type_t
Definition conduit.h:34
@ FR_CONDUIT_STDOUT
Definition conduit.h:36
@ FR_CONDUIT_HELP
Definition conduit.h:43
@ FR_CONDUIT_STDIN
Definition conduit.h:35
@ FR_CONDUIT_STDERR
Definition conduit.h:37
@ FR_CONDUIT_CMD_STATUS
Definition conduit.h:38
@ FR_CONDUIT_INIT_ACK
Definition conduit.h:39
@ FR_CONDUIT_COMPLETE
Definition conduit.h:44
uint32_t length
Definition conduit.h:78
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:177
#define ERROR(fmt,...)
Definition dhcpclient.c:40
#define DEBUG(fmt,...)
Definition dhcpclient.c:38
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
fr_bio_t * fr_bio_fd_alloc(TALLOC_CTX *ctx, fr_bio_fd_config_t const *cfg, size_t offset)
Allocate a FD bio.
Definition fd.c:1047
fr_bio_fd_info_t const * fr_bio_fd_info(fr_bio_t *bio)
Returns a pointer to the bio-specific information.
Definition fd.c:1377
fr_socket_t socket
as connected socket
Definition fd.h:145
@ FR_BIO_FD_LISTEN
call fr_bio_fd_accept() for each new connection
Definition fd.h:64
@ FR_BIO_FD_TRANSPORT_UNIX
Unix domain socket, named by 'path'.
Definition fd.h:81
Configuration for sockets.
Definition fd.h:92
Run-time status of the socket.
Definition fd.h:144
FILE * fopencookie(void *cookie, const char *mode, cookie_io_functions_t io_funcs)
Definition fopencookie.c:99
cookie_close_function_t close
Definition fopencookie.h:55
cookie_seek_function_t seek
Definition fopencookie.h:54
cookie_read_function_t read
Definition fopencookie.h:52
cookie_write_function_t write
Definition fopencookie.h:53
talloc_free(hp)
int af
Address family.
Definition inet.h:64
IPv4/6 prefix.
ssize_t(* fr_io_data_read_t)(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time, uint8_t *buffer, size_t buffer_len, size_t *leftover)
Read from a socket.
Definition base.h:176
char const * server
Name of the virtual server client is associated with.
Definition client.h:127
fr_ipaddr_t ipaddr
IPv4/IPv6 address of the host.
Definition client.h:83
fr_ipaddr_t src_ipaddr
IPv4/IPv6 address to send responses from (family must match ipaddr).
Definition client.h:84
char const * longname
Client identifier.
Definition client.h:87
CONF_SECTION * server_cs
Virtual server that the client is associated with.
Definition client.h:128
Describes a host allowed to send packets to the server.
Definition client.h:80
#define PERROR(_fmt,...)
Definition log.h:233
#define DEBUG3(_fmt,...)
Definition log.h:271
uint64_t total_responses
Definition stats.h:38
#define fr_time()
Definition event.c:58
CONF_SECTION * cs
of this listener
Definition listen.h:41
void const * app_io_instance
I/O path configuration context.
Definition listen.h:33
void * thread_instance
thread / socket context
Definition listen.h:34
int fd
file descriptor for this socket - set by open
Definition listen.h:28
main_config_t const * main_config
Main server configuration.
Definition main_config.c:56
#define fr_add(_out, _a, _b)
Adds two integers.
Definition math.h:190
unsigned short uint16_t
@ FR_TYPE_UINT32
32 Bit unsigned integer.
unsigned int uint32_t
long int ssize_t
unsigned char uint8_t
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
static uint16_t fr_nbo_to_uint16(uint8_t const data[static sizeof(uint16_t)])
Read an unsigned 16bit integer from wire format (big endian)
Definition nbo.h:146
int fr_perm_getpwnam(TALLOC_CTX *ctx, struct passwd **out, char const *name)
Resolve a username to a passwd entry.
Definition perm.c:268
int fr_perm_gid_from_str(TALLOC_CTX *ctx, gid_t *out, char const *name)
Resolve a group name to a GID.
Definition perm.c:475
fr_client_t radclient
for faking out clients
char const * name
socket name
static void mod_network_get(int *ipproto, bool *dynamic_clients, fr_trie_t const **trie, UNUSED void *instance)
static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time_p, uint8_t *buffer, size_t buffer_len, size_t *leftover)
static const conf_parser_t peercred_config[]
char const * filename
filename of control socket
static int _close_cookies(proto_control_unix_thread_t *thread)
char const * gid_name
name of GID to require
bool recv_buff_is_set
Whether we were provided with a receive buffer value.
fr_cmd_info_t * info
for running commands
fr_io_data_read_t read
function to process data after reading
uint32_t recv_buff
How big the kernel's receive buffer should be.
fr_io_address_t * connection
for connected sockets.
fr_app_io_t proto_control_unix
static int mod_open(fr_listen_t *li)
Open a UNIX listener for control sockets.
static SINT write_stdout(void *instance, char const *buffer, INT buffer_size)
fr_bio_fd_config_t fd_config
FD BIO configuration.
char const * peer_uid_name
name of UID to require
CONF_SECTION * cs
our configuration
char const * peer_gid_name
name of GID to require
static ssize_t mod_read_init(fr_listen_t *li, UNUSED void **packet_ctx, UNUSED fr_time_t *recv_time_p, uint8_t *buffer, size_t buffer_len, UNUSED size_t *leftover)
#define FR_WRITE
static ssize_t mod_write(fr_listen_t *li, UNUSED void *packet_ctx, UNUSED fr_time_t request_time, uint8_t *buffer, size_t buffer_len, size_t written)
#define FR_READ
static SINT write_misc(void *instance, char const *buffer, INT buffer_size)
#define SINT
static int mod_connection_set(fr_listen_t *li, fr_io_address_t *connection)
static SINT write_stderr(void *instance, char const *buffer, INT buffer_size)
static int mod_fd_set(fr_listen_t *li, int fd)
Set the file descriptor for this socket.
fr_stats_t stats
statistics for this socket
static char const * mod_name(fr_listen_t *li)
uint32_t max_packet_size
for message ring buffer.
static int mod_instantiate(module_inst_ctx_t const *mctx)
static size_t mode_names_len
static ssize_t mod_read_command(fr_listen_t *li, UNUSED void **packet_ctx, UNUSED fr_time_t *recv_time_p, uint8_t *buffer, UNUSED size_t buffer_len, UNUSED size_t *leftover)
static fr_table_num_sorted_t mode_names[]
static const conf_parser_t unix_listen_config[]
char const * uid_name
name of UID to require
static fr_client_t * mod_client_find(fr_listen_t *li, UNUSED fr_ipaddr_t const *ipaddr, UNUSED int ipproto)
#define INT
#define fr_assert(_expr)
Definition rad_assert.h:37
#define DEBUG2(fmt,...)
static bool done
Definition radclient.c:80
static int ipproto
Definition radclient.c:91
static rs_t * conf
Definition radsniff.c:52
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:355
void * data
Module's instance data.
Definition module.h:297
conf_parser_t const * config
How to convert a CONF_SECTION to a module instance.
Definition module.h:207
eap_aka_sim_process_conf_t * inst
eap_type_t type
The preferred EAP-Type of this instance of the EAP-SIM/AKA/AKA' state machine.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition syserror.c:243
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
Definition table.h:685
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition talloc.c:621
#define talloc_get_type_abort_const
Definition talloc.h:117
"server local" time.
Definition time.h:69
int fd
File descriptor if this is a live socket.
Definition socket.h:86
char const * fr_strerror(void)
Get the last library error.
Definition strerror.c:558
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64