Implement login_cap capability lookup.

This commit is contained in:
mjl 2000-01-14 02:39:14 +00:00
parent 633ab39a92
commit e6ac440ed4
3 changed files with 80 additions and 14 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.16 1999/07/20 09:35:21 mrg Exp $ # $NetBSD: Makefile,v 1.17 2000/01/14 02:39:14 mjl Exp $
# from: @(#)Makefile 8.1 (Berkeley) 7/19/93 # from: @(#)Makefile 8.1 (Berkeley) 7/19/93
SRCTOP= ../.. SRCTOP= ../..
@ -6,10 +6,11 @@ SRCTOP= ../..
PROG= su PROG= su
DPADD+= ${LIBCRYPT} DPADD+= ${LIBCRYPT}
LDADD+= -lcrypt LDADD+= -lcrypt -lutil
BINOWN= root BINOWN= root
BINMODE=4555 BINMODE=4555
INSTALLFLAGS=-fschg INSTALLFLAGS=-fschg
CPPFLAGS+=-DLOGIN_CAP
# Uncomment the following line to change the group that may su root to "sugroup" # Uncomment the following line to change the group that may su root to "sugroup"
# #

View File

@ -30,9 +30,9 @@
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" from: @(#)su.1 8.2 (Berkeley) 4/18/94 .\" from: @(#)su.1 8.2 (Berkeley) 4/18/94
.\" $NetBSD: su.1,v 1.16 1999/09/27 19:41:33 mjl Exp $ .\" $NetBSD: su.1,v 1.17 2000/01/14 02:39:14 mjl Exp $
.\" .\"
.Dd April 18, 1994 .Dd January 14, 2000
.Dt SU 1 .Dt SU 1
.Os .Os
.Sh NAME .Sh NAME
@ -41,6 +41,7 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl Kflm .Op Fl Kflm
.Op Fl c Ar login-class
.Op Ar login Op Ar "shell arguments" .Op Ar login Op Ar "shell arguments"
.Sh DESCRIPTION .Sh DESCRIPTION
.Nm .Nm
@ -89,6 +90,9 @@ The options are as follows:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Fl K .It Fl K
Do not attempt to use Kerberos to authenticate the user. Do not attempt to use Kerberos to authenticate the user.
.It Fl c
Specify a login class.
You may only override the default class if you're already root.
.It Fl f .It Fl f
If the invoked shell is If the invoked shell is
.Xr csh 1 , .Xr csh 1 ,
@ -112,7 +116,11 @@ are modified as above.
is set to the target login. is set to the target login.
.Ev PATH .Ev PATH
is set to is set to
.Dq Pa /usr/bin:/bin:/usr/pkg/bin:/usr/local/bin . is set to the path specified in the
.Pa /etc/login.conf
file (or to the default of
.Dq Pa /usr/bin:/bin:/usr/pkg/bin:/usr/local/bin
).
.Ev TERM .Ev TERM
is imported from your current environment. is imported from your current environment.
The invoked shell is the target login's, and The invoked shell is the target login's, and
@ -171,6 +179,8 @@ to remind one of its awesome power.
.Xr skey 1 , .Xr skey 1 ,
.Xr kinit 1 , .Xr kinit 1 ,
.Xr kerberos 1 , .Xr kerberos 1 ,
.Xr setusercontext 3 ,
.Xr login.conf 5 ,
.Xr passwd 5 , .Xr passwd 5 ,
.Xr group 5 , .Xr group 5 ,
.Xr environ 7 .Xr environ 7

View File

