xref: /illumos-gate/usr/src/test/libsec-tests/cmd/lib_stubs.c (revision 7655c6d53c36750b508636f48c73a2de57754e5a)
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
100 idmap_get_create(idmap_get_handle_t **gh)
101 {
102 	*gh = stub_idmh;
103 	return (0);
104 }
105 
106 void
107 idmap_get_destroy(idmap_get_handle_t *gh)
108 {
109 }
110 
111 idmap_stat
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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 *
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 *
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 *
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