summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1995-01-31 10:04:18 +0000
committerwpaul <wpaul@FreeBSD.org>1995-01-31 10:04:18 +0000
commit5902fd25c28494ce194edad49898610e485c708f (patch)
tree54f1e9f4e852b7f7a93f2b5aebc75603545a3a8c /lib
parent86715246c4a790c232b707102fbed0d2e3318f31 (diff)
downloadFreeBSD-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.c120
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;
}
OpenPOWER on IntegriCloud