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