Switch to NetBSD passwd format
Based on work by Vivek Prakash and Gianluca Guida. See UPDATING about caveats on currently existing accounts. . restores netbsd libc pwcache functions
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
.if defined(NBSD_LIBC) && (${NBSD_LIBC} != "no")
|
||||
LIBC_DIR= nbsd_libc
|
||||
LIBM_DIR= nbsd_libm
|
||||
LIBUTIL_DIR= libutil
|
||||
LIBCOMPAT_DIR= nbsd_libcompat_minix
|
||||
LIBMINLIB_DIR= nbsd_libminlib
|
||||
LIBASYN_DIR= nbsd_libasyn
|
||||
@@ -10,12 +11,13 @@ LIBASYN_DIR= nbsd_libasyn
|
||||
|
||||
LIBC_DIR?= libc
|
||||
LIBM_DIR?= libm
|
||||
LIBUTIL_DIR?= libminixutil
|
||||
LIBCOMPAT_DIR?=
|
||||
LIBMINLIB_DIR?=
|
||||
LIBASYN_DIR?=
|
||||
|
||||
SUBDIR= csu ${LIBCOMPAT_DIR} ${LIBC_DIR} libdriver libnetdriver \
|
||||
libedit ${LIBM_DIR} libsys libtimers libminixutil libbz2 libl libhgfs \
|
||||
libedit ${LIBM_DIR} libsys libtimers ${LIBUTIL_DIR} libbz2 libl libhgfs \
|
||||
libz libfetch libarchive libvtreefs libaudiodriver libmthread \
|
||||
libexec libdevman libusb ${LIBMINLIB_DIR} ${LIBASYN_DIR} \
|
||||
libddekit libminixfs libbdev
|
||||
|
||||
@@ -41,7 +41,6 @@ SRCS+= \
|
||||
bcopy.c \
|
||||
bzero.c \
|
||||
configfile.c \
|
||||
crypt.c \
|
||||
ctermid.c \
|
||||
cuserid.c \
|
||||
dirname.c \
|
||||
@@ -64,7 +63,6 @@ SRCS+= \
|
||||
getpagesize.c \
|
||||
getpass.c \
|
||||
getprogname.c \
|
||||
getpwent.c \
|
||||
getsubopt.c \
|
||||
getttyent.c \
|
||||
getw.c \
|
||||
@@ -85,7 +83,6 @@ SRCS+= \
|
||||
popen.c \
|
||||
putenv.c \
|
||||
putw.c \
|
||||
pwcache.c \
|
||||
random.c \
|
||||
read_tsc.S \
|
||||
read_tsc_64.c \
|
||||
@@ -125,3 +122,9 @@ SRCS+= \
|
||||
vwarnx.c \
|
||||
warn.c \
|
||||
warnx.c
|
||||
|
||||
# XXX To be removed after full
|
||||
# XXX switch to NetBSD passwd.
|
||||
SRCS+= \
|
||||
getpwent.c \
|
||||
pwcache.c
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
/* crypt() - one-way password encryption function Author: Kees J. Bot
|
||||
* 7 Feb 1994
|
||||
* This routine does not encrypt anything, it uses the pwdauth
|
||||
* program to do the hard work.
|
||||
*/
|
||||
#define nil ((void*)0)
|
||||
#define pipe _pipe
|
||||
#define fork _fork
|
||||
#define close _close
|
||||
#define dup2 _dup2
|
||||
#define execl _execl
|
||||
#define read _read
|
||||
#define _exit __exit
|
||||
#define write _write
|
||||
#define waitpid _waitpid
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
/* Set-uid root program to read /etc/shadow or encrypt passwords. */
|
||||
static char PWDAUTH[] = "/usr/lib/pwdauth";
|
||||
#define LEN 1024
|
||||
|
||||
static void tell(const char *s0, ...)
|
||||
{
|
||||
va_list ap;
|
||||
const char *s;
|
||||
|
||||
va_start(ap, s0);
|
||||
s= s0;
|
||||
while (s != nil) {
|
||||
(void) write(2, s, strlen(s));
|
||||
s= va_arg(ap, const char *);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
char *crypt(const char *key, const char *salt)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
int pfd[2];
|
||||
static char pwdata[LEN];
|
||||
char *p= pwdata;
|
||||
const char *k= key;
|
||||
const char *s= salt;
|
||||
int n;
|
||||
|
||||
/* Fill pwdata[] with the key and salt. */
|
||||
while ((*p++ = *k++) != 0) if (p == pwdata+LEN-1) goto fail;
|
||||
while ((*p++ = *s++) != 0) if (p == pwdata+LEN-0) goto fail;
|
||||
|
||||
if (pipe(pfd) < 0) goto fail;
|
||||
|
||||
/* Prefill the pipe. */
|
||||
(void) write(pfd[1], pwdata, p - pwdata);
|
||||
|
||||
switch ((pid= fork())) {
|
||||
case -1:
|
||||
close(pfd[0]);
|
||||
close(pfd[1]);
|
||||
goto fail;
|
||||
case 0:
|
||||
/* Connect both input and output to the pipe. */
|
||||
if (pfd[0] != 0) {
|
||||
dup2(pfd[0], 0);
|
||||
close(pfd[0]);
|
||||
}
|
||||
if (pfd[1] != 1) {
|
||||
dup2(pfd[1], 1);
|
||||
close(pfd[1]);
|
||||
}
|
||||
|
||||
execl(PWDAUTH, PWDAUTH, (char *) nil);
|
||||
|
||||
tell("crypt(): ", PWDAUTH, ": ", strerror(errno), "\r\n",
|
||||
(char *) nil);
|
||||
/* No pwdauth? Fail! */
|
||||
(void) read(0, pwdata, LEN);
|
||||
_exit(1);
|
||||
}
|
||||
close(pfd[1]);
|
||||
|
||||
status= -1;
|
||||
while (waitpid(pid, &status, 0) == -1 && errno == EINTR) {}
|
||||
if (status != 0) {
|
||||
close(pfd[0]);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Read and return the result. Check if it contains exactly one
|
||||
* string.
|
||||
*/
|
||||
n= read(pfd[0], pwdata, LEN);
|
||||
close(pfd[0]);
|
||||
if (n < 0) goto fail;
|
||||
p = pwdata + n;
|
||||
n = 0;
|
||||
while (p > pwdata) if (*--p == 0) n++;
|
||||
if (n != 1) goto fail;
|
||||
return pwdata;
|
||||
|
||||
fail:
|
||||
pwdata[0] = salt[0] ^ 1; /* make result != salt */
|
||||
pwdata[1] = 0;
|
||||
return pwdata;
|
||||
}
|
||||
|
||||
/*
|
||||
* $PchId: crypt.c,v 1.5 1996/04/11 07:46:11 philip Exp $
|
||||
*/
|
||||
@@ -17,7 +17,7 @@ SRCS= efun.c getbootfile.c \
|
||||
passwd.c pw_scan.c pidfile.c pidlock.c pty.c \
|
||||
raise_default_signal.c \
|
||||
secure_path.c snprintb.c \
|
||||
ttyaction.c
|
||||
ttyaction.c login_cap.c
|
||||
#disklabel_dkcksum.c disklabel_scan.c \
|
||||
#if_media.c \
|
||||
#sockaddr_snprintf.c
|
||||
@@ -25,7 +25,6 @@ SRCS= efun.c getbootfile.c \
|
||||
#getmaxpartitions.c
|
||||
#stat_flags.c
|
||||
#getrawpartition.c
|
||||
#login_cap.c
|
||||
#ttymsg.c
|
||||
#parsedate.y
|
||||
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
.PATH: ${.CURDIR}/compat
|
||||
|
||||
CPPFLAGS+=-I${.CURDIR}/../libc -I${.CURDIR}/../../sys
|
||||
SRCS+=compat_passwd.c compat_loginx.c compat_login.c compat_parsedate.c \
|
||||
SRCS+=compat_passwd.c compat_loginx.c compat_parsedate.c \
|
||||
compat_login_cap.c
|
||||
# compat_login.c
|
||||
|
||||
@@ -417,12 +417,16 @@ static struct {
|
||||
{ RLIMIT_FSIZE, R_CSIZE, "filesize", },
|
||||
{ RLIMIT_DATA, R_CSIZE, "datasize", },
|
||||
{ RLIMIT_STACK, R_CSIZE, "stacksize", },
|
||||
#ifndef __minix
|
||||
{ RLIMIT_RSS, R_CSIZE, "memoryuse", },
|
||||
{ RLIMIT_MEMLOCK, R_CSIZE, "memorylocked", },
|
||||
{ RLIMIT_NPROC, R_CNUMB, "maxproc", },
|
||||
#endif
|
||||
{ RLIMIT_NOFILE, R_CNUMB, "openfiles", },
|
||||
{ RLIMIT_CORE, R_CSIZE, "coredumpsize", },
|
||||
#ifdef RLIMIT_SBSIZE
|
||||
{ RLIMIT_SBSIZE, R_CSIZE, "sbsize", },
|
||||
#endif
|
||||
{ -1, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -472,11 +476,13 @@ gsetrl(login_cap_t *lc, int what, const char *name, int type)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#ifndef __minix
|
||||
if (setrlimit(what, &rl)) {
|
||||
syslog(LOG_ERR, "%s: setting resource limit %s: %m",
|
||||
lc->lc_class, name);
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
#undef RCUR
|
||||
#undef RMAX
|
||||
return (0);
|
||||
@@ -570,6 +576,7 @@ setusercontext(login_cap_t *lc, struct passwd *pwd, uid_t uid, u_int flags)
|
||||
if (!lc)
|
||||
flc = lc = login_getclass(pwd ? pwd->pw_class : NULL);
|
||||
|
||||
#define LOGIN_SETLOGIN 0
|
||||
/*
|
||||
* Without the pwd entry being passed we cannot set either
|
||||
* the group or the login. We could complain about it.
|
||||
|
||||
@@ -59,6 +59,16 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
/*
|
||||
* XXX Undefine the renames of these functions so that we don't
|
||||
* XXX rename the versions found in the host's <pwd.h> by mistake!
|
||||
*/
|
||||
#undef group_from_gid
|
||||
#undef user_from_uid
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
@@ -81,6 +91,18 @@ __RCSID("$NetBSD: pwcache.c,v 1.31 2010/03/23 20:28:59 drochner Exp $");
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
/* XXX Now, re-apply the renaming that we undid above. */
|
||||
#define group_from_gid __nbcompat_group_from_gid
|
||||
#define user_from_uid __nbcompat_user_from_uid
|
||||
#endif
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(user_from_uid,_user_from_uid)
|
||||
__weak_alias(group_from_gid,_group_from_gid)
|
||||
__weak_alias(pwcache_groupdb,_pwcache_groupdb)
|
||||
#endif
|
||||
|
||||
#if !HAVE_PWCACHE_USERDB || HAVE_NBTOOL_CONFIG_H
|
||||
#include "pwcache.h"
|
||||
|
||||
@@ -226,6 +248,273 @@ grptb_start(void)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* user_from_uid()
|
||||
* caches the name (if any) for the uid. If noname clear, we always
|
||||
* return the stored name (if valid or invalid match).
|
||||
* We use a simple hash table.
|
||||
* Return
|
||||
* Pointer to stored name (or a empty string)
|
||||
*/
|
||||
const char *
|
||||
user_from_uid(uid_t uid, int noname)
|
||||
{
|
||||
struct passwd *pw;
|
||||
UIDC *ptr, **pptr;
|
||||
|
||||
if ((uidtb == NULL) && (uidtb_start() < 0))
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* see if we have this uid cached
|
||||
*/
|
||||
pptr = uidtb + (uid % UID_SZ);
|
||||
ptr = *pptr;
|
||||
|
||||
if ((ptr != NULL) && (ptr->valid > 0) && (ptr->uid == uid)) {
|
||||
/*
|
||||
* have an entry for this uid
|
||||
*/
|
||||
if (!noname || (ptr->valid == VALID))
|
||||
return (ptr->name);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* No entry for this uid, we will add it
|
||||
*/
|
||||
if (!pwopn) {
|
||||
if (_pwcache_setpassent != NULL)
|
||||
(*_pwcache_setpassent)(1);
|
||||
++pwopn;
|
||||
}
|
||||
|
||||
if (ptr == NULL)
|
||||
*pptr = ptr = (UIDC *)malloc(sizeof(UIDC));
|
||||
|
||||
if ((pw = (*_pwcache_getpwuid)(uid)) == NULL) {
|
||||
/*
|
||||
* no match for this uid in the local password file
|
||||
* a string that is the uid in numeric format
|
||||
*/
|
||||
if (ptr == NULL)
|
||||
return (NULL);
|
||||
ptr->uid = uid;
|
||||
(void)snprintf(ptr->name, UNMLEN, "%lu", (long) uid);
|
||||
ptr->valid = INVALID;
|
||||
if (noname)
|
||||
return (NULL);
|
||||
} else {
|
||||
/*
|
||||
* there is an entry for this uid in the password file
|
||||
*/
|
||||
if (ptr == NULL)
|
||||
return (pw->pw_name);
|
||||
ptr->uid = uid;
|
||||
(void)strlcpy(ptr->name, pw->pw_name, UNMLEN);
|
||||
ptr->valid = VALID;
|
||||
}
|
||||
return (ptr->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* group_from_gid()
|
||||
* caches the name (if any) for the gid. If noname clear, we always
|
||||
* return the stored name (if valid or invalid match).
|
||||
* We use a simple hash table.
|
||||
* Return
|
||||
* Pointer to stored name (or a empty string)
|
||||
*/
|
||||
const char *
|
||||
group_from_gid(gid_t gid, int noname)
|
||||
{
|
||||
struct group *gr;
|
||||
GIDC *ptr, **pptr;
|
||||
|
||||
if ((gidtb == NULL) && (gidtb_start() < 0))
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* see if we have this gid cached
|
||||
*/
|
||||
pptr = gidtb + (gid % GID_SZ);
|
||||
ptr = *pptr;
|
||||
|
||||
if ((ptr != NULL) && (ptr->valid > 0) && (ptr->gid == gid)) {
|
||||
/*
|
||||
* have an entry for this gid
|
||||
*/
|
||||
if (!noname || (ptr->valid == VALID))
|
||||
return (ptr->name);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* No entry for this gid, we will add it
|
||||
*/
|
||||
if (!gropn) {
|
||||
if (_pwcache_setgroupent != NULL)
|
||||
(*_pwcache_setgroupent)(1);
|
||||
++gropn;
|
||||
}
|
||||
|
||||
if (ptr == NULL)
|
||||
*pptr = ptr = (GIDC *)malloc(sizeof(GIDC));
|
||||
|
||||
if ((gr = (*_pwcache_getgrgid)(gid)) == NULL) {
|
||||
/*
|
||||
* no match for this gid in the local group file, put in
|
||||
* a string that is the gid in numberic format
|
||||
*/
|
||||
if (ptr == NULL)
|
||||
return (NULL);
|
||||
ptr->gid = gid;
|
||||
(void)snprintf(ptr->name, GNMLEN, "%lu", (long) gid);
|
||||
ptr->valid = INVALID;
|
||||
if (noname)
|
||||
return (NULL);
|
||||
} else {
|
||||
/*
|
||||
* there is an entry for this group in the group file
|
||||
*/
|
||||
if (ptr == NULL)
|
||||
return (gr->gr_name);
|
||||
ptr->gid = gid;
|
||||
(void)strlcpy(ptr->name, gr->gr_name, GNMLEN);
|
||||
ptr->valid = VALID;
|
||||
}
|
||||
return (ptr->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* uid_from_user()
|
||||
* caches the uid for a given user name. We use a simple hash table.
|
||||
* Return
|
||||
* the uid (if any) for a user name, or a -1 if no match can be found
|
||||
*/
|
||||
int
|
||||
uid_from_user(const char *name, uid_t *uid)
|
||||
{
|
||||
struct passwd *pw;
|
||||
UIDC *ptr, **pptr;
|
||||
size_t namelen;
|
||||
|
||||
/*
|
||||
* return -1 for mangled names
|
||||
*/
|
||||
if (name == NULL || ((namelen = strlen(name)) == 0))
|
||||
return (-1);
|
||||
if ((usrtb == NULL) && (usrtb_start() < 0))
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* look up in hash table, if found and valid return the uid,
|
||||
* if found and invalid, return a -1
|
||||
*/
|
||||
pptr = usrtb + st_hash(name, namelen, UNM_SZ);
|
||||
ptr = *pptr;
|
||||
|
||||
if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
|
||||
if (ptr->valid == INVALID)
|
||||
return (-1);
|
||||
*uid = ptr->uid;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!pwopn) {
|
||||
if (_pwcache_setpassent != NULL)
|
||||
(*_pwcache_setpassent)(1);
|
||||
++pwopn;
|
||||
}
|
||||
|
||||
if (ptr == NULL)
|
||||
*pptr = ptr = (UIDC *)malloc(sizeof(UIDC));
|
||||
|
||||
/*
|
||||
* no match, look it up, if no match store it as an invalid entry,
|
||||
* or store the matching uid
|
||||
*/
|
||||
if (ptr == NULL) {
|
||||
if ((pw = (*_pwcache_getpwnam)(name)) == NULL)
|
||||
return (-1);
|
||||
*uid = pw->pw_uid;
|
||||
return (0);
|
||||
}
|
||||
(void)strlcpy(ptr->name, name, UNMLEN);
|
||||
if ((pw = (*_pwcache_getpwnam)(name)) == NULL) {
|
||||
ptr->valid = INVALID;
|
||||
return (-1);
|
||||
}
|
||||
ptr->valid = VALID;
|
||||
*uid = ptr->uid = pw->pw_uid;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* gid_from_group()
|
||||
* caches the gid for a given group name. We use a simple hash table.
|
||||
* Return
|
||||
* the gid (if any) for a group name, or a -1 if no match can be found
|
||||
*/
|
||||
int
|
||||
gid_from_group(const char *name, gid_t *gid)
|
||||
{
|
||||
struct group *gr;
|
||||
GIDC *ptr, **pptr;
|
||||
size_t namelen;
|
||||
|
||||
/*
|
||||
* return -1 for mangled names
|
||||
*/
|
||||
if (name == NULL || ((namelen = strlen(name)) == 0))
|
||||
return (-1);
|
||||
if ((grptb == NULL) && (grptb_start() < 0))
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* look up in hash table, if found and valid return the uid,
|
||||
* if found and invalid, return a -1
|
||||
*/
|
||||
pptr = grptb + st_hash(name, namelen, GID_SZ);
|
||||
ptr = *pptr;
|
||||
|
||||
if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
|
||||
if (ptr->valid == INVALID)
|
||||
return (-1);
|
||||
*gid = ptr->gid;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!gropn) {
|
||||
if (_pwcache_setgroupent != NULL)
|
||||
(*_pwcache_setgroupent)(1);
|
||||
++gropn;
|
||||
}
|
||||
|
||||
if (ptr == NULL)
|
||||
*pptr = ptr = (GIDC *)malloc(sizeof(GIDC));
|
||||
|
||||
/*
|
||||
* no match, look it up, if no match store it as an invalid entry,
|
||||
* or store the matching gid
|
||||
*/
|
||||
if (ptr == NULL) {
|
||||
if ((gr = (*_pwcache_getgrnam)(name)) == NULL)
|
||||
return (-1);
|
||||
*gid = gr->gr_gid;
|
||||
return (0);
|
||||
}
|
||||
|
||||
(void)strlcpy(ptr->name, name, GNMLEN);
|
||||
if ((gr = (*_pwcache_getgrnam)(name)) == NULL) {
|
||||
ptr->valid = INVALID;
|
||||
return (-1);
|
||||
}
|
||||
ptr->valid = VALID;
|
||||
*gid = ptr->gid = gr->gr_gid;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define FLUSHTB(arr, len, fail) \
|
||||
do { \
|
||||
if (arr != NULL) { \
|
||||
|
||||
@@ -24,11 +24,6 @@ SRCS+= nlist.c
|
||||
# NetBSD's 'mtab' format.
|
||||
SRCS+= mtab.c
|
||||
|
||||
# Minix legacy passwd format
|
||||
# These should be removed when we switch to
|
||||
# NetBSD's 'passwd' db-based format.
|
||||
SRCS+= getpwent.c
|
||||
|
||||
# fttyslot(fd), a Minix-specific extension
|
||||
SRCS+= fttyslot.c
|
||||
|
||||
@@ -36,11 +31,6 @@ SRCS+= fttyslot.c
|
||||
# Now considered "compat" feature in NetBSD.
|
||||
SRCS+= cuserid.c
|
||||
|
||||
# XXX: hack
|
||||
# user_from_uid(), uid_from_user()
|
||||
# group_from_gid(), gid_from_group()
|
||||
SRCS+= passwd.c
|
||||
|
||||
.include "include/Makefile.inc"
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
/* getpwent(), getpwuid(), getpwnam() - password file routines
|
||||
*
|
||||
* Author: Kees J. Bot
|
||||
* 31 Jan 1994
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <compat/pwd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define arraysize(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#define arraylimit(a) ((a) + arraysize(a))
|
||||
|
||||
static char PASSWD[]= "/etc/passwd"; /* The password file. */
|
||||
static const char *pwfile; /* Current password file. */
|
||||
|
||||
static char buf[1024]; /* Read buffer. */
|
||||
static char pwline[256]; /* One line from the password file. */
|
||||
static struct passwd entry; /* Entry to fill and return. */
|
||||
static int pwfd= -1; /* Filedescriptor to the file. */
|
||||
static char *bufptr; /* Place in buf. */
|
||||
static ssize_t buflen= 0; /* Remaining characters in buf. */
|
||||
static char *lineptr; /* Place in the line. */
|
||||
|
||||
void endpwent(void)
|
||||
/* Close the password file. */
|
||||
{
|
||||
if (pwfd >= 0) {
|
||||
(void) close(pwfd);
|
||||
pwfd= -1;
|
||||
buflen= 0;
|
||||
}
|
||||
}
|
||||
|
||||
int setpwent(void)
|
||||
/* Open the password file. */
|
||||
{
|
||||
if (pwfd >= 0) endpwent();
|
||||
|
||||
if (pwfile == NULL) pwfile= PASSWD;
|
||||
|
||||
if ((pwfd= open(pwfile, O_RDONLY)) < 0) return -1;
|
||||
(void) fcntl(pwfd, F_SETFD, fcntl(pwfd, F_GETFD) | FD_CLOEXEC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setpwfile(const char *file)
|
||||
/* Prepare for reading an alternate password file. */
|
||||
{
|
||||
endpwent();
|
||||
pwfile= file;
|
||||
}
|
||||
|
||||
static int getline(void)
|
||||
/* Get one line from the password file, return 0 if bad or EOF. */
|
||||
{
|
||||
lineptr= pwline;
|
||||
|
||||
do {
|
||||
if (buflen == 0) {
|
||||
if ((buflen= read(pwfd, buf, sizeof(buf))) <= 0)
|
||||
return 0;
|
||||
bufptr= buf;
|
||||
}
|
||||
|
||||
if (lineptr == arraylimit(pwline)) return 0;
|
||||
buflen--;
|
||||
} while ((*lineptr++ = *bufptr++) != '\n');
|
||||
|
||||
lineptr= pwline;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *scan_colon(void)
|
||||
/* Scan for a field separator in a line, return the start of the field. */
|
||||
{
|
||||
char *field= lineptr;
|
||||
char *last;
|
||||
|
||||
for (;;) {
|
||||
last= lineptr;
|
||||
if (*lineptr == 0) return NULL;
|
||||
if (*lineptr == '\n') break;
|
||||
if (*lineptr++ == ':') break;
|
||||
}
|
||||
*last= 0;
|
||||
return field;
|
||||
}
|
||||
|
||||
struct passwd *getpwent(void)
|
||||
/* Read one entry from the password file. */
|
||||
{
|
||||
char *p;
|
||||
|
||||
/* Open the file if not yet open. */
|
||||
if (pwfd < 0 && setpwent() < 0) return NULL;
|
||||
|
||||
/* Until a good line is read. */
|
||||
for (;;) {
|
||||
if (!getline()) return NULL; /* EOF or corrupt. */
|
||||
|
||||
if ((entry.pw_name= scan_colon()) == NULL) continue;
|
||||
if ((entry.pw_passwd= scan_colon()) == NULL) continue;
|
||||
if ((p= scan_colon()) == NULL) continue;
|
||||
entry.pw_uid= strtol(p, NULL, 0);
|
||||
if ((p= scan_colon()) == NULL) continue;
|
||||
entry.pw_gid= strtol(p, NULL, 0);
|
||||
if ((entry.pw_gecos= scan_colon()) == NULL) continue;
|
||||
if ((entry.pw_dir= scan_colon()) == NULL) continue;
|
||||
if ((entry.pw_shell= scan_colon()) == NULL) continue;
|
||||
|
||||
if (*lineptr == 0) return &entry;
|
||||
}
|
||||
}
|
||||
|
||||
struct passwd *getpwuid(uid_t uid)
|
||||
/* Return the password file entry belonging to the user-id. */
|
||||
{
|
||||
struct passwd *pw;
|
||||
|
||||
endpwent();
|
||||
while ((pw= getpwent()) != NULL && pw->pw_uid != uid) {}
|
||||
endpwent();
|
||||
return pw;
|
||||
}
|
||||
|
||||
struct passwd *getpwnam(const char *name)
|
||||
/* Return the password file entry belonging to the user name. */
|
||||
{
|
||||
struct passwd *pw;
|
||||
|
||||
endpwent();
|
||||
while ((pw= getpwent()) != NULL && strcmp(pw->pw_name, name) != 0) {}
|
||||
endpwent();
|
||||
return pw;
|
||||
}
|
||||
|
||||
#ifndef L_cuserid
|
||||
#define L_cuserid 9
|
||||
#endif
|
||||
|
||||
char *getlogin()
|
||||
{
|
||||
static char userid[L_cuserid];
|
||||
struct passwd *pw_entry;
|
||||
|
||||
pw_entry = getpwuid(getuid());
|
||||
|
||||
if (pw_entry == (struct passwd *)NULL) return((char *)NULL);
|
||||
|
||||
strcpy(userid, pw_entry->pw_name);
|
||||
|
||||
return(userid);
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* grotesque hack to get these functions working.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <compat/pwd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* group_from_gid()
|
||||
* caches the name (if any) for the gid. If noname clear, we always
|
||||
* return the stored name (if valid or invalid match).
|
||||
* We use a simple hash table.
|
||||
* Return
|
||||
* Pointer to stored name (or a empty string)
|
||||
*/
|
||||
const char *
|
||||
group_from_gid(gid_t gid, int noname)
|
||||
{
|
||||
static char buf[16];
|
||||
struct group *g = getgrgid(gid);
|
||||
if (g == NULL) {
|
||||
if (noname) {
|
||||
return NULL;
|
||||
} else {
|
||||
sprintf(buf, "%d", gid);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
return g->gr_name;
|
||||
}
|
||||
|
||||
/*
|
||||
* user_from_uid()
|
||||
* caches the name (if any) for the uid. If noname clear, we always
|
||||
* return the stored name (if valid or invalid match).
|
||||
* We use a simple hash table.
|
||||
* Return
|
||||
* Pointer to stored name (or a empty string)
|
||||
*/
|
||||
const char *
|
||||
user_from_uid(uid_t uid, int noname)
|
||||
{
|
||||
static char buf[16];
|
||||
struct passwd *p = getpwuid(uid);
|
||||
if (p == NULL) {
|
||||
if (noname) {
|
||||
return NULL;
|
||||
} else {
|
||||
sprintf(buf, "%d", uid);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
return p->pw_name;
|
||||
}
|
||||
|
||||
/*
|
||||
* uid_from_user()
|
||||
* caches the uid for a given user name. We use a simple hash table.
|
||||
* Return
|
||||
* the uid (if any) for a user name, or a -1 if no match can be found
|
||||
*/
|
||||
int
|
||||
uid_from_user(const char *name, uid_t *uid)
|
||||
{
|
||||
struct passwd *p = getpwnam(name);
|
||||
if (p == NULL) {
|
||||
return -1;
|
||||
}
|
||||
*uid = p->pw_uid;
|
||||
return *uid;
|
||||
}
|
||||
|
||||
/*
|
||||
* gid_from_group()
|
||||
* caches the gid for a given group name. We use a simple hash table.
|
||||
* Return
|
||||
* the gid (if any) for a group name, or a -1 if no match can be found
|
||||
*/
|
||||
int
|
||||
gid_from_group(const char *name, gid_t *gid)
|
||||
{
|
||||
struct group *g = getgrnam(name);
|
||||
if (g == NULL) {
|
||||
return -1;
|
||||
}
|
||||
*gid = g->gr_gid;
|
||||
return *gid;
|
||||
}
|
||||
Reference in New Issue
Block a user