Add a few files which are needed to build "passwd" now that

the standard version of these files have been PAMified (and axed).
This commit is contained in:
Luigi Rizzo 2002-06-20 21:17:33 +00:00
parent 2042599684
commit d813626f4d
6 changed files with 891 additions and 35 deletions

View file

@ -1,9 +1,8 @@
# From: @(#)Makefile 8.3 (Berkeley) 4/2/94
# $FreeBSD$
# NOPAM is used by PicoBSD
# Only NOPAM is used by PicoBSD and supported here
.if defined(NOPAM)
PROG= passwd
SRCS= local_passwd.c passwd.c pw_copy.c pw_util.c
@ -15,41 +14,15 @@ CFLAGS+=-Wall
DPADD= ${LIBCRYPT} ${LIBUTIL}
LDADD= -lcrypt -lutil
.PATH: ${.CURDIR}/../../../../usr.bin/chpass \
${.CURDIR}/../../../../usr.sbin/vipw \
${.CURDIR}/../../../../usr.bin/passwd
# ${.CURDIR}/../../../../usr.sbin/vipw \
# ${.CURDIR}/../../../../usr.bin/passwd
CFLAGS+= -DLOGIN_CAP -DCRYPT -I. -I${.CURDIR} \
-I${.CURDIR}/../../../../usr.bin/passwd \
-I${.CURDIR}/../../../../usr.sbin/vipw \
-I${.CURDIR}/../../../../usr.bin/chpass \
-I${.CURDIR}/../../../../lib/libc/gen \
-Dyp_error=warnx -DLOGGING
.else
PROG= passwd
SRCS= local_passwd.c passwd.c pw_copy.c pw_util.c pw_yp.c \
yp_passwd.c ypxfr_misc.c ${GENSRCS}
GENSRCS=yp.h yp_clnt.c yppasswd.h yppasswd_clnt.c \
yppasswd_private.h yppasswd_private_clnt.c yppasswd_private_xdr.c
CFLAGS+=-Wall
DPADD= ${LIBCRYPT} ${LIBRPCSVC} ${LIBUTIL}
LDADD= -lcrypt -lrpcsvc -lutil
.PATH: ${.CURDIR}/../../../../usr.bin/chpass \
${.CURDIR}/../../../../usr.sbin/vipw \
${.CURDIR}/../../../../usr.bin/passwd \
${.CURDIR}/../../../../libexec/ypxfr \
${.CURDIR}/../../../../usr.sbin/rpc.yppasswdd
CFLAGS+= -DLOGIN_CAP -DCRYPT -DYP -I. -I${.CURDIR} \
-I${.CURDIR}/../../../../usr.bin/passwd \
-I${.CURDIR}/../../usr.sbin/vipw \
-I${.CURDIR}/../../../../usr.bin/chpass \
-I${.CURDIR}/../../../../libexec/ypxfr \
-I${.CURDIR}/../../../../usr.sbin/rpc.yppasswdd \
-I${.CURDIR}/../../../../lib/libc/gen \
-Dyp_error=warnx -DLOGGING
.endif
# -I${.CURDIR}/../../../../usr.bin/passwd \
# -I${.CURDIR}/../../../../usr.sbin/vipw \
# -I${.CURDIR}/../../../../usr.bin/chpass \
# -I${.CURDIR}/../../../../lib/libc/gen \
# -Dyp_error=warnx -DLOGGING
CLEANFILES= ${GENSRCS}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 1994
* 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.
*
* From: @(#)extern.h 8.1 (Berkeley) 4/2/94
* $FreeBSD$
*/
int krb_passwd(char *, char *, char *, char *);
int local_passwd(char *);

View file

@ -0,0 +1,237 @@
/*-
* Copyright (c) 1990, 1993, 1994
* 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.
*/
#ifndef lint
static const char sccsid[] = "@(#)local_passwd.c 8.3 (Berkeley) 4/2/94";
#endif /* not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/time.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <pw_util.h>
#ifdef YP
#include <pw_yp.h>
#endif
#ifdef LOGGING
#include <syslog.h>
#endif
#ifdef LOGIN_CAP
#ifdef AUTH_NONE /* multiple defs :-( */
#undef AUTH_NONE
#endif
#include <login_cap.h>
#endif
#include "extern.h"
static uid_t uid;
int randinit;
extern void
pw_copy(int ffd, int tfd, struct passwd *pw, struct passwd *old_pw);
char *tempname;
static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
void
to64(s, v, n)
char *s;
long v;
int n;
{
while (--n >= 0) {
*s++ = itoa64[v&0x3f];
v >>= 6;
}
}
char *
getnewpasswd(pw, nis)
struct passwd *pw;
int nis;
{
int tries, min_length = 6;
int force_mix_case = 1;
char *p, *t;
#ifdef LOGIN_CAP
login_cap_t * lc;
#endif
char buf[_PASSWORD_LEN+1], salt[32];
struct timeval tv;
if (!nis)
(void)printf("Changing local password for %s.\n", pw->pw_name);
if (uid && pw->pw_passwd[0] &&
strcmp(crypt(getpass("Old password:"), pw->pw_passwd),
pw->pw_passwd)) {
errno = EACCES;
pw_error(NULL, 1, 1);
}
#ifdef LOGIN_CAP
/*
* Determine minimum password length, next password change date,
* and whether or not to force mixed case passwords.
* Note that even for NIS passwords, login_cap is still used.
*/
if ((lc = login_getpwclass(pw)) != NULL) {
time_t period;
/* minpasswordlen capablity */
min_length = (int)login_getcapnum(lc, "minpasswordlen",
min_length, min_length);
/* passwordtime capability */
period = login_getcaptime(lc, "passwordtime", 0, 0);
if (period > (time_t)0) {
pw->pw_change = time(NULL) + period;
}
/* mixpasswordcase capability */
force_mix_case = login_getcapbool(lc, "mixpasswordcase", 1);
}
#endif
for (buf[0] = '\0', tries = 0;;) {
p = getpass("New password:");
if (!*p) {
(void)printf("Password unchanged.\n");
pw_error(NULL, 0, 0);
}
if (strlen(p) < min_length && (uid != 0 || ++tries < 2)) {
(void)printf("Please enter a password at least %d characters in length.\n", min_length);
continue;
}
if (force_mix_case) {
for (t = p; *t && islower(*t); ++t);
if (!*t && (uid != 0 || ++tries < 2)) {
(void)printf("Please don't use an all-lower case password.\nUnusual capitalization, control characters or digits are suggested.\n");
continue;
}
}
(void)strcpy(buf, p);
if (!strcmp(buf, getpass("Retype new password:")))
break;
(void)printf("Mismatch; try again, EOF to quit.\n");
}
/* grab a random printable character that isn't a colon */
if (!randinit) {
randinit = 1;
srandomdev();
}
#ifdef NEWSALT
salt[0] = _PASSWORD_EFMT1;
to64(&salt[1], (long)(29 * 25), 4);
to64(&salt[5], random(), 4);
salt[9] = '\0';
#else
/* Make a good size salt for algoritms that can use it. */
gettimeofday(&tv,0);
#ifdef LOGIN_CAP
if (login_setcryptfmt(lc, "md5", NULL) == NULL)
pw_error("cannot set password cipher", 1, 1);
login_close(lc);
#else
(void)crypt_set_format("md5");
#endif
/* Salt suitable for anything */
to64(&salt[0], random(), 3);
to64(&salt[3], tv.tv_usec, 3);
to64(&salt[6], tv.tv_sec, 2);
to64(&salt[8], random(), 5);
to64(&salt[13], random(), 5);
to64(&salt[17], random(), 5);
to64(&salt[22], random(), 5);
salt[27] = '\0';
#endif
return (crypt(buf, salt));
}
int
local_passwd(uname)
char *uname;
{
struct passwd *pw;
int pfd, tfd;
if (!(pw = getpwnam(uname)))
errx(1, "unknown user %s", uname);
#ifdef YP
/* Use the right password information. */
pw = (struct passwd *)&local_password;
#endif
uid = getuid();
if (uid && uid != pw->pw_uid)
errx(1, "%s", strerror(EACCES));
pw_init();
/*
* Get the new password. Reset passwd change time to zero by
* default. If the user has a valid login class (or the default
* fallback exists), then the next password change date is set
* by getnewpasswd() according to the "passwordtime" capability
* if one has been specified.
*/
pw->pw_change = 0;
pw->pw_passwd = getnewpasswd(pw, 0);
pfd = pw_lock();
tfd = pw_tmp();
pw_copy(pfd, tfd, pw, NULL);
if (!pw_mkdb(uname))
pw_error((char *)NULL, 0, 1);
#ifdef LOGGING
syslog(LOG_DEBUG, "user %s changed their local password\n", uname);
#endif
return (0);
}

View file

@ -0,0 +1,306 @@
/*-
* Copyright (c) 1990, 1993, 1994
* 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.
*
* $FreeBSD$
*/
#ifndef lint
static const char sccsid[] = "@(#)pw_copy.c 8.4 (Berkeley) 4/2/94";
#endif /* not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* This module is used to copy the master password file, replacing a single
* record, by chpass(1) and passwd(1).
*/
#include <err.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#if 0
#include <pw_scan.h>
#endif
extern int pw_big_ids_warning;
extern int pw_scan __P((char *, struct passwd *));
#include <pw_util.h>
extern char *tempname;
/* for use in pw_copy(). Compare a pw entry to a pw struct. */
static int
pw_equal(char *buf, struct passwd *pw)
{
struct passwd buf_pw;
int len;
len = strlen (buf);
if (buf[len-1] == '\n')
buf[len-1] = '\0';
return (strcmp(pw->pw_name, buf_pw.pw_name) == 0
&& pw->pw_uid == buf_pw.pw_uid
&& pw->pw_gid == buf_pw.pw_gid
&& strcmp(pw->pw_class, buf_pw.pw_class) == 0
&& (long)pw->pw_change == (long)buf_pw.pw_change
&& (long)pw->pw_expire == (long)buf_pw.pw_expire
&& strcmp(pw->pw_gecos, buf_pw.pw_gecos) == 0
&& strcmp(pw->pw_dir, buf_pw.pw_dir) == 0
&& strcmp(pw->pw_shell, buf_pw.pw_shell) == 0);
}
void
pw_copy(int ffd, int tfd, struct passwd *pw, struct passwd *old_pw)
{
FILE *from, *to;
int done;
char *p, buf[8192];
char uidstr[20];
char gidstr[20];
char chgstr[20];
char expstr[20];
snprintf(uidstr, sizeof(uidstr), "%lu", (unsigned long)pw->pw_uid);
snprintf(gidstr, sizeof(gidstr), "%lu", (unsigned long)pw->pw_gid);
snprintf(chgstr, sizeof(chgstr), "%ld", (long)pw->pw_change);
snprintf(expstr, sizeof(expstr), "%ld", (long)pw->pw_expire);
if (!(from = fdopen(ffd, "r")))
pw_error(_PATH_MASTERPASSWD, 1, 1);
if (!(to = fdopen(tfd, "w")))
pw_error(tempname, 1, 1);
for (done = 0; fgets(buf, sizeof(buf), from);) {
if (!strchr(buf, '\n')) {
warnx("%s: line too long", _PATH_MASTERPASSWD);
pw_error(NULL, 0, 1);
}
if (done) {
(void)fprintf(to, "%s", buf);
if (ferror(to))
goto err;
continue;
}
for (p = buf; *p != '\n'; p++)
if (*p != ' ' && *p != '\t')
break;
if (*p == '#' || *p == '\n') {
(void)fprintf(to, "%s", buf);
if (ferror(to))
goto err;
continue;
}
if (!(p = strchr(buf, ':'))) {
warnx("%s: corrupted entry", _PATH_MASTERPASSWD);
pw_error(NULL, 0, 1);
}
*p = '\0';
if (strcmp(buf, pw->pw_name)) {
*p = ':';
(void)fprintf(to, "%s", buf);
if (ferror(to))
goto err;
continue;
}
*p = ':';
if (old_pw && !pw_equal(buf, old_pw)) {
warnx("%s: entry for %s has changed",
_PATH_MASTERPASSWD, pw->pw_name);
pw_error(NULL, 0, 1);
}
(void)fprintf(to, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
pw->pw_name, pw->pw_passwd,
pw->pw_fields & _PWF_UID ? uidstr : "",
pw->pw_fields & _PWF_GID ? gidstr : "",
pw->pw_class,
pw->pw_fields & _PWF_CHANGE ? chgstr : "",
pw->pw_fields & _PWF_EXPIRE ? expstr : "",
pw->pw_gecos, pw->pw_dir, pw->pw_shell);
done = 1;
if (ferror(to))
goto err;
}
if (!done) {
#ifdef YP
/* Ultra paranoid: shouldn't happen. */
if (getuid()) {
warnx("%s: not found in %s -- permission denied",
pw->pw_name, _PATH_MASTERPASSWD);
pw_error(NULL, 0, 1);
} else
#endif /* YP */
(void)fprintf(to, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
pw->pw_name, pw->pw_passwd,
pw->pw_fields & _PWF_UID ? uidstr : "",
pw->pw_fields & _PWF_GID ? gidstr : "",
pw->pw_class,
pw->pw_fields & _PWF_CHANGE ? chgstr : "",
pw->pw_fields & _PWF_EXPIRE ? expstr : "",
pw->pw_gecos, pw->pw_dir, pw->pw_shell);
}
if (ferror(to))
err: pw_error(NULL, 1, 1);
(void)fclose(to);
}
#include <sys/param.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
/*
* Some software assumes that IDs are short. We should emit warnings
* for id's which can not be stored in a short, but we are more liberal
* by default, warning for IDs greater than USHRT_MAX.
*
* If pw_big_ids_warning is anything other than -1 on entry to pw_scan()
* it will be set based on the existance of PW_SCAN_BIG_IDS in the
* environment.
*/
int pw_big_ids_warning = -1;
int
pw_scan(bp, pw)
char *bp;
struct passwd *pw;
{
uid_t id;
int root;
char *p, *sh;
if (pw_big_ids_warning == -1)
pw_big_ids_warning = getenv("PW_SCAN_BIG_IDS") == NULL ? 1 : 0;
pw->pw_fields = 0;
if (!(pw->pw_name = strsep(&bp, ":"))) /* login */
goto fmt;
root = !strcmp(pw->pw_name, "root");
if(pw->pw_name[0] && (pw->pw_name[0] != '+' || pw->pw_name[1] == '\0'))
pw->pw_fields |= _PWF_NAME;
if (!(pw->pw_passwd = strsep(&bp, ":"))) /* passwd */
goto fmt;
if(pw->pw_passwd[0]) pw->pw_fields |= _PWF_PASSWD;
if (!(p = strsep(&bp, ":"))) /* uid */
goto fmt;
if (p[0])
pw->pw_fields |= _PWF_UID;
else {
if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') {
warnx("no uid for user %s", pw->pw_name);
return (0);
}
}
id = strtoul(p, (char **)NULL, 10);
if (errno == ERANGE) {
warnx("%s > max uid value (%lu)", p, ULONG_MAX);
return (0);
}
if (root && id) {
warnx("root uid should be 0");
return (0);
}
if (pw_big_ids_warning && id > USHRT_MAX) {
warnx("%s > recommended max uid value (%u)", p, USHRT_MAX);
/*return (0);*/ /* THIS SHOULD NOT BE FATAL! */
}
pw->pw_uid = id;
if (!(p = strsep(&bp, ":"))) /* gid */
goto fmt;
if(p[0]) pw->pw_fields |= _PWF_GID;
id = strtoul(p, (char **)NULL, 10);
if (errno == ERANGE) {
warnx("%s > max gid value (%u)", p, ULONG_MAX);
return (0);
}
if (pw_big_ids_warning && id > USHRT_MAX) {
warnx("%s > recommended max gid value (%u)", p, USHRT_MAX);
/* return (0); This should not be fatal! */
}
pw->pw_gid = id;
pw->pw_class = strsep(&bp, ":"); /* class */
if(pw->pw_class[0]) pw->pw_fields |= _PWF_CLASS;
if (!(p = strsep(&bp, ":"))) /* change */
goto fmt;
if(p[0]) pw->pw_fields |= _PWF_CHANGE;
pw->pw_change = atol(p);
if (!(p = strsep(&bp, ":"))) /* expire */
goto fmt;
if(p[0]) pw->pw_fields |= _PWF_EXPIRE;
pw->pw_expire = atol(p);
if (!(pw->pw_gecos = strsep(&bp, ":"))) /* gecos */
goto fmt;
if(pw->pw_gecos[0]) pw->pw_fields |= _PWF_GECOS;
if (!(pw->pw_dir = strsep(&bp, ":"))) /* directory */
goto fmt;
if(pw->pw_dir[0]) pw->pw_fields |= _PWF_DIR;
if (!(pw->pw_shell = strsep(&bp, ":"))) /* shell */
goto fmt;
p = pw->pw_shell;
if (root && *p) /* empty == /bin/sh */
for (setusershell();;) {
if (!(sh = getusershell())) {
warnx("warning, unknown root shell");
break;
}
if (!strcmp(p, sh))
break;
}
if(p[0]) pw->pw_fields |= _PWF_SHELL;
if ((p = strsep(&bp, ":"))) { /* too many */
fmt: warnx("corrupted entry");
return (0);
}
return (1);
}

