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