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