diff options
| -rw-r--r-- | map_common.c | 375 | ||||
| -rw-r--r-- | map_common.h | 17 | ||||
| -rw-r--r-- | nss_mapname.c | 130 | ||||
| -rw-r--r-- | nss_mapuid.c | 261 | 
4 files changed, 387 insertions, 396 deletions
| diff --git a/map_common.c b/map_common.c index f7ee038..6313c88 100644 --- a/map_common.c +++ b/map_common.c @@ -23,128 +23,123 @@   * during the linking phase (made internal only).   */ -  #include "map_common.h"  #include <sys/stat.h>  static const char config_file[] = "/etc/nss_mapuser.conf"; -#define DEF_MIN_UID 1001 /*  fail lookups on uid's below this value */ +#define DEF_MIN_UID 1001	/*  fail lookups on uid's below this value */  /* set from configuration file parsing; stripped from exported symbols   * in build, so local to the shared lib. */ -char *exclude_users; /*  don't lookup these users */ +char *exclude_users;		/*  don't lookup these users */  char *mappeduser;  char *mapped_priv_user;  uid_t min_uid = DEF_MIN_UID;  int debug;  static int conf_parsed = 0; -static const char *libname; /* for syslogs, set in each library */ +static const char *libname;	/* for syslogs, set in each library */  /*  reset all config variables when we are going to re-parse */ -static void -reset_config(void) +static void reset_config(void)  { -    /*  reset the config variables that we use, freeing memory where needed */ -    if(exclude_users) { -        (void)free(exclude_users); -        exclude_users = NULL; -    } -    if(mappeduser) { -        (void)free(mappeduser); -        mappeduser = NULL; -    } -    if(mapped_priv_user) { -        (void)free(mapped_priv_user); -        mapped_priv_user = NULL; -    } -    debug = 0; -    min_uid = DEF_MIN_UID; +	/*  reset the config variables that we use, freeing memory where needed */ +	if (exclude_users) { +		(void)free(exclude_users); +		exclude_users = NULL; +	} +	if (mappeduser) { +		(void)free(mappeduser); +		mappeduser = NULL; +	} +	if (mapped_priv_user) { +		(void)free(mapped_priv_user); +		mapped_priv_user = NULL; +	} +	debug = 0; +	min_uid = DEF_MIN_UID;  }  /*   * return 0 on succesful parsing (at least no hard errors), 1 if   *  an error, and 2 if already parsed and no change to config file   */ -int -nss_mapuser_config(int *errnop, const char *lname) +int nss_mapuser_config(int *errnop, const char *lname)  { -    FILE *conf; -    char lbuf[256]; -    static struct stat lastconf; +	FILE *conf; +	char lbuf[256]; +	static struct stat lastconf; -    if(conf_parsed) { -        struct stat st, *lst = &lastconf; -        /* -         *  check to see if the config file(s) have changed since last time, -         *  in case we are part of a long-lived daemon.  If any changed, -         *  reparse.  If not, return the appropriate status (err or OK) -         */ -        if (stat(config_file, &st) && st.st_ino == lst->st_ino && -            st.st_mtime == lst->st_mtime && st.st_ctime == lst->st_ctime) -            return 2; /*  nothing to reparse */ -        reset_config(); -        conf_parsed = 0; -        if (debug && conf_parsed) -            syslog(LOG_DEBUG, "%s: Configuration file changed, re-initializing", -                libname); -    } +	if (conf_parsed) { +		struct stat st, *lst = &lastconf; +		/* +		 *  check to see if the config file(s) have changed since last time, +		 *  in case we are part of a long-lived daemon.  If any changed, +		 *  reparse.  If not, return the appropriate status (err or OK) +		 */ +		if (stat(config_file, &st) && st.st_ino == lst->st_ino && +		    st.st_mtime == lst->st_mtime +		    && st.st_ctime == lst->st_ctime) +			return 2;	/*  nothing to reparse */ +		reset_config(); +		conf_parsed = 0; +		if (debug && conf_parsed) +			syslog(LOG_DEBUG, +			       "%s: Configuration file changed, re-initializing", +			       libname); +	} -    libname = lname; +	libname = lname; -    conf = fopen(config_file, "r"); -    if(conf == NULL) { -        *errnop = errno; -        syslog(LOG_NOTICE, "%s: can't open config file %s: %m", -            libname, config_file); -        return 1; -    } -    if (fstat(fileno(conf), &lastconf) != 0) -        memset(&lastconf, 0, sizeof lastconf); /*  avoid stale data, no warning */ +	conf = fopen(config_file, "r"); +	if (conf == NULL) { +		*errnop = errno; +		syslog(LOG_NOTICE, "%s: can't open config file %s: %m", +		       libname, config_file); +		return 1; +	} +	if (fstat(fileno(conf), &lastconf) != 0) +		memset(&lastconf, 0, sizeof lastconf);	/*  avoid stale data, no warning */ -    while(fgets(lbuf, sizeof lbuf, conf)) { -        if(*lbuf == '#' || isspace(*lbuf)) -            continue; /* skip comments, white space lines, etc. */ -        strtok(lbuf, " \t\n\r\f"); /* terminate buffer at first whitespace */ -        if(!strncmp(lbuf, "debug=", 6)) -            debug = strtoul(lbuf+6, NULL, 0); -        else if(!strncmp(lbuf, "exclude_users=", 14)) { -            /* -             * Don't lookup users in this comma-separated list for both -             * robustness and performnce.  Typically root and other commonly -             * used local users.  If set, we also look up the uids -             * locally, and won't do remote lookup on those uids either. -             */ -            exclude_users = strdup(lbuf+14); -        } -        else if(!strncmp(lbuf, "mapped_user=", 12)) { -            /*  the user we are mapping to */ -            mappeduser = strdup(lbuf+12); -        } -        else if(!strncmp(lbuf, "mapped_priv_user=", 17)) { -            /*  the user we are mapping to */ -            mapped_priv_user = strdup(lbuf+17); -        } -        else if(!strncmp(lbuf, "min_uid=", 8)) { -            /* -             * Don't lookup uids that are local, typically set to either -             * 0 or smallest always local user's uid -             */ -            unsigned long uid; -            char *valid; -            uid = strtoul(lbuf+8, &valid, 0); -            if (valid > (lbuf+8)) -                min_uid = (uid_t)uid; -        } -        else if(debug) /* ignore unrecognized lines, unless debug on */ -            syslog(LOG_WARNING, "%s: unrecognized parameter: %s", -                libname, lbuf); -    } -    fclose(conf); -    conf_parsed = 1; +	while (fgets(lbuf, sizeof lbuf, conf)) { +		if (*lbuf == '#' || isspace(*lbuf)) +			continue;	/* skip comments, white space lines, etc. */ +		strtok(lbuf, " \t\n\r\f");	/* terminate buffer at first whitespace */ +		if (!strncmp(lbuf, "debug=", 6)) +			debug = strtoul(lbuf + 6, NULL, 0); +		else if (!strncmp(lbuf, "exclude_users=", 14)) { +			/* +			 * Don't lookup users in this comma-separated list for both +			 * robustness and performnce.  Typically root and other commonly +			 * used local users.  If set, we also look up the uids +			 * locally, and won't do remote lookup on those uids either. +			 */ +			exclude_users = strdup(lbuf + 14); +		} else if (!strncmp(lbuf, "mapped_user=", 12)) { +			/*  the user we are mapping to */ +			mappeduser = strdup(lbuf + 12); +		} else if (!strncmp(lbuf, "mapped_priv_user=", 17)) { +			/*  the user we are mapping to */ +			mapped_priv_user = strdup(lbuf + 17); +		} else if (!strncmp(lbuf, "min_uid=", 8)) { +			/* +			 * Don't lookup uids that are local, typically set to either +			 * 0 or smallest always local user's uid +			 */ +			unsigned long uid; +			char *valid; +			uid = strtoul(lbuf + 8, &valid, 0); +			if (valid > (lbuf + 8)) +				min_uid = (uid_t) uid; +		} else if (debug)	/* ignore unrecognized lines, unless debug on */ +			syslog(LOG_WARNING, "%s: unrecognized parameter: %s", +			       libname, lbuf); +	} +	fclose(conf); +	conf_parsed = 1; -    return mappeduser ? 0 : 1; /*  can't do anything without this */ +	return mappeduser ? 0 : 1;	/*  can't do anything without this */  }  /* @@ -159,81 +154,87 @@ int  pwcopy(char *buf, size_t len, struct passwd *srcpw, struct passwd *destpw,         const char *usename)  { -    int needlen, cnt, origlen = len; -    char *shell; +	int needlen, cnt, origlen = len; +	char *shell; -    if(!mappeduser) { -        if(debug) -            syslog(LOG_DEBUG, "%s: empty mapped_user, failing", libname); -        return 1; -    } -    if(!usename) { /*  this should never happen */ -        if(debug) -            syslog(LOG_DEBUG, "%s: empty username, failing", libname); -        return 1; -    } +	if (!mappeduser) { +		if (debug) +			syslog(LOG_DEBUG, "%s: empty mapped_user, failing", +			       libname); +		return 1; +	} +	if (!usename) {		/*  this should never happen */ +		if (debug) +			syslog(LOG_DEBUG, "%s: empty username, failing", +			       libname); +		return 1; +	} -    needlen = 2 * strlen(usename) + 2 + /*  pw_name and pw_gecos */ -        srcpw->pw_dir ? strlen(srcpw->pw_dir) + 1 : 1 + -        srcpw->pw_shell ? strlen(srcpw->pw_shell) + 1 : 1 + -        2 + /*  for 'x' in the passwd field */ -        12; /*  for the "Mapped user" in the gecos field */ -    if(needlen > len) { -        if(debug) -            syslog(LOG_DEBUG, "%s provided password buffer too small (%ld<%d)", -                libname, (long)len, needlen); -        return 1; -    } +	needlen = 2 * strlen(usename) + 2 +	/*  pw_name and pw_gecos */ +	    srcpw->pw_dir ? strlen(srcpw->pw_dir) + 1 : 1 + srcpw->pw_shell ? +		strlen(srcpw->pw_shell) + 1 : 1 + 2 +	/*  for 'x' in passwd */ +		12;			/*  for the "Mapped user" in gecos */ +	if (needlen > len) { +		if (debug) +			syslog(LOG_DEBUG, +			       "%s provided password buffer too small (%ld<%d)", +			       libname, (long)len, needlen); +		return 1; +	} -    destpw->pw_uid = srcpw->pw_uid; -    destpw->pw_gid = srcpw->pw_gid; +	destpw->pw_uid = srcpw->pw_uid; +	destpw->pw_gid = srcpw->pw_gid; -    cnt = snprintf(buf, len, "%s", usename); -    destpw->pw_name = buf; -    cnt++; /* allow for null byte also */ -    buf += cnt; -    len -= cnt; -    cnt = snprintf(buf, len, "%s", "x"); -    destpw->pw_passwd = buf; -    cnt++; -    buf += cnt; -    len -= cnt; -    cnt = snprintf(buf, len, "%s", srcpw->pw_shell ? srcpw->pw_shell : ""); -    destpw->pw_shell = buf; -    shell = strrchr(buf, '/'); -    shell = shell ? shell+1 : buf; -    cnt++; -    buf += cnt; -    len -= cnt; -    cnt = snprintf(buf, len, "%s mapped user", usename); -    destpw->pw_gecos = buf; -    cnt++; -    buf += cnt; -    len -= cnt; -    if (usename) { -        char *slash, dbuf[strlen(srcpw->pw_dir) + strlen(usename)]; -        snprintf(dbuf, sizeof dbuf, "%s", srcpw->pw_dir ? srcpw->pw_dir : ""); -        slash = strrchr(dbuf, '/'); -        if (slash) { -            slash++; -            snprintf(slash, sizeof dbuf - (slash-dbuf), "%s", usename); -        } -        cnt = snprintf(buf, len, "%s", dbuf); -    } -    else -        cnt = snprintf(buf, len, "%s", srcpw->pw_dir ? srcpw->pw_dir : ""); -    destpw->pw_dir = buf; -    cnt++; -    buf += cnt; -    len -= cnt; -    if(len < 0) { -        if(debug) -            syslog(LOG_DEBUG, "%s provided password buffer too small (%ld<%d)", -                libname, (long)origlen, origlen-(int)len); -        return 1; -    } +	cnt = snprintf(buf, len, "%s", usename); +	destpw->pw_name = buf; +	cnt++;			/* allow for null byte also */ +	buf += cnt; +	len -= cnt; +	cnt = snprintf(buf, len, "%s", "x"); +	destpw->pw_passwd = buf; +	cnt++; +	buf += cnt; +	len -= cnt; +	cnt = snprintf(buf, len, "%s", srcpw->pw_shell ? srcpw->pw_shell : ""); +	destpw->pw_shell = buf; +	shell = strrchr(buf, '/'); +	shell = shell ? shell + 1 : buf; +	cnt++; +	buf += cnt; +	len -= cnt; +	cnt = snprintf(buf, len, "%s mapped user", usename); +	destpw->pw_gecos = buf; +	cnt++; +	buf += cnt; +	len -= cnt; +	if (usename) { +		char *slash, dbuf[strlen(srcpw->pw_dir) + strlen(usename)]; +		snprintf(dbuf, sizeof dbuf, "%s", +			 srcpw->pw_dir ? srcpw->pw_dir : ""); +		slash = strrchr(dbuf, '/'); +		if (slash) { +			slash++; +			snprintf(slash, sizeof dbuf - (slash - dbuf), "%s", +				 usename); +		} +		cnt = snprintf(buf, len, "%s", dbuf); +	} else +		cnt = +		    snprintf(buf, len, "%s", +			     srcpw->pw_dir ? srcpw->pw_dir : ""); +	destpw->pw_dir = buf; +	cnt++; +	buf += cnt; +	len -= cnt; +	if (len < 0) { +		if (debug) +			syslog(LOG_DEBUG, +			       "%s provided password buffer too small (%ld<%d)", +			       libname, (long)origlen, origlen - (int)len); +		return 1; +	} -    return 0; +	return 0;  }  /* @@ -242,33 +243,31 @@ pwcopy(char *buf, size_t len, struct passwd *srcpw, struct passwd *destpw,   * map file.   * returns 0 on success   */ -int -get_pw_mapuser(const char *name, struct pwbuf *pb) +int get_pw_mapuser(const char *name, struct pwbuf *pb)  { -    FILE *pwfile; -    struct passwd *ent; -    int ret = 1; - +	FILE *pwfile; +	struct passwd *ent; +	int ret = 1; -    pwfile = fopen("/etc/passwd", "r"); -    if(!pwfile) { -        syslog(LOG_WARNING, "%s: failed to open /etc/passwd: %m", -            libname); -        return 1; -    } +	pwfile = fopen("/etc/passwd", "r"); +	if (!pwfile) { +		syslog(LOG_WARNING, "%s: failed to open /etc/passwd: %m", +		       libname); +		return 1; +	} -    pb->pw->pw_name = NULL; /* be paranoid */ -    for(ret = 1; ret && (ent = fgetpwent(pwfile)); ) { -        if(!ent->pw_name) -            continue; /* shouldn't happen */ -        if(!strcmp(ent->pw_name, mappeduser)) { -            ret = pwcopy(pb->buf, pb->buflen, ent, pb->pw, name); -            break; -        } -    } -    fclose(pwfile); -    if(ret) -       *pb->errnop = ERANGE; +	pb->pw->pw_name = NULL;	/* be paranoid */ +	for (ret = 1; ret && (ent = fgetpwent(pwfile));) { +		if (!ent->pw_name) +			continue;	/* shouldn't happen */ +		if (!strcmp(ent->pw_name, mappeduser)) { +			ret = pwcopy(pb->buf, pb->buflen, ent, pb->pw, name); +			break; +		} +	} +	fclose(pwfile); +	if (ret) +		*pb->errnop = ERANGE; -    return ret; +	return ret;  } diff --git a/map_common.h b/map_common.h index ff136d3..b3401ea 100644 --- a/map_common.h +++ b/map_common.h @@ -23,7 +23,6 @@   * stripped during the linking phase (made internal only).   */ -  #include <string.h>  #include <syslog.h>  #include <stdlib.h> @@ -34,17 +33,16 @@  #include <ctype.h>  #include <nss.h> -  /*   * pwbuf is used to reduce number of arguments passed around; the strings in   * the passwd struct need to point into this buffer.   */  struct pwbuf { -    char *name; -    char *buf; -    struct passwd *pw; -    int *errnop; -    size_t buflen; +	char *name; +	char *buf; +	struct passwd *pw; +	int *errnop; +	size_t buflen;  };  /* configuration variables. */ @@ -55,7 +53,6 @@ extern uid_t min_uid;  extern int debug;  extern int nss_mapuser_config(int *errnop, const char *lname); -extern int pwcopy(char *buf, size_t len, struct passwd *srcpw, struct passwd *destpw, -       const char *usename); +extern int pwcopy(char *buf, size_t len, struct passwd *srcpw, +		  struct passwd *destpw, const char *usename);  extern int get_pw_mapuser(const char *name, struct pwbuf *pb); - diff --git a/nss_mapname.c b/nss_mapname.c index f795cf5..e974b75 100644 --- a/nss_mapname.c +++ b/nss_mapname.c @@ -35,12 +35,10 @@   * See nss_mapuid.c for the matching getpwuid_r for UIDs.   */ -  #include "map_common.h"  #include <stdbool.h> - -static const char *nssname = "nss_mapuser"; /* for syslogs */ +static const char *nssname = "nss_mapuser";	/* for syslogs */  /*   * If you aren't using glibc or a variant that supports this, @@ -57,75 +55,75 @@ extern const char *__progname;   * Because we always have a positive reply, it's important that this   * be the last NSS module for passwd lookups.   */ -__attribute__ ((visibility ("default"))) +__attribute__ ((visibility("default")))  enum nss_status _nss_mapname_getpwnam_r(const char *name, struct passwd *pw, -    char *buffer, size_t buflen, int *errnop) +					char *buffer, size_t buflen, +					int *errnop)  { -    enum nss_status status = NSS_STATUS_NOTFOUND; -    struct pwbuf pbuf; -    bool islocal = 0; - -    /* -     * the useradd family will not add/mod/del users correctly with -     * the mapuid functionality, so return immediately if we are -     * running as part of those processes. -     */ -    if (__progname && (!strcmp(__progname, "useradd") ||  -        !strcmp(__progname, "usermod") ||  -        !strcmp(__progname, "userdel"))) -        return status; +	enum nss_status status = NSS_STATUS_NOTFOUND; +	struct pwbuf pbuf; +	bool islocal = 0; -    if (nss_mapuser_config(errnop, nssname) == 1) { -         syslog(LOG_NOTICE, "%s: bad configuration", nssname); -         return status; -    } +	/* +	 * the useradd family will not add/mod/del users correctly with +	 * the mapuid functionality, so return immediately if we are +	 * running as part of those processes. +	 */ +	if (__progname && (!strcmp(__progname, "useradd") || +			   !strcmp(__progname, "usermod") || +			   !strcmp(__progname, "userdel"))) +		return status; -    /* -     * Ignore any name starting with tacacs[0-9] in case a -     * tacplus client is installed.  Cleaner than listing -     * all 16 in the exclude_users list or implementing -     * some form of wildcard.  Also ignore our own mappeduser -     * and mapped_priv_user names if set. -     */ -    if ((mappeduser && !strcmp(mappeduser, name)) || -        (mapped_priv_user && !strcmp(mapped_priv_user, name))) -        islocal = 1; -    else if (!strncmp("tacacs", name, 6) && isdigit(name[6])) -        islocal = 1; -    else if (exclude_users) { -        char *user, *list; -        list = strdup(exclude_users); -        if (list) { -            static const char *delim = ", \t\n"; -            user = strtok(list, delim); -            list = NULL; -            while (user) { -                if(!strcmp(user, name)) { -                    islocal = 1; -                    break; -                } -                user = strtok(NULL, delim); -            } -            free(list); -        } -    } -    if (islocal) { -        if(debug > 1) -            syslog(LOG_DEBUG, "%s: skipped excluded user: %s", nssname, -                name); -        return 2; -    } +	if (nss_mapuser_config(errnop, nssname) == 1) { +		syslog(LOG_NOTICE, "%s: bad configuration", nssname); +		return status; +	} +	/* +	 * Ignore any name starting with tacacs[0-9] in case a +	 * tacplus client is installed.  Cleaner than listing +	 * all 16 in the exclude_users list or implementing +	 * some form of wildcard.  Also ignore our own mappeduser +	 * and mapped_priv_user names if set. +	 */ +	if ((mappeduser && !strcmp(mappeduser, name)) || +	    (mapped_priv_user && !strcmp(mapped_priv_user, name))) +		islocal = 1; +	else if (!strncmp("tacacs", name, 6) && isdigit(name[6])) +		islocal = 1; +	else if (exclude_users) { +		char *user, *list; +		list = strdup(exclude_users); +		if (list) { +			static const char *delim = ", \t\n"; +			user = strtok(list, delim); +			list = NULL; +			while (user) { +				if (!strcmp(user, name)) { +					islocal = 1; +					break; +				} +				user = strtok(NULL, delim); +			} +			free(list); +		} +	} +	if (islocal) { +		if (debug > 1) +			syslog(LOG_DEBUG, "%s: skipped excluded user: %s", +			       nssname, name); +		return 2; +	} -    /* marshal the args for the lower level functions */ -    pbuf.name = (char *)name; -    pbuf.pw = pw; -    pbuf.buf = buffer; -    pbuf.buflen = buflen; -    pbuf.errnop = errnop; +	/* marshal the args for the lower level functions */ +	pbuf.name = (char *)name; +	pbuf.pw = pw; +	pbuf.buf = buffer; +	pbuf.buflen = buflen; +	pbuf.errnop = errnop; -    if(!get_pw_mapuser(name, &pbuf)) -        status = NSS_STATUS_SUCCESS; +	if (!get_pw_mapuser(name, &pbuf)) +		status = NSS_STATUS_SUCCESS; -    return status; +	return status;  } diff --git a/nss_mapuid.c b/nss_mapuid.c index f97b28e..cc6c5ec 100644 --- a/nss_mapuid.c +++ b/nss_mapuid.c @@ -17,7 +17,6 @@   * along with this program - see the file COPYING.   */ -  /*   * This plugin implements getpwuid_r for NSS to map a UID back to   * a mapped username account, set up via nss_mapuser. @@ -48,8 +47,7 @@  #include <dirent.h>  #include <ctype.h> - -static const char *nssname = "nss_mapuid"; /* for syslogs */ +static const char *nssname = "nss_mapuid";	/* for syslogs */  static const char dbdir[] = "/run/mapuser/";  /* @@ -66,98 +64,97 @@ extern const char *__progname;   */  static int chk_session_file(char *sfile, uid_t uid, struct pwbuf *pb)  { -    char rbuf[256], user[64]; -    FILE *mapf; -    uid_t auid = 0; -    int ret = 1; - -    mapf = fopen(sfile, "r"); -    if (!mapf) { -        if( debug) -            syslog(LOG_DEBUG, "%s:  session map file %s open fails: %m", -                nssname, sfile); -        return ret; -    } -    user[0] = '\0'; -    while(fgets(rbuf, sizeof rbuf, mapf)) { -        strtok(rbuf, " \t\n\r\f"); /* terminate buffer at first whitespace */ -        if(!strncmp("user=", rbuf, 5)) { /* should precede auid */ -            snprintf(user, sizeof user, "%s", rbuf+5); -            if (auid) /* found out of order, but now have both */ -                break; -        } -        else if(!strncmp("auid=", rbuf, 5)) { -            uid_t fuid = (uid_t)strtoul(rbuf+5, NULL, 10); -            if (fuid && uid == fuid) { -                auid = fuid; -                if (user[0]) -                    break; /*  normal ordering, else keep looking for user */ -            } -        } -    } -    fclose(mapf); - -    if (auid && user[0]) /*  otherwise not a match */ -        ret = get_pw_mapuser(user, pb); /* should always succeed */ - -    return ret; +	char rbuf[256], user[64]; +	FILE *mapf; +	uid_t auid = 0; +	int ret = 1; + +	mapf = fopen(sfile, "r"); +	if (!mapf) { +		if (debug) +			syslog(LOG_DEBUG, +			       "%s:  session map file %s open fails: %m", +			       nssname, sfile); +		return ret; +	} +	user[0] = '\0'; +	while (fgets(rbuf, sizeof rbuf, mapf)) { +		strtok(rbuf, " \t\n\r\f");	/* terminate buffer at first whitespace */ +		if (!strncmp("user=", rbuf, 5)) {	/* should precede auid */ +			snprintf(user, sizeof user, "%s", rbuf + 5); +			if (auid)	/* found out of order, but now have both */ +				break; +		} else if (!strncmp("auid=", rbuf, 5)) { +			uid_t fuid = (uid_t) strtoul(rbuf + 5, NULL, 10); +			if (fuid && uid == fuid) { +				auid = fuid; +				if (user[0]) +					break;	/*  normal ordering, else keep looking for user */ +			} +		} +	} +	fclose(mapf); + +	if (auid && user[0])	/*  otherwise not a match */ +		ret = get_pw_mapuser(user, pb);	/* should always succeed */ + +	return ret;  }  /* find mapping for this sessionid */ -static int -find_mapped_name(struct pwbuf *pb, uid_t uid, uint32_t session) +static int find_mapped_name(struct pwbuf *pb, uid_t uid, uint32_t session)  { -    char sessfile[sizeof dbdir + 11]; +	char sessfile[sizeof dbdir + 11]; -    snprintf(sessfile, sizeof sessfile, "%s%u", dbdir, session); -    return chk_session_file(sessfile, uid, pb); +	snprintf(sessfile, sizeof sessfile, "%s%u", dbdir, session); +	return chk_session_file(sessfile, uid, pb);  }  static int find_mappingfile(struct pwbuf *pb, uid_t uid)  { -    DIR *dir; -    struct dirent *ent; -    int ret = 1; - -    dir = opendir(dbdir); -    if (!dir) { /*  can happen if no mapped users logged in */ -        if (debug > 1) -            syslog(LOG_DEBUG, "%s: Unable to open mapping directory %s: %m", -                nssname, dbdir); -        return 1; -    } - -    /* Loop through all numeric files in dbdir, check for matching uid */ -    while (ret && (ent = readdir(dir))) { -        char sessfile[sizeof dbdir + 11]; -        if (!isdigit(ent->d_name[0])) /* sanity check on session file */ -            continue; -        snprintf(sessfile, sizeof sessfile, "%s%s", dbdir, ent->d_name); -        ret = chk_session_file(sessfile, uid, pb); -    } -    if (ret && debug) -        syslog(LOG_DEBUG, "%s: uid %u mapping not found in map files", -            nssname, uid); -    closedir(dir); -    return ret; +	DIR *dir; +	struct dirent *ent; +	int ret = 1; + +	dir = opendir(dbdir); +	if (!dir) {		/*  can happen if no mapped users logged in */ +		if (debug > 1) +			syslog(LOG_DEBUG, +			       "%s: Unable to open mapping directory %s: %m", +			       nssname, dbdir); +		return 1; +	} + +	/* Loop through all numeric files in dbdir, check for matching uid */ +	while (ret && (ent = readdir(dir))) { +		char sessfile[sizeof dbdir + 11]; +		if (!isdigit(ent->d_name[0]))	/* sanity check on session file */ +			continue; +		snprintf(sessfile, sizeof sessfile, "%s%s", dbdir, ent->d_name); +		ret = chk_session_file(sessfile, uid, pb); +	} +	if (ret && debug) +		syslog(LOG_DEBUG, "%s: uid %u mapping not found in map files", +		       nssname, uid); +	closedir(dir); +	return ret;  } -static uint32_t -get_sessionid(void) +static uint32_t get_sessionid(void)  { -    int fd = -1, cnt; -    uint32_t id = 0U; -    static char buf[12]; - -    fd = open("/proc/self/sessionid", O_RDONLY); -    if(fd != -1) { -        cnt = read(fd, buf, sizeof(buf)); -        close(fd); -    } -    if(fd != -1 && cnt > 0) { -        id = strtoul(buf, NULL, 0); -    } -    return id; +	int fd = -1, cnt; +	uint32_t id = 0U; +	static char buf[12]; + +	fd = open("/proc/self/sessionid", O_RDONLY); +	if (fd != -1) { +		cnt = read(fd, buf, sizeof(buf)); +		close(fd); +	} +	if (fd != -1 && cnt > 0) { +		id = strtoul(buf, NULL, 0); +	} +	return id;  }  /* @@ -184,55 +181,55 @@ get_sessionid(void)   * just get the files, ldap, etc. entry for the UID   * Returns the first match if multiple mapped users.   */ -__attribute__ ((visibility ("default"))) +__attribute__ ((visibility("default")))  enum nss_status _nss_mapuid_getpwuid_r(uid_t uid, struct passwd *pw, -    char *buffer, size_t buflen, int *errnop) +				       char *buffer, size_t buflen, int *errnop)  { -    struct pwbuf pb; -    enum nss_status status = NSS_STATUS_NOTFOUND; -    uint32_t session; - -    /* -     * the useradd family will not add/mod/del users correctly with -     * the mapuid functionality, so return immediately if we are -     * running as part of those processes. -     */ -    if (__progname && (!strcmp(__progname, "useradd") ||  -        !strcmp(__progname, "usermod") ||  -        !strcmp(__progname, "userdel"))) -        return status; - -    /*  this can happen for permission reasons, do don't complain except -     *  at debug */ -    if (nss_mapuser_config(errnop, nssname) == 1) { -         return status; /* syslog already done */ -    } - - -    if (min_uid != ~0U && uid < min_uid) { -        if(debug > 1) -            syslog(LOG_DEBUG, "%s: uid %u < min_uid %u, don't lookup", -                nssname, uid, min_uid); -        return status; -    } - -    /* marshal the args for the lower level functions */ -    pb.pw = pw; -    pb.buf = buffer; -    pb.buflen = buflen; -    pb.errnop = errnop; -    pb.name = NULL; - -    /* session needs to be set to lookup this user.  May also be set -     * for other users. -     */ -    session = get_sessionid(); -    if(session && !find_mapped_name(&pb, uid, session)) -        status = NSS_STATUS_SUCCESS; -    if(status != NSS_STATUS_SUCCESS) { -        /* lookup by some other user or unrelated process, try dir lookup */ -        if (!find_mappingfile(&pb, uid)) -            status = NSS_STATUS_SUCCESS; -    } -    return status; +	struct pwbuf pb; +	enum nss_status status = NSS_STATUS_NOTFOUND; +	uint32_t session; + +	/* +	 * the useradd family will not add/mod/del users correctly with +	 * the mapuid functionality, so return immediately if we are +	 * running as part of those processes. +	 */ +	if (__progname && (!strcmp(__progname, "useradd") || +			   !strcmp(__progname, "usermod") || +			   !strcmp(__progname, "userdel"))) +		return status; + +	/*  this can happen for permission reasons, do don't complain except +	 *  at debug */ +	if (nss_mapuser_config(errnop, nssname) == 1) { +		return status;	/* syslog already done */ +	} + +	if (min_uid != ~0U && uid < min_uid) { +		if (debug > 1) +			syslog(LOG_DEBUG, +			       "%s: uid %u < min_uid %u, don't lookup", nssname, +			       uid, min_uid); +		return status; +	} + +	/* marshal the args for the lower level functions */ +	pb.pw = pw; +	pb.buf = buffer; +	pb.buflen = buflen; +	pb.errnop = errnop; +	pb.name = NULL; + +	/* session needs to be set to lookup this user.  May also be set +	 * for other users. +	 */ +	session = get_sessionid(); +	if (session && !find_mapped_name(&pb, uid, session)) +		status = NSS_STATUS_SUCCESS; +	if (status != NSS_STATUS_SUCCESS) { +		/* lookup by some other user or unrelated process, try dir lookup */ +		if (!find_mappingfile(&pb, uid)) +			status = NSS_STATUS_SUCCESS; +	} +	return status;  } | 
