25 #include <freeradius-devel/server/main_config.h>
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/server/protocol.h>
31 #include <freeradius-devel/util/perm.h>
32 #include <freeradius-devel/util/trie.h>
33 #include <freeradius-devel/util/file.h>
39 #include <freeradius-devel/bio/fd.h>
41 #ifdef HAVE_SYS_STAT_H
104 .dflt =
"${run_dir}/radiusd.sock}" },
169 if (hdr->
length >=
sizeof(
string))
goto fail;
182 memcpy(
string, cmd, hdr->
length);
183 string[hdr->
length] =
'\0';
204 if (hdr->
length < 2)
goto fail;
206 start = (
string[0] << 8) |
string[1];
217 DEBUG(
"ERROR: Ignoring data which is from wrong input");
221 DEBUG(
"radmin-remote> %.*s", (
int) hdr->
length, cmd);
228 }
else if (rcode == 0) {
240 status = htonl(status);
256 DEBUG(
"ERROR: Connection is missing initial ACK packet.");
260 if (buffer_len <
sizeof(*hdr)) {
261 DEBUG(
"ERROR: Initial ACK is malformed");
265 if (htonl(hdr->
length) != 8) {
266 DEBUG(
"ERROR: Initial ACK has wrong length (%lu).", (
size_t) htonl(hdr->
length));
270 memcpy(&magic,
buffer +
sizeof(*hdr),
sizeof(magic));
271 magic = htonl(magic);
273 DEBUG(
"ERROR: Connection from incompatible version of radmin.");
281 DEBUG(
"ERROR: Blocking write to socket... oops");
303 DEBUG2(
"proto_control_unix got read error %zd: %s", data_size,
fr_syserror(errno));
328 DEBUG3(
"proto_control_unix - Received command packet length %d on %s",
329 (
int) data_size, thread->
name);
334 return thread->
read(li, packet_ctx, recv_time_p,
buffer, (
size_t) data_size, leftover);
355 data_size = write(thread->
sockfd,
buffer + written, buffer_len - written);
360 if (data_size <= 0)
return data_size;
373 if (data_size + written > SSIZE_MAX)
return -1;
376 return data_size + written;
394 *dynamic_clients =
false;
416 .socket_type = SOCK_STREAM,
417 .path =
inst->filename,
426 PERROR(
"Failed allocating UNIX path %s",
inst->filename);
458 #if !defined(HAVE_GETPEEREID) && defined(SO_PEERCRED)
459 static int getpeereid(
int s, uid_t *euid, gid_t *egid)
462 socklen_t cl =
sizeof(cr);
464 if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cl) < 0) {
474 #define HAVE_GETPEEREID (1)
482 if (thread->
misc) fclose(thread->
misc);
497 #ifdef HAVE_GETPEEREID
505 if (
inst->peer_uid ||
inst->peer_gid) {
509 if (getpeereid(fd, &uid, &gid) < 0) {
510 ERROR(
"Failed getting peer credentials for %s: %s",
524 if (
inst->peer_uid_name && (
inst->peer_uid == uid))
break;
525 if (
inst->peer_gid_name && (
inst->peer_gid == gid))
break;
527 if (
inst->peer_uid_name && (
inst->peer_uid != uid)) {
528 ERROR(
"Unauthorized connection to %s from uid %ld",
529 inst->filename, (
long int) uid);
533 if (
inst->peer_gid_name && (
inst->peer_gid != gid)) {
534 ERROR(
"Unauthorized connection to %s from gid %ld",
535 inst->filename, (
long int) gid);
543 (
unsigned int) uid, (
unsigned int) gid);
577 (void) setvbuf(thread->
stdout_fp, NULL, _IOLBF, 0);
578 (void) setvbuf(thread->
stderr_fp, NULL, _IOLBF, 0);
579 (void) setvbuf(thread->
misc, NULL, _IOLBF, 0);
602 if (
inst->recv_buff_is_set) {
607 if (
inst->uid_name) {
611 PERROR(
"Failed getting uid for %s",
inst->uid_name);
614 inst->uid = pwd->pw_uid;
621 inst->uid = getuid();
624 if (
inst->gid_name) {
626 PERROR(
"Failed getting gid for %s",
inst->gid_name);
634 inst->gid = getgid();
640 if (
inst->peer_uid_name) {
644 PERROR(
"Failed getting peer uid for %s",
inst->peer_uid_name);
647 inst->peer_uid = pwd->pw_uid;
651 if (
inst->peer_gid_name) {
653 PERROR(
"Failed getting peer gid for %s",
inst->peer_gid_name);
658 if (!
inst->mode_name) {
659 inst->read_only =
true;
665 ERROR(
"Invalid mode name \"%s\"",
671 inst->read_only =
true;
673 inst->read_only =
false;
694 .name =
"control_unix",
700 .default_message_size = 4096,
static int const char char buffer[256]
module_t common
Common fields to all loadable modules.
Public structure describing an I/O path for a protocol.
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.
void fr_radmin_complete(FILE *fp, const char *text, int start)
void fr_radmin_help(FILE *fp, char const *text)
#define L(_str)
Helper for initialising arrays of string literals.
#define CONF_PARSER_TERMINATOR
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
#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
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
#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,...
#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
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Defines a CONF_PAIR to C data type mapping.
Common header for all CONF_* types.
A section grouping multiple CONF_PAIR.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
int fr_command_clear(int new_argc, fr_cmd_info_t *info)
Clear out any value boxes etc.
void fr_command_info_init(TALLOC_CTX *ctx, fr_cmd_info_t *info)
Initialize an fr_cmd_info_t structure.
ssize_t fr_conduit_write(int fd, fr_conduit_type_t conduit, void const *out, size_t outlen)
ssize_t fr_conduit_read_async(int fd, fr_conduit_type_t *pconduit, void *out, size_t outlen, size_t *leftover, bool *want_more)
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
fr_bio_t * fr_bio_fd_alloc(TALLOC_CTX *ctx, fr_bio_fd_config_t const *cfg, size_t offset)
Allocate a FD bio.
fr_bio_fd_info_t const * fr_bio_fd_info(fr_bio_t *bio)
Returns a pointer to the bio-specific information.
fr_socket_t socket
as connected socket
@ FR_BIO_FD_LISTEN
returns new fd in buffer on fr_bio_read() or fr_bio_fd_accept()
fr_bio_fd_type_t type
accept, connected, unconnected, etc.
Configuration for sockets.
Run-time status of the socket.
FILE * fopencookie(void *cookie, const char *mode, cookie_io_functions_t io_funcs)
cookie_close_function_t close
cookie_seek_function_t seek
cookie_read_function_t read
cookie_write_function_t write
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.
void const * app_io_instance
I/O path configuration context.
void * thread_instance
thread / socket context
int fd
file descriptor for this socket - set by open
char const * server
Name of the virtual server client is associated with.
fr_ipaddr_t ipaddr
IPv4/IPv6 address of the host.
fr_ipaddr_t src_ipaddr
IPv4/IPv6 address to send responses from (family must match ipaddr).
char const * longname
Client identifier.
CONF_SECTION * server_cs
Virtual server that the client is associated with.
Describes a host allowed to send packets to the server.
main_config_t const * main_config
Main server configuration.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for instantiation calls.
int fr_perm_getpwnam(TALLOC_CTX *ctx, struct passwd **out, char const *name)
Resolve a username to a passwd entry.
int fr_perm_gid_from_str(TALLOC_CTX *ctx, gid_t *out, char const *name)
Resolve a group name to a GID.
fr_conduit_type_t misc_conduit
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 char const * mod_name(fr_listen_t *li)
static SINT write_stdout(void *instance, char const *buffer, INT buffer_size)
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)
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)
static SINT write_misc(void *instance, char const *buffer, INT buffer_size)
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
uint32_t max_packet_size
for message ring buffer.
static fr_client_t * mod_client_find(fr_listen_t *li, UNUSED fr_ipaddr_t const *ipaddr, UNUSED int ipproto)
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
CONF_SECTION * conf
Module's instance configuration.
void * data
Module's instance data.
fr_uint_t total_responses
eap_aka_sim_process_conf_t * inst
#define fr_time()
Allow us to arbitrarily manipulate time.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
An element in a lexicographically sorted array of name to num mappings.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
#define talloc_get_type_abort_const
int fd
File descriptor if this is a live socket.