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 |
- |
|
|