git: ee81c8e455ef - main - security/sssd2: Add patch to enumerate UIDs

From: John Hixson <jhixson_at_FreeBSD.org>
Date: Mon, 24 Jun 2024 14:36:07 UTC
The branch main has been updated by jhixson:

URL: https://cgit.FreeBSD.org/ports/commit/?id=ee81c8e455ef5c11a6d2f40d51a05d5d0b4708be

commit ee81c8e455ef5c11a6d2f40d51a05d5d0b4708be
Author:     John Hixson <jhixson@FreeBSD.org>
AuthorDate: 2024-06-24 06:01:08 +0000
Commit:     John Hixson <jhixson@FreeBSD.org>
CommitDate: 2024-06-24 14:35:36 +0000

    security/sssd2: Add patch to enumerate UIDs
    
    The legacy security/sssd port has a patch which lets one set
    krb5_store_password_if_offline=True in a IPA provider configuration
    block.  The patch fixes some code which uses /proc to enumerate the UIDs
    of logged-in users.  Without the patch, if one has this configuration
    variable set, sssd dies with an obscure error.  This caused some pain
    when a user was updating from sssd to sssd2.
    
    Sponsored by: Serenity Cybersecurity, LLC
    
    PR: 279255
    Reported by: markj@freebsd.org, arrowd@freebsd.org
    Obtained from:  arrowd@freebsd.org
---
 security/sssd2/Makefile                          |   2 +-
 security/sssd2/files/patch-src__util__find_uid.c | 227 +++++++++++++++++++++++
 2 files changed, 228 insertions(+), 1 deletion(-)

diff --git a/security/sssd2/Makefile b/security/sssd2/Makefile
index d2b6ca35c7ef..0a2a9527d468 100644
--- a/security/sssd2/Makefile
+++ b/security/sssd2/Makefile
@@ -1,6 +1,6 @@
 PORTNAME=	sssd
 PORTVERSION=	2.9.4
-PORTREVISION=	5
+PORTREVISION=	6
 CATEGORIES=	security
 PKGNAMESUFFIX=	2
 
