Home | History | Annotate | Line # | Download | only in su
su.c revision 1.19
      1  1.19     lukem /*	$NetBSD: su.c,v 1.19 1997/10/19 23:31:54 lukem 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.19     lukem __RCSID("$NetBSD: su.c,v 1.19 1997/10/19 23:31:54 lukem 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.17     lukem #include <skey.h>
     61   1.7       jtc #include <stdlib.h>
     62   1.1       cgd #include <string.h>
     63  1.17     lukem #include <syslog.h>
     64  1.17     lukem #include <tzfile.h>
     65   1.1       cgd #include <unistd.h>
     66   1.1       cgd 
     67   1.1       cgd #ifdef KERBEROS
     68   1.1       cgd #include <kerberosIV/des.h>
     69   1.1       cgd #include <kerberosIV/krb.h>
     70   1.1       cgd #include <netdb.h>
     71   1.1       cgd 
     72   1.1       cgd #define	ARGSTR	"-Kflm"
     73   1.1       cgd 
     74   1.1       cgd int use_kerberos = 1;
     75  1.11  christos 
     76  1.11  christos static int kerberos __P((char *, char *, int));
     77  1.11  christos static int koktologin __P((char *, char *, char *));
     78  1.11  christos 
     79   1.1       cgd #else
     80   1.1       cgd #define	ARGSTR	"-flm"
     81   1.1       cgd #endif
     82   1.1       cgd 
     83  1.18     lukem #ifndef	SUGROUP
     84  1.18     lukem #define	SUGROUP	"wheel"
     85  1.18     lukem #endif
     86  1.18     lukem 
     87  1.11  christos 
     88  1.11  christos int main __P((int, char **));
     89  1.11  christos 
     90  1.11  christos static int chshell __P((char *));
     91  1.11  christos static char *ontty __P((void));
     92  1.11  christos 
     93   1.2       sef 
     94   1.7       jtc int
     95   1.1       cgd main(argc, argv)
     96   1.1       cgd 	int argc;
     97   1.1       cgd 	char **argv;
     98   1.1       cgd {
     99  1.11  christos 	extern char *__progname;
    100   1.1       cgd 	extern char **environ;
    101  1.13       tls 	struct passwd *pwd;
    102  1.17     lukem 	char *p;
    103   1.1       cgd 	struct group *gr;
    104  1.17     lukem 	struct timeval tp;
    105  1.11  christos 	uid_t ruid;
    106   1.1       cgd 	int asme, ch, asthem, fastlogin, prio;
    107   1.1       cgd 	enum { UNSET, YES, NO } iscsh = UNSET;
    108   1.8   mycroft 	char *user, *shell, *avshell, *username, *cleanenv[10], **np;
    109   1.8   mycroft 	char shellbuf[MAXPATHLEN], avshellbuf[MAXPATHLEN];
    110   1.1       cgd 
    111   1.1       cgd 	asme = asthem = fastlogin = 0;
    112  1.17     lukem 	shell = NULL;
    113  1.19     lukem 	while ((ch = getopt(argc, argv, ARGSTR)) != -1)
    114   1.1       cgd 		switch((char)ch) {
    115   1.1       cgd #ifdef KERBEROS
    116   1.1       cgd 		case 'K':
    117   1.1       cgd 			use_kerberos = 0;
    118   1.1       cgd 			break;
    119   1.1       cgd #endif
    120   1.1       cgd 		case 'f':
    121   1.1       cgd 			fastlogin = 1;
    122   1.1       cgd 			break;
    123   1.1       cgd 		case '-':
    124   1.1       cgd 		case 'l':
    125   1.1       cgd 			asme = 0;
    126   1.1       cgd 			asthem = 1;
    127   1.1       cgd 			break;
    128   1.1       cgd 		case 'm':
    129   1.1       cgd 			asme = 1;
    130   1.1       cgd 			asthem = 0;
    131   1.1       cgd 			break;
    132   1.1       cgd 		case '?':
    133   1.1       cgd 		default:
    134  1.11  christos 			(void)fprintf(stderr,
    135  1.11  christos 			    "Usage: %s [%s] [login [shell arguments]]\n",
    136  1.11  christos 			    __progname, ARGSTR);
    137   1.1       cgd 			exit(1);
    138   1.1       cgd 		}
    139   1.1       cgd 	argv += optind;
    140   1.1       cgd 
    141   1.1       cgd 	errno = 0;
    142   1.1       cgd 	prio = getpriority(PRIO_PROCESS, 0);
    143   1.1       cgd 	if (errno)
    144   1.1       cgd 		prio = 0;
    145   1.1       cgd 	(void)setpriority(PRIO_PROCESS, 0, -2);
    146   1.1       cgd 	openlog("su", LOG_CONS, 0);
    147   1.1       cgd 
    148   1.1       cgd 	/* get current login name and shell */
    149   1.1       cgd 	ruid = getuid();
    150   1.1       cgd 	username = getlogin();
    151   1.1       cgd 	if (username == NULL || (pwd = getpwnam(username)) == NULL ||
    152   1.1       cgd 	    pwd->pw_uid != ruid)
    153   1.1       cgd 		pwd = getpwuid(ruid);
    154   1.1       cgd 	if (pwd == NULL) {
    155  1.13       tls 		errx(1, "who are you?");
    156   1.1       cgd 	}
    157   1.1       cgd 	username = strdup(pwd->pw_name);
    158   1.1       cgd 	if (asme)
    159   1.1       cgd 		if (pwd->pw_shell && *pwd->pw_shell)
    160  1.15       mrg 			shell = strncpy(shellbuf, pwd->pw_shell,
    161  1.15       mrg 			    sizeof(shellbuf) + 1);
    162   1.1       cgd 		else {
    163   1.1       cgd 			shell = _PATH_BSHELL;
    164   1.1       cgd 			iscsh = NO;
    165   1.1       cgd 		}
    166   1.1       cgd 
    167   1.1       cgd 	/* get target login information, default to root */
    168   1.1       cgd 	user = *argv ? *argv : "root";
    169   1.2       sef 	np = *argv ? argv : argv-1;
    170   1.2       sef 
    171   1.1       cgd 	if ((pwd = getpwnam(user)) == NULL) {
    172  1.13       tls 		errx(1, "unknown login %s", user);
    173   1.1       cgd 	}
    174   1.1       cgd 
    175   1.1       cgd 	if (ruid) {
    176   1.1       cgd #ifdef KERBEROS
    177   1.1       cgd 	    if (!use_kerberos || kerberos(username, user, pwd->pw_uid))
    178   1.1       cgd #endif
    179   1.1       cgd 	    {
    180  1.18     lukem 		/* Only allow those in group SUGROUP to su to root,
    181  1.18     lukem 		   but only if that group has any members.
    182  1.18     lukem 		   If SUGROUP has no members, allow anyone to su root */
    183  1.18     lukem 		if (pwd->pw_uid == 0 &&
    184  1.18     lukem 		    (gr = getgrnam(SUGROUP)) && *gr->gr_mem) {
    185  1.18     lukem 			char **g;
    186  1.18     lukem 
    187  1.18     lukem 			for (g = gr->gr_mem; ; g++) {
    188  1.18     lukem 				if (*g == NULL)
    189  1.18     lukem 					errx(1,
    190  1.18     lukem 	    "you are not listed in the correct secondary group (%s) to su %s.",
    191  1.18     lukem 					    SUGROUP, user);
    192  1.18     lukem 				if (strcmp(username, *g) == 0)
    193  1.17     lukem 					break;
    194  1.18     lukem 			}
    195   1.1       cgd 		}
    196   1.1       cgd 		/* if target requires a password, verify it */
    197   1.1       cgd 		if (*pwd->pw_passwd) {
    198   1.1       cgd 			p = getpass("Password:");
    199  1.10   deraadt #ifdef SKEY
    200  1.10   deraadt 			if (strcasecmp(p, "s/key") == 0) {
    201  1.13       tls 				if (skey_haskey(user))
    202  1.13       tls 					errx(1, "Sorry, you have no s/key.");
    203  1.13       tls 				else {
    204  1.10   deraadt 					if (skey_authenticate(user)) {
    205  1.10   deraadt 						goto badlogin;
    206  1.10   deraadt 					}
    207  1.10   deraadt 				}
    208  1.10   deraadt 
    209  1.10   deraadt 			} else
    210  1.10   deraadt #endif
    211   1.1       cgd 			if (strcmp(pwd->pw_passwd, crypt(p, pwd->pw_passwd))) {
    212  1.10   deraadt badlogin:
    213   1.1       cgd 				fprintf(stderr, "Sorry\n");
    214   1.1       cgd 				syslog(LOG_AUTH|LOG_WARNING,
    215   1.1       cgd 					"BAD SU %s to %s%s", username,
    216   1.1       cgd 					user, ontty());
    217   1.1       cgd 				exit(1);
    218   1.1       cgd 			}
    219   1.1       cgd 		}
    220   1.1       cgd 	    }
    221   1.1       cgd 	}
    222   1.1       cgd 
    223   1.1       cgd 	if (asme) {
    224   1.1       cgd 		/* if asme and non-standard target shell, must be root */
    225  1.13       tls 		if (!chshell(pwd->pw_shell) && ruid)
    226  1.13       tls 			errx(1,"permission denied (shell).");
    227   1.1       cgd 	} else if (pwd->pw_shell && *pwd->pw_shell) {
    228   1.1       cgd 		shell = pwd->pw_shell;
    229   1.1       cgd 		iscsh = UNSET;
    230   1.1       cgd 	} else {
    231   1.1       cgd 		shell = _PATH_BSHELL;
    232   1.1       cgd 		iscsh = NO;
    233   1.1       cgd 	}
    234   1.1       cgd 
    235  1.17     lukem 	if ((p = strrchr(shell, '/')) != NULL)
    236   1.9       cgd 		avshell = p+1;
    237   1.9       cgd 	else
    238   1.9       cgd 		avshell = shell;
    239   1.9       cgd 
    240   1.1       cgd 	/* if we're forking a csh, we want to slightly muck the args */
    241   1.9       cgd 	if (iscsh == UNSET)
    242  1.11  christos 		iscsh = strstr(avshell, "csh") ? YES : NO;
    243   1.1       cgd 
    244   1.1       cgd 	/* set permissions */
    245  1.13       tls 	if (setgid(pwd->pw_gid) < 0)
    246  1.13       tls 		err(1, "setgid");
    247  1.13       tls 	if (initgroups(user, pwd->pw_gid))
    248  1.13       tls 		errx(1, "initgroups failed");
    249  1.13       tls 	if (setuid(pwd->pw_uid) < 0)
    250  1.13       tls 		err(1, "setuid");
    251   1.1       cgd 
    252   1.1       cgd 	if (!asme) {
    253   1.1       cgd 		if (asthem) {
    254   1.1       cgd 			p = getenv("TERM");
    255   1.8   mycroft 			cleanenv[0] = NULL;
    256   1.1       cgd 			environ = cleanenv;
    257   1.8   mycroft 			(void)setenv("PATH", _PATH_DEFPATH, 1);
    258  1.11  christos 			if (p)
    259  1.11  christos 				(void)setenv("TERM", p, 1);
    260  1.13       tls 			if (chdir(pwd->pw_dir) < 0)
    261  1.13       tls 				errx(1, "no directory");
    262   1.1       cgd 		}
    263   1.5       jtc 		if (asthem || pwd->pw_uid)
    264   1.1       cgd 			(void)setenv("USER", pwd->pw_name, 1);
    265   1.1       cgd 		(void)setenv("HOME", pwd->pw_dir, 1);
    266   1.1       cgd 		(void)setenv("SHELL", shell, 1);
    267   1.1       cgd 	}
    268   1.1       cgd 
    269  1.12  christos 	if (iscsh == YES) {
    270  1.12  christos 		if (fastlogin)
    271  1.12  christos 			*np-- = "-f";
    272  1.12  christos 		if (asme)
    273  1.12  christos 			*np-- = "-m";
    274  1.12  christos 	}
    275   1.1       cgd 
    276   1.8   mycroft 	if (asthem) {
    277   1.8   mycroft 		avshellbuf[0] = '-';
    278  1.15       mrg 		(void)strncpy(avshellbuf+1, avshell, sizeof(avshellbuf) - 2);
    279   1.8   mycroft 		avshell = avshellbuf;
    280   1.8   mycroft 	} else if (iscsh == YES) {
    281   1.8   mycroft 		/* csh strips the first character... */
    282   1.8   mycroft 		avshellbuf[0] = '_';
    283  1.15       mrg 		(void)strncpy(avshellbuf+1, avshell, sizeof(avshellbuf) - 2);
    284   1.8   mycroft 		avshell = avshellbuf;
    285   1.8   mycroft 	}
    286  1.12  christos 	*np = avshell;
    287  1.11  christos 
    288  1.17     lukem 	if (pwd->pw_change || pwd->pw_expire)
    289  1.17     lukem 		(void)gettimeofday(&tp, (struct timezone *)NULL);
    290  1.17     lukem 	if (pwd->pw_change)
    291  1.17     lukem 		if (tp.tv_sec >= pwd->pw_change) {
    292  1.17     lukem 			(void)printf("%s -- %s's password has expired.\n",
    293  1.17     lukem 				     (ruid ? "Sorry" : "Note"), user);
    294  1.17     lukem 			if (ruid != 0)
    295  1.17     lukem 				exit(1);
    296  1.17     lukem 		} else if (pwd->pw_change - tp.tv_sec <
    297  1.17     lukem 		    _PASSWORD_WARNDAYS * SECSPERDAY)
    298  1.17     lukem 			(void)printf("Warning: %s's password expires on %s",
    299  1.17     lukem 				     user, ctime(&pwd->pw_change));
    300  1.17     lukem 	if (pwd->pw_expire)
    301  1.17     lukem 		if (tp.tv_sec >= pwd->pw_expire) {
    302  1.17     lukem 			(void)printf("%s -- %s's account has expired.\n",
    303  1.17     lukem 				     (ruid ? "Sorry" : "Note"), user);
    304  1.17     lukem 			if (ruid != 0)
    305  1.17     lukem 				exit(1);
    306  1.17     lukem 		} else if (pwd->pw_expire - tp.tv_sec <
    307  1.17     lukem 		    _PASSWORD_WARNDAYS * SECSPERDAY)
    308  1.17     lukem 			(void)printf("Warning: %s's account expires on %s",
    309  1.17     lukem 				     user, ctime(&pwd->pw_expire));
    310  1.17     lukem 
    311   1.1       cgd 	if (ruid != 0)
    312   1.1       cgd 		syslog(LOG_NOTICE|LOG_AUTH, "%s to %s%s",
    313   1.1       cgd 		    username, user, ontty());
    314   1.1       cgd 
    315   1.1       cgd 	(void)setpriority(PRIO_PROCESS, 0, prio);
    316   1.1       cgd 
    317  1.12  christos 	execv(shell, np);
    318  1.13       tls 	err(1, "%s", shell);
    319   1.1       cgd }
    320  1.11  christos 
    321  1.11  christos static int
    322   1.1       cgd chshell(sh)
    323   1.1       cgd 	char *sh;
    324   1.1       cgd {
    325  1.13       tls 	char *cp;
    326   1.1       cgd 
    327   1.1       cgd 	while ((cp = getusershell()) != NULL)
    328   1.1       cgd 		if (!strcmp(cp, sh))
    329   1.1       cgd 			return (1);
    330   1.1       cgd 	return (0);
    331   1.1       cgd }
    332   1.1       cgd 
    333  1.11  christos static char *
    334   1.1       cgd ontty()
    335   1.1       cgd {
    336  1.19     lukem 	char *p;
    337   1.1       cgd 	static char buf[MAXPATHLEN + 4];
    338   1.1       cgd 
    339   1.1       cgd 	buf[0] = 0;
    340  1.17     lukem 	if ((p = ttyname(STDERR_FILENO)) != NULL)
    341  1.15       mrg 		(void)snprintf(buf, sizeof buf, " on %s", p);
    342   1.1       cgd 	return (buf);
    343   1.1       cgd }
    344   1.1       cgd 
    345   1.1       cgd #ifdef KERBEROS
    346  1.11  christos static int
    347   1.1       cgd kerberos(username, user, uid)
    348   1.1       cgd 	char *username, *user;
    349   1.1       cgd 	int uid;
    350   1.1       cgd {
    351   1.1       cgd 	KTEXT_ST ticket;
    352   1.1       cgd 	AUTH_DAT authdata;
    353   1.1       cgd 	struct hostent *hp;
    354  1.19     lukem 	char *p;
    355   1.1       cgd 	int kerno;
    356   1.1       cgd 	u_long faddr;
    357   1.1       cgd 	char lrealm[REALM_SZ], krbtkfile[MAXPATHLEN];
    358   1.1       cgd 	char hostname[MAXHOSTNAMELEN], savehost[MAXHOSTNAMELEN];
    359   1.1       cgd 	char *ontty(), *krb_get_phost();
    360   1.1       cgd 
    361   1.1       cgd 	if (krb_get_lrealm(lrealm, 1) != KSUCCESS)
    362   1.1       cgd 		return (1);
    363   1.1       cgd 	if (koktologin(username, lrealm, user) && !uid) {
    364  1.13       tls 		warnx("kerberos: not in %s's ACL.", user);
    365   1.1       cgd 		return (1);
    366   1.1       cgd 	}
    367  1.15       mrg 	(void)(void)snprintf(krbtkfile, sizeof krbtkfile, "%s_%s_%d", TKT_ROOT,
    368  1.15       mrg 	    user, getuid());
    369   1.1       cgd 
    370   1.1       cgd 	(void)setenv("KRBTKFILE", krbtkfile, 1);
    371   1.1       cgd 	(void)krb_set_tkt_string(krbtkfile);
    372   1.1       cgd 	/*
    373   1.1       cgd 	 * Set real as well as effective ID to 0 for the moment,
    374   1.1       cgd 	 * to make the kerberos library do the right thing.
    375   1.1       cgd 	 */
    376   1.1       cgd 	if (setuid(0) < 0) {
    377  1.13       tls 		warn("setuid");
    378   1.1       cgd 		return (1);
    379   1.1       cgd 	}
    380   1.1       cgd 
    381   1.1       cgd 	/*
    382   1.1       cgd 	 * Little trick here -- if we are su'ing to root,
    383   1.1       cgd 	 * we need to get a ticket for "xxx.root", where xxx represents
    384   1.1       cgd 	 * the name of the person su'ing.  Otherwise (non-root case),
    385   1.1       cgd 	 * we need to get a ticket for "yyy.", where yyy represents
    386   1.1       cgd 	 * the name of the person being su'd to, and the instance is null
    387   1.1       cgd 	 *
    388   1.1       cgd 	 * We should have a way to set the ticket lifetime,
    389   1.1       cgd 	 * with a system default for root.
    390   1.1       cgd 	 */
    391   1.1       cgd 	kerno = krb_get_pw_in_tkt((uid == 0 ? username : user),
    392   1.1       cgd 		(uid == 0 ? "root" : ""), lrealm,
    393  1.17     lukem 		"krbtgt", lrealm, DEFAULT_TKT_LIFE, 0);
    394   1.1       cgd 
    395   1.1       cgd 	if (kerno != KSUCCESS) {
    396   1.1       cgd 		if (kerno == KDC_PR_UNKNOWN) {
    397  1.13       tls 			warnx("kerberos: principal unknown: %s.%s@%s",
    398   1.1       cgd 				(uid == 0 ? username : user),
    399   1.1       cgd 				(uid == 0 ? "root" : ""), lrealm);
    400   1.1       cgd 			return (1);
    401   1.1       cgd 		}
    402  1.13       tls 		warnx("kerberos: unable to su: %s", krb_err_txt[kerno]);
    403   1.1       cgd 		syslog(LOG_NOTICE|LOG_AUTH,
    404   1.1       cgd 		    "BAD Kerberos SU: %s to %s%s: %s",
    405   1.1       cgd 		    username, user, ontty(), krb_err_txt[kerno]);
    406   1.1       cgd 		return (1);
    407   1.1       cgd 	}
    408   1.1       cgd 
    409   1.1       cgd 	if (chown(krbtkfile, uid, -1) < 0) {
    410  1.13       tls 		warn("chown");
    411   1.1       cgd 		(void)unlink(krbtkfile);
    412   1.1       cgd 		return (1);
    413   1.1       cgd 	}
    414   1.1       cgd 
    415   1.1       cgd 	(void)setpriority(PRIO_PROCESS, 0, -2);
    416   1.1       cgd 
    417   1.1       cgd 	if (gethostname(hostname, sizeof(hostname)) == -1) {
    418  1.13       tls 		warn("gethostname");
    419   1.1       cgd 		dest_tkt();
    420   1.1       cgd 		return (1);
    421   1.1       cgd 	}
    422   1.1       cgd 
    423   1.1       cgd 	(void)strncpy(savehost, krb_get_phost(hostname), sizeof(savehost));
    424   1.1       cgd 	savehost[sizeof(savehost) - 1] = '\0';
    425   1.1       cgd 
    426   1.1       cgd 	kerno = krb_mk_req(&ticket, "rcmd", savehost, lrealm, 33);
    427   1.1       cgd 
    428   1.1       cgd 	if (kerno == KDC_PR_UNKNOWN) {
    429  1.13       tls 		warnx("Warning: TGT not verified.");
    430   1.1       cgd 		syslog(LOG_NOTICE|LOG_AUTH,
    431   1.1       cgd 		    "%s to %s%s, TGT not verified (%s); %s.%s not registered?",
    432   1.1       cgd 		    username, user, ontty(), krb_err_txt[kerno],
    433   1.1       cgd 		    "rcmd", savehost);
    434   1.1       cgd 	} else if (kerno != KSUCCESS) {
    435  1.13       tls 		warnx("Unable to use TGT: %s", krb_err_txt[kerno]);
    436   1.1       cgd 		syslog(LOG_NOTICE|LOG_AUTH, "failed su: %s to %s%s: %s",
    437   1.1       cgd 		    username, user, ontty(), krb_err_txt[kerno]);
    438   1.1       cgd 		dest_tkt();
    439   1.1       cgd 		return (1);
    440   1.1       cgd 	} else {
    441   1.1       cgd 		if (!(hp = gethostbyname(hostname))) {
    442  1.13       tls 			warnx("can't get addr of %s", hostname);
    443   1.1       cgd 			dest_tkt();
    444   1.1       cgd 			return (1);
    445   1.1       cgd 		}
    446  1.13       tls 		memmove((char *)&faddr, (char *)hp->h_addr, sizeof(faddr));
    447   1.1       cgd 
    448   1.1       cgd 		if ((kerno = krb_rd_req(&ticket, "rcmd", savehost, faddr,
    449   1.1       cgd 		    &authdata, "")) != KSUCCESS) {
    450  1.13       tls 			warnx("kerberos: unable to verify rcmd ticket: %s\n",
    451   1.1       cgd 			    krb_err_txt[kerno]);
    452   1.1       cgd 			syslog(LOG_NOTICE|LOG_AUTH,
    453   1.1       cgd 			    "failed su: %s to %s%s: %s", username,
    454   1.1       cgd 			     user, ontty(), krb_err_txt[kerno]);
    455   1.1       cgd 			dest_tkt();
    456   1.1       cgd 			return (1);
    457   1.1       cgd 		}
    458   1.1       cgd 	}
    459   1.1       cgd 	return (0);
    460   1.1       cgd }
    461   1.1       cgd 
    462  1.11  christos static int
    463   1.1       cgd koktologin(name, realm, toname)
    464   1.1       cgd 	char *name, *realm, *toname;
    465   1.1       cgd {
    466  1.19     lukem 	AUTH_DAT *kdata;
    467   1.1       cgd 	AUTH_DAT kdata_st;
    468   1.1       cgd 
    469   1.1       cgd 	kdata = &kdata_st;
    470  1.13       tls 	memset((char *)kdata, 0, sizeof(*kdata));
    471  1.15       mrg 	(void)strncpy(kdata->pname, name, sizeof(kdata->pname) - 1);
    472  1.16  explorer 	(void)strncpy(kdata->pinst,
    473  1.15       mrg 	    ((strcmp(toname, "root") == 0) ? "root" : ""), sizeof(kdata->pinst) - 1);
    474  1.16  explorer 	(void)strncpy(kdata->prealm, realm, sizeof(kdata->prealm) - 1);
    475   1.1       cgd 	return (kuserok(kdata, toname));
    476   1.1       cgd }
    477   1.1       cgd #endif
    478