View file

@ -0,0 +1,258 @@
/*-
* Copyright (c) 1990, 1993, 1994
* 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.
*/
#ifndef lint
#if 0
static const char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94";
#endif
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
/*
* This file is used by all the "password" programs; vipw(8), chpass(1),
* and passwd(1).
*/
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <err.h>
#include <fcntl.h>
#include <paths.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pw_util.h"
extern char *tempname;
static pid_t editpid = -1;
static int lockfd;
static char _default_editor[] = _PATH_VI;
static char _default_mppath[] = _PATH_PWD;
static char _default_masterpasswd[] = _PATH_MASTERPASSWD;
char *mppath = _default_mppath;
char *masterpasswd = _default_masterpasswd;
void pw_cont(int);
void
pw_cont(int sig)
{
if (editpid != -1)
kill(editpid, sig);
}
void
pw_init(void)
{
struct rlimit rlim;
/* Unlimited resource limits. */
rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
(void)setrlimit(RLIMIT_CPU, &rlim);
(void)setrlimit(RLIMIT_FSIZE, &rlim);
(void)setrlimit(RLIMIT_STACK, &rlim);
(void)setrlimit(RLIMIT_DATA, &rlim);
(void)setrlimit(RLIMIT_RSS, &rlim);
/* Don't drop core (not really necessary, but GP's). */
rlim.rlim_cur = rlim.rlim_max = 0;
(void)setrlimit(RLIMIT_CORE, &rlim);
/* Turn off signals. */
(void)signal(SIGALRM, SIG_IGN);
(void)signal(SIGHUP, SIG_IGN);
(void)signal(SIGINT, SIG_IGN);
(void)signal(SIGPIPE, SIG_IGN);
(void)signal(SIGQUIT, SIG_IGN);
(void)signal(SIGTERM, SIG_IGN);
(void)signal(SIGCONT, pw_cont);
/* Create with exact permissions. */
(void)umask(0);
}
int
pw_lock(void)
{
/*
* If the master password file doesn't exist, the system is hosed.
* Might as well try to build one. Set the close-on-exec bit so
* that users can't get at the encrypted passwords while editing.
* Open should allow flock'ing the file; see 4.4BSD. XXX
*/
for (;;) {
struct stat st;
lockfd = open(masterpasswd, O_RDONLY, 0);
if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1)
err(1, "%s", masterpasswd);
if (flock(lockfd, LOCK_EX|LOCK_NB))
errx(1, "the password db file is busy");
/*
* If the password file was replaced while we were trying to
* get the lock, our hardlink count will be 0 and we have to
* close and retry.
*/
if (fstat(lockfd, &st) < 0)
errx(1, "fstat() failed");
if (st.st_nlink != 0)
break;
close(lockfd);
lockfd = -1;
}
return (lockfd);
}
int
pw_tmp(void)
{
static char path[MAXPATHLEN];
int fd;
char *p;
strncpy(path, masterpasswd, MAXPATHLEN - 1);
path[MAXPATHLEN] = '\0';
if ((p = strrchr(path, '/')))
++p;
else
p = path;
strcpy(p, "pw.XXXXXX");
if ((fd = mkstemp(path)) == -1)
err(1, "%s", path);
tempname = path;
return (fd);
}
int
pw_mkdb(const char *username)
{
int pstat;
pid_t pid;
(void)fflush(stderr);
if (!(pid = fork())) {
if(!username) {
warnx("rebuilding the database...");
execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath,
tempname, (char *)NULL);
} else {
warnx("updating the database...");
execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath,
"-u", username, tempname, (char *)NULL);
}
pw_error(_PATH_PWD_MKDB, 1, 1);
}
pid = waitpid(pid, &pstat, 0);
if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
return (0);
warnx("done");
return (1);
}
void
pw_edit(int notsetuid)
{
int pstat;
char *p, *editor;
if (!(editor = getenv("EDITOR")))
editor = _default_editor;
if ((p = strrchr(editor, '/')))
++p;
else
p = editor;
if (!(editpid = fork())) {
if (notsetuid) {
(void)setgid(getgid());
(void)setuid(getuid());
}
errno = 0;
execlp(editor, p, tempname, (char *)NULL);
_exit(errno);
}
for (;;) {
editpid = waitpid(editpid, (int *)&pstat, WUNTRACED);
errno = WEXITSTATUS(pstat);
if (editpid == -1)
pw_error(editor, 1, 1);
else if (WIFSTOPPED(pstat))
raise(WSTOPSIG(pstat));
else if (WIFEXITED(pstat) && errno == 0)
break;
else
pw_error(editor, 1, 1);
}
editpid = -1;
}
void
pw_prompt(void)
{
int c, first;
(void)printf("re-edit the password file? [y]: ");
(void)fflush(stdout);
first = c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
if (first == 'n')
pw_error(NULL, 0, 0);
}
void
pw_error(const char *name, int error, int eval)
{
if (error) {
if (name != NULL)
warn("%s", name);
else
warn(NULL);
}
warnx("password information unchanged");
(void)unlink(tempname);
exit(eval);
}

View file

@ -0,0 +1,44 @@
/*-
* Copyright (c) 1994
* 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.
*
* @(#)pw_util.h 8.2 (Berkeley) 4/1/94
*
* $FreeBSD$
*/
void pw_edit(int);
void pw_error(const char *, int, int);
void pw_init(void);
int pw_lock(void);
int pw_mkdb(const char *);
void pw_prompt(void);
int pw_tmp(void);