-# @(#)Makefile 8.1 (Berkeley) %G%
+# @(#)Makefile 8.2 (Berkeley) %G%
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
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)chpass.c 8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)chpass.c 8.2 (Berkeley) %G%";
#endif /* not lint */
#include <sys/param.h>
#include <sys/signal.h>
#include <sys/time.h>
#include <sys/resource.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
-#include <errno.h>
#include <stdio.h>
-#include <ctype.h>
+#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+
+#include <pw_scan.h>
+#include <pw_util.h>
+
#include "chpass.h"
#include "pathnames.h"
char *tempname;
uid_t uid;
+void baduser __P((void));
+void usage __P((void));
+
+int
main(argc, argv)
int argc;
char **argv;
{
- extern int optind;
- extern char *optarg;
- register enum { NEWSH, LOADENTRY, EDITENTRY } op;
- register struct passwd *pw;
- struct passwd lpw;
+ enum { NEWSH, LOADENTRY, EDITENTRY } op;
+ struct passwd *pw, lpw;
int ch, pfd, tfd;
char *arg;
if (op == EDITENTRY || op == NEWSH)
switch(argc) {
case 0:
- if (!(pw = getpwuid(uid))) {
- (void)fprintf(stderr,
- "chpass: unknown user: uid %u\n", uid);
- exit(1);
- }
+ if (!(pw = getpwuid(uid)))
+ errx(1, "unknown user: uid %u", uid);
break;
case 1:
- if (!(pw = getpwnam(*argv))) {
- (void)fprintf(stderr,
- "chpass: unknown user %s.\n", *argv);
- exit(1);
- }
+ if (!(pw = getpwnam(*argv)))
+ errx(1, "unknown user: %s", *argv);
if (uid && uid != pw->pw_uid)
baduser();
break;
exit(0);
}
+void
baduser()
{
- (void)fprintf(stderr, "chpass: %s\n", strerror(EACCES));
- exit(1);
+
+ errx(1, "%s", strerror(EACCES));
}
+void
usage()
{
+
(void)fprintf(stderr, "usage: chpass [-a list] [-s shell] [user]\n");
exit(1);
}
*
* %sccs.include.redist.c%
*
- * @(#)chpass.h 8.1 (Berkeley) %G%
+ * @(#)chpass.h 8.2 (Berkeley) %G%
*/
+struct passwd;
+
typedef struct _entry {
char *prompt;
int (*func)(), restricted, len;
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 *));
+void pw_copy __P((int, int, struct passwd *));
+char *ttoa __P((time_t));
+int verify __P((struct passwd *));
*/
#ifndef lint
-static char sccsid[] = "@(#)edit.c 8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)edit.c 8.2 (Berkeley) %G%";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
-#include <pwd.h>
+
+#include <ctype.h>
+#include <err.h>
#include <errno.h>
-#include <stdio.h>
#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+
+#include <pw_scan.h>
+#include <pw_util.h>
+
#include "chpass.h"
extern char *tempname;
if (stat(tempname, &end))
pw_error(tempname, 1, 1);
if (begin.st_mtime == end.st_mtime) {
- (void)fprintf(stderr, "chpass: no changes made\n");
+ warnx("no changes made");
pw_error(NULL, 0, 0);
}
if (verify(pw))
* 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;
{
- register char *p;
FILE *fp;
- char *bp, *ok_shell(), *ttoa();
+ char *bp, *p, *ttoa();
if (!(fp = fdopen(fd, "w")))
pw_error(tempname, 1, 1);
(void)fclose(fp);
}
+int
verify(pw)
struct passwd *pw;
{
- register ENTRY *ep;
- register char *p;
+ ENTRY *ep;
+ char *p;
struct stat sb;
FILE *fp;
int len;
if (fstat(fileno(fp), &sb))
pw_error(tempname, 1, 1);
if (sb.st_size == 0) {
- (void)fprintf(stderr, "chpass: corrupted temporary file.\n");
+ warnx("corrupted temporary file");
goto bad;
}
while (fgets(buf, sizeof(buf), fp)) {
if (!buf[0] || buf[0] == '#')
continue;
- if (!(p = index(buf, '\n'))) {
- (void)fprintf(stderr, "chpass: line too long.\n");
+ if (!(p = strchr(buf, '\n'))) {
+ warnx("line too long");
goto bad;
}
*p = '\0';
for (ep = list;; ++ep) {
if (!ep->prompt) {
- (void)fprintf(stderr,
- "chpass: unrecognized field.\n");
+ warnx("unrecognized field");
goto bad;
}
if (!strncasecmp(buf, ep->prompt, ep->len)) {
if (ep->restricted && uid) {
- (void)fprintf(stderr,
- "chpass: you may not change the %s field.\n",
- ep->prompt);
+ warnx(
+ "you may not change the %s field",
+ ep->prompt);
goto bad;
}
- if (!(p = index(buf, ':'))) {
- (void)fprintf(stderr,
- "chpass: line corrupted.\n");
+ if (!(p = strchr(buf, ':'))) {
+ warnx("line corrupted");
goto bad;
}
while (isspace(*++p));
if (ep->except && strpbrk(p, ep->except)) {
- (void)fprintf(stderr,
- "chpass: illegal character in the \"%s\" field.\n",
+ warnx(
+ "illegal character in the \"%s\" field",
ep->prompt);
goto bad;
}
if ((ep->func)(p, pw, ep)) {
bad: (void)fclose(fp);
- return(0);
+ return (0);
}
break;
}
/* 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))) {
- (void)fprintf(stderr, "chpass: %s\n", strerror(errno));
- exit(1);
- }
+ 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);
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)) {
- (void)fprintf(stderr, "chpass: entries too long\n");
- return(0);
+ warnx("entries too long");
+ return (0);
}
- return(pw_scan(buf, pw));
+ return (pw_scan(buf, pw));
}
*/
#ifndef lint
-static char sccsid[] = "@(#)field.c 8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)field.c 8.3 (Berkeley) %G%";
#endif /* not lint */
#include <sys/param.h>
-#include <pwd.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
#include <grp.h>
-#include <string.h>
+#include <pwd.h>
#include <stdio.h>
-#include <errno.h>
-#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
#include "chpass.h"
#include "pathnames.h"
/* ARGSUSED */
+int
p_login(p, pw, ep)
char *p;
struct passwd *pw;
ENTRY *ep;
{
if (!*p) {
- (void)fprintf(stderr, "chpass: empty login field.\n");
- return(1);
+ warnx("empty login field");
+ return (1);
}
if (*p == '-') {
- (void)fprintf(stderr,
- "chpass: login names may not begin with a hyphen.\n");
- return(1);
+ warnx("login names may not begin with a hyphen");
+ return (1);
}
if (!(pw->pw_name = strdup(p))) {
- (void)fprintf(stderr, "chpass: can't save entry.\n");
- return(1);
+ warnx("can't save entry");
+ return (1);
}
- if (index(p, '.'))
- (void)fprintf(stderr,
- "chpass: \'.\' is dangerous in a login name.\n");
+ if (strchr(p, '.'))
+ warnx("\'.\' is dangerous in a login name");
for (; *p; ++p)
if (isupper(*p)) {
- (void)fprintf(stderr,
- "chpass: upper-case letters are dangerous in a login name.\n");
+ warnx("upper-case letters are dangerous in a login name");
break;
}
- return(0);
+ return (0);
}
/* ARGSUSED */
+int
p_passwd(p, pw, ep)
char *p;
struct passwd *pw;
if (!*p)
pw->pw_passwd = ""; /* "NOLOGIN"; */
else if (!(pw->pw_passwd = strdup(p))) {
- (void)fprintf(stderr, "chpass: can't save password entry.\n");
- return(1);
+ warnx("can't save password entry");
+ return (1);
}
- return(0);
+ return (0);
}
/* ARGSUSED */
+int
p_uid(p, pw, ep)
- register char *p;
+ char *p;
struct passwd *pw;
ENTRY *ep;
{
char *np;
if (!*p) {
- (void)fprintf(stderr, "chpass: empty uid field.\n");
- return(1);
+ warnx("empty uid field");
+ return (1);
}
if (!isdigit(*p)) {
- (void)fprintf(stderr, "chpass: illegal uid.\n");
- return(1);
+ warnx("illegal uid");
+ return (1);
}
errno = 0;
id = strtoul(p, &np, 10);
if (*np || (id == ULONG_MAX && errno == ERANGE)) {
- (void)fprintf(stderr, "chpass: illegal uid.\n");
- return(1);
+ warnx("illegal uid");
+ return (1);
}
pw->pw_uid = id;
- return(0);
+ return (0);
}
/* ARGSUSED */
+int
p_gid(p, pw, ep)
- register char *p;
+ char *p;
struct passwd *pw;
ENTRY *ep;
{
char *np;
if (!*p) {
- (void)fprintf(stderr, "chpass: empty gid field.\n");
- return(1);
+ warnx("empty gid field");
+ return (1);
}
if (!isdigit(*p)) {
if (!(gr = getgrnam(p))) {
- (void)fprintf(stderr,
- "chpass: unknown group %s.\n", p);
- return(1);
+ warnx("unknown group %s", p);
+ return (1);
}
pw->pw_gid = gr->gr_gid;
- return(0);
+ return (0);
}
errno = 0;
id = strtoul(p, &np, 10);
if (*np || (id == ULONG_MAX && errno == ERANGE)) {
- (void)fprintf(stderr, "chpass: illegal gid.\n");
- return(1);
+ warnx("illegal gid");
+ return (1);
}
pw->pw_gid = id;
- return(0);
+ return (0);
}
/* ARGSUSED */
+int
p_class(p, pw, ep)
char *p;
struct passwd *pw;
if (!*p)
pw->pw_class = "";
else if (!(pw->pw_class = strdup(p))) {
- (void)fprintf(stderr, "chpass: can't save entry.\n");
- return(1);
+ warnx("can't save entry");
+ return (1);
}
- return(0);
+ return (0);
}
/* ARGSUSED */
+int
p_change(p, pw, ep)
char *p;
struct passwd *pw;
ENTRY *ep;
{
if (!atot(p, &pw->pw_change))
- return(0);
- (void)fprintf(stderr, "chpass: illegal date for change field.\n");
- return(1);
+ 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);
- (void)fprintf(stderr, "chpass: illegal date for expire field.\n");
- return(1);
+ return (0);
+ warnx("illegal date for expire field");
+ return (1);
}
/* ARGSUSED */
+int
p_gecos(p, pw, ep)
char *p;
struct passwd *pw;
if (!*p)
ep->save = "";
else if (!(ep->save = strdup(p))) {
- (void)fprintf(stderr, "chpass: can't save entry.\n");
- return(1);
+ warnx("can't save entry");
+ return (1);
}
- return(0);
+ return (0);
}
/* ARGSUSED */
+int
p_hdir(p, pw, ep)
char *p;
struct passwd *pw;
ENTRY *ep;
{
if (!*p) {
- (void)fprintf(stderr, "chpass: empty home directory field.\n");
- return(1);
+ warnx("empty home directory field");
+ return (1);
}
if (!(pw->pw_dir = strdup(p))) {
- (void)fprintf(stderr, "chpass: can't save entry.\n");
- return(1);
+ warnx("can't save entry");
+ return (1);
}
- return(0);
+ return (0);
}
/* ARGSUSED */
+int
p_shell(p, pw, ep)
- register char *p;
+ char *p;
struct passwd *pw;
ENTRY *ep;
{
if (!*p) {
pw->pw_shell = _PATH_BSHELL;
- return(0);
+ return (0);
}
/* only admin can change from or to "restricted" shells */
if (uid && pw->pw_shell && !ok_shell(pw->pw_shell)) {
- (void)fprintf(stderr,
- "chpass: %s: current shell non-standard.\n", pw->pw_shell);
- return(1);
+ warnx("%s: current shell non-standard", pw->pw_shell);
+ return (1);
}
if (!(t = ok_shell(p))) {
if (uid) {
- (void)fprintf(stderr,
- "chpass: %s: non-standard shell.\n", p);
- return(1);
+ warnx("%s: non-standard shell", p);
+ return (1);
}
}
else
p = t;
if (!(pw->pw_shell = strdup(p))) {
- (void)fprintf(stderr, "chpass: can't save entry.\n");
- return(1);
+ warnx("can't save entry");
+ return (1);
}
- return(0);
+ return (0);
}
*/
#ifndef lint
-static char sccsid[] = "@(#)pw_copy.c 8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)pw_copy.c 8.2 (Berkeley) %G%";
#endif /* not lint */
/*
* record, by chpass(1) and passwd(1).
*/
+#include <err.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
-extern char *progname, *tempname;
+#include <pw_util.h>
+extern char *tempname;
+
+void
pw_copy(ffd, tfd, pw)
int ffd, tfd;
struct passwd *pw;
{
- register FILE *from, *to;
- register int done;
- register char *p;
- char buf[8192];
+ FILE *from, *to;
+ int done;
+ char *p, buf[8192];
if (!(from = fdopen(ffd, "r")))
pw_error(_PATH_MASTERPASSWD, 1, 1);
pw_error(tempname, 1, 1);
for (done = 0; fgets(buf, sizeof(buf), from);) {
- if (!index(buf, '\n')) {
- (void)fprintf(stderr, "%s: %s: line too long\n",
- progname, _PATH_MASTERPASSWD);
+ if (!strchr(buf, '\n')) {
+ warnx("%s: line too long", _PATH_MASTERPASSWD);
pw_error(NULL, 0, 1);
}
if (done) {
goto err;
continue;
}
- if (!(p = index(buf, ':'))) {
- (void)fprintf(stderr, "%s: %s: corrupted entry\n",
- progname, _PATH_MASTERPASSWD);
+ if (!(p = strchr(buf, ':'))) {
+ warnx("%s: corrupted entry", _PATH_MASTERPASSWD);
pw_error(NULL, 0, 1);
}
*p = '\0';
*/
#ifndef lint
-static char sccsid[] = "@(#)table.c 8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)table.c 8.2 (Berkeley) %G%";
#endif /* not lint */
#include <sys/types.h>
char e1[] = ": ";
char e2[] = ":,";
-int p_change(), p_class(), p_expire(), p_gecos(), p_gid(), p_hdir();
-int p_login(), p_passwd(), p_shell(), p_uid();
-
ENTRY list[] = {
{ "login", p_login, 1, 5, e1, },
{ "password", p_passwd, 1, 8, e1, },
*/
#ifndef lint
-static char sccsid[] = "@(#)util.c 8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)util.c 8.3 (Berkeley) %G%";
#endif /* not lint */
#include <sys/types.h>
-#include <sys/time.h>
-#include <tzfile.h>
+
+#include <ctype.h>
#include <pwd.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
+#include <time.h>
+#include <tzfile.h>
+#include <unistd.h>
+
#include "chpass.h"
#include "pathnames.h"
{ "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November",
"December", NULL };
+
char *
ttoa(tval)
time_t tval;
}
else
*tbuf = '\0';
- return(tbuf);
+ return (tbuf);
}
+int
atot(p, store)
char *p;
time_t *store;
{
- register char *t, **mp;
static struct tm *lt;
- time_t tval, time();
+ char *t, **mp;
+ time_t tval;
int day, month, year;
if (!*p) {
*store = 0;
- return(0);
+ return (0);
}
if (!lt) {
unsetenv("TZ");
if (year < 100)
year += TM_YEAR_BASE;
if (year <= EPOCH_YEAR)
-bad: return(1);
+bad: return (1);
tval = isleap(year) && month > 2;
for (--year; year >= EPOCH_YEAR; --year)
tval += isleap(year) ?
tval = tval * HOURSPERDAY * MINSPERHOUR * SECSPERMIN;
tval -= lt->tm_gmtoff;
*store = tval;
- return(0);
+ return (0);
}
char *
ok_shell(name)
- register char *name;
+ char *name;
{
- register char *p, *sh;
- char *getusershell();
+ char *p, *sh;
setusershell();
while (sh = getusershell()) {
if (!strcmp(name, sh))
- return(name);
+ return (name);
/* allow just shell name, but use "real" path */
- if ((p = rindex(sh, '/')) && !strcmp(name, p + 1))
- return(sh);
+ if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0)
+ return (sh);
}
- return(NULL);
+ return (NULL);
}
*/
#ifndef lint
-static char sccsid[] = "@(#)klogin.c 8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)klogin.c 8.2 (Berkeley) %G%";
#endif /* not lint */
#ifdef KERBEROS
#include <sys/syslog.h>
#include <kerberosIV/des.h>
#include <kerberosIV/krb.h>
-#include <pwd.h>
+
+#include <err.h>
#include <netdb.h>
+#include <pwd.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
* to make the kerberos library do the right thing.
*/
if (setuid(0) < 0) {
- perror("login: setuid");
+ warnx("setuid");
return (1);
}
kerror = krb_get_pw_in_tkt(pw->pw_name, instance,
"warning: TGT not verified (%s); %s.%s not registered, or srvtab is wrong?",
krb_err_txt[kerror], VERIFY_SERVICE, savehost);
notickets = 0;
- return(0);
+ return (0);
}
if (kerror != KSUCCESS) {
- (void)printf("unable to use TGT: (%s)\n", krb_err_txt[kerror]);
+ warnx("unable to use TGT: (%s)", krb_err_txt[kerror]);
syslog(LOG_NOTICE, "unable to use TGT: (%s)",
krb_err_txt[kerror]);
dest_tkt();
- return(1);
+ return (1);
}
if (!(hp = gethostbyname(localhost))) {
syslog(LOG_ERR, "couldn't get local host address");
dest_tkt();
- return(1);
+ return (1);
}
- bcopy((void *)hp->h_addr, (void *)&faddr, sizeof(faddr));
+ memmove((void *)&faddr, (void *)hp->h_addr, sizeof(faddr));
kerror = krb_rd_req(&ticket, VERIFY_SERVICE, savehost, faddr,
&authdata, "");
if (kerror == KSUCCESS) {
notickets = 0;
- return(0);
+ return (0);
}
/* undecipherable: probably didn't have a srvtab on the local host */
if (kerror = RD_AP_UNDEC) {
syslog(LOG_NOTICE, "krb_rd_req: (%s)\n", krb_err_txt[kerror]);
dest_tkt();
- return(1);
+ return (1);
}
/* failed for some other reason */
- (void)printf("unable to verify %s ticket: (%s)\n", VERIFY_SERVICE,
+ warnx("unable to verify %s ticket: (%s)", VERIFY_SERVICE,
krb_err_txt[kerror]);
syslog(LOG_NOTICE, "couldn't verify %s ticket: %s", VERIFY_SERVICE,
krb_err_txt[kerror]);
dest_tkt();
- return(1);
+ return (1);
}
#endif
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)login.c 8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)login.c 8.3 (Berkeley) %G%";
#endif /* not lint */
/*
#include <sys/resource.h>
#include <sys/file.h>
-#include <signal.h>
-#include <ttyent.h>
-#include <syslog.h>
-#include <setjmp.h>
-#include <tzfile.h>
-#include <utmp.h>
+#include <err.h>
#include <errno.h>
#include <grp.h>
#include <pwd.h>
-#include <unistd.h>
+#include <setjmp.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <syslog.h>
+#include <ttyent.h>
+#include <tzfile.h>
+#include <unistd.h>
+#include <utmp.h>
+
#include "pathnames.h"
void badlogin __P((char *));
int klogin __P((struct passwd *, char *, char *, char *));
#endif
+extern void login __P((struct utmp *));
+
#define TTYGRPNAME "tty" /* name of group to own ttys */
/*
* This bounds the time given to login. Not a define so it can
* be patched on machines where it's too small.
*/
-int timeout = 300;
+u_int timeout = 300;
#ifdef KERBEROS
int notickets = 1;
char *argv[];
{
extern char **environ;
- register int ch;
- register char *p;
struct group *gr;
struct stat st;
struct timeval tp;
struct utmp utmp;
- int ask, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval, uid;
- char *domain, *salt, *ttyn;
+ int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval;
+ uid_t uid;
+ char *domain, *p, *salt, *ttyn;
char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
char localhost[MAXHOSTNAMELEN];
(void)signal(SIGALRM, timedout);
- (void)alarm((u_int)timeout);
+ (void)alarm(timeout);
(void)signal(SIGQUIT, SIG_IGN);
(void)signal(SIGINT, SIG_IGN);
(void)setpriority(PRIO_PROCESS, 0, 0);
if (gethostname(localhost, sizeof(localhost)) < 0)
syslog(LOG_ERR, "couldn't get local hostname: %m");
else
- domain = index(localhost, '.');
+ domain = strchr(localhost, '.');
fflag = hflag = pflag = rflag = 0;
uid = getuid();
fflag = 1;
break;
case 'h':
- if (uid) {
- (void)fprintf(stderr,
- "login: -h option: %s\n", strerror(EPERM));
- exit(1);
- }
+ if (uid)
+ errx(1, "-h option: %s", strerror(EPERM));
if (rflag) {
fprintf(stderr,
"login: only one of -r and -h allowed.\n");
exit(1);
}
hflag = 1;
- if (domain && (p = index(optarg, '.')) &&
+ if (domain && (p = strchr(optarg, '.')) &&
strcasecmp(p, domain) == 0)
*p = 0;
hostname = optarg;
(void)snprintf(tname, sizeof(tname), "%s??", _PATH_TTY);
ttyn = tname;
}
- if (tty = rindex(ttyn, '/'))
+ if (tty = strrchr(ttyn, '/'))
++tty;
else
tty = ttyn;
}
rootlogin = 0;
#ifdef KERBEROS
- if ((instance = index(username, '.')) != NULL) {
+ if ((instance = strchr(username, '.')) != NULL) {
if (strncmp(instance, ".root", 5) == 0)
rootlogin = 1;
*instance++ = '\0';
rval = strcmp(crypt(p, salt), pwd->pw_passwd);
#endif
}
- bzero(p, strlen(p));
+ memset(p, 0, strlen(p));
(void)setpriority(PRIO_PROCESS, 0, 0);
ctime(&pwd->pw_expire));
/* Nothing else left to fail -- really log in. */
- bzero((void *)&utmp, sizeof(utmp));
+ memset((void *)&utmp, 0, sizeof(utmp));
(void)time(&utmp.ut_time);
(void)strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
if (hostname)
(void)signal(SIGTSTP, SIG_IGN);
tbuf[0] = '-';
- (void)strcpy(tbuf + 1, (p = rindex(pwd->pw_shell, '/')) ?
+ (void)strcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ?
p + 1 : pwd->pw_shell);
if (setlogin(pwd->pw_name) < 0)
(void) setuid(pwd->pw_uid);
execlp(pwd->pw_shell, tbuf, 0);
- (void)fprintf(stderr, "%s: %s\n", pwd->pw_shell, strerror(errno));
- exit(1);
+ err(1, "%s", pwd->pw_shell);
}
#ifdef KERBEROS
void
getloginname()
{
- register int ch;
- register char *p;
+ int ch;
+ char *p;
static char nbuf[NBUFSIZ];
for (;;) {
{
struct ttyent *t;
- return((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
+ return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
}
jmp_buf motdinterrupt;
void
motd()
{
- register int fd, nchars;
+ int fd, nchars;
sig_t oldint;
char tbuf[8192];
sigint(signo)
int signo;
{
+
longjmp(motdinterrupt, 1);
}
timedout(signo)
int signo;
{
+
(void)fprintf(stderr, "Login timed out after %d seconds\n", timeout);
exit(0);
}
void
checknologin()
{
- register int fd, nchars;
+ int fd, nchars;
char tbuf[8192];
if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
}
(void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
}
- bzero((void *)&ll, sizeof(ll));
+ memset((void *)&ll, 0, sizeof(ll));
(void)time(&ll.ll_time);
(void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
if (hostname)
badlogin(name)
char *name;
{
+
if (failures == 0)
return;
if (hostname) {
{
struct ttyent *t;
- return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
+ return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
}
void
sleepexit(eval)
int eval;
{
- (void)sleep((u_int)5);
+
+ (void)sleep(5);
exit(eval);
}
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)su.c 8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)su.c 8.2 (Berkeley) %G%";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
#include <sys/resource.h>
-#include <syslog.h>
-#include <stdio.h>
-#include <pwd.h>
+
+#include <err.h>
+#include <errno.h>
#include <grp.h>
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <syslog.h>
#include <unistd.h>
-#include <paths.h>
#ifdef KERBEROS
#include <kerberosIV/des.h>
#define ARGSTR "-flm"
#endif
+char *ontty __P((void));
+int chshell __P((char *));
+
+int
main(argc, argv)
int argc;
char **argv;
{
extern char **environ;
- extern int errno, optind;
- register struct passwd *pwd;
- register char *p, **g;
+ struct passwd *pwd;
+ char *p, **g, *user, *shell, *username, *cleanenv[2], *nargv[4], **np;
struct group *gr;
- uid_t ruid, getuid();
+ uid_t ruid;
int asme, ch, asthem, fastlogin, prio;
enum { UNSET, YES, NO } iscsh = UNSET;
- char *user, *shell, *username, *cleanenv[2], *nargv[4], **np;
char shellbuf[MAXPATHLEN];
- char *crypt(), *getpass(), *getenv(), *getlogin(), *ontty();
np = &nargv[3];
*np-- = NULL;
if (username == NULL || (pwd = getpwnam(username)) == NULL ||
pwd->pw_uid != ruid)
pwd = getpwuid(ruid);
- if (pwd == NULL) {
- fprintf(stderr, "su: who are you?\n");
- exit(1);
- }
+ if (pwd == NULL)
+ errx(1, "who are you?");
username = strdup(pwd->pw_name);
+ if (username == NULL)
+ err(1, NULL);
if (asme)
if (pwd->pw_shell && *pwd->pw_shell)
shell = strcpy(shellbuf, pwd->pw_shell);
/* only allow those in group zero to su to root. */
if (pwd->pw_uid == 0 && (gr = getgrgid((gid_t)0)))
for (g = gr->gr_mem;; ++g) {
- if (!*g) {
- (void)fprintf(stderr,
- "su: you are not in the correct group to su %s.\n",
+ if (!*g)
+ errx(1,
+ "you are not in the correct group to su %s.",
user);
- exit(1);
- }
- if (!strcmp(username, *g))
+ if (strcmp(username, *g) == 0)
break;
}
/* if target requires a password, verify it */
if (asme) {
/* if asme and non-standard target shell, must be root */
- if (!chshell(pwd->pw_shell) && ruid) {
- (void)fprintf(stderr,
- "su: permission denied (shell).\n");
- exit(1);
- }
+ if (!chshell(pwd->pw_shell) && ruid)
+ errx(1, "permission denied (shell).");
} else if (pwd->pw_shell && *pwd->pw_shell) {
shell = pwd->pw_shell;
iscsh = UNSET;
/* if we're forking a csh, we want to slightly muck the args */
if (iscsh == UNSET) {
- if (p = rindex(shell, '/'))
+ if (p = strrchr(shell, '/'))
++p;
else
p = shell;
}
/* set permissions */
- if (setgid(pwd->pw_gid) < 0) {
- perror("su: setgid");
- exit(1);
- }
- if (initgroups(user, pwd->pw_gid)) {
- (void)fprintf(stderr, "su: initgroups failed.\n");
- exit(1);
- }
- if (setuid(pwd->pw_uid) < 0) {
- perror("su: setuid");
- exit(1);
- }
+ if (setgid(pwd->pw_gid) < 0)
+ err(1, "setgid");
+ if (initgroups(user, pwd->pw_gid))
+ errx(1, "initgroups failed");
+ if (setuid(pwd->pw_uid) < 0)
+ err(1, "setuid");
if (!asme) {
if (asthem) {
cleanenv[1] = NULL;
environ = cleanenv;
(void)setenv("TERM", p, 1);
- if (chdir(pwd->pw_dir) < 0) {
- fprintf(stderr, "su: no directory\n");
- exit(1);
- }
+ if (chdir(pwd->pw_dir) < 0)
+ errx(1, "no directory");
}
if (asthem || pwd->pw_uid)
(void)setenv("USER", pwd->pw_name, 1);
(void)setpriority(PRIO_PROCESS, 0, prio);
execv(shell, np);
- (void)fprintf(stderr, "su: %s not found.\n", shell);
- exit(1);
+ err(1, "%s", shell);
}
+int
chshell(sh)
char *sh;
{
- register char *cp;
- char *getusershell();
+ char *cp;
while ((cp = getusershell()) != NULL)
- if (!strcmp(cp, sh))
+ if (strcmp(cp, sh) == 0)
return (1);
return (0);
}
char *
ontty()
{
- char *p, *ttyname();
+ char *p;
static char buf[MAXPATHLEN + 4];
buf[0] = 0;
if (p = ttyname(STDERR_FILENO))
- sprintf(buf, " on %s", p);
+ snprintf(buf, sizeof(buf), " on %s", p);
return (buf);
}
KTEXT_ST ticket;
AUTH_DAT authdata;
struct hostent *hp;
- register char *p;
+ char *p;
int kerno;
u_long faddr;
char lrealm[REALM_SZ], krbtkfile[MAXPATHLEN];
char hostname[MAXHOSTNAMELEN], savehost[MAXHOSTNAMELEN];
- char *ontty(), *krb_get_phost();
+ char *krb_get_phost();
if (krb_get_lrealm(lrealm, 1) != KSUCCESS)
return (1);
if (koktologin(username, lrealm, user) && !uid) {
- (void)fprintf(stderr, "kerberos su: not in %s's ACL.\n", user);
+ warnx("kerberos: not in %s's ACL.", user);
return (1);
}
(void)sprintf(krbtkfile, "%s_%s_%d", TKT_ROOT, user, getuid());
* to make the kerberos library do the right thing.
*/
if (setuid(0) < 0) {
- perror("su: setuid");
+ warn("setuid");
return (1);
}
if (kerno != KSUCCESS) {
if (kerno == KDC_PR_UNKNOWN) {
- fprintf(stderr, "principal unknown: %s.%s@%s\n",
+ warnx("kerberos: principal unknown: %s.%s@%s",
(uid == 0 ? username : user),
(uid == 0 ? "root" : ""), lrealm);
return (1);
}
- (void)fprintf(stderr, "su: unable to su: %s\n",
- krb_err_txt[kerno]);
+ warnx("kerberos: unable to su: %s", krb_err_txt[kerno]);
syslog(LOG_NOTICE|LOG_AUTH,
"BAD Kerberos SU: %s to %s%s: %s",
username, user, ontty(), krb_err_txt[kerno]);
}
if (chown(krbtkfile, uid, -1) < 0) {
- perror("su: chown:");
+ warn("chown");
(void)unlink(krbtkfile);
return (1);
}
(void)setpriority(PRIO_PROCESS, 0, -2);
if (gethostname(hostname, sizeof(hostname)) == -1) {
- perror("su: gethostname");
+ warn("gethostname");
dest_tkt();
return (1);
}
kerno = krb_mk_req(&ticket, "rcmd", savehost, lrealm, 33);
if (kerno == KDC_PR_UNKNOWN) {
- (void)fprintf(stderr, "Warning: TGT not verified.\n");
+ warnx("Warning: TGT not verified.");
syslog(LOG_NOTICE|LOG_AUTH,
"%s to %s%s, TGT not verified (%s); %s.%s not registered?",
username, user, ontty(), krb_err_txt[kerno],
"rcmd", savehost);
} else if (kerno != KSUCCESS) {
- (void)fprintf(stderr, "Unable to use TGT: %s\n",
- krb_err_txt[kerno]);
+ warnx("Unable to use TGT: %s", krb_err_txt[kerno]);
syslog(LOG_NOTICE|LOG_AUTH, "failed su: %s to %s%s: %s",
username, user, ontty(), krb_err_txt[kerno]);
dest_tkt();
return (1);
} else {
if (!(hp = gethostbyname(hostname))) {
- (void)fprintf(stderr, "su: can't get addr of %s\n",
- hostname);
+ warnx("can't get addr of %s", hostname);
dest_tkt();
return (1);
}
- (void)bcopy((char *)hp->h_addr, (char *)&faddr, sizeof(faddr));
+ memmove((char *)&faddr, (char *)hp->h_addr, sizeof(faddr));
if ((kerno = krb_rd_req(&ticket, "rcmd", savehost, faddr,
&authdata, "")) != KSUCCESS) {
- (void)fprintf(stderr,
- "su: unable to verify rcmd ticket: %s\n",
+ warnx("kerberos: unable to verify rcmd ticket: %s\n",
krb_err_txt[kerno]);
syslog(LOG_NOTICE|LOG_AUTH,
"failed su: %s to %s%s: %s", username,
koktologin(name, realm, toname)
char *name, *realm, *toname;
{
- register AUTH_DAT *kdata;
+ AUTH_DAT *kdata;
AUTH_DAT kdata_st;
kdata = &kdata_st;
- bzero((caddr_t) kdata, sizeof(*kdata));
+ memset((char *)kdata, 0, sizeof(*kdata));
(void)strcpy(kdata->pname, name);
(void)strcpy(kdata->pinst,
((strcmp(toname, "root") == 0) ? "root" : ""));