1 /* 2 * Copyright (c) 1997-2001 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 #include "rsh_locl.h" 35 RCSID("$Id: rshd.c,v 1.41 2001/02/20 01:44:48 assar Exp $"); 36 37 int 38 login_access( struct passwd *user, char *from); 39 40 enum auth_method auth_method; 41 42 krb5_context context; 43 krb5_keyblock *keyblock; 44 krb5_crypto crypto; 45 46 #ifdef KRB4 47 des_key_schedule schedule; 48 des_cblock iv; 49 #endif 50 51 krb5_ccache ccache, ccache2; 52 int kerberos_status = 0; 53 54 int do_encrypt = 0; 55 56 static int do_unique_tkfile = 0; 57 static char tkfile[MAXPATHLEN] = ""; 58 59 static int do_inetd = 1; 60 static char *port_str; 61 static int do_rhosts; 62 static int do_kerberos = 0; 63 static int do_vacuous = 0; 64 static int do_log = 1; 65 static int do_newpag = 1; 66 static int do_version; 67 static int do_help = 0; 68 69 #if defined(DCE) 70 int dfsk5ok = 0; 71 int dfspag = 0; 72 int dfsfwd = 0; 73 krb5_ticket *user_ticket; 74 #endif 75 76 static void 77 syslog_and_die (const char *m, ...) 78 __attribute__ ((format (printf, 1, 2))); 79 80 static void 81 syslog_and_die (const char *m, ...) 82 { 83 va_list args; 84 85 va_start(args, m); 86 vsyslog (LOG_ERR, m, args); 87 va_end(args); 88 exit (1); 89 } 90 91 static void 92 fatal (int sock, const char *m, ...) 93 __attribute__ ((format (printf, 2, 3))); 94 95 static void 96 fatal (int sock, const char *m, ...) 97 { 98 va_list args; 99 char buf[BUFSIZ]; 100 size_t len; 101 102 *buf = 1; 103 va_start(args, m); 104 len = vsnprintf (buf + 1, sizeof(buf) - 1, m, args); 105 va_end(args); 106 syslog (LOG_ERR, "%s", buf + 1); 107 net_write (sock, buf, len + 1); 108 exit (1); 109 } 110 111 static void 112 read_str (int s, char *str, size_t sz, char *expl) 113 { 114 while (sz > 0) { 115 if (net_read (s, str, 1) != 1) 116 syslog_and_die ("read: %m"); 117 if (*str == '\0') 118 return; 119 --sz; 120 ++str; 121 } 122 fatal (s, "%s too long", expl); 123 } 124 125 static int 126 recv_bsd_auth (int s, u_char *buf, 127 struct sockaddr_in *thisaddr, 128 struct sockaddr_in *thataddr, 129 char *client_username, 130 char *server_username, 131 char *cmd) 132 { 133 struct passwd *pwd; 134 135 read_str (s, client_username, USERNAME_SZ, "local username"); 136 read_str (s, server_username, USERNAME_SZ, "remote username"); 137 read_str (s, cmd, COMMAND_SZ, "command"); 138 pwd = getpwnam(server_username); 139 if (pwd == NULL) 140 fatal(s, "Login incorrect."); 141 if (iruserok(thataddr->sin_addr.s_addr, pwd->pw_uid == 0, 142 client_username, server_username)) 143 fatal(s, "Login incorrect."); 144 return 0; 145 } 146 147 #ifdef KRB4 148 static int 149 recv_krb4_auth (int s, u_char *buf, 150 struct sockaddr *thisaddr, 151 struct sockaddr *thataddr, 152 char *client_username, 153 char *server_username, 154 char *cmd) 155 { 156 int status; 157 int32_t options; 158 KTEXT_ST ticket; 159 AUTH_DAT auth; 160 char instance[INST_SZ + 1]; 161 char version[KRB_SENDAUTH_VLEN + 1]; 162 163 if (memcmp (buf, KRB_SENDAUTH_VERS, 4) != 0) 164 return -1; 165 if (net_read (s, buf + 4, KRB_SENDAUTH_VLEN - 4) != 166 KRB_SENDAUTH_VLEN - 4) 167 syslog_and_die ("reading auth info: %m"); 168 if (memcmp (buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN) != 0) 169 syslog_and_die("unrecognized auth protocol: %.8s", buf); 170 171 options = KOPT_IGNORE_PROTOCOL; 172 if (do_encrypt) 173 options |= KOPT_DO_MUTUAL; 174 k_getsockinst (s, instance, sizeof(instance)); 175 status = krb_recvauth (options, 176 s, 177 &ticket, 178 "rcmd", 179 instance, 180 (struct sockaddr_in *)thataddr, 181 (struct sockaddr_in *)thisaddr, 182 &auth, 183 "", 184 schedule, 185 version); 186 if (status != KSUCCESS) 187 syslog_and_die ("recvauth: %s", krb_get_err_text(status)); 188 if (strncmp (version, KCMD_VERSION, KRB_SENDAUTH_VLEN) != 0) 189 syslog_and_die ("bad version: %s", version); 190 191 read_str (s, server_username, USERNAME_SZ, "remote username"); 192 if (kuserok (&auth, server_username) != 0) 193 fatal (s, "Permission denied"); 194 read_str (s, cmd, COMMAND_SZ, "command"); 195 196 syslog(LOG_INFO|LOG_AUTH, 197 "kerberos v4 shell from %s on %s as %s, cmd '%.80s'", 198 krb_unparse_name_long(auth.pname, auth.pinst, auth.prealm), 199 200 inet_ntoa(((struct sockaddr_in *)thataddr)->sin_addr), 201 server_username, 202 cmd); 203 204 memcpy (iv, auth.session, sizeof(iv)); 205 206 return 0; 207 } 208 209 #endif /* KRB4 */ 210 211 static int 212 save_krb5_creds (int s, 213 krb5_auth_context auth_context, 214 krb5_principal client) 215 216 { 217 int ret; 218 krb5_data remote_cred; 219 220 krb5_data_zero (&remote_cred); 221 ret= krb5_read_message (context, (void *)&s, &remote_cred); 222 if (ret) { 223 krb5_data_free(&remote_cred); 224 return 0; 225 } 226 if (remote_cred.length == 0) 227 return 0; 228 229 ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache); 230 if (ret) { 231 krb5_data_free(&remote_cred); 232 return 0; 233 } 234 235 krb5_cc_initialize(context,ccache,client); 236 ret = krb5_rd_cred2(context, auth_context, ccache, &remote_cred); 237 krb5_data_free (&remote_cred); 238 if (ret) 239 return 0; 240 return 1; 241 } 242 243 static void 244 krb5_start_session (void) 245 { 246 krb5_error_code ret; 247 248 ret = krb5_cc_resolve (context, tkfile, &ccache2); 249 if (ret) { 250 krb5_cc_destroy(context, ccache); 251 return; 252 } 253 254 ret = krb5_cc_copy_cache (context, ccache, ccache2); 255 if (ret) { 256 krb5_cc_destroy(context, ccache); 257 return ; 258 } 259 260 krb5_cc_close(context, ccache2); 261 krb5_cc_destroy(context, ccache); 262 return; 263 } 264 265 static int 266 recv_krb5_auth (int s, u_char *buf, 267 struct sockaddr *thisaddr, 268 struct sockaddr *thataddr, 269 char *client_username, 270 char *server_username, 271 char *cmd) 272 { 273 u_int32_t len; 274 krb5_auth_context auth_context = NULL; 275 krb5_ticket *ticket; 276 krb5_error_code status; 277 krb5_data cksum_data; 278 krb5_principal server; 279 280 if (memcmp (buf, "\x00\x00\x00\x13", 4) != 0) 281 return -1; 282 len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]); 283 284 if (net_read(s, buf, len) != len) 285 syslog_and_die ("reading auth info: %m"); 286 if (len != sizeof(KRB5_SENDAUTH_VERSION) 287 || memcmp (buf, KRB5_SENDAUTH_VERSION, len) != 0) 288 syslog_and_die ("bad sendauth version: %.8s", buf); 289 290 status = krb5_sock_to_principal (context, 291 s, 292 "host", 293 KRB5_NT_SRV_HST, 294 &server); 295 if (status) 296 syslog_and_die ("krb5_sock_to_principal: %s", 297 krb5_get_err_text(context, status)); 298 299 status = krb5_recvauth(context, 300 &auth_context, 301 &s, 302 KCMD_VERSION, 303 server, 304 KRB5_RECVAUTH_IGNORE_VERSION, 305 NULL, 306 &ticket); 307 krb5_free_principal (context, server); 308 if (status) 309 syslog_and_die ("krb5_recvauth: %s", 310 krb5_get_err_text(context, status)); 311 312 read_str (s, server_username, USERNAME_SZ, "remote username"); 313 read_str (s, cmd, COMMAND_SZ, "command"); 314 read_str (s, client_username, COMMAND_SZ, "local username"); 315 316 status = krb5_auth_con_getkey (context, auth_context, &keyblock); 317 if (status) 318 syslog_and_die ("krb5_auth_con_getkey: %s", 319 krb5_get_err_text(context, status)); 320 321 status = krb5_crypto_init(context, keyblock, 0, &crypto); 322 if(status) 323 syslog_and_die("krb5_crypto_init: %s", 324 krb5_get_err_text(context, status)); 325 326 327 cksum_data.length = asprintf ((char **)&cksum_data.data, 328 "%u:%s%s", 329 ntohs(socket_get_port (thisaddr)), 330 cmd, 331 server_username); 332 333 status = krb5_verify_authenticator_checksum(context, 334 auth_context, 335 cksum_data.data, 336 cksum_data.length); 337 338 if (status) 339 syslog_and_die ("krb5_verify_authenticator_checksum: %s", 340 krb5_get_err_text(context, status)); 341 342 free (cksum_data.data); 343 344 if (strncmp (client_username, "-u ", 3) == 0) { 345 do_unique_tkfile = 1; 346 memmove (client_username, client_username + 3, 347 strlen(client_username) - 2); 348 } 349 350 if (strncmp (client_username, "-U ", 3) == 0) { 351 char *end, *temp_tkfile; 352 353 do_unique_tkfile = 1; 354 if (strncmp (server_username + 3, "FILE:", 5) == 0) { 355 temp_tkfile = tkfile; 356 } else { 357 strcpy (tkfile, "FILE:"); 358 temp_tkfile = tkfile + 5; 359 } 360 end = strchr(client_username + 3,' '); 361 strncpy(temp_tkfile, client_username + 3, end - client_username - 3); 362 temp_tkfile[end - client_username - 3] = '\0'; 363 memmove (client_username, end +1, strlen(end+1)+1); 364 } 365 366 kerberos_status = save_krb5_creds (s, auth_context, ticket->client); 367 368 if(!krb5_kuserok (context, 369 ticket->client, 370 server_username)) 371 fatal (s, "Permission denied"); 372 373 if (strncmp (cmd, "-x ", 3) == 0) { 374 do_encrypt = 1; 375 memmove (cmd, cmd + 3, strlen(cmd) - 2); 376 } else { 377 if(do_encrypt) 378 fatal (s, "Encryption required"); 379 do_encrypt = 0; 380 } 381 382 { 383 char *name; 384 385 if (krb5_unparse_name (context, ticket->client, &name) == 0) { 386 char addr_str[256]; 387 388 if (inet_ntop (thataddr->sa_family, 389 socket_get_address (thataddr), 390 addr_str, sizeof(addr_str)) == NULL) 391 strlcpy (addr_str, "unknown address", 392 sizeof(addr_str)); 393 394 syslog(LOG_INFO|LOG_AUTH, 395 "kerberos v5 shell from %s on %s as %s, cmd '%.80s'", 396 name, 397 addr_str, 398 server_username, 399 cmd); 400 free (name); 401 } 402 } 403 404 #if defined(DCE) 405 user_ticket = ticket; 406 #endif 407 408 return 0; 409 } 410 411 static void 412 loop (int from0, int to0, 413 int to1, int from1, 414 int to2, int from2) 415 { 416 fd_set real_readset; 417 int max_fd; 418 int count = 2; 419 420 if(from0 >= FD_SETSIZE || from1 >= FD_SETSIZE || from2 >= FD_SETSIZE) 421 errx (1, "fd too large"); 422 423 FD_ZERO(&real_readset); 424 FD_SET(from0, &real_readset); 425 FD_SET(from1, &real_readset); 426 FD_SET(from2, &real_readset); 427 max_fd = max(from0, max(from1, from2)) + 1; 428 for (;;) { 429 int ret; 430 fd_set readset = real_readset; 431 char buf[RSH_BUFSIZ]; 432 433 ret = select (max_fd, &readset, NULL, NULL, NULL); 434 if (ret < 0) { 435 if (errno == EINTR) 436 continue; 437 else 438 syslog_and_die ("select: %m"); 439 } 440 if (FD_ISSET(from0, &readset)) { 441 ret = do_read (from0, buf, sizeof(buf)); 442 if (ret < 0) 443 syslog_and_die ("read: %m"); 444 else if (ret == 0) { 445 close (from0); 446 close (to0); 447 FD_CLR(from0, &real_readset); 448 } else 449 net_write (to0, buf, ret); 450 } 451 if (FD_ISSET(from1, &readset)) { 452 ret = read (from1, buf, sizeof(buf)); 453 if (ret < 0) 454 syslog_and_die ("read: %m"); 455 else if (ret == 0) { 456 close (from1); 457 close (to1); 458 FD_CLR(from1, &real_readset); 459 if (--count == 0) 460 exit (0); 461 } else 462 do_write (to1, buf, ret); 463 } 464 if (FD_ISSET(from2, &readset)) { 465 ret = read (from2, buf, sizeof(buf)); 466 if (ret < 0) 467 syslog_and_die ("read: %m"); 468 else if (ret == 0) { 469 close (from2); 470 close (to2); 471 FD_CLR(from2, &real_readset); 472 if (--count == 0) 473 exit (0); 474 } else 475 do_write (to2, buf, ret); 476 } 477 } 478 } 479 480 /* 481 * Used by `setup_copier' to create some pipe-like means of 482 * communcation. Real pipes would probably be the best thing, but 483 * then the shell doesn't understand it's talking to rshd. If 484 * socketpair doesn't work everywhere, some autoconf magic would have 485 * to be added here. 486 * 487 * If it fails creating the `pipe', it aborts by calling fatal. 488 */ 489 490 static void 491 pipe_a_like (int fd[2]) 492 { 493 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fd) < 0) 494 fatal (STDOUT_FILENO, "socketpair: %m"); 495 } 496 497 /* 498 * Start a child process and leave the parent copying data to and from it. */ 499 500 static void 501 setup_copier (void) 502 { 503 int p0[2], p1[2], p2[2]; 504 pid_t pid; 505 506 pipe_a_like(p0); 507 pipe_a_like(p1); 508 pipe_a_like(p2); 509 pid = fork (); 510 if (pid < 0) 511 fatal (STDOUT_FILENO, "fork: %m"); 512 if (pid == 0) { /* child */ 513 close (p0[1]); 514 close (p1[0]); 515 close (p2[0]); 516 dup2 (p0[0], STDIN_FILENO); 517 dup2 (p1[1], STDOUT_FILENO); 518 dup2 (p2[1], STDERR_FILENO); 519 close (p0[0]); 520 close (p1[1]); 521 close (p2[1]); 522 } else { /* parent */ 523 close (p0[0]); 524 close (p1[1]); 525 close (p2[1]); 526 527 if (net_write (STDOUT_FILENO, "", 1) != 1) 528 fatal (STDOUT_FILENO, "write failed"); 529 530 loop (STDIN_FILENO, p0[1], 531 STDOUT_FILENO, p1[0], 532 STDERR_FILENO, p2[0]); 533 } 534 } 535 536 /* 537 * Is `port' a ``reserverd'' port? 538 */ 539 540 static int 541 is_reserved(u_short port) 542 { 543 return ntohs(port) < IPPORT_RESERVED; 544 } 545 546 /* 547 * Set the necessary part of the environment in `env'. 548 */ 549 550 static void 551 setup_environment (char ***env, const struct passwd *pwd) 552 { 553 int i, j, path; 554 char **e; 555 556 i = 0; 557 path = 0; 558 *env = NULL; 559 560 i = read_environment(_PATH_ETC_ENVIRONMENT, env); 561 e = *env; 562 for (j = 0; j < i; j++) { 563 if (!strncmp(e[j], "PATH=", 5)) { 564 path = 1; 565 } 566 } 567 568 e = *env; 569 e = realloc(e, (i + 7) * sizeof(char *)); 570 571 asprintf (&e[i++], "USER=%s", pwd->pw_name); 572 asprintf (&e[i++], "HOME=%s", pwd->pw_dir); 573 asprintf (&e[i++], "SHELL=%s", pwd->pw_shell); 574 if (! path) { 575 asprintf (&e[i++], "PATH=%s", _PATH_DEFPATH); 576 } 577 asprintf (&e[i++], "SSH_CLIENT=only_to_make_bash_happy"); 578 #if defined(DCE) 579 if (getenv("KRB5CCNAME")) 580 asprintf (&e[i++], "KRB5CCNAME=%s", getenv("KRB5CCNAME")); 581 #else 582 if (do_unique_tkfile) 583 asprintf (&e[i++], "KRB5CCNAME=%s", tkfile); 584 #endif 585 e[i++] = NULL; 586 *env = e; 587 } 588 589 static void 590 doit (int do_kerberos, int check_rhosts) 591 { 592 u_char buf[BUFSIZ]; 593 u_char *p; 594 struct sockaddr_storage thisaddr_ss; 595 struct sockaddr *thisaddr = (struct sockaddr *)&thisaddr_ss; 596 struct sockaddr_storage thataddr_ss; 597 struct sockaddr *thataddr = (struct sockaddr *)&thataddr_ss; 598 struct sockaddr_storage erraddr_ss; 599 struct sockaddr *erraddr = (struct sockaddr *)&erraddr_ss; 600 socklen_t thisaddr_len, thataddr_len; 601 int port; 602 int errsock = -1; 603 char client_user[COMMAND_SZ], server_user[USERNAME_SZ]; 604 char cmd[COMMAND_SZ]; 605 struct passwd *pwd; 606 int s = STDIN_FILENO; 607 char **env; 608 int ret; 609 char that_host[NI_MAXHOST]; 610 611 thisaddr_len = sizeof(thisaddr_ss); 612 if (getsockname (s, thisaddr, &thisaddr_len) < 0) 613 syslog_and_die("getsockname: %m"); 614 thataddr_len = sizeof(thataddr_ss); 615 if (getpeername (s, thataddr, &thataddr_len) < 0) 616 syslog_and_die ("getpeername: %m"); 617 618 if (!do_kerberos && !is_reserved(socket_get_port(thataddr))) 619 fatal(s, "Permission denied"); 620 621 p = buf; 622 port = 0; 623 for(;;) { 624 if (net_read (s, p, 1) != 1) 625 syslog_and_die ("reading port number: %m"); 626 if (*p == '\0') 627 break; 628 else if (isdigit(*p)) 629 port = port * 10 + *p - '0'; 630 else 631 syslog_and_die ("non-digit in port number: %c", *p); 632 } 633 634 if (!do_kerberos && !is_reserved(htons(port))) 635 fatal(s, "Permission denied"); 636 637 if (port) { 638 int priv_port = IPPORT_RESERVED - 1; 639 640 /* 641 * There's no reason to require a ``privileged'' port number 642 * here, but for some reason the brain dead rsh clients 643 * do... :-( 644 */ 645 646 erraddr->sa_family = thataddr->sa_family; 647 socket_set_address_and_port (erraddr, 648 socket_get_address (thataddr), 649 htons(port)); 650 651 /* 652 * we only do reserved port for IPv4 653 */ 654 655 if (erraddr->sa_family == AF_INET) 656 errsock = rresvport (&priv_port); 657 else 658 errsock = socket (erraddr->sa_family, SOCK_STREAM, 0); 659 if (errsock < 0) 660 syslog_and_die ("socket: %m"); 661 if (connect (errsock, 662 erraddr, 663 socket_sockaddr_size (erraddr)) < 0) { 664 syslog (LOG_WARNING, "connect: %m"); 665 close (errsock); 666 } 667 } 668 669 if(do_kerberos) { 670 if (net_read (s, buf, 4) != 4) 671 syslog_and_die ("reading auth info: %m"); 672 673 #ifdef KRB4 674 if (recv_krb4_auth (s, buf, thisaddr, thataddr, 675 client_user, 676 server_user, 677 cmd) == 0) 678 auth_method = AUTH_KRB4; 679 else 680 #endif /* KRB4 */ 681 if(recv_krb5_auth (s, buf, thisaddr, thataddr, 682 client_user, 683 server_user, 684 cmd) == 0) 685 auth_method = AUTH_KRB5; 686 else 687 syslog_and_die ("unrecognized auth protocol: %x %x %x %x", 688 buf[0], buf[1], buf[2], buf[3]); 689 } else { 690 if(recv_bsd_auth (s, buf, 691 (struct sockaddr_in *)thisaddr, 692 (struct sockaddr_in *)thataddr, 693 client_user, 694 server_user, 695 cmd) == 0) { 696 auth_method = AUTH_BROKEN; 697 if(do_vacuous) { 698 printf("Remote host requires Kerberos authentication\n"); 699 exit(0); 700 } 701 } else 702 syslog_and_die("recv_bsd_auth failed"); 703 } 704 705 #if defined(DCE) && defined(_AIX) 706 esetenv("AUTHSTATE", "DCE", 1); 707 #endif 708 709 pwd = getpwnam (server_user); 710 if (pwd == NULL) 711 fatal (s, "Login incorrect."); 712 713 if (*pwd->pw_shell == '\0') 714 pwd->pw_shell = _PATH_BSHELL; 715 716 if (pwd->pw_uid != 0 && access (_PATH_NOLOGIN, F_OK) == 0) 717 fatal (s, "Login disabled."); 718 719 720 ret = getnameinfo_verified (thataddr, thataddr_len, 721 that_host, sizeof(that_host), 722 NULL, 0, 0); 723 if (ret) 724 fatal (s, "getnameinfo: %s", gai_strerror(ret)); 725 726 if (login_access(pwd, that_host) == 0) { 727 syslog(LOG_NOTICE, "Kerberos rsh denied to %s from %s", 728 server_user, that_host); 729 fatal(s, "Permission denied"); 730 } 731 732 #ifdef HAVE_GETSPNAM 733 { 734 struct spwd *sp; 735 long today; 736 737 sp = getspnam(server_user); 738 if (sp != NULL) { 739 today = time(0)/(24L * 60 * 60); 740 if (sp->sp_expire > 0) 741 if (today > sp->sp_expire) 742 fatal(s, "Account has expired."); 743 } 744 } 745 #endif 746 747 748 #ifdef KRB5 749 { 750 int fd; 751 752 if (!do_unique_tkfile) 753 snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_%u",pwd->pw_uid); 754 else if (*tkfile=='\0') { 755 snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_XXXXXX"); 756 fd = mkstemp(tkfile+5); 757 close(fd); 758 unlink(tkfile+5); 759 } 760 761 if (kerberos_status) 762 krb5_start_session(); 763 } 764 chown(tkfile + 5, pwd->pw_uid, -1); 765 766 #if defined(DCE) 767 if (kerberos_status) { 768 esetenv("KRB5CCNAME", tkfile, 1); 769 dfspag = krb5_dfs_pag(context, kerberos_status, user_ticket->client, server_user); 770 } 771 #endif 772 773 #endif 774 775 #ifdef HAVE_SETLOGIN 776 if (setlogin(pwd->pw_name) < 0) 777 syslog(LOG_ERR, "setlogin() failed: %m"); 778 #endif 779 780 #ifdef HAVE_SETPCRED 781 if (setpcred (pwd->pw_name, NULL) == -1) 782 syslog(LOG_ERR, "setpcred() failure: %m"); 783 #endif /* HAVE_SETPCRED */ 784 785 if (initgroups (pwd->pw_name, pwd->pw_gid) < 0) 786 fatal (s, "Login incorrect."); 787 788 if (setgid(pwd->pw_gid) < 0) 789 fatal (s, "Login incorrect."); 790 791 if (setuid (pwd->pw_uid) < 0) 792 fatal (s, "Login incorrect."); 793 794 if (chdir (pwd->pw_dir) < 0) 795 fatal (s, "Remote directory."); 796 797 if (errsock >= 0) { 798 if (dup2 (errsock, STDERR_FILENO) < 0) 799 fatal (s, "Dup2 failed."); 800 close (errsock); 801 } 802 803 setup_environment (&env, pwd); 804 805 if (do_encrypt) { 806 setup_copier (); 807 } else { 808 if (net_write (s, "", 1) != 1) 809 fatal (s, "write failed"); 810 } 811 812 #ifdef KRB4 813 if(k_hasafs()) { 814 char cell[64]; 815 816 if(do_newpag) 817 k_setpag(); 818 if (k_afs_cell_of_file (pwd->pw_dir, cell, sizeof(cell)) == 0) 819 krb_afslog_uid_home (cell, NULL, pwd->pw_uid, pwd->pw_dir); 820 821 krb_afslog_uid_home(NULL, NULL, pwd->pw_uid, pwd->pw_dir); 822 823 #ifdef KRB5 824 /* XXX */ 825 if (kerberos_status) { 826 krb5_ccache ccache; 827 krb5_error_code status; 828 829 status = krb5_cc_resolve (context, tkfile, &ccache); 830 if (!status) { 831 krb5_afslog_uid_home(context,ccache,NULL,NULL, 832 pwd->pw_uid, pwd->pw_dir); 833 krb5_cc_close (context, ccache); 834 } 835 } 836 #endif /* KRB5 */ 837 } 838 #endif /* KRB4 */ 839 execle (pwd->pw_shell, pwd->pw_shell, "-c", cmd, NULL, env); 840 err(1, "exec %s", pwd->pw_shell); 841 } 842 843 struct getargs args[] = { 844 { "inetd", 'i', arg_negative_flag, &do_inetd, 845 "Not started from inetd" }, 846 { "kerberos", 'k', arg_flag, &do_kerberos, 847 "Implement kerberised services" }, 848 { "encrypt", 'x', arg_flag, &do_encrypt, 849 "Implement encrypted service" }, 850 { "rhosts", 'l', arg_flag, &do_rhosts, 851 "Check users .rhosts" }, 852 { "port", 'p', arg_string, &port_str, "Use this port", 853 "port" }, 854 { "vacuous", 'v', arg_flag, &do_vacuous, 855 "Don't accept non-kerberised connections" }, 856 { NULL, 'P', arg_negative_flag, &do_newpag, 857 "Don't put process in new PAG" }, 858 /* compatibility flag: */ 859 { NULL, 'L', arg_flag, &do_log }, 860 { "version", 0, arg_flag, &do_version }, 861 { "help", 0, arg_flag, &do_help } 862 }; 863 864 static void 865 usage (int ret) 866 { 867 if(isatty(STDIN_FILENO)) 868 arg_printusage (args, 869 sizeof(args) / sizeof(args[0]), 870 NULL, 871 ""); 872 else 873 syslog (LOG_ERR, "Usage: %s [-ikxlvPL] [-p port]", getprogname()); 874 exit (ret); 875 } 876 877 878 int 879 main(int argc, char **argv) 880 { 881 int optind = 0; 882 int port = 0; 883 884 setprogname (argv[0]); 885 roken_openlog ("rshd", LOG_ODELAY | LOG_PID, LOG_AUTH); 886 887 if (getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, 888 &optind)) 889 usage(1); 890 891 if(do_help) 892 usage (0); 893 894 if (do_version) { 895 print_version(NULL); 896 exit(0); 897 } 898 899 #ifdef KRB5 900 { 901 krb5_error_code ret; 902 903 ret = krb5_init_context (&context); 904 if (ret) 905 errx (1, "krb5_init_context failed: %d", ret); 906 } 907 #endif 908 909 if(port_str) { 910 struct servent *s = roken_getservbyname (port_str, "tcp"); 911 912 if (s) 913 port = s->s_port; 914 else { 915 char *ptr; 916 917 port = strtol (port_str, &ptr, 10); 918 if (port == 0 && ptr == port_str) 919 syslog_and_die("Bad port `%s'", port_str); 920 port = htons(port); 921 } 922 } 923 924 if (do_encrypt) 925 do_kerberos = 1; 926 927 if (!do_inetd) { 928 if (port == 0) { 929 if (do_kerberos) { 930 if (do_encrypt) 931 port = krb5_getportbyname (context, "ekshell", "tcp", 545); 932 else 933 port = krb5_getportbyname (context, "kshell", "tcp", 544); 934 } else { 935 port = krb5_getportbyname(context, "shell", "tcp", 514); 936 } 937 } 938 mini_inetd (port); 939 } 940 941 signal (SIGPIPE, SIG_IGN); 942 943 doit (do_kerberos, do_rhosts); 944 return 0; 945 } 946