su.c revision 21646
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1988, 1993, 1994 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 3514440Smarkmstatic const char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1988, 1993, 1994\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 381590Srgrimes#endif /* not lint */ 391590Srgrimes 401590Srgrimes#ifndef lint 4114440Smarkm/* 421590Srgrimesstatic char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94"; 4314440Smarkm*/ 4414440Smarkmstatic const char rcsid[] = 4521646Sdavidn "$Id: su.c,v 1.14 1996/10/07 10:00:58 joerg Exp $"; 461590Srgrimes#endif /* not lint */ 471590Srgrimes 481590Srgrimes#include <sys/param.h> 491590Srgrimes#include <sys/time.h> 501590Srgrimes#include <sys/resource.h> 511590Srgrimes 521590Srgrimes#include <err.h> 531590Srgrimes#include <errno.h> 541590Srgrimes#include <grp.h> 551590Srgrimes#include <paths.h> 561590Srgrimes#include <pwd.h> 571590Srgrimes#include <stdio.h> 581590Srgrimes#include <stdlib.h> 591590Srgrimes#include <string.h> 601590Srgrimes#include <syslog.h> 611590Srgrimes#include <unistd.h> 621590Srgrimes 6321646Sdavidn#ifdef LOGIN_CAP 6421646Sdavidn#include <login_cap.h> 6521646Sdavidn#ifdef LOGIN_CAP_AUTH 6621646Sdavidn#undef SKEY 6721646Sdavidn#undef KERBEROS 6821646Sdavidn#endif 6921646Sdavidn#endif 7021646Sdavidn 713702Spst#ifdef SKEY 723702Spst#include <skey.h> 733702Spst#endif 743702Spst 751590Srgrimes#ifdef KERBEROS 7614024Smarkm#include <des.h> 771590Srgrimes#include <kerberosIV/krb.h> 781590Srgrimes#include <netdb.h> 791590Srgrimes 801590Srgrimes#define ARGSTR "-Kflm" 811590Srgrimes 8214440Smarkmstatic int kerberos(char *username, char *user, int uid, char *pword); 8314440Smarkmstatic int koktologin(char *name, char *toname); 8414440Smarkm 851590Srgrimesint use_kerberos = 1; 8621646Sdavidn#else /* !KERBEROS */ 871590Srgrimes#define ARGSTR "-flm" 8821646Sdavidn#endif /* KERBEROS */ 891590Srgrimes 901590Srgrimeschar *ontty __P((void)); 911590Srgrimesint chshell __P((char *)); 921590Srgrimes 931590Srgrimesint 941590Srgrimesmain(argc, argv) 951590Srgrimes int argc; 961590Srgrimes char **argv; 971590Srgrimes{ 981590Srgrimes extern char **environ; 991590Srgrimes struct passwd *pwd; 1009502Swollman#ifdef WHEELSU 1019502Swollman char *targetpass; 1029502Swollman int iswheelsu; 1039502Swollman#endif /* WHEELSU */ 10410586Sjoerg char *p, **g, *user, *shell, *username, *cleanenv[20], **nargv, **np; 1051590Srgrimes struct group *gr; 1061590Srgrimes uid_t ruid; 10710586Sjoerg int asme, ch, asthem, fastlogin, prio, i; 1081590Srgrimes enum { UNSET, YES, NO } iscsh = UNSET; 10921646Sdavidn#ifdef LOGIN_CAP 11021646Sdavidn login_cap_t *lc; 11121646Sdavidn int setwhat; 11221646Sdavidn#ifdef LOGIN_CAP_AUTH 11321646Sdavidn char *style, *approvep, *auth_method = NULL; 11421646Sdavidn#endif 11521646Sdavidn#endif 1161590Srgrimes char shellbuf[MAXPATHLEN]; 1171590Srgrimes 1189502Swollman#ifdef WHEELSU 1199502Swollman iswheelsu = 1209502Swollman#endif /* WHEELSU */ 1211590Srgrimes asme = asthem = fastlogin = 0; 12210586Sjoerg user = "root"; 12310586Sjoerg while(optind < argc) 12410586Sjoerg if((ch = getopt(argc, argv, ARGSTR)) != EOF) 1251590Srgrimes switch((char)ch) { 1261590Srgrimes#ifdef KERBEROS 1271590Srgrimes case 'K': 1281590Srgrimes use_kerberos = 0; 1291590Srgrimes break; 1301590Srgrimes#endif 1311590Srgrimes case 'f': 1321590Srgrimes fastlogin = 1; 1331590Srgrimes break; 1341590Srgrimes case '-': 1351590Srgrimes case 'l': 1361590Srgrimes asme = 0; 1371590Srgrimes asthem = 1; 1381590Srgrimes break; 1391590Srgrimes case 'm': 1401590Srgrimes asme = 1; 1411590Srgrimes asthem = 0; 1421590Srgrimes break; 1431590Srgrimes case '?': 1441590Srgrimes default: 1451590Srgrimes (void)fprintf(stderr, "usage: su [%s] [login]\n", 14610586Sjoerg ARGSTR); 1471590Srgrimes exit(1); 14810586Sjoerg } 14910586Sjoerg else 15010586Sjoerg { 15110586Sjoerg user = argv[optind++]; 15210586Sjoerg break; 15310586Sjoerg } 15410586Sjoerg 15510586Sjoerg if((nargv = malloc (sizeof (char *) * (argc + 4))) == NULL) { 15610586Sjoerg errx(1, "malloc failure"); 15710586Sjoerg } 15810586Sjoerg 15910586Sjoerg nargv[argc + 3] = NULL; 16010586Sjoerg for (i = argc; i >= optind; i--) 16110586Sjoerg nargv[i + 3] = argv[i]; 16210586Sjoerg np = &nargv[i + 3]; 16310586Sjoerg 1641590Srgrimes argv += optind; 1651590Srgrimes 1661590Srgrimes errno = 0; 1671590Srgrimes prio = getpriority(PRIO_PROCESS, 0); 1681590Srgrimes if (errno) 1691590Srgrimes prio = 0; 1701590Srgrimes (void)setpriority(PRIO_PROCESS, 0, -2); 1711590Srgrimes openlog("su", LOG_CONS, 0); 1721590Srgrimes 1731590Srgrimes /* get current login name and shell */ 1741590Srgrimes ruid = getuid(); 1751590Srgrimes username = getlogin(); 1761590Srgrimes if (username == NULL || (pwd = getpwnam(username)) == NULL || 1771590Srgrimes pwd->pw_uid != ruid) 1781590Srgrimes pwd = getpwuid(ruid); 1791590Srgrimes if (pwd == NULL) 1801590Srgrimes errx(1, "who are you?"); 1811590Srgrimes username = strdup(pwd->pw_name); 1821590Srgrimes if (username == NULL) 1831590Srgrimes err(1, NULL); 18421646Sdavidn if (asme) { 18521646Sdavidn if (pwd->pw_shell != NULL && *pwd->pw_shell != '\0') { 18621646Sdavidn /* copy: pwd memory is recycled */ 18721646Sdavidn shell = strncpy(shellbuf, pwd->pw_shell, sizeof shellbuf); 18821646Sdavidn shellbuf[sizeof shellbuf - 1] = '\0'; 18921646Sdavidn } else { 1901590Srgrimes shell = _PATH_BSHELL; 1911590Srgrimes iscsh = NO; 1921590Srgrimes } 19321646Sdavidn } 1941590Srgrimes 19521646Sdavidn#ifdef LOGIN_CAP_AUTH 19621646Sdavidn if (auth_method = strchr(user, ':')) { 19721646Sdavidn *auth_method = '\0'; 19821646Sdavidn auth_method++; 19921646Sdavidn if (*auth_method == '\0') 20021646Sdavidn auth_method = NULL; 20121646Sdavidn } 20221646Sdavidn#endif /* !LOGIN_CAP_AUTH */ 20321646Sdavidn 2041590Srgrimes /* get target login information, default to root */ 2051590Srgrimes if ((pwd = getpwnam(user)) == NULL) { 2069502Swollman errx(1, "unknown login: %s", user); 2071590Srgrimes } 20821646Sdavidn#ifdef LOGIN_CAP 20921646Sdavidn lc = login_getclass(pwd); 21021646Sdavidn#endif 2111590Srgrimes 2129502Swollman#ifdef WHEELSU 2139502Swollman targetpass = strdup(pwd->pw_passwd); 2149502Swollman#endif /* WHEELSU */ 2159502Swollman 2161590Srgrimes if (ruid) { 2171590Srgrimes#ifdef KERBEROS 21814440Smarkm if (use_kerberos && koktologin(username, user) 21914572Smarkm && !pwd->pw_uid) { 22014572Smarkm warnx("kerberos: not in %s's ACL.", user); 22114572Smarkm use_kerberos = 0; 22214572Smarkm } 2231590Srgrimes#endif 22414440Smarkm { 22514440Smarkm /* only allow those in group zero to su to root. */ 22614440Smarkm if (pwd->pw_uid == 0 && (gr = getgrgid((gid_t)0))) 22714440Smarkm for (g = gr->gr_mem;; ++g) { 22814440Smarkm if (!*g) 22914440Smarkm errx(1, 2301590Srgrimes "you are not in the correct group to su %s.", 23114440Smarkm user); 23214440Smarkm if (strcmp(username, *g) == 0) { 2339502Swollman#ifdef WHEELSU 23414440Smarkm iswheelsu = 1; 2359502Swollman#endif /* WHEELSU */ 23614440Smarkm break; 23714440Smarkm } 2389502Swollman } 23914440Smarkm } 2401590Srgrimes /* if target requires a password, verify it */ 2411590Srgrimes if (*pwd->pw_passwd) { 24221646Sdavidn#ifdef LOGIN_CAP_AUTH 24321646Sdavidn /* 24421646Sdavidn * This hands off authorisation to an authorisation program, 24521646Sdavidn * depending on the styles available for the "auth-su", 24621646Sdavidn * authorisation styles. 24721646Sdavidn */ 24821646Sdavidn if ((style = login_getstyle(lc, auth_method, "su")) == NULL) 24921646Sdavidn errx(1, "auth method available for su.\n"); 25021646Sdavidn if (authenticate(user, lc ? lc->lc_class : "default", style, "su") != 0) { 25121646Sdavidn#ifdef WHEELSU 25221646Sdavidn if (!iswheelsu || authenticate(username, lc ? lc->lc_class : "default", style, "su") != 0) { 25321646Sdavidn#endif /* WHEELSU */ 25421646Sdavidn { 25521646Sdavidn fprintf(stderr, "Sorry\n"); 25621646Sdavidn syslog(LOG_AUTH|LOG_WARNING,"BAD SU %s to %s%s", username, user, ontty()); 25721646Sdavidn exit(1); 25821646Sdavidn } 25921646Sdavidn } 26021646Sdavidn 26121646Sdavidn /* 26221646Sdavidn * If authentication succeeds, run any approval 26321646Sdavidn * program, if applicable for this class. 26421646Sdavidn */ 26521646Sdavidn approvep = login_getcapstr(lc, "approve", NULL, NULL); 26621646Sdavidn if (approvep==NULL || auth_script(approvep, approvep, username, lc->lc_class, 0) == 0) { 26721646Sdavidn int r = auth_scan(AUTH_OKAY); 26821646Sdavidn /* See what the authorise program says */ 26921646Sdavidn if (!(r & AUTH_ROOTOKAY) && pwd->pw_uid == 0) { 27021646Sdavidn fprintf(stderr, "Sorry\n"); 27121646Sdavidn syslog(LOG_AUTH|LOG_WARNING,"UNAPPROVED ROOT SU %s%s", user, ontty()); 27221646Sdavidn exit(1); 27321646Sdavidn } 27421646Sdavidn } 27521646Sdavidn#else /* !LOGIN_CAP_AUTH */ 2763208Spst#ifdef SKEY 2779502Swollman#ifdef WHEELSU 2789502Swollman if (iswheelsu) { 2799502Swollman pwd = getpwnam(username); 2809502Swollman } 2819502Swollman#endif /* WHEELSU */ 2823208Spst p = skey_getpass("Password:", pwd, 1); 28321646Sdavidn if (!(!strcmp(pwd->pw_passwd, skey_crypt(p, pwd->pw_passwd, pwd, 1)) 2849502Swollman#ifdef WHEELSU 28521646Sdavidn || (iswheelsu && !strcmp(targetpass, crypt(p,targetpass))) 2869502Swollman#endif /* WHEELSU */ 2879502Swollman )) { 2883208Spst#else 2891590Srgrimes p = getpass("Password:"); 2901590Srgrimes if (strcmp(pwd->pw_passwd, crypt(p, pwd->pw_passwd))) { 2913208Spst#endif 29214440Smarkm#ifdef KERBEROS 29321646Sdavidn if (!use_kerberos || (use_kerberos && kerberos(username, user, pwd->pw_uid, p))) 29414440Smarkm#endif 29514440Smarkm { 29614440Smarkm fprintf(stderr, "Sorry\n"); 29721646Sdavidn syslog(LOG_AUTH|LOG_WARNING, "BAD SU %s to %s%s", username, user, ontty()); 29814440Smarkm exit(1); 29914440Smarkm } 3001590Srgrimes } 3019502Swollman#ifdef WHEELSU 3029502Swollman if (iswheelsu) { 3039502Swollman pwd = getpwnam(user); 3049502Swollman } 3059502Swollman#endif /* WHEELSU */ 30621646Sdavidn#endif /* LOGIN_CAP_AUTH */ 3071590Srgrimes } 30810401Smpp if (pwd->pw_expire && time(NULL) >= pwd->pw_expire) { 30910401Smpp fprintf(stderr, "Sorry - account expired\n"); 31010401Smpp syslog(LOG_AUTH|LOG_WARNING, 31110401Smpp "BAD SU %s to %s%s", username, 31210401Smpp user, ontty()); 31310401Smpp exit(1); 31410401Smpp } 3151590Srgrimes } 3161590Srgrimes 3171590Srgrimes if (asme) { 3181590Srgrimes /* if asme and non-standard target shell, must be root */ 3191590Srgrimes if (!chshell(pwd->pw_shell) && ruid) 3201590Srgrimes errx(1, "permission denied (shell)."); 3211590Srgrimes } else if (pwd->pw_shell && *pwd->pw_shell) { 3221590Srgrimes shell = pwd->pw_shell; 3231590Srgrimes iscsh = UNSET; 3241590Srgrimes } else { 3251590Srgrimes shell = _PATH_BSHELL; 3261590Srgrimes iscsh = NO; 3271590Srgrimes } 3281590Srgrimes 3291590Srgrimes /* if we're forking a csh, we want to slightly muck the args */ 3301590Srgrimes if (iscsh == UNSET) { 33114440Smarkm p = strrchr(shell, '/'); 33214440Smarkm if (p) 3331590Srgrimes ++p; 3341590Srgrimes else 3351590Srgrimes p = shell; 3367641Sjkh if ((iscsh = strcmp(p, "csh") ? NO : YES) == NO) 3377641Sjkh iscsh = strcmp(p, "tcsh") ? NO : YES; 3381590Srgrimes } 3391590Srgrimes 34021646Sdavidn (void)setpriority(PRIO_PROCESS, 0, prio); 34121646Sdavidn 34221646Sdavidn#ifdef LOGIN_CAP 34321646Sdavidn /* Set everything now except the environment & umask */ 34421646Sdavidn setwhat = LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUMASK|LOGIN_SETENV); 34521646Sdavidn /* 34621646Sdavidn * Don't touch resource/priority settings if -m has been 34721646Sdavidn * used or -l hasn't, and we're not su'ing to root. 34821646Sdavidn */ 34921646Sdavidn if ((asme || !asthem) && pwd->pw_uid) 35021646Sdavidn setwhat &= ~(LOGIN_SETPRIORITY|~LOGIN_SETRESOURCES); 35121646Sdavidn if (setusercontext(lc, pwd, pwd->pw_uid, setwhat) < 0) 35221646Sdavidn err(1, "setusercontext"); 35321646Sdavidn#else 3541590Srgrimes /* set permissions */ 3551590Srgrimes if (setgid(pwd->pw_gid) < 0) 3561590Srgrimes err(1, "setgid"); 3571590Srgrimes if (initgroups(user, pwd->pw_gid)) 3581590Srgrimes errx(1, "initgroups failed"); 3591590Srgrimes if (setuid(pwd->pw_uid) < 0) 3601590Srgrimes err(1, "setuid"); 36121646Sdavidn#endif 3621590Srgrimes 3631590Srgrimes if (!asme) { 3641590Srgrimes if (asthem) { 3651590Srgrimes p = getenv("TERM"); 3664563Sats cleanenv[0] = NULL; 3671590Srgrimes environ = cleanenv; 36821646Sdavidn#ifdef LOGIN_CAP 36921646Sdavidn /* set the su'd user's environment & umask */ 37021646Sdavidn setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETPATH|LOGIN_SETUMASK|LOGIN_SETENV); 37121646Sdavidn#else 3724563Sats (void)setenv("PATH", _PATH_DEFPATH, 1); 37321646Sdavidn#endif 37418789Sjoerg if (p) 37518789Sjoerg (void)setenv("TERM", p, 1); 3761590Srgrimes if (chdir(pwd->pw_dir) < 0) 3771590Srgrimes errx(1, "no directory"); 3781590Srgrimes } 3791590Srgrimes if (asthem || pwd->pw_uid) 3801590Srgrimes (void)setenv("USER", pwd->pw_name, 1); 3811590Srgrimes (void)setenv("HOME", pwd->pw_dir, 1); 3821590Srgrimes (void)setenv("SHELL", shell, 1); 3831590Srgrimes } 3841590Srgrimes if (iscsh == YES) { 3851590Srgrimes if (fastlogin) 3861590Srgrimes *np-- = "-f"; 3871590Srgrimes if (asme) 3881590Srgrimes *np-- = "-m"; 3891590Srgrimes } 3901590Srgrimes 3911590Srgrimes /* csh strips the first character... */ 3921590Srgrimes *np = asthem ? "-su" : iscsh == YES ? "_su" : "su"; 3931590Srgrimes 3941590Srgrimes if (ruid != 0) 3951590Srgrimes syslog(LOG_NOTICE|LOG_AUTH, "%s to %s%s", 3961590Srgrimes username, user, ontty()); 3971590Srgrimes 39821646Sdavidn login_close(lc); 3991590Srgrimes 4001590Srgrimes execv(shell, np); 4011590Srgrimes err(1, "%s", shell); 4021590Srgrimes} 4031590Srgrimes 4041590Srgrimesint 4051590Srgrimeschshell(sh) 4061590Srgrimes char *sh; 4071590Srgrimes{ 40821646Sdavidn int r = 0; 4091590Srgrimes char *cp; 4101590Srgrimes 41121646Sdavidn setusershell(); 41221646Sdavidn while (!r && (cp = getusershell()) != NULL) 41321646Sdavidn r = strcmp(cp, sh) == 0; 41421646Sdavidn endusershell(); 41521646Sdavidn return r; 4161590Srgrimes} 4171590Srgrimes 4181590Srgrimeschar * 4191590Srgrimesontty() 4201590Srgrimes{ 4211590Srgrimes char *p; 4221590Srgrimes static char buf[MAXPATHLEN + 4]; 4231590Srgrimes 4241590Srgrimes buf[0] = 0; 42514440Smarkm p = ttyname(STDERR_FILENO); 42614440Smarkm if (p) 4271590Srgrimes snprintf(buf, sizeof(buf), " on %s", p); 4281590Srgrimes return (buf); 4291590Srgrimes} 4301590Srgrimes 4311590Srgrimes#ifdef KERBEROS 43214440Smarkmint 43314440Smarkmkerberos(username, user, uid, pword) 4341590Srgrimes char *username, *user; 4351590Srgrimes int uid; 43614440Smarkm char *pword; 4371590Srgrimes{ 4381590Srgrimes extern char *krb_err_txt[]; 4391590Srgrimes KTEXT_ST ticket; 4401590Srgrimes AUTH_DAT authdata; 4411590Srgrimes int kerno; 4421590Srgrimes u_long faddr; 44311233Sgibbs struct sockaddr_in local_addr; 4441590Srgrimes char lrealm[REALM_SZ], krbtkfile[MAXPATHLEN]; 4451590Srgrimes char hostname[MAXHOSTNAMELEN], savehost[MAXHOSTNAMELEN]; 4461590Srgrimes char *krb_get_phost(); 4471590Srgrimes 4481590Srgrimes if (krb_get_lrealm(lrealm, 1) != KSUCCESS) 4491590Srgrimes return (1); 45014440Smarkm (void)sprintf(krbtkfile, "%s_%s_%lu", TKT_ROOT, user, 45114440Smarkm (unsigned long)getuid()); 4521590Srgrimes 4531590Srgrimes (void)setenv("KRBTKFILE", krbtkfile, 1); 4541590Srgrimes (void)krb_set_tkt_string(krbtkfile); 4551590Srgrimes /* 4561590Srgrimes * Set real as well as effective ID to 0 for the moment, 4571590Srgrimes * to make the kerberos library do the right thing. 4581590Srgrimes */ 4591590Srgrimes if (setuid(0) < 0) { 4601590Srgrimes warn("setuid"); 4611590Srgrimes return (1); 4621590Srgrimes } 4631590Srgrimes 4641590Srgrimes /* 4651590Srgrimes * Little trick here -- if we are su'ing to root, 4661590Srgrimes * we need to get a ticket for "xxx.root", where xxx represents 4671590Srgrimes * the name of the person su'ing. Otherwise (non-root case), 4681590Srgrimes * we need to get a ticket for "yyy.", where yyy represents 4691590Srgrimes * the name of the person being su'd to, and the instance is null 4701590Srgrimes * 4711590Srgrimes * We should have a way to set the ticket lifetime, 4721590Srgrimes * with a system default for root. 4731590Srgrimes */ 4741590Srgrimes kerno = krb_get_pw_in_tkt((uid == 0 ? username : user), 4751590Srgrimes (uid == 0 ? "root" : ""), lrealm, 47614440Smarkm "krbtgt", lrealm, DEFAULT_TKT_LIFE, pword); 4771590Srgrimes 4781590Srgrimes if (kerno != KSUCCESS) { 4791590Srgrimes if (kerno == KDC_PR_UNKNOWN) { 4801590Srgrimes warnx("kerberos: principal unknown: %s.%s@%s", 4811590Srgrimes (uid == 0 ? username : user), 4821590Srgrimes (uid == 0 ? "root" : ""), lrealm); 4831590Srgrimes return (1); 4841590Srgrimes } 4851590Srgrimes warnx("kerberos: unable to su: %s", krb_err_txt[kerno]); 4861590Srgrimes syslog(LOG_NOTICE|LOG_AUTH, 4871590Srgrimes "BAD Kerberos SU: %s to %s%s: %s", 4881590Srgrimes username, user, ontty(), krb_err_txt[kerno]); 4891590Srgrimes return (1); 4901590Srgrimes } 4911590Srgrimes 4921590Srgrimes if (chown(krbtkfile, uid, -1) < 0) { 4931590Srgrimes warn("chown"); 4941590Srgrimes (void)unlink(krbtkfile); 4951590Srgrimes return (1); 4961590Srgrimes } 4971590Srgrimes 4981590Srgrimes (void)setpriority(PRIO_PROCESS, 0, -2); 4991590Srgrimes 5001590Srgrimes if (gethostname(hostname, sizeof(hostname)) == -1) { 5011590Srgrimes warn("gethostname"); 5021590Srgrimes dest_tkt(); 5031590Srgrimes return (1); 5041590Srgrimes } 5051590Srgrimes 5061590Srgrimes (void)strncpy(savehost, krb_get_phost(hostname), sizeof(savehost)); 5071590Srgrimes savehost[sizeof(savehost) - 1] = '\0'; 5081590Srgrimes 5091590Srgrimes kerno = krb_mk_req(&ticket, "rcmd", savehost, lrealm, 33); 5101590Srgrimes 5111590Srgrimes if (kerno == KDC_PR_UNKNOWN) { 5121590Srgrimes warnx("Warning: TGT not verified."); 5131590Srgrimes syslog(LOG_NOTICE|LOG_AUTH, 5141590Srgrimes "%s to %s%s, TGT not verified (%s); %s.%s not registered?", 5151590Srgrimes username, user, ontty(), krb_err_txt[kerno], 5161590Srgrimes "rcmd", savehost); 5171590Srgrimes } else if (kerno != KSUCCESS) { 5181590Srgrimes warnx("Unable to use TGT: %s", krb_err_txt[kerno]); 5191590Srgrimes syslog(LOG_NOTICE|LOG_AUTH, "failed su: %s to %s%s: %s", 5201590Srgrimes username, user, ontty(), krb_err_txt[kerno]); 5211590Srgrimes dest_tkt(); 5221590Srgrimes return (1); 5231590Srgrimes } else { 52411233Sgibbs if ((kerno = krb_get_local_addr(&local_addr)) != KSUCCESS) { 52511233Sgibbs warnx("Unable to get our local address: %s", 52611233Sgibbs krb_err_txt[kerno]); 5271590Srgrimes dest_tkt(); 5281590Srgrimes return (1); 5291590Srgrimes } 53011233Sgibbs faddr = local_addr.sin_addr.s_addr; 5311590Srgrimes if ((kerno = krb_rd_req(&ticket, "rcmd", savehost, faddr, 5321590Srgrimes &authdata, "")) != KSUCCESS) { 5331590Srgrimes warnx("kerberos: unable to verify rcmd ticket: %s\n", 5341590Srgrimes krb_err_txt[kerno]); 5351590Srgrimes syslog(LOG_NOTICE|LOG_AUTH, 5361590Srgrimes "failed su: %s to %s%s: %s", username, 5371590Srgrimes user, ontty(), krb_err_txt[kerno]); 5381590Srgrimes dest_tkt(); 5391590Srgrimes return (1); 5401590Srgrimes } 5411590Srgrimes } 5421590Srgrimes return (0); 5431590Srgrimes} 5441590Srgrimes 54514440Smarkmint 54614440Smarkmkoktologin(name, toname) 54714440Smarkm char *name, *toname; 5481590Srgrimes{ 5491590Srgrimes AUTH_DAT *kdata; 5501590Srgrimes AUTH_DAT kdata_st; 55114440Smarkm char realm[REALM_SZ]; 5521590Srgrimes 55314440Smarkm if (krb_get_lrealm(realm, 1) != KSUCCESS) 55414440Smarkm return (1); 5551590Srgrimes kdata = &kdata_st; 5561590Srgrimes memset((char *)kdata, 0, sizeof(*kdata)); 55721646Sdavidn (void)strncpy(kdata->pname, name, sizeof kdata->pname - 1); 55821646Sdavidn (void)strncpy(kdata->pinst, 55921646Sdavidn ((strcmp(toname, "root") == 0) ? "root" : ""), sizeof kdata->pinst - 1); 56021646Sdavidn (void)strncpy(kdata->prealm, realm, sizeof kdata->prealm - 1); 5611590Srgrimes return (kuserok(kdata, toname)); 5621590Srgrimes} 5631590Srgrimes#endif 564