2 * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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
35 #include "login_locl.h"
36 __RCSID("$Heimdal: rshd.c 21515 2007-07-12 12:47:07Z lha $"
40 login_access( struct passwd
*user
, char *from
);
42 read_limits_conf(const char *file
, const struct passwd
*pwd
);
44 #ifdef NEED_IRUSEROK_PROTO
45 int iruserok(uint32_t, int, const char *, const char *);
48 enum auth_method auth_method
;
52 krb5_keyblock
*keyblock
;
57 des_key_schedule schedule
;
62 krb5_ccache ccache
, ccache2
;
63 int kerberos_status
= 0;
68 static int do_unique_tkfile
= 0;
69 static char tkfile
[MAXPATHLEN
] = "";
71 static int do_inetd
= 1;
72 static char *port_str
;
73 static int do_rhosts
= 1;
74 static int do_kerberos
= 0;
77 static int do_vacuous
= 0;
78 static int do_log
= 1;
79 static int do_newpag
= 1;
80 static int do_addr_verify
= 0;
81 static int do_keepalive
= 1;
82 static int do_version
;
83 static int do_help
= 0;
86 syslog_and_die (const char *m
, ...)
87 __attribute__ ((format (printf
, 1, 2)));
90 syslog_and_die (const char *m
, ...)
95 vsyslog (LOG_ERR
, m
, args
);
101 fatal (int, const char*, const char *, ...)
102 __attribute__ ((noreturn
, format (printf
, 3, 4)));
105 fatal (int sock
, const char *what
, const char *m
, ...)
113 len
= vsnprintf (buf
+ 1, sizeof(buf
) - 1, m
, args
);
114 len
= min(len
, sizeof(buf
) - 1);
117 syslog (LOG_ERR
, "%s: %m: %s", what
, buf
+ 1);
119 syslog (LOG_ERR
, "%s", buf
+ 1);
120 net_write (sock
, buf
, len
+ 1);
125 read_str (int s
, size_t sz
, char *expl
)
127 char *str
= malloc(sz
);
130 fatal(s
, NULL
, "%s too long", expl
);
131 while(p
< str
+ sz
) {
132 if(net_read(s
, p
, 1) != 1)
133 syslog_and_die("read: %m");
138 fatal(s
, NULL
, "%s too long", expl
);
142 recv_bsd_auth (int s
, u_char
*buf
,
143 struct sockaddr_in
*thisaddr
,
144 struct sockaddr_in
*thataddr
,
145 char **client_username
,
146 char **server_username
,
151 *client_username
= read_str (s
, USERNAME_SZ
, "local username");
152 *server_username
= read_str (s
, USERNAME_SZ
, "remote username");
153 *cmd
= read_str (s
, ARG_MAX
+ 1, "command");
154 pwd
= getpwnam(*server_username
);
156 fatal(s
, NULL
, "Login incorrect.");
157 if (iruserok(thataddr
->sin_addr
.s_addr
, pwd
->pw_uid
== 0,
158 *client_username
, *server_username
))
159 fatal(s
, NULL
, "Login incorrect.");
165 recv_krb4_auth (int s
, u_char
*buf
,
166 struct sockaddr
*thisaddr
,
167 struct sockaddr
*thataddr
,
168 char **client_username
,
169 char **server_username
,
176 char instance
[INST_SZ
+ 1];
177 char version
[KRB_SENDAUTH_VLEN
+ 1];
179 if (memcmp (buf
, KRB_SENDAUTH_VERS
, 4) != 0)
181 if (net_read (s
, buf
+ 4, KRB_SENDAUTH_VLEN
- 4) !=
182 KRB_SENDAUTH_VLEN
- 4)
183 syslog_and_die ("reading auth info: %m");
184 if (memcmp (buf
, KRB_SENDAUTH_VERS
, KRB_SENDAUTH_VLEN
) != 0)
185 syslog_and_die("unrecognized auth protocol: %.8s", buf
);
187 options
= KOPT_IGNORE_PROTOCOL
;
189 options
|= KOPT_DO_MUTUAL
;
190 k_getsockinst (s
, instance
, sizeof(instance
));
191 status
= krb_recvauth (options
,
196 (struct sockaddr_in
*)thataddr
,
197 (struct sockaddr_in
*)thisaddr
,
202 if (status
!= KSUCCESS
)
203 syslog_and_die ("recvauth: %s", krb_get_err_text(status
));
204 if (strncmp (version
, KCMD_OLD_VERSION
, KRB_SENDAUTH_VLEN
) != 0)
205 syslog_and_die ("bad version: %s", version
);
207 *server_username
= read_str (s
, USERNAME_SZ
, "remote username");
208 if (kuserok (&auth
, *server_username
) != 0)
209 fatal (s
, NULL
, "Permission denied.");
210 *cmd
= read_str (s
, ARG_MAX
+ 1, "command");
212 syslog(LOG_INFO
|LOG_AUTH
,
213 "kerberos v4 shell from %s on %s as %s, cmd '%.80s'",
214 krb_unparse_name_long(auth
.pname
, auth
.pinst
, auth
.prealm
),
216 inet_ntoa(((struct sockaddr_in
*)thataddr
)->sin_addr
),
220 memcpy (iv
, auth
.session
, sizeof(iv
));
229 save_krb5_creds (int s
,
230 krb5_auth_context auth_context
,
231 krb5_principal client
)
235 krb5_data remote_cred
;
237 krb5_data_zero (&remote_cred
);
238 ret
= krb5_read_message (context
, (void *)&s
, &remote_cred
);
240 krb5_data_free(&remote_cred
);
243 if (remote_cred
.length
== 0)
246 ret
= krb5_cc_gen_new(context
, &krb5_mcc_ops
, &ccache
);
248 krb5_data_free(&remote_cred
);
252 krb5_cc_initialize(context
,ccache
,client
);
253 ret
= krb5_rd_cred2(context
, auth_context
, ccache
, &remote_cred
);
255 syslog(LOG_INFO
|LOG_AUTH
,
256 "reading creds: %s", krb5_get_err_text(context
, ret
));
257 krb5_data_free (&remote_cred
);
264 krb5_start_session (void)
269 ret
= krb5_cc_resolve (context
, tkfile
, &ccache2
);
271 estr
= krb5_get_error_string(context
);
272 syslog(LOG_WARNING
, "resolve cred cache %s: %s",
274 estr
? estr
: krb5_get_err_text(context
, ret
));
276 krb5_cc_destroy(context
, ccache
);
280 ret
= krb5_cc_copy_cache (context
, ccache
, ccache2
);
282 estr
= krb5_get_error_string(context
);
283 syslog(LOG_WARNING
, "storing credentials: %s",
284 estr
? estr
: krb5_get_err_text(context
, ret
));
286 krb5_cc_destroy(context
, ccache
);
290 krb5_cc_close(context
, ccache2
);
291 krb5_cc_destroy(context
, ccache
);
295 static int protocol_version
;
298 match_kcmd_version(const void *data
, const char *version
)
300 if(strcmp(version
, KCMD_NEW_VERSION
) == 0) {
301 protocol_version
= 2;
304 if(strcmp(version
, KCMD_OLD_VERSION
) == 0) {
305 protocol_version
= 1;
306 key_usage
= KRB5_KU_OTHER_ENCRYPTED
;
314 recv_krb5_auth (int s
, u_char
*buf
,
315 struct sockaddr
*thisaddr
,
316 struct sockaddr
*thataddr
,
317 char **client_username
,
318 char **server_username
,
322 krb5_auth_context auth_context
= NULL
;
324 krb5_error_code status
;
325 krb5_data cksum_data
;
326 krb5_principal server
;
329 if (memcmp (buf
, "\x00\x00\x00\x13", 4) != 0)
331 len
= (buf
[0] << 24) | (buf
[1] << 16) | (buf
[2] << 8) | (buf
[3]);
333 if (net_read(s
, buf
, len
) != len
)
334 syslog_and_die ("reading auth info: %m");
335 if (len
!= sizeof(KRB5_SENDAUTH_VERSION
)
336 || memcmp (buf
, KRB5_SENDAUTH_VERSION
, len
) != 0)
337 syslog_and_die ("bad sendauth version: %.8s", buf
);
339 status
= krb5_sock_to_principal (context
,
345 syslog_and_die ("krb5_sock_to_principal: %s",
346 krb5_get_err_text(context
, status
));
348 status
= krb5_recvauth_match_version(context
,
354 KRB5_RECVAUTH_IGNORE_VERSION
,
357 krb5_free_principal (context
, server
);
359 syslog_and_die ("krb5_recvauth: %s",
360 krb5_get_err_text(context
, status
));
362 *server_username
= read_str (s
, USERNAME_SZ
, "remote username");
363 *cmd
= read_str (s
, ARG_MAX
+ 1, "command");
364 *client_username
= read_str (s
, ARG_MAX
+ 1, "local username");
366 if(protocol_version
== 2) {
367 status
= krb5_auth_con_getremotesubkey(context
, auth_context
,
369 if(status
!= 0 || keyblock
== NULL
)
370 syslog_and_die("failed to get remote subkey");
371 } else if(protocol_version
== 1) {
372 status
= krb5_auth_con_getkey (context
, auth_context
, &keyblock
);
373 if(status
!= 0 || keyblock
== NULL
)
374 syslog_and_die("failed to get key");
376 if (status
!= 0 || keyblock
== NULL
)
377 syslog_and_die ("krb5_auth_con_getkey: %s",
378 krb5_get_err_text(context
, status
));
380 status
= krb5_crypto_init(context
, keyblock
, 0, &crypto
);
382 syslog_and_die("krb5_crypto_init: %s",
383 krb5_get_err_text(context
, status
));
386 cksum_data
.length
= asprintf (&str
,
388 ntohs(socket_get_port (thisaddr
)),
392 syslog_and_die ("asprintf: out of memory");
393 cksum_data
.data
= str
;
395 status
= krb5_verify_authenticator_checksum(context
,
401 syslog_and_die ("krb5_verify_authenticator_checksum: %s",
402 krb5_get_err_text(context
, status
));
404 free (cksum_data
.data
);
406 if (strncmp (*client_username
, "-u ", 3) == 0) {
407 do_unique_tkfile
= 1;
408 memmove (*client_username
, *client_username
+ 3,
409 strlen(*client_username
) - 2);
412 if (strncmp (*client_username
, "-U ", 3) == 0) {
413 char *end
, *temp_tkfile
;
415 do_unique_tkfile
= 1;
416 if (strncmp (*client_username
+ 3, "FILE:", 5) == 0) {
417 temp_tkfile
= tkfile
;
419 strlcpy (tkfile
, "FILE:", sizeof(tkfile
));
420 temp_tkfile
= tkfile
+ 5;
422 end
= strchr(*client_username
+ 3,' ');
424 syslog_and_die("missing argument after -U");
425 snprintf(temp_tkfile
, sizeof(tkfile
) - (temp_tkfile
- tkfile
),
427 (int)(end
- *client_username
- 3),
428 *client_username
+ 3);
429 memmove (*client_username
, end
+ 1, strlen(end
+1)+1);
432 kerberos_status
= save_krb5_creds (s
, auth_context
, ticket
->client
);
434 if(!krb5_kuserok (context
,
437 fatal (s
, NULL
, "Permission denied.");
439 if (strncmp (*cmd
, "-x ", 3) == 0) {
441 memmove (*cmd
, *cmd
+ 3, strlen(*cmd
) - 2);
444 fatal (s
, NULL
, "Encryption is required.");
451 if (krb5_unparse_name (context
, ticket
->client
, &name
) == 0) {
454 if (inet_ntop (thataddr
->sa_family
,
455 socket_get_address (thataddr
),
456 addr_str
, sizeof(addr_str
)) == NULL
)
457 strlcpy (addr_str
, "unknown address",
460 syslog(LOG_INFO
|LOG_AUTH
,
461 "kerberos v5 shell from %s on %s as %s, cmd '%.80s'",
475 rshd_loop (int from0
, int to0
,
485 if(from0
>= FD_SETSIZE
|| from1
>= FD_SETSIZE
|| from2
>= FD_SETSIZE
)
486 errx (1, "fd too large");
489 if(auth_method
== AUTH_KRB5
&& protocol_version
== 2)
490 init_ivecs(0, have_errsock
);
493 FD_ZERO(&real_readset
);
494 FD_SET(from0
, &real_readset
);
495 FD_SET(from1
, &real_readset
);
496 FD_SET(from2
, &real_readset
);
497 max_fd
= max(from0
, max(from1
, from2
)) + 1;
499 buf
= malloc(max(RSHD_BUFSIZ
, RSH_BUFSIZ
));
501 syslog_and_die("out of memory");
505 fd_set readset
= real_readset
;
507 ret
= select (max_fd
, &readset
, NULL
, NULL
, NULL
);
512 syslog_and_die ("select: %m");
514 if (FD_ISSET(from0
, &readset
)) {
515 ret
= do_read (from0
, buf
, RSHD_BUFSIZ
, ivec_in
[0]);
517 syslog_and_die ("read: %m");
521 FD_CLR(from0
, &real_readset
);
523 net_write (to0
, buf
, ret
);
525 if (FD_ISSET(from1
, &readset
)) {
526 ret
= read (from1
, buf
, RSH_BUFSIZ
);
528 syslog_and_die ("read: %m");
532 FD_CLR(from1
, &real_readset
);
536 do_write (to1
, buf
, ret
, ivec_out
[0]);
538 if (FD_ISSET(from2
, &readset
)) {
539 ret
= read (from2
, buf
, RSH_BUFSIZ
);
541 syslog_and_die ("read: %m");
545 FD_CLR(from2
, &real_readset
);
549 do_write (to2
, buf
, ret
, ivec_out
[1]);
555 * Used by `setup_copier' to create some pipe-like means of
556 * communcation. Real pipes would probably be the best thing, but
557 * then the shell doesn't understand it's talking to rshd. If
558 * socketpair doesn't work everywhere, some autoconf magic would have
561 * If it fails creating the `pipe', it aborts by calling fatal.
565 pipe_a_like (int fd
[2])
567 if (socketpair (AF_UNIX
, SOCK_STREAM
, 0, fd
) < 0)
568 fatal (STDOUT_FILENO
, "socketpair", "Pipe creation failed.");
572 * Start a child process and leave the parent copying data to and from it. */
575 setup_copier (int have_errsock
)
577 int p0
[2], p1
[2], p2
[2];
585 fatal (STDOUT_FILENO
, "fork", "Could not create child process.");
586 if (pid
== 0) { /* child */
590 dup2 (p0
[0], STDIN_FILENO
);
591 dup2 (p1
[1], STDOUT_FILENO
);
592 dup2 (p2
[1], STDERR_FILENO
);
596 } else { /* parent */
601 if (net_write (STDOUT_FILENO
, "", 1) != 1)
602 fatal (STDOUT_FILENO
, "net_write", "Write failure.");
604 rshd_loop (STDIN_FILENO
, p0
[1],
605 STDOUT_FILENO
, p1
[0],
606 STDERR_FILENO
, p2
[0],
612 * Is `port' a ``reserverd'' port?
616 is_reserved(u_short port
)
618 return ntohs(port
) < IPPORT_RESERVED
;
622 * Set the necessary part of the environment in `env'.
626 setup_environment (char ***env
, const struct passwd
*pwd
)
635 i
= read_environment(_PATH_ETC_ENVIRONMENT
, env
);
637 for (j
= 0; j
< i
; j
++) {
638 if (!strncmp(e
[j
], "PATH=", 5)) {
644 e
= realloc(e
, (i
+ 7) * sizeof(char *));
646 if (asprintf (&e
[i
++], "USER=%s", pwd
->pw_name
) == -1)
647 syslog_and_die ("asprintf: out of memory");
648 if (asprintf (&e
[i
++], "HOME=%s", pwd
->pw_dir
) == -1)
649 syslog_and_die ("asprintf: out of memory");
650 if (asprintf (&e
[i
++], "SHELL=%s", pwd
->pw_shell
) == -1)
651 syslog_and_die ("asprintf: out of memory");
653 if (asprintf (&e
[i
++], "PATH=%s", _PATH_DEFPATH
) == -1)
654 syslog_and_die ("asprintf: out of memory");
656 asprintf (&e
[i
++], "SSH_CLIENT=only_to_make_bash_happy");
657 if (do_unique_tkfile
)
658 if (asprintf (&e
[i
++], "KRB5CCNAME=%s", tkfile
) == -1)
659 syslog_and_die ("asprintf: out of memory");
669 struct sockaddr_storage thisaddr_ss
;
670 struct sockaddr
*thisaddr
= (struct sockaddr
*)&thisaddr_ss
;
671 struct sockaddr_storage thataddr_ss
;
672 struct sockaddr
*thataddr
= (struct sockaddr
*)&thataddr_ss
;
673 struct sockaddr_storage erraddr_ss
;
674 struct sockaddr
*erraddr
= (struct sockaddr
*)&erraddr_ss
;
675 socklen_t thisaddr_len
, thataddr_len
;
678 char *client_user
= NULL
, *server_user
= NULL
, *cmd
= NULL
;
680 int s
= STDIN_FILENO
;
683 char that_host
[NI_MAXHOST
];
685 thisaddr_len
= sizeof(thisaddr_ss
);
686 if (getsockname (s
, thisaddr
, &thisaddr_len
) < 0)
687 syslog_and_die("getsockname: %m");
688 thataddr_len
= sizeof(thataddr_ss
);
689 if (getpeername (s
, thataddr
, &thataddr_len
) < 0)
690 syslog_and_die ("getpeername: %m");
692 /* check for V4MAPPED addresses? */
694 if (do_kerberos
== 0 && !is_reserved(socket_get_port(thataddr
)))
695 fatal(s
, NULL
, "Permission denied.");
700 if (net_read (s
, p
, 1) != 1)
701 syslog_and_die ("reading port number: %m");
704 else if (isdigit(*p
))
705 port
= port
* 10 + *p
- '0';
707 syslog_and_die ("non-digit in port number: %c", *p
);
710 if (do_kerberos
== 0 && !is_reserved(htons(port
)))
711 fatal(s
, NULL
, "Permission denied.");
714 int priv_port
= IPPORT_RESERVED
- 1;
717 * There's no reason to require a ``privileged'' port number
718 * here, but for some reason the brain dead rsh clients
722 erraddr
->sa_family
= thataddr
->sa_family
;
723 socket_set_address_and_port (erraddr
,
724 socket_get_address (thataddr
),
728 * we only do reserved port for IPv4
731 if (erraddr
->sa_family
== AF_INET
)
732 errsock
= rresvport (&priv_port
);
734 errsock
= socket (erraddr
->sa_family
, SOCK_STREAM
, 0);
736 syslog_and_die ("socket: %m");
737 if (connect (errsock
,
739 socket_sockaddr_size (erraddr
)) < 0) {
740 syslog (LOG_WARNING
, "connect: %m");
746 if (net_read (s
, buf
, 4) != 4)
747 syslog_and_die ("reading auth info: %m");
750 if ((do_kerberos
& DO_KRB4
) &&
751 recv_krb4_auth (s
, buf
, thisaddr
, thataddr
,
755 auth_method
= AUTH_KRB4
;
759 if((do_kerberos
& DO_KRB5
) &&
760 recv_krb5_auth (s
, buf
, thisaddr
, thataddr
,
764 auth_method
= AUTH_KRB5
;
767 syslog_and_die ("unrecognized auth protocol: %x %x %x %x",
768 buf
[0], buf
[1], buf
[2], buf
[3]);
770 if(recv_bsd_auth (s
, buf
,
771 (struct sockaddr_in
*)thisaddr
,
772 (struct sockaddr_in
*)thataddr
,
776 auth_method
= AUTH_BROKEN
;
778 printf("Remote host requires Kerberos authentication\n");
782 syslog_and_die("recv_bsd_auth failed");
785 if (client_user
== NULL
|| server_user
== NULL
|| cmd
== NULL
)
786 syslog_and_die("mising client/server/cmd");
788 pwd
= getpwnam (server_user
);
790 fatal (s
, NULL
, "Login incorrect.");
792 if (*pwd
->pw_shell
== '\0')
793 pwd
->pw_shell
= _PATH_BSHELL
;
795 if (pwd
->pw_uid
!= 0 && access (_PATH_NOLOGIN
, F_OK
) == 0)
796 fatal (s
, NULL
, "Login disabled.");
799 ret
= getnameinfo_verified (thataddr
, thataddr_len
,
800 that_host
, sizeof(that_host
),
803 fatal (s
, NULL
, "getnameinfo: %s", gai_strerror(ret
));
805 if (login_access(pwd
, that_host
) == 0) {
806 syslog(LOG_NOTICE
, "Kerberos rsh denied to %s from %s",
807 server_user
, that_host
);
808 fatal(s
, NULL
, "Permission denied.");
816 sp
= getspnam(server_user
);
818 today
= time(0)/(24L * 60 * 60);
819 if (sp
->sp_expire
> 0)
820 if (today
> sp
->sp_expire
)
821 fatal(s
, NULL
, "Account has expired.");
828 if (setlogin(pwd
->pw_name
) < 0)
829 syslog(LOG_ERR
, "setlogin() failed: %m");
833 if (setpcred (pwd
->pw_name
, NULL
) == -1)
834 syslog(LOG_ERR
, "setpcred() failure: %m");
835 #endif /* HAVE_SETPCRED */
837 /* Apply limits if not root */
838 if(pwd
->pw_uid
!= 0) {
839 const char *file
= _PATH_LIMITS_CONF
;
840 read_limits_conf(file
, pwd
);
843 if (initgroups (pwd
->pw_name
, pwd
->pw_gid
) < 0)
844 fatal (s
, "initgroups", "Login incorrect.");
846 if (setgid(pwd
->pw_gid
) < 0)
847 fatal (s
, "setgid", "Login incorrect.");
849 if (setuid (pwd
->pw_uid
) < 0)
850 fatal (s
, "setuid", "Login incorrect.");
852 if (chdir (pwd
->pw_dir
) < 0)
853 fatal (s
, "chdir", "Remote directory.");
856 if (dup2 (errsock
, STDERR_FILENO
) < 0)
857 fatal (s
, "dup2", "Cannot dup stderr.");
860 if (dup2 (STDOUT_FILENO
, STDERR_FILENO
) < 0)
861 fatal (s
, "dup2", "Cannot dup stderr.");
868 if (!do_unique_tkfile
)
869 snprintf(tkfile
,sizeof(tkfile
),"FILE:/tmp/krb5cc_%lu",
870 (unsigned long)pwd
->pw_uid
);
871 else if (*tkfile
=='\0') {
872 snprintf(tkfile
,sizeof(tkfile
),"FILE:/tmp/krb5cc_XXXXXX");
873 fd
= mkstemp(tkfile
+5);
879 krb5_start_session();
883 setup_environment (&env
, pwd
);
886 setup_copier (errsock
>= 0);
888 if (net_write (s
, "", 1) != 1)
889 fatal (s
, "net_write", "write failed");
892 #if defined(KRB4) || defined(KRB5)
899 if (k_afs_cell_of_file (pwd
->pw_dir
, cell
, sizeof(cell
)) == 0)
900 krb_afslog_uid_home (cell
, NULL
, pwd
->pw_uid
, pwd
->pw_dir
);
901 krb_afslog_uid_home(NULL
, NULL
, pwd
->pw_uid
, pwd
->pw_dir
);
906 if (kerberos_status
) {
908 krb5_error_code status
;
910 status
= krb5_cc_resolve (context
, tkfile
, &ccache
);
912 if (k_afs_cell_of_file (pwd
->pw_dir
, cell
, sizeof(cell
)) == 0)
913 krb5_afslog_uid_home(context
, ccache
, cell
, NULL
,
914 pwd
->pw_uid
, pwd
->pw_dir
);
915 krb5_afslog_uid_home(context
, ccache
, NULL
, NULL
,
916 pwd
->pw_uid
, pwd
->pw_dir
);
917 krb5_cc_close (context
, ccache
);
922 #endif /* KRB5 || KRB4 */
923 execle (pwd
->pw_shell
, pwd
->pw_shell
, "-c", cmd
, NULL
, env
);
924 err(1, "exec %s", pwd
->pw_shell
);
927 struct getargs args
[] = {
928 { NULL
, 'a', arg_flag
, &do_addr_verify
},
929 { "keepalive", 'n', arg_negative_flag
, &do_keepalive
},
930 { "inetd", 'i', arg_negative_flag
, &do_inetd
,
931 "Not started from inetd" },
932 #if defined(KRB4) || defined(KRB5)
933 { "kerberos", 'k', arg_flag
, &do_kerberos
,
934 "Implement kerberised services" },
935 { "encrypt", 'x', arg_flag
, &do_encrypt
,
936 "Implement encrypted service" },
938 { "rhosts", 'l', arg_negative_flag
, &do_rhosts
,
939 "Don't check users .rhosts" },
940 { "port", 'p', arg_string
, &port_str
, "Use this port",
942 { "vacuous", 'v', arg_flag
, &do_vacuous
,
943 "Don't accept non-kerberised connections" },
944 #if defined(KRB4) || defined(KRB5)
945 { NULL
, 'P', arg_negative_flag
, &do_newpag
,
946 "Don't put process in new PAG" },
948 /* compatibility flag: */
949 { NULL
, 'L', arg_flag
, &do_log
},
950 { "version", 0, arg_flag
, &do_version
},
951 { "help", 0, arg_flag
, &do_help
}
957 if(isatty(STDIN_FILENO
))
958 arg_printusage (args
,
959 sizeof(args
) / sizeof(args
[0]),
963 syslog (LOG_ERR
, "Usage: %s [-ikxlvPL] [-p port]", getprogname());
969 main(int argc
, char **argv
)
974 setprogname (argv
[0]);
975 roken_openlog ("rshd", LOG_ODELAY
| LOG_PID
, LOG_AUTH
);
977 if (getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
,
989 #if defined(KRB4) || defined(KRB5)
994 do_kerberos
= DO_KRB4
| DO_KRB5
;
998 if((do_kerberos
& DO_KRB5
) && krb5_init_context (&context
) != 0)
999 do_kerberos
&= ~DO_KRB5
;
1004 struct addrinfo
*ai
= NULL
, hints
;
1005 char portstr
[NI_MAXSERV
];
1007 memset (&hints
, 0, sizeof(hints
));
1008 hints
.ai_flags
= AI_PASSIVE
;
1009 hints
.ai_socktype
= SOCK_STREAM
;
1010 hints
.ai_family
= PF_UNSPEC
;
1012 if(port_str
!= NULL
) {
1013 error
= getaddrinfo (NULL
, port_str
, &hints
, &ai
);
1015 errx (1, "getaddrinfo: %s", gai_strerror (error
));
1018 #if defined(KRB4) || defined(KRB5)
1021 error
= getaddrinfo(NULL
, "ekshell", &hints
, &ai
);
1022 if(error
== EAI_NONAME
) {
1023 snprintf(portstr
, sizeof(portstr
), "%d", 545);
1024 error
= getaddrinfo(NULL
, portstr
, &hints
, &ai
);
1027 errx (1, "getaddrinfo: %s", gai_strerror (error
));
1029 error
= getaddrinfo(NULL
, "kshell", &hints
, &ai
);
1030 if(error
== EAI_NONAME
) {
1031 snprintf(portstr
, sizeof(portstr
), "%d", 544);
1032 error
= getaddrinfo(NULL
, portstr
, &hints
, &ai
);
1035 errx (1, "getaddrinfo: %s", gai_strerror (error
));
1040 error
= getaddrinfo(NULL
, "shell", &hints
, &ai
);
1041 if(error
== EAI_NONAME
) {
1042 snprintf(portstr
, sizeof(portstr
), "%d", 514);
1043 error
= getaddrinfo(NULL
, portstr
, &hints
, &ai
);
1046 errx (1, "getaddrinfo: %s", gai_strerror (error
));
1049 mini_inetd_addrinfo (ai
);
1054 setsockopt(0, SOL_SOCKET
, SO_KEEPALIVE
, (char *)&on
,
1056 syslog(LOG_WARNING
, "setsockopt (SO_KEEPALIVE): %m");
1058 /* set SO_LINGER? */
1060 signal (SIGPIPE
, SIG_IGN
);