From: Alan T. DeKok Date: Fri, 29 Nov 2024 20:17:07 +0000 (-0500) Subject: add conf_parser_t for FD BIO X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9dc15c4b0259c29fd604d2c783fd65b54a08c03c;p=thirdparty%2Ffreeradius-server.git add conf_parser_t for FD BIO and put it into a separate library, as some things want the BIOs, but don't want to pull in all of libfreeradius-server, unlang, etc. --- diff --git a/src/lib/bio/all.mk b/src/lib/bio/all.mk index 08d11b098f0..eb7c6d52deb 100644 --- a/src/lib/bio/all.mk +++ b/src/lib/bio/all.mk @@ -1,18 +1,3 @@ -TARGET := libfreeradius-bio$(L) +SUBMAKEFILES := libfreeradius-bio.mk \ + libfreeradius-bio-config.mk -SOURCES := \ - base.c \ - buf.c \ - fd.c \ - fd_open.c \ - haproxy.c \ - mem.c \ - network.c \ - null.c \ - packet.c \ - pipe.c \ - queue.c \ - dedup.c \ - retry.c - -TGT_PREREQS := libfreeradius-util$(L) diff --git a/src/lib/bio/fd.h b/src/lib/bio/fd.h index de40208e60f..da94a7cfa45 100644 --- a/src/lib/bio/fd.h +++ b/src/lib/bio/fd.h @@ -30,6 +30,8 @@ RCSIDH(lib_bio_fd_h, "$Id$") #include #include +#include + #include /* @@ -102,8 +104,16 @@ typedef struct { bool async; //!< is it async bool tcp_delay; //!< We do tcp_nodelay by default. + + /* + * Extra fields for conf_parser_t + */ + bool recv_buff_is_set; //!< Whether we were provided with a recv_buf + bool send_buff_is_set; //!< Whether we were provided with a send_buf } fr_bio_fd_config_t; +extern const conf_parser_t fr_bio_fd_config[]; + /** Run-time status of the socket. * */ diff --git a/src/lib/bio/fd_config.c b/src/lib/bio/fd_config.c new file mode 100644 index 00000000000..dbd14bb7ac0 --- /dev/null +++ b/src/lib/bio/fd_config.c @@ -0,0 +1,173 @@ +/* + * This program is is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * $Id$ + * @file lib/bio/fd_config.c + * @brief BIO abstractions for configuring file descriptors + * + * @copyright 2024 Network RADIUS SAS (legal@networkradius.com) + */ + +#include +#include +#include + +#include + +static fr_table_num_sorted_t socket_type_names[] = { + { L("udp"), SOCK_DGRAM }, + { L("datagram"), SOCK_DGRAM }, + { L("tcp"), SOCK_STREAM }, + { L("stream"), SOCK_STREAM }, +}; +static size_t socket_type_names_len = NUM_ELEMENTS(socket_type_names); + + + +static int socket_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule) +{ + int type; + char const *name = cf_pair_value(cf_item_to_pair(ci)); + + type = fr_table_value_by_str(socket_type_names, name, -1); + if (type < 0) { + cf_log_err(ci, "Invalid protocol name \"%s\"", name); + return -1; + } + + *(int *) out = type; + + return 0; +} + + +static int uid_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule) +{ + struct passwd *pwd; + uid_t *uid = (uid_t *) out; + char const *name = cf_pair_value(cf_item_to_pair(ci)); + + if (fr_perm_getpwnam(ctx, &pwd, name) < 0) { + cf_log_perr(ci, "Failed getting uid from name %s", name); + return -1; + } + + *uid = pwd->pw_uid; + talloc_free(pwd); + return 0; +} + +static int gid_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule) +{ + gid_t *gid = (gid_t *) out; + char const *name = cf_pair_value(cf_item_to_pair(ci)); + + if (fr_perm_gid_from_str(ctx, gid, name) < 0) { + cf_log_perr(ci, "Failed getting gid from name %s", name); + return -1; + } + + return 0; +} + +#define FR_READ (1) +#define FR_WRITE (2) + +static fr_table_num_sorted_t mode_names[] = { + { L("read-only"), FR_READ }, + { L("read-write"), FR_READ | FR_WRITE }, + { L("ro"), FR_READ }, + { L("rw"), FR_READ | FR_WRITE } +}; +static size_t mode_names_len = NUM_ELEMENTS(mode_names); + +static int mode_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule) +{ + int mode; + char const *name = cf_pair_value(cf_item_to_pair(ci)); + + mode = fr_table_value_by_str(mode_names, name, 0); + if (!mode) { + cf_log_err(ci, "Invalid mode name \"%s\"", name); + return -1; + } + + if ((mode & FR_WRITE) == 0) { + *(int *) out = O_RDWR; + } else { + *(int *) out = O_RDONLY; + } + + return 0; +} + +static int perm_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule) +{ + mode_t mode; + char const *name = cf_pair_value(cf_item_to_pair(ci)); + + if (fr_perm_mode_from_str(&mode, name) < 0) { + cf_log_perr(ci, "Invalid permissions string"); + return -1; + } + + *(mode_t *) out = mode; + + return 0; +} + + +const conf_parser_t fr_bio_fd_config[] = { + { FR_CONF_OFFSET("uid", fr_bio_fd_config_t, socket_type), .func = socket_type_parse }, + + { FR_CONF_OFFSET_TYPE_FLAGS("ipaddr", FR_TYPE_COMBO_IP_ADDR, 0, fr_bio_fd_config_t, dst_ipaddr), }, + { FR_CONF_OFFSET_TYPE_FLAGS("ipv4addr", FR_TYPE_IPV4_ADDR, 0, fr_bio_fd_config_t, dst_ipaddr) }, + { FR_CONF_OFFSET_TYPE_FLAGS("ipv6addr", FR_TYPE_IPV6_ADDR, 0, fr_bio_fd_config_t, dst_ipaddr) }, + + { FR_CONF_OFFSET("port", fr_bio_fd_config_t, dst_port) }, + + { FR_CONF_OFFSET_TYPE_FLAGS("src_ipaddr", FR_TYPE_COMBO_IP_ADDR, 0, fr_bio_fd_config_t, src_ipaddr) }, + { FR_CONF_OFFSET_TYPE_FLAGS("src_ipv4addr", FR_TYPE_IPV4_ADDR, 0, fr_bio_fd_config_t, src_ipaddr) }, + { FR_CONF_OFFSET_TYPE_FLAGS("src_ipv6addr", FR_TYPE_IPV6_ADDR, 0, fr_bio_fd_config_t, src_ipaddr) }, + + { FR_CONF_OFFSET("src_port", fr_bio_fd_config_t, src_port) }, + + { FR_CONF_OFFSET("interface", fr_bio_fd_config_t, interface) }, + + { FR_CONF_OFFSET_IS_SET("recv_buff", FR_TYPE_UINT32, 0, fr_bio_fd_config_t, recv_buff) }, + { FR_CONF_OFFSET_IS_SET("send_buff", FR_TYPE_UINT32, 0, fr_bio_fd_config_t, send_buff) }, + + /* + * Unix socket information + */ + { FR_CONF_OFFSET_FLAGS("filename", CONF_FLAG_REQUIRED, fr_bio_fd_config_t, filename), }, + + { FR_CONF_OFFSET("uid", fr_bio_fd_config_t, uid), .func = uid_parse }, + { FR_CONF_OFFSET("gid", fr_bio_fd_config_t, gid), .func = gid_parse }, + + { FR_CONF_OFFSET("perm", fr_bio_fd_config_t, perm), .func = perm_parse, .dflt = "0600" }, + + { FR_CONF_OFFSET("mode", fr_bio_fd_config_t, flags), .func = mode_parse, .dflt = "read-only" }, + + { FR_CONF_OFFSET("mkdir", fr_bio_fd_config_t, mkdir) }, + + { FR_CONF_OFFSET("async", fr_bio_fd_config_t, async), .dflt = "true" }, + + { FR_CONF_OFFSET("delay_tcp_writes", fr_bio_fd_config_t, tcp_delay) }, + + CONF_PARSER_TERMINATOR +}; diff --git a/src/lib/bio/libfreeradius-bio-config.mk b/src/lib/bio/libfreeradius-bio-config.mk new file mode 100644 index 00000000000..a4868c8ed01 --- /dev/null +++ b/src/lib/bio/libfreeradius-bio-config.mk @@ -0,0 +1,6 @@ +TARGET := libfreeradius-bio-config$(L) + +SOURCES := \ + fd_config.c + +TGT_PREREQS := libfreeradius-bio$(L) diff --git a/src/lib/bio/libfreeradius-bio.mk b/src/lib/bio/libfreeradius-bio.mk new file mode 100644 index 00000000000..08d11b098f0 --- /dev/null +++ b/src/lib/bio/libfreeradius-bio.mk @@ -0,0 +1,18 @@ +TARGET := libfreeradius-bio$(L) + +SOURCES := \ + base.c \ + buf.c \ + fd.c \ + fd_open.c \ + haproxy.c \ + mem.c \ + network.c \ + null.c \ + packet.c \ + pipe.c \ + queue.c \ + dedup.c \ + retry.c + +TGT_PREREQS := libfreeradius-util$(L)