View | Details | Raw Unified | Return to bug 282469
Collapse All | Expand All

(-)b/security/sssd2/files/patch-src__util__find_uid.c (-198 / +95 lines)
Lines 1-227 Link Here
1
--- src/util/find_uid.c.orig	2024-01-12 12:05:40 UTC
1
--- src/util/find_uid.c.orig	2024-05-16 11:35:27 UTC
2
+++ src/util/find_uid.c
2
+++ src/util/find_uid.c
3
@@ -58,6 +58,97 @@ static void hash_talloc_free(void *ptr, void *pvt)
3
@@ -36,6 +36,10 @@
4
     talloc_free(ptr);
4
 #include <ctype.h>
5
 #include <sys/time.h>
6
 #include <dhash.h>
7
+#ifdef __FreeBSD__
8
+#include <sys/sysctl.h>
9
+#include <sys/user.h>
10
+#endif
11
 
12
 #include "util/find_uid.h"
13
 #include "util/util.h"
14
@@ -325,9 +329,86 @@ done:
15
     return ret;
5
 }
16
 }
6
17
 
7
+static int parse_procfs_linux(const char* buf, uid_t *uid, bool *is_systemd)
18
-errno_t get_uid_table(TALLOC_CTX *mem_ctx, hash_table_t **table)
8
+{
19
+#ifdef __FreeBSD__
9
+    char *p;
20
+static errno_t get_active_uid_freebsd(hash_table_t *table, uid_t uid)
10
+    char *e;
21
 {
11
+    char *endptr;
22
+    struct kinfo_proc *kp;
12
+    uint32_t num=0;
23
+    hash_key_t key;
13
+    errno_t error=EOK;
24
+    hash_value_t value;
25
+    size_t sz;
26
+    int err, mib[3];
14
+
27
+
15
+    /* Get uid */
28
+    mib[0] = CTL_KERN;
16
+    p = strstr(buf, "\nUid:\t");
29
+    mib[1] = KERN_PROC;
17
+    if (p != NULL) {
30
+    mib[2] = KERN_PROC_PROC;
18
+        p += 6;
19
+        e = strchr(p,'\t');
20
+        if (e == NULL) {
21
+            DEBUG(SSSDBG_CRIT_FAILURE, "missing delimiter.\n");
22
+            return EINVAL;
23
+        } else {
24
+            *e = '\0';
25
+        }
26
+        num = (uint32_t) strtoint32(p, &endptr, 10);
27
+        error = errno;
28
+        if (error != 0) {
29
+            DEBUG(SSSDBG_CRIT_FAILURE,
30
+                  "strtol failed [%s].\n", strerror(error));
31
+            return error;
32
+        }
33
+        if (*endptr != '\0') {
34
+            DEBUG(SSSDBG_CRIT_FAILURE, "uid contains extra characters\n");
35
+            return EINVAL;
36
+        }
37
+
31
+
38
+    } else {
32
+    sz = 0;
39
+        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
33
+    err = sysctl(mib, 3, NULL, &sz, NULL, 0);
40
+        return EINVAL;
34
+    if (err) {
35
+        err = errno;
36
+        DEBUG(SSSDBG_CRIT_FAILURE, "sysctl failed.\n");
37
+        return err;
41
+    }
38
+    }
39
+    sz *= 2;
42
+
40
+
43
+    /* Get process name. */
41
+    kp = talloc_size(NULL, sz);
44
+    p = strstr(buf, "Name:\t");
42
+    if (kp == NULL) {
45
+    if (p == NULL) {
43
+        DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
46
+        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
44
+        return ENOMEM;
47
+        return EINVAL;
48
+    }
49
+    p += 6;
50
+    e = strchr(p,'\n');
51
+    if (e == NULL) {
52
+        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
53
+        return EINVAL;
54
+    }
45
+    }
55
+    if (strncmp(p, "systemd", e-p) == 0 || strncmp(p, "(sd-pam)", e-p) == 0) {
56
+        *is_systemd = true;
57
+    } else {
58
+        *is_systemd = false;
59
+    }
60
+
61
+    *uid = num;
62
+
46
+
63
+    return error;
47
+    err = sysctl(mib, 3, kp, &sz, NULL, 0);
64
+}
48
+    if (err) {
65
+
49
+        err = errno;
66
+static int parse_procfs_freebsd(char* buf, uid_t *uid, bool *is_systemd)
50
+        DEBUG(SSSDBG_CRIT_FAILURE, "sysctl failed.\n");
67
+{
51
+        talloc_free(kp);
68
+    uint32_t field_idx=0;
52
+        return err;
69
+    errno_t error=EOK;
70
+    char** str = &buf, *token;
71
+
72
+    /* See man procfs
73
+       nextcloud 21186 4726 110 90383 ttyv0 ctty 1718001838,183475 11,76617 2,473238 select 1001 1001 1001,1001,0,5,44,920 -
74
+                                                                                            |uid|
75
+    */
76
+    while ((token = strsep(str, " ")) != NULL && field_idx < 11) {
77
+        field_idx++;
78
+    }
53
+    }
79
+
54
+
80
+    if (token == NULL || field_idx != 11) {
55
+    err = ENOENT;
81
+        DEBUG(SSSDBG_CRIT_FAILURE, "format error %d %d\n", token, field_idx);
56
+    for (size_t i = 0; i < sz / sizeof(struct kinfo_proc); i++) {
82
+        return EINVAL;
57
+        if (kp[i].ki_uid == 0) {
83
+    }
58
+            continue;
84
+
59
+        }
85
+    *uid = (uint32_t) strtoint32(token, NULL, 10);
86
+    error = errno;
87
+    if (error != 0) {
88
+        DEBUG(SSSDBG_CRIT_FAILURE,
89
+                "strtol failed [%s].\n", strerror(error));
90
+        return error;
91
+    }
92
+
60
+
93
+    *is_systemd = false;
61
+        if (table != NULL) {
62
+            key.type = HASH_KEY_ULONG;
63
+            key.ul = (unsigned long) kp[i].ki_ruid;
64
+            value.type = HASH_VALUE_ULONG;
65
+            value.ul = (unsigned long) kp[i].ki_ruid;
94
+
66
+
95
+    return error;
67
+            err = hash_enter(table, &key, &value);
68
+            if (err != HASH_SUCCESS) {
69
+                DEBUG(SSSDBG_CRIT_FAILURE,
70
+                      "cannot add to table [%s]\n", hash_error_string(err));
71
+                err = ENOMEM;
72
+                break;
73
+            }
74
+        } else {
75
+            if (kp[i].ki_ruid == uid) {
76
+                err = EOK;
77
+                break;
78
+            }
79
+        }
80
+    }
81
+    talloc_free(kp);
82
+    return err;
96
+}
83
+}
84
+#endif /* __FreeBSD__ */
97
+
85
+
98
 static errno_t get_uid_from_pid(const pid_t pid, uid_t *uid, bool *is_systemd)
