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.
This commit is contained in:
wpaul 1995-01-31 10:04:18 +00:00
parent 86715246c4
commit 5902fd25c2

View File

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