(root)/
acl-2.3.1/
test/
test_passwd.c
       1  #include "config.h"
       2  #include <sys/types.h>
       3  #include <stdio.h>
       4  #include <string.h>
       5  #include <stdlib.h>
       6  #include <errno.h>
       7  #include <libgen.h>
       8  #include <limits.h>
       9  #include <pwd.h>
      10  
      11  #define TEST_PASSWD "test/test.passwd"
      12  static char pwfile[PATH_MAX];
      13  static void setup_pwfile() __attribute__((constructor));
      14  
      15  static void setup_pwfile() {
      16  	snprintf(pwfile, sizeof(pwfile), "%s/%s", BASEDIR, TEST_PASSWD);
      17  }
      18  
      19  #define ALIGN_MASK(x, mask)    (((x) + (mask)) & ~(mask))
      20  #define ALIGN(x, a)            ALIGN_MASK(x, (typeof(x))(a) - 1)
      21  
      22  static int test_getpwent_r(FILE *file, struct passwd *pwd, char *buf,
      23  			   size_t buflen, struct passwd **result)
      24  {
      25  	char *str, *line;
      26  	int index = 0;
      27  
      28  	*result = NULL;
      29  
      30  	line = fgets(buf, buflen, file);
      31  	if (!line) {
      32  		return 0;
      33  	}
      34  
      35  	while ((str = strtok(line, ":"))) {
      36  		switch (index++) {
      37  		case 0:
      38  			pwd->pw_name = str;
      39  			break;
      40  		case 1:
      41  			pwd->pw_passwd = str;
      42  			break;
      43  		case 2:
      44  			errno = 0;
      45  			pwd->pw_uid = strtol(str, NULL, 10);
      46  			if (errno)
      47  				return -1;
      48  			break;
      49  		case 3:
      50  			errno = 0;
      51  			pwd->pw_gid = strtol(str, NULL, 10);
      52  			if (errno)
      53  				return -1;
      54  			break;
      55  		case 4:
      56  			pwd->pw_gecos = str;
      57  			break;
      58  		case 5:
      59  			pwd->pw_dir = str;
      60  			break;
      61  		case 6:
      62  			pwd->pw_shell = str;
      63  			break;
      64  		}
      65  		line = NULL;
      66  	}
      67  
      68  	*result = pwd;
      69  
      70  	return 0;
      71  }
      72  
      73  static int test_getpw_match(struct passwd *pwd, char *buf, size_t buflen,
      74  			    struct passwd **result,
      75  			    int (*match)(const struct passwd *, const void *),
      76  			    const void *data)
      77  {
      78  	FILE *file;
      79  	struct passwd *_result;
      80  
      81  	*result = NULL;
      82  
      83  	file = fopen(pwfile, "r");
      84  	if (!file) {
      85  		fprintf(stderr, "Failed to open %s\n", pwfile);
      86  		errno = EBADF;
      87  		return -1;
      88  	}
      89  
      90  	errno = 0;
      91  	while (!test_getpwent_r(file, pwd, buf, buflen, &_result)) {
      92  		if (!_result)
      93  			break;
      94  		else if (match(pwd, data)) {
      95  			*result = pwd;
      96  			break;
      97  		}
      98  	}
      99  
     100  	fclose(file);
     101  	if (!errno && !*result)
     102  		errno = ENOENT;
     103  	if (errno)
     104  		return -1;
     105  	return 0;
     106  }
     107  
     108  static int match_name(const struct passwd *pwd, const void *data)
     109  {
     110  	const char *name = data;
     111  	return !strcmp(pwd->pw_name, name);
     112  }
     113  
     114  EXPORT
     115  int getpwnam_r(const char *name, struct passwd *pwd, char *buf, size_t buflen,
     116  	       struct passwd **result)
     117  {
     118  	return test_getpw_match(pwd, buf, buflen, result, match_name, name);
     119  }
     120  
     121  EXPORT
     122  struct passwd *getpwnam(const char *name)
     123  {
     124  	static char buf[16384];
     125  	static struct passwd pwd;
     126  	struct passwd *result;
     127  
     128  	(void) getpwnam_r(name, &pwd, buf, sizeof(buf), &result);
     129  	return result;
     130  }
     131  
     132  static int match_uid(const struct passwd *pwd, const void *data)
     133  {
     134  	uid_t uid = *(uid_t *)data;
     135  	return pwd->pw_uid == uid;
     136  }
     137  
     138  EXPORT
     139  int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen,
     140  	       struct passwd **result)
     141  {
     142  	return test_getpw_match(pwd, buf, buflen, result, match_uid, &uid);
     143  }
     144  
     145  EXPORT
     146  struct passwd *getpwuid(uid_t uid)
     147  {
     148  	static char buf[16384];
     149  	static struct passwd pwd;
     150  	struct passwd *result;
     151  
     152  	(void) getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
     153  	return result;
     154  }