1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2024 RackTop Systems, Inc.
14 */
15
16 /*
17 * Stubs to replace libidmap and libc calls for these test programs.
18 * See -Wl,-zinterpose in Makefile
19 */
20
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <strings.h>
25 #include <pwd.h>
26 #include <grp.h>
27 #include "idmap.h"
28
29 struct mapping {
30 uid_t pid;
31 int is_user;
32 char *sid; /* may be NULL */
33 char *name;
34 char *domain; /* may be NULL */
35 };
36
37 struct mapping mappings[] = {
38 /* User and group with no SID, no domain */
39 {
40 .pid = 501,
41 .is_user = 1,
42 .sid = NULL,
43 .name = "user501",
44 .domain = NULL
45 },
46 {
47 .pid = 502,
48 .is_user = 0,
49 .sid = NULL,
50 .name = "group502",
51 .domain = NULL
52 },
53 /* Users and groups with SID, names, domains of various length. */
54 {
55 .pid = 0x80000001,
56 .is_user = 1,
57 .sid = "S-1-5-21-1813420391-1960978090-3893453001-1001",
58 .name = "user1001",
59 .domain = "test-domain-name"
60 },
61 {
62 .pid = 0x80000002,
63 .is_user = 0,
64 .sid = "S-1-5-21-1813420391-1960978090-3893453001-1002",
65 .name = "group1002",
66 .domain = "test-domain-name"
67 },
68 {
69 .pid = 0x80000003,
70 .is_user = 0,
71 .sid = "S-1-5-21-1813420391-1960978090-3893453001-1003",
72 .name = "group1003-name-really-crazy-long-long"
73 "-long-long-long-long-long-long-long",
74 .domain = "test-domain-name"
75 },
76 {
77 .pid = 0x80000004,
78 .is_user = 0,
79 .sid = "S-1-5-21-1813420391-1960978090-3893453002-2002",
80 .name = "group2002",
81 .domain = "test-domain-name-somewhat-longer"
82 },
83 {
84 .pid = 0x80000005,
85 .is_user = 0,
86 .sid = "S-1-5-21-1813420391-1960978090-3893453003-3003",
87 .name = "group3003",
88 .domain = "test-domain-name-really-crazy-long"
89 "-long-long-long-long-long-long-long-long"
90 },
91 {
92 .pid = 0
93 }
94 };
95
96
97 idmap_get_handle_t *stub_idmh = (idmap_get_handle_t *)0x40;
98
99 idmap_stat
idmap_get_create(idmap_get_handle_t ** gh)100 idmap_get_create(idmap_get_handle_t **gh)
101 {
102 *gh = stub_idmh;
103 return (0);
104 }
105
106 void
idmap_get_destroy(idmap_get_handle_t * gh)107 idmap_get_destroy(idmap_get_handle_t *gh)
108 {
109 }
110
111 idmap_stat
idmap_get_mappings(idmap_get_handle_t * gh)112 idmap_get_mappings(idmap_get_handle_t *gh)
113 {
114 if (gh != stub_idmh)
115 return (IDMAP_ERR_ARG);
116 return (0);
117 }
118
119
120 /*
121 * Get winname given pid
122 */
123 idmap_stat
idmap_getwinnamebypid(uid_t pid,int is_user,int flag,char ** name,char ** domain)124 idmap_getwinnamebypid(uid_t pid, int is_user, int flag, char **name,
125 char **domain)
126 {
127 struct mapping *mp;
128
129 if (name == NULL)
130 return (IDMAP_ERR_ARG);
131
132 /* Get mapping */
133 for (mp = mappings; mp->pid != 0; mp++) {
134 if (mp->is_user != is_user)
135 continue;
136 if (mp->pid == pid)
137 break;
138 }
139 if (mp->pid == 0 || mp->name == NULL || mp->domain == NULL)
140 return (IDMAP_ERR_NORESULT);
141
142 if (domain != NULL) {
143 *name = strdup(mp->name);
144 *domain = strdup(mp->domain);
145 } else {
146 (void) asprintf(name, "%s@%s", mp->name, mp->domain);
147 }
148
149 return (0);
150 }
151
152 idmap_stat
idmap_getwinnamebyuid(uid_t uid,int flag,char ** name,char ** domain)153 idmap_getwinnamebyuid(uid_t uid, int flag, char **name, char **domain)
154 {
155 return (idmap_getwinnamebypid(uid, 1, flag, name, domain));
156 }
157
158 idmap_stat
idmap_getwinnamebygid(gid_t gid,int flag,char ** name,char ** domain)159 idmap_getwinnamebygid(gid_t gid, int flag, char **name, char **domain)
160 {
161 return (idmap_getwinnamebypid(gid, 0, flag, name, domain));
162 }
163
164 idmap_stat
idmap_getpidbywinname(const char * name,const char * domain,int flag,uid_t * uid,int is_user)165 idmap_getpidbywinname(const char *name, const char *domain, int flag,
166 uid_t *uid, int is_user)
167 {
168 struct mapping *mp;
169
170 /* Get mapping */
171 for (mp = mappings; mp->pid != 0; mp++) {
172 if (mp->is_user != is_user)
173 continue;
174 if (mp->domain == NULL)
175 continue;
176 if (strcmp(mp->domain, domain) == 0 &&
177 strcmp(mp->name, name) == 0)
178 break;
179 }
180 if (mp->pid == 0)
181 return (IDMAP_ERR_NORESULT);
182
183 *uid = mp->pid;
184 return (0);
185 }
186
187
188 idmap_stat
idmap_getuidbywinname(const char * name,const char * domain,int flag,uid_t * uid)189 idmap_getuidbywinname(const char *name, const char *domain, int flag,
190 uid_t *uid)
191 {
192 return (idmap_getpidbywinname(name, domain, flag, uid, 1));
193 }
194
195 idmap_stat
idmap_getgidbywinname(const char * name,const char * domain,int flag,gid_t * gid)196 idmap_getgidbywinname(const char *name, const char *domain, int flag,
197 gid_t *gid)
198 {
199 return (idmap_getpidbywinname(name, domain, flag, gid, 0));
200 }
201
202
203 idmap_stat
idmap_get_sidbypid(idmap_get_handle_t * gh,uid_t pid,int flag,char ** sidprefix,idmap_rid_t * rid,idmap_stat * stat,int is_user)204 idmap_get_sidbypid(idmap_get_handle_t *gh, uid_t pid, int flag,
205 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat, int is_user)
206 {
207 struct mapping *mp;
208 char *p;
209 int len;
210
211 /* Get mapping */
212 for (mp = mappings; mp->pid != 0; mp++) {
213 if (mp->is_user != is_user)
214 continue;
215 if (mp->pid == pid)
216 break;
217 }
218 if (mp->pid == 0 || mp->sid == NULL)
219 goto errout;
220
221 p = strrchr(mp->sid, '-');
222 if (p == NULL)
223 goto errout;
224 len = p - mp->sid;
225 *sidprefix = malloc(len + 1);
226 if (*sidprefix == NULL)
227 goto errout;
228 (void) strlcpy(*sidprefix, mp->sid, len + 1);
229
230 *rid = strtol(p + 1, NULL, 10);
231 *stat = 0;
232 return (0);
233
234 errout:
235 *stat = IDMAP_ERR_NORESULT;
236 return (0);
237 }
238
239 idmap_stat
idmap_get_sidbyuid(idmap_get_handle_t * gh,uid_t uid,int flag,char ** sidprefix,idmap_rid_t * rid,idmap_stat * stat)240 idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
241 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat)
242 {
243 return (idmap_get_sidbypid(gh, uid, flag,
244 sidprefix, rid, stat, 1));
245 }
246
247 idmap_stat
idmap_get_sidbygid(idmap_get_handle_t * gh,gid_t gid,int flag,char ** sidprefix,idmap_rid_t * rid,idmap_stat * stat)248 idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
249 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat)
250 {
251 return (idmap_get_sidbypid(gh, gid, flag,
252 sidprefix, rid, stat, 0));
253 }
254
255 idmap_stat
idmap_get_pidbysid(idmap_get_handle_t * gh,char * sidprefix,idmap_rid_t rid,int flag,uid_t * pid,int * is_user,idmap_stat * stat)256 idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
257 int flag, uid_t *pid, int *is_user, idmap_stat *stat)
258 {
259 char tmpsid[80];
260 struct mapping *mp;
261
262 (void) snprintf(tmpsid, sizeof (tmpsid), "%s-%u", sidprefix, rid);
263
264 /* Get mapping */
265 for (mp = mappings; mp->pid != 0; mp++) {
266 if (mp->sid != NULL &&
267 strcmp(mp->sid, tmpsid) == 0)
268 break;
269 }
270 if (mp->pid == 0)
271 return (IDMAP_ERR_NORESULT);
272
273 *pid = mp->pid;
274 *is_user = mp->is_user;
275 *stat = 0;
276
277 return (0);
278 }
279
280 idmap_stat
idmap_get_uidbysid(idmap_get_handle_t * gh,char * sidprefix,idmap_rid_t rid,int flag,uid_t * uid,idmap_stat * stat)281 idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
282 int flag, uid_t *uid, idmap_stat *stat)
283 {
284 idmap_stat rc;
285 uid_t pid;
286 int is_user;
287
288 rc = idmap_get_pidbysid(gh, sidprefix, rid, flag, &pid, &is_user, stat);
289 if (rc == 0) {
290 if (is_user != 1) {
291 *stat = IDMAP_ERR_NOTUSER;
292 return (0);
293 }
294 *uid = pid;
295 }
296
297 return (rc);
298 }
299
300 idmap_stat
idmap_get_gidbysid(idmap_get_handle_t * gh,char * sidprefix,idmap_rid_t rid,int flag,gid_t * gid,idmap_stat * stat)301 idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
302 int flag, gid_t *gid, idmap_stat *stat)
303 {
304 idmap_stat rc;
305 uid_t pid;
306 int is_user;
307
308 rc = idmap_get_pidbysid(gh, sidprefix, rid, flag, &pid, &is_user, stat);
309 if (rc == 0) {
310 if (is_user != 0) {
311 *stat = IDMAP_ERR_NOTGROUP;
312 return (rc);
313 }
314 *gid = pid;
315 }
316
317 return (rc);
318 }
319
320 struct passwd *
getpwnam(const char * nam)321 getpwnam(const char *nam)
322 {
323 static char pwname[128];
324 static struct passwd pw;
325 struct mapping *mp;
326 char *p;
327
328 /* Allow lookup with or without domain part */
329 if ((p = strchr(nam, '@')) != NULL) {
330 int len = p - nam;
331 if (len >= sizeof (pwname))
332 return (NULL);
333 (void) strlcpy(pwname, nam, len + 1);
334 pwname[len] = '\0';
335 } else {
336 (void) strlcpy(pwname, nam, sizeof (pwname));
337 }
338
339 /* Get mapping */
340 for (mp = mappings; mp->pid != 0; mp++) {
341 if (mp->is_user != 1)
342 continue;
343 if (strcmp(mp->name, pwname) == 0)
344 break;
345 }
346 if (mp->pid == 0)
347 return (NULL);
348
349 if (mp->domain != NULL)
350 (void) snprintf(pwname, sizeof (pwname),
351 "%s@%s", mp->name, mp->domain);
352 else
353 (void) strlcpy(pwname, mp->name, sizeof (pwname));
354
355 pw.pw_name = pwname;
356 pw.pw_uid = mp->pid;
357 return (&pw);
358 }
359
360 struct passwd *
getpwuid(uid_t uid)361 getpwuid(uid_t uid)
362 {
363 static char pwname[128];
364 static struct passwd pw;
365 struct mapping *mp;
366
367 /* Get mapping */
368 for (mp = mappings; mp->pid != 0; mp++) {
369 if (mp->is_user != 1)
370 continue;
371 if (mp->pid == uid)
372 break;
373 }
374 if (mp->pid == 0)
375 return (NULL);
376
377 if (mp->domain != NULL)
378 (void) snprintf(pwname, sizeof (pwname),
379 "%s@%s", mp->name, mp->domain);
380 else
381 (void) strlcpy(pwname, mp->name, sizeof (pwname));
382
383 pw.pw_name = pwname;
384 pw.pw_uid = uid;
385 return (&pw);
386 }
387
388 struct group *
getgrnam(const char * nam)389 getgrnam(const char *nam)
390 {
391 static char grname[128];
392 static struct group gr;
393 struct mapping *mp;
394 char *p;
395
396 /* Allow lookup with or without domain part */
397 if ((p = strchr(nam, '@')) != NULL) {
398 int len = p - nam;
399 if (len >= sizeof (grname))
400 return (NULL);
401 (void) strlcpy(grname, nam, len + 1);
402 grname[len] = '\0';
403 } else {
404 (void) strlcpy(grname, nam, sizeof (grname));
405 }
406
407 /* Get mapping */
408 for (mp = mappings; mp->pid != 0; mp++) {
409 if (mp->is_user != 0)
410 continue;
411 if (strcmp(mp->name, grname) == 0)
412 break;
413 }
414 if (mp->pid == 0)
415 return (NULL);
416
417 if (mp->domain != NULL)
418 (void) snprintf(grname, sizeof (grname),
419 "%s@%s", mp->name, mp->domain);
420 else
421 (void) strlcpy(grname, mp->name, sizeof (grname));
422
423 gr.gr_name = grname;
424 gr.gr_gid = mp->pid;
425 return (&gr);
426 }
427
428 struct group *
getgrgid(gid_t gid)429 getgrgid(gid_t gid)
430 {
431 static char grname[128];
432 static struct group gr;
433 struct mapping *mp;
434
435 /* Get mapping */
436 for (mp = mappings; mp->pid != 0; mp++) {
437 if (mp->is_user != 0)
438 continue;
439 if (mp->pid == gid)
440 break;
441 }
442 if (mp->pid == 0)
443 return (NULL);
444
445 if (mp->domain != NULL)
446 (void) snprintf(grname, sizeof (grname),
447 "%s@%s", mp->name, mp->domain);
448 else
449 (void) strlcpy(grname, mp->name, sizeof (grname));
450
451 gr.gr_name = grname;
452 gr.gr_gid = gid;
453 return (&gr);
454 }
455