=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/su/su.c,v retrieving revision 1.7 retrieving revision 1.8 diff -c -r1.7 -r1.8 *** src/usr.bin/su/su.c 1996/10/12 17:13:57 1.7 --- src/usr.bin/su/su.c 1996/10/12 20:40:37 1.8 *************** *** 1,4 **** ! /* $OpenBSD: su.c,v 1.7 1996/10/12 17:13:57 millert Exp $ */ /* * Copyright (c) 1988 The Regents of the University of California. --- 1,4 ---- ! /* $OpenBSD: su.c,v 1.8 1996/10/12 20:40:37 millert Exp $ */ /* * Copyright (c) 1988 The Regents of the University of California. *************** *** 41,61 **** #ifndef lint /*static char sccsid[] = "from: @(#)su.c 5.26 (Berkeley) 7/6/91";*/ ! static char rcsid[] = "$OpenBSD: su.c,v 1.7 1996/10/12 17:13:57 millert Exp $"; #endif /* not lint */ #include #include #include ! #include #include #include - #include - #include #include #include - #include #ifdef KERBEROS #include #include --- 41,68 ---- #ifndef lint /*static char sccsid[] = "from: @(#)su.c 5.26 (Berkeley) 7/6/91";*/ ! static char rcsid[] = "$OpenBSD: su.c,v 1.8 1996/10/12 20:40:37 millert Exp $"; #endif /* not lint */ #include #include #include ! ! #include ! #include ! #include ! #include ! #include #include #include #include + #include #include + #ifdef SKEY + #include + #endif + #ifdef KERBEROS #include #include *************** *** 68,75 **** #define ARGSTR "-flm" #endif ! extern char *crypt(); ! int chshell(); int main(argc, argv) --- 75,82 ---- #define ARGSTR "-flm" #endif ! char *ontty __P((void)); ! int chshell __P((char *)); int main(argc, argv) *************** *** 77,83 **** char **argv; { extern char **environ; - extern int errno, optind; register struct passwd *pwd; register char *p, **g; struct group *gr; --- 84,89 ---- *************** *** 86,92 **** enum { UNSET, YES, NO } iscsh = UNSET; char *user, *shell, *avshell, *username, *cleanenv[10], **np; char shellbuf[MAXPATHLEN], avshellbuf[MAXPATHLEN]; - char *getpass(), *getenv(), *getlogin(), *ontty(); asme = asthem = fastlogin = 0; while ((ch = getopt(argc, argv, ARGSTR)) != EOF) --- 92,97 ---- *************** *** 130,139 **** 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); ! } username = strdup(pwd->pw_name); if (asme) if (pwd->pw_shell && *pwd->pw_shell) --- 135,142 ---- if (username == NULL || (pwd = getpwnam(username)) == NULL || pwd->pw_uid != ruid) pwd = getpwuid(ruid); ! if (pwd == NULL) ! errx(1, "who are you?"); username = strdup(pwd->pw_name); if (asme) if (pwd->pw_shell && *pwd->pw_shell) *************** *** 147,156 **** user = *argv ? *argv : "root"; np = *argv ? argv : argv-1; ! if ((pwd = getpwnam(user)) == NULL) { ! fprintf(stderr, "su: unknown login %s\n", user); ! exit(1); ! } if (ruid) { #ifdef KERBEROS --- 150,157 ---- user = *argv ? *argv : "root"; np = *argv ? argv : argv-1; ! if ((pwd = getpwnam(user)) == NULL) ! errx(1, "unknown login %s", user); if (ruid) { #ifdef KERBEROS *************** *** 161,173 **** if (pwd->pw_uid == 0 && (gr = getgrgid((gid_t)0)) && gr->gr_mem && *(gr->gr_mem)) for (g = gr->gr_mem;; ++g) { ! if (!*g) { ! (void)fprintf(stderr, ! "su: you are not in the correct group to su %s.\n", ! user); ! exit(1); ! } ! if (!strcmp(username, *g)) break; } /* if target requires a password, verify it */ --- 162,170 ---- if (pwd->pw_uid == 0 && (gr = getgrgid((gid_t)0)) && gr->gr_mem && *(gr->gr_mem)) for (g = gr->gr_mem;; ++g) { ! if (!*g) ! errx(1, "you are not in the correct group to su %s.", user); ! if (strcmp(username, *g) == 0) break; } /* if target requires a password, verify it */ *************** *** 175,189 **** p = getpass("Password:"); #ifdef SKEY if (strcasecmp(p, "s/key") == 0) { ! if (skey_haskey(user)) { ! fprintf(stderr, "Sorry, you have no s/key.\n"); ! exit(1); ! } else { ! if (skey_authenticate(user)) { ! goto badlogin; ! } ! } ! } else #endif if (strcmp(pwd->pw_passwd, crypt(p, pwd->pw_passwd))) { --- 172,181 ---- p = getpass("Password:"); #ifdef SKEY if (strcasecmp(p, "s/key") == 0) { ! if (skey_haskey(user)) ! errx(1, "Sorry, you have no s/key."); ! else if (skey_authenticate(user)) ! goto badlogin; } else #endif if (strcmp(pwd->pw_passwd, crypt(p, pwd->pw_passwd))) { *************** *** 196,210 **** } } } } 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); ! } } else if (pwd->pw_shell && *pwd->pw_shell) { shell = pwd->pw_shell; iscsh = UNSET; --- 188,205 ---- } } } + if (pwd->pw_expire && time(NULL) >= pwd->pw_expire) { + fprintf(stderr, "Sorry - account expired\n"); + syslog(LOG_AUTH|LOG_WARNING, "BAD SU %s to %s%s", username, + user, ontty()); + exit(1); + } } if (asme) { /* if asme and non-standard target shell, must be root */ ! 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; *************** *** 213,219 **** iscsh = NO; } ! if (p = rindex(shell, '/')) avshell = p+1; else avshell = shell; --- 208,214 ---- iscsh = NO; } ! if (p = strrchr(shell, '/')) avshell = p+1; else avshell = shell; *************** *** 223,240 **** iscsh = strcmp(avshell, "csh") ? NO : YES; /* 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 (!asme) { if (asthem) { --- 218,229 ---- iscsh = strcmp(avshell, "csh") ? NO : YES; /* set permissions */ ! if (setgid(pwd->pw_gid) < 0) ! err(1, "setgid"); ! if (initgroups(user, pwd->pw_gid)) ! err(1, "initgroups failed"); ! if (setuid(pwd->pw_uid) < 0) ! err(1, "setuid"); if (!asme) { if (asthem) { *************** *** 247,256 **** seteuid(pwd->pw_uid); setegid(pwd->pw_gid); ! if (chdir(pwd->pw_dir) < 0) { ! fprintf(stderr, "su: no directory\n"); ! exit(1); ! } seteuid(0); setegid(0); /* XXX use a saved gid instead? */ } --- 236,243 ---- seteuid(pwd->pw_uid); setegid(pwd->pw_gid); ! if (chdir(pwd->pw_dir) < 0) ! errx(1, "no directory"); seteuid(0); setegid(0); /* XXX use a saved gid instead? */ } *************** *** 287,294 **** (void)setpriority(PRIO_PROCESS, 0, prio); execv(shell, np); ! (void)fprintf(stderr, "su: %s not found.\n", shell); ! exit(1); } int --- 274,280 ---- (void)setpriority(PRIO_PROCESS, 0, prio); execv(shell, np); ! err(1, "%s", shell); } int *************** *** 296,305 **** char *sh; { register char *cp; - char *getusershell(); while ((cp = getusershell()) != NULL) ! if (!strcmp(cp, sh)) return (1); return (0); } --- 282,290 ---- char *sh; { register char *cp; while ((cp = getusershell()) != NULL) ! if (strcmp(cp, sh) == 0) return (1); return (0); } *************** *** 312,318 **** buf[0] = 0; if (p = ttyname(STDERR_FILENO)) ! sprintf(buf, " on %s", p); return (buf); } --- 297,303 ---- buf[0] = 0; if (p = ttyname(STDERR_FILENO)) ! snprintf(buf, sizeof(buf), " on %s", p); return (buf); } *************** *** 337,343 **** (void)fprintf(stderr, "kerberos su: not in %s's ACL.\n", user); return (1); } ! (void)sprintf(krbtkfile, "%s_%s_%d", TKT_ROOT, user, getuid()); (void)setenv("KRBTKFILE", krbtkfile, 1); (void)krb_set_tkt_string(krbtkfile); --- 322,329 ---- (void)fprintf(stderr, "kerberos su: not in %s's ACL.\n", user); return (1); } ! (void)snprintf(krbtkfile, sizeof(krbtkfile), "%s_%s_%d", TKT_ROOT, ! user, getuid()); (void)setenv("KRBTKFILE", krbtkfile, 1); (void)krb_set_tkt_string(krbtkfile); *************** *** 346,352 **** * to make the kerberos library do the right thing. */ if (setuid(0) < 0) { ! perror("su: setuid"); return (1); } --- 332,338 ---- * to make the kerberos library do the right thing. */ if (setuid(0) < 0) { ! warn("setuid"); return (1); } *************** *** 366,378 **** if (kerno != KSUCCESS) { if (kerno == KDC_PR_UNKNOWN) { ! fprintf(stderr, "principal unknown: %s.%s@%s\n", (uid == 0 ? username : user), (uid == 0 ? "root" : ""), lrealm); return (1); } ! (void)fprintf(stderr, "su: unable to su: %s\n", ! krb_err_txt[kerno]); syslog(LOG_NOTICE|LOG_AUTH, "BAD Kerberos SU: %s to %s%s: %s", username, user, ontty(), krb_err_txt[kerno]); --- 352,363 ---- if (kerno != KSUCCESS) { if (kerno == KDC_PR_UNKNOWN) { ! warnx("kerberos principal unknown: %s.%s@%s", (uid == 0 ? username : user), (uid == 0 ? "root" : ""), lrealm); return (1); } ! warnx("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]); *************** *** 380,386 **** } if (chown(krbtkfile, uid, -1) < 0) { ! perror("su: chown:"); (void)unlink(krbtkfile); return (1); } --- 365,371 ---- } if (chown(krbtkfile, uid, -1) < 0) { ! warn("chown"); (void)unlink(krbtkfile); return (1); } *************** *** 388,394 **** (void)setpriority(PRIO_PROCESS, 0, -2); if (gethostname(hostname, sizeof(hostname)) == -1) { ! perror("su: gethostname"); dest_tkt(); return (1); } --- 373,379 ---- (void)setpriority(PRIO_PROCESS, 0, -2); if (gethostname(hostname, sizeof(hostname)) == -1) { ! warn("gethostname"); dest_tkt(); return (1); } *************** *** 399,420 **** kerno = krb_mk_req(&ticket, "rcmd", savehost, lrealm, 33); if (kerno == KDC_PR_UNKNOWN) { ! (void)fprintf(stderr, "Warning: TGT not verified.\n"); 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]); 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); dest_tkt(); return (1); } --- 384,403 ---- kerno = krb_mk_req(&ticket, "rcmd", savehost, lrealm, 33); if (kerno == KDC_PR_UNKNOWN) { ! 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) { ! 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))) { ! warnx("can't get addr of %s", hostname); dest_tkt(); return (1); } *************** *** 422,430 **** if ((kerno = krb_rd_req(&ticket, "rcmd", savehost, faddr, &authdata, "")) != KSUCCESS) { ! (void)fprintf(stderr, ! "su: unable to verify rcmd ticket: %s\n", ! krb_err_txt[kerno]); syslog(LOG_NOTICE|LOG_AUTH, "failed su: %s to %s%s: %s", username, user, ontty(), krb_err_txt[kerno]); --- 405,412 ---- if ((kerno = krb_rd_req(&ticket, "rcmd", savehost, faddr, &authdata, "")) != KSUCCESS) { ! warnx("unable to verify rcmd ticket: %s", ! krb_err_txt[kerno]); syslog(LOG_NOTICE|LOG_AUTH, "failed su: %s to %s%s: %s", username, user, ontty(), krb_err_txt[kerno]);