Subject: bin/5788: su enhancement: allow root to su explicitly with /bin/sh
To: None <gnats-bugs@gnats.netbsd.org>
From: None <woods@most.weird.com>
List: netbsd-bugs
Date: 07/18/1998 01:56:05
>Number: 5788
>Category: bin
>Synopsis: su enhancement: allow root to su explicitly with /bin/sh
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Fri Jul 17 23:05:00 1998
>Last-Modified:
>Originator: Greg A. Woods
>Organization:
Planix, Inc.; Toronto, Ontario; Canada
>Release: NetBSD-1.3.1
>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:
When a user has a non-generic shell (i.e. not one of the normal
command-line shells such as /bin/sh, but instead something like
/sbin/nologin), it is impossible, even for root, to start a normal
shell as that user.
>How-To-Repeat:
Try to run a command as the user 'daemon' when that user's shell
is set to /sbin/nologin. For example:
01:35 [2083] # su daemon -c id
This account is currently not available.
>Fix:
Apply the following patch. It adds a new option '-s' to su(1)
which when used with the above example results in success:
01:35 [2085] # su -s daemon -c id
uid=1(daemon) gid=31(guest) groups=31(guest), 1(daemon)
Note that this new option is only available to root.
BTW, defaulting to /bin/sh only is more than enough -- anyone
who wants some other shell can get it from there....
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/17 17:48:48
***************
*** 70,76 ****
#include <kerberosIV/krb.h>
#include <netdb.h>
! #define ARGSTR "-Kflm"
int use_kerberos = 1;
--- 70,76 ----
#include <kerberosIV/krb.h>
#include <netdb.h>
! #define ARGSTR "-Kflms"
int use_kerberos = 1;
***************
*** 78,84 ****
static int koktologin __P((char *, char *, char *));
#else
! #define ARGSTR "-flm"
#endif
#ifndef SUGROUP
--- 78,84 ----
static int koktologin __P((char *, char *, char *));
#else
! #define ARGSTR "-flms"
#endif
#ifndef SUGROUP
***************
*** 104,115 ****
struct group *gr;
struct timeval tp;
uid_t ruid;
! int asme, ch, asthem, fastlogin, prio;
enum { UNSET, YES, NO } iscsh = UNSET;
char *user, *shell, *avshell, *username, *cleanenv[10], **np;
char shellbuf[MAXPATHLEN], avshellbuf[MAXPATHLEN];
! asme = asthem = fastlogin = 0;
shell = NULL;
while ((ch = getopt(argc, argv, ARGSTR)) != -1)
switch((char)ch) {
--- 104,115 ----
struct group *gr;
struct timeval tp;
uid_t ruid;
! int asme, ch, asthem, fastlogin, prio, usebshell;
enum { UNSET, YES, NO } iscsh = UNSET;
char *user, *shell, *avshell, *username, *cleanenv[10], **np;
char shellbuf[MAXPATHLEN], avshellbuf[MAXPATHLEN];
! asme = asthem = fastlogin = usebshell = 0;
shell = NULL;
while ((ch = getopt(argc, argv, ARGSTR)) != -1)
switch((char)ch) {
***************
*** 130,135 ****
--- 130,138 ----
asme = 1;
asthem = 0;
break;
+ case 's':
+ usebshell = 1;
+ break;
case '?':
default:
(void)fprintf(stderr,
***************
*** 155,165 ****
if (pwd == NULL) {
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;
--- 158,170 ----
if (pwd == NULL) {
errx(1, "who are you?");
}
+ if (usebshell && ruid)
+ errx(1,"permission denied (-s).");
username = strdup(pwd->pw_name);
if (asme)
! if (!usebshell && pwd->pw_shell && *pwd->pw_shell)
shell = strncpy(shellbuf, pwd->pw_shell,
! sizeof(shellbuf) + 1);
else {
shell = _PATH_BSHELL;
iscsh = NO;
***************
*** 225,231 ****
/* 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 {
--- 230,236 ----
/* if asme and non-standard target shell, must be root */
if (!chshell(pwd->pw_shell) && ruid)
errx(1,"permission denied (shell).");
! } else if (!usebshell && pwd->pw_shell && *pwd->pw_shell) {
shell = pwd->pw_shell;
iscsh = UNSET;
} else {
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/17 17:02:16
***************
*** 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 17, 1998
.Dt SU 1
.Os
.Sh NAME
***************
*** 40,46 ****
.Nd substitute user identity
.Sh SYNOPSIS
.Nm
! .Op Fl Kflm
.Op Ar login Op Ar "shell arguments"
.Sh DESCRIPTION
.Nm
--- 40,46 ----
.Nd substitute user identity
.Sh SYNOPSIS
.Nm
! .Op Fl Kflms
.Op Ar login Op Ar "shell arguments"
.Sh DESCRIPTION
.Nm
***************
*** 128,133 ****
--- 128,138 ----
non-zero,
.Nm
will fail.
+ .It Fl s
+ Ignore the user's shell and invoke
+ .Pa /bin/sh
+ instead.
+ This option is only available for callers with a real uid of zero.
.El
.Pp
The
>Audit-Trail:
>Unformatted: