Subject: bin/5803: su doesn't support it's "-f" option for sh and/or ksh
To: None <gnats-bugs@gnats.netbsd.org>
From: None <woods@most.weird.com>
List: netbsd-bugs
Date: 07/19/1998 19:28:56
>Number: 5803
>Category: bin
>Synopsis: su doesn't support it's "-f" option for sh and/or ksh
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Jul 19 16:35:00 1998
>Last-Modified:
>Originator: Greg A. Woods
>Organization:
Planix, Inc.; Toronto, Ontario; Canada
>Release: NetBSD-current 19980719
>Environment:
System: NetBSD most 1.3.1 NetBSD 1.3.1 (MOST) #0: Mon May 25 01:21:22 EDT 1998 woods@most:/usr/src-1.3.1/sys/arch/sparc/compile/MOST sparc
>Description:
Su(1) does not include support for its '-f' option for any shell
but csh(1). However both sh(1) and ksh(1) will source a file
pointed to by the $ENV environment variable. Su(1) should unset
this variable if '-f' is given to provide the same behaviour for
sh(1) and ksh(1) as it does for csh(1).
>How-To-Repeat:
by behavioural observation and code walk-through
>Fix:
Apply the attached patch.
The core of this patch are the segments for the manual page and
the following change:
***************
*** 272,278 ****
*np-- = "-f";
if (asme)
*np-- = "-m";
! }
if (asthem) {
avshellbuf[0] = '-';
--- 272,279 ----
*np-- = "-f"; /* don't read .cshrc */
if (asme)
*np-- = "-m"; /* allow reading of my .cshrc by user */
! } else if (fastlogin)
! unsetenv("ENV"); /* sh & ksh: don't process $ENV */
if (asthem) {
avshellbuf[0] = '-';
The full patch also includes some KNF and a minor error message
clarification and clarification of logic leading to that error:
Index: su.c
===================================================================
RCS file: /cvs/NetBSD/src/usr.bin/su/su.c,v
retrieving revision 1.1.1.2
diff -c -r1.1.1.2 su.c
*** su.c 1998/04/04 22:57:32 1.1.1.2
--- su.c 1998/07/19 23:07:45
***************
*** 156,165 ****
errx(1, "who are you?");
}
username = strdup(pwd->pw_name);
! if (asme)
if (pwd->pw_shell && *pwd->pw_shell)
shell = strncpy(shellbuf, pwd->pw_shell,
! sizeof(shellbuf) + 1);
else {
shell = _PATH_BSHELL;
iscsh = NO;
--- 156,165 ----
errx(1, "who are you?");
}
username = strdup(pwd->pw_name);
! if (asme) /* use my shell */
if (pwd->pw_shell && *pwd->pw_shell)
shell = strncpy(shellbuf, pwd->pw_shell,
! sizeof(shellbuf) + 1);
else {
shell = _PATH_BSHELL;
iscsh = NO;
***************
*** 174,238 ****
}
if (ruid) {
#ifdef KERBEROS
! if (!use_kerberos || kerberos(username, user, pwd->pw_uid))
#endif
! {
! /* Only allow those in group SUGROUP to su to root,
! but only if that group has any members.
! If SUGROUP has no members, allow anyone to su root */
! if (pwd->pw_uid == 0 &&
! (gr = getgrnam(SUGROUP)) && *gr->gr_mem) {
! char **g;
!
! for (g = gr->gr_mem; ; g++) {
! if (*g == NULL)
! errx(1,
"you are not listed in the correct secondary group (%s) to su %s.",
! SUGROUP, user);
! if (strcmp(username, *g) == 0)
! break;
}
! }
! /* if target requires a password, verify it */
! if (*pwd->pw_passwd) {
! 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))) {
badlogin:
! fprintf(stderr, "Sorry\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;
! } else {
! shell = _PATH_BSHELL;
! iscsh = NO;
}
-
if ((p = strrchr(shell, '/')) != NULL)
avshell = p+1;
else
--- 174,239 ----
}
if (ruid) {
+ /* if asme and non-standard target shell, must be root */
+ if (asme && !chshell(pwd->pw_shell))
+ errx(1, "permission denied (%s has non-standard shell %s).", user, pwd->pw_shell);
#ifdef KERBEROS
! if (!use_kerberos || kerberos(username, user, pwd->pw_uid))
#endif
! {
! /* Only allow those in group SUGROUP to su to root,
! * but only if that group has any members.
! * If SUGROUP has no members, allow anyone to su root */
! if (pwd->pw_uid == 0 &&
! (gr = getgrnam(SUGROUP)) && *gr->gr_mem) {
! char **g;
!
! for (g = gr->gr_mem; ; g++) {
! if (*g == NULL)
! errx(1,
"you are not listed in the correct secondary group (%s) to su %s.",
! SUGROUP, user);
! if (strcmp(username, *g) == 0)
! break;
! }
}
! /* if target requires a password, verify it */
! if (*pwd->pw_passwd) {
! 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))) {
badlogin:
! fprintf(stderr, "Sorry\n");
! syslog(LOG_AUTH|LOG_WARNING,
! "BAD SU %s to %s%s", username,
! user, ontty());
! exit(1);
! }
! }
}
}
}
! if (!asme) {
! if (pwd->pw_shell && *pwd->pw_shell) {
! shell = pwd->pw_shell;
! iscsh = UNSET;
! } else {
! shell = _PATH_BSHELL;
! iscsh = NO;
! }
}
if ((p = strrchr(shell, '/')) != NULL)
avshell = p+1;
else
***************
*** 266,278 ****
(void)setenv("HOME", pwd->pw_dir, 1);
(void)setenv("SHELL", shell, 1);
}
-
if (iscsh == YES) {
if (fastlogin)
! *np-- = "-f";
if (asme)
! *np-- = "-m";
! }
if (asthem) {
avshellbuf[0] = '-';
--- 267,279 ----
(void)setenv("HOME", pwd->pw_dir, 1);
(void)setenv("SHELL", shell, 1);
}
if (iscsh == YES) {
if (fastlogin)
! *np-- = "-f"; /* don't read .cshrc */
if (asme)
! *np-- = "-m"; /* allow reading of my .cshrc by user */
! } else if (fastlogin)
! unsetenv("ENV"); /* sh & ksh: don't process $ENV */
if (asthem) {
avshellbuf[0] = '-';
***************
*** 325,330 ****
--- 326,333 ----
{
char *cp;
+ if (!pwd->pw_shell || !*pwd->pw_shell)
+ return (1); /* an unspecified shell is always "standard" */
while ((cp = getusershell()) != NULL)
if (!strcmp(cp, sh))
return (1);
Index: su.1
===================================================================
RCS file: /cvs/NetBSD/src/usr.bin/su/su.1,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 su.1
*** su.1 1998/02/20 00:43:25 1.1.1.1
--- su.1 1998/07/19 23:10:01
***************
*** 32,38 ****
.\" from: @(#)su.1 8.2 (Berkeley) 4/18/94
.\" $NetBSD: su.1,v 1.14 1997/10/19 23:31:52 lukem Exp $
.\"
! .Dd April 18, 1994
.Dt SU 1
.Os
.Sh NAME
--- 32,38 ----
.\" from: @(#)su.1 8.2 (Berkeley) 4/18/94
.\" $NetBSD: su.1,v 1.14 1997/10/19 23:31:52 lukem Exp $
.\"
! .Dd July 19, 1998
.Dt SU 1
.Os
.Sh NAME
***************
*** 81,89 ****
.Ev USER
is set to the target login, unless the target login has a user ID of 0,
in which case it is unmodified.
! The invoked shell is the target login's.
! This is the traditional behavior of
! .Nm "" .
.Pp
The options are as follows:
.Bl -tag -width Ds
--- 81,89 ----
.Ev USER
is set to the target login, unless the target login has a user ID of 0,
in which case it is unmodified.
! The invoked shell is the target login's default shell unless the
! .Fl m
! option is set.
.Pp
The options are as follows:
.Bl -tag -width Ds
***************
*** 95,100 ****
--- 95,109 ----
this option prevents it from reading the
.Dq Pa .cshrc
file.
+ If the invoked shell is not
+ .Xr csh 1 ,
+ this option unsets any occurance of
+ .Ev ENV
+ in the environment to prevent possible processing of the file pointed to
+ by this variable by
+ .Xr ksh 1
+ or
+ .Xr sh 1 .
.It Fl l
Simulate a full login.
The environment is discarded except for
***************
*** 121,128 ****
.It Fl m
Leave the environment unmodified.
The invoked shell is your login shell, and no directory changes are made.
! As a security precaution, if the target user's shell is a non-standard
! shell (as defined by
.Xr getusershell 3 )
and the caller's real uid is
non-zero,
--- 130,137 ----
.It Fl m
Leave the environment unmodified.
The invoked shell is your login shell, and no directory changes are made.
! As a security precaution, if the target user's default shell is a
! non-standard shell (as defined by
.Xr getusershell 3 )
and the caller's real uid is
non-zero,
***************
*** 163,168 ****
--- 172,178 ----
to remind one of its awesome power.
.Sh SEE ALSO
.Xr csh 1 ,
+ .Xr ksh 1 ,
.Xr login 1 ,
.Xr sh 1 ,
.Xr skey 1 ,
***************
*** 175,180 ****
--- 185,195 ----
Environment variables used by
.Nm "" :
.Bl -tag -width "HOME"
+ .It Ev ENV
+ Gives file to process on shell startup, used by
+ .Xr ksh
+ and
+ .Xr sh .
.It Ev HOME
Default home directory of real user ID unless modified as
specified above.
>Audit-Trail:
>Unformatted: