diff options
author | luigi <luigi@FreeBSD.org> | 2002-06-20 21:17:33 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 2002-06-20 21:17:33 +0000 |
commit | 3c1b590b1703814b73c679c7f60d34e347d29da9 (patch) | |
tree | 1b4a886d1de65b3814e9fcda9b9d1144be9923b9 /release | |
parent | b3f134766195e32ea1f8d3e640d4dcccf5aa4f23 (diff) | |
download | FreeBSD-src-3c1b590b1703814b73c679c7f60d34e347d29da9.zip FreeBSD-src-3c1b590b1703814b73c679c7f60d34e347d29da9.tar.gz |
Add a few files which are needed to build "passwd" now that
the standard version of these files have been PAMified (and axed).
Diffstat (limited to 'release')
-rw-r--r-- | release/picobsd/tinyware/passwd/Makefile | 43 | ||||
-rw-r--r-- | release/picobsd/tinyware/passwd/extern.h | 38 | ||||
-rw-r--r-- | release/picobsd/tinyware/passwd/local_passwd.c | 237 | ||||
-rw-r--r-- | release/picobsd/tinyware/passwd/pw_copy.c | 306 | ||||
-rw-r--r-- | release/picobsd/tinyware/passwd/pw_util.c | 258 | ||||
-rw-r--r-- | release/picobsd/tinyware/passwd/pw_util.h | 44 |
6 files changed, 891 insertions, 35 deletions
diff --git a/release/picobsd/tinyware/passwd/Makefile b/release/picobsd/tinyware/passwd/Makefile index 17fbfc8..c7b3183 100644 --- a/release/picobsd/tinyware/passwd/Makefile +++ b/release/picobsd/tinyware/passwd/Makefile @@ -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} diff --git a/release/picobsd/tinyware/passwd/extern.h b/release/picobsd/tinyware/passwd/extern.h new file mode 100644 index 0000000..eae768c --- /dev/null +++ b/release/picobsd/tinyware/passwd/extern.h @@ -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 *); diff --git a/release/picobsd/tinyware/passwd/local_passwd.c b/release/picobsd/tinyware/passwd/local_passwd.c new file mode 100644 index 0000000..6bbf24d --- /dev/null +++ b/release/picobsd/tinyware/passwd/local_passwd.c @@ -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); +} diff --git a/release/picobsd/tinyware/passwd/pw_copy.c b/release/picobsd/tinyware/passwd/pw_copy.c new file mode 100644 index 0000000..681eea8 --- /dev/null +++ b/release/picobsd/tinyware/passwd/pw_copy.c @@ -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); +} diff --git a/release/picobsd/tinyware/passwd/pw_util.c b/release/picobsd/tinyware/passwd/pw_util.c new file mode 100644 index 0000000..1c163d2 --- /dev/null +++ b/release/picobsd/tinyware/passwd/pw_util.c @@ -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); +} diff --git a/release/picobsd/tinyware/passwd/pw_util.h b/release/picobsd/tinyware/passwd/pw_util.h new file mode 100644 index 0000000..1000a9a --- /dev/null +++ b/release/picobsd/tinyware/passwd/pw_util.h @@ -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); |