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