Home | History | Annotate | Line # | Download | only in su
su.c revision 1.33.2.1
      1  1.33.2.1        he /*	$NetBSD: su.c,v 1.33.2.1 1999/08/29 11:25:05 he Exp $	*/
      2      1.12  christos 
      3       1.1       cgd /*
      4       1.1       cgd  * Copyright (c) 1988 The Regents of the University of California.
      5       1.1       cgd  * All rights reserved.
      6       1.1       cgd  *
      7       1.1       cgd  * Redistribution and use in source and binary forms, with or without
      8       1.1       cgd  * modification, are permitted provided that the following conditions
      9       1.1       cgd  * are met:
     10       1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     11       1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     12       1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     14       1.1       cgd  *    documentation and/or other materials provided with the distribution.
     15       1.1       cgd  * 3. All advertising materials mentioning features or use of this software
     16       1.1       cgd  *    must display the following acknowledgement:
     17       1.1       cgd  *	This product includes software developed by the University of
     18       1.1       cgd  *	California, Berkeley and its contributors.
     19       1.1       cgd  * 4. Neither the name of the University nor the names of its contributors
     20       1.1       cgd  *    may be used to endorse or promote products derived from this software
     21       1.1       cgd  *    without specific prior written permission.
     22       1.1       cgd  *
     23       1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24       1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25       1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26       1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27       1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28       1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29       1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30       1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31       1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32       1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33       1.1       cgd  * SUCH DAMAGE.
     34       1.1       cgd  */
     35       1.1       cgd 
     36      1.19     lukem #include <sys/cdefs.h>
     37       1.1       cgd #ifndef lint
     38      1.19     lukem __COPYRIGHT(
     39      1.19     lukem     "@(#) Copyright (c) 1988 The Regents of the University of California.\n\
     40      1.19     lukem  All rights reserved.\n");
     41       1.1       cgd #endif /* not lint */
     42       1.1       cgd 
     43       1.1       cgd #ifndef lint
     44      1.12  christos #if 0
     45      1.13       tls static char sccsid[] = "@(#)su.c	8.3 (Berkeley) 4/2/94";*/
     46      1.12  christos #else
     47  1.33.2.1        he __RCSID("$NetBSD: su.c,v 1.33.2.1 1999/08/29 11:25:05 he Exp $");
     48      1.12  christos #endif
     49       1.1       cgd #endif /* not lint */
     50       1.1       cgd 
     51       1.1       cgd #include <sys/param.h>
     52       1.1       cgd #include <sys/time.h>
     53       1.1       cgd #include <sys/resource.h>
     54      1.13       tls #include <err.h>
     55      1.11  christos #include <errno.h>
     56      1.17     lukem #include <grp.h>
     57      1.17     lukem #include <paths.h>
     58      1.17     lukem #include <pwd.h>
     59      1.17     lukem #include <stdio.h>
     60      1.27  wsanchez #ifdef SKEY
     61      1.17     lukem #include <skey.h>
     62      1.27  wsanchez #endif
     63       1.7       jtc #include <stdlib.h>
     64       1.1       cgd #include <string.h>
     65      1.17     lukem #include <syslog.h>
     66      1.21    kleink #include <time.h>
     67      1.17     lukem #include <tzfile.h>
     68       1.1       cgd #include <unistd.h>
     69       1.1       cgd 
     70       1.1       cgd #ifdef KERBEROS
     71       1.1       cgd #include <kerberosIV/des.h>
     72       1.1       cgd #include <kerberosIV/krb.h>
     73       1.1       cgd #include <netdb.h>
     74       1.1       cgd 
     75       1.1       cgd #define	ARGSTR	"-Kflm"
     76       1.1       cgd 
     77       1.1       cgd int use_kerberos = 1;
     78      1.11  christos 
     79      1.11  christos static int kerberos __P((char *, char *, int));
     80      1.11  christos static int koktologin __P((char *, char *, char *));
     81      1.11  christos 
     82       1.1       cgd #else
     83       1.1       cgd #define	ARGSTR	"-flm"
     84       1.1       cgd #endif
     85       1.1       cgd 
     86      1.18     lukem #ifndef	SUGROUP
     87      1.18     lukem #define	SUGROUP	"wheel"
     88      1.18     lukem #endif
     89      1.18     lukem 
     90      1.11  christos int main __P((int, char **));
     91      1.11  christos 
     92      1.25   mycroft static int chshell __P((const char *));
     93      1.11  christos static char *ontty __P((void));
     94      1.11  christos 
     95       1.2       sef 
     96       1.7       jtc int
     97       1.1       cgd main(argc, argv)
     98       1.1       cgd 	int argc;
     99       1.1       cgd 	char **argv;
    100       1.1       cgd {
    101      1.11  christos 	extern char *__progname;
    102       1.1       cgd 	extern char **environ;
    103      1.13       tls 	struct passwd *pwd;
    104      1.17     lukem 	char *p;
    105       1.1       cgd 	struct group *gr;
    106      1.28  christos #ifdef BSD4_4
    107      1.17     lukem 	struct timeval tp;
    108      1.28  christos #endif
    109      1.11  christos 	uid_t ruid;
    110       1.1       cgd 	int asme, ch, asthem, fastlogin, prio;
    111       1.1       cgd 	enum { UNSET, YES, NO } iscsh = UNSET;
    112  1.33.2.1        he 	char *user, *shell, *avshell, *username, **np;
    113      1.30  christos 	char *userpass;
    114      1.24       mrg 	char shellbuf[MAXPATHLEN], avshellbuf[MAXPATHLEN];
    115       1.1       cgd 
    116       1.1       cgd 	asme = asthem = fastlogin = 0;
    117      1.17     lukem 	shell = NULL;
    118      1.19     lukem 	while ((ch = getopt(argc, argv, ARGSTR)) != -1)
    119       1.1       cgd 		switch((char)ch) {
    120       1.1       cgd #ifdef KERBEROS
    121       1.1       cgd 		case 'K':
    122       1.1       cgd 			use_kerberos = 0;
    123       1.1       cgd 			break;
    124       1.1       cgd #endif
    125       1.1       cgd 		case 'f':
    126       1.1       cgd 			fastlogin = 1;
    127       1.1       cgd 			break;
    128       1.1       cgd 		case '-':
    129       1.1       cgd 		case 'l':
    130       1.1       cgd 			asme = 0;
    131       1.1       cgd 			asthem = 1;
    132       1.1       cgd 			break;
    133       1.1       cgd 		case 'm':
    134       1.1       cgd 			asme = 1;
    135       1.1       cgd 			asthem = 0;
    136       1.1       cgd 			break;
    137       1.1       cgd 		case '?':
    138       1.1       cgd 		default:
    139      1.11  christos 			(void)fprintf(stderr,
    140      1.11  christos 			    "Usage: %s [%s] [login [shell arguments]]\n",
    141      1.11  christos 			    __progname, ARGSTR);
    142       1.1       cgd 			exit(1);
    143       1.1       cgd 		}
    144       1.1       cgd 	argv += optind;
    145      1.30  christos 
    146       1.1       cgd 	errno = 0;
    147       1.1       cgd 	prio = getpriority(PRIO_PROCESS, 0);
    148       1.1       cgd 	if (errno)
    149       1.1       cgd 		prio = 0;
    150       1.1       cgd 	(void)setpriority(PRIO_PROCESS, 0, -2);
    151       1.1       cgd 	openlog("su", LOG_CONS, 0);
    152       1.1       cgd 
    153       1.1       cgd 	/* get current login name and shell */
    154       1.1       cgd 	ruid = getuid();
    155       1.1       cgd 	username = getlogin();
    156       1.1       cgd 	if (username == NULL || (pwd = getpwnam(username)) == NULL ||
    157       1.1       cgd 	    pwd->pw_uid != ruid)
    158       1.1       cgd 		pwd = getpwuid(ruid);
    159      1.23       mrg 	if (pwd == NULL)
    160      1.13       tls 		errx(1, "who are you?");
    161       1.1       cgd 	username = strdup(pwd->pw_name);
    162      1.30  christos 	userpass = strdup(pwd->pw_passwd);
    163      1.30  christos 	if (username == NULL || userpass == NULL)
    164      1.23       mrg 		err(1, "strdup");
    165       1.1       cgd 
    166      1.26      ross 	if (asme) {
    167      1.24       mrg 		if (pwd->pw_shell && *pwd->pw_shell) {
    168      1.24       mrg 			shell = strncpy(shellbuf, pwd->pw_shell,
    169      1.24       mrg 			    sizeof(shellbuf) - 1);
    170      1.24       mrg 			shellbuf[sizeof(shellbuf) - 1] = '\0';
    171      1.24       mrg 		} else {
    172      1.24       mrg 			shell = _PATH_BSHELL;
    173      1.24       mrg 			iscsh = NO;
    174      1.24       mrg 		}
    175      1.26      ross 	}
    176       1.1       cgd 	/* get target login information, default to root */
    177       1.1       cgd 	user = *argv ? *argv : "root";
    178       1.2       sef 	np = *argv ? argv : argv-1;
    179       1.2       sef 
    180      1.23       mrg 	if ((pwd = getpwnam(user)) == NULL)
    181      1.13       tls 		errx(1, "unknown login %s", user);
    182      1.24       mrg 	if (ruid
    183       1.1       cgd #ifdef KERBEROS
    184      1.24       mrg 	    && (!use_kerberos || kerberos(username, user, pwd->pw_uid))
    185       1.1       cgd #endif
    186      1.24       mrg 	    ) {
    187      1.30  christos 		char *pass = pwd->pw_passwd;
    188      1.30  christos 		int ok = pwd->pw_uid != 0;
    189      1.30  christos 		char **g;
    190      1.30  christos 
    191      1.24       mrg 		/*
    192      1.24       mrg 		 * Only allow those in group SUGROUP to su to root,
    193      1.24       mrg 		 * but only if that group has any members.
    194      1.24       mrg 		 * If SUGROUP has no members, allow anyone to su root
    195      1.24       mrg 		 */
    196      1.33       abs 		if (!ok) {
    197      1.33       abs 			if ( !(gr = getgrnam(SUGROUP)) || !*gr->gr_mem)
    198      1.33       abs 				ok = 1;
    199      1.33       abs 			else
    200      1.33       abs 				for (g = gr->gr_mem; ; g++) {
    201      1.33       abs 					if (*g == NULL) {
    202      1.33       abs 						ok = 0;
    203      1.33       abs 						break;
    204      1.33       abs 					}
    205      1.33       abs 					if (strcmp(username, *g) == 0) {
    206      1.33       abs 						ok = 1;
    207      1.33       abs 						break;
    208      1.33       abs 					}
    209      1.30  christos 				}
    210       1.1       cgd 		}
    211      1.30  christos #ifdef ROOTAUTH
    212      1.30  christos 		/*
    213      1.30  christos 		 * Allow those in group rootauth to su to root, by supplying
    214      1.30  christos 		 * their own password.
    215      1.30  christos 		 */
    216      1.30  christos 		if (!ok && (gr = getgrnam(ROOTAUTH)))
    217      1.30  christos 			for (g = gr->gr_mem;; ++g) {
    218      1.30  christos 				if (!*g) {
    219      1.30  christos 					ok = 0;
    220      1.30  christos 					break;
    221      1.30  christos 				}
    222      1.30  christos 				if (!strcmp(username, *g)) {
    223      1.30  christos 					pass = userpass;
    224      1.30  christos 					user = username;
    225      1.30  christos 					ok = 1;
    226      1.30  christos 					break;
    227      1.30  christos 				}
    228      1.30  christos 			}
    229      1.30  christos #endif
    230      1.30  christos 		if (!ok)
    231      1.30  christos 			errx(1,
    232      1.30  christos 	    "you are not listed in the correct secondary group (%s) to su %s.",
    233      1.30  christos 					    SUGROUP, user);
    234       1.1       cgd 		/* if target requires a password, verify it */
    235      1.30  christos 		if (*pass) {
    236       1.1       cgd 			p = getpass("Password:");
    237      1.10   deraadt #ifdef SKEY
    238      1.10   deraadt 			if (strcasecmp(p, "s/key") == 0) {
    239      1.13       tls 				if (skey_haskey(user))
    240      1.13       tls 					errx(1, "Sorry, you have no s/key.");
    241      1.13       tls 				else {
    242      1.10   deraadt 					if (skey_authenticate(user)) {
    243      1.10   deraadt 						goto badlogin;
    244      1.10   deraadt 					}
    245      1.10   deraadt 				}
    246      1.10   deraadt 
    247      1.10   deraadt 			} else
    248      1.10   deraadt #endif
    249      1.30  christos 			if (strcmp(pass, crypt(p, pass))) {
    250      1.31  christos #ifdef SKEY
    251      1.10   deraadt badlogin:
    252      1.27  wsanchez #endif
    253       1.1       cgd 				fprintf(stderr, "Sorry\n");
    254       1.1       cgd 				syslog(LOG_AUTH|LOG_WARNING,
    255       1.1       cgd 					"BAD SU %s to %s%s", username,
    256      1.30  christos 					pwd->pw_name, ontty());
    257       1.1       cgd 				exit(1);
    258       1.1       cgd 			}
    259       1.1       cgd 		}
    260       1.1       cgd 	}
    261       1.1       cgd 
    262       1.1       cgd 	if (asme) {
    263       1.1       cgd 		/* if asme and non-standard target shell, must be root */
    264      1.13       tls 		if (!chshell(pwd->pw_shell) && ruid)
    265      1.13       tls 			errx(1,"permission denied (shell).");
    266       1.1       cgd 	} else if (pwd->pw_shell && *pwd->pw_shell) {
    267       1.1       cgd 		shell = pwd->pw_shell;
    268       1.1       cgd 		iscsh = UNSET;
    269       1.1       cgd 	} else {
    270       1.1       cgd 		shell = _PATH_BSHELL;
    271       1.1       cgd 		iscsh = NO;
    272       1.1       cgd 	}
    273       1.1       cgd 
    274      1.17     lukem 	if ((p = strrchr(shell, '/')) != NULL)
    275       1.9       cgd 		avshell = p+1;
    276       1.9       cgd 	else
    277       1.9       cgd 		avshell = shell;
    278       1.9       cgd 
    279       1.1       cgd 	/* if we're forking a csh, we want to slightly muck the args */
    280       1.9       cgd 	if (iscsh == UNSET)
    281      1.11  christos 		iscsh = strstr(avshell, "csh") ? YES : NO;
    282       1.1       cgd 
    283       1.1       cgd 	/* set permissions */
    284      1.13       tls 	if (setgid(pwd->pw_gid) < 0)
    285      1.13       tls 		err(1, "setgid");
    286      1.13       tls 	if (initgroups(user, pwd->pw_gid))
    287      1.13       tls 		errx(1, "initgroups failed");
    288      1.13       tls 	if (setuid(pwd->pw_uid) < 0)
    289      1.13       tls 		err(1, "setuid");
    290       1.1       cgd 
    291       1.1       cgd 	if (!asme) {
    292       1.1       cgd 		if (asthem) {
    293       1.1       cgd 			p = getenv("TERM");
    294  1.33.2.1        he 			/* Create an empty environment */
    295  1.33.2.1        he 			if ((environ = malloc(sizeof(char *))) == NULL)
    296  1.33.2.1        he 				err(1, "%s", "");
    297  1.33.2.1        he 			environ[0] = NULL;
    298       1.8   mycroft 			(void)setenv("PATH", _PATH_DEFPATH, 1);
    299      1.11  christos 			if (p)
    300      1.11  christos 				(void)setenv("TERM", p, 1);
    301      1.13       tls 			if (chdir(pwd->pw_dir) < 0)
    302      1.13       tls 				errx(1, "no directory");
    303       1.1       cgd 		}
    304       1.5       jtc 		if (asthem || pwd->pw_uid)
    305       1.1       cgd 			(void)setenv("USER", pwd->pw_name, 1);
    306       1.1       cgd 		(void)setenv("HOME", pwd->pw_dir, 1);
    307       1.1       cgd 		(void)setenv("SHELL", shell, 1);
    308       1.1       cgd 	}
    309       1.1       cgd 
    310      1.12  christos 	if (iscsh == YES) {
    311      1.12  christos 		if (fastlogin)
    312      1.12  christos 			*np-- = "-f";
    313      1.12  christos 		if (asme)
    314      1.12  christos 			*np-- = "-m";
    315      1.12  christos 	}
    316       1.1       cgd 
    317       1.8   mycroft 	if (asthem) {
    318       1.8   mycroft 		avshellbuf[0] = '-';
    319      1.15       mrg 		(void)strncpy(avshellbuf+1, avshell, sizeof(avshellbuf) - 2);
    320       1.8   mycroft 		avshell = avshellbuf;
    321       1.8   mycroft 	} else if (iscsh == YES) {
    322       1.8   mycroft 		/* csh strips the first character... */
    323       1.8   mycroft 		avshellbuf[0] = '_';
    324      1.15       mrg 		(void)strncpy(avshellbuf+1, avshell, sizeof(avshellbuf) - 2);
    325       1.8   mycroft 		avshell = avshellbuf;
    326       1.8   mycroft 	}
    327      1.12  christos 	*np = avshell;
    328      1.11  christos 
    329      1.28  christos #ifdef BSD4_4
    330      1.17     lukem 	if (pwd->pw_change || pwd->pw_expire)
    331      1.17     lukem 		(void)gettimeofday(&tp, (struct timezone *)NULL);
    332      1.26      ross 	if (pwd->pw_change) {
    333      1.17     lukem 		if (tp.tv_sec >= pwd->pw_change) {
    334      1.17     lukem 			(void)printf("%s -- %s's password has expired.\n",
    335      1.17     lukem 				     (ruid ? "Sorry" : "Note"), user);
    336      1.17     lukem 			if (ruid != 0)
    337      1.17     lukem 				exit(1);
    338      1.17     lukem 		} else if (pwd->pw_change - tp.tv_sec <
    339      1.17     lukem 		    _PASSWORD_WARNDAYS * SECSPERDAY)
    340      1.17     lukem 			(void)printf("Warning: %s's password expires on %s",
    341      1.17     lukem 				     user, ctime(&pwd->pw_change));
    342      1.26      ross 	}
    343      1.26      ross 	if (pwd->pw_expire) {
    344      1.17     lukem 		if (tp.tv_sec >= pwd->pw_expire) {
    345      1.17     lukem 			(void)printf("%s -- %s's account has expired.\n",
    346      1.17     lukem 				     (ruid ? "Sorry" : "Note"), user);
    347      1.17     lukem 			if (ruid != 0)
    348      1.17     lukem 				exit(1);
    349      1.17     lukem 		} else if (pwd->pw_expire - tp.tv_sec <
    350      1.17     lukem 		    _PASSWORD_WARNDAYS * SECSPERDAY)
    351      1.17     lukem 			(void)printf("Warning: %s's account expires on %s",
    352      1.17     lukem 				     user, ctime(&pwd->pw_expire));
    353      1.26      ross  	}
    354      1.28  christos #endif
    355       1.1       cgd 	if (ruid != 0)
    356       1.1       cgd 		syslog(LOG_NOTICE|LOG_AUTH, "%s to %s%s",
    357      1.30  christos 		    username, pwd->pw_name, ontty());
    358       1.1       cgd 
    359       1.1       cgd 	(void)setpriority(PRIO_PROCESS, 0, prio);
    360       1.1       cgd 
    361      1.12  christos 	execv(shell, np);
    362      1.13       tls 	err(1, "%s", shell);
    363      1.27  wsanchez         /* NOTREACHED */
    364       1.1       cgd }
    365      1.11  christos 
    366      1.11  christos static int
    367       1.1       cgd chshell(sh)
    368      1.25   mycroft 	const char *sh;
    369       1.1       cgd {
    370      1.25   mycroft 	const char *cp;
    371       1.1       cgd 
    372       1.1       cgd 	while ((cp = getusershell()) != NULL)
    373       1.1       cgd 		if (!strcmp(cp, sh))
    374       1.1       cgd 			return (1);
    375       1.1       cgd 	return (0);
    376       1.1       cgd }
    377       1.1       cgd 
    378      1.11  christos static char *
    379       1.1       cgd ontty()
    380       1.1       cgd {
    381      1.19     lukem 	char *p;
    382       1.1       cgd 	static char buf[MAXPATHLEN + 4];
    383       1.1       cgd 
    384       1.1       cgd 	buf[0] = 0;
    385      1.17     lukem 	if ((p = ttyname(STDERR_FILENO)) != NULL)
    386      1.15       mrg 		(void)snprintf(buf, sizeof buf, " on %s", p);
    387       1.1       cgd 	return (buf);
    388       1.1       cgd }
    389       1.1       cgd 
    390       1.1       cgd #ifdef KERBEROS
    391      1.11  christos static int
    392       1.1       cgd kerberos(username, user, uid)
    393       1.1       cgd 	char *username, *user;
    394       1.1       cgd 	int uid;
    395       1.1       cgd {
    396       1.1       cgd 	KTEXT_ST ticket;
    397       1.1       cgd 	AUTH_DAT authdata;
    398       1.1       cgd 	struct hostent *hp;
    399       1.1       cgd 	int kerno;
    400       1.1       cgd 	u_long faddr;
    401       1.1       cgd 	char lrealm[REALM_SZ], krbtkfile[MAXPATHLEN];
    402      1.22       mrg 	char hostname[MAXHOSTNAMELEN + 1], savehost[MAXHOSTNAMELEN + 1];
    403       1.1       cgd 
    404      1.29    scottr 	if (krb_get_lrealm(lrealm, 1) != KSUCCESS ||
    405      1.29    scottr 	    strcmp(lrealm, KRB_REALM) == 0)
    406       1.1       cgd 		return (1);
    407       1.1       cgd 	if (koktologin(username, lrealm, user) && !uid) {
    408      1.13       tls 		warnx("kerberos: not in %s's ACL.", user);
    409       1.1       cgd 		return (1);
    410       1.1       cgd 	}
    411      1.29    scottr 	(void)snprintf(krbtkfile, sizeof krbtkfile, "%s_%s_%d", TKT_ROOT,
    412      1.15       mrg 	    user, getuid());
    413       1.1       cgd 
    414       1.1       cgd 	(void)setenv("KRBTKFILE", krbtkfile, 1);
    415       1.1       cgd 	(void)krb_set_tkt_string(krbtkfile);
    416       1.1       cgd 	/*
    417       1.1       cgd 	 * Set real as well as effective ID to 0 for the moment,
    418       1.1       cgd 	 * to make the kerberos library do the right thing.
    419       1.1       cgd 	 */
    420       1.1       cgd 	if (setuid(0) < 0) {
    421      1.13       tls 		warn("setuid");
    422       1.1       cgd 		return (1);
    423       1.1       cgd 	}
    424       1.1       cgd 
    425       1.1       cgd 	/*
    426       1.1       cgd 	 * Little trick here -- if we are su'ing to root,
    427       1.1       cgd 	 * we need to get a ticket for "xxx.root", where xxx represents
    428       1.1       cgd 	 * the name of the person su'ing.  Otherwise (non-root case),
    429       1.1       cgd 	 * we need to get a ticket for "yyy.", where yyy represents
    430       1.1       cgd 	 * the name of the person being su'd to, and the instance is null
    431       1.1       cgd 	 *
    432       1.1       cgd 	 * We should have a way to set the ticket lifetime,
    433       1.1       cgd 	 * with a system default for root.
    434       1.1       cgd 	 */
    435       1.1       cgd 	kerno = krb_get_pw_in_tkt((uid == 0 ? username : user),
    436       1.1       cgd 		(uid == 0 ? "root" : ""), lrealm,
    437      1.17     lukem 		"krbtgt", lrealm, DEFAULT_TKT_LIFE, 0);
    438       1.1       cgd 
    439       1.1       cgd 	if (kerno != KSUCCESS) {
    440       1.1       cgd 		if (kerno == KDC_PR_UNKNOWN) {
    441      1.13       tls 			warnx("kerberos: principal unknown: %s.%s@%s",
    442       1.1       cgd 				(uid == 0 ? username : user),
    443       1.1       cgd 				(uid == 0 ? "root" : ""), lrealm);
    444       1.1       cgd 			return (1);
    445       1.1       cgd 		}
    446      1.13       tls 		warnx("kerberos: unable to su: %s", krb_err_txt[kerno]);
    447       1.1       cgd 		syslog(LOG_NOTICE|LOG_AUTH,
    448       1.1       cgd 		    "BAD Kerberos SU: %s to %s%s: %s",
    449       1.1       cgd 		    username, user, ontty(), krb_err_txt[kerno]);
    450       1.1       cgd 		return (1);
    451       1.1       cgd 	}
    452       1.1       cgd 
    453       1.1       cgd 	if (chown(krbtkfile, uid, -1) < 0) {
    454      1.13       tls 		warn("chown");
    455       1.1       cgd 		(void)unlink(krbtkfile);
    456       1.1       cgd 		return (1);
    457       1.1       cgd 	}
    458       1.1       cgd 
    459       1.1       cgd 	(void)setpriority(PRIO_PROCESS, 0, -2);
    460       1.1       cgd 
    461       1.1       cgd 	if (gethostname(hostname, sizeof(hostname)) == -1) {
    462      1.13       tls 		warn("gethostname");
    463       1.1       cgd 		dest_tkt();
    464       1.1       cgd 		return (1);
    465       1.1       cgd 	}
    466      1.22       mrg 	hostname[sizeof(hostname) - 1] = '\0';
    467       1.1       cgd 
    468       1.1       cgd 	(void)strncpy(savehost, krb_get_phost(hostname), sizeof(savehost));
    469       1.1       cgd 	savehost[sizeof(savehost) - 1] = '\0';
    470       1.1       cgd 
    471       1.1       cgd 	kerno = krb_mk_req(&ticket, "rcmd", savehost, lrealm, 33);
    472       1.1       cgd 
    473       1.1       cgd 	if (kerno == KDC_PR_UNKNOWN) {
    474      1.13       tls 		warnx("Warning: TGT not verified.");
    475       1.1       cgd 		syslog(LOG_NOTICE|LOG_AUTH,
    476       1.1       cgd 		    "%s to %s%s, TGT not verified (%s); %s.%s not registered?",
    477       1.1       cgd 		    username, user, ontty(), krb_err_txt[kerno],
    478       1.1       cgd 		    "rcmd", savehost);
    479       1.1       cgd 	} else if (kerno != KSUCCESS) {
    480      1.13       tls 		warnx("Unable to use TGT: %s", krb_err_txt[kerno]);
    481       1.1       cgd 		syslog(LOG_NOTICE|LOG_AUTH, "failed su: %s to %s%s: %s",
    482       1.1       cgd 		    username, user, ontty(), krb_err_txt[kerno]);
    483       1.1       cgd 		dest_tkt();
    484       1.1       cgd 		return (1);
    485       1.1       cgd 	} else {
    486       1.1       cgd 		if (!(hp = gethostbyname(hostname))) {
    487      1.13       tls 			warnx("can't get addr of %s", hostname);
    488       1.1       cgd 			dest_tkt();
    489       1.1       cgd 			return (1);
    490       1.1       cgd 		}
    491      1.13       tls 		memmove((char *)&faddr, (char *)hp->h_addr, sizeof(faddr));
    492       1.1       cgd 
    493       1.1       cgd 		if ((kerno = krb_rd_req(&ticket, "rcmd", savehost, faddr,
    494       1.1       cgd 		    &authdata, "")) != KSUCCESS) {
    495      1.13       tls 			warnx("kerberos: unable to verify rcmd ticket: %s\n",
    496       1.1       cgd 			    krb_err_txt[kerno]);
    497       1.1       cgd 			syslog(LOG_NOTICE|LOG_AUTH,
    498       1.1       cgd 			    "failed su: %s to %s%s: %s", username,
    499       1.1       cgd 			     user, ontty(), krb_err_txt[kerno]);
    500       1.1       cgd 			dest_tkt();
    501       1.1       cgd 			return (1);
    502       1.1       cgd 		}
    503       1.1       cgd 	}
    504       1.1       cgd 	return (0);
    505       1.1       cgd }
    506       1.1       cgd 
    507      1.11  christos static int
    508       1.1       cgd koktologin(name, realm, toname)
    509       1.1       cgd 	char *name, *realm, *toname;
    510       1.1       cgd {
    511      1.19     lukem 	AUTH_DAT *kdata;
    512       1.1       cgd 	AUTH_DAT kdata_st;
    513       1.1       cgd 
    514       1.1       cgd 	kdata = &kdata_st;
    515      1.13       tls 	memset((char *)kdata, 0, sizeof(*kdata));
    516      1.15       mrg 	(void)strncpy(kdata->pname, name, sizeof(kdata->pname) - 1);
    517      1.16  explorer 	(void)strncpy(kdata->pinst,
    518      1.15       mrg 	    ((strcmp(toname, "root") == 0) ? "root" : ""), sizeof(kdata->pinst) - 1);
    519      1.16  explorer 	(void)strncpy(kdata->prealm, realm, sizeof(kdata->prealm) - 1);
    520       1.1       cgd 	return (kuserok(kdata, toname));
    521       1.1       cgd }
    522       1.1       cgd #endif
    523