su.c revision 74874
1/* 2 * Copyright (c) 1988, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint 35static const char copyright[] = 36"@(#) Copyright (c) 1988, 1993, 1994\n\ 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41#if 0 42static char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94"; 43#endif 44static const char rcsid[] = 45 "$FreeBSD: head/usr.bin/su/su.c 74874 2001-03-27 19:40:51Z markm $"; 46#endif /* not lint */ 47 48#include <sys/param.h> 49#include <sys/time.h> 50#include <sys/resource.h> 51 52#include <err.h> 53#include <errno.h> 54#include <grp.h> 55#include <paths.h> 56#include <pwd.h> 57#include <stdio.h> 58#include <stdlib.h> 59#include <string.h> 60#include <syslog.h> 61#include <unistd.h> 62#include <libutil.h> 63#include <login_cap.h> 64 65#ifdef USE_PAM 66#include <security/pam_appl.h> 67#include <security/pam_misc.h> 68#include <signal.h> 69#include <sys/wait.h> 70 71static int export_pam_environment __P((void)); 72static int ok_to_export __P((const char *)); 73 74static pam_handle_t *pamh = NULL; 75static char **environ_pam; 76 77#define PAM_END { \ 78 if ((retcode = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS) { \ 79 syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, retcode)); \ 80 } \ 81 if ((retcode = pam_end(pamh,retcode)) != PAM_SUCCESS) { \ 82 syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, retcode)); \ 83 } \ 84} 85#else /* !USE_PAM */ 86#ifdef SKEY 87#include <skey.h> 88#endif 89#endif /* USE_PAM */ 90 91#ifdef KERBEROS 92#include <openssl/des.h> 93#include <krb.h> 94#include <netdb.h> 95 96#define ARGSTR "-Kflmc:" 97 98static int kerberos(char *username, char *user, int uid, char *pword); 99static int koktologin(char *name, char *toname); 100 101int use_kerberos = 1; 102#else /* !KERBEROS */ 103#define ARGSTR "-flmc:" 104#endif /* KERBEROS */ 105 106char *ontty __P((void)); 107int chshell __P((char *)); 108static void usage __P((void)); 109 110int 111main(argc, argv) 112 int argc; 113 char **argv; 114{ 115 extern char **environ; 116 struct passwd *pwd; 117#ifdef WHEELSU 118 char *targetpass; 119 int iswheelsu; 120#endif /* WHEELSU */ 121 char *p, *user, *shell=NULL, *username, *cleanenv = NULL, **nargv, **np; 122 uid_t ruid; 123 gid_t gid; 124 int asme, ch, asthem, fastlogin, prio, i; 125 enum { UNSET, YES, NO } iscsh = UNSET; 126 login_cap_t *lc; 127 char *class=NULL; 128 int setwhat; 129#ifdef USE_PAM 130 int retcode; 131 struct pam_conv conv = { misc_conv, NULL }; 132 char myhost[MAXHOSTNAMELEN + 1], *mytty; 133 int statusp=0; 134 int child_pid, child_pgrp, ret_pid; 135#else /* !USE_PAM */ 136 char **g; 137 struct group *gr; 138#endif /* USE_PAM */ 139#ifdef KERBEROS 140 char *k; 141#endif 142 char shellbuf[MAXPATHLEN]; 143 144#ifdef WHEELSU 145 iswheelsu = 146#endif /* WHEELSU */ 147 asme = asthem = fastlogin = 0; 148 user = "root"; 149 while((ch = getopt(argc, argv, ARGSTR)) != -1) 150 switch((char)ch) { 151#ifdef KERBEROS 152 case 'K': 153 use_kerberos = 0; 154 break; 155#endif 156 case 'f': 157 fastlogin = 1; 158 break; 159 case '-': 160 case 'l': 161 asme = 0; 162 asthem = 1; 163 break; 164 case 'm': 165 asme = 1; 166 asthem = 0; 167 break; 168 case 'c': 169 class = optarg; 170 break; 171 case '?': 172 default: 173 usage(); 174 } 175 176 if (optind < argc) 177 user = argv[optind++]; 178 179 if (strlen(user) > MAXLOGNAME - 1) { 180 errx(1, "username too long"); 181 } 182 183 if (user == NULL) 184 usage(); 185 186 if ((nargv = malloc (sizeof (char *) * (argc + 4))) == NULL) { 187 errx(1, "malloc failure"); 188 } 189 190 nargv[argc + 3] = NULL; 191 for (i = argc; i >= optind; i--) 192 nargv[i + 3] = argv[i]; 193 np = &nargv[i + 3]; 194 195 argv += optind; 196 197#ifdef KERBEROS 198 k = auth_getval("auth_list"); 199 if (k && !strstr(k, "kerberos")) 200 use_kerberos = 0; 201#endif 202 errno = 0; 203 prio = getpriority(PRIO_PROCESS, 0); 204 if (errno) 205 prio = 0; 206 (void)setpriority(PRIO_PROCESS, 0, -2); 207 openlog("su", LOG_CONS, LOG_AUTH); 208 209 /* get current login name and shell */ 210 ruid = getuid(); 211 username = getlogin(); 212 if (username == NULL || (pwd = getpwnam(username)) == NULL || 213 pwd->pw_uid != ruid) 214 pwd = getpwuid(ruid); 215 if (pwd == NULL) 216 errx(1, "who are you?"); 217 username = strdup(pwd->pw_name); 218 gid = pwd->pw_gid; 219 if (username == NULL) 220 err(1, NULL); 221 if (asme) { 222 if (pwd->pw_shell != NULL && *pwd->pw_shell != '\0') { 223 /* copy: pwd memory is recycled */ 224 shell = strncpy(shellbuf, pwd->pw_shell, sizeof shellbuf); 225 shellbuf[sizeof shellbuf - 1] = '\0'; 226 } else { 227 shell = _PATH_BSHELL; 228 iscsh = NO; 229 } 230 } 231 232#ifdef USE_PAM 233 retcode = pam_start("su", user, &conv, &pamh); 234 if (retcode != PAM_SUCCESS) { 235 syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, retcode)); 236 errx(1, "pam_start: %s", pam_strerror(pamh, retcode)); 237 } 238 239 gethostname(myhost, sizeof(myhost)); 240 retcode = pam_set_item(pamh, PAM_RHOST, myhost); 241 if (retcode != PAM_SUCCESS) { 242 syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s", pam_strerror(pamh, retcode)); 243 errx(1, "pam_set_item(PAM_RHOST): %s", pam_strerror(pamh, retcode)); 244 } 245 246 mytty = ttyname(STDERR_FILENO); 247 if (!mytty) 248 mytty = "tty"; 249 retcode = pam_set_item(pamh, PAM_TTY, mytty); 250 if (retcode != PAM_SUCCESS) { 251 syslog(LOG_ERR, "pam_set_item(PAM_TTY): %s", pam_strerror(pamh, retcode)); 252 errx(1, "pam_set_item(PAM_TTY): %s", pam_strerror(pamh, retcode)); 253 } 254 255 if (ruid) { 256 retcode = pam_authenticate(pamh, 0); 257 if (retcode != PAM_SUCCESS) { 258 syslog(LOG_ERR, "pam_authenticate: %s", pam_strerror(pamh, retcode)); 259 errx(1, "Sorry"); 260 } 261 262 if ((retcode = pam_get_item(pamh, PAM_USER, (const void **) &p)) == PAM_SUCCESS) { 263 user = p; 264 } else 265 syslog(LOG_ERR, "pam_get_item(PAM_USER): %s", 266 pam_strerror(pamh, retcode)); 267 268 retcode = pam_acct_mgmt(pamh, 0); 269 if (retcode == PAM_NEW_AUTHTOK_REQD) { 270 retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); 271 if (retcode != PAM_SUCCESS) { 272 syslog(LOG_ERR, "pam_chauthtok: %s", pam_strerror(pamh, retcode)); 273 errx(1, "Sorry"); 274 } 275 } 276 if (retcode != PAM_SUCCESS) { 277 syslog(LOG_ERR, "pam_acct_mgmt: %s", pam_strerror(pamh, retcode)); 278 errx(1, "Sorry"); 279 } 280 } 281#endif /* USE_PAM */ 282 283 /* get target login information, default to root */ 284 if ((pwd = getpwnam(user)) == NULL) { 285 errx(1, "unknown login: %s", user); 286 } 287 if (class==NULL) { 288 lc = login_getpwclass(pwd); 289 } else { 290 if (ruid) 291 errx(1, "only root may use -c"); 292 lc = login_getclass(class); 293 if (lc == NULL) 294 errx(1, "unknown class: %s", class); 295 } 296 297#ifndef USE_PAM 298#ifdef WHEELSU 299 targetpass = strdup(pwd->pw_passwd); 300#endif /* WHEELSU */ 301 302 if (ruid) { 303#ifdef KERBEROS 304 if (use_kerberos && koktologin(username, user) 305 && !pwd->pw_uid) { 306 warnx("kerberos: not in %s's ACL.", user); 307 use_kerberos = 0; 308 } 309#endif 310 { 311 /* 312 * Only allow those with pw_gid==0 or those listed in 313 * group zero to su to root. If group zero entry is 314 * missing or empty, then allow anyone to su to root. 315 * iswheelsu will only be set if the user is EXPLICITLY 316 * listed in group zero. 317 */ 318 if (pwd->pw_uid == 0 && (gr = getgrgid((gid_t)0)) && 319 gr->gr_mem && *(gr->gr_mem)) 320 for (g = gr->gr_mem;; ++g) { 321 if (!*g) { 322 if (gid == 0) 323 break; 324 else 325 errx(1, "you are not in the correct group to su %s.", user); 326 } 327 if (strcmp(username, *g) == 0) { 328#ifdef WHEELSU 329 iswheelsu = 1; 330#endif /* WHEELSU */ 331 break; 332 } 333 } 334 } 335 /* if target requires a password, verify it */ 336 if (*pwd->pw_passwd) { 337#ifdef SKEY 338#ifdef WHEELSU 339 if (iswheelsu) { 340 pwd = getpwnam(username); 341 } 342#endif /* WHEELSU */ 343 p = skey_getpass("Password:", pwd, 1); 344 if (!(!strcmp(pwd->pw_passwd, skey_crypt(p, pwd->pw_passwd, pwd, 1)) 345#ifdef WHEELSU 346 || (iswheelsu && !strcmp(targetpass, crypt(p,targetpass))) 347#endif /* WHEELSU */ 348 )) 349#else /* !SKEY */ 350 p = getpass("Password:"); 351 if (strcmp(pwd->pw_passwd, crypt(p, pwd->pw_passwd))) 352#endif /* SKEY */ 353 { 354#ifdef KERBEROS 355 if (!use_kerberos || (use_kerberos && kerberos(username, user, pwd->pw_uid, p))) 356#endif 357 { 358 syslog(LOG_AUTH|LOG_WARNING, "BAD SU %s to %s%s", username, user, ontty()); 359 errx(1, "Sorry"); 360 } 361 } 362#ifdef WHEELSU 363 if (iswheelsu) { 364 pwd = getpwnam(user); 365 } 366#endif /* WHEELSU */ 367 } 368 if (pwd->pw_expire && time(NULL) >= pwd->pw_expire) { 369 syslog(LOG_AUTH|LOG_WARNING, 370 "BAD SU %s to %s%s", username, 371 user, ontty()); 372 errx(1, "Sorry - account expired"); 373 } 374 } 375#endif /* USE_PAM */ 376 377 if (asme) { 378 /* if asme and non-standard target shell, must be root */ 379 if (ruid && !chshell(pwd->pw_shell)) 380 errx(1, "permission denied (shell)."); 381 } else if (pwd->pw_shell && *pwd->pw_shell) { 382 shell = pwd->pw_shell; 383 iscsh = UNSET; 384 } else { 385 shell = _PATH_BSHELL; 386 iscsh = NO; 387 } 388 389 /* if we're forking a csh, we want to slightly muck the args */ 390 if (iscsh == UNSET) { 391 p = strrchr(shell, '/'); 392 if (p) 393 ++p; 394 else 395 p = shell; 396 if ((iscsh = strcmp(p, "csh") ? NO : YES) == NO) 397 iscsh = strcmp(p, "tcsh") ? NO : YES; 398 } 399 400 (void)setpriority(PRIO_PROCESS, 0, prio); 401 402 /* 403 * PAM modules might add supplementary groups in 404 * pam_setcred(), so initialize them first. 405 */ 406 if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETGROUP) < 0) 407 err(1, "setusercontext"); 408 409#ifdef USE_PAM 410 retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED); 411 if (retcode != PAM_SUCCESS) { 412 syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, retcode)); 413 } 414 415 /* 416 * We must fork() before setuid() because we need to call 417 * pam_setcred(pamh, PAM_DELETE_CRED) as root. 418 */ 419 420 statusp = 1; 421 switch ((child_pid = fork())) { 422 default: 423 while ((ret_pid = waitpid(child_pid, &statusp, WUNTRACED)) != -1) { 424 if (WIFSTOPPED(statusp)) { 425 child_pgrp = tcgetpgrp(1); 426 kill(getpid(), SIGSTOP); 427 tcsetpgrp(1, child_pgrp); 428 kill(child_pid, SIGCONT); 429 statusp = 1; 430 continue; 431 } 432 break; 433 } 434 if (ret_pid == -1) 435 err(1, "waitpid"); 436 PAM_END; 437 exit(statusp); 438 case -1: 439 err(1, "fork"); 440 PAM_END; 441 exit (1); 442 case 0: 443#endif /* USE_PAM */ 444 445 /* 446 * Set all user context except for: 447 * Environmental variables 448 * Umask 449 * Login records (wtmp, etc) 450 * Path 451 */ 452 setwhat = LOGIN_SETALL & ~(LOGIN_SETENV | LOGIN_SETUMASK | 453 LOGIN_SETLOGIN | LOGIN_SETPATH | LOGIN_SETGROUP); 454 455 /* 456 * Don't touch resource/priority settings if -m has been 457 * used or -l and -c hasn't, and we're not su'ing to root. 458 */ 459 if ((asme || (!asthem && class == NULL)) && pwd->pw_uid) 460 setwhat &= ~(LOGIN_SETPRIORITY|LOGIN_SETRESOURCES); 461 if (setusercontext(lc, pwd, pwd->pw_uid, setwhat) < 0) 462 err(1, "setusercontext"); 463 464 if (!asme) { 465 if (asthem) { 466 p = getenv("TERM"); 467#ifdef KERBEROS 468 k = getenv("KRBTKFILE"); 469#endif 470 environ = &cleanenv; 471 472#ifdef USE_PAM 473 /* 474 * Add any environmental variables that the 475 * PAM modules may have set. 476 */ 477 environ_pam = pam_getenvlist(pamh); 478 if (environ_pam) 479 export_pam_environment(); 480#endif /* USE_PAM */ 481 482 /* set the su'd user's environment & umask */ 483 setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETPATH|LOGIN_SETUMASK|LOGIN_SETENV); 484 if (p) 485 (void)setenv("TERM", p, 1); 486#ifdef KERBEROS 487 if (k) 488 (void)setenv("KRBTKFILE", k, 1); 489#endif 490 if (chdir(pwd->pw_dir) < 0) 491 errx(1, "no directory"); 492 } 493 if (asthem || pwd->pw_uid) 494 (void)setenv("USER", pwd->pw_name, 1); 495 (void)setenv("HOME", pwd->pw_dir, 1); 496 (void)setenv("SHELL", shell, 1); 497 } 498 499 login_close(lc); 500 501 if (iscsh == YES) { 502 if (fastlogin) 503 *np-- = "-f"; 504 if (asme) 505 *np-- = "-m"; 506 } 507 508 /* csh strips the first character... */ 509 *np = asthem ? "-su" : iscsh == YES ? "_su" : "su"; 510 511 if (ruid != 0) 512 syslog(LOG_NOTICE, "%s to %s%s", 513 username, user, ontty()); 514 515 execv(shell, np); 516 err(1, "%s", shell); 517#ifdef USE_PAM 518 } 519#endif /* USE_PAM */ 520} 521 522#ifdef USE_PAM 523static int 524export_pam_environment() 525{ 526 char **pp; 527 528 for (pp = environ_pam; *pp != NULL; pp++) { 529 if (ok_to_export(*pp)) 530 (void) putenv(*pp); 531 free(*pp); 532 } 533 return PAM_SUCCESS; 534} 535 536/* 537 * Sanity checks on PAM environmental variables: 538 * - Make sure there is an '=' in the string. 539 * - Make sure the string doesn't run on too long. 540 * - Do not export certain variables. This list was taken from the 541 * Solaris pam_putenv(3) man page. 542 */ 543static int 544ok_to_export(s) 545 const char *s; 546{ 547 static const char *noexport[] = { 548 "SHELL", "HOME", "LOGNAME", "MAIL", "CDPATH", 549 "IFS", "PATH", NULL 550 }; 551 const char **pp; 552 size_t n; 553 554 if (strlen(s) > 1024 || strchr(s, '=') == NULL) 555 return 0; 556 if (strncmp(s, "LD_", 3) == 0) 557 return 0; 558 for (pp = noexport; *pp != NULL; pp++) { 559 n = strlen(*pp); 560 if (s[n] == '=' && strncmp(s, *pp, n) == 0) 561 return 0; 562 } 563 return 1; 564} 565#endif /* USE_PAM */ 566 567static void 568usage() 569{ 570 errx(1, "usage: su [%s] [login [args]]", ARGSTR); 571} 572 573int 574chshell(sh) 575 char *sh; 576{ 577 int r = 0; 578 char *cp; 579 580 setusershell(); 581 while (!r && (cp = getusershell()) != NULL) 582 r = strcmp(cp, sh) == 0; 583 endusershell(); 584 return r; 585} 586 587char * 588ontty() 589{ 590 char *p; 591 static char buf[MAXPATHLEN + 4]; 592 593 buf[0] = 0; 594 p = ttyname(STDERR_FILENO); 595 if (p) 596 snprintf(buf, sizeof(buf), " on %s", p); 597 return (buf); 598} 599 600#ifdef KERBEROS 601int 602kerberos(username, user, uid, pword) 603 char *username, *user; 604 int uid; 605 char *pword; 606{ 607 KTEXT_ST ticket; 608 AUTH_DAT authdata; 609 int kerno; 610 u_long faddr; 611 char lrealm[REALM_SZ], krbtkfile[MAXPATHLEN]; 612 char hostname[MAXHOSTNAMELEN], savehost[MAXHOSTNAMELEN]; 613 char *krb_get_phost(); 614 struct hostent *hp; 615 616 if (krb_get_lrealm(lrealm, 1) != KSUCCESS) 617 return (1); 618 (void)sprintf(krbtkfile, "%s_%s_%lu", TKT_ROOT, user, 619 (unsigned long)getuid()); 620 621 (void)setenv("KRBTKFILE", krbtkfile, 1); 622 (void)krb_set_tkt_string(krbtkfile); 623 /* 624 * Set real as well as effective ID to 0 for the moment, 625 * to make the kerberos library do the right thing. 626 */ 627 if (setuid(0) < 0) { 628 warn("setuid"); 629 return (1); 630 } 631 632 /* 633 * Little trick here -- if we are su'ing to root, 634 * we need to get a ticket for "xxx.root", where xxx represents 635 * the name of the person su'ing. Otherwise (non-root case), 636 * we need to get a ticket for "yyy.", where yyy represents 637 * the name of the person being su'd to, and the instance is null 638 * 639 * We should have a way to set the ticket lifetime, 640 * with a system default for root. 641 */ 642 kerno = krb_get_pw_in_tkt((uid == 0 ? username : user), 643 (uid == 0 ? "root" : ""), lrealm, 644 "krbtgt", lrealm, DEFAULT_TKT_LIFE, pword); 645 646 if (kerno != KSUCCESS) { 647 if (kerno == KDC_PR_UNKNOWN) { 648 warnx("kerberos: principal unknown: %s.%s@%s", 649 (uid == 0 ? username : user), 650 (uid == 0 ? "root" : ""), lrealm); 651 return (1); 652 } 653 warnx("kerberos: unable to su: %s", krb_err_txt[kerno]); 654 syslog(LOG_NOTICE, 655 "BAD Kerberos SU: %s to %s%s: %s", 656 username, user, ontty(), krb_err_txt[kerno]); 657 return (1); 658 } 659 660 if (chown(krbtkfile, uid, -1) < 0) { 661 warn("chown"); 662 (void)unlink(krbtkfile); 663 return (1); 664 } 665 666 (void)setpriority(PRIO_PROCESS, 0, -2); 667 668 if (gethostname(hostname, sizeof(hostname)) == -1) { 669 warn("gethostname"); 670 dest_tkt(); 671 return (1); 672 } 673 674 (void)strncpy(savehost, krb_get_phost(hostname), sizeof(savehost)); 675 savehost[sizeof(savehost) - 1] = '\0'; 676 677 kerno = krb_mk_req(&ticket, "rcmd", savehost, lrealm, 33); 678 679 if (kerno == KDC_PR_UNKNOWN) { 680 warnx("Warning: TGT not verified."); 681 syslog(LOG_NOTICE, 682 "%s to %s%s, TGT not verified (%s); %s.%s not registered?", 683 username, user, ontty(), krb_err_txt[kerno], 684 "rcmd", savehost); 685 } else if (kerno != KSUCCESS) { 686 warnx("Unable to use TGT: %s", krb_err_txt[kerno]); 687 syslog(LOG_NOTICE, "failed su: %s to %s%s: %s", 688 username, user, ontty(), krb_err_txt[kerno]); 689 dest_tkt(); 690 return (1); 691 } else { 692 if (!(hp = gethostbyname(hostname))) { 693 warnx("can't get addr of %s", hostname); 694 dest_tkt(); 695 return (1); 696 } 697 memmove((char *)&faddr, (char *)hp->h_addr, sizeof(faddr)); 698 699 if ((kerno = krb_rd_req(&ticket, "rcmd", savehost, faddr, 700 &authdata, "")) != KSUCCESS) { 701 warnx("kerberos: unable to verify rcmd ticket: %s", 702 krb_err_txt[kerno]); 703 syslog(LOG_NOTICE, 704 "failed su: %s to %s%s: %s", username, 705 user, ontty(), krb_err_txt[kerno]); 706 dest_tkt(); 707 return (1); 708 } 709 } 710 return (0); 711} 712 713int 714koktologin(name, toname) 715 char *name, *toname; 716{ 717 AUTH_DAT *kdata; 718 AUTH_DAT kdata_st; 719 char realm[REALM_SZ]; 720 721 if (krb_get_lrealm(realm, 1) != KSUCCESS) 722 return (1); 723 kdata = &kdata_st; 724 memset((char *)kdata, 0, sizeof(*kdata)); 725 (void)strncpy(kdata->pname, name, sizeof kdata->pname - 1); 726 (void)strncpy(kdata->pinst, 727 ((strcmp(toname, "root") == 0) ? "root" : ""), sizeof kdata->pinst - 1); 728 (void)strncpy(kdata->prealm, realm, sizeof kdata->prealm - 1); 729 return (kuserok(kdata, toname)); 730} 731#endif 732