From e6ac440ed4de6debcb6f5514cdb32acbf4b4e982 Mon Sep 17 00:00:00 2001 From: mjl Date: Fri, 14 Jan 2000 02:39:14 +0000 Subject: [PATCH] Implement login_cap capability lookup. --- usr.bin/su/Makefile | 5 ++-- usr.bin/su/su.1 | 16 ++++++++-- usr.bin/su/su.c | 73 +++++++++++++++++++++++++++++++++++++++------ 3 files changed, 80 insertions(+), 14 deletions(-) diff --git a/usr.bin/su/Makefile b/usr.bin/su/Makefile index 8ea6658627e2..8d1aaec0ff87 100644 --- a/usr.bin/su/Makefile +++ b/usr.bin/su/Makefile @@ -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 SRCTOP= ../.. @@ -6,10 +6,11 @@ SRCTOP= ../.. PROG= su DPADD+= ${LIBCRYPT} -LDADD+= -lcrypt +LDADD+= -lcrypt -lutil BINOWN= root BINMODE=4555 INSTALLFLAGS=-fschg +CPPFLAGS+=-DLOGIN_CAP # Uncomment the following line to change the group that may su root to "sugroup" # diff --git a/usr.bin/su/su.1 b/usr.bin/su/su.1 index b166fb8eac8e..a61b7e7d0e98 100644 --- a/usr.bin/su/su.1 +++ b/usr.bin/su/su.1 @@ -30,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" 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 .Os .Sh NAME @@ -41,6 +41,7 @@ .Sh SYNOPSIS .Nm .Op Fl Kflm +.Op Fl c Ar login-class .Op Ar login Op Ar "shell arguments" .Sh DESCRIPTION .Nm @@ -89,6 +90,9 @@ The options are as follows: .Bl -tag -width Ds .It Fl K 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 If the invoked shell is .Xr csh 1 , @@ -112,7 +116,11 @@ are modified as above. is set to the target login. .Ev PATH 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 is imported from your current environment. The invoked shell is the target login's, and @@ -171,6 +179,8 @@ to remind one of its awesome power. .Xr skey 1 , .Xr kinit 1 , .Xr kerberos 1 , +.Xr setusercontext 3 , +.Xr login.conf 5 , .Xr passwd 5 , .Xr group 5 , .Xr environ 7 diff --git a/usr.bin/su/su.c b/usr.bin/su/su.c index b27f89e50ca3..c769cfd025d2 100644 --- a/usr.bin/su/su.c +++ b/usr.bin/su/su.c @@ -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. @@ -44,7 +44,7 @@ __COPYRIGHT( #if 0 static char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94";*/ #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 /* not lint */ @@ -67,12 +67,16 @@ __RCSID("$NetBSD: su.c,v 1.36 1999/11/09 15:06:37 drochner Exp $"); #include #include +#ifdef LOGIN_CAP +#include +#endif + #ifdef KERBEROS #include #include #include -#define ARGSTR "-Kflm" +#define ARGSTRX "-Kflm" int use_kerberos = 1; @@ -80,13 +84,19 @@ static int kerberos __P((char *, char *, int)); static int koktologin __P((char *, char *, char *)); #else -#define ARGSTR "-flm" +#define ARGSTRX "-flm" #endif #ifndef SUGROUP #define SUGROUP "wheel" #endif +#ifdef LOGIN_CAP +#define ARGSTR ARGSTRX "c:" +#else +#define ARGSTR ARGSTRX +#endif + int main __P((int, char **)); static int chshell __P((const char *)); @@ -110,17 +120,26 @@ main(argc, argv) int asme, ch, asthem, fastlogin, prio; enum { UNSET, YES, NO } iscsh = UNSET; char *user, *shell, *avshell, *username, **np; - char *userpass; + char *userpass, *class; char shellbuf[MAXPATHLEN], avshellbuf[MAXPATHLEN]; + time_t pw_warntime = _PASSWORD_WARNDAYS * SECSPERDAY; +#ifdef LOGIN_CAP + login_cap_t *lc; +#endif asme = asthem = fastlogin = 0; - shell = NULL; + shell = class = NULL; while ((ch = getopt(argc, argv, ARGSTR)) != -1) switch((char)ch) { #ifdef KERBEROS case 'K': use_kerberos = 0; break; +#endif +#ifdef LOGIN_CAP + case 'c': + class = optarg; + break; #endif case 'f': fastlogin = 1; @@ -163,6 +182,7 @@ main(argc, argv) if (username == NULL || userpass == NULL) err(1, "strdup"); + if (asme) { if (pwd->pw_shell && *pwd->pw_shell) { shell = strncpy(shellbuf, pwd->pw_shell, @@ -179,6 +199,22 @@ main(argc, argv) if ((pwd = getpwnam(user)) == NULL) 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 #ifdef KERBEROS && (!use_kerberos || kerberos(username, user, pwd->pw_uid)) @@ -280,6 +316,7 @@ badlogin: if (iscsh == UNSET) iscsh = strstr(avshell, "csh") ? YES : NO; +#ifndef LOGIN_CAP /* This is done by setusercontext() */ /* set permissions */ if (setgid(pwd->pw_gid) < 0) err(1, "setgid"); @@ -287,6 +324,7 @@ badlogin: errx(1, "initgroups failed"); if (setuid(pwd->pw_uid) < 0) err(1, "setuid"); +#endif if (!asme) { if (asthem) { @@ -295,12 +333,24 @@ badlogin: if ((environ = malloc(sizeof(char *))) == NULL) err(1, 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); +#endif if (p) (void)setenv("TERM", p, 1); if (chdir(pwd->pw_dir) < 0) 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) (void)setenv("USER", pwd->pw_name, 1); (void)setenv("HOME", pwd->pw_dir, 1); @@ -335,8 +385,7 @@ badlogin: (ruid ? "Sorry" : "Note"), user); if (ruid != 0) exit(1); - } else if (pwd->pw_change - tp.tv_sec < - _PASSWORD_WARNDAYS * SECSPERDAY) + } else if (pwd->pw_change - tp.tv_sec < pw_warntime) (void)printf("Warning: %s's password expires on %s", user, ctime(&pwd->pw_change)); } @@ -357,6 +406,12 @@ badlogin: username, pwd->pw_name, ontty()); (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); err(1, "%s", shell);