* move pw_scan() from libutil to libc
* add support for YP "master.passwd.by*" (master.passwd in YP, including pw_passwd) and "passwd.adjunct.by*" (SunOS `secure' maps (?)), based on code in FreeBSD and partially from OpenBSD. this is only used if euid == 0. with this, the YP "passwd.by*" maps can have `*' in the pw_passwd field. * use pw_scan() to parse YP "passwd.by*" and "master.passwd.by*" entries XXX: i didn't test the "passwd.adjunct" support...
This commit is contained in:
parent
32e5dd1f22
commit
9557a71026
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile.inc,v 1.90 1998/04/28 17:54:41 fair Exp $
|
||||
# $NetBSD: Makefile.inc,v 1.91 1998/06/08 03:17:59 lukem Exp $
|
||||
# from: @(#)Makefile.inc 8.6 (Berkeley) 5/4/95
|
||||
|
||||
# gen sources
|
||||
|
@ -15,7 +15,7 @@ SRCS+= _errno.c alarm.c assert.c basename.c clock.c closedir.c \
|
|||
getusershell.c __glob13.c glob.c initgroups.c isatty.c \
|
||||
isctype.c lockf.c nice.c nlist.c nlist_aout.c \
|
||||
nlist_ecoff.c nlist_elf32.c nlist_elf64.c opendir.c \
|
||||
pause.c popen.c psignal.c pwcache.c raise.c readdir.c \
|
||||
pause.c popen.c psignal.c pwcache.c pw_scan.c raise.c readdir.c \
|
||||
rewinddir.c scandir.c seekdir.c setdomainname.c \
|
||||
sethostname.c setjmperr.c setmode.c setproctitle.c \
|
||||
siginterrupt.c siglist.c signal.c signame.c sigsetops.c \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: getpwent.c,v 1.25 1998/02/10 03:56:33 mrg Exp $ */
|
||||
/* $NetBSD: getpwent.c,v 1.26 1998/06/08 03:18:00 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
|
@ -39,7 +39,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)getpwent.c 8.2 (Berkeley) 4/27/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: getpwent.c,v 1.25 1998/02/10 03:56:33 mrg Exp $");
|
||||
__RCSID("$NetBSD: getpwent.c,v 1.26 1998/06/08 03:18:00 lukem Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
|
@ -93,6 +93,8 @@ const char __yp_token[] = "__YP!"; /* Let pwd_mkdb pull this in. */
|
|||
enum _ypmode { YPMODE_NONE, YPMODE_FULL, YPMODE_USER, YPMODE_NETGRP };
|
||||
static enum _ypmode __ypmode;
|
||||
|
||||
enum _ypmap { YPMAP_NONE, YPMAP_ADJUNCT, YPMAP_MASTER };
|
||||
|
||||
static char *__ypcurrent, *__ypdomain;
|
||||
static int __ypcurrentlen;
|
||||
static struct passwd *__ypproto = (struct passwd *)NULL;
|
||||
|
@ -104,12 +106,19 @@ static DB *__ypexclude = (DB *)NULL;
|
|||
static int __has_yppw __P((void));
|
||||
static int __ypexclude_add __P((const char *));
|
||||
static int __ypexclude_is __P((const char *));
|
||||
static int __ypmaptype __P((void));
|
||||
static void __ypproto_set __P((void));
|
||||
static int __ypparse __P((struct passwd *, char *));
|
||||
|
||||
/* macros for deciding which YP maps to use. */
|
||||
#define PASSWD_BYNAME (__ypmaptype() == YPMAP_MASTER \
|
||||
? "master.passwd.byname" : "passwd.byname")
|
||||
#define PASSWD_BYUID (__ypmaptype() == YPMAP_MASTER \
|
||||
? "master.passwd.byuid" : "passwd.byuid")
|
||||
|
||||
static int
|
||||
__ypexclude_add(name)
|
||||
const char *name;
|
||||
const char *name;
|
||||
{
|
||||
DBT key, data;
|
||||
|
||||
|
@ -137,7 +146,7 @@ const char *name;
|
|||
|
||||
static int
|
||||
__ypexclude_is(name)
|
||||
const char *name;
|
||||
const char *name;
|
||||
{
|
||||
DBT key, data;
|
||||
|
||||
|
@ -232,35 +241,61 @@ __ypproto_set()
|
|||
}
|
||||
|
||||
static int
|
||||
__ypparse(pw, s)
|
||||
struct passwd *pw;
|
||||
char *s;
|
||||
__ypmaptype()
|
||||
{
|
||||
char *bp, *cp, *ep;
|
||||
unsigned long id;
|
||||
static int maptype = -1;
|
||||
int order, r;
|
||||
|
||||
/* since this is currently using strsep(), parse it first */
|
||||
bp = s;
|
||||
pw->pw_name = strsep(&bp, ":\n");
|
||||
pw->pw_passwd = strsep(&bp, ":\n");
|
||||
if (!(cp = strsep(&bp, ":\n")))
|
||||
if (maptype != -1)
|
||||
return (maptype);
|
||||
|
||||
maptype = YPMAP_NONE;
|
||||
if (geteuid() != 0)
|
||||
return (maptype);
|
||||
|
||||
if (!__ypdomain) {
|
||||
if( _yp_check(&__ypdomain) == 0)
|
||||
return (maptype);
|
||||
}
|
||||
|
||||
r = yp_order(__ypdomain, "master.passwd.byname", &order);
|
||||
if (r == 0) {
|
||||
maptype = YPMAP_MASTER;
|
||||
return (maptype);
|
||||
}
|
||||
|
||||
/*
|
||||
* NIS+ in YP compat mode doesn't support
|
||||
* YPPROC_ORDER -- no point in continuing.
|
||||
*/
|
||||
if (r == YPERR_YPERR)
|
||||
return (maptype);
|
||||
|
||||
/* master.passwd doesn't exist -- try passwd.adjunct */
|
||||
if (r == YPERR_MAP) {
|
||||
r = yp_order(__ypdomain, "passwd.adjunct.byname", &order);
|
||||
if (r == 0)
|
||||
maptype = YPMAP_ADJUNCT;
|
||||
return (maptype);
|
||||
}
|
||||
|
||||
return (maptype);
|
||||
}
|
||||
|
||||
static int
|
||||
__ypparse(pw, s)
|
||||
struct passwd *pw;
|
||||
char *s;
|
||||
{
|
||||
static char adjunctpw[YPMAXRECORD + 2];
|
||||
int flags, maptype;
|
||||
|
||||
maptype = __ypmaptype();
|
||||
flags = _PASSWORD_NOWARN;
|
||||
if (maptype != YPMAP_MASTER)
|
||||
flags |= _PASSWORD_OLDFMT;
|
||||
if (! pw_scan(s, pw, &flags))
|
||||
return 1;
|
||||
id = strtoul(cp, &ep, 10);
|
||||
if (id > UID_MAX || *ep != '\0')
|
||||
return 1;
|
||||
pw->pw_uid = (uid_t)id;
|
||||
if (!(cp = strsep(&bp, ":\n")))
|
||||
return 1;
|
||||
id = strtoul(cp, &ep, 10);
|
||||
if (id > GID_MAX || *ep != '\0')
|
||||
return 1;
|
||||
pw->pw_gid = (gid_t)id;
|
||||
pw->pw_change = 0;
|
||||
pw->pw_class = "";
|
||||
pw->pw_gecos = strsep(&bp, ":\n");
|
||||
pw->pw_dir = strsep(&bp, ":\n");
|
||||
pw->pw_shell = strsep(&bp, ":\n");
|
||||
pw->pw_expire = 0;
|
||||
|
||||
/* now let the prototype override, if set. */
|
||||
if(__ypproto != (struct passwd *)NULL) {
|
||||
|
@ -279,6 +314,23 @@ char *s;
|
|||
if(__ypproto->pw_shell != (char *)NULL)
|
||||
pw->pw_shell = __ypproto->pw_shell;
|
||||
}
|
||||
if ((maptype == YPMAP_ADJUNCT) &&
|
||||
(strstr(pw->pw_passwd, "##") != NULL)) {
|
||||
char *data, *bp;
|
||||
int datalen;
|
||||
|
||||
if (yp_match(__ypdomain, "passwd.adjunct.byname", pw->pw_name,
|
||||
strlen(pw->pw_name), &data, &datalen) == 0) {
|
||||
if (datalen > sizeof(adjunctpw) - 1)
|
||||
datalen = sizeof(adjunctpw) - 1;
|
||||
strncpy(adjunctpw, data, datalen);
|
||||
|
||||
/* skip name to get password */
|
||||
if ((bp = strsep(&data, ":")) != NULL &&
|
||||
(bp = strsep(&data, ":")) != NULL)
|
||||
pw->pw_passwd = bp;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -317,7 +369,7 @@ again:
|
|||
data = NULL;
|
||||
if(__ypcurrent) {
|
||||
key = NULL;
|
||||
r = yp_next(__ypdomain, "passwd.byname",
|
||||
r = yp_next(__ypdomain, PASSWD_BYNAME,
|
||||
__ypcurrent, __ypcurrentlen,
|
||||
&key, &keylen, &data, &datalen);
|
||||
free(__ypcurrent);
|
||||
|
@ -331,7 +383,7 @@ again:
|
|||
__ypcurrentlen = keylen;
|
||||
}
|
||||
} else {
|
||||
r = yp_first(__ypdomain, "passwd.byname",
|
||||
r = yp_first(__ypdomain, PASSWD_BYNAME,
|
||||
&__ypcurrent, &__ypcurrentlen,
|
||||
&data, &datalen);
|
||||
}
|
||||
|
@ -355,7 +407,7 @@ again:
|
|||
}
|
||||
if(user && *user) {
|
||||
data = NULL;
|
||||
r = yp_match(__ypdomain, "passwd.byname",
|
||||
r = yp_match(__ypdomain, PASSWD_BYNAME,
|
||||
user, strlen(user),
|
||||
&data, &datalen);
|
||||
} else
|
||||
|
@ -376,7 +428,7 @@ again:
|
|||
case YPMODE_USER:
|
||||
if(name != (char *)NULL) {
|
||||
data = NULL;
|
||||
r = yp_match(__ypdomain, "passwd.byname",
|
||||
r = yp_match(__ypdomain, PASSWD_BYNAME,
|
||||
name, strlen(name),
|
||||
&data, &datalen);
|
||||
__ypmode = YPMODE_NONE;
|
||||
|
@ -535,7 +587,7 @@ getpwnam(name)
|
|||
__ypcurrent = NULL;
|
||||
}
|
||||
r = yp_match(__ypdomain,
|
||||
"passwd.byname",
|
||||
PASSWD_BYNAME,
|
||||
name, strlen(name),
|
||||
&__ypcurrent, &__ypcurrentlen);
|
||||
if(r != 0) {
|
||||
|
@ -561,7 +613,7 @@ pwnam_netgrp:
|
|||
} else {
|
||||
if(user && *user) {
|
||||
r = yp_match(__ypdomain,
|
||||
"passwd.byname",
|
||||
PASSWD_BYNAME,
|
||||
user, strlen(user),
|
||||
&__ypcurrent,
|
||||
&__ypcurrentlen);
|
||||
|
@ -587,7 +639,7 @@ pwnam_netgrp:
|
|||
}
|
||||
user = _pw_passwd.pw_name + 1;
|
||||
r = yp_match(__ypdomain,
|
||||
"passwd.byname",
|
||||
PASSWD_BYNAME,
|
||||
user, strlen(user),
|
||||
&__ypcurrent,
|
||||
&__ypcurrentlen);
|
||||
|
@ -720,7 +772,7 @@ getpwuid(uid)
|
|||
free(__ypcurrent);
|
||||
__ypcurrent = NULL;
|
||||
}
|
||||
r = yp_match(__ypdomain, "passwd.byuid",
|
||||
r = yp_match(__ypdomain, PASSWD_BYUID,
|
||||
uidbuf, strlen(uidbuf),
|
||||
&__ypcurrent, &__ypcurrentlen);
|
||||
if(r != 0) {
|
||||
|
@ -746,7 +798,7 @@ pwuid_netgrp:
|
|||
} else {
|
||||
if(user && *user) {
|
||||
r = yp_match(__ypdomain,
|
||||
"passwd.byname",
|
||||
PASSWD_BYNAME,
|
||||
user, strlen(user),
|
||||
&__ypcurrent,
|
||||
&__ypcurrentlen);
|
||||
|
@ -772,7 +824,7 @@ pwuid_netgrp:
|
|||
}
|
||||
user = _pw_passwd.pw_name + 1;
|
||||
r = yp_match(__ypdomain,
|
||||
"passwd.byname",
|
||||
PASSWD_BYNAME,
|
||||
user, strlen(user),
|
||||
&__ypcurrent,
|
||||
&__ypcurrentlen);
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/* $NetBSD: pw_scan.c,v 1.1 1998/06/08 03:18:00 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: pw_scan.c,v 1.1 1998/06/08 03:18:00 lukem Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
pw_scan(bp, pw, flags)
|
||||
char *bp;
|
||||
struct passwd *pw;
|
||||
int *flags;
|
||||
{
|
||||
unsigned long id;
|
||||
int root, inflags;
|
||||
char *p, *sh, *ep;
|
||||
|
||||
inflags = 0;
|
||||
if (flags != (int *)NULL) {
|
||||
inflags = *flags;
|
||||
*flags = 0;
|
||||
}
|
||||
|
||||
if (!(pw->pw_name = strsep(&bp, ":"))) /* login */
|
||||
goto fmt;
|
||||
root = !strcmp(pw->pw_name, "root");
|
||||
|
||||
if (!(pw->pw_passwd = strsep(&bp, ":"))) /* passwd */
|
||||
goto fmt;
|
||||
|
||||
if (!(p = strsep(&bp, ":"))) /* uid */
|
||||
goto fmt;
|
||||
id = strtoul(p, &ep, 10);
|
||||
if (root && id) {
|
||||
if (!(inflags & _PASSWORD_NOWARN))
|
||||
warnx("root uid should be 0");
|
||||
return (0);
|
||||
}
|
||||
if (id > UID_MAX || *ep != '\0') {
|
||||
if (!(inflags & _PASSWORD_NOWARN))
|
||||
warnx("invalid uid '%s'", p);
|
||||
return (0);
|
||||
}
|
||||
pw->pw_uid = (uid_t)id;
|
||||
if ((*p == '\0') && (flags != (int *)NULL))
|
||||
*flags |= _PASSWORD_NOUID;
|
||||
|
||||
if (!(p = strsep(&bp, ":"))) /* gid */
|
||||
goto fmt;
|
||||
id = strtoul(p, &ep, 10);
|
||||
if (id > GID_MAX || *ep != '\0') {
|
||||
if (!(inflags & _PASSWORD_NOWARN))
|
||||
warnx("invalid gid '%s'", p);
|
||||
return (0);
|
||||
}
|
||||
pw->pw_gid = (gid_t)id;
|
||||
if ((*p == '\0') && (flags != (int *)NULL))
|
||||
*flags |= _PASSWORD_NOGID;
|
||||
|
||||
if (inflags & _PASSWORD_OLDFMT) {
|
||||
pw->pw_class = "";
|
||||
pw->pw_change = 0;
|
||||
pw->pw_expire = 0;
|
||||
*flags |= (_PASSWORD_NOCHG | _PASSWORD_NOEXP);
|
||||
} else {
|
||||
pw->pw_class = strsep(&bp, ":"); /* class */
|
||||
if (!(p = strsep(&bp, ":"))) /* change */
|
||||
goto fmt;
|
||||
pw->pw_change = atol(p);
|
||||
if ((*p == '\0') && (flags != (int *)NULL))
|
||||
*flags |= _PASSWORD_NOCHG;
|
||||
if (!(p = strsep(&bp, ":"))) /* expire */
|
||||
goto fmt;
|
||||
pw->pw_expire = atol(p);
|
||||
if ((*p == '\0') && (flags != (int *)NULL))
|
||||
*flags |= _PASSWORD_NOEXP;
|
||||
}
|
||||
pw->pw_gecos = strsep(&bp, ":"); /* gecos */
|
||||
pw->pw_dir = strsep(&bp, ":"); /* directory */
|
||||
if (!(pw->pw_shell = strsep(&bp, ":"))) /* shell */
|
||||
goto fmt;
|
||||
|
||||
p = pw->pw_shell;
|
||||
if (root && *p) /* empty == /bin/sh */
|
||||
for (setusershell();;) {
|
||||
if (!(sh = getusershell())) {
|
||||
if (!(inflags & _PASSWORD_NOWARN))
|
||||
warnx("warning, unknown root shell");
|
||||
break;
|
||||
}
|
||||
if (!strcmp(p, sh))
|
||||
break;
|
||||
}
|
||||
|
||||
if ((p = strsep(&bp, ":"))) { /* too many */
|
||||
fmt:
|
||||
if (!(inflags & _PASSWORD_NOWARN))
|
||||
warnx("corrupted entry");
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
Loading…
Reference in New Issue