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; } |