diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1996-10-12 20:40:39 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1996-10-12 20:40:39 +0000 |
commit | efac72f150f9fd0df48d723fe961a11c1c782e3a (patch) | |
tree | 23f66d1f08357f4e7484d1839426ed297d36f43f | |
parent | 7edb493036b03f0cb9f8e9cea8d2069f12273528 (diff) |
su.c: minor cleanup, some from FreeBSD
su.1: Examples from FreeBSD + minor nits fixed.
-rw-r--r-- | usr.bin/su/su.1 | 34 | ||||
-rw-r--r-- | usr.bin/su/su.c | 134 |
2 files changed, 89 insertions, 79 deletions
diff --git a/usr.bin/su/su.1 b/usr.bin/su/su.1 index 4809407d143..293c981bc06 100644 --- a/usr.bin/su/su.1 +++ b/usr.bin/su/su.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: su.1,v 1.3 1996/06/26 05:39:34 deraadt Exp $ +.\" $OpenBSD: su.1,v 1.4 1996/10/12 20:40:38 millert Exp $ .\" Copyright (c) 1988, 1990 The Regents of the University of California. .\" All rights reserved. .\" @@ -57,7 +57,7 @@ are passed to the shell. .Nm Su will resort to the local password file to find the password for .Ar login -if there is a Kerberos error. +if there is a Kerberos error or if Kerberos is not installed. If .Nm su is executed by root, no password is requested and a shell @@ -112,7 +112,7 @@ are modified as above. is set to the target login. .Ev PATH is set to -.Dq Pa /bin:/usr/bin . +.Dq Pa /usr/bin:/bin . .Ev TERM is imported from your current environment. The invoked shell is the target login's, and @@ -136,6 +136,17 @@ and .Fl m options are mutually exclusive; the last one specified overrides any previous ones. +.Pp +If the optional +.Ar "shell arguments" +are provided on the command line, they are passed to the login shell of +the target login. This allows it to pass arbitrary commands via +the +.Fl c +option as understood by most shells. Note that +.Fl c +usually expects a single argument only; you have to quote it when +passing multiple words. .Pp If group 0 (normally .Dq wheel ) @@ -152,6 +163,23 @@ By default (unless the prompt is reset by a startup file) the super-user prompt is set to .Dq Sy \&# to remind one of its awesome power. +.Sh EXAMPLES +.Bl -tag -width 5n -compact +.It Li "su bin -c makewhatis" +Runs the command +.Li makewhatis +as user +.Li bin . +You will be asked for bin's password unless your real UID is 0. +.Pp +.It Li "su bin -c 'makewhatis /usr/local/man'" +Same as above, but the target command consists of more than a +single word. +.Pp +.It Li "su -l foo" +Pretend a login for user +.Li foo . +.El .Sh SEE ALSO .Xr csh 1 , .Xr login 1 , diff --git a/usr.bin/su/su.c b/usr.bin/su/su.c index 9ba66b8153b..94a3aff8323 100644 --- a/usr.bin/su/su.c +++ b/usr.bin/su/su.c @@ -1,4 +1,4 @@ -/* $OpenBSD: su.c,v 1.7 1996/10/12 17:13:57 millert Exp $ */ +/* $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,20 +41,27 @@ char copyright[] = #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 $"; +static char rcsid[] = "$OpenBSD: su.c,v 1.8 1996/10/12 20:40:37 millert Exp $"; #endif /* not lint */ #include <sys/param.h> #include <sys/time.h> #include <sys/resource.h> -#include <syslog.h> + +#include <err.h> +#include <errno.h> +#include <grp.h> +#include <paths.h> +#include <pwd.h> #include <stdio.h> #include <stdlib.h> -#include <pwd.h> -#include <grp.h> #include <string.h> +#include <syslog.h> #include <unistd.h> -#include <paths.h> + +#ifdef SKEY +#include <skey.h> +#endif #ifdef KERBEROS #include <kerberosIV/des.h> @@ -68,8 +75,8 @@ int use_kerberos = 1; #define ARGSTR "-flm" #endif -extern char *crypt(); -int chshell(); +char *ontty __P((void)); +int chshell __P((char *)); int main(argc, argv) @@ -77,7 +84,6 @@ main(argc, argv) char **argv; { extern char **environ; - extern int errno, optind; register struct passwd *pwd; register char *p, **g; struct group *gr; @@ -86,7 +92,6 @@ main(argc, argv) 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) @@ -130,10 +135,8 @@ main(argc, argv) 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 (asme) if (pwd->pw_shell && *pwd->pw_shell) @@ -147,10 +150,8 @@ main(argc, argv) 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 ((pwd = getpwnam(user)) == NULL) + errx(1, "unknown login %s", user); if (ruid) { #ifdef KERBEROS @@ -161,13 +162,9 @@ main(argc, argv) 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)) + 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,15 +172,10 @@ main(argc, argv) 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; - } - } - + 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,15 +188,18 @@ badlogin: } } } + 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) { - (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; @@ -213,7 +208,7 @@ badlogin: iscsh = NO; } - if (p = rindex(shell, '/')) + if (p = strrchr(shell, '/')) avshell = p+1; else avshell = shell; @@ -223,18 +218,12 @@ badlogin: 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 (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,10 +236,8 @@ badlogin: seteuid(pwd->pw_uid); setegid(pwd->pw_gid); - if (chdir(pwd->pw_dir) < 0) { - fprintf(stderr, "su: no directory\n"); - exit(1); - } + if (chdir(pwd->pw_dir) < 0) + errx(1, "no directory"); seteuid(0); setegid(0); /* XXX use a saved gid instead? */ } @@ -287,8 +274,7 @@ badlogin: (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 @@ -296,10 +282,9 @@ chshell(sh) char *sh; { register char *cp; - char *getusershell(); while ((cp = getusershell()) != NULL) - if (!strcmp(cp, sh)) + if (strcmp(cp, sh) == 0) return (1); return (0); } @@ -312,7 +297,7 @@ ontty() buf[0] = 0; if (p = ttyname(STDERR_FILENO)) - sprintf(buf, " on %s", p); + snprintf(buf, sizeof(buf), " on %s", p); return (buf); } @@ -337,7 +322,8 @@ kerberos(username, user, uid) (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)snprintf(krbtkfile, sizeof(krbtkfile), "%s_%s_%d", TKT_ROOT, + user, getuid()); (void)setenv("KRBTKFILE", krbtkfile, 1); (void)krb_set_tkt_string(krbtkfile); @@ -346,7 +332,7 @@ kerberos(username, user, uid) * to make the kerberos library do the right thing. */ if (setuid(0) < 0) { - perror("su: setuid"); + warn("setuid"); return (1); } @@ -366,13 +352,12 @@ kerberos(username, user, uid) 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("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,7 +365,7 @@ kerberos(username, user, uid) } if (chown(krbtkfile, uid, -1) < 0) { - perror("su: chown:"); + warn("chown"); (void)unlink(krbtkfile); return (1); } @@ -388,7 +373,7 @@ kerberos(username, user, uid) (void)setpriority(PRIO_PROCESS, 0, -2); if (gethostname(hostname, sizeof(hostname)) == -1) { - perror("su: gethostname"); + warn("gethostname"); dest_tkt(); return (1); } @@ -399,22 +384,20 @@ kerberos(username, user, uid) 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); } @@ -422,9 +405,8 @@ kerberos(username, user, uid) 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]); + 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]); |