From: Alan T. DeKok Date: Sat, 30 Nov 2024 14:44:53 +0000 (-0500) Subject: move to common functions for parsing permissions X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=48a93ddaede959e798ea1f58722cf5b2e929063e;p=thirdparty%2Ffreeradius-server.git move to common functions for parsing permissions and extend the permission parsing code to allow for text-based permissions --- diff --git a/src/lib/bio/fd_config.c b/src/lib/bio/fd_config.c index dbd14bb7ac0..31c54ab7c05 100644 --- a/src/lib/bio/fd_config.c +++ b/src/lib/bio/fd_config.c @@ -17,7 +17,7 @@ /** * $Id$ * @file lib/bio/fd_config.c - * @brief BIO abstractions for configuring file descriptors + * @brief BIO abstractions for configuring file descriptors. * * @copyright 2024 Network RADIUS SAS (legal@networkradius.com) */ @@ -37,7 +37,6 @@ static fr_table_num_sorted_t socket_type_names[] = { 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; @@ -55,35 +54,6 @@ static int socket_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *par } -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) @@ -115,24 +85,8 @@ static int mode_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CO 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("proto", 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) }, @@ -156,12 +110,12 @@ const conf_parser_t fr_bio_fd_config[] = { */ { 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("uid", fr_bio_fd_config_t, uid), .func = cf_parse_uid }, + { FR_CONF_OFFSET("gid", fr_bio_fd_config_t, gid), .func = cf_parse_gid }, - { FR_CONF_OFFSET("perm", fr_bio_fd_config_t, perm), .func = perm_parse, .dflt = "0600" }, + { FR_CONF_OFFSET("perm", fr_bio_fd_config_t, perm), .dflt = "0600", .func = cf_parse_permissions }, - { FR_CONF_OFFSET("mode", fr_bio_fd_config_t, flags), .func = mode_parse, .dflt = "read-only" }, + { FR_CONF_OFFSET("mode", fr_bio_fd_config_t, flags), .dflt = "read-only", .func = mode_parse }, { FR_CONF_OFFSET("mkdir", fr_bio_fd_config_t, mkdir) }, diff --git a/src/lib/server/cf_parse.c b/src/lib/server/cf_parse.c index 19d22d80989..8e9ddbb4351 100644 --- a/src/lib/server/cf_parse.c +++ b/src/lib/server/cf_parse.c @@ -1548,3 +1548,23 @@ int cf_parse_gid(TALLOC_CTX *ctx, void *out, UNUSED void *parent, return 0; } + +/** Generic function for resolving permissions to a mode-t + * + * Type should be FR_TYPE_VOID, struct field should be a gid_t. + */ +int cf_parse_permissions(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; +} diff --git a/src/lib/server/cf_parse.h b/src/lib/server/cf_parse.h index b30974bcbe2..2932901c292 100644 --- a/src/lib/server/cf_parse.h +++ b/src/lib/server/cf_parse.h @@ -677,6 +677,9 @@ int cf_parse_uid(TALLOC_CTX *ctx, void *out, UNUSED void *parent, int cf_parse_gid(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule); +int cf_parse_permissions(TALLOC_CTX *ctx, void *out, UNUSED void *parent, + CONF_ITEM *ci, conf_parser_t const *rule); + #ifdef __cplusplus } #endif diff --git a/src/lib/util/perm.c b/src/lib/util/perm.c index 1708f41efe7..6d1c02a5ae3 100644 --- a/src/lib/util/perm.c +++ b/src/lib/util/perm.c @@ -115,12 +115,10 @@ redo: p += 2; } else if (*p == 'o') { - /* - * People may do this, and we don't want them to be able to make configuration files - * world-writeable. - */ - fr_strerror_const("It is not possible to set 'o+...' for secure files"); - return -1; + if (p[1] != '=') goto expected_set; + + shift = 6; + p += 2; } /* else 'rwx' is implicitly "u=rwx" */ diff --git a/src/modules/rlm_detail/rlm_detail.c b/src/modules/rlm_detail/rlm_detail.c index 2acf642fcd6..194fc6f49da 100644 --- a/src/modules/rlm_detail/rlm_detail.c +++ b/src/modules/rlm_detail/rlm_detail.c @@ -47,7 +47,7 @@ RCSID("$Id$") * Holds the configuration and preparsed data for a instance of rlm_detail. */ typedef struct { - uint32_t perm; //!< Permissions to use for new files. + mode_t perm; //!< Permissions to use for new files. gid_t group; //!< Resolved group. bool group_is_set; //!< Whether group was set. @@ -67,12 +67,13 @@ typedef struct { fr_hash_table_t *ht; //!< Holds suppressed attributes. } rlm_detail_env_t; -int detail_group_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, - CONF_ITEM *ci, conf_parser_t const *rule); +/* + * @todo - put this into common function in cf_parse.c ? + */ static const conf_parser_t module_config[] = { - { FR_CONF_OFFSET("permissions", rlm_detail_t, perm), .dflt = "0600" }, - { FR_CONF_OFFSET_IS_SET("group", FR_TYPE_VOID, 0, rlm_detail_t, group), .func = detail_group_parse }, + { FR_CONF_OFFSET("permissions", rlm_detail_t, perm), .dflt = "0600", .func = cf_parse_permissions }, + { FR_CONF_OFFSET_IS_SET("group", FR_TYPE_VOID, 0, rlm_detail_t, group), .func = cf_parse_gid }, { FR_CONF_OFFSET("locking", rlm_detail_t, locking), .dflt = "no" }, { FR_CONF_OFFSET("escape_filenames", rlm_detail_t, escape), .dflt = "no" }, { FR_CONF_OFFSET("log_packet_header", rlm_detail_t, log_srcdst), .dflt = "no" }, @@ -138,32 +139,6 @@ static void CC_HINT(nonnull) fr_pair_fprint(FILE *fp, fr_pair_t const *vp) -/** Generic function for parsing conf pair values as int - * - * @note This should be used for enum types as c99 6.4.4.3 states that the enumeration - * constants are of type int. - * - */ -int detail_group_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, - CONF_ITEM *ci, UNUSED conf_parser_t const *rule) -{ - char const *group; - char *endptr; - gid_t gid; - - group = cf_pair_value(cf_item_to_pair(ci)); - gid = strtol(group, &endptr, 10); - if (*endptr != '\0') { - if (fr_perm_gid_from_str(parent, &gid, group) < 0) { - cf_log_err(ci, "Unable to find system group '%s'", group); - return -1; - } - } - *((gid_t *)out) = gid; - - return 0; -} - static uint32_t detail_hash(void const *data) { fr_dict_attr_t const *da = data; diff --git a/src/modules/rlm_linelog/rlm_linelog.c b/src/modules/rlm_linelog/rlm_linelog.c index d57de4da7ae..78edc856ed1 100644 --- a/src/modules/rlm_linelog/rlm_linelog.c +++ b/src/modules/rlm_linelog/rlm_linelog.c @@ -116,7 +116,7 @@ typedef struct { } syslog; struct { - uint32_t permissions; //!< Permissions to use when creating new files. + mode_t permissions; //!< Permissions to use when creating new files. char const *group_str; //!< Group to set on new files. gid_t group; //!< Resolved gid. exfile_t *ef; //!< Exclusive file access handle. @@ -141,7 +141,7 @@ typedef struct { static const conf_parser_t file_config[] = { - { FR_CONF_OFFSET("permissions", rlm_linelog_t, file.permissions), .dflt = "0600" }, + { FR_CONF_OFFSET("permissions", rlm_linelog_t, file.permissions), .dflt = "0600", .func = cf_parse_permissions }, { FR_CONF_OFFSET("group", rlm_linelog_t, file.group_str) }, { FR_CONF_OFFSET("escape_filenames", rlm_linelog_t, file.escape), .dflt = "no" }, { FR_CONF_OFFSET("fsync", rlm_linelog_t, file.fsync), .dflt = "no" }, diff --git a/src/modules/rlm_radutmp/rlm_radutmp.c b/src/modules/rlm_radutmp/rlm_radutmp.c index 0b05b004934..e5186eb149a 100644 --- a/src/modules/rlm_radutmp/rlm_radutmp.c +++ b/src/modules/rlm_radutmp/rlm_radutmp.c @@ -55,7 +55,7 @@ typedef struct { typedef struct { rlm_radutmp_mutable_t *mutable; bool check_nas; - uint32_t permission; + mode_t permission; bool caller_id_ok; } rlm_radutmp_t; @@ -66,7 +66,7 @@ typedef struct { static const conf_parser_t module_config[] = { { FR_CONF_OFFSET("check_with_nas", rlm_radutmp_t, check_nas), .dflt = "yes" }, - { FR_CONF_OFFSET("permissions", rlm_radutmp_t, permission), .dflt = "0644" }, + { FR_CONF_OFFSET("permissions", rlm_radutmp_t, permission), .dflt = "0644", .func = cf_parse_permissions }, { FR_CONF_OFFSET("caller_id", rlm_radutmp_t, caller_id_ok), .dflt = "no" }, CONF_PARSER_TERMINATOR };