@ -1,4 +1,4 @@
/* $NetBSD: su.c,v 1.36 1999/11/09 15:06:37 drochner Exp $ */ /* $NetBSD: su.c,v 1.37 2000/01/14 02:39:14 mjl Exp $ */
/* /*
* Copyright (c) 1988 The Regents of the University of California. * Copyright (c) 1988 The Regents of the University of California.
@ -44,7 +44,7 @@ __COPYRIGHT(
#if 0 #if 0
static char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94";*/ static char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94";*/
#else #else
__RCSID("$NetBSD: su.c,v 1.36 1999/11/09 15:06:37 drochner Exp $"); __RCSID("$NetBSD: su.c,v 1.37 2000/01/14 02:39:14 mjl Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -67,12 +67,16 @@ __RCSID("$NetBSD: su.c,v 1.36 1999/11/09 15:06:37 drochner Exp $");
#include <tzfile.h> #include <tzfile.h>
#include <unistd.h> #include <unistd.h>
#ifdef LOGIN_CAP
#include <login_cap.h>
#endif
#ifdef KERBEROS #ifdef KERBEROS
#include <kerberosIV/des.h> #include <kerberosIV/des.h>
#include <kerberosIV/krb.h> #include <kerberosIV/krb.h>
#include <netdb.h> #include <netdb.h>
#define ARGSTR "-Kflm" #define ARGSTRX "-Kflm"
int use_kerberos = 1; int use_kerberos = 1;
@ -80,13 +84,19 @@ static int kerberos __P((char *, char *, int));
static int koktologin __P((char *, char *, char *)); static int koktologin __P((char *, char *, char *));
#else #else
#define ARGSTR "-flm" #define ARGSTRX "-flm"
#endif #endif
#ifndef SUGROUP #ifndef SUGROUP
#define SUGROUP "wheel" #define SUGROUP "wheel"
#endif #endif
#ifdef LOGIN_CAP
#define ARGSTR ARGSTRX "c:"
#else
#define ARGSTR ARGSTRX
#endif
int main __P((int, char **)); int main __P((int, char **));
static int chshell __P((const char *)); static int chshell __P((const char *));
@ -110,17 +120,26 @@ main(argc, argv)
int asme, ch, asthem, fastlogin, prio; int asme, ch, asthem, fastlogin, prio;
enum { UNSET, YES, NO } iscsh = UNSET; enum { UNSET, YES, NO } iscsh = UNSET;
char *user, *shell, *avshell, *username, **np; char *user, *shell, *avshell, *username, **np;
char *userpass; char *userpass, *class;
char shellbuf[MAXPATHLEN], avshellbuf[MAXPATHLEN]; char shellbuf[MAXPATHLEN], avshellbuf[MAXPATHLEN];
time_t pw_warntime = _PASSWORD_WARNDAYS * SECSPERDAY;
#ifdef LOGIN_CAP
login_cap_t *lc;
#endif
asme = asthem = fastlogin = 0; asme = asthem = fastlogin = 0;
shell = NULL; shell = class = NULL;
while ((ch = getopt(argc, argv, ARGSTR)) != -1) while ((ch = getopt(argc, argv, ARGSTR)) != -1)
switch((char)ch) { switch((char)ch) {
#ifdef KERBEROS #ifdef KERBEROS
case 'K': case 'K':
use_kerberos = 0; use_kerberos = 0;
break; break;
#endif
#ifdef LOGIN_CAP
case 'c':
class = optarg;
break;
#endif #endif
case 'f': case 'f':
fastlogin = 1; fastlogin = 1;
@ -163,6 +182,7 @@ main(argc, argv)
if (username == NULL || userpass == NULL) if (username == NULL || userpass == NULL)
err(1, "strdup"); err(1, "strdup");
if (asme) { if (asme) {
if (pwd->pw_shell && *pwd->pw_shell) { if (pwd->pw_shell && *pwd->pw_shell) {
shell = strncpy(shellbuf, pwd->pw_shell, shell = strncpy(shellbuf, pwd->pw_shell,
@ -179,6 +199,22 @@ main(argc, argv)
if ((pwd = getpwnam(user)) == NULL) if ((pwd = getpwnam(user)) == NULL)
errx(1, "unknown login %s", user); errx(1, "unknown login %s", user);
#ifdef LOGIN_CAP
/* force the usage of specified class */
if (class) {
if (ruid)
errx(1, "Only root may use -c");
pwd->pw_class = class;
}
lc = login_getclass(pwd->pw_class);
pw_warntime = login_getcaptime(lc, "password-warn",
_PASSWORD_WARNDAYS * SECSPERDAY,
_PASSWORD_WARNDAYS * SECSPERDAY);
#endif
if (ruid if (ruid
#ifdef KERBEROS #ifdef KERBEROS
&& (!use_kerberos || kerberos(username, user, pwd->pw_uid)) && (!use_kerberos || kerberos(username, user, pwd->pw_uid))
@ -280,6 +316,7 @@ badlogin:
if (iscsh == UNSET) if (iscsh == UNSET)
iscsh = strstr(avshell, "csh") ? YES : NO; iscsh = strstr(avshell, "csh") ? YES : NO;
#ifndef LOGIN_CAP /* This is done by setusercontext() */
/* set permissions */ /* set permissions */
if (setgid(pwd->pw_gid) < 0) if (setgid(pwd->pw_gid) < 0)
err(1, "setgid"); err(1, "setgid");
@ -287,6 +324,7 @@ badlogin:
errx(1, "initgroups failed"); errx(1, "initgroups failed");
if (setuid(pwd->pw_uid) < 0) if (setuid(pwd->pw_uid) < 0)
err(1, "setuid"); err(1, "setuid");
#endif
if (!asme) { if (!asme) {
if (asthem) { if (asthem) {
@ -295,12 +333,24 @@ badlogin:
if ((environ = malloc(sizeof(char *))) == NULL) if ((environ = malloc(sizeof(char *))) == NULL)
err(1, NULL); err(1, NULL);
environ[0] = NULL; environ[0] = NULL;
#ifdef LOGIN_CAP
if (setusercontext(lc,
pwd, pwd->pw_uid, LOGIN_SETPATH))
err(1, "setting user context");
#else
(void)setenv("PATH", _PATH_DEFPATH, 1); (void)setenv("PATH", _PATH_DEFPATH, 1);
#endif
if (p) if (p)
(void)setenv("TERM", p, 1); (void)setenv("TERM", p, 1);
if (chdir(pwd->pw_dir) < 0) if (chdir(pwd->pw_dir) < 0)
errx(1, "no directory"); errx(1, "no directory");
} }
#ifdef LOGIN_CAP
else if (pwd->pw_uid == 0)
if (setusercontext(lc,
pwd, pwd->pw_uid, LOGIN_SETPATH|LOGIN_SETUMASK))
err(1, "setting path");
#endif
if (asthem || pwd->pw_uid) if (asthem || pwd->pw_uid)
(void)setenv("USER", pwd->pw_name, 1); (void)setenv("USER", pwd->pw_name, 1);
(void)setenv("HOME", pwd->pw_dir, 1); (void)setenv("HOME", pwd->pw_dir, 1);
@ -335,8 +385,7 @@ badlogin:
(ruid ? "Sorry" : "Note"), user); (ruid ? "Sorry" : "Note"), user);
if (ruid != 0) if (ruid != 0)
exit(1); exit(1);
} else if (pwd->pw_change - tp.tv_sec < } else if (pwd->pw_change - tp.tv_sec < pw_warntime)
_PASSWORD_WARNDAYS * SECSPERDAY)
(void)printf("Warning: %s's password expires on %s", (void)printf("Warning: %s's password expires on %s",
user, ctime(&pwd->pw_change)); user, ctime(&pwd->pw_change));
} }
@ -357,6 +406,12 @@ badlogin:
username, pwd->pw_name, ontty()); username, pwd->pw_name, ontty());
(void)setpriority(PRIO_PROCESS, 0, prio); (void)setpriority(PRIO_PROCESS, 0, prio);
#ifdef LOGIN_CAP
if (setusercontext(lc, pwd, pwd->pw_uid,
(asthem ? (LOGIN_SETPRIORITY | LOGIN_SETUMASK) : 0) |
LOGIN_SETRESOURCES | LOGIN_SETGROUP | LOGIN_SETUSER))
err(1, "setting user context");
#endif
execv(shell, np); execv(shell, np);
err(1, "%s", shell); err(1, "%s", shell);