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 krb5_ccache ccache
, ccache2
;
57 int kerberos_status
= 0;
62 static int do_unique_tkfile
= 0;
63 static char tkfile
[MAXPATHLEN
] = "";
65 static int do_inetd
= 1;
66 static char *port_str
;
67 static int do_rhosts
= 1;
68 static int do_kerberos
= 0;
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;
79 syslog_and_die (const char *m
, ...)
80 __attribute__ ((format (printf
, 1, 2)));
83 syslog_and_die (const char *m
, ...)
88 vsyslog (LOG_ERR
, m
, args
);
94 fatal (int, const char*, const char *, ...)
95 __attribute__ ((noreturn
, format (printf
, 3, 4)));
98 fatal (int sock
, const char *what
, const char *m
, ...)
106 len
= vsnprintf (buf
+ 1, sizeof(buf
) - 1, m
, args
);
107 len
= min(len
, sizeof(buf
) - 1);
110 syslog (LOG_ERR
, "%s: %s: %s", what
, strerror(errno
), buf
+ 1);
112 syslog (LOG_ERR
, "%s", buf
+ 1);
113 net_write (sock
, buf
, len
+ 1);
118 read_str (int s
, size_t sz
, char *expl
)
120 char *str
= malloc(sz
);
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
));
131 fatal(s
, NULL
, "%s too long", expl
);
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
,
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
);
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.");
158 save_krb5_creds (int s
,
159 krb5_auth_context auth_context
,
160 krb5_principal client
)
164 krb5_data remote_cred
;
166 krb5_data_zero (&remote_cred
);
167 ret
= krb5_read_message (context
, (void *)&s
, &remote_cred
);
169 krb5_data_free(&remote_cred
);
172 if (remote_cred
.length
== 0)
175 ret
= krb5_cc_new_unique(context
, krb5_cc_type_memory
, NULL
, &ccache
);
177 krb5_data_free(&remote_cred
);
181 krb5_cc_initialize(context
,ccache
,client
);
182 ret
= krb5_rd_cred2(context
, auth_context
, ccache
, &remote_cred
);
184 syslog(LOG_INFO
|LOG_AUTH
,
185 "reading creds: %s", krb5_get_err_text(context
, ret
));
186 krb5_data_free (&remote_cred
);
193 krb5_start_session (void)
198 ret
= krb5_cc_resolve (context
, tkfile
, &ccache2
);
200 estr
= krb5_get_error_string(context
);
201 syslog(LOG_WARNING
, "resolve cred cache %s: %s",
203 estr
? estr
: krb5_get_err_text(context
, ret
));
205 krb5_cc_destroy(context
, ccache
);
209 ret
= krb5_cc_copy_cache (context
, ccache
, ccache2
);
211 estr
= krb5_get_error_string(context
);
212 syslog(LOG_WARNING
, "storing credentials: %s",
213 estr
? estr
: krb5_get_err_text(context
, ret
));
215 krb5_cc_destroy(context
, ccache
);
219 krb5_cc_close(context
, ccache2
);
220 krb5_cc_destroy(context
, ccache
);
224 static int protocol_version
;
227 match_kcmd_version(const void *data
, const char *version
)
229 if(strcmp(version
, KCMD_NEW_VERSION
) == 0) {
230 protocol_version
= 2;
233 if(strcmp(version
, KCMD_OLD_VERSION
) == 0) {
234 protocol_version
= 1;
235 key_usage
= KRB5_KU_OTHER_ENCRYPTED
;
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
,
251 krb5_auth_context auth_context
= NULL
;
253 krb5_error_code status
;
254 krb5_data cksum_data
;
255 krb5_principal server
;
258 if (memcmp (buf
, "\x00\x00\x00\x13", 4) != 0)
260 len
= (buf
[0] << 24) | (buf
[1] << 16) | (buf
[2] << 8) | (buf
[3]);
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
);
268 status
= krb5_sock_to_principal (context
,
274 syslog_and_die ("krb5_sock_to_principal: %s",
275 krb5_get_err_text(context
, status
));
277 status
= krb5_recvauth_match_version(context
,
283 KRB5_RECVAUTH_IGNORE_VERSION
,
286 krb5_free_principal (context
, server
);
288 syslog_and_die ("krb5_recvauth: %s",
289 krb5_get_err_text(context
, status
));
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");
295 if(protocol_version
== 2) {
296 status
= krb5_auth_con_getremotesubkey(context
, auth_context
,
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");
305 if (status
!= 0 || keyblock
== NULL
)
306 syslog_and_die ("krb5_auth_con_getkey: %s",
307 krb5_get_err_text(context
, status
));
309 status
= krb5_crypto_init(context
, keyblock
, 0, &crypto
);
311 syslog_and_die("krb5_crypto_init: %s",
312 krb5_get_err_text(context
, status
));
315 cksum_data
.length
= asprintf (&str
,
317 ntohs(socket_get_port (thisaddr
)),
321 syslog_and_die ("asprintf: out of memory");
322 cksum_data
.data
= str
;
324 status
= krb5_verify_authenticator_checksum(context
,
330 syslog_and_die ("krb5_verify_authenticator_checksum: %s",
331 krb5_get_err_text(context
, status
));
333 free (cksum_data
.data
);
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);
341 if (strncmp (*client_username
, "-U ", 3) == 0) {
342 char *end
, *temp_tkfile
;
344 do_unique_tkfile
= 1;
345 if (strncmp (*client_username
+ 3, "FILE:", 5) == 0) {
346 temp_tkfile
= tkfile
;
348 strlcpy (tkfile
, "FILE:", sizeof(tkfile
));
349 temp_tkfile
= tkfile
+ 5;
351 end
= strchr(*client_username
+ 3,' ');
353 syslog_and_die("missing argument after -U");
354 snprintf(temp_tkfile
, sizeof(tkfile
) - (temp_tkfile
- tkfile
),
356 (int)(end
- *client_username
- 3),
357 *client_username
+ 3);
358 memmove (*client_username
, end
+ 1, strlen(end
+1)+1);
361 kerberos_status
= save_krb5_creds (s
, auth_context
, ticket
->client
);
363 if(!krb5_kuserok (context
,
366 fatal (s
, NULL
, "Permission denied.");
368 if (strncmp (*cmd
, "-x ", 3) == 0) {
370 memmove (*cmd
, *cmd
+ 3, strlen(*cmd
) - 2);
373 fatal (s
, NULL
, "Encryption is required.");
380 if (krb5_unparse_name (context
, ticket
->client
, &name
) == 0) {
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",
389 syslog(LOG_INFO
|LOG_AUTH
,
390 "kerberos v5 shell from %s on %s as %s, cmd '%.80s'",
404 rshd_loop (int from0
, int to0
,
414 if(from0
>= FD_SETSIZE
|| from1
>= FD_SETSIZE
|| from2
>= FD_SETSIZE
)
415 errx (1, "fd too large");
418 if(auth_method
== AUTH_KRB5
&& protocol_version
== 2)
419 init_ivecs(0, have_errsock
);
422 FD_ZERO(&real_readset
);
423 FD_SET(from0
, &real_readset
);
424 FD_SET(from1
, &real_readset
);
425 FD_SET(from2
, &real_readset
);
426 max_fd
= max(from0
, max(from1
, from2
)) + 1;
428 buf
= malloc(max(RSHD_BUFSIZ
, RSH_BUFSIZ
));
430 syslog_and_die("out of memory");
434 fd_set readset
= real_readset
;
436 ret
= select (max_fd
, &readset
, NULL
, NULL
, NULL
);
441 syslog_and_die ("select: %s", strerror(errno
));
443 if (FD_ISSET(from0
, &readset
)) {
444 ret
= do_read (from0
, buf
, RSHD_BUFSIZ
, ivec_in
[0]);
446 syslog_and_die ("read: %s", strerror(errno
));
450 FD_CLR(from0
, &real_readset
);
452 net_write (to0
, buf
, ret
);
454 if (FD_ISSET(from1
, &readset
)) {
455 ret
= read (from1
, buf
, RSH_BUFSIZ
);
457 syslog_and_die ("read: %s", strerror(errno
));
461 FD_CLR(from1
, &real_readset
);
465 do_write (to1
, buf
, ret
, ivec_out
[0]);
467 if (FD_ISSET(from2
, &readset
)) {
468 ret
= read (from2
, buf
, RSH_BUFSIZ
);
470 syslog_and_die ("read: %s", strerror(errno
));
474 FD_CLR(from2
, &real_readset
);
478 do_write (to2
, buf
, ret
, ivec_out
[1]);
484 * Used by `setup_copier' to create some pipe-like means of
485 * communcation. Real pipes would probably be the best thing, but
486 * then the shell doesn't understand it's talking to rshd. If
487 * socketpair doesn't work everywhere, some autoconf magic would have
490 * If it fails creating the `pipe', it aborts by calling fatal.
494 pipe_a_like (int fd
[2])
496 if (socketpair (AF_UNIX
, SOCK_STREAM
, 0, fd
) < 0)
497 fatal (STDOUT_FILENO
, "socketpair", "Pipe creation failed.");
501 * Start a child process and leave the parent copying data to and from it. */
504 setup_copier (int have_errsock
)
506 int p0
[2], p1
[2], p2
[2];
514 fatal (STDOUT_FILENO
, "fork", "Could not create child process.");
515 if (pid
== 0) { /* child */
519 dup2 (p0
[0], STDIN_FILENO
);
520 dup2 (p1
[1], STDOUT_FILENO
);
521 dup2 (p2
[1], STDERR_FILENO
);
525 } else { /* parent */
530 if (net_write (STDOUT_FILENO
, "", 1) != 1)
531 fatal (STDOUT_FILENO
, "net_write", "Write failure.");
533 rshd_loop (STDIN_FILENO
, p0
[1],
534 STDOUT_FILENO
, p1
[0],
535 STDERR_FILENO
, p2
[0],
541 * Is `port' a ``reserverd'' port?
545 is_reserved(u_short port
)
547 return ntohs(port
) < IPPORT_RESERVED
;
551 * Set the necessary part of the environment in `env'.
555 setup_environment (char ***env
, const struct passwd
*pwd
)
564 i
= read_environment(_PATH_ETC_ENVIRONMENT
, env
);
566 for (j
= 0; j
< i
; j
++) {
567 if (!strncmp(e
[j
], "PATH=", 5)) {
573 e
= realloc(e
, (i
+ 7) * sizeof(char *));
575 if (asprintf (&e
[i
++], "USER=%s", pwd
->pw_name
) == -1)
576 syslog_and_die ("asprintf: out of memory");
577 if (asprintf (&e
[i
++], "HOME=%s", pwd
->pw_dir
) == -1)
578 syslog_and_die ("asprintf: out of memory");
579 if (asprintf (&e
[i
++], "SHELL=%s", pwd
->pw_shell
) == -1)
580 syslog_and_die ("asprintf: out of memory");
582 if (asprintf (&e
[i
++], "PATH=%s", _PATH_DEFPATH
) == -1)
583 syslog_and_die ("asprintf: out of memory");
585 asprintf (&e
[i
++], "SSH_CLIENT=only_to_make_bash_happy");
586 if (do_unique_tkfile
)
587 if (asprintf (&e
[i
++], "KRB5CCNAME=%s", tkfile
) == -1)
588 syslog_and_die ("asprintf: out of memory");
598 struct sockaddr_storage thisaddr_ss
;
599 struct sockaddr
*thisaddr
= (struct sockaddr
*)&thisaddr_ss
;
600 struct sockaddr_storage thataddr_ss
;
601 struct sockaddr
*thataddr
= (struct sockaddr
*)&thataddr_ss
;
602 struct sockaddr_storage erraddr_ss
;
603 struct sockaddr
*erraddr
= (struct sockaddr
*)&erraddr_ss
;
604 socklen_t thisaddr_len
, thataddr_len
;
607 char *client_user
= NULL
, *server_user
= NULL
, *cmd
= NULL
;
609 int s
= STDIN_FILENO
;
612 char that_host
[NI_MAXHOST
];
614 thisaddr_len
= sizeof(thisaddr_ss
);
615 if (getsockname (s
, thisaddr
, &thisaddr_len
) < 0)
616 syslog_and_die("getsockname: %s", strerror(errno
));
617 thataddr_len
= sizeof(thataddr_ss
);
618 if (getpeername (s
, thataddr
, &thataddr_len
) < 0)
619 syslog_and_die ("getpeername: %s", strerror(errno
));
621 /* check for V4MAPPED addresses? */
623 if (do_kerberos
== 0 && !is_reserved(socket_get_port(thataddr
)))
624 fatal(s
, NULL
, "Permission denied.");
629 if (net_read (s
, p
, 1) != 1)
630 syslog_and_die ("reading port number: %s", strerror(errno
));
633 else if (isdigit(*p
))
634 port
= port
* 10 + *p
- '0';
636 syslog_and_die ("non-digit in port number: %c", *p
);
639 if (do_kerberos
== 0 && !is_reserved(htons(port
)))
640 fatal(s
, NULL
, "Permission denied.");
643 int priv_port
= IPPORT_RESERVED
- 1;
646 * There's no reason to require a ``privileged'' port number
647 * here, but for some reason the brain dead rsh clients
651 erraddr
->sa_family
= thataddr
->sa_family
;
652 socket_set_address_and_port (erraddr
,
653 socket_get_address (thataddr
),
657 * we only do reserved port for IPv4
660 if (erraddr
->sa_family
== AF_INET
)
661 errsock
= rresvport (&priv_port
);
663 errsock
= socket (erraddr
->sa_family
, SOCK_STREAM
, 0);
665 syslog_and_die ("socket: %s", strerror(errno
));
666 if (connect (errsock
,
668 socket_sockaddr_size (erraddr
)) < 0) {
669 syslog (LOG_WARNING
, "connect: %s", strerror(errno
));
675 if (net_read (s
, buf
, 4) != 4)
676 syslog_and_die ("reading auth info: %s", strerror(errno
));
679 if((do_kerberos
& DO_KRB5
) &&
680 recv_krb5_auth (s
, buf
, thisaddr
, thataddr
,
684 auth_method
= AUTH_KRB5
;
687 syslog_and_die ("unrecognized auth protocol: %x %x %x %x",
688 buf
[0], buf
[1], buf
[2], buf
[3]);
690 if(recv_bsd_auth (s
, buf
,
691 (struct sockaddr_in
*)thisaddr
,
692 (struct sockaddr_in
*)thataddr
,
696 auth_method
= AUTH_BROKEN
;
698 printf("Remote host requires Kerberos authentication\n");
702 syslog_and_die("recv_bsd_auth failed");
705 if (client_user
== NULL
|| server_user
== NULL
|| cmd
== NULL
)
706 syslog_and_die("mising client/server/cmd");
708 pwd
= getpwnam (server_user
);
710 fatal (s
, NULL
, "Login incorrect.");
712 if (*pwd
->pw_shell
== '\0')
713 pwd
->pw_shell
= _PATH_BSHELL
;
715 if (pwd
->pw_uid
!= 0 && access (_PATH_NOLOGIN
, F_OK
) == 0)
716 fatal (s
, NULL
, "Login disabled.");
719 ret
= getnameinfo_verified (thataddr
, thataddr_len
,
720 that_host
, sizeof(that_host
),
723 fatal (s
, NULL
, "getnameinfo: %s", gai_strerror(ret
));
725 if (login_access(pwd
, that_host
) == 0) {
726 syslog(LOG_NOTICE
, "Kerberos rsh denied to %s from %s",
727 server_user
, that_host
);
728 fatal(s
, NULL
, "Permission denied.");
736 sp
= getspnam(server_user
);
738 today
= time(0)/(24L * 60 * 60);
739 if (sp
->sp_expire
> 0)
740 if (today
> sp
->sp_expire
)
741 fatal(s
, NULL
, "Account has expired.");
748 if (setlogin(pwd
->pw_name
) < 0)
749 syslog(LOG_ERR
, "setlogin() failed: %s", strerror(errno
));
753 if (setpcred (pwd
->pw_name
, NULL
) == -1)
754 syslog(LOG_ERR
, "setpcred() failure: %s", strerror(errno
));
755 #endif /* HAVE_SETPCRED */
757 /* Apply limits if not root */
758 if(pwd
->pw_uid
!= 0) {
759 const char *file
= _PATH_LIMITS_CONF
;
760 read_limits_conf(file
, pwd
);
763 if (initgroups (pwd
->pw_name
, pwd
->pw_gid
) < 0)
764 fatal (s
, "initgroups", "Login incorrect.");
766 if (setgid(pwd
->pw_gid
) < 0)
767 fatal (s
, "setgid", "Login incorrect.");
769 if (setuid (pwd
->pw_uid
) < 0)
770 fatal (s
, "setuid", "Login incorrect.");
772 if (chdir (pwd
->pw_dir
) < 0)
773 fatal (s
, "chdir", "Remote directory.");
776 if (dup2 (errsock
, STDERR_FILENO
) < 0)
777 fatal (s
, "dup2", "Cannot dup stderr.");
780 if (dup2 (STDOUT_FILENO
, STDERR_FILENO
) < 0)
781 fatal (s
, "dup2", "Cannot dup stderr.");
788 if (!do_unique_tkfile
)
789 snprintf(tkfile
,sizeof(tkfile
),"FILE:/tmp/krb5cc_%lu",
790 (unsigned long)pwd
->pw_uid
);
791 else if (*tkfile
=='\0') {
792 snprintf(tkfile
,sizeof(tkfile
),"FILE:/tmp/krb5cc_XXXXXX");
793 fd
= mkstemp(tkfile
+5);
799 krb5_start_session();
803 setup_environment (&env
, pwd
);
806 setup_copier (errsock
>= 0);
808 if (net_write (s
, "", 1) != 1)
809 fatal (s
, "net_write", "write failed");
820 if (kerberos_status
) {
822 krb5_error_code status
;
824 status
= krb5_cc_resolve (context
, tkfile
, &ccache
);
826 if (k_afs_cell_of_file (pwd
->pw_dir
, cell
, sizeof(cell
)) == 0)
827 krb5_afslog_uid_home(context
, ccache
, cell
, NULL
,
828 pwd
->pw_uid
, pwd
->pw_dir
);
829 krb5_afslog_uid_home(context
, ccache
, NULL
, NULL
,
830 pwd
->pw_uid
, pwd
->pw_dir
);
831 krb5_cc_close (context
, ccache
);
836 execle (pwd
->pw_shell
, pwd
->pw_shell
, "-c", cmd
, NULL
, env
);
837 err(1, "exec %s", pwd
->pw_shell
);
840 struct getargs args
[] = {
841 { NULL
, 'a', arg_flag
, &do_addr_verify
},
842 { "keepalive", 'n', arg_negative_flag
, &do_keepalive
},
843 { "inetd", 'i', arg_negative_flag
, &do_inetd
,
844 "Not started from inetd" },
846 { "kerberos", 'k', arg_flag
, &do_kerberos
,
847 "Implement kerberised services" },
848 { "encrypt", 'x', arg_flag
, &do_encrypt
,
849 "Implement encrypted service" },
851 { "rhosts", 'l', arg_negative_flag
, &do_rhosts
,
852 "Don't check users .rhosts" },
853 { "port", 'p', arg_string
, &port_str
, "Use this port",
855 { "vacuous", 'v', arg_flag
, &do_vacuous
,
856 "Don't accept non-kerberised connections" },
858 { NULL
, 'P', arg_negative_flag
, &do_newpag
,
859 "Don't put process in new PAG" },
861 /* compatibility flag: */
862 { NULL
, 'L', arg_flag
, &do_log
},
863 { "version", 0, arg_flag
, &do_version
},
864 { "help", 0, arg_flag
, &do_help
}
870 if(isatty(STDIN_FILENO
))
871 arg_printusage (args
,
872 sizeof(args
) / sizeof(args
[0]),
876 syslog (LOG_ERR
, "Usage: %s [-ikxlvPL] [-p port]", getprogname());
882 main(int argc
, char **argv
)
887 setprogname (argv
[0]);
888 roken_openlog ("rshd", LOG_ODELAY
| LOG_PID
, LOG_AUTH
);
890 if (getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
,
907 do_kerberos
= DO_KRB5
;
911 if((do_kerberos
& DO_KRB5
) && krb5_init_context (&context
) != 0)
912 do_kerberos
&= ~DO_KRB5
;
917 struct addrinfo
*ai
= NULL
, hints
;
918 char portstr
[NI_MAXSERV
];
920 memset (&hints
, 0, sizeof(hints
));
921 hints
.ai_flags
= AI_PASSIVE
;
922 hints
.ai_socktype
= SOCK_STREAM
;
923 hints
.ai_family
= PF_UNSPEC
;
925 if(port_str
!= NULL
) {
926 error
= getaddrinfo (NULL
, port_str
, &hints
, &ai
);
928 errx (1, "getaddrinfo: %s", gai_strerror (error
));
934 error
= getaddrinfo(NULL
, "ekshell", &hints
, &ai
);
935 if(error
== EAI_NONAME
) {
936 snprintf(portstr
, sizeof(portstr
), "%d", 545);
937 error
= getaddrinfo(NULL
, portstr
, &hints
, &ai
);
940 errx (1, "getaddrinfo: %s", gai_strerror (error
));
942 error
= getaddrinfo(NULL
, "kshell", &hints
, &ai
);
943 if(error
== EAI_NONAME
) {
944 snprintf(portstr
, sizeof(portstr
), "%d", 544);
945 error
= getaddrinfo(NULL
, portstr
, &hints
, &ai
);
948 errx (1, "getaddrinfo: %s", gai_strerror (error
));
953 error
= getaddrinfo(NULL
, "shell", &hints
, &ai
);
954 if(error
== EAI_NONAME
) {
955 snprintf(portstr
, sizeof(portstr
), "%d", 514);
956 error
= getaddrinfo(NULL
, portstr
, &hints
, &ai
);
959 errx (1, "getaddrinfo: %s", gai_strerror (error
));
962 mini_inetd_addrinfo (ai
);
967 setsockopt(0, SOL_SOCKET
, SO_KEEPALIVE
, (char *)&on
,
969 syslog(LOG_WARNING
, "setsockopt (SO_KEEPALIVE): %s", strerror(errno
));
973 signal (SIGPIPE
, SIG_IGN
);