From 15898a97e3f1366a56d5fa9d53743f716eb31110 Mon Sep 17 00:00:00 2001 From: "Rodney W. Grimes" Date: Fri, 27 May 1994 12:33:43 +0000 Subject: BSD 4.4 Lite Usr.bin Sources --- chpass/Makefile | 15 +++ chpass/chpass.1 | 231 +++++++++++++++++++++++++++++++++++++++++++++ chpass/chpass.c | 192 ++++++++++++++++++++++++++++++++++++++ chpass/chpass.h | 70 ++++++++++++++ chpass/edit.c | 213 ++++++++++++++++++++++++++++++++++++++++++ chpass/field.c | 268 +++++++++++++++++++++++++++++++++++++++++++++++++++++ chpass/pathnames.h | 39 ++++++++ chpass/pw_copy.c | 107 +++++++++++++++++++++ chpass/pw_copy.h | 36 +++++++ chpass/table.c | 60 ++++++++++++ chpass/util.c | 145 +++++++++++++++++++++++++++++ 11 files changed, 1376 insertions(+) create mode 100644 chpass/Makefile create mode 100644 chpass/chpass.1 create mode 100644 chpass/chpass.c create mode 100644 chpass/chpass.h create mode 100644 chpass/edit.c create mode 100644 chpass/field.c create mode 100644 chpass/pathnames.h create mode 100644 chpass/pw_copy.c create mode 100644 chpass/pw_copy.h create mode 100644 chpass/table.c create mode 100644 chpass/util.c (limited to 'chpass') diff --git a/chpass/Makefile b/chpass/Makefile new file mode 100644 index 0000000..b68ad10 --- /dev/null +++ b/chpass/Makefile @@ -0,0 +1,15 @@ +# @(#)Makefile 8.2 (Berkeley) 4/2/94 + +PROG= chpass +SRCS= chpass.c edit.c field.c pw_copy.c pw_scan.c pw_util.c table.c util.c +BINOWN= root +BINMODE=4555 +.PATH: ${.CURDIR}/../../usr.sbin/pwd_mkdb ${.CURDIR}/../../usr.sbin/vipw +CFLAGS+=-I${.CURDIR}/../../usr.sbin/pwd_mkdb -I${.CURDIR}/../../usr.sbin/vipw +LINKS= ${BINDIR}/chpass ${BINDIR}/chfn ${BINDIR}/chpass ${BINDIR}/chsh +MLINKS= chpass.1 chfn.1 chpass.1 chsh.1 + +afterinstall: + chflags schg /usr/bin/chpass + +.include diff --git a/chpass/chpass.1 b/chpass/chpass.1 new file mode 100644 index 0000000..1a40905 --- /dev/null +++ b/chpass/chpass.1 @@ -0,0 +1,231 @@ +.\" Copyright (c) 1988, 1990, 1993 +.\" 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. +.\" +.\" @(#)chpass.1 8.2 (Berkeley) 12/30/93 +.\" +.Dd December 30, 1993 +.Dt CHPASS 1 +.Os +.Sh NAME +.Nm chpass +.Nd add or change user database information +.Sh SYNOPSIS +chpass +.Op Fl a Ar list +.Op Fl s Ar newshell +.Op user +.Sh DESCRIPTION +.Nm Chpass +allows editing of the user database information associated +with +.Ar user +or, by default, the current user. +The information is formatted and supplied to an editor for changes. +.Pp +Only the information that the user is allowed to change is displayed. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl a +The super-user is allowed to directly supply a user database +entry, in the format specified by +.Xr passwd 5 , +as an argument. +This argument must be a colon (``:'') separated list of all the +user database fields, although they may be empty. +.It Fl s +The +.Fl s +option attempts to change the user's shell to +.Ar newshell . +.El +.Pp +Possible display items are as follows: +.Pp +.Bl -tag -width "Home Directory:" -compact -offset indent +.It Login: +user's login name +.It Password: +user's encrypted password +.It Uid: +user's login +.It Gid: +user's login group +.It Change: +password change time +.It Expire: +account expiration time +.It Class: +user's general classification +.It Home Directory: +user's home directory +.It Shell: +user's login shell +.It Full Name: +user's real name +.It Location: +user's normal location +.It Home Phone: +user's home phone +.It Office Phone: +user's office phone +.El +.Pp +The +.Ar login +field is the user name used to access the computer account. +.Pp +The +.Ar password +field contains the encrypted form of the user's password. +.Pp +The +.Ar uid +field is the number associated with the +.Ar login +field. +Both of these fields should be unique across the system (and often +across a group of systems) as they control file access. +.Pp +While it is possible to have multiple entries with identical login names +and/or identical user id's, it is usually a mistake to do so. Routines +that manipulate these files will often return only one of the multiple +entries, and that one by random selection. +.Pp +The +.Ar group +field is the group that the user will be placed in at login. +Since BSD supports multiple groups (see +.Xr groups 1 ) +this field currently has little special meaning. +This field may be filled in with either a number or a group name (see +.Xr group 5 ) . +.Pp +The +.Ar change +field is the date by which the password must be changed. +.Pp +The +.Ar expire +field is the date on which the account expires. +.Pp +Both the +.Ar change +and +.Ar expire +fields should be entered in the form ``month day year'' where +.Ar month +is the month name (the first three characters are sufficient), +.Ar day +is the day of the month, and +.Ar year +is the year. +.Pp +The +.Ar class +field is currently unused. In the near future it will be a key to +a +.Xr termcap 5 +style database of user attributes. +.Pp +The user's +.Ar home directory +is the full UNIX path name where the user +will be placed at login. +.Pp +The +.Ar shell +field is the command interpreter the user prefers. +If the +.Ar shell +field is empty, the Bourne shell, +.Pa /bin/sh , +is assumed. +When altering a login shell, and not the super-user, the user +may not change from a non-standard shell or to a non-standard +shell. +Non-standard is defined as a shell not found in +.Pa /etc/shells . +.Pp +The last four fields are for storing the user's +.Ar full name , office location , +and +.Ar home +and +.Ar work telephone +numbers. +.Pp +Once the information has been verified, +.Nm chpass +uses +.Xr pwd_mkdb 8 +to update the user database. +.Sh ENVIRONMENT +The +.Xr vi 1 +editor will be used unless the environment variable EDITOR is set to +an alternate editor. +When the editor terminates, the information is re-read and used to +update the user database itself. +Only the user, or the super-user, may edit the information associated +with the user. +.Sh FILES +.Bl -tag -width /etc/master.passwd -compact +.It Pa /etc/master.passwd +The user database +.It Pa /etc/passwd +A Version 7 format password file +.It Pa /etc/chpass.XXXXXX +Temporary copy of the password file +.It Pa /etc/shells +The list of approved shells +.El +.Sh SEE ALSO +.Xr login 1 , +.Xr finger 1 , +.Xr passwd 1 , +.Xr getusershell 3 , +.Xr passwd 5 , +.Xr pwd_mkdb 8 , +.Xr vipw 8 +.Rs +.%A Robert Morris +and +.%A Ken Thompson +.%T "UNIX Password security" +.Re +.Sh BUGS +User information should (and eventually will) be stored elsewhere. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.3 Reno . diff --git a/chpass/chpass.c b/chpass/chpass.c new file mode 100644 index 0000000..0852c53 --- /dev/null +++ b/chpass/chpass.c @@ -0,0 +1,192 @@ +/*- + * Copyright (c) 1988, 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 char copyright[] = +"@(#) Copyright (c) 1988, 1993, 1994\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)chpass.c 8.4 (Berkeley) 4/2/94"; +#endif /* not lint */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "pw_copy.h" + +#include "chpass.h" +#include "pathnames.h" + +char *progname = "chpass"; +char *tempname; +uid_t uid; + +void baduser __P((void)); +void usage __P((void)); + +int +main(argc, argv) + int argc; + char **argv; +{ + enum { NEWSH, LOADENTRY, EDITENTRY } op; + struct passwd *pw, lpw; + int ch, pfd, tfd; + char *arg; + + op = EDITENTRY; + while ((ch = getopt(argc, argv, "a:s:")) != EOF) + switch(ch) { + case 'a': + op = LOADENTRY; + arg = optarg; + break; + case 's': + op = NEWSH; + arg = optarg; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + uid = getuid(); + + if (op == EDITENTRY || op == NEWSH) + switch(argc) { + case 0: + if (!(pw = getpwuid(uid))) + errx(1, "unknown user: uid %u", uid); + break; + case 1: + if (!(pw = getpwnam(*argv))) + errx(1, "unknown user: %s", *argv); + if (uid && uid != pw->pw_uid) + baduser(); + break; + default: + usage(); + } + + if (op == NEWSH) { + /* protect p_shell -- it thinks NULL is /bin/sh */ + if (!arg[0]) + usage(); + if (p_shell(arg, pw, (ENTRY *)NULL)) + pw_error((char *)NULL, 0, 1); + } + + if (op == LOADENTRY) { + if (uid) + baduser(); + pw = &lpw; + if (!pw_scan(arg, pw)) + exit(1); + } + + /* + * The temporary file/file descriptor usage is a little tricky here. + * 1: We start off with two fd's, one for the master password + * file (used to lock everything), and one for a temporary file. + * 2: Display() gets an fp for the temporary file, and copies the + * user's information into it. It then gives the temporary file + * to the user and closes the fp, closing the underlying fd. + * 3: The user edits the temporary file some number of times. + * 4: Verify() gets an fp for the temporary file, and verifies the + * contents. It can't use an fp derived from the step #2 fd, + * because the user's editor may have created a new instance of + * the file. Once the file is verified, its contents are stored + * in a password structure. The verify routine closes the fp, + * closing the underlying fd. + * 5: Delete the temporary file. + * 6: Get a new temporary file/fd. Pw_copy() gets an fp for it + * file and copies the master password file into it, replacing + * the user record with a new one. We can't use the first + * temporary file for this because it was owned by the user. + * Pw_copy() closes its fp, flushing the data and closing the + * underlying file descriptor. We can't close the master + * password fp, or we'd lose the lock. + * 7: Call pw_mkdb() (which renames the temporary file) and exit. + * The exit closes the master passwd fp/fd. + */ + pw_init(); + pfd = pw_lock(); + tfd = pw_tmp(); + + if (op == EDITENTRY) { + display(tfd, pw); + edit(pw); + (void)unlink(tempname); + tfd = pw_tmp(); + } + + pw_copy(pfd, tfd, pw); + + if (!pw_mkdb()) + pw_error((char *)NULL, 0, 1); + exit(0); +} + +void +baduser() +{ + + errx(1, "%s", strerror(EACCES)); +} + +void +usage() +{ + + (void)fprintf(stderr, "usage: chpass [-a list] [-s shell] [user]\n"); + exit(1); +} diff --git a/chpass/chpass.h b/chpass/chpass.h new file mode 100644 index 0000000..e7891ce --- /dev/null +++ b/chpass/chpass.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1988, 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. + * + * @(#)chpass.h 8.4 (Berkeley) 4/2/94 + */ + +struct passwd; + +typedef struct _entry { + char *prompt; + int (*func)(), restricted, len; + char *except, *save; +} ENTRY; + +/* Field numbers. */ +#define E_BPHONE 8 +#define E_HPHONE 9 +#define E_LOCATE 10 +#define E_NAME 7 +#define E_SHELL 12 + +extern ENTRY list[]; +extern uid_t uid; + +int atot __P((char *, time_t *)); +void display __P((int, struct passwd *)); +void edit __P((struct passwd *)); +char *ok_shell __P((char *)); +int p_change __P((char *, struct passwd *, ENTRY *)); +int p_class __P((char *, struct passwd *, ENTRY *)); +int p_expire __P((char *, struct passwd *, ENTRY *)); +int p_gecos __P((char *, struct passwd *, ENTRY *)); +int p_gid __P((char *, struct passwd *, ENTRY *)); +int p_hdir __P((char *, struct passwd *, ENTRY *)); +int p_login __P((char *, struct passwd *, ENTRY *)); +int p_login __P((char *, struct passwd *, ENTRY *)); +int p_passwd __P((char *, struct passwd *, ENTRY *)); +int p_shell __P((char *, struct passwd *, ENTRY *)); +int p_uid __P((char *, struct passwd *, ENTRY *)); +char *ttoa __P((time_t)); +int verify __P((struct passwd *)); diff --git a/chpass/edit.c b/chpass/edit.c new file mode 100644 index 0000000..34bd35b --- /dev/null +++ b/chpass/edit.c @@ -0,0 +1,213 @@ +/*- + * 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 char sccsid[] = "@(#)edit.c 8.3 (Berkeley) 4/2/94"; +#endif /* not lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "chpass.h" + +extern char *tempname; + +void +edit(pw) + struct passwd *pw; +{ + struct stat begin, end; + + for (;;) { + if (stat(tempname, &begin)) + pw_error(tempname, 1, 1); + pw_edit(1); + if (stat(tempname, &end)) + pw_error(tempname, 1, 1); + if (begin.st_mtime == end.st_mtime) { + warnx("no changes made"); + pw_error(NULL, 0, 0); + } + if (verify(pw)) + break; + pw_prompt(); + } +} + +/* + * display -- + * print out the file for the user to edit; strange side-effect: + * set conditional flag if the user gets to edit the shell. + */ +void +display(fd, pw) + int fd; + struct passwd *pw; +{ + FILE *fp; + char *bp, *p, *ttoa(); + + if (!(fp = fdopen(fd, "w"))) + pw_error(tempname, 1, 1); + + (void)fprintf(fp, + "#Changing user database information for %s.\n", pw->pw_name); + if (!uid) { + (void)fprintf(fp, "Login: %s\n", pw->pw_name); + (void)fprintf(fp, "Password: %s\n", pw->pw_passwd); + (void)fprintf(fp, "Uid [#]: %d\n", pw->pw_uid); + (void)fprintf(fp, "Gid [# or name]: %d\n", pw->pw_gid); + (void)fprintf(fp, "Change [month day year]: %s\n", + ttoa(pw->pw_change)); + (void)fprintf(fp, "Expire [month day year]: %s\n", + ttoa(pw->pw_expire)); + (void)fprintf(fp, "Class: %s\n", pw->pw_class); + (void)fprintf(fp, "Home directory: %s\n", pw->pw_dir); + (void)fprintf(fp, "Shell: %s\n", + *pw->pw_shell ? pw->pw_shell : _PATH_BSHELL); + } + /* Only admin can change "restricted" shells. */ + else if (ok_shell(pw->pw_shell)) + /* + * Make shell a restricted field. Ugly with a + * necklace, but there's not much else to do. + */ + (void)fprintf(fp, "Shell: %s\n", + *pw->pw_shell ? pw->pw_shell : _PATH_BSHELL); + else + list[E_SHELL].restricted = 1; + bp = pw->pw_gecos; + p = strsep(&bp, ","); + (void)fprintf(fp, "Full Name: %s\n", p ? p : ""); + p = strsep(&bp, ","); + (void)fprintf(fp, "Location: %s\n", p ? p : ""); + p = strsep(&bp, ","); + (void)fprintf(fp, "Office Phone: %s\n", p ? p : ""); + p = strsep(&bp, ","); + (void)fprintf(fp, "Home Phone: %s\n", p ? p : ""); + + (void)fchown(fd, getuid(), getgid()); + (void)fclose(fp); +} + +int +verify(pw) + struct passwd *pw; +{ + ENTRY *ep; + char *p; + struct stat sb; + FILE *fp; + int len; + char buf[LINE_MAX]; + + if (!(fp = fopen(tempname, "r"))) + pw_error(tempname, 1, 1); + if (fstat(fileno(fp), &sb)) + pw_error(tempname, 1, 1); + if (sb.st_size == 0) { + warnx("corrupted temporary file"); + goto bad; + } + while (fgets(buf, sizeof(buf), fp)) { + if (!buf[0] || buf[0] == '#') + continue; + if (!(p = strchr(buf, '\n'))) { + warnx("line too long"); + goto bad; + } + *p = '\0'; + for (ep = list;; ++ep) { + if (!ep->prompt) { + warnx("unrecognized field"); + goto bad; + } + if (!strncasecmp(buf, ep->prompt, ep->len)) { + if (ep->restricted && uid) { + warnx( + "you may not change the %s field", + ep->prompt); + goto bad; + } + if (!(p = strchr(buf, ':'))) { + warnx("line corrupted"); + goto bad; + } + while (isspace(*++p)); + if (ep->except && strpbrk(p, ep->except)) { + warnx( + "illegal character in the \"%s\" field", + ep->prompt); + goto bad; + } + if ((ep->func)(p, pw, ep)) { +bad: (void)fclose(fp); + return (0); + } + break; + } + } + } + (void)fclose(fp); + + /* Build the gecos field. */ + len = strlen(list[E_NAME].save) + strlen(list[E_BPHONE].save) + + strlen(list[E_HPHONE].save) + strlen(list[E_LOCATE].save) + 4; + if (!(p = malloc(len))) + err(1, NULL); + (void)sprintf(pw->pw_gecos = p, "%s,%s,%s,%s", list[E_NAME].save, + list[E_LOCATE].save, list[E_BPHONE].save, list[E_HPHONE].save); + + if (snprintf(buf, sizeof(buf), + "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s", + pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_class, + pw->pw_change, pw->pw_expire, pw->pw_gecos, pw->pw_dir, + pw->pw_shell) >= sizeof(buf)) { + warnx("entries too long"); + return (0); + } + return (pw_scan(buf, pw)); +} diff --git a/chpass/field.c b/chpass/field.c new file mode 100644 index 0000000..898ba4d --- /dev/null +++ b/chpass/field.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 1988, 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 char sccsid[] = "@(#)field.c 8.4 (Berkeley) 4/2/94"; +#endif /* not lint */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "chpass.h" +#include "pathnames.h" + +/* ARGSUSED */ +int +p_login(p, pw, ep) + char *p; + struct passwd *pw; + ENTRY *ep; +{ + if (!*p) { + warnx("empty login field"); + return (1); + } + if (*p == '-') { + warnx("login names may not begin with a hyphen"); + return (1); + } + if (!(pw->pw_name = strdup(p))) { + warnx("can't save entry"); + return (1); + } + if (strchr(p, '.')) + warnx("\'.\' is dangerous in a login name"); + for (; *p; ++p) + if (isupper(*p)) { + warnx("upper-case letters are dangerous in a login name"); + break; + } + return (0); +} + +/* ARGSUSED */ +int +p_passwd(p, pw, ep) + char *p; + struct passwd *pw; + ENTRY *ep; +{ + if (!*p) + pw->pw_passwd = ""; /* "NOLOGIN"; */ + else if (!(pw->pw_passwd = strdup(p))) { + warnx("can't save password entry"); + return (1); + } + + return (0); +} + +/* ARGSUSED */ +int +p_uid(p, pw, ep) + char *p; + struct passwd *pw; + ENTRY *ep; +{ + uid_t id; + char *np; + + if (!*p) { + warnx("empty uid field"); + return (1); + } + if (!isdigit(*p)) { + warnx("illegal uid"); + return (1); + } + errno = 0; + id = strtoul(p, &np, 10); + if (*np || (id == ULONG_MAX && errno == ERANGE)) { + warnx("illegal uid"); + return (1); + } + pw->pw_uid = id; + return (0); +} + +/* ARGSUSED */ +int +p_gid(p, pw, ep) + char *p; + struct passwd *pw; + ENTRY *ep; +{ + struct group *gr; + gid_t id; + char *np; + + if (!*p) { + warnx("empty gid field"); + return (1); + } + if (!isdigit(*p)) { + if (!(gr = getgrnam(p))) { + warnx("unknown group %s", p); + return (1); + } + pw->pw_gid = gr->gr_gid; + return (0); + } + errno = 0; + id = strtoul(p, &np, 10); + if (*np || (id == ULONG_MAX && errno == ERANGE)) { + warnx("illegal gid"); + return (1); + } + pw->pw_gid = id; + return (0); +} + +/* ARGSUSED */ +int +p_class(p, pw, ep) + char *p; + struct passwd *pw; + ENTRY *ep; +{ + if (!*p) + pw->pw_class = ""; + else if (!(pw->pw_class = strdup(p))) { + warnx("can't save entry"); + return (1); + } + + return (0); +} + +/* ARGSUSED */ +int +p_change(p, pw, ep) + char *p; + struct passwd *pw; + ENTRY *ep; +{ + if (!atot(p, &pw->pw_change)) + return (0); + warnx("illegal date for change field"); + return (1); +} + +/* ARGSUSED */ +int +p_expire(p, pw, ep) + char *p; + struct passwd *pw; + ENTRY *ep; +{ + if (!atot(p, &pw->pw_expire)) + return (0); + warnx("illegal date for expire field"); + return (1); +} + +/* ARGSUSED */ +int +p_gecos(p, pw, ep) + char *p; + struct passwd *pw; + ENTRY *ep; +{ + if (!*p) + ep->save = ""; + else if (!(ep->save = strdup(p))) { + warnx("can't save entry"); + return (1); + } + return (0); +} + +/* ARGSUSED */ +int +p_hdir(p, pw, ep) + char *p; + struct passwd *pw; + ENTRY *ep; +{ + if (!*p) { + warnx("empty home directory field"); + return (1); + } + if (!(pw->pw_dir = strdup(p))) { + warnx("can't save entry"); + return (1); + } + return (0); +} + +/* ARGSUSED */ +int +p_shell(p, pw, ep) + char *p; + struct passwd *pw; + ENTRY *ep; +{ + char *t, *ok_shell(); + + if (!*p) { + pw->pw_shell = _PATH_BSHELL; + return (0); + } + /* only admin can change from or to "restricted" shells */ + if (uid && pw->pw_shell && !ok_shell(pw->pw_shell)) { + warnx("%s: current shell non-standard", pw->pw_shell); + return (1); + } + if (!(t = ok_shell(p))) { + if (uid) { + warnx("%s: non-standard shell", p); + return (1); + } + } + else + p = t; + if (!(pw->pw_shell = strdup(p))) { + warnx("can't save entry"); + return (1); + } + return (0); +} diff --git a/chpass/pathnames.h b/chpass/pathnames.h new file mode 100644 index 0000000..30f3c0d --- /dev/null +++ b/chpass/pathnames.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1989, 1993 + * 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. + * + * @(#)pathnames.h 8.1 (Berkeley) 6/6/93 + */ + +#include + +#undef _PATH_TMP +#define _PATH_TMP "/tmp/chpass.XXXXXX" diff --git a/chpass/pw_copy.c b/chpass/pw_copy.c new file mode 100644 index 0000000..3db04ed --- /dev/null +++ b/chpass/pw_copy.c @@ -0,0 +1,107 @@ +/*- + * 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 char sccsid[] = "@(#)pw_copy.c 8.4 (Berkeley) 4/2/94"; +#endif /* not lint */ + +/* + * This module is used to copy the master password file, replacing a single + * record, by chpass(1) and passwd(1). + */ + +#include +#include +#include +#include + +#include +#include "pw_copy.h" + +extern char *tempname; + +void +pw_copy(ffd, tfd, pw) + int ffd, tfd; + struct passwd *pw; +{ + FILE *from, *to; + int done; + char *p, buf[8192]; + + 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; + } + 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; + } + (void)fprintf(to, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", + pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid, + pw->pw_class, pw->pw_change, pw->pw_expire, pw->pw_gecos, + pw->pw_dir, pw->pw_shell); + done = 1; + if (ferror(to)) + goto err; + } + if (!done) + (void)fprintf(to, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", + pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid, + pw->pw_class, pw->pw_change, pw->pw_expire, pw->pw_gecos, + pw->pw_dir, pw->pw_shell); + + if (ferror(to)) +err: pw_error(NULL, 1, 1); + (void)fclose(to); +} diff --git a/chpass/pw_copy.h b/chpass/pw_copy.h new file mode 100644 index 0000000..4ef68c5 --- /dev/null +++ b/chpass/pw_copy.h @@ -0,0 +1,36 @@ +/* + * 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_copy.h 8.1 (Berkeley) 4/2/94 + */ + +void pw_copy __P((int, int, struct passwd *)); diff --git a/chpass/table.c b/chpass/table.c new file mode 100644 index 0000000..46a12d1 --- /dev/null +++ b/chpass/table.c @@ -0,0 +1,60 @@ +/*- + * 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 char sccsid[] = "@(#)table.c 8.3 (Berkeley) 4/2/94"; +#endif /* not lint */ + +#include +#include +#include "chpass.h" + +char e1[] = ": "; +char e2[] = ":,"; + +ENTRY list[] = { + { "login", p_login, 1, 5, e1, }, + { "password", p_passwd, 1, 8, e1, }, + { "uid", p_uid, 1, 3, e1, }, + { "gid", p_gid, 1, 3, e1, }, + { "class", p_class, 1, 5, e1, }, + { "change", p_change, 1, 6, NULL, }, + { "expire", p_expire, 1, 6, NULL, }, + { "full name", p_gecos, 0, 9, e2, }, + { "office phone", p_gecos, 0, 12, e2, }, + { "home phone", p_gecos, 0, 10, e2, }, + { "location", p_gecos, 0, 8, e2, }, + { "home directory", p_hdir, 1, 14, e1, }, + { "shell", p_shell, 0, 5, e1, }, + { NULL, 0, }, +}; diff --git a/chpass/util.c b/chpass/util.c new file mode 100644 index 0000000..ec4cc1f --- /dev/null +++ b/chpass/util.c @@ -0,0 +1,145 @@ +/*- + * Copyright (c) 1988, 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 char sccsid[] = "@(#)util.c 8.4 (Berkeley) 4/2/94"; +#endif /* not lint */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "chpass.h" +#include "pathnames.h" + +static int dmsize[] = + { -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +static char *months[] = + { "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", + "December", NULL }; + +char * +ttoa(tval) + time_t tval; +{ + struct tm *tp; + static char tbuf[50]; + + if (tval) { + tp = localtime(&tval); + (void)sprintf(tbuf, "%s %d, %d", months[tp->tm_mon], + tp->tm_mday, tp->tm_year + TM_YEAR_BASE); + } + else + *tbuf = '\0'; + return (tbuf); +} + +int +atot(p, store) + char *p; + time_t *store; +{ + static struct tm *lt; + char *t, **mp; + time_t tval; + int day, month, year; + + if (!*p) { + *store = 0; + return (0); + } + if (!lt) { + unsetenv("TZ"); + (void)time(&tval); + lt = localtime(&tval); + } + if (!(t = strtok(p, " \t"))) + goto bad; + for (mp = months;; ++mp) { + if (!*mp) + goto bad; + if (!strncasecmp(*mp, t, 3)) { + month = mp - months + 1; + break; + } + } + if (!(t = strtok((char *)NULL, " \t,")) || !isdigit(*t)) + goto bad; + day = atoi(t); + if (!(t = strtok((char *)NULL, " \t,")) || !isdigit(*t)) + goto bad; + year = atoi(t); + if (day < 1 || day > 31 || month < 1 || month > 12 || !year) + goto bad; + if (year < 100) + year += TM_YEAR_BASE; + if (year <= EPOCH_YEAR) +bad: return (1); + tval = isleap(year) && month > 2; + for (--year; year >= EPOCH_YEAR; --year) + tval += isleap(year) ? + DAYSPERLYEAR : DAYSPERNYEAR; + while (--month) + tval += dmsize[month]; + tval += day; + tval = tval * HOURSPERDAY * MINSPERHOUR * SECSPERMIN; + tval -= lt->tm_gmtoff; + *store = tval; + return (0); +} + +char * +ok_shell(name) + char *name; +{ + char *p, *sh; + + setusershell(); + while (sh = getusershell()) { + if (!strcmp(name, sh)) + return (name); + /* allow just shell name, but use "real" path */ + if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0) + return (sh); + } + return (NULL); +} -- cgit v1.2.3-56-ge451