diff --git a/security/sssd2/files/patch-src__util__find_uid.c b/security/sssd2/files/patch-src__util__find_uid.c
new file mode 100644
index 000000000000..e319f3289a0a
--- /dev/null
+++ b/security/sssd2/files/patch-src__util__find_uid.c
@@ -0,0 +1,227 @@
+--- src/util/find_uid.c.orig	2024-01-12 12:05:40 UTC
++++ src/util/find_uid.c
+@@ -58,6 +58,97 @@ static void hash_talloc_free(void *ptr, void *pvt)
+     talloc_free(ptr);
+ }
+
++static int parse_procfs_linux(const char* buf, uid_t *uid, bool *is_systemd)
++{
++    char *p;
++    char *e;
++    char *endptr;
++    uint32_t num=0;
++    errno_t error=EOK;
++
++    /* Get uid */
++    p = strstr(buf, "\nUid:\t");
++    if (p != NULL) {
++        p += 6;
++        e = strchr(p,'\t');
++        if (e == NULL) {
++            DEBUG(SSSDBG_CRIT_FAILURE, "missing delimiter.\n");
++            return EINVAL;
++        } else {
++            *e = '\0';
++        }
++        num = (uint32_t) strtoint32(p, &endptr, 10);
++        error = errno;
++        if (error != 0) {
++            DEBUG(SSSDBG_CRIT_FAILURE,
++                  "strtol failed [%s].\n", strerror(error));
++            return error;
++        }
++        if (*endptr != '\0') {
++            DEBUG(SSSDBG_CRIT_FAILURE, "uid contains extra characters\n");
++            return EINVAL;
++        }
++
++    } else {
++        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
++        return EINVAL;
++    }
++
++    /* Get process name. */
++    p = strstr(buf, "Name:\t");
++    if (p == NULL) {
++        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
++        return EINVAL;
++    }
++    p += 6;
++    e = strchr(p,'\n');
++    if (e == NULL) {
++        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
++        return EINVAL;
++    }
++    if (strncmp(p, "systemd", e-p) == 0 || strncmp(p, "(sd-pam)", e-p) == 0) {
++        *is_systemd = true;
++    } else {
++        *is_systemd = false;
++    }
++
++    *uid = num;
++
++    return error;
++}
++
++static int parse_procfs_freebsd(char* buf, uid_t *uid, bool *is_systemd)
++{
++    uint32_t field_idx=0;
++    errno_t error=EOK;
++    char** str = &buf, *token;
++
++    /* See man procfs
++       nextcloud 21186 4726 110 90383 ttyv0 ctty 1718001838,183475 11,76617 2,473238 select 1001 1001 1001,1001,0,5,44,920 -
++                                                                                            |uid|
++    */
++    while ((token = strsep(str, " ")) != NULL && field_idx < 11) {
++        field_idx++;
++    }
++
++    if (token == NULL || field_idx != 11) {
++        DEBUG(SSSDBG_CRIT_FAILURE, "format error %d %d\n", token, field_idx);
++        return EINVAL;
++    }
++
++    *uid = (uint32_t) strtoint32(token, NULL, 10);
++    error = errno;
++    if (error != 0) {
++        DEBUG(SSSDBG_CRIT_FAILURE,
++                "strtol failed [%s].\n", strerror(error));
++        return error;
++    }
++
++    *is_systemd = false;
++
++    return error;
++}
++
+ static errno_t get_uid_from_pid(const pid_t pid, uid_t *uid, bool *is_systemd)
+ {
+     int ret;
+@@ -65,10 +156,6 @@ static errno_t get_uid_from_pid(const pid_t pid, uid_t
+     struct stat stat_buf;
+     int fd;
+     char buf[BUFSIZE];
+-    char *p;
+-    char *e;
+-    char *endptr;
+-    uint32_t num=0;
+     errno_t error;
+
+     ret = snprintf(path, PATHLEN, "/proc/%d/status", pid);
+@@ -138,56 +225,14 @@ static errno_t get_uid_from_pid(const pid_t pid, uid_t
+               "close failed [%d][%s].\n", error, strerror(error));
+     }
+
+-    /* Get uid */
+-    p = strstr(buf, "\nUid:\t");
+-    if (p != NULL) {
+-        p += 6;
+-        e = strchr(p,'\t');
+-        if (e == NULL) {
+-            DEBUG(SSSDBG_CRIT_FAILURE, "missing delimiter.\n");
+-            return EINVAL;
+-        } else {
+-            *e = '\0';
+-        }
+-        num = (uint32_t) strtoint32(p, &endptr, 10);
+-        error = errno;
+-        if (error != 0) {
+-            DEBUG(SSSDBG_CRIT_FAILURE,
+-                  "strtol failed [%s].\n", strerror(error));
+-            return error;
+-        }
+-        if (*endptr != '\0') {
+-            DEBUG(SSSDBG_CRIT_FAILURE, "uid contains extra characters\n");
+-            return EINVAL;
+-        }
++#if defined(__linux__)
++    return parse_procfs_linux(buf, uid, is_systemd);
++#elif defined(__FreeBSD__)
++    return parse_procfs_freebsd(buf, uid, is_systemd);
++#else
++    return ENOSYS;
++#endif
+
+-    } else {
+-        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
+-        return EINVAL;
+-    }
+-
+-    /* Get process name. */
+-    p = strstr(buf, "Name:\t");
+-    if (p == NULL) {
+-        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
+-        return EINVAL;
+-    }
+-    p += 6;
+-    e = strchr(p,'\n');
+-    if (e == NULL) {
+-        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
+-        return EINVAL;
+-    }
+-    if (strncmp(p, "systemd", e-p) == 0 || strncmp(p, "(sd-pam)", e-p) == 0) {
+-        *is_systemd = true;
+-    } else {
+-        *is_systemd = false;
+-    }
+-
+-    *uid = num;
+-
+-    return EOK;
+-
+ fail_fd:
+     close(fd);
+     return error;
+@@ -212,7 +257,12 @@ static errno_t name_to_pid(const char *name, pid_t *pi
+         return EINVAL;
+     }
+
++    /* FreeBSD has /proc/0/... */
++#if defined(__FreeBSD__)
++    if (num < 0 || num >= INT_MAX) {
++#else
+     if (num <= 0 || num >= INT_MAX) {
++#endif
+         DEBUG(SSSDBG_CRIT_FAILURE, "pid out of range.\n");
+         return ERANGE;
+     }
+@@ -228,7 +278,7 @@ static int only_numbers(char *p)
+     return *p;
+ }
+
+-static errno_t get_active_uid_linux(hash_table_t *table, uid_t search_uid)
++static errno_t get_active_uid_procfs(hash_table_t *table, uid_t search_uid)
+ {
+     DIR *proc_dir = NULL;
+     struct dirent *dirent;
+@@ -327,7 +377,7 @@ errno_t get_uid_table(TALLOC_CTX *mem_ctx, hash_table_
+
+ errno_t get_uid_table(TALLOC_CTX *mem_ctx, hash_table_t **table)
+ {
+-#ifdef __linux__
++#if defined(__linux__) || defined(__FreeBSD__)
+     int ret;
+
+     ret = hash_create_ex(0, table, 0, 0, 0, 0,
+@@ -339,7 +389,7 @@ errno_t get_uid_table(TALLOC_CTX *mem_ctx, hash_table_
+         return ENOMEM;
+     }
+
+-    return get_active_uid_linux(*table, 0);
++    return get_active_uid_procfs(*table, 0);
+ #else
+     return ENOSYS;
+ #endif
+@@ -365,9 +415,9 @@ errno_t check_if_uid_is_active(uid_t uid, bool *result
+     /* fall back to the old method */
+ #endif
+
+-    ret = get_active_uid_linux(NULL, uid);
++    ret = get_active_uid_procfs(NULL, uid);
+     if (ret != EOK && ret != ENOENT) {
+-        DEBUG(SSSDBG_CRIT_FAILURE, "get_active_uid_linux() failed.\n");
++        DEBUG(SSSDBG_CRIT_FAILURE, "get_active_uid_procfs() failed.\n");
+         return ret;
+     }
+