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"
39 login_access( struct passwd
*user
, char *from
);
41 read_limits_conf(const char *file
, const struct passwd
*pwd
);
43 #ifdef NEED_IRUSEROK_PROTO
44 int iruserok(uint32_t, int, const char *, const char *);
47 enum auth_method auth_method
;
51 krb5_keyblock
*keyblock
;
56 des_key_schedule schedule
;
61 krb5_ccache ccache
, ccache2
;
62 int kerberos_status
= 0;
67 static int do_unique_tkfile
= 0;
68 static char tkfile
[MAXPATHLEN
] = "";
70 static int do_inetd
= 1;
71 static char *port_str
;
72 static int do_rhosts
= 1;
73 static int do_kerberos
= 0;
76 static int do_vacuous
= 0;
77 static int do_log
= 1;
78 static int do_newpag
= 1;
79 static int do_addr_verify
= 0;
80 static int do_keepalive
= 1;
81 static int do_version
;
82 static int do_help
= 0;
85 syslog_and_die (const char *m
, ...)
86 __attribute__ ((format (printf
, 1, 2)));
89 syslog_and_die (const char *m
, ...)
94 vsyslog (LOG_ERR
, m
, args
);
100 fatal (int, const char*, const char *, ...)
101 __attribute__ ((noreturn
, format (printf
, 3, 4)));
104 fatal (int sock
, const char *what
, const char *m
, ...)
112 len
= vsnprintf (buf
+ 1, sizeof(buf
) - 1, m
, args
);
113 len
= min(len
, sizeof(buf
) - 1);
116 syslog (LOG_ERR
, "%s: %m: %s", what
, buf
+ 1);
118 syslog (LOG_ERR
, "%s", buf
+ 1);
119 net_write (sock
, buf
, len
+ 1);
124 read_str (int s
, size_t sz
, char *expl
)
126 char *str
= malloc(sz
);
129 fatal(s
, NULL
, "%s too long", expl
);
130 while(p
< str
+ sz
) {
131 if(net_read(s
, p
, 1) != 1)
132 syslog_and_die("read: %m");
137 fatal(s
, NULL
, "%s too long", expl
);
141 recv_bsd_auth (int s
, u_char
*buf
,
142 struct sockaddr_in
*thisaddr
,
143 struct sockaddr_in
*thataddr
,
144 char **client_username
,
145 char **server_username
,
150 *client_username
= read_str (s
, USERNAME_SZ
, "local username");
151 *server_username
= read_str (s
, USERNAME_SZ
, "remote username");
152 *cmd
= read_str (s
, ARG_MAX
+ 1, "command");
153 pwd
= getpwnam(*server_username
);
155 fatal(s
, NULL
, "Login incorrect.");
156 if (iruserok(thataddr
->sin_addr
.s_addr
, pwd
->pw_uid
== 0,
157 *client_username
, *server_username
))
158 fatal(s
, NULL
, "Login incorrect.");
164 recv_krb4_auth (int s
, u_char
*buf
,
165 struct sockaddr
*thisaddr
,
166 struct sockaddr
*thataddr
,
167 char **client_username
,
168 char **server_username
,
175 char instance
[INST_SZ
+ 1];
176 char version
[KRB_SENDAUTH_VLEN
+ 1];
178 if (memcmp (buf
, KRB_SENDAUTH_VERS
, 4) != 0)
180 if (net_read (s
, buf
+ 4, KRB_SENDAUTH_VLEN
- 4) !=
181 KRB_SENDAUTH_VLEN
- 4)
182 syslog_and_die ("reading auth info: %m");
183 if (memcmp (buf
, KRB_SENDAUTH_VERS
, KRB_SENDAUTH_VLEN
) != 0)
184 syslog_and_die("unrecognized auth protocol: %.8s", buf
);
186 options
= KOPT_IGNORE_PROTOCOL
;
188 options
|= KOPT_DO_MUTUAL
;
189 k_getsockinst (s
, instance
, sizeof(instance
));
190 status
= krb_recvauth (options
,
195 (struct sockaddr_in
*)thataddr
,
196 (struct sockaddr_in
*)thisaddr
,
201 if (status
!= KSUCCESS
)
202 syslog_and_die ("recvauth: %s", krb_get_err_text(status
));
203 if (strncmp (version
, KCMD_OLD_VERSION
, KRB_SENDAUTH_VLEN
) != 0)
204 syslog_and_die ("bad version: %s", version
);
206 *server_username
= read_str (s
, USERNAME_SZ
, "remote username");
207 if (kuserok (&auth
, *server_username
) != 0)
208 fatal (s
, NULL
, "Permission denied.");
209 *cmd
= read_str (s
, ARG_MAX
+ 1, "command");
211 syslog(LOG_INFO
|LOG_AUTH
,
212 "kerberos v4 shell from %s on %s as %s, cmd '%.80s'",
213 krb_unparse_name_long(auth
.pname
, auth
.pinst
, auth
.prealm
),
215 inet_ntoa(((struct sockaddr_in
*)thataddr
)->sin_addr
),
219 memcpy (iv
, auth
.session
, sizeof(iv
));
228 save_krb5_creds (int s
,
229 krb5_auth_context auth_context
,
230 krb5_principal client
)
234 krb5_data remote_cred
;
236 krb5_data_zero (&remote_cred
);
237 ret
= krb5_read_message (context
, (void *)&s
, &remote_cred
);
239 krb5_data_free(&remote_cred
);
242 if (remote_cred
.length
== 0)
245 ret
= krb5_cc_gen_new(context
, &krb5_mcc_ops
, &ccache
);
247 krb5_data_free(&remote_cred
);
251 krb5_cc_initialize(context
,ccache
,client
);
252 ret
= krb5_rd_cred2(context
, auth_context
, ccache
, &remote_cred
);
254 syslog(LOG_INFO
|LOG_AUTH
,
255 "reading creds: %s", krb5_get_err_text(context
, ret
));
256 krb5_data_free (&remote_cred
);
263 krb5_start_session (void)
268 ret
= krb5_cc_resolve (context
, tkfile
, &ccache2
);
270 estr
= krb5_get_error_string(context
);
271 syslog(LOG_WARNING
, "resolve cred cache %s: %s",
273 estr
? estr
: krb5_get_err_text(context
, ret
));
275 krb5_cc_destroy(context
, ccache
);
279 ret
= krb5_cc_copy_cache (context
, ccache
, ccache2
);
281 estr
= krb5_get_error_string(context
);
282 syslog(LOG_WARNING
, "storing credentials: %s",
283 estr
? estr
: krb5_get_err_text(context
, ret
));
285 krb5_cc_destroy(context
, ccache
);
289 krb5_cc_close(context
, ccache2
);
290 krb5_cc_destroy(context
, ccache
);
294 static int protocol_version
;
297 match_kcmd_version(const void *data
, const char *version
)
299 if(strcmp(version
, KCMD_NEW_VERSION
) == 0) {
300 protocol_version
= 2;
303 if(strcmp(version
, KCMD_OLD_VERSION
) == 0) {
304 protocol_version
= 1;
305 key_usage
= KRB5_KU_OTHER_ENCRYPTED
;
313 recv_krb5_auth (int s
, u_char
*buf
,
314 struct sockaddr
*thisaddr
,
315 struct sockaddr
*thataddr
,
316 char **client_username
,
317 char **server_username
,
321 krb5_auth_context auth_context
= NULL
;
323 krb5_error_code status
;
324 krb5_data cksum_data
;
325 krb5_principal server
;
328 if (memcmp (buf
, "\x00\x00\x00\x13", 4) != 0)
330 len
= (buf
[0] << 24) | (buf
[1] << 16) | (buf
[2] << 8) | (buf
[3]);
332 if (net_read(s
, buf
, len
) != len
)
333 syslog_and_die ("reading auth info: %m");
334 if (len
!= sizeof(KRB5_SENDAUTH_VERSION
)
335 || memcmp (buf
, KRB5_SENDAUTH_VERSION
, len
) != 0)
336 syslog_and_die ("bad sendauth version: %.8s", buf
);
338 status
= krb5_sock_to_principal (context
,
344 syslog_and_die ("krb5_sock_to_principal: %s",
345 krb5_get_err_text(context
, status
));
347 status
= krb5_recvauth_match_version(context
,
353 KRB5_RECVAUTH_IGNORE_VERSION
,
356 krb5_free_principal (context
, server
);
358 syslog_and_die ("krb5_recvauth: %s",
359 krb5_get_err_text(context
, status
));
361 *server_username
= read_str (s
, USERNAME_SZ
, "remote username");
362 *cmd
= read_str (s
, ARG_MAX
+ 1, "command");
363 *client_username
= read_str (s
, ARG_MAX
+ 1, "local username");
365 if(protocol_version
== 2) {
366 status
= krb5_auth_con_getremotesubkey(context
, auth_context
,
368 if(status
!= 0 || keyblock
== NULL
)
369 syslog_and_die("failed to get remote subkey");
370 } else if(protocol_version
== 1) {
371 status
= krb5_auth_con_getkey (context
, auth_context
, &keyblock
);
372 if(status
!= 0 || keyblock
== NULL
)
373 syslog_and_die("failed to get key");
375 if (status
!= 0 || keyblock
== NULL
)
376 syslog_and_die ("krb5_auth_con_getkey: %s",
377 krb5_get_err_text(context
, status
));
379 status
= krb5_crypto_init(context
, keyblock
, 0, &crypto
);
381 syslog_and_die("krb5_crypto_init: %s",
382 krb5_get_err_text(context
, status
));
385 cksum_data
.length
= asprintf (&str
,
387 ntohs(socket_get_port (thisaddr
)),
391 syslog_and_die ("asprintf: out of memory");
392 cksum_data
.data
= str
;
394 status
= krb5_verify_authenticator_checksum(context
,
400 syslog_and_die ("krb5_verify_authenticator_checksum: %s",
401 krb5_get_err_text(context
, status
));
403 free (cksum_data
.data
);
405 if (strncmp (*client_username
, "-u ", 3) == 0) {
406 do_unique_tkfile
= 1;
407 memmove (*client_username
, *client_username
+ 3,
408 strlen(*client_username
) - 2);
411 if (strncmp (*client_username
, "-U ", 3) == 0) {
412 char *end
, *temp_tkfile
;
414 do_unique_tkfile
= 1;
415 if (strncmp (*client_username
+ 3, "FILE:", 5) == 0) {
416 temp_tkfile
= tkfile
;
418 strlcpy (tkfile
, "FILE:", sizeof(tkfile
));
419 temp_tkfile
= tkfile
+ 5;
421 end
= strchr(*client_username
+ 3,' ');
423 syslog_and_die("missing argument after -U");
424 snprintf(temp_tkfile
, sizeof(tkfile
) - (temp_tkfile
- tkfile
),
426 (int)(end
- *client_username
- 3),
427 *client_username
+ 3);
428 memmove (*client_username
, end
+ 1, strlen(end
+1)+1);
431 kerberos_status
= save_krb5_creds (s
, auth_context
, ticket
->client
);
433 if(!krb5_kuserok (context
,
436 fatal (s
, NULL
, "Permission denied.");
438 if (strncmp (*cmd
, "-x ", 3) == 0) {
440 memmove (*cmd
, *cmd
+ 3, strlen(*cmd
) - 2);
443 fatal (s
, NULL
, "Encryption is required.");
450 if (krb5_unparse_name (context
, ticket
->client
, &name
) == 0) {
453 if (inet_ntop (thataddr
->sa_family
,
454 socket_get_address (thataddr
),
455 addr_str
, sizeof(addr_str
)) == NULL
)
456 strlcpy (addr_str
, "unknown address",
459 syslog(LOG_INFO
|LOG_AUTH
,
460 "kerberos v5 shell from %s on %s as %s, cmd '%.80s'",
474 rshd_loop (int from0
, int to0
,
484 if(from0
>= FD_SETSIZE
|| from1
>= FD_SETSIZE
|| from2
>= FD_SETSIZE
)
485 errx (1, "fd too large");
488 if(auth_method
== AUTH_KRB5
&& protocol_version
== 2)
489 init_ivecs(0, have_errsock
);
492 FD_ZERO(&real_readset
);
493 FD_SET(from0
, &real_readset
);
494 FD_SET(from1
, &real_readset
);
495 FD_SET(from2
, &real_readset
);
496 max_fd
= max(from0
, max(from1
, from2
)) + 1;
498 buf
= malloc(max(RSHD_BUFSIZ
, RSH_BUFSIZ
));
500 syslog_and_die("out of memory");
504 fd_set readset
= real_readset
;
506 ret
= select (max_fd
, &readset
, NULL
, NULL
, NULL
);
511 syslog_and_die ("select: %m");
513 if (FD_ISSET(from0
, &readset
)) {
514 ret
= do_read (from0
, buf
, RSHD_BUFSIZ
, ivec_in
[0]);
516 syslog_and_die ("read: %m");
520 FD_CLR(from0
, &real_readset
);
522 net_write (to0
, buf
, ret
);
524 if (FD_ISSET(from1
, &readset
)) {
525 ret
= read (from1
, buf
, RSH_BUFSIZ
);
527 syslog_and_die ("read: %m");
531 FD_CLR(from1
, &real_readset
);
535 do_write (to1
, buf
, ret
, ivec_out
[0]);
537 if (FD_ISSET(from2
, &readset
)) {
538 ret
= read (from2
, buf
, RSH_BUFSIZ
);
540 syslog_and_die ("read: %m");
544 FD_CLR(from2
, &real_readset
);
548 do_write (to2
, buf
, ret
, ivec_out
[1]);
554 * Used by `setup_copier' to create some pipe-like means of
555 * communcation. Real pipes would probably be the best thing, but
556 * then the shell doesn't understand it's talking to rshd. If
557 * socketpair doesn't work everywhere, some autoconf magic would have
560 * If it fails creating the `pipe', it aborts by calling fatal.
564 pipe_a_like (int fd
[2])
566 if (socketpair (AF_UNIX
, SOCK_STREAM
, 0, fd
) < 0)
567 fatal (STDOUT_FILENO
, "socketpair", "Pipe creation failed.");
571 * Start a child process and leave the parent copying data to and from it. */
574 setup_copier (int have_errsock
)
576 int p0
[2], p1
[2], p2
[2];
584 fatal (STDOUT_FILENO
, "fork", "Could not create child process.");
585 if (pid
== 0) { /* child */
589 dup2 (p0
[0], STDIN_FILENO
);
590 dup2 (p1
[1], STDOUT_FILENO
);
591 dup2 (p2
[1], STDERR_FILENO
);
595 } else { /* parent */
600 if (net_write (STDOUT_FILENO
, "", 1) != 1)
601 fatal (STDOUT_FILENO
, "net_write", "Write failure.");
603 rshd_loop (STDIN_FILENO
, p0
[1],
604 STDOUT_FILENO
, p1
[0],
605 STDERR_FILENO
, p2
[0],
611 * Is `port' a ``reserverd'' port?
615 is_reserved(u_short port
)
617 return ntohs(port
) < IPPORT_RESERVED
;
621 * Set the necessary part of the environment in `env'.
625 setup_environment (char ***env
, const struct passwd
*pwd
)
634 i
= read_environment(_PATH_ETC_ENVIRONMENT
, env
);
636 for (j
= 0; j
< i
; j
++) {
637 if (!strncmp(e
[j
], "PATH=", 5)) {
643 e
= realloc(e
, (i
+ 7) * sizeof(char *));
645 if (asprintf (&e
[i
++], "USER=%s", pwd
->pw_name
) == -1)
646 syslog_and_die ("asprintf: out of memory");
647 if (asprintf (&e
[i
++], "HOME=%s", pwd
->pw_dir
) == -1)
648 syslog_and_die ("asprintf: out of memory");
649 if (asprintf (&e
[i
++], "SHELL=%s", pwd
->pw_shell
) == -1)
650 syslog_and_die ("asprintf: out of memory");
652 if (asprintf (&e
[i
++], "PATH=%s", _PATH_DEFPATH
) == -1)
653 syslog_and_die ("asprintf: out of memory");
655 asprintf (&e
[i
++], "SSH_CLIENT=only_to_make_bash_happy");
656 if (do_unique_tkfile
)
657 if (asprintf (&e
[i
++], "KRB5CCNAME=%s", tkfile
) == -1)
658 syslog_and_die ("asprintf: out of memory");
668 struct sockaddr_storage thisaddr_ss
;
669 struct sockaddr
*thisaddr
= (struct sockaddr
*)&thisaddr_ss
;
670 struct sockaddr_storage thataddr_ss
;
671 struct sockaddr
*thataddr
= (struct sockaddr
*)&thataddr_ss
;
672 struct sockaddr_storage erraddr_ss
;
673 struct sockaddr
*erraddr
= (struct sockaddr
*)&erraddr_ss
;
674 socklen_t thisaddr_len
, thataddr_len
;
677 char *client_user
= NULL
, *server_user
= NULL
, *cmd
= NULL
;
679 int s
= STDIN_FILENO
;
682 char that_host
[NI_MAXHOST
];
684 thisaddr_len
= sizeof(thisaddr_ss
);
685 if (getsockname (s
, thisaddr
, &thisaddr_len
) < 0)
686 syslog_and_die("getsockname: %m");
687 thataddr_len
= sizeof(thataddr_ss
);
688 if (getpeername (s
, thataddr
, &thataddr_len
) < 0)
689 syslog_and_die ("getpeername: %m");
691 /* check for V4MAPPED addresses? */
693 if (do_kerberos
== 0 && !is_reserved(socket_get_port(thataddr
)))
694 fatal(s
, NULL
, "Permission denied.");
699 if (net_read (s
, p
, 1) != 1)
700 syslog_and_die ("reading port number: %m");
703 else if (isdigit(*p
))
704 port
= port
* 10 + *p
- '0';
706 syslog_and_die ("non-digit in port number: %c", *p
);
709 if (do_kerberos
== 0 && !is_reserved(htons(port
)))
710 fatal(s
, NULL
, "Permission denied.");
713 int priv_port
= IPPORT_RESERVED
- 1;
716 * There's no reason to require a ``privileged'' port number
717 * here, but for some reason the brain dead rsh clients
721 erraddr
->sa_family
= thataddr
->sa_family
;
722 socket_set_address_and_port (erraddr
,
723 socket_get_address (thataddr
),
727 * we only do reserved port for IPv4
730 if (erraddr
->sa_family
== AF_INET
)
731 errsock
= rresvport (&priv_port
);
733 errsock
= socket (erraddr
->sa_family
, SOCK_STREAM
, 0);
735 syslog_and_die ("socket: %m");
736 if (connect (errsock
,
738 socket_sockaddr_size (erraddr
)) < 0) {
739 syslog (LOG_WARNING
, "connect: %m");
745 if (net_read (s
, buf
, 4) != 4)
746 syslog_and_die ("reading auth info: %m");
749 if ((do_kerberos
& DO_KRB4
) &&
750 recv_krb4_auth (s
, buf
, thisaddr
, thataddr
,
754 auth_method
= AUTH_KRB4
;
758 if((do_kerberos
& DO_KRB5
) &&
759 recv_krb5_auth (s
, buf
, thisaddr
, thataddr
,
763 auth_method
= AUTH_KRB5
;
766 syslog_and_die ("unrecognized auth protocol: %x %x %x %x",
767 buf
[0], buf
[1], buf
[2], buf
[3]);
769 if(recv_bsd_auth (s
, buf
,
770 (struct sockaddr_in
*)thisaddr
,
771 (struct sockaddr_in
*)thataddr
,
775 auth_method
= AUTH_BROKEN
;
777 printf("Remote host requires Kerberos authentication\n");
781 syslog_and_die("recv_bsd_auth failed");
784 if (client_user
== NULL
|| server_user
== NULL
|| cmd
== NULL
)
785 syslog_and_die("mising client/server/cmd");
787 pwd
= getpwnam (server_user
);
789 fatal (s
, NULL
, "Login incorrect.");
791 if (*pwd
->pw_shell
== '\0')
792 pwd
->pw_shell
= _PATH_BSHELL
;
794 if (pwd
->pw_uid
!= 0 && access (_PATH_NOLOGIN
, F_OK
) == 0)
795 fatal (s
, NULL
, "Login disabled.");
798 ret
= getnameinfo_verified (thataddr
, thataddr_len
,
799 that_host
, sizeof(that_host
),
802 fatal (s
, NULL
, "getnameinfo: %s", gai_strerror(ret
));
804 if (login_access(pwd
, that_host
) == 0) {
805 syslog(LOG_NOTICE
, "Kerberos rsh denied to %s from %s",
806 server_user
, that_host
);
807 fatal(s
, NULL
, "Permission denied.");
815 sp
= getspnam(server_user
);
817 today
= time(0)/(24L * 60 * 60);
818 if (sp
->sp_expire
> 0)
819 if (today
> sp
->sp_expire
)
820 fatal(s
, NULL
, "Account has expired.");
827 if (setlogin(pwd
->pw_name
) < 0)
828 syslog(LOG_ERR
, "setlogin() failed: %m");
832 if (setpcred (pwd
->pw_name
, NULL
) == -1)
833 syslog(LOG_ERR
, "setpcred() failure: %m");
834 #endif /* HAVE_SETPCRED */
836 /* Apply limits if not root */
837 if(pwd
->pw_uid
!= 0) {
838 const char *file
= _PATH_LIMITS_CONF
;
839 read_limits_conf(file
, pwd
);
842 if (initgroups (pwd
->pw_name
, pwd
->pw_gid
) < 0)
843 fatal (s
, "initgroups", "Login incorrect.");
845 if (setgid(pwd
->pw_gid
) < 0)
846 fatal (s
, "setgid", "Login incorrect.");
848 if (setuid (pwd
->pw_uid
) < 0)
849 fatal (s
, "setuid", "Login incorrect.");
851 if (chdir (pwd
->pw_dir
) < 0)
852 fatal (s
, "chdir", "Remote directory.");
855 if (dup2 (errsock
, STDERR_FILENO
) < 0)
856 fatal (s
, "dup2", "Cannot dup stderr.");
859 if (dup2 (STDOUT_FILENO
, STDERR_FILENO
) < 0)
860 fatal (s
, "dup2", "Cannot dup stderr.");
867 if (!do_unique_tkfile
)
868 snprintf(tkfile
,sizeof(tkfile
),"FILE:/tmp/krb5cc_%lu",
869 (unsigned long)pwd
->pw_uid
);
870 else if (*tkfile
=='\0') {
871 snprintf(tkfile
,sizeof(tkfile
),"FILE:/tmp/krb5cc_XXXXXX");
872 fd
= mkstemp(tkfile
+5);
878 krb5_start_session();
882 setup_environment (&env
, pwd
);
885 setup_copier (errsock
>= 0);
887 if (net_write (s
, "", 1) != 1)
888 fatal (s
, "net_write", "write failed");
891 #if defined(KRB4) || defined(KRB5)
898 if (k_afs_cell_of_file (pwd
->pw_dir
, cell
, sizeof(cell
)) == 0)
899 krb_afslog_uid_home (cell
, NULL
, pwd
->pw_uid
, pwd
->pw_dir
);
900 krb_afslog_uid_home(NULL
, NULL
, pwd
->pw_uid
, pwd
->pw_dir
);
905 if (kerberos_status
) {
907 krb5_error_code status
;
909 status
= krb5_cc_resolve (context
, tkfile
, &ccache
);
911 if (k_afs_cell_of_file (pwd
->pw_dir
, cell
, sizeof(cell
)) == 0)
912 krb5_afslog_uid_home(context
, ccache
, cell
, NULL
,
913 pwd
->pw_uid
, pwd
->pw_dir
);
914 krb5_afslog_uid_home(context
, ccache
, NULL
, NULL
,
915 pwd
->pw_uid
, pwd
->pw_dir
);
916 krb5_cc_close (context
, ccache
);
921 #endif /* KRB5 || KRB4 */
922 execle (pwd
->pw_shell
, pwd
->pw_shell
, "-c", cmd
, NULL
, env
);
923 err(1, "exec %s", pwd
->pw_shell
);
926 struct getargs args
[] = {
927 { NULL
, 'a', arg_flag
, &do_addr_verify
},
928 { "keepalive", 'n', arg_negative_flag
, &do_keepalive
},
929 { "inetd", 'i', arg_negative_flag
, &do_inetd
,
930 "Not started from inetd" },
931 #if defined(KRB4) || defined(KRB5)
932 { "kerberos", 'k', arg_flag
, &do_kerberos
,
933 "Implement kerberised services" },
934 { "encrypt", 'x', arg_flag
, &do_encrypt
,
935 "Implement encrypted service" },
937 { "rhosts", 'l', arg_negative_flag
, &do_rhosts
,
938 "Don't check users .rhosts" },
939 { "port", 'p', arg_string
, &port_str
, "Use this port",
941 { "vacuous", 'v', arg_flag
, &do_vacuous
,
942 "Don't accept non-kerberised connections" },
943 #if defined(KRB4) || defined(KRB5)
944 { NULL
, 'P', arg_negative_flag
, &do_newpag
,
945 "Don't put process in new PAG" },
947 /* compatibility flag: */
948 { NULL
, 'L', arg_flag
, &do_log
},
949 { "version", 0, arg_flag
, &do_version
},
950 { "help", 0, arg_flag
, &do_help
}
956 if(isatty(STDIN_FILENO
))
957 arg_printusage (args
,
958 sizeof(args
) / sizeof(args
[0]),
962 syslog (LOG_ERR
, "Usage: %s [-ikxlvPL] [-p port]", getprogname());
968 main(int argc
, char **argv
)
973 setprogname (argv
[0]);
974 roken_openlog ("rshd", LOG_ODELAY
| LOG_PID
, LOG_AUTH
);
976 if (getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
,
988 #if defined(KRB4) || defined(KRB5)
993 do_kerberos
= DO_KRB4
| DO_KRB5
;
997 if((do_kerberos
& DO_KRB5
) && krb5_init_context (&context
) != 0)
998 do_kerberos
&= ~DO_KRB5
;
1003 struct addrinfo
*ai
= NULL
, hints
;
1004 char portstr
[NI_MAXSERV
];
1006 memset (&hints
, 0, sizeof(hints
));
1007 hints
.ai_flags
= AI_PASSIVE
;
1008 hints
.ai_socktype
= SOCK_STREAM
;
1009 hints
.ai_family
= PF_UNSPEC
;
1011 if(port_str
!= NULL
) {
1012 error
= getaddrinfo (NULL
, port_str
, &hints
, &ai
);
1014 errx (1, "getaddrinfo: %s", gai_strerror (error
));
1017 #if defined(KRB4) || defined(KRB5)
1020 error
= getaddrinfo(NULL
, "ekshell", &hints
, &ai
);
1021 if(error
== EAI_NONAME
) {
1022 snprintf(portstr
, sizeof(portstr
), "%d", 545);
1023 error
= getaddrinfo(NULL
, portstr
, &hints
, &ai
);
1026 errx (1, "getaddrinfo: %s", gai_strerror (error
));
1028 error
= getaddrinfo(NULL
, "kshell", &hints
, &ai
);
1029 if(error
== EAI_NONAME
) {
1030 snprintf(portstr
, sizeof(portstr
), "%d", 544);
1031 error
= getaddrinfo(NULL
, portstr
, &hints
, &ai
);
1034 errx (1, "getaddrinfo: %s", gai_strerror (error
));
1039 error
= getaddrinfo(NULL
, "shell", &hints
, &ai
);
1040 if(error
== EAI_NONAME
) {
1041 snprintf(portstr
, sizeof(portstr
), "%d", 514);
1042 error
= getaddrinfo(NULL
, portstr
, &hints
, &ai
);
1045 errx (1, "getaddrinfo: %s", gai_strerror (error
));
1048 mini_inetd_addrinfo (ai
);
1053 setsockopt(0, SOL_SOCKET
, SO_KEEPALIVE
, (char *)&on
,
1055 syslog(LOG_WARNING
, "setsockopt (SO_KEEPALIVE): %m");
1057 /* set SO_LINGER? */
1059 signal (SIGPIPE
, SIG_IGN
);