]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Move user/group/permissions functions into util library
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 27 Apr 2021 17:23:58 +0000 (12:23 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 27 Apr 2021 17:43:02 +0000 (12:43 -0500)
13 files changed:
src/lib/server/cf_file.c
src/lib/server/exfile.c
src/lib/server/main_config.c
src/lib/server/util.c
src/lib/server/util.h
src/lib/util/libfreeradius-util.mk
src/lib/util/perm.c [new file with mode: 0644]
src/lib/util/perm.h [new file with mode: 0644]
src/listen/control/proto_control_unix.c
src/modules/rlm_detail/rlm_detail.c
src/modules/rlm_linelog/rlm_linelog.c
src/modules/rlm_opendirectory/rlm_opendirectory.c
src/modules/rlm_unix/rlm_unix.c

index 176e6d2c5d5fc4ca1c0d7c74cda3c7eed3bee93d..7a05229af30aa62b7ee79ed3efca21a0b97682ae 100644 (file)
@@ -38,6 +38,7 @@ RCSID("$Id$")
 #include <freeradius-devel/server/virtual_servers.h>
 #include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/util/misc.h>
+#include <freeradius-devel/util/perm.h>
 #include <freeradius-devel/util/syserror.h>
 
 #include <sys/types.h>
@@ -623,7 +624,7 @@ bool cf_file_check(CONF_SECTION *cs, char const *filename, bool check_perms)
        if (!check_perms) {
                if (stat(filename, &file->buf) < 0) {
                perm_error:
-                       rad_file_error(errno);  /* Write error and euid/egid to error buff */
+                       fr_perm_file_error(errno);      /* Write error and euid/egid to error buff */
                        PERROR("Unable to open file \"%s\"", filename);
                error:
                        if (fd >= 0) close(fd);
index 7c6668fe279947e0a3bd4daee01143e07d317bb4..901589ce48f7d0e95e0b3324d3f5986b3b0c5bf7 100644 (file)
  * @author Alan DeKok (aland@freeradius.org)
  * @copyright 2014 The FreeRADIUS server project
  */
+#include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
 #include <freeradius-devel/server/base.h>
-#include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/server/exfile.h>
-#include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
 
+#include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/util/misc.h>
+#include <freeradius-devel/util/perm.h>
+#include <freeradius-devel/util/syserror.h>
 
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -476,19 +478,19 @@ try_lock:
                char str_need[10], oct_need[5];
                char str_have[10], oct_have[5];
 
-               rad_mode_to_oct(oct_need, permissions);
-               rad_mode_to_str(str_need, permissions);
+               fr_perm_mode_to_oct(oct_need, permissions);
+               fr_perm_mode_to_str(str_need, permissions);
 
-               rad_mode_to_oct(oct_have, st.st_mode & ~S_IFMT);
-               rad_mode_to_str(str_have, st.st_mode & ~S_IFMT);
+               fr_perm_mode_to_oct(oct_have, st.st_mode & ~S_IFMT);
+               fr_perm_mode_to_str(str_have, st.st_mode & ~S_IFMT);
 
                WARN("File %s permissions are %s (%s) not %s (%s))", filename,
                     oct_have, str_have, oct_need, str_need);
 
                if (((st.st_mode | permissions) != st.st_mode) &&
                    (fchmod(ef->entries[i].fd, (st.st_mode & ~S_IFMT) | permissions) < 0)) {
-                       rad_mode_to_oct(oct_need, (st.st_mode & ~S_IFMT) | permissions);
-                       rad_mode_to_str(str_need, (st.st_mode & ~S_IFMT) | permissions);
+                       fr_perm_mode_to_oct(oct_need, (st.st_mode & ~S_IFMT) | permissions);
+                       fr_perm_mode_to_str(str_need, (st.st_mode & ~S_IFMT) | permissions);
 
                        WARN("Failed resetting file %s permissions to %s (%s): %s",
                             filename, oct_need, str_need, fr_syserror(errno));
index 85e899476ad74f22bf495f17364e020c1880c6c6..198dd0c1488d4da84905fb71ad65259a17cdba6c 100644 (file)
@@ -40,6 +40,7 @@ RCSID("$Id$")
 #include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/util/dict.h>
 #include <freeradius-devel/util/file.h>
+#include <freeradius-devel/util/perm.h>
 #include <freeradius-devel/util/sem.h>
 
 #include <sys/stat.h>
@@ -372,7 +373,7 @@ static int uid_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent,
 
        uid_name = cf_pair_value(cf_item_to_pair(ci));
 
-       if (rad_getpwnam(ctx, &user, uid_name) < 0) {
+       if (fr_perm_getpwnam(ctx, &user, uid_name) < 0) {
                cf_log_perr(ci, "Cannot get passwd entry for user \"%s\"", uid_name);
                return 0;
        }
@@ -392,7 +393,7 @@ static int gid_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent,
 
        gid_name = cf_pair_value(cf_item_to_pair(ci));
 
-       if (rad_getgrnam(ctx, &group, gid_name) < 0) {
+       if (fr_perm_getgrnam(ctx, &group, gid_name) < 0) {
                cf_log_perr(ci, "Cannot resolve group name \"%s\"", gid_name);
                return 0;
        }
@@ -629,7 +630,7 @@ static int switch_users(main_config_t *config, CONF_SECTION *cs)
                {
                        struct passwd *user;
 
-                       if (rad_getpwuid(config, &user, config->uid) < 0) {
+                       if (fr_perm_getpwuid(config, &user, config->uid) < 0) {
                                fprintf(stderr, "%s: Failed resolving UID %i: %s\n",
                                        config->name, (int)config->uid, fr_syserror(errno));
                                return -1;
@@ -690,7 +691,7 @@ static int switch_users(main_config_t *config, CONF_SECTION *cs)
                if (setgid(config->server_gid) < 0) {
                        struct group *group;
 
-                       if (rad_getgrgid(config, &group, config->gid) < 0) {
+                       if (fr_perm_getgrgid(config, &group, config->gid) < 0) {
                                        fprintf(stderr, "%s: Failed resolving GID %i: %s\n",
                                                config->name, (int)config->gid, fr_syserror(errno));
                                        return -1;
index e494976c54953cfa98890035ba8698389196cbc9..84354e9ef5fa5bff66930d09780dcefbfd498750 100644 (file)
@@ -22,7 +22,6 @@
 
 RCSID("$Id$")
 
-
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/stats.h>
 #include <freeradius-devel/server/util.h>
@@ -30,6 +29,7 @@ RCSID("$Id$")
 #include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/util/hex.h>
 #include <freeradius-devel/util/misc.h>
+#include <freeradius-devel/util/perm.h>
 
 #include <ctype.h>
 #include <fcntl.h>
@@ -679,371 +679,6 @@ int rad_expand_xlat(request_t *request, char const *cmd,
        return argc;
 }
 
-/** Convert mode_t into humanly readable permissions flags
- *
- * @author Jonathan Leffler.
- *
- * @param mode to convert.
- * @param out Where to write the string to, must be exactly 10 bytes long.
- */
-void rad_mode_to_str(char out[static 10], mode_t mode)
-{
-       static char const *rwx[] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
-
-       strcpy(&out[0], rwx[(mode >> 6) & 0x07]);
-       strcpy(&out[3], rwx[(mode >> 3) & 0x07]);
-       strcpy(&out[6], rwx[(mode & 7)]);
-       if (mode & S_ISUID) out[2] = (mode & 0100) ? 's' : 'S';
-       if (mode & S_ISGID) out[5] = (mode & 0010) ? 's' : 'l';
-       if (mode & S_ISVTX) out[8] = (mode & 0100) ? 't' : 'T';
-       out[9] = '\0';
-}
-
-void rad_mode_to_oct(char out[static 5], mode_t mode)
-{
-       out[0] = '0' + ((mode >> 9) & 0x07);
-       out[1] = '0' + ((mode >> 6) & 0x07);
-       out[2] = '0' + ((mode >> 3) & 0x07);
-       out[3] = '0' + (mode & 0x07);
-       out[4] = '\0';
-}
-
-/** Resolve a uid to a passwd entry
- *
- * Resolves a uid to a passwd entry. The memory to hold the
- * passwd entry is talloced under ctx, and must be freed when no
- * longer required.
- *
- * @param ctx to allocate passwd entry in.
- * @param out Where to write pointer to entry.
- * @param uid to resolve.
- * @return
- *     - 0 on success.
- *     - -1 on failure.
- */
-int rad_getpwuid(TALLOC_CTX *ctx, struct passwd **out, uid_t uid)
-{
-       static size_t len;
-       uint8_t *buff;
-       int ret;
-
-       *out = NULL;
-
-       /*
-        *      We assume this won't change between calls,
-        *      and that the value is the same, so races don't
-        *      matter.
-        */
-       if (len == 0) {
-#ifdef _SC_GETPW_R_SIZE_MAX
-               long int sc_len;
-
-               sc_len = sysconf(_SC_GETPW_R_SIZE_MAX);
-               if (sc_len <= 0) sc_len = 1024;
-               len = (size_t)sc_len;
-#else
-               len = 1024;
-#endif
-       }
-
-       buff = talloc_array(ctx, uint8_t, sizeof(struct passwd) + len);
-       if (!buff) return -1;
-
-       /*
-        *      In some cases we may need to dynamically
-        *      grow the string buffer.
-        */
-       while ((ret = getpwuid_r(uid, (struct passwd *)buff, (char *)(buff + sizeof(struct passwd)),
-                                talloc_array_length(buff) - sizeof(struct passwd), out)) == ERANGE) {
-               MEM(buff = talloc_realloc_size(ctx, buff, talloc_array_length(buff) * 2));
-       }
-
-       if ((ret != 0) || !*out) {
-               fr_strerror_printf("%s", (errno != 0) ? fr_syserror(ret) : "Non-existent user");
-               talloc_free(buff);
-               errno = ret;
-               return -1;
-       }
-
-       talloc_set_type(buff, struct passwd);
-       *out = (struct passwd *)buff;
-
-       return 0;
-}
-
-/** Resolve a username to a passwd entry
- *
- * Resolves a username to a passwd entry. The memory to hold the
- * passwd entry is talloced under ctx, and must be freed when no
- * longer required.
- *
- * @param ctx to allocate passwd entry in.
- * @param out Where to write pointer to entry.
- * @param name to resolve.
- * @return
- *     - 0 on success.
- *     - -1 on failure.
- */
-int rad_getpwnam(TALLOC_CTX *ctx, struct passwd **out, char const *name)
-{
-       static size_t len;
-       uint8_t *buff;
-       int ret;
-
-       *out = NULL;
-
-       /*
-        *      We assume this won't change between calls,
-        *      and that the value is the same, so races don't
-        *      matter.
-        */
-       if (len == 0) {
-#ifdef _SC_GETPW_R_SIZE_MAX
-               long int sc_len;
-
-               sc_len = sysconf(_SC_GETPW_R_SIZE_MAX);
-               if (sc_len <= 0) sc_len = 1024;
-               len = (size_t)sc_len;
-#else
-               sc_len = 1024;
-#endif
-       }
-
-       buff = talloc_array(ctx, uint8_t, sizeof(struct passwd) + len);
-       if (!buff) return -1;
-
-       /*
-        *      In some cases we may need to dynamically
-        *      grow the string buffer.
-        */
-       while ((ret = getpwnam_r(name, (struct passwd *)buff, (char *)(buff + sizeof(struct passwd)),
-                                talloc_array_length(buff) - sizeof(struct passwd), out)) == ERANGE) {
-               MEM(buff = talloc_realloc_size(ctx, buff, talloc_array_length(buff) * 2));
-       }
-
-       if ((ret != 0) || !*out) {
-               fr_strerror_printf("%s", (errno != 0) ? fr_syserror(ret) : "Non-existent user");
-               talloc_free(buff);
-               errno = ret;
-               return -1;
-       }
-
-       talloc_set_type(buff, struct passwd);
-       *out = (struct passwd *)buff;
-
-       return 0;
-}
-
-/** Resolve a gid to a group database entry
- *
- * Resolves a gid to a group database entry. The memory to hold the
- * group entry is talloced under ctx, and must be freed when no
- * longer required.
- *
- * @param ctx to allocate passwd entry in.
- * @param out Where to write pointer to entry.
- * @param gid to resolve.
- * @return
- *     - 0 on success.
- *     - -1 on failure.
- */
-int rad_getgrgid(TALLOC_CTX *ctx, struct group **out, gid_t gid)
-{
-       static size_t len;
-       uint8_t *buff;
-       int ret;
-
-       *out = NULL;
-
-       /*
-        *      We assume this won't change between calls,
-        *      and that the value is the same, so races don't
-        *      matter.
-        */
-       if (len == 0) {
-#ifdef _SC_GETGR_R_SIZE_MAX
-               long int sc_len;
-
-               sc_len = sysconf(_SC_GETGR_R_SIZE_MAX);
-               if (sc_len <= 0) sc_len = 1024;
-               len = (size_t)sc_len;
-#else
-               sc_len = 1024;
-#endif
-       }
-
-       buff = talloc_array(ctx, uint8_t, sizeof(struct group) + len);
-       if (!buff) return -1;
-
-       /*
-        *      In some cases we may need to dynamically
-        *      grow the string buffer.
-        */
-       while ((ret = getgrgid_r(gid, (struct group *)buff, (char *)(buff + sizeof(struct group)),
-                                talloc_array_length(buff) - sizeof(struct group), out)) == ERANGE) {
-               MEM(buff = talloc_realloc_size(ctx, buff, talloc_array_length(buff) * 2));
-       }
-
-       if ((ret != 0) || !*out) {
-               fr_strerror_printf("%s", (ret != 0) ? fr_syserror(ret) : "Non-existent group");
-               talloc_free(buff);
-               errno = ret;
-               return -1;
-       }
-
-       talloc_set_type(buff, struct group);
-       *out = (struct group *)buff;
-
-       return 0;
-}
-
-/** Resolve a group name to a group database entry
- *
- * Resolves a group name to a group database entry.
- * The memory to hold the group entry is talloced under ctx,
- * and must be freed when no longer required.
- *
- * @param ctx to allocate passwd entry in.
- * @param out Where to write pointer to entry.
- * @param name to resolve.
- * @return
- *     - 0 on success.
- *     - -1 on failure.
- */
-int rad_getgrnam(TALLOC_CTX *ctx, struct group **out, char const *name)
-{
-       static size_t len;
-       uint8_t *buff;
-       int ret;
-
-       *out = NULL;
-
-       /*
-        *      We assume this won't change between calls,
-        *      and that the value is the same, so races don't
-        *      matter.
-        */
-       if (len == 0) {
-#ifdef _SC_GETGR_R_SIZE_MAX
-               long int sc_len;
-
-               sc_len = sysconf(_SC_GETGR_R_SIZE_MAX);
-               if (sc_len <= 0) sc_len = 1024;
-               len = (size_t)sc_len;
-#else
-               len = 1024;
-#endif
-       }
-
-       buff = talloc_array(ctx, uint8_t, sizeof(struct group) + len);
-       if (!buff) return -1;
-
-       /*
-        *      In some cases we may need to dynamically
-        *      grow the string buffer.
-        */
-       while ((ret = getgrnam_r(name, (struct group *)buff, (char *)(buff + sizeof(struct group)),
-                                talloc_array_length(buff) - sizeof(struct group), out)) == ERANGE) {
-               MEM(buff = talloc_realloc_size(ctx, buff, talloc_array_length(buff) * 2));
-       }
-
-       if ((ret != 0) || !*out) {
-               fr_strerror_printf("%s", (ret != 0) ? fr_syserror(ret) : "Non-existent group");
-               talloc_free(buff);
-               errno = ret;
-               return -1;
-       }
-
-       talloc_set_type(buff, struct group);
-       *out = (struct group *)buff;
-
-       return 0;
-}
-
-/** Resolve a group name to a GID
- *
- * @param ctx TALLOC_CTX for temporary allocations.
- * @param name of group.
- * @param out where to write gid.
- * @return
- *     - 0 on success.
- *     - -1 on failure.
- */
-int rad_getgid(TALLOC_CTX *ctx, gid_t *out, char const *name)
-{
-       int ret;
-       struct group *result;
-
-       ret = rad_getgrnam(ctx, &result, name);
-       if (ret < 0) return -1;
-
-       *out = result->gr_gid;
-       talloc_free(result);
-       return 0;
-}
-
-/** Print uid to a string
- *
- * @param ctx TALLOC_CTX for temporary allocations.
- * @param uid to resolve.
- * @return
- *     - 0 on success.
- *     - -1 on failure.
- */
-char *rad_asprint_uid(TALLOC_CTX *ctx, uid_t uid)
-{
-       struct passwd *result;
-       char *out;
-
-       if (rad_getpwuid(ctx, &result, uid) < 0) return NULL;
-       out = talloc_typed_strdup(ctx, result->pw_name);
-       talloc_free(result);
-
-       return out;
-}
-
-/** Print gid to a string
- *
- * @param ctx TALLOC_CTX for temporary allocations.
- * @param gid to resolve.
- * @return
- *     - 0 on success.
- *     - -1 on failure.
- */
-char *rad_asprint_gid(TALLOC_CTX *ctx, uid_t gid){
-       struct group *result;
-       char *out;
-
-       if (rad_getgrgid(ctx, &result, gid) < 0) return NULL;
-       out = talloc_typed_strdup(ctx, result->gr_name);
-       talloc_free(result);
-
-       return out;
-}
-
-/** Write a file access error to the fr_strerror buffer, including euid/egid
- *
- * @note retrieve error with fr_strerror()
- *
- * @param num Usually errno, unless the error is returned by the function.
- */
-void rad_file_error(int num)
-{
-       char const      *error;
-       struct passwd   *user = NULL;
-       struct group    *group = NULL;
-
-       error = fr_syserror(num);
-
-       if (rad_getpwuid(NULL, &user, geteuid()) < 0) goto finish;
-       if (rad_getgrgid(NULL, &group, getegid()) < 0) goto finish;
-
-       fr_strerror_printf("Effective user/group - %s:%s: %s", user->pw_name, group->gr_name, error);
-finish:
-       talloc_free(user);
-       talloc_free(group);
-}
-
 #ifdef HAVE_SETUID
 static bool doing_setuid = false;
 static uid_t suid_down_uid = (uid_t)-1;
@@ -1089,7 +724,7 @@ void rad_suid_down(void)
                struct passwd *passwd;
                char const *name;
 
-               name = (rad_getpwuid(NULL, &passwd, suid_down_uid) < 0) ? "unknown" : passwd->pw_name;
+               name = (fr_perm_getpwuid(NULL, &passwd, suid_down_uid) < 0) ? "unknown" : passwd->pw_name;
                ERROR("Failed switching to uid %s: %s", name, fr_syserror(errno));
                talloc_free(passwd);
                fr_exit_now(EXIT_FAILURE);
@@ -1111,7 +746,7 @@ void rad_suid_down_permanent(void)
                struct passwd *passwd;
                char const *name;
 
-               name = (rad_getpwuid(NULL, &passwd, suid_down_uid) < 0) ? "unknown" : passwd->pw_name;
+               name = (fr_perm_getpwuid(NULL, &passwd, suid_down_uid) < 0) ? "unknown" : passwd->pw_name;
                ERROR("Failed in permanent switch to uid %s: %s", name, fr_syserror(errno));
                talloc_free(passwd);
                fr_exit_now(EXIT_FAILURE);
@@ -1151,7 +786,7 @@ void rad_suid_down(void)
                struct passwd *passwd;
                char const *name;
 
-               name = (rad_getpwuid(NULL, &passwd, suid_down_uid) < 0) ? "unknown": passwd->pw_name;
+               name = (fr_perm_getpwuid(NULL, &passwd, suid_down_uid) < 0) ? "unknown": passwd->pw_name;
                ERROR("Failed switching to euid %s: %s", name, fr_syserror(errno));
                talloc_free(passwd);
                fr_exit_now(EXIT_FAILURE);
@@ -1181,7 +816,7 @@ void rad_suid_down_permanent(void)
                struct passwd *passwd;
                char const *name;
 
-               name = (rad_getpwuid(NULL, &passwd, suid_down_uid) < 0) ? "unknown": passwd->pw_name;
+               name = (fr_perm_getpwuid(NULL, &passwd, suid_down_uid) < 0) ? "unknown": passwd->pw_name;
                ERROR("Failed switching permanently to uid %s: %s", name, fr_syserror(errno));
                talloc_free(passwd);
                fr_exit_now(EXIT_FAILURE);
@@ -1233,10 +868,10 @@ bool rad_suid_is_down_permanent(void)
 int rad_seuid(uid_t uid)
 {
        if (seteuid(uid) < 0) {
-               int sete_errno = errno; /* errno sets overwritten by rad_getpwuid */
+               int sete_errno = errno; /* errno sets overwritten by fr_perm_getpwuid */
                struct passwd *passwd;
 
-               if (rad_getpwuid(NULL, &passwd, uid) < 0) return -1;
+               if (fr_perm_getpwuid(NULL, &passwd, uid) < 0) return -1;
                fr_strerror_printf("%s", fr_syserror(sete_errno));
                talloc_free(passwd);
 
@@ -1255,10 +890,10 @@ int rad_seuid(uid_t uid)
 int rad_segid(gid_t gid)
 {
        if (setegid(gid) < 0) {
-               int sete_errno = errno; /* errno sets overwritten by rad_getgrgid */
+               int sete_errno = errno; /* errno sets overwritten by fr_perm_getgrgid */
                struct group *group;
 
-               if (rad_getgrgid(NULL, &group, gid) < 0) return -1;
+               if (fr_perm_getgrgid(NULL, &group, gid) < 0) return -1;
                fr_strerror_printf("%s", fr_syserror(sete_errno));
                talloc_free(group);
 
index ae4bb0512a58d26cce872fabeb7581870fe8a61c..565775a335cff52c6da40f4738df80f2d382f78b 100644 (file)
@@ -46,16 +46,6 @@ int          rad_expand_xlat(request_t *request, char const *cmd,
                                int max_argc, char const *argv[], bool can_fail,
                                size_t argv_buflen, char *argv_buf);
 
-void           rad_mode_to_str(char out[static 10], mode_t mode);
-void           rad_mode_to_oct(char out[static 5], mode_t mode);
-int            rad_getpwuid(TALLOC_CTX *ctx, struct passwd **out, uid_t uid);
-int            rad_getpwnam(TALLOC_CTX *ctx, struct passwd **out, char const *name);
-int            rad_getgrgid(TALLOC_CTX *ctx, struct group **out, gid_t gid);
-int            rad_getgrnam(TALLOC_CTX *ctx, struct group **out, char const *name);
-int            rad_getgid(TALLOC_CTX *ctx, gid_t *out, char const *name);
-char           *rad_asprint_uid(TALLOC_CTX *ctx, uid_t uid);
-char           *rad_asprint_gid(TALLOC_CTX *ctx, gid_t gid);
-void           rad_file_error(int num);
 int            rad_seuid(uid_t uid);
 int            rad_segid(gid_t gid);
 
index e3a6840422353b4bf32ef14e53e762723c5722f4..f413d4c324c279f232f15a9c94247a24f6b3fbce 100644 (file)
@@ -52,6 +52,7 @@ SOURCES               := \
                   pair_tokenize.c \
                   paths.c \
                   pcap.c \
+                  perm.c \
                   print.c \
                   proto.c \
                   rand.c \
diff --git a/src/lib/util/perm.c b/src/lib/util/perm.c
new file mode 100644 (file)
index 0000000..4f5572b
--- /dev/null
@@ -0,0 +1,392 @@
+/*
+ *   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
+ */
+
+/** Implementation of filed semaphores that release on exit
+ *
+ * @file src/lib/util/perm.c
+ *
+ * @copyright 2021 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
+ */
+RCSID("$Id$")
+
+#include <freeradius-devel/util/perm.h>
+#include <freeradius-devel/util/strerror.h>
+#include <freeradius-devel/util/syserror.h>
+
+/** Convert mode_t into humanly readable permissions flags
+ *
+ * @author Jonathan Leffler.
+ *
+ * @param mode to convert.
+ * @param out Where to write the string to, must be exactly 10 bytes long.
+ */
+void fr_perm_mode_to_str(char out[static 10], mode_t mode)
+{
+       static char const *rwx[] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
+
+       strcpy(&out[0], rwx[(mode >> 6) & 0x07]);
+       strcpy(&out[3], rwx[(mode >> 3) & 0x07]);
+       strcpy(&out[6], rwx[(mode & 7)]);
+       if (mode & S_ISUID) out[2] = (mode & 0100) ? 's' : 'S';
+       if (mode & S_ISGID) out[5] = (mode & 0010) ? 's' : 'l';
+       if (mode & S_ISVTX) out[8] = (mode & 0100) ? 't' : 'T';
+       out[9] = '\0';
+}
+
+void fr_perm_mode_to_oct(char out[static 5], mode_t mode)
+{
+       out[0] = '0' + ((mode >> 9) & 0x07);
+       out[1] = '0' + ((mode >> 6) & 0x07);
+       out[2] = '0' + ((mode >> 3) & 0x07);
+       out[3] = '0' + (mode & 0x07);
+       out[4] = '\0';
+}
+
+/** Resolve a uid to a passwd entry
+ *
+ * Resolves a uid to a passwd entry. The memory to hold the
+ * passwd entry is talloced under ctx, and must be freed when no
+ * longer required.
+ *
+ * @param ctx to allocate passwd entry in.
+ * @param out Where to write pointer to entry.
+ * @param uid to resolve.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+int fr_perm_getpwuid(TALLOC_CTX *ctx, struct passwd **out, uid_t uid)
+{
+       static size_t len;
+       uint8_t *buff;
+       int ret;
+
+       *out = NULL;
+
+       /*
+        *      We assume this won't change between calls,
+        *      and that the value is the same, so races don't
+        *      matter.
+        */
+       if (len == 0) {
+#ifdef _SC_GETPW_R_SIZE_MAX
+               long int sc_len;
+
+               sc_len = sysconf(_SC_GETPW_R_SIZE_MAX);
+               if (sc_len <= 0) sc_len = 1024;
+               len = (size_t)sc_len;
+#else
+               len = 1024;
+#endif
+       }
+
+       buff = talloc_array(ctx, uint8_t, sizeof(struct passwd) + len);
+       if (!buff) return -1;
+
+       /*
+        *      In some cases we may need to dynamically
+        *      grow the string buffer.
+        */
+       while ((ret = getpwuid_r(uid, (struct passwd *)buff, (char *)(buff + sizeof(struct passwd)),
+                                talloc_array_length(buff) - sizeof(struct passwd), out)) == ERANGE) {
+               buff = talloc_realloc_size(ctx, buff, talloc_array_length(buff) * 2);
+       }
+
+       if ((ret != 0) || !*out) {
+               fr_strerror_printf("%s", (errno != 0) ? fr_syserror(ret) : "Non-existent user");
+               talloc_free(buff);
+               errno = ret;
+               return -1;
+       }
+
+       talloc_set_type(buff, struct passwd);
+       *out = (struct passwd *)buff;
+
+       return 0;
+}
+
+/** Resolve a username to a passwd entry
+ *
+ * Resolves a username to a passwd entry. The memory to hold the
+ * passwd entry is talloced under ctx, and must be freed when no
+ * longer required.
+ *
+ * @param ctx to allocate passwd entry in.
+ * @param out Where to write pointer to entry.
+ * @param name to resolve.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+int fr_perm_getpwnam(TALLOC_CTX *ctx, struct passwd **out, char const *name)
+{
+       static size_t len;
+       uint8_t *buff;
+       int ret;
+
+       *out = NULL;
+
+       /*
+        *      We assume this won't change between calls,
+        *      and that the value is the same, so races don't
+        *      matter.
+        */
+       if (len == 0) {
+#ifdef _SC_GETPW_R_SIZE_MAX
+               long int sc_len;
+
+               sc_len = sysconf(_SC_GETPW_R_SIZE_MAX);
+               if (sc_len <= 0) sc_len = 1024;
+               len = (size_t)sc_len;
+#else
+               sc_len = 1024;
+#endif
+       }
+
+       buff = talloc_array(ctx, uint8_t, sizeof(struct passwd) + len);
+       if (!buff) return -1;
+
+       /*
+        *      In some cases we may need to dynamically
+        *      grow the string buffer.
+        */
+       while ((ret = getpwnam_r(name, (struct passwd *)buff, (char *)(buff + sizeof(struct passwd)),
+                                talloc_array_length(buff) - sizeof(struct passwd), out)) == ERANGE) {
+               buff = talloc_realloc_size(ctx, buff, talloc_array_length(buff) * 2);
+       }
+
+       if ((ret != 0) || !*out) {
+               fr_strerror_printf("%s", (errno != 0) ? fr_syserror(ret) : "Non-existent user");
+               talloc_free(buff);
+               errno = ret;
+               return -1;
+       }
+
+       talloc_set_type(buff, struct passwd);
+       *out = (struct passwd *)buff;
+
+       return 0;
+}
+
+/** Resolve a gid to a group database entry
+ *
+ * Resolves a gid to a group database entry. The memory to hold the
+ * group entry is talloced under ctx, and must be freed when no
+ * longer required.
+ *
+ * @param ctx to allocate passwd entry in.
+ * @param out Where to write pointer to entry.
+ * @param gid to resolve.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+int fr_perm_getgrgid(TALLOC_CTX *ctx, struct group **out, gid_t gid)
+{
+       static size_t len;
+       uint8_t *buff;
+       int ret;
+
+       *out = NULL;
+
+       /*
+        *      We assume this won't change between calls,
+        *      and that the value is the same, so races don't
+        *      matter.
+        */
+       if (len == 0) {
+#ifdef _SC_GETGR_R_SIZE_MAX
+               long int sc_len;
+
+               sc_len = sysconf(_SC_GETGR_R_SIZE_MAX);
+               if (sc_len <= 0) sc_len = 1024;
+               len = (size_t)sc_len;
+#else
+               sc_len = 1024;
+#endif
+       }
+
+       buff = talloc_array(ctx, uint8_t, sizeof(struct group) + len);
+       if (!buff) return -1;
+
+       /*
+        *      In some cases we may need to dynamically
+        *      grow the string buffer.
+        */
+       while ((ret = getgrgid_r(gid, (struct group *)buff, (char *)(buff + sizeof(struct group)),
+                                talloc_array_length(buff) - sizeof(struct group), out)) == ERANGE) {
+               buff = talloc_realloc_size(ctx, buff, talloc_array_length(buff) * 2);
+       }
+
+       if ((ret != 0) || !*out) {
+               fr_strerror_printf("%s", (ret != 0) ? fr_syserror(ret) : "Non-existent group");
+               talloc_free(buff);
+               errno = ret;
+               return -1;
+       }
+
+       talloc_set_type(buff, struct group);
+       *out = (struct group *)buff;
+
+       return 0;
+}
+
+/** Resolve a group name to a group database entry
+ *
+ * Resolves a group name to a group database entry.
+ * The memory to hold the group entry is talloced under ctx,
+ * and must be freed when no longer required.
+ *
+ * @param ctx to allocate passwd entry in.
+ * @param out Where to write pointer to entry.
+ * @param name to resolve.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+int fr_perm_getgrnam(TALLOC_CTX *ctx, struct group **out, char const *name)
+{
+       static size_t len;
+       uint8_t *buff;
+       int ret;
+
+       *out = NULL;
+
+       /*
+        *      We assume this won't change between calls,
+        *      and that the value is the same, so races don't
+        *      matter.
+        */
+       if (len == 0) {
+#ifdef _SC_GETGR_R_SIZE_MAX
+               long int sc_len;
+
+               sc_len = sysconf(_SC_GETGR_R_SIZE_MAX);
+               if (sc_len <= 0) sc_len = 1024;
+               len = (size_t)sc_len;
+#else
+               len = 1024;
+#endif
+       }
+
+       buff = talloc_array(ctx, uint8_t, sizeof(struct group) + len);
+       if (!buff) return -1;
+
+       /*
+        *      In some cases we may need to dynamically
+        *      grow the string buffer.
+        */
+       while ((ret = getgrnam_r(name, (struct group *)buff, (char *)(buff + sizeof(struct group)),
+                                talloc_array_length(buff) - sizeof(struct group), out)) == ERANGE) {
+               buff = talloc_realloc_size(ctx, buff, talloc_array_length(buff) * 2);
+       }
+
+       if ((ret != 0) || !*out) {
+               fr_strerror_printf("%s", (ret != 0) ? fr_syserror(ret) : "Non-existent group");
+               talloc_free(buff);
+               errno = ret;
+               return -1;
+       }
+
+       talloc_set_type(buff, struct group);
+       *out = (struct group *)buff;
+
+       return 0;
+}
+
+/** Resolve a group name to a GID
+ *
+ * @param ctx TALLOC_CTX for temporary allocations.
+ * @param name of group.
+ * @param out where to write gid.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+int fr_perm_gid_from_str(TALLOC_CTX *ctx, gid_t *out, char const *name)
+{
+       int ret;
+       struct group *result;
+
+       ret = fr_perm_getgrnam(ctx, &result, name);
+       if (ret < 0) return -1;
+
+       *out = result->gr_gid;
+       talloc_free(result);
+       return 0;
+}
+
+/** Print uid to a string
+ *
+ * @param ctx TALLOC_CTX for temporary allocations.
+ * @param uid to resolve.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+char *fr_perm_uid_to_str(TALLOC_CTX *ctx, uid_t uid)
+{
+       struct passwd *result;
+       char *out;
+
+       if (fr_perm_getpwuid(ctx, &result, uid) < 0) return NULL;
+       out = talloc_typed_strdup(ctx, result->pw_name);
+       talloc_free(result);
+
+       return out;
+}
+
+/** Print gid to a string
+ *
+ * @param ctx TALLOC_CTX for temporary allocations.
+ * @param gid to resolve.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+char *fr_perm_gid_to_str(TALLOC_CTX *ctx, uid_t gid){
+       struct group *result;
+       char *out;
+
+       if (fr_perm_getgrgid(ctx, &result, gid) < 0) return NULL;
+       out = talloc_typed_strdup(ctx, result->gr_name);
+       talloc_free(result);
+
+       return out;
+}
+
+/** Write a file access error to the fr_strerror buffer, including euid/egid
+ *
+ * @note retrieve error with fr_strerror()
+ *
+ * @param num Usually errno, unless the error is returned by the function.
+ */
+void fr_perm_file_error(int num)
+{
+       char const      *error;
+       struct passwd   *user = NULL;
+       struct group    *group = NULL;
+
+       error = fr_syserror(num);
+
+       if (fr_perm_getpwuid(NULL, &user, geteuid()) < 0) goto finish;
+       if (fr_perm_getgrgid(NULL, &group, getegid()) < 0) goto finish;
+
+       fr_strerror_printf("Effective user/group - %s:%s: %s", user->pw_name, group->gr_name, error);
+finish:
+       talloc_free(user);
+       talloc_free(group);
+}
diff --git a/src/lib/util/perm.h b/src/lib/util/perm.h
new file mode 100644 (file)
index 0000000..f72b57d
--- /dev/null
@@ -0,0 +1,50 @@
+#pragma once
+/*
+ *   This library is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU Lesser General Public
+ *   License as published by the Free Software Foundation; either
+ *   version 2.1 of the License, or (at your option) any later version.
+ *
+ *   This library 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
+ *   Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public
+ *   License along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/** Functions to produce and parse the FreeRADIUS presentation format
+ *
+ * @file src/lib/util/perm.h
+ *
+ * @copyright 2021 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
+ */
+RCSIDH(perm_h, "$Id$")
+
+#include <pwd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <grp.h>
+
+#include <freeradius-devel/util/talloc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void           fr_perm_mode_to_str(char out[static 10], mode_t mode);
+void           fr_perm_mode_to_oct(char out[static 5], mode_t mode);
+int            fr_perm_getpwuid(TALLOC_CTX *ctx, struct passwd **out, uid_t uid);
+int            fr_perm_getpwnam(TALLOC_CTX *ctx, struct passwd **out, char const *name);
+int            fr_perm_getgrgid(TALLOC_CTX *ctx, struct group **out, gid_t gid);
+int            fr_perm_getgrnam(TALLOC_CTX *ctx, struct group **out, char const *name);
+int            fr_perm_gid_from_str(TALLOC_CTX *ctx, gid_t *out, char const *name);
+char           *fr_perm_uid_to_str(TALLOC_CTX *ctx, uid_t uid);
+char           *fr_perm_gid_to_str(TALLOC_CTX *ctx, gid_t gid);
+void           fr_perm_file_error(int num);
+
+#ifdef __cplusplus
+}
+#endif
index 9fa8aed0a08ef0b4bec93c11468389ca1ec7d9ed..20b6218909245c522880188d99bd7c6d5e256fa5 100644 (file)
@@ -30,6 +30,7 @@
 #include <freeradius-devel/server/protocol.h>
 #include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/util/fopencookie.h>
+#include <freeradius-devel/util/perm.h>
 #include <freeradius-devel/util/socket.h>
 #include <freeradius-devel/util/trie.h>
 #include <netdb.h>
@@ -648,8 +649,8 @@ static int fr_server_domain_socket_perm(char const *path, uid_t uid, gid_t gid)
                struct passwd *user;
                struct group *group;
 
-               if (rad_getpwuid(NULL, &user, euid) < 0) goto error;
-               if (rad_getgrgid(NULL, &group, egid) < 0) {
+               if (fr_perm_getpwuid(NULL, &user, euid) < 0) goto error;
+               if (fr_perm_getgrgid(NULL, &group, egid) < 0) {
                        talloc_free(user);
                        goto error;
                }
@@ -719,8 +720,8 @@ static int fr_server_domain_socket_perm(char const *path, uid_t uid, gid_t gid)
                if ((uid != (uid_t)-1) && (st.st_uid != uid)) {
                        struct passwd *need_user, *have_user;
 
-                       if (rad_getpwuid(NULL, &need_user, uid) < 0) goto error;
-                       if (rad_getpwuid(NULL, &have_user, st.st_uid) < 0) {
+                       if (fr_perm_getpwuid(NULL, &need_user, uid) < 0) goto error;
+                       if (fr_perm_getpwuid(NULL, &have_user, st.st_uid) < 0) {
                                talloc_free(need_user);
                                goto error;
                        }
@@ -734,8 +735,8 @@ static int fr_server_domain_socket_perm(char const *path, uid_t uid, gid_t gid)
                if ((gid != (gid_t)-1) && (st.st_gid != gid)) {
                        struct group *need_group, *have_group;
 
-                       if (rad_getgrgid(NULL, &need_group, gid) < 0) goto error;
-                       if (rad_getgrgid(NULL, &have_group, st.st_gid) < 0) {
+                       if (fr_perm_getgrgid(NULL, &need_group, gid) < 0) goto error;
+                       if (fr_perm_getgrgid(NULL, &have_group, st.st_gid) < 0) {
                                talloc_free(need_group);
                                goto error;
                        }
@@ -750,10 +751,10 @@ static int fr_server_domain_socket_perm(char const *path, uid_t uid, gid_t gid)
                        char str_need[10], oct_need[5];
                        char str_have[10], oct_have[5];
 
-                       rad_mode_to_str(str_need, perm);
-                       rad_mode_to_oct(oct_need, perm);
-                       rad_mode_to_str(str_have, st.st_mode);
-                       rad_mode_to_oct(oct_have, st.st_mode);
+                       fr_perm_mode_to_str(str_need, perm);
+                       fr_perm_mode_to_oct(oct_need, perm);
+                       fr_perm_mode_to_str(str_have, st.st_mode);
+                       fr_perm_mode_to_oct(oct_have, st.st_mode);
                        fr_strerror_printf("Control socket directory must have permissions %s (%s), current "
                                           "permissions are %s (%s)", str_need, oct_need, str_have, oct_have);
                        goto error;
@@ -852,8 +853,8 @@ static int fr_server_domain_socket_perm(char const *path, uid_t uid, gid_t gid)
        if (fchmod(sock_fd, perm) < 0) {
                char str_need[10], oct_need[5];
 
-               rad_mode_to_str(str_need, perm);
-               rad_mode_to_oct(oct_need, perm);
+               fr_perm_mode_to_str(str_need, perm);
+               fr_perm_mode_to_oct(oct_need, perm);
                fr_strerror_printf("Failed changing socket permissions to %s (%s)", str_need, oct_need);
 
                goto sock_error;
@@ -863,8 +864,8 @@ static int fr_server_domain_socket_perm(char const *path, uid_t uid, gid_t gid)
                struct passwd *user;
                struct group *group;
 
-               if (rad_getpwuid(NULL, &user, uid) < 0) goto sock_error;
-               if (rad_getgrgid(NULL, &group, gid) < 0) {
+               if (fr_perm_getpwuid(NULL, &user, uid) < 0) goto sock_error;
+               if (fr_perm_getgrgid(NULL, &group, gid) < 0) {
                        talloc_free(user);
                        goto sock_error;
                }
@@ -1133,7 +1134,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *cs)
        if (inst->uid_name) {
                struct passwd *pwd;
 
-               if (rad_getpwnam(cs, &pwd, inst->uid_name) < 0) {
+               if (fr_perm_getpwnam(cs, &pwd, inst->uid_name) < 0) {
                        PERROR("Failed getting uid for %s", inst->uid_name);
                        return -1;
                }
@@ -1144,7 +1145,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *cs)
        }
 
        if (inst->gid_name) {
-               if (rad_getgid(cs, &inst->gid, inst->gid_name) < 0) {
+               if (fr_perm_gid_from_str(cs, &inst->gid, inst->gid_name) < 0) {
                        PERROR("Failed getting gid for %s", inst->gid_name);
                        return -1;
                }
index 536e744af84e1e942d4b3c71656c167d37cc15a5..606d8352cab77f9c0b1933df1cbae1a10c4a7e5c 100644 (file)
@@ -27,9 +27,10 @@ RCSID("$Id$")
 #define LOG_PREFIX_ARGS inst->name
 
 #include <freeradius-devel/server/base.h>
+#include <freeradius-devel/server/exfile.h>
 #include <freeradius-devel/server/module.h>
 #include <freeradius-devel/util/debug.h>
-#include <freeradius-devel/server/exfile.h>
+#include <freeradius-devel/util/perm.h>
 
 #include <ctype.h>
 #include <fcntl.h>
@@ -397,7 +398,7 @@ static unlang_action_t CC_HINT(nonnull) detail_do(rlm_rcode_t *p_result, module_
        if (inst->group != NULL) {
                gid = strtol(inst->group, &endptr, 10);
                if (*endptr != '\0') {
-                       if (rad_getgid(request, &gid, inst->group) < 0) {
+                       if (fr_perm_gid_from_str(request, &gid, inst->group) < 0) {
                                RDEBUG2("Unable to find system group '%s'", inst->group);
                                goto skip_group;
                        }
index 53730c0b54e03229b83d2e91118e13ab1ad74f19..2284485b1a5607e5bc4d635fe22504b20a15a240 100644 (file)
 RCSID("$Id$")
 
 #include <freeradius-devel/server/base.h>
+#include <freeradius-devel/server/exfile.h>
 #include <freeradius-devel/server/module.h>
 #include <freeradius-devel/util/debug.h>
-#include <freeradius-devel/server/exfile.h>
+#include <freeradius-devel/util/perm.h>
 
 #ifdef HAVE_FCNTL_H
 #  include <fcntl.h>
@@ -334,7 +335,7 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf)
 
                        inst->file.group = strtol(inst->file.group_str, &endptr, 10);
                        if (*endptr != '\0') {
-                               if (rad_getgid(inst, &(inst->file.group), inst->file.group_str) < 0) {
+                               if (fr_perm_gid_from_str(inst, &(inst->file.group), inst->file.group_str) < 0) {
                                        cf_log_err(conf, "Unable to find system group \"%s\"",
                                                      inst->file.group_str);
                                        return -1;
index aa0d95b3a6670d0bfff18132da1845c94c17e795..22c1e51a437bfcdb864eca9ae072a334aa660b4a 100644 (file)
@@ -32,6 +32,7 @@ USES_APPLE_DEPRECATED_API
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/module.h>
 #include <freeradius-devel/util/debug.h>
+#include <freeradius-devel/util/perm.h>
 
 #include <ctype.h>
 #include <stdlib.h>
@@ -409,7 +410,7 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, mod
        /* resolve SACL */
        uuid_clear(guid_sacl);
 
-       if (rad_getgid(request, &gid, kRadiusSACLName) < 0) {
+       if (fr_perm_gid_from_str(request, &gid, kRadiusSACLName) < 0) {
                RDEBUG2("The SACL group \"%s\" does not exist on this system", kRadiusSACLName);
        } else {
                err = mbr_gid_to_uuid(gid, guid_sacl);
@@ -463,7 +464,7 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, mod
        /* resolve user */
        uuid_clear(uuid);
 
-       rad_getpwnam(request, &userdata, username->vp_strvalue);
+       fr_perm_getpwnam(request, &userdata, username->vp_strvalue);
        if (userdata != NULL) {
                err = mbr_uid_to_uuid(userdata->pw_uid, uuid);
                if (err != 0)
index 7a9df5a73da5f2d34e933b5e3d58f9c3777f3445..8a571f4f1efd2e963bd7a244c42757904ecca66b 100644 (file)
@@ -33,10 +33,11 @@ USES_APPLE_DEPRECATED_API
 #define LOG_PREFIX "rlm_unix (%s) - "
 #define LOG_PREFIX_ARGS inst->name
 
+#include <freeradius-devel/radius/radius.h>
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/module.h>
 #include <freeradius-devel/server/sysutmp.h>
-#include <freeradius-devel/radius/radius.h>
+#include <freeradius-devel/util/perm.h>
 
 #include <grp.h>
 #include <pwd.h>
@@ -115,12 +116,12 @@ static int groupcmp(UNUSED void *instance, request_t *request, UNUSED fr_pair_li
        username = fr_pair_find_by_da(&request->request_pairs, attr_user_name, 0);
        if (!username) return -1;
 
-       if (rad_getpwnam(request, &pwd, username->vp_strvalue) < 0) {
+       if (fr_perm_getpwnam(request, &pwd, username->vp_strvalue) < 0) {
                RPEDEBUG("Failed resolving user name");
                return -1;
        }
 
-       if (rad_getgrnam(request, &grp, check->vp_strvalue) < 0) {
+       if (fr_perm_getgrnam(request, &grp, check->vp_strvalue) < 0) {
                RPEDEBUG("Failed resolving group name");
                talloc_free(pwd);
                return -1;