diff options
author | wpaul <wpaul@FreeBSD.org> | 1995-01-31 10:04:18 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 1995-01-31 10:04:18 +0000 |
commit | 5902fd25c28494ce194edad49898610e485c708f (patch) | |
tree | 54f1e9f4e852b7f7a93f2b5aebc75603545a3a8c /lib | |
parent | 86715246c4a790c232b707102fbed0d2e3318f31 (diff) | |
download | FreeBSD-src-5902fd25c28494ce194edad49898610e485c708f.zip FreeBSD-src-5902fd25c28494ce194edad49898610e485c708f.tar.gz |
Some changes for YP password map handling:
- FreeBSD's NIS server can supply a master.passwd map, which has
more fields in it than a standard passwd map, so we need a
_master_pw_breakout() fuction.
- When doing passwd map lookups, look for master.passwd.* by attempting
a _yp_first() on master.passwd.byname. If it exists, we're being served
by a FreeBSD NIS server and we should use this map.
- If we aren't the superuser, retrieve only the standard passwd maps.
If we're being served by a FreeBSD system, then the passwd map has
no passwords in it, and it won't serve us the master.passwd map unless
we're superuser anyway.
There's a small speed hit for the superuser inherent in the check for
the master.passwd map, but this lets us dynamically decide what to do
rather than rely on a non-standard config file somewhere. Since all
of this is bypassed for normal users, they shouldn't notice the
difference.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/gen/getpwent.c | 120 |
1 files changed, 114 insertions, 6 deletions
diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c index 31a88c8..9f978af 100644 --- a/lib/libc/gen/getpwent.c +++ b/lib/libc/gen/getpwent.c @@ -58,6 +58,7 @@ static int _pw_stepping_yp; /* set true when stepping thru map */ #endif static int __hashpw(), __initdb(); +static int _havemaster(const char *); static int _getyppass(struct passwd *, const char *, const char *); static int _nextyppass(struct passwd *); @@ -339,21 +340,113 @@ _pw_breakout_yp(struct passwd *pw, char *result) } } +static void +_masterpw_breakout_yp(struct passwd *pw, char *result) +{ + char *s; + + s = strsep(&result, ":"); /* name */ + if(!(pw->pw_fields & _PWF_NAME) || (pw->pw_name[0] == '+')) { + pw->pw_name = s; + pw->pw_fields |= _PWF_NAME; + } + + s = strsep(&result, ":"); /* password */ + if(!(pw->pw_fields & _PWF_PASSWD)) { + pw->pw_passwd = s; + pw->pw_fields |= _PWF_PASSWD; + } + + s = strsep(&result, ":"); /* uid */ + if(!(pw->pw_fields & _PWF_UID)) { + pw->pw_uid = atoi(s); + pw->pw_fields |= _PWF_UID; + } + + s = strsep(&result, ":"); /* gid */ + if(!(pw->pw_fields & _PWF_GID)) { + pw->pw_gid = atoi(s); + pw->pw_fields |= _PWF_GID; + } + + s = strsep(&result, ":"); /* class */ + if(!(pw->pw_fields & _PWF_CLASS)) { + pw->pw_class = s; + pw->pw_fields |= _PWF_CLASS; + } + + s = strsep(&result, ":"); /* change */ + if(!(pw->pw_fields & _PWF_CHANGE)) { + pw->pw_change = atol(s); + pw->pw_fields |= _PWF_CHANGE; + } + + s = strsep(&result, ":"); /* expire */ + if(!(pw->pw_fields & _PWF_EXPIRE)) { + pw->pw_expire = atol(s); + pw->pw_fields |= _PWF_EXPIRE; + } + + s = strsep(&result, ":"); /* gecos */ + if(!(pw->pw_fields & _PWF_GECOS)) { + pw->pw_gecos = s; + pw->pw_fields |= _PWF_GECOS; + } + + s = strsep(&result, ":"); /* dir */ + if(!(pw->pw_fields & _PWF_DIR)) { + pw->pw_dir = s; + pw->pw_fields |= _PWF_DIR; + } + + s = strsep(&result, ":"); /* shell */ + if(!(pw->pw_fields & _PWF_SHELL)) { + pw->pw_shell = s; + pw->pw_fields |= _PWF_SHELL; + } +} + static char *_pw_yp_domain; static int +_havemaster(const char *_pw_yp_domain) +{ + char *result; + static char *key; + int resultlen; + static int keylen; + + if (yp_first(_pw_yp_domain, "master.passwd.byname", + &key, &keylen, &result, &resultlen)) + return 0; + + return 1; +} + +static int _getyppass(struct passwd *pw, const char *name, const char *map) { char *result, *s; static char resultbuf[1024]; int resultlen; + char mastermap[1024]; + int gotmaster = 0; if(!_pw_yp_domain) { if(yp_get_default_domain(&_pw_yp_domain)) return 0; } - if(yp_match(_pw_yp_domain, map, name, strlen(name), + sprintf(mastermap,"%s",map); + + /* Don't even bother with this if we aren't root. */ + if (!geteuid()) + if (_havemaster(_pw_yp_domain)) { + sprintf(mastermap,"master.passwd.%s",map); + gotmaster++; + } + + if(yp_match(_pw_yp_domain, &mastermap, name, strlen(name), &result, &resultlen)) return 0; @@ -363,7 +456,10 @@ _getyppass(struct passwd *pw, const char *name, const char *map) if(resultlen >= sizeof resultbuf) return 0; strcpy(resultbuf, result); result = resultbuf; - _pw_breakout_yp(pw, resultbuf); + if (gotmaster) + _masterpw_breakout_yp(pw, resultbuf); + else + _pw_breakout_yp(pw, resultbuf); return 1; } @@ -377,16 +473,25 @@ _nextyppass(struct passwd *pw) static char resultbuf[1024]; int resultlen; int rv; + char *map = "passwd.byname"; + int gotmaster = 0; if(!_pw_yp_domain) { if(yp_get_default_domain(&_pw_yp_domain)) return 0; } + /* Don't even bother with this if we aren't root. */ + if (!geteuid()) + if(_havemaster(_pw_yp_domain)) { + map = "master.passwd.byname"; + gotmaster++; + } + if(!_pw_stepping_yp) { if(key) free(key); - rv = yp_first(_pw_yp_domain, "passwd.byname", - &key, &keylen, &result, &resultlen); + rv = yp_first(_pw_yp_domain, map, + &key, &keylen, &result, &resultlen); if(rv) { return 0; } @@ -395,7 +500,7 @@ _nextyppass(struct passwd *pw) } else { tryagain: lastkey = key; - rv = yp_next(_pw_yp_domain, "passwd.byname", key, keylen, + rv = yp_next(_pw_yp_domain, map, key, keylen, &key, &keylen, &result, &resultlen); free(lastkey); unpack: @@ -412,7 +517,10 @@ unpack: strcpy(resultbuf, result); free(result); if(result = strchr(resultbuf, '\n')) *result = '\0'; - _pw_breakout_yp(pw, resultbuf); + if (gotmaster) + _masterpw_breakout_yp(pw, resultbuf); + else + _pw_breakout_yp(pw, resultbuf); } return 1; } |