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