Better integrate kerberos into su so that if an incorrect Kerberos

password is entered, the user is not prompted for a password a second
time.

This closes pr-bin/1006.
This commit is contained in:
Mark Murray 1996-03-09 14:57:43 +00:00
parent 0a2c4bde08
commit 5a453b0ef3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=14440
2 changed files with 53 additions and 32 deletions

View File

@ -7,6 +7,7 @@ COPTS+= -DSKEY
.if defined(WHEELSU)
COPTS+= -DWHEELSU
.endif
CFLAGS+= -Wall
LDADD= -lskey -lmd -lcrypt
DPADD= ${LIBSKEY} ${LIBMD} ${LIBCRYPT}

View File

@ -32,13 +32,17 @@
*/
#ifndef lint
static char copyright[] =
static const char copyright[] =
"@(#) Copyright (c) 1988, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
/*
static char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94";
*/
static const char rcsid[] =
"$Id$";
#endif /* not lint */
#include <sys/param.h>
@ -67,6 +71,9 @@ static char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94";
#define ARGSTR "-Kflm"
static int kerberos(char *username, char *user, int uid, char *pword);
static int koktologin(char *name, char *toname);
int use_kerberos = 1;
#else
#define ARGSTR "-flm"
@ -178,23 +185,27 @@ main(argc, argv)
if (ruid) {
#ifdef KERBEROS
if (!use_kerberos || kerberos(username, user, pwd->pw_uid))
if (use_kerberos && koktologin(username, user)
&& !pwd->pw_uid)
errx(1, "kerberos: not in %s's ACL.", user);
else
#endif
{
/* only allow those in group zero to su to root. */
if (pwd->pw_uid == 0 && (gr = getgrgid((gid_t)0)))
for (g = gr->gr_mem;; ++g) {
if (!*g)
errx(1,
{
/* only allow those in group zero to su to root. */
if (pwd->pw_uid == 0 && (gr = getgrgid((gid_t)0)))
for (g = gr->gr_mem;; ++g) {
if (!*g)
errx(1,
"you are not in the correct group to su %s.",
user);
if (strcmp(username, *g) == 0) {
user);
if (strcmp(username, *g) == 0) {
#ifdef WHEELSU
iswheelsu = 1;
iswheelsu = 1;
#endif /* WHEELSU */
break;
break;
}
}
}
}
/* if target requires a password, verify it */
if (*pwd->pw_passwd) {
#ifdef SKEY
@ -216,11 +227,18 @@ main(argc, argv)
p = getpass("Password:");
if (strcmp(pwd->pw_passwd, crypt(p, pwd->pw_passwd))) {
#endif
fprintf(stderr, "Sorry\n");
syslog(LOG_AUTH|LOG_WARNING,
"BAD SU %s to %s%s", username,
user, ontty());
exit(1);
#ifdef KERBEROS
if (use_kerberos &&
kerberos(username, user, pwd->pw_uid, p)
)
#endif
{
fprintf(stderr, "Sorry\n");
syslog(LOG_AUTH|LOG_WARNING,
"BAD SU %s to %s%s", username,
user, ontty());
exit(1);
}
}
#ifdef WHEELSU
if (iswheelsu) {
@ -235,7 +253,6 @@ main(argc, argv)
user, ontty());
exit(1);
}
}
}
if (asme) {
@ -252,7 +269,8 @@ main(argc, argv)
/* if we're forking a csh, we want to slightly muck the args */
if (iscsh == UNSET) {
if (p = strrchr(shell, '/'))
p = strrchr(shell, '/');
if (p)
++p;
else
p = shell;
@ -323,21 +341,22 @@ ontty()
static char buf[MAXPATHLEN + 4];
buf[0] = 0;
if (p = ttyname(STDERR_FILENO))
p = ttyname(STDERR_FILENO);
if (p)
snprintf(buf, sizeof(buf), " on %s", p);
return (buf);
}
#ifdef KERBEROS
kerberos(username, user, uid)
int
kerberos(username, user, uid, pword)
char *username, *user;
int uid;
char *pword;
{
extern char *krb_err_txt[];
KTEXT_ST ticket;
AUTH_DAT authdata;
struct hostent *hp;
char *p;
int kerno;
u_long faddr;
struct sockaddr_in local_addr;
@ -347,11 +366,8 @@ kerberos(username, user, uid)
if (krb_get_lrealm(lrealm, 1) != KSUCCESS)
return (1);
if (koktologin(username, lrealm, user) && !uid) {
warnx("kerberos: not in %s's ACL.", user);
return (1);
}
(void)sprintf(krbtkfile, "%s_%s_%d", TKT_ROOT, user, getuid());
(void)sprintf(krbtkfile, "%s_%s_%lu", TKT_ROOT, user,
(unsigned long)getuid());
(void)setenv("KRBTKFILE", krbtkfile, 1);
(void)krb_set_tkt_string(krbtkfile);
@ -376,7 +392,7 @@ kerberos(username, user, uid)
*/
kerno = krb_get_pw_in_tkt((uid == 0 ? username : user),
(uid == 0 ? "root" : ""), lrealm,
"krbtgt", lrealm, DEFAULT_TKT_LIFE, 0);
"krbtgt", lrealm, DEFAULT_TKT_LIFE, pword);
if (kerno != KSUCCESS) {
if (kerno == KDC_PR_UNKNOWN) {
@ -445,12 +461,16 @@ kerberos(username, user, uid)
return (0);
}
koktologin(name, realm, toname)
char *name, *realm, *toname;
int
koktologin(name, toname)
char *name, *toname;
{
AUTH_DAT *kdata;
AUTH_DAT kdata_st;
char realm[REALM_SZ];
if (krb_get_lrealm(realm, 1) != KSUCCESS)
return (1);
kdata = &kdata_st;
memset((char *)kdata, 0, sizeof(*kdata));
(void)strcpy(kdata->pname, name);