86
+static errno_t get_active_uid(hash_table_t *table, uid_t uid)
99
 {
87
+{
100
     int ret;
88
 #ifdef __linux__
101
@@ -65,10 +156,6 @@ static errno_t get_uid_from_pid(const pid_t pid, uid_t
89
+    return get_active_uid_linux(table, uid);
102
     struct stat stat_buf;
103
     int fd;
104
     char buf[BUFSIZE];
105
-    char *p;
106
-    char *e;
107
-    char *endptr;
108
-    uint32_t num=0;
109
     errno_t error;
110
111
     ret = snprintf(path, PATHLEN, "/proc/%d/status", pid);
112
@@ -138,56 +225,14 @@ static errno_t get_uid_from_pid(const pid_t pid, uid_t
113
               "close failed [%d][%s].\n", error, strerror(error));
114
     }
115
116
-    /* Get uid */
117
-    p = strstr(buf, "\nUid:\t");
118
-    if (p != NULL) {
119
-        p += 6;
120
-        e = strchr(p,'\t');
121
-        if (e == NULL) {
122
-            DEBUG(SSSDBG_CRIT_FAILURE, "missing delimiter.\n");
123
-            return EINVAL;
124
-        } else {
125
-            *e = '\0';
126
-        }
127
-        num = (uint32_t) strtoint32(p, &endptr, 10);
128
-        error = errno;
129
-        if (error != 0) {
130
-            DEBUG(SSSDBG_CRIT_FAILURE,
131
-                  "strtol failed [%s].\n", strerror(error));
132
-            return error;
133
-        }
134
-        if (*endptr != '\0') {
135
-            DEBUG(SSSDBG_CRIT_FAILURE, "uid contains extra characters\n");
136
-            return EINVAL;
137
-        }
138
+#if defined(__linux__)
139
+    return parse_procfs_linux(buf, uid, is_systemd);
140
+#elif defined(__FreeBSD__)
90
+#elif defined(__FreeBSD__)
141
+    return parse_procfs_freebsd(buf, uid, is_systemd);
91
+    return get_active_uid_freebsd(table, uid);
142
+#else
92
+#else
143
+    return ENOSYS;
93
+    return ENOSYS;
144
+#endif
94
+#endif
145
95
+}
146
-    } else {
96
+
147
-        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
97
+errno_t get_uid_table(TALLOC_CTX *mem_ctx, hash_table_t **table)
148
-        return EINVAL;
98
+{
149
-    }
150
-
151
-    /* Get process name. */
152
-    p = strstr(buf, "Name:\t");
153
-    if (p == NULL) {
154
-        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
155
-        return EINVAL;
156
-    }
157
-    p += 6;
158
-    e = strchr(p,'\n');
159
-    if (e == NULL) {
160
-        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
161
-        return EINVAL;
162
-    }
163
-    if (strncmp(p, "systemd", e-p) == 0 || strncmp(p, "(sd-pam)", e-p) == 0) {
164
-        *is_systemd = true;
165
-    } else {
166
-        *is_systemd = false;
167
-    }
168
-
169
-    *uid = num;
170
-
171
-    return EOK;
172
-
173
 fail_fd:
174
     close(fd);
175
     return error;
176
@@ -212,7 +257,12 @@ static errno_t name_to_pid(const char *name, pid_t *pi
177
         return EINVAL;
178
     }
179
180
+    /* FreeBSD has /proc/0/... */
181
+#if defined(__FreeBSD__)
182
+    if (num < 0 || num >= INT_MAX) {
183
+#else
184
     if (num <= 0 || num >= INT_MAX) {
185
+#endif
186
         DEBUG(SSSDBG_CRIT_FAILURE, "pid out of range.\n");
187
         return ERANGE;
188
     }
189
@@ -228,7 +278,7 @@ static int only_numbers(char *p)
190
     return *p;
191
 }
192
193
-static errno_t get_active_uid_linux(hash_table_t *table, uid_t search_uid)
194
+static errno_t get_active_uid_procfs(hash_table_t *table, uid_t search_uid)
195
 {
196
     DIR *proc_dir = NULL;
197
     struct dirent *dirent;
198
@@ -327,7 +377,7 @@ errno_t get_uid_table(TALLOC_CTX *mem_ctx, hash_table_
199
200
 errno_t get_uid_table(TALLOC_CTX *mem_ctx, hash_table_t **table)
201
 {
202
-#ifdef __linux__
203
+#if defined(__linux__) || defined(__FreeBSD__)
204
     int ret;
99
     int ret;
205
100
 
206
     ret = hash_create_ex(0, table, 0, 0, 0, 0,
101
     ret = hash_create_ex(0, table, 0, 0, 0, 0,
207
@@ -339,7 +389,7 @@ errno_t get_uid_table(TALLOC_CTX *mem_ctx, hash_table_
102
@@ -339,10 +420,7 @@ errno_t get_uid_table(TALLOC_CTX *mem_ctx, hash_table_
208
         return ENOMEM;
103
         return ENOMEM;
209
     }
104
     }
210
105
 
211
-    return get_active_uid_linux(*table, 0);
106
-    return get_active_uid_linux(*table, 0);
212
+    return get_active_uid_procfs(*table, 0);
107
-#else
213
 #else
108
-    return ENOSYS;
214
     return ENOSYS;
109
-#endif
215
 #endif
110
+    return get_active_uid(*table, 0);
216
@@ -365,9 +415,9 @@ errno_t check_if_uid_is_active(uid_t uid, bool *result
111
 }
112
 
113
 errno_t check_if_uid_is_active(uid_t uid, bool *result)
114
@@ -365,9 +443,9 @@ errno_t check_if_uid_is_active(uid_t uid, bool *result
217
     /* fall back to the old method */
115
     /* fall back to the old method */
218
 #endif
116
 #endif
219
117
 
220
-    ret = get_active_uid_linux(NULL, uid);
118
-    ret = get_active_uid_linux(NULL, uid);
221
+    ret = get_active_uid_procfs(NULL, uid);
119
+    ret = get_active_uid(NULL, uid);
222
     if (ret != EOK && ret != ENOENT) {
120
     if (ret != EOK && ret != ENOENT) {
223
-        DEBUG(SSSDBG_CRIT_FAILURE, "get_active_uid_linux() failed.\n");
121
-        DEBUG(SSSDBG_CRIT_FAILURE, "get_active_uid_linux() failed.\n");
224
+        DEBUG(SSSDBG_CRIT_FAILURE, "get_active_uid_procfs() failed.\n");
122
+        DEBUG(SSSDBG_CRIT_FAILURE, "get_active_uid() failed.\n");
225
         return ret;
123
         return ret;
226
     }
124
     }
227
125
 
228
- 

Return to bug 282469