github.com/cloudfoundry-attic/garden-linux@v0.333.2-candidate/linux_backend/src/nstar/pwd.c (about) 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #include "pwd.h" 6 7 #define _GETPWNAM_NEXT(x, y) \ 8 do { \ 9 if ((y) != NULL) { \ 10 (x) = (y) + 1; \ 11 } \ 12 \ 13 (y) = strchr((x), ':'); \ 14 \ 15 /* Search for \n in last iteration */ \ 16 if ((y) == NULL) { \ 17 (y) = strchr((x), '\n'); \ 18 } \ 19 \ 20 if ((y) == NULL) { \ 21 goto done; \ 22 } \ 23 \ 24 *(y) = '\0'; \ 25 } while(0); 26 27 /* Instead of using getpwnam from glibc, the following custom version is used 28 * because we need to bypass dynamically loading the nsswitch libraries. 29 * The version of glibc inside a container may be different than the version 30 * that wshd is compiled for, leading to undefined behavior. */ 31 struct passwd *getpwnam(const char *name) { 32 static struct passwd passwd; 33 static char buf[1024]; 34 struct passwd *_passwd = NULL; 35 FILE *f; 36 char *p, *q; 37 38 f = fopen("/etc/passwd", "r"); 39 if (f == NULL) { 40 goto done; 41 } 42 43 while (fgets(buf, sizeof(buf), f) != NULL) { 44 p = buf; 45 q = NULL; 46 47 /* Username */ 48 _GETPWNAM_NEXT(p, q); 49 50 if (strcmp(p, name) != 0) { 51 continue; 52 } 53 54 passwd.pw_name = p; 55 56 /* User password */ 57 _GETPWNAM_NEXT(p, q); 58 passwd.pw_passwd = p; 59 60 /* User ID */ 61 _GETPWNAM_NEXT(p, q); 62 passwd.pw_uid = atoi(p); 63 64 /* Group ID */ 65 _GETPWNAM_NEXT(p, q); 66 passwd.pw_gid = atoi(p); 67 68 /* User information */ 69 _GETPWNAM_NEXT(p, q); 70 passwd.pw_gecos = p; 71 72 /* Home directory */ 73 _GETPWNAM_NEXT(p, q); 74 passwd.pw_dir = p; 75 76 /* Shell program */ 77 _GETPWNAM_NEXT(p, q); 78 passwd.pw_shell = p; 79 80 /* Done! */ 81 _passwd = &passwd; 82 goto done; 83 } 84 85 done: 86 if (f != NULL) { 87 fclose(f); 88 } 89 90 return _passwd; 91 } 92 93 #undef _GETPWNAM_NEXT