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.46 2002/02/18 20:02:14 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_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 281 recv_krb5_auth (int s, u_char *buf, 282 struct sockaddr *thisaddr, 283 struct sockaddr *thataddr, 284 char *client_username, 285 char *server_username, 286 char *cmd) 287 { 288 u_int32_t len; 289 krb5_auth_context auth_context = NULL; 290 krb5_ticket *ticket; 291 krb5_error_code status; 292 krb5_data cksum_data; 293 krb5_principal server; 294 295 if (memcmp (buf, "\x00\x00\x00\x13", 4) != 0) 296 return -1; 297 len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]); 298 299 if (net_read(s, buf, len) != len) 300 syslog_and_die ("reading auth info: %m"); 301 if (len != sizeof(KRB5_SENDAUTH_VERSION) 302 || memcmp (buf, KRB5_SENDAUTH_VERSION, len) != 0) 303 syslog_and_die ("bad sendauth version: %.8s", buf); 304 305 status = krb5_sock_to_principal (context, 306 s, 307 "host", 308 KRB5_NT_SRV_HST, 309 &server); 310 if (status) 311 syslog_and_die ("krb5_sock_to_principal: %s", 312 krb5_get_err_text(context, status)); 313 314 status = krb5_recvauth(context, 315 &auth_context, 316 &s, 317 KCMD_VERSION, 318 server, 319 KRB5_RECVAUTH_IGNORE_VERSION, 320 NULL, 321 &ticket); 322 krb5_free_principal (context, server); 323 if (status) 324 syslog_and_die ("krb5_recvauth: %s", 325 krb5_get_err_text(context, status)); 326 327 read_str (s, server_username, USERNAME_SZ, "remote username"); 328 read_str (s, cmd, COMMAND_SZ, "command"); 329 read_str (s, client_username, COMMAND_SZ, "local username"); 330 331 status = krb5_auth_con_getkey (context, auth_context, &keyblock); 332 if (status) 333 syslog_and_die ("krb5_auth_con_getkey: %s", 334 krb5_get_err_text(context, status)); 335 336 status = krb5_crypto_init(context, keyblock, 0, &crypto); 337 if(status) 338 syslog_and_die("krb5_crypto_init: %s", 339 krb5_get_err_text(context, status)); 340 341 342 cksum_data.length = asprintf ((char **)&cksum_data.data, 343 "%u:%s%s", 344 ntohs(socket_get_port (thisaddr)), 345 cmd, 346 server_username); 347 348 status = krb5_verify_authenticator_checksum(context, 349 auth_context, 350 cksum_data.data, 351 cksum_data.length); 352 353 if (status) 354 syslog_and_die ("krb5_verify_authenticator_checksum: %s", 355 krb5_get_err_text(context, status)); 356 357 free (cksum_data.data); 358 359 if (strncmp (client_username, "-u ", 3) == 0) { 360 do_unique_tkfile = 1; 361 memmove (client_username, client_username + 3, 362 strlen(client_username) - 2); 363 } 364 365 if (strncmp (client_username, "-U ", 3) == 0) { 366 char *end, *temp_tkfile; 367 368 do_unique_tkfile = 1; 369 if (strncmp (server_username + 3, "FILE:", 5) == 0) { 370 temp_tkfile = tkfile; 371 } else { 372 strcpy (tkfile, "FILE:"); 373 temp_tkfile = tkfile + 5; 374 } 375 end = strchr(client_username + 3,' '); 376 strncpy(temp_tkfile, client_username + 3, end - client_username - 3); 377 temp_tkfile[end - client_username - 3] = '\0'; 378 memmove (client_username, end +1, strlen(end+1)+1); 379 } 380 381 kerberos_status = save_krb5_creds (s, auth_context, ticket->client); 382 383 if(!krb5_kuserok (context, 384 ticket->client, 385 server_username)) 386 fatal (s, NULL, "Permission denied."); 387 388 if (strncmp (cmd, "-x ", 3) == 0) { 389 do_encrypt = 1; 390 memmove (cmd, cmd + 3, strlen(cmd) - 2); 391 } else { 392 if(do_encrypt) 393 fatal (s, NULL, "Encryption is required."); 394 do_encrypt = 0; 395 } 396 397 { 398 char *name; 399 400 if (krb5_unparse_name (context, ticket->client, &name) == 0) { 401 char addr_str[256]; 402 403 if (inet_ntop (thataddr->sa_family, 404 socket_get_address (thataddr), 405 addr_str, sizeof(addr_str)) == NULL) 406 strlcpy (addr_str, "unknown address", 407 sizeof(addr_str)); 408 409 syslog(LOG_INFO|LOG_AUTH, 410 "kerberos v5 shell from %s on %s as %s, cmd '%.80s'", 411 name, 412 addr_str, 413 server_username, 414 cmd); 415 free (name); 416 } 417 } 418 419 #if defined(DCE) 420 user_ticket = ticket; 421 #endif 422 423 return 0; 424 } 425 #endif /* KRB5 */ 426 427 static void 428 loop (int from0, int to0, 429 int to1, int from1, 430 int to2, int from2) 431 { 432 fd_set real_readset; 433 int max_fd; 434 int count = 2; 435 436 if(from0 >= FD_SETSIZE || from1 >= FD_SETSIZE || from2 >= FD_SETSIZE) 437 errx (1, "fd too large"); 438 439 FD_ZERO(&real_readset); 440 FD_SET(from0, &real_readset); 441 FD_SET(from1, &real_readset); 442 FD_SET(from2, &real_readset); 443 max_fd = max(from0, max(from1, from2)) + 1; 444 for (;;) { 445 int ret; 446 fd_set readset = real_readset; 447 char buf[RSH_BUFSIZ]; 448 449 ret = select (max_fd, &readset, NULL, NULL, NULL); 450 if (ret < 0) { 451 if (errno == EINTR) 452 continue; 453 else 454 syslog_and_die ("select: %m"); 455 } 456 if (FD_ISSET(from0, &readset)) { 457 ret = do_read (from0, buf, sizeof(buf)); 458 if (ret < 0) 459 syslog_and_die ("read: %m"); 460 else if (ret == 0) { 461 close (from0); 462 close (to0); 463 FD_CLR(from0, &real_readset); 464 } else 465 net_write (to0, buf, ret); 466 } 467 if (FD_ISSET(from1, &readset)) { 468 ret = read (from1, buf, sizeof(buf)); 469 if (ret < 0) 470 syslog_and_die ("read: %m"); 471 else if (ret == 0) { 472 close (from1); 473 close (to1); 474 FD_CLR(from1, &real_readset); 475 if (--count == 0) 476 exit (0); 477 } else 478 do_write (to1, buf, ret); 479 } 480 if (FD_ISSET(from2, &readset)) { 481 ret = read (from2, buf, sizeof(buf)); 482 if (ret < 0) 483 syslog_and_die ("read: %m"); 484 else if (ret == 0) { 485 close (from2); 486 close (to2); 487 FD_CLR(from2, &real_readset); 488 if (--count == 0) 489 exit (0); 490 } else 491 do_write (to2, buf, ret); 492 } 493 } 494 } 495 496 /* 497 * Used by `setup_copier' to create some pipe-like means of 498 * communcation. Real pipes would probably be the best thing, but 499 * then the shell doesn't understand it's talking to rshd. If 500 * socketpair doesn't work everywhere, some autoconf magic would have 501 * to be added here. 502 * 503 * If it fails creating the `pipe', it aborts by calling fatal. 504 */ 505 506 static void 507 pipe_a_like (int fd[2]) 508 { 509 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fd) < 0) 510 fatal (STDOUT_FILENO, "socketpair", "Pipe creation failed."); 511 } 512 513 /* 514 * Start a child process and leave the parent copying data to and from it. */ 515 516 static void 517 setup_copier (void) 518 { 519 int p0[2], p1[2], p2[2]; 520 pid_t pid; 521 522 pipe_a_like(p0); 523 pipe_a_like(p1); 524 pipe_a_like(p2); 525 pid = fork (); 526 if (pid < 0) 527 fatal (STDOUT_FILENO, "fork", "Could not create child process."); 528 if (pid == 0) { /* child */ 529 close (p0[1]); 530 close (p1[0]); 531 close (p2[0]); 532 dup2 (p0[0], STDIN_FILENO); 533 dup2 (p1[1], STDOUT_FILENO); 534 dup2 (p2[1], STDERR_FILENO); 535 close (p0[0]); 536 close (p1[1]); 537 close (p2[1]); 538 } else { /* parent */ 539 close (p0[0]); 540 close (p1[1]); 541 close (p2[1]); 542 543 if (net_write (STDOUT_FILENO, "", 1) != 1) 544 fatal (STDOUT_FILENO, "net_write", "Write failure."); 545 546 loop (STDIN_FILENO, p0[1], 547 STDOUT_FILENO, p1[0], 548 STDERR_FILENO, p2[0]); 549 } 550 } 551 552 /* 553 * Is `port' a ``reserverd'' port? 554 */ 555 556 static int 557 is_reserved(u_short port) 558 { 559 return ntohs(port) < IPPORT_RESERVED; 560 } 561 562 /* 563 * Set the necessary part of the environment in `env'. 564 */ 565 566 static void 567 setup_environment (char ***env, const struct passwd *pwd) 568 { 569 int i, j, path; 570 char **e; 571 572 i = 0; 573 path = 0; 574 *env = NULL; 575 576 i = read_environment(_PATH_ETC_ENVIRONMENT, env); 577 e = *env; 578 for (j = 0; j < i; j++) { 579 if (!strncmp(e[j], "PATH=", 5)) { 580 path = 1; 581 } 582 } 583 584 e = *env; 585 e = realloc(e, (i + 7) * sizeof(char *)); 586 587 asprintf (&e[i++], "USER=%s", pwd->pw_name); 588 asprintf (&e[i++], "HOME=%s", pwd->pw_dir); 589 asprintf (&e[i++], "SHELL=%s", pwd->pw_shell); 590 if (! path) { 591 asprintf (&e[i++], "PATH=%s", _PATH_DEFPATH); 592 } 593 asprintf (&e[i++], "SSH_CLIENT=only_to_make_bash_happy"); 594 #if defined(DCE) 595 if (getenv("KRB5CCNAME")) 596 asprintf (&e[i++], "KRB5CCNAME=%s", getenv("KRB5CCNAME")); 597 #else 598 if (do_unique_tkfile) 599 asprintf (&e[i++], "KRB5CCNAME=%s", tkfile); 600 #endif 601 e[i++] = NULL; 602 *env = e; 603 } 604 605 static void 606 doit (void) 607 { 608 u_char buf[BUFSIZ]; 609 u_char *p; 610 struct sockaddr_storage thisaddr_ss; 611 struct sockaddr *thisaddr = (struct sockaddr *)&thisaddr_ss; 612 struct sockaddr_storage thataddr_ss; 613 struct sockaddr *thataddr = (struct sockaddr *)&thataddr_ss; 614 struct sockaddr_storage erraddr_ss; 615 struct sockaddr *erraddr = (struct sockaddr *)&erraddr_ss; 616 socklen_t thisaddr_len, thataddr_len; 617 int port; 618 int errsock = -1; 619 char client_user[COMMAND_SZ], server_user[USERNAME_SZ]; 620 char cmd[COMMAND_SZ]; 621 struct passwd *pwd; 622 int s = STDIN_FILENO; 623 char **env; 624 int ret; 625 char that_host[NI_MAXHOST]; 626 627 thisaddr_len = sizeof(thisaddr_ss); 628 if (getsockname (s, thisaddr, &thisaddr_len) < 0) 629 syslog_and_die("getsockname: %m"); 630 thataddr_len = sizeof(thataddr_ss); 631 if (getpeername (s, thataddr, &thataddr_len) < 0) 632 syslog_and_die ("getpeername: %m"); 633 634 /* check for V4MAPPED addresses? */ 635 636 if (do_kerberos == 0 && !is_reserved(socket_get_port(thataddr))) 637 fatal(s, NULL, "Permission denied."); 638 639 p = buf; 640 port = 0; 641 for(;;) { 642 if (net_read (s, p, 1) != 1) 643 syslog_and_die ("reading port number: %m"); 644 if (*p == '\0') 645 break; 646 else if (isdigit(*p)) 647 port = port * 10 + *p - '0'; 648 else 649 syslog_and_die ("non-digit in port number: %c", *p); 650 } 651 652 if (do_kerberos == 0 && !is_reserved(htons(port))) 653 fatal(s, NULL, "Permission denied."); 654 655 if (port) { 656 int priv_port = IPPORT_RESERVED - 1; 657 658 /* 659 * There's no reason to require a ``privileged'' port number 660 * here, but for some reason the brain dead rsh clients 661 * do... :-( 662 */ 663 664 erraddr->sa_family = thataddr->sa_family; 665 socket_set_address_and_port (erraddr, 666 socket_get_address (thataddr), 667 htons(port)); 668 669 /* 670 * we only do reserved port for IPv4 671 */ 672 673 if (erraddr->sa_family == AF_INET) 674 errsock = rresvport (&priv_port); 675 else 676 errsock = socket (erraddr->sa_family, SOCK_STREAM, 0); 677 if (errsock < 0) 678 syslog_and_die ("socket: %m"); 679 if (connect (errsock, 680 erraddr, 681 socket_sockaddr_size (erraddr)) < 0) { 682 syslog (LOG_WARNING, "connect: %m"); 683 close (errsock); 684 } 685 } 686 687 if(do_kerberos) { 688 if (net_read (s, buf, 4) != 4) 689 syslog_and_die ("reading auth info: %m"); 690 691 #ifdef KRB4 692 if ((do_kerberos & DO_KRB4) && 693 recv_krb4_auth (s, buf, thisaddr, thataddr, 694 client_user, 695 server_user, 696 cmd) == 0) 697 auth_method = AUTH_KRB4; 698 else 699 #endif /* KRB4 */ 700 #ifdef KRB5 701 if((do_kerberos & DO_KRB5) && 702 recv_krb5_auth (s, buf, thisaddr, thataddr, 703 client_user, 704 server_user, 705 cmd) == 0) 706 auth_method = AUTH_KRB5; 707 else 708 #endif /* KRB5 */ 709 syslog_and_die ("unrecognized auth protocol: %x %x %x %x", 710 buf[0], buf[1], buf[2], buf[3]); 711 } else { 712 if(recv_bsd_auth (s, buf, 713 (struct sockaddr_in *)thisaddr, 714 (struct sockaddr_in *)thataddr, 715 client_user, 716 server_user, 717 cmd) == 0) { 718 auth_method = AUTH_BROKEN; 719 if(do_vacuous) { 720 printf("Remote host requires Kerberos authentication\n"); 721 exit(0); 722 } 723 } else 724 syslog_and_die("recv_bsd_auth failed"); 725 } 726 727 #if defined(DCE) && defined(_AIX) 728 esetenv("AUTHSTATE", "DCE", 1); 729 #endif 730 731 pwd = getpwnam (server_user); 732 if (pwd == NULL) 733 fatal (s, NULL, "Login incorrect."); 734 735 if (*pwd->pw_shell == '\0') 736 pwd->pw_shell = _PATH_BSHELL; 737 738 if (pwd->pw_uid != 0 && access (_PATH_NOLOGIN, F_OK) == 0) 739 fatal (s, NULL, "Login disabled."); 740 741 742 ret = getnameinfo_verified (thataddr, thataddr_len, 743 that_host, sizeof(that_host), 744 NULL, 0, 0); 745 if (ret) 746 fatal (s, NULL, "getnameinfo: %s", gai_strerror(ret)); 747 748 if (login_access(pwd, that_host) == 0) { 749 syslog(LOG_NOTICE, "Kerberos rsh denied to %s from %s", 750 server_user, that_host); 751 fatal(s, NULL, "Permission denied."); 752 } 753 754 #ifdef HAVE_GETSPNAM 755 { 756 struct spwd *sp; 757 long today; 758 759 sp = getspnam(server_user); 760 if (sp != NULL) { 761 today = time(0)/(24L * 60 * 60); 762 if (sp->sp_expire > 0) 763 if (today > sp->sp_expire) 764 fatal(s, NULL, "Account has expired."); 765 } 766 } 767 #endif 768 769 770 #ifdef KRB5 771 { 772 int fd; 773 774 if (!do_unique_tkfile) 775 snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_%u",pwd->pw_uid); 776 else if (*tkfile=='\0') { 777 snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_XXXXXX"); 778 fd = mkstemp(tkfile+5); 779 close(fd); 780 unlink(tkfile+5); 781 } 782 783 if (kerberos_status) 784 krb5_start_session(); 785 } 786 chown(tkfile + 5, pwd->pw_uid, -1); 787 788 #if defined(DCE) 789 if (kerberos_status) { 790 esetenv("KRB5CCNAME", tkfile, 1); 791 dfspag = krb5_dfs_pag(context, kerberos_status, user_ticket->client, server_user); 792 } 793 #endif 794 795 #endif 796 797 #ifdef HAVE_SETLOGIN 798 if (setlogin(pwd->pw_name) < 0) 799 syslog(LOG_ERR, "setlogin() failed: %m"); 800 #endif 801 802 #ifdef HAVE_SETPCRED 803 if (setpcred (pwd->pw_name, NULL) == -1) 804 syslog(LOG_ERR, "setpcred() failure: %m"); 805 #endif /* HAVE_SETPCRED */ 806 807 if (initgroups (pwd->pw_name, pwd->pw_gid) < 0) 808 fatal (s, "initgroups", "Login incorrect."); 809 810 if (setgid(pwd->pw_gid) < 0) 811 fatal (s, "setgid", "Login incorrect."); 812 813 if (setuid (pwd->pw_uid) < 0) 814 fatal (s, "setuid", "Login incorrect."); 815 816 if (chdir (pwd->pw_dir) < 0) 817 fatal (s, "chdir", "Remote directory."); 818 819 if (errsock >= 0) { 820 if (dup2 (errsock, STDERR_FILENO) < 0) 821 fatal (s, "dup2", "Cannot dup stderr."); 822 close (errsock); 823 } 824 825 setup_environment (&env, pwd); 826 827 if (do_encrypt) { 828 setup_copier (); 829 } else { 830 if (net_write (s, "", 1) != 1) 831 fatal (s, "net_write", "write failed"); 832 } 833 834 #ifdef KRB4 835 if(k_hasafs()) { 836 char cell[64]; 837 838 if(do_newpag) 839 k_setpag(); 840 if (k_afs_cell_of_file (pwd->pw_dir, cell, sizeof(cell)) == 0) 841 krb_afslog_uid_home (cell, NULL, pwd->pw_uid, pwd->pw_dir); 842 843 krb_afslog_uid_home(NULL, NULL, pwd->pw_uid, pwd->pw_dir); 844 845 #ifdef KRB5 846 /* XXX */ 847 if (kerberos_status) { 848 krb5_ccache ccache; 849 krb5_error_code status; 850 851 status = krb5_cc_resolve (context, tkfile, &ccache); 852 if (!status) { 853 krb5_afslog_uid_home(context,ccache,NULL,NULL, 854 pwd->pw_uid, pwd->pw_dir); 855 krb5_cc_close (context, ccache); 856 } 857 } 858 #endif /* KRB5 */ 859 } 860 #endif /* KRB4 */ 861 execle (pwd->pw_shell, pwd->pw_shell, "-c", cmd, NULL, env); 862 err(1, "exec %s", pwd->pw_shell); 863 } 864 865 struct getargs args[] = { 866 { NULL, 'a', arg_flag, &do_addr_verify }, 867 { "keepalive", 'n', arg_negative_flag, &do_keepalive }, 868 { "inetd", 'i', arg_negative_flag, &do_inetd, 869 "Not started from inetd" }, 870 #if defined(KRB4) || defined(KRB5) 871 { "kerberos", 'k', arg_flag, &do_kerberos, 872 "Implement kerberised services" }, 873 { "encrypt", 'x', arg_flag, &do_encrypt, 874 "Implement encrypted service" }, 875 #endif 876 { "rhosts", 'l', arg_negative_flag, &do_rhosts, 877 "Don't check users .rhosts" }, 878 { "port", 'p', arg_string, &port_str, "Use this port", 879 "port" }, 880 { "vacuous", 'v', arg_flag, &do_vacuous, 881 "Don't accept non-kerberised connections" }, 882 #ifdef KRB4 883 { NULL, 'P', arg_negative_flag, &do_newpag, 884 "Don't put process in new PAG" }, 885 #endif 886 /* compatibility flag: */ 887 { NULL, 'L', arg_flag, &do_log }, 888 { "version", 0, arg_flag, &do_version }, 889 { "help", 0, arg_flag, &do_help } 890 }; 891 892 static void 893 usage (int ret) 894 { 895 if(isatty(STDIN_FILENO)) 896 arg_printusage (args, 897 sizeof(args) / sizeof(args[0]), 898 NULL, 899 ""); 900 else 901 syslog (LOG_ERR, "Usage: %s [-ikxlvPL] [-p port]", getprogname()); 902 exit (ret); 903 } 904 905 906 int 907 main(int argc, char **argv) 908 { 909 int optind = 0; 910 int on = 1; 911 912 setprogname (argv[0]); 913 roken_openlog ("rshd", LOG_ODELAY | LOG_PID, LOG_AUTH); 914 915 if (getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, 916 &optind)) 917 usage(1); 918 919 if(do_help) 920 usage (0); 921 922 if (do_version) { 923 print_version(NULL); 924 exit(0); 925 } 926 927 #if defined(KRB4) || defined(KRB5) 928 if (do_encrypt) 929 do_kerberos = 1; 930 931 if(do_kerberos) 932 do_kerberos = DO_KRB4 | DO_KRB5; 933 #endif 934 935 if (do_keepalive && 936 setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, 937 sizeof(on)) < 0) 938 syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); 939 940 /* set SO_LINGER? */ 941 942 #ifdef KRB5 943 if((do_kerberos & DO_KRB5) && krb5_init_context (&context) != 0) 944 do_kerberos &= ~DO_KRB5; 945 #endif 946 947 if (!do_inetd) { 948 int error; 949 struct addrinfo *ai = NULL, hints; 950 char portstr[NI_MAXSERV]; 951 952 memset (&hints, 0, sizeof(hints)); 953 hints.ai_flags = AI_PASSIVE; 954 hints.ai_socktype = SOCK_STREAM; 955 hints.ai_family = PF_UNSPEC; 956 957 if(port_str != NULL) { 958 error = getaddrinfo (NULL, port_str, &hints, &ai); 959 if (error) 960 errx (1, "getaddrinfo: %s", gai_strerror (error)); 961 } 962 if (ai == NULL) { 963 #if defined(KRB4) || defined(KRB5) 964 if (do_kerberos) { 965 if (do_encrypt) { 966 error = getaddrinfo(NULL, "ekshell", &hints, &ai); 967 if(error == EAI_NONAME) { 968 snprintf(portstr, sizeof(portstr), "%d", 545); 969 error = getaddrinfo(NULL, portstr, &hints, &ai); 970 } 971 if(error) 972 errx (1, "getaddrinfo: %s", gai_strerror (error)); 973 } else { 974 error = getaddrinfo(NULL, "kshell", &hints, &ai); 975 if(error == EAI_NONAME) { 976 snprintf(portstr, sizeof(portstr), "%d", 544); 977 error = getaddrinfo(NULL, portstr, &hints, &ai); 978 } 979 if(error) 980 errx (1, "getaddrinfo: %s", gai_strerror (error)); 981 } 982 } else 983 #endif 984 { 985 error = getaddrinfo(NULL, "shell", &hints, &ai); 986 if(error == EAI_NONAME) { 987 snprintf(portstr, sizeof(portstr), "%d", 514); 988 error = getaddrinfo(NULL, portstr, &hints, &ai); 989 } 990 if(error) 991 errx (1, "getaddrinfo: %s", gai_strerror (error)); 992 } 993 } 994 mini_inetd_addrinfo (ai); 995 freeaddrinfo(ai); 996 } 997 998 signal (SIGPIPE, SIG_IGN); 999 1000 doit (); 1001 return 0; 1002 } 1003