2 * Copyright (c) 1997-2006 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
38 login_access( struct passwd
*user
, char *from
);
40 enum auth_method auth_method
;
44 krb5_keyblock
*keyblock
;
49 des_key_schedule schedule
;
54 krb5_ccache ccache
, ccache2
;
55 int kerberos_status
= 0;
60 static int do_unique_tkfile
= 0;
61 static char tkfile
[MAXPATHLEN
] = "";
63 static int do_inetd
= 1;
64 static char *port_str
;
65 static int do_rhosts
= 1;
66 static int do_kerberos
= 0;
69 static int do_vacuous
= 0;
70 static int do_log
= 1;
71 static int do_newpag
= 1;
72 static int do_addr_verify
= 0;
73 static int do_keepalive
= 1;
74 static int do_version
;
75 static int do_help
= 0;
78 syslog_and_die (const char *m
, ...)
79 __attribute__ ((format (printf
, 1, 2)));
82 syslog_and_die (const char *m
, ...)
87 vsyslog (LOG_ERR
, m
, args
);
93 fatal (int, const char*, const char *, ...)
94 __attribute__ ((noreturn
, format (printf
, 3, 4)));
97 fatal (int sock
, const char *what
, const char *m
, ...)
105 len
= vsnprintf (buf
+ 1, sizeof(buf
) - 1, m
, args
);
106 len
= min(len
, sizeof(buf
) - 1);
109 syslog (LOG_ERR
, "%s: %m: %s", what
, buf
+ 1);
111 syslog (LOG_ERR
, "%s", buf
+ 1);
112 net_write (sock
, buf
, len
+ 1);
117 read_str (int s
, size_t sz
, char *expl
)
119 char *str
= malloc(sz
);
122 fatal(s
, NULL
, "%s too long", expl
);
123 while(p
< str
+ sz
) {
124 if(net_read(s
, p
, 1) != 1)
125 syslog_and_die("read: %m");
130 fatal(s
, NULL
, "%s too long", expl
);
134 recv_bsd_auth (int s
, u_char
*buf
,
135 struct sockaddr_in
*thisaddr
,
136 struct sockaddr_in
*thataddr
,
137 char **client_username
,
138 char **server_username
,
143 *client_username
= read_str (s
, USERNAME_SZ
, "local username");
144 *server_username
= read_str (s
, USERNAME_SZ
, "remote username");
145 *cmd
= read_str (s
, ARG_MAX
+ 1, "command");
146 pwd
= getpwnam(*server_username
);
148 fatal(s
, NULL
, "Login incorrect.");
149 if (iruserok(thataddr
->sin_addr
.s_addr
, pwd
->pw_uid
== 0,
150 *client_username
, *server_username
))
151 fatal(s
, NULL
, "Login incorrect.");
157 recv_krb4_auth (int s
, u_char
*buf
,
158 struct sockaddr
*thisaddr
,
159 struct sockaddr
*thataddr
,
160 char **client_username
,
161 char **server_username
,
168 char instance
[INST_SZ
+ 1];
169 char version
[KRB_SENDAUTH_VLEN
+ 1];
171 if (memcmp (buf
, KRB_SENDAUTH_VERS
, 4) != 0)
173 if (net_read (s
, buf
+ 4, KRB_SENDAUTH_VLEN
- 4) !=
174 KRB_SENDAUTH_VLEN
- 4)
175 syslog_and_die ("reading auth info: %m");
176 if (memcmp (buf
, KRB_SENDAUTH_VERS
, KRB_SENDAUTH_VLEN
) != 0)
177 syslog_and_die("unrecognized auth protocol: %.8s", buf
);
179 options
= KOPT_IGNORE_PROTOCOL
;
181 options
|= KOPT_DO_MUTUAL
;
182 k_getsockinst (s
, instance
, sizeof(instance
));
183 status
= krb_recvauth (options
,
188 (struct sockaddr_in
*)thataddr
,
189 (struct sockaddr_in
*)thisaddr
,
194 if (status
!= KSUCCESS
)
195 syslog_and_die ("recvauth: %s", krb_get_err_text(status
));
196 if (strncmp (version
, KCMD_OLD_VERSION
, KRB_SENDAUTH_VLEN
) != 0)
197 syslog_and_die ("bad version: %s", version
);
199 *server_username
= read_str (s
, USERNAME_SZ
, "remote username");
200 if (kuserok (&auth
, *server_username
) != 0)
201 fatal (s
, NULL
, "Permission denied.");
202 *cmd
= read_str (s
, ARG_MAX
+ 1, "command");
204 syslog(LOG_INFO
|LOG_AUTH
,
205 "kerberos v4 shell from %s on %s as %s, cmd '%.80s'",
206 krb_unparse_name_long(auth
.pname
, auth
.pinst
, auth
.prealm
),
208 inet_ntoa(((struct sockaddr_in
*)thataddr
)->sin_addr
),
212 memcpy (iv
, auth
.session
, sizeof(iv
));
221 save_krb5_creds (int s
,
222 krb5_auth_context auth_context
,
223 krb5_principal client
)
227 krb5_data remote_cred
;
229 krb5_data_zero (&remote_cred
);
230 ret
= krb5_read_message (context
, (void *)&s
, &remote_cred
);
232 krb5_data_free(&remote_cred
);
235 if (remote_cred
.length
== 0)
238 ret
= krb5_cc_gen_new(context
, &krb5_mcc_ops
, &ccache
);
240 krb5_data_free(&remote_cred
);
244 krb5_cc_initialize(context
,ccache
,client
);
245 ret
= krb5_rd_cred2(context
, auth_context
, ccache
, &remote_cred
);
247 syslog(LOG_INFO
|LOG_AUTH
,
248 "reading creds: %s", krb5_get_err_text(context
, ret
));
249 krb5_data_free (&remote_cred
);
256 krb5_start_session (void)
261 ret
= krb5_cc_resolve (context
, tkfile
, &ccache2
);
263 estr
= krb5_get_error_string(context
);
264 syslog(LOG_WARNING
, "resolve cred cache %s: %s",
266 estr
? estr
: krb5_get_err_text(context
, ret
));
268 krb5_cc_destroy(context
, ccache
);
272 ret
= krb5_cc_copy_cache (context
, ccache
, ccache2
);
274 estr
= krb5_get_error_string(context
);
275 syslog(LOG_WARNING
, "storing credentials: %s",
276 estr
? estr
: krb5_get_err_text(context
, ret
));
278 krb5_cc_destroy(context
, ccache
);
282 krb5_cc_close(context
, ccache2
);
283 krb5_cc_destroy(context
, ccache
);
287 static int protocol_version
;
290 match_kcmd_version(const void *data
, const char *version
)
292 if(strcmp(version
, KCMD_NEW_VERSION
) == 0) {
293 protocol_version
= 2;
296 if(strcmp(version
, KCMD_OLD_VERSION
) == 0) {
297 protocol_version
= 1;
298 key_usage
= KRB5_KU_OTHER_ENCRYPTED
;
306 recv_krb5_auth (int s
, u_char
*buf
,
307 struct sockaddr
*thisaddr
,
308 struct sockaddr
*thataddr
,
309 char **client_username
,
310 char **server_username
,
314 krb5_auth_context auth_context
= NULL
;
316 krb5_error_code status
;
317 krb5_data cksum_data
;
318 krb5_principal server
;
320 if (memcmp (buf
, "\x00\x00\x00\x13", 4) != 0)
322 len
= (buf
[0] << 24) | (buf
[1] << 16) | (buf
[2] << 8) | (buf
[3]);
324 if (net_read(s
, buf
, len
) != len
)
325 syslog_and_die ("reading auth info: %m");
326 if (len
!= sizeof(KRB5_SENDAUTH_VERSION
)
327 || memcmp (buf
, KRB5_SENDAUTH_VERSION
, len
) != 0)
328 syslog_and_die ("bad sendauth version: %.8s", buf
);
330 status
= krb5_sock_to_principal (context
,
336 syslog_and_die ("krb5_sock_to_principal: %s",
337 krb5_get_err_text(context
, status
));
339 status
= krb5_recvauth_match_version(context
,
345 KRB5_RECVAUTH_IGNORE_VERSION
,
348 krb5_free_principal (context
, server
);
350 syslog_and_die ("krb5_recvauth: %s",
351 krb5_get_err_text(context
, status
));
353 *server_username
= read_str (s
, USERNAME_SZ
, "remote username");
354 *cmd
= read_str (s
, ARG_MAX
+ 1, "command");
355 *client_username
= read_str (s
, ARG_MAX
+ 1, "local username");
357 if(protocol_version
== 2) {
358 status
= krb5_auth_con_getremotesubkey(context
, auth_context
,
360 if(status
!= 0 || keyblock
== NULL
)
361 syslog_and_die("failed to get remote subkey");
362 } else if(protocol_version
== 1) {
363 status
= krb5_auth_con_getkey (context
, auth_context
, &keyblock
);
364 if(status
!= 0 || keyblock
== NULL
)
365 syslog_and_die("failed to get key");
367 if (status
!= 0 || keyblock
== NULL
)
368 syslog_and_die ("krb5_auth_con_getkey: %s",
369 krb5_get_err_text(context
, status
));
371 status
= krb5_crypto_init(context
, keyblock
, 0, &crypto
);
373 syslog_and_die("krb5_crypto_init: %s",
374 krb5_get_err_text(context
, status
));
377 cksum_data
.length
= asprintf ((char **)&cksum_data
.data
,
379 ntohs(socket_get_port (thisaddr
)),
382 if (cksum_data
.length
== -1)
383 syslog_and_die ("asprintf: out of memory");
385 status
= krb5_verify_authenticator_checksum(context
,
391 syslog_and_die ("krb5_verify_authenticator_checksum: %s",
392 krb5_get_err_text(context
, status
));
394 free (cksum_data
.data
);
396 if (strncmp (*client_username
, "-u ", 3) == 0) {
397 do_unique_tkfile
= 1;
398 memmove (*client_username
, *client_username
+ 3,
399 strlen(*client_username
) - 2);
402 if (strncmp (*client_username
, "-U ", 3) == 0) {
403 char *end
, *temp_tkfile
;
405 do_unique_tkfile
= 1;
406 if (strncmp (*client_username
+ 3, "FILE:", 5) == 0) {
407 temp_tkfile
= tkfile
;
409 strlcpy (tkfile
, "FILE:", sizeof(tkfile
));
410 temp_tkfile
= tkfile
+ 5;
412 end
= strchr(*client_username
+ 3,' ');
414 syslog_and_die("missing argument after -U");
415 snprintf(temp_tkfile
, sizeof(tkfile
) - (temp_tkfile
- tkfile
),
417 (int)(end
- *client_username
- 3),
418 *client_username
+ 3);
419 memmove (*client_username
, end
+ 1, strlen(end
+1)+1);
422 kerberos_status
= save_krb5_creds (s
, auth_context
, ticket
->client
);
424 if(!krb5_kuserok (context
,
427 fatal (s
, NULL
, "Permission denied.");
429 if (strncmp (*cmd
, "-x ", 3) == 0) {
431 memmove (*cmd
, *cmd
+ 3, strlen(*cmd
) - 2);
434 fatal (s
, NULL
, "Encryption is required.");
441 if (krb5_unparse_name (context
, ticket
->client
, &name
) == 0) {
444 if (inet_ntop (thataddr
->sa_family
,
445 socket_get_address (thataddr
),
446 addr_str
, sizeof(addr_str
)) == NULL
)
447 strlcpy (addr_str
, "unknown address",
450 syslog(LOG_INFO
|LOG_AUTH
,
451 "kerberos v5 shell from %s on %s as %s, cmd '%.80s'",
465 rshd_loop (int from0
, int to0
,
475 if(from0
>= FD_SETSIZE
|| from1
>= FD_SETSIZE
|| from2
>= FD_SETSIZE
)
476 errx (1, "fd too large");
479 if(auth_method
== AUTH_KRB5
&& protocol_version
== 2)
480 init_ivecs(0, have_errsock
);
483 FD_ZERO(&real_readset
);
484 FD_SET(from0
, &real_readset
);
485 FD_SET(from1
, &real_readset
);
486 FD_SET(from2
, &real_readset
);
487 max_fd
= max(from0
, max(from1
, from2
)) + 1;
489 buf
= malloc(max(RSHD_BUFSIZ
, RSH_BUFSIZ
));
491 syslog_and_die("out of memory");
495 fd_set readset
= real_readset
;
497 ret
= select (max_fd
, &readset
, NULL
, NULL
, NULL
);
502 syslog_and_die ("select: %m");
504 if (FD_ISSET(from0
, &readset
)) {
505 ret
= do_read (from0
, buf
, RSHD_BUFSIZ
, ivec_in
[0]);
507 syslog_and_die ("read: %m");
511 FD_CLR(from0
, &real_readset
);
513 net_write (to0
, buf
, ret
);
515 if (FD_ISSET(from1
, &readset
)) {
516 ret
= read (from1
, buf
, RSH_BUFSIZ
);
518 syslog_and_die ("read: %m");
522 FD_CLR(from1
, &real_readset
);
526 do_write (to1
, buf
, ret
, ivec_out
[0]);
528 if (FD_ISSET(from2
, &readset
)) {
529 ret
= read (from2
, buf
, RSH_BUFSIZ
);
531 syslog_and_die ("read: %m");
535 FD_CLR(from2
, &real_readset
);
539 do_write (to2
, buf
, ret
, ivec_out
[1]);
545 * Used by `setup_copier' to create some pipe-like means of
546 * communcation. Real pipes would probably be the best thing, but
547 * then the shell doesn't understand it's talking to rshd. If
548 * socketpair doesn't work everywhere, some autoconf magic would have
551 * If it fails creating the `pipe', it aborts by calling fatal.
555 pipe_a_like (int fd
[2])
557 if (socketpair (AF_UNIX
, SOCK_STREAM
, 0, fd
) < 0)
558 fatal (STDOUT_FILENO
, "socketpair", "Pipe creation failed.");
562 * Start a child process and leave the parent copying data to and from it. */
565 setup_copier (int have_errsock
)
567 int p0
[2], p1
[2], p2
[2];
575 fatal (STDOUT_FILENO
, "fork", "Could not create child process.");
576 if (pid
== 0) { /* child */
580 dup2 (p0
[0], STDIN_FILENO
);
581 dup2 (p1
[1], STDOUT_FILENO
);
582 dup2 (p2
[1], STDERR_FILENO
);
586 } else { /* parent */
591 if (net_write (STDOUT_FILENO
, "", 1) != 1)
592 fatal (STDOUT_FILENO
, "net_write", "Write failure.");
594 rshd_loop (STDIN_FILENO
, p0
[1],
595 STDOUT_FILENO
, p1
[0],
596 STDERR_FILENO
, p2
[0],
602 * Is `port' a ``reserverd'' port?
606 is_reserved(u_short port
)
608 return ntohs(port
) < IPPORT_RESERVED
;
612 * Set the necessary part of the environment in `env'.
616 setup_environment (char ***env
, const struct passwd
*pwd
)
625 i
= read_environment(_PATH_ETC_ENVIRONMENT
, env
);
627 for (j
= 0; j
< i
; j
++) {
628 if (!strncmp(e
[j
], "PATH=", 5)) {
634 e
= realloc(e
, (i
+ 7) * sizeof(char *));
636 if (asprintf (&e
[i
++], "USER=%s", pwd
->pw_name
) == -1)
637 syslog_and_die ("asprintf: out of memory");
638 if (asprintf (&e
[i
++], "HOME=%s", pwd
->pw_dir
) == -1)
639 syslog_and_die ("asprintf: out of memory");
640 if (asprintf (&e
[i
++], "SHELL=%s", pwd
->pw_shell
) == -1)
641 syslog_and_die ("asprintf: out of memory");
643 if (asprintf (&e
[i
++], "PATH=%s", _PATH_DEFPATH
) == -1)
644 syslog_and_die ("asprintf: out of memory");
646 asprintf (&e
[i
++], "SSH_CLIENT=only_to_make_bash_happy");
647 if (do_unique_tkfile
)
648 if (asprintf (&e
[i
++], "KRB5CCNAME=%s", tkfile
) == -1)
649 syslog_and_die ("asprintf: out of memory");
659 struct sockaddr_storage thisaddr_ss
;
660 struct sockaddr
*thisaddr
= (struct sockaddr
*)&thisaddr_ss
;
661 struct sockaddr_storage thataddr_ss
;
662 struct sockaddr
*thataddr
= (struct sockaddr
*)&thataddr_ss
;
663 struct sockaddr_storage erraddr_ss
;
664 struct sockaddr
*erraddr
= (struct sockaddr
*)&erraddr_ss
;
665 socklen_t thisaddr_len
, thataddr_len
;
668 char *client_user
= NULL
, *server_user
= NULL
, *cmd
= NULL
;
670 int s
= STDIN_FILENO
;
673 char that_host
[NI_MAXHOST
];
675 thisaddr_len
= sizeof(thisaddr_ss
);
676 if (getsockname (s
, thisaddr
, &thisaddr_len
) < 0)
677 syslog_and_die("getsockname: %m");
678 thataddr_len
= sizeof(thataddr_ss
);
679 if (getpeername (s
, thataddr
, &thataddr_len
) < 0)
680 syslog_and_die ("getpeername: %m");
682 /* check for V4MAPPED addresses? */
684 if (do_kerberos
== 0 && !is_reserved(socket_get_port(thataddr
)))
685 fatal(s
, NULL
, "Permission denied.");
690 if (net_read (s
, p
, 1) != 1)
691 syslog_and_die ("reading port number: %m");
694 else if (isdigit(*p
))
695 port
= port
* 10 + *p
- '0';
697 syslog_and_die ("non-digit in port number: %c", *p
);
700 if (do_kerberos
== 0 && !is_reserved(htons(port
)))
701 fatal(s
, NULL
, "Permission denied.");
704 int priv_port
= IPPORT_RESERVED
- 1;
707 * There's no reason to require a ``privileged'' port number
708 * here, but for some reason the brain dead rsh clients
712 erraddr
->sa_family
= thataddr
->sa_family
;
713 socket_set_address_and_port (erraddr
,
714 socket_get_address (thataddr
),
718 * we only do reserved port for IPv4
721 if (erraddr
->sa_family
== AF_INET
)
722 errsock
= rresvport (&priv_port
);
724 errsock
= socket (erraddr
->sa_family
, SOCK_STREAM
, 0);
726 syslog_and_die ("socket: %m");
727 if (connect (errsock
,
729 socket_sockaddr_size (erraddr
)) < 0) {
730 syslog (LOG_WARNING
, "connect: %m");
736 if (net_read (s
, buf
, 4) != 4)
737 syslog_and_die ("reading auth info: %m");
740 if ((do_kerberos
& DO_KRB4
) &&
741 recv_krb4_auth (s
, buf
, thisaddr
, thataddr
,
745 auth_method
= AUTH_KRB4
;
749 if((do_kerberos
& DO_KRB5
) &&
750 recv_krb5_auth (s
, buf
, thisaddr
, thataddr
,
754 auth_method
= AUTH_KRB5
;
757 syslog_and_die ("unrecognized auth protocol: %x %x %x %x",
758 buf
[0], buf
[1], buf
[2], buf
[3]);
760 if(recv_bsd_auth (s
, buf
,
761 (struct sockaddr_in
*)thisaddr
,
762 (struct sockaddr_in
*)thataddr
,
766 auth_method
= AUTH_BROKEN
;
768 printf("Remote host requires Kerberos authentication\n");
772 syslog_and_die("recv_bsd_auth failed");
775 if (client_user
== NULL
|| server_user
== NULL
|| cmd
== NULL
)
776 syslog_and_die("mising client/server/cmd");
778 pwd
= getpwnam (server_user
);
780 fatal (s
, NULL
, "Login incorrect.");
782 if (*pwd
->pw_shell
== '\0')
783 pwd
->pw_shell
= _PATH_BSHELL
;
785 if (pwd
->pw_uid
!= 0 && access (_PATH_NOLOGIN
, F_OK
) == 0)
786 fatal (s
, NULL
, "Login disabled.");
789 ret
= getnameinfo_verified (thataddr
, thataddr_len
,
790 that_host
, sizeof(that_host
),
793 fatal (s
, NULL
, "getnameinfo: %s", gai_strerror(ret
));
795 if (login_access(pwd
, that_host
) == 0) {
796 syslog(LOG_NOTICE
, "Kerberos rsh denied to %s from %s",
797 server_user
, that_host
);
798 fatal(s
, NULL
, "Permission denied.");
806 sp
= getspnam(server_user
);
808 today
= time(0)/(24L * 60 * 60);
809 if (sp
->sp_expire
> 0)
810 if (today
> sp
->sp_expire
)
811 fatal(s
, NULL
, "Account has expired.");
818 if (setlogin(pwd
->pw_name
) < 0)
819 syslog(LOG_ERR
, "setlogin() failed: %m");
823 if (setpcred (pwd
->pw_name
, NULL
) == -1)
824 syslog(LOG_ERR
, "setpcred() failure: %m");
825 #endif /* HAVE_SETPCRED */
827 if (initgroups (pwd
->pw_name
, pwd
->pw_gid
) < 0)
828 fatal (s
, "initgroups", "Login incorrect.");
830 if (setgid(pwd
->pw_gid
) < 0)
831 fatal (s
, "setgid", "Login incorrect.");
833 if (setuid (pwd
->pw_uid
) < 0)
834 fatal (s
, "setuid", "Login incorrect.");
836 if (chdir (pwd
->pw_dir
) < 0)
837 fatal (s
, "chdir", "Remote directory.");
840 if (dup2 (errsock
, STDERR_FILENO
) < 0)
841 fatal (s
, "dup2", "Cannot dup stderr.");
844 if (dup2 (STDOUT_FILENO
, STDERR_FILENO
) < 0)
845 fatal (s
, "dup2", "Cannot dup stderr.");
852 if (!do_unique_tkfile
)
853 snprintf(tkfile
,sizeof(tkfile
),"FILE:/tmp/krb5cc_%lu",
854 (unsigned long)pwd
->pw_uid
);
855 else if (*tkfile
=='\0') {
856 snprintf(tkfile
,sizeof(tkfile
),"FILE:/tmp/krb5cc_XXXXXX");
857 fd
= mkstemp(tkfile
+5);
863 krb5_start_session();
867 setup_environment (&env
, pwd
);
870 setup_copier (errsock
>= 0);
872 if (net_write (s
, "", 1) != 1)
873 fatal (s
, "net_write", "write failed");
876 #if defined(KRB4) || defined(KRB5)
883 if (k_afs_cell_of_file (pwd
->pw_dir
, cell
, sizeof(cell
)) == 0)
884 krb_afslog_uid_home (cell
, NULL
, pwd
->pw_uid
, pwd
->pw_dir
);
885 krb_afslog_uid_home(NULL
, NULL
, pwd
->pw_uid
, pwd
->pw_dir
);
890 if (kerberos_status
) {
892 krb5_error_code status
;
894 status
= krb5_cc_resolve (context
, tkfile
, &ccache
);
896 if (k_afs_cell_of_file (pwd
->pw_dir
, cell
, sizeof(cell
)) == 0)
897 krb5_afslog_uid_home(context
, ccache
, cell
, NULL
,
898 pwd
->pw_uid
, pwd
->pw_dir
);
899 krb5_afslog_uid_home(context
, ccache
, NULL
, NULL
,
900 pwd
->pw_uid
, pwd
->pw_dir
);
901 krb5_cc_close (context
, ccache
);
906 #endif /* KRB5 || KRB4 */
907 execle (pwd
->pw_shell
, pwd
->pw_shell
, "-c", cmd
, NULL
, env
);
908 err(1, "exec %s", pwd
->pw_shell
);
911 struct getargs args
[] = {
912 { NULL
, 'a', arg_flag
, &do_addr_verify
},
913 { "keepalive", 'n', arg_negative_flag
, &do_keepalive
},
914 { "inetd", 'i', arg_negative_flag
, &do_inetd
,
915 "Not started from inetd" },
916 #if defined(KRB4) || defined(KRB5)
917 { "kerberos", 'k', arg_flag
, &do_kerberos
,
918 "Implement kerberised services" },
919 { "encrypt", 'x', arg_flag
, &do_encrypt
,
920 "Implement encrypted service" },
922 { "rhosts", 'l', arg_negative_flag
, &do_rhosts
,
923 "Don't check users .rhosts" },
924 { "port", 'p', arg_string
, &port_str
, "Use this port",
926 { "vacuous", 'v', arg_flag
, &do_vacuous
,
927 "Don't accept non-kerberised connections" },
928 #if defined(KRB4) || defined(KRB5)
929 { NULL
, 'P', arg_negative_flag
, &do_newpag
,
930 "Don't put process in new PAG" },
932 /* compatibility flag: */
933 { NULL
, 'L', arg_flag
, &do_log
},
934 { "version", 0, arg_flag
, &do_version
},
935 { "help", 0, arg_flag
, &do_help
}
941 if(isatty(STDIN_FILENO
))
942 arg_printusage (args
,
943 sizeof(args
) / sizeof(args
[0]),
947 syslog (LOG_ERR
, "Usage: %s [-ikxlvPL] [-p port]", getprogname());
953 main(int argc
, char **argv
)
958 setprogname (argv
[0]);
959 roken_openlog ("rshd", LOG_ODELAY
| LOG_PID
, LOG_AUTH
);
961 if (getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
,
973 #if defined(KRB4) || defined(KRB5)
978 do_kerberos
= DO_KRB4
| DO_KRB5
;
982 if((do_kerberos
& DO_KRB5
) && krb5_init_context (&context
) != 0)
983 do_kerberos
&= ~DO_KRB5
;
988 struct addrinfo
*ai
= NULL
, hints
;
989 char portstr
[NI_MAXSERV
];
991 memset (&hints
, 0, sizeof(hints
));
992 hints
.ai_flags
= AI_PASSIVE
;
993 hints
.ai_socktype
= SOCK_STREAM
;
994 hints
.ai_family
= PF_UNSPEC
;
996 if(port_str
!= NULL
) {
997 error
= getaddrinfo (NULL
, port_str
, &hints
, &ai
);
999 errx (1, "getaddrinfo: %s", gai_strerror (error
));
1002 #if defined(KRB4) || defined(KRB5)
1005 error
= getaddrinfo(NULL
, "ekshell", &hints
, &ai
);
1006 if(error
== EAI_NONAME
) {
1007 snprintf(portstr
, sizeof(portstr
), "%d", 545);
1008 error
= getaddrinfo(NULL
, portstr
, &hints
, &ai
);
1011 errx (1, "getaddrinfo: %s", gai_strerror (error
));
1013 error
= getaddrinfo(NULL
, "kshell", &hints
, &ai
);
1014 if(error
== EAI_NONAME
) {
1015 snprintf(portstr
, sizeof(portstr
), "%d", 544);
1016 error
= getaddrinfo(NULL
, portstr
, &hints
, &ai
);
1019 errx (1, "getaddrinfo: %s", gai_strerror (error
));
1024 error
= getaddrinfo(NULL
, "shell", &hints
, &ai
);
1025 if(error
== EAI_NONAME
) {
1026 snprintf(portstr
, sizeof(portstr
), "%d", 514);
1027 error
= getaddrinfo(NULL
, portstr
, &hints
, &ai
);
1030 errx (1, "getaddrinfo: %s", gai_strerror (error
));
1033 mini_inetd_addrinfo (ai
);
1038 setsockopt(0, SOL_SOCKET
, SO_KEEPALIVE
, (char *)&on
,
1040 syslog(LOG_WARNING
, "setsockopt (SO_KEEPALIVE): %m");
1042 /* set SO_LINGER? */
1044 signal (SIGPIPE
, SIG_IGN
);