2 * Copyright (c) 1997 - 2004 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 __RCSID("$Heimdal: rsh.c 21516 2007-07-12 12:47:23Z lha $"
38 enum auth_method auth_method
;
39 #if defined(KRB4) || defined(KRB5)
43 int do_unique_tkfile
= 0;
44 char *unique_tkfile
= NULL
;
45 char tkfile
[MAXPATHLEN
];
47 int do_forwardable
= -1;
49 krb5_keyblock
*keyblock
;
53 des_key_schedule schedule
;
59 static int use_v4
= -1;
62 static int use_v5
= -1;
64 #if defined(KRB4) || defined(KRB5)
65 static int use_only_broken
= 0;
67 static int use_only_broken
= 1;
69 static int use_broken
= 1;
70 static char *port_str
;
71 static const char *user
;
72 static int do_version
;
74 static int do_errsock
= 1;
76 static char *protocol_version_str
;
77 static int protocol_version
= 2;
84 static int input
= 1; /* Read from stdin */
87 rsh_loop (int s
, int errsock
)
93 if(auth_method
== AUTH_KRB5
&& protocol_version
== 2)
94 init_ivecs(1, errsock
!= -1);
97 if (s
>= FD_SETSIZE
|| (errsock
!= -1 && errsock
>= FD_SETSIZE
))
98 errx (1, "fd too large");
100 FD_ZERO(&real_readset
);
101 FD_SET(s
, &real_readset
);
103 FD_SET(errsock
, &real_readset
);
107 FD_SET(STDIN_FILENO
, &real_readset
);
112 char buf
[RSH_BUFSIZ
];
114 readset
= real_readset
;
115 ret
= select (max(s
, errsock
) + 1, &readset
, NULL
, NULL
, NULL
);
122 if (FD_ISSET(s
, &readset
)) {
123 ret
= do_read (s
, buf
, sizeof(buf
), ivec_in
[0]);
128 FD_CLR(s
, &real_readset
);
132 net_write (STDOUT_FILENO
, buf
, ret
);
134 if (errsock
!= -1 && FD_ISSET(errsock
, &readset
)) {
135 ret
= do_read (errsock
, buf
, sizeof(buf
), ivec_in
[1]);
140 FD_CLR(errsock
, &real_readset
);
144 net_write (STDERR_FILENO
, buf
, ret
);
146 if (FD_ISSET(STDIN_FILENO
, &readset
)) {
147 ret
= read (STDIN_FILENO
, buf
, sizeof(buf
));
151 close (STDIN_FILENO
);
152 FD_CLR(STDIN_FILENO
, &real_readset
);
153 shutdown (s
, SHUT_WR
);
155 do_write (s
, buf
, ret
, ivec_out
[0]);
162 send_krb4_auth(int s
,
163 struct sockaddr
*thisaddr
,
164 struct sockaddr
*thataddr
,
165 const char *hostname
,
166 const char *remote_user
,
167 const char *local_user
,
177 /* the normal default for krb4 should be to disable encryption */
178 status
= krb_sendauth ((do_encrypt
== 1) ? KOPT_DO_MUTUAL
: 0,
180 (char *)hostname
, krb_realmofhost (hostname
),
181 getpid(), &msg
, &cred
, schedule
,
182 (struct sockaddr_in
*)thisaddr
,
183 (struct sockaddr_in
*)thataddr
,
185 if (status
!= KSUCCESS
) {
186 warnx("%s: %s", hostname
, krb_get_err_text(status
));
189 memcpy (iv
, cred
.session
, sizeof(iv
));
191 len
= strlen(remote_user
) + 1;
192 if (net_write (s
, remote_user
, len
) != len
) {
196 if (net_write (s
, cmd
, cmd_len
) != cmd_len
) {
206 * Send forward information on `s' for host `hostname', them being
207 * forwardable themselves if `forwardable'
211 krb5_forward_cred (krb5_auth_context auth_context
,
213 const char *hostname
,
219 krb5_kdc_flags flags
;
221 krb5_principal principal
;
223 memset (&creds
, 0, sizeof(creds
));
225 ret
= krb5_cc_default (context
, &ccache
);
227 warnx ("could not forward creds: krb5_cc_default: %s",
228 krb5_get_err_text (context
, ret
));
232 ret
= krb5_cc_get_principal (context
, ccache
, &principal
);
234 warnx ("could not forward creds: krb5_cc_get_principal: %s",
235 krb5_get_err_text (context
, ret
));
239 creds
.client
= principal
;
241 ret
= krb5_build_principal (context
,
243 strlen(principal
->realm
),
250 warnx ("could not forward creds: krb5_build_principal: %s",
251 krb5_get_err_text (context
, ret
));
255 creds
.times
.endtime
= 0;
258 flags
.b
.forwarded
= 1;
259 flags
.b
.forwardable
= forwardable
;
261 ret
= krb5_get_forwarded_creds (context
,
269 warnx ("could not forward creds: krb5_get_forwarded_creds: %s",
270 krb5_get_err_text (context
, ret
));
274 ret
= krb5_write_message (context
,
277 krb5_data_free (&out_data
);
280 warnx ("could not forward creds: krb5_write_message: %s",
281 krb5_get_err_text (context
, ret
));
285 static int sendauth_version_error
;
288 send_krb5_auth(int s
,
289 struct sockaddr
*thisaddr
,
290 struct sockaddr
*thataddr
,
291 const char *hostname
,
292 const char *remote_user
,
293 const char *local_user
,
297 krb5_principal server
;
298 krb5_data cksum_data
;
301 krb5_auth_context auth_context
= NULL
;
302 const char *protocol_string
= NULL
;
306 status
= krb5_sname_to_principal(context
,
312 warnx ("%s: %s", hostname
, krb5_get_err_text(context
, status
));
316 if(do_encrypt
== -1) {
317 krb5_appdefault_boolean(context
, NULL
,
318 krb5_principal_get_realm(context
, server
),
324 cksum_data
.length
= asprintf (&str
,
326 ntohs(socket_get_port(thataddr
)),
327 do_encrypt
? "-x " : "",
331 warnx ("%s: failed to allocate command", hostname
);
334 cksum_data
.data
= str
;
339 ap_opts
|= AP_OPTS_MUTUAL_REQUIRED
;
341 switch(protocol_version
) {
343 ap_opts
|= AP_OPTS_USE_SUBKEY
;
344 protocol_string
= KCMD_NEW_VERSION
;
347 protocol_string
= KCMD_OLD_VERSION
;
348 key_usage
= KRB5_KU_OTHER_ENCRYPTED
;
354 status
= krb5_sendauth (context
,
368 /* do this while we have a principal */
369 if(do_forward
== -1 || do_forwardable
== -1) {
370 krb5_const_realm realm
= krb5_principal_get_realm(context
, server
);
371 if (do_forwardable
== -1)
372 krb5_appdefault_boolean(context
, NULL
, realm
,
373 "forwardable", FALSE
,
375 if (do_forward
== -1)
376 krb5_appdefault_boolean(context
, NULL
, realm
,
381 krb5_free_principal(context
, server
);
382 krb5_data_free(&cksum_data
);
385 if(status
== KRB5_SENDAUTH_REJECTED
&&
386 protocol_version
== 2 && protocol_version_str
== NULL
)
387 sendauth_version_error
= 1;
389 krb5_warn(context
, status
, "%s", hostname
);
393 status
= krb5_auth_con_getlocalsubkey (context
, auth_context
, &keyblock
);
395 status
= krb5_auth_con_getkey (context
, auth_context
, &keyblock
);
397 warnx ("krb5_auth_con_getkey: %s", krb5_get_err_text(context
, status
));
401 status
= krb5_auth_con_setaddrs_from_fd (context
,
405 warnx("krb5_auth_con_setaddrs_from_fd: %s",
406 krb5_get_err_text(context
, status
));
410 status
= krb5_crypto_init(context
, keyblock
, 0, &crypto
);
412 warnx ("krb5_crypto_init: %s", krb5_get_err_text(context
, status
));
416 len
= strlen(remote_user
) + 1;
417 if (net_write (s
, remote_user
, len
) != len
) {
421 if (do_encrypt
&& net_write (s
, "-x ", 3) != 3) {
425 if (net_write (s
, cmd
, cmd_len
) != cmd_len
) {
430 if (do_unique_tkfile
) {
431 if (net_write (s
, tkfile
, strlen(tkfile
)) != strlen(tkfile
)) {
436 len
= strlen(local_user
) + 1;
437 if (net_write (s
, local_user
, len
) != len
) {
443 || krb5_forward_cred (auth_context
, s
, hostname
, do_forwardable
)) {
444 /* Empty forwarding info */
446 u_char zero
[4] = {0, 0, 0, 0};
449 krb5_auth_con_free (context
, auth_context
);
456 send_broken_auth(int s
,
457 struct sockaddr
*thisaddr
,
458 struct sockaddr
*thataddr
,
459 const char *hostname
,
460 const char *remote_user
,
461 const char *local_user
,
467 len
= strlen(local_user
) + 1;
468 if (net_write (s
, local_user
, len
) != len
) {
472 len
= strlen(remote_user
) + 1;
473 if (net_write (s
, remote_user
, len
) != len
) {
477 if (net_write (s
, cmd
, cmd_len
) != cmd_len
) {
485 proto (int s
, int errsock
,
486 const char *hostname
, const char *local_user
, const char *remote_user
,
487 const char *cmd
, size_t cmd_len
,
488 int (*auth_func
)(int s
,
489 struct sockaddr
*this, struct sockaddr
*that
,
490 const char *hostname
, const char *remote_user
,
491 const char *local_user
, size_t cmd_len
,
499 struct sockaddr_storage thisaddr_ss
;
500 struct sockaddr
*thisaddr
= (struct sockaddr
*)&thisaddr_ss
;
501 struct sockaddr_storage thataddr_ss
;
502 struct sockaddr
*thataddr
= (struct sockaddr
*)&thataddr_ss
;
503 struct sockaddr_storage erraddr_ss
;
504 struct sockaddr
*erraddr
= (struct sockaddr
*)&erraddr_ss
;
508 addrlen
= sizeof(thisaddr_ss
);
509 if (getsockname (s
, thisaddr
, &addrlen
) < 0) {
510 warn ("getsockname(%s)", hostname
);
513 addrlen
= sizeof(thataddr_ss
);
514 if (getpeername (s
, thataddr
, &addrlen
) < 0) {
515 warn ("getpeername(%s)", hostname
);
521 addrlen
= sizeof(erraddr_ss
);
522 if (getsockname (errsock
, erraddr
, &addrlen
) < 0) {
523 warn ("getsockname");
527 if (listen (errsock
, 1) < 0) {
533 snprintf (p
, sizeof(buf
), "%u",
534 ntohs(socket_get_port(erraddr
)));
535 len
= strlen(buf
) + 1;
536 if(net_write (s
, buf
, len
) != len
) {
546 if (errsock
>= FD_SETSIZE
|| s
>= FD_SETSIZE
)
547 errx (1, "fd too large");
550 FD_SET(errsock
, &fdset
);
553 ret
= select (max(errsock
, s
) + 1, &fdset
, NULL
, NULL
, NULL
);
561 if (FD_ISSET(errsock
, &fdset
)) {
562 errsock2
= accept (errsock
, NULL
, NULL
);
572 * there should not arrive any data on this fd so if it's
573 * readable it probably indicates that the other side when
577 if (FD_ISSET(s
, &fdset
)) {
578 warnx ("socket closed");
585 if (net_write (s
, "0", 2) != 2) {
592 if ((*auth_func
)(s
, thisaddr
, thataddr
, hostname
,
593 remote_user
, local_user
,
599 ret
= net_read (s
, &reply
, 1);
604 } else if (ret
== 0) {
605 warnx ("unexpected EOF from %s", hostname
);
611 warnx ("Error from rshd at %s:", hostname
);
613 while ((ret
= read (s
, buf
, sizeof(buf
))) > 0)
614 write (STDOUT_FILENO
, buf
, ret
);
615 write (STDOUT_FILENO
,"\n",1);
622 if (setsockopt(s
, SOL_SOCKET
, SO_DEBUG
, (void *)&one
, sizeof(one
)) < 0)
623 warn("setsockopt remote");
624 if (errsock2
!= -1 &&
625 setsockopt(errsock2
, SOL_SOCKET
, SO_DEBUG
,
626 (void *)&one
, sizeof(one
)) < 0)
627 warn("setsockopt stderr");
630 return rsh_loop (s
, errsock2
);
634 * Return in `res' a copy of the concatenation of `argc, argv' into
638 construct_command (char **res
, int argc
, char **argv
)
644 for (i
= 0; i
< argc
; ++i
)
645 len
+= strlen(argv
[i
]) + 1;
649 errx (1, "malloc %lu failed", (unsigned long)len
);
652 for (i
= 0; i
< argc
- 1; ++i
) {
653 strlcat (tmp
, argv
[i
], len
);
654 strlcat (tmp
, " ", len
);
657 strlcat (tmp
, argv
[argc
-1], len
);
663 print_addr (const struct sockaddr
*sa
)
667 const char *as
= NULL
;
669 if(sa
->sa_family
== AF_INET
)
670 as
= inet_ntop (sa
->sa_family
, &((struct sockaddr_in
*)sa
)->sin_addr
,
671 addr_str
, sizeof(addr_str
));
673 else if(sa
->sa_family
== AF_INET6
)
674 as
= inet_ntop (sa
->sa_family
, &((struct sockaddr_in6
*)sa
)->sin6_addr
,
675 addr_str
, sizeof(addr_str
));
681 errx (1, "malloc: out of memory");
686 doit_broken (int argc
,
690 const char *remote_user
,
691 const char *local_user
,
699 if (connect (priv_socket1
, ai
->ai_addr
, ai
->ai_addrlen
) < 0) {
700 int save_errno
= errno
;
705 for (a
= ai
->ai_next
; a
!= NULL
; a
= a
->ai_next
) {
707 char *adr
= print_addr(a
->ai_addr
);
718 new_argv
= malloc((argc
+ 2) * sizeof(*new_argv
));
719 if (new_argv
== NULL
)
720 errx (1, "malloc: out of memory");
721 new_argv
[i
] = argv
[i
];
725 new_argv
[i
++] = "-K";
726 for(; i
<= argc
; ++i
)
727 new_argv
[i
] = argv
[i
- 1];
729 new_argv
[hostindex
+ 1] = adr
;
730 new_argv
[argc
+ 1] = NULL
;
731 execv(PATH_RSH
, new_argv
);
732 err(1, "execv(%s)", PATH_RSH
);
737 while(waitpid(pid
, &status
, 0) < 0)
739 if(WIFEXITED(status
) && WEXITSTATUS(status
) == 0)
744 warn("%s", argv
[hostindex
]);
749 ret
= proto (priv_socket1
, priv_socket2
,
751 local_user
, remote_user
,
758 #if defined(KRB4) || defined(KRB5)
760 doit (const char *hostname
,
762 const char *remote_user
,
763 const char *local_user
,
766 int (*auth_func
)(int s
,
767 struct sockaddr
*this, struct sockaddr
*that
,
768 const char *hostname
, const char *remote_user
,
769 const char *local_user
, size_t cmd_len
,
774 int socketfailed
= 1;
777 for (a
= ai
; a
!= NULL
; a
= a
->ai_next
) {
781 s
= socket (a
->ai_family
, a
->ai_socktype
, a
->ai_protocol
);
785 if (connect (s
, a
->ai_addr
, a
->ai_addrlen
) < 0) {
787 if(getnameinfo(a
->ai_addr
, a
->ai_addrlen
,
788 addr
, sizeof(addr
), NULL
, 0, NI_NUMERICHOST
) == 0)
789 warn ("connect(%s [%s])", hostname
, addr
);
791 warn ("connect(%s)", hostname
);
796 struct addrinfo
*ea
, *eai
;
797 struct addrinfo hints
;
799 memset (&hints
, 0, sizeof(hints
));
800 hints
.ai_socktype
= a
->ai_socktype
;
801 hints
.ai_protocol
= a
->ai_protocol
;
802 hints
.ai_family
= a
->ai_family
;
803 hints
.ai_flags
= AI_PASSIVE
;
807 error
= getaddrinfo (NULL
, "0", &hints
, &eai
);
809 errx (1, "getaddrinfo: %s", gai_strerror(error
));
810 for (ea
= eai
; ea
!= NULL
; ea
= ea
->ai_next
) {
811 errsock
= socket (ea
->ai_family
, ea
->ai_socktype
,
815 if (bind (errsock
, ea
->ai_addr
, ea
->ai_addrlen
) < 0)
825 ret
= proto (s
, errsock
,
827 local_user
, remote_user
,
828 cmd
, cmd_len
, auth_func
);
833 warnx ("failed to contact %s", hostname
);
836 #endif /* KRB4 || KRB5 */
838 struct getargs args
[] = {
840 { "krb4", '4', arg_flag
, &use_v4
, "Use Kerberos V4" },
843 { "krb5", '5', arg_flag
, &use_v5
, "Use Kerberos V5" },
844 { "forward", 'f', arg_flag
, &do_forward
, "Forward credentials [krb5]"},
845 { "forwardable", 'F', arg_flag
, &do_forwardable
,
846 "Forward forwardable credentials [krb5]" },
847 { NULL
, 'G', arg_negative_flag
,&do_forward
, "Don't forward credentials" },
848 { "unique", 'u', arg_flag
, &do_unique_tkfile
,
849 "Use unique remote credentials cache [krb5]" },
850 { "tkfile", 'U', arg_string
, &unique_tkfile
,
851 "Specifies remote credentials cache [krb5]" },
852 { "protocol", 'P', arg_string
, &protocol_version_str
,
853 "Protocol version [krb5]", "protocol" },
855 { "broken", 'K', arg_flag
, &use_only_broken
, "Use only priv port" },
856 #if defined(KRB4) || defined(KRB5)
857 { "encrypt", 'x', arg_flag
, &do_encrypt
, "Encrypt connection" },
858 { NULL
, 'z', arg_negative_flag
, &do_encrypt
,
859 "Don't encrypt connection", NULL
},
861 { NULL
, 'd', arg_flag
, &sock_debug
, "Enable socket debugging" },
862 { "input", 'n', arg_negative_flag
, &input
, "Close stdin" },
863 { "port", 'p', arg_string
, &port_str
, "Use this port",
865 { "user", 'l', arg_string
, &user
, "Run as this user", "login" },
866 { "stderr", 'e', arg_negative_flag
, &do_errsock
, "Don't open stderr"},
869 { "version", 0, arg_flag
, &do_version
, NULL
},
870 { "help", 0, arg_flag
, &do_help
, NULL
}
876 arg_printusage (args
,
877 sizeof(args
) / sizeof(args
[0]),
879 "[login@]host [command]");
888 main(int argc
, char **argv
)
890 int priv_port1
, priv_port2
;
891 int priv_socket1
, priv_socket2
;
894 struct addrinfo hints
, *ai
;
899 const char *local_user
;
907 priv_port1
= priv_port2
= IPPORT_RESERVED
-1;
908 priv_socket1
= rresvport(&priv_port1
);
909 priv_socket2
= rresvport(&priv_port2
);
911 if (setuid (uid
) || (uid
!= 0 && setuid(0) == 0))
914 setprogname (argv
[0]);
916 if (argc
>= 2 && argv
[1][0] != '-') {
917 host
= argv
[host_index
= 1];
921 if (getarg (args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
,
929 print_version (NULL
);
934 if(protocol_version_str
!= NULL
) {
935 if(strcasecmp(protocol_version_str
, "N") == 0)
936 protocol_version
= 2;
937 else if(strcasecmp(protocol_version_str
, "O") == 0)
938 protocol_version
= 1;
942 v
= strtol(protocol_version_str
, &end
, 0);
943 if(*end
!= '\0' || (v
!= 1 && v
!= 2)) {
944 errx(1, "unknown protocol version \"%s\"",
945 protocol_version_str
);
947 protocol_version
= v
;
951 status
= krb5_init_context (&context
);
954 errx(1, "krb5_init_context failed: %d", status
);
959 /* request for forwardable on the command line means we should
961 if (do_forwardable
== 1)
966 #if defined(KRB4) && defined(KRB5)
967 if(use_v4
== -1 && use_v5
== 1)
969 if(use_v5
== -1 && use_v4
== 1)
973 if (use_only_broken
) {
982 if(priv_socket1
< 0) {
984 errx (1, "unable to bind reserved port: is rsh setuid root?");
988 #if defined(KRB4) || defined(KRB5)
989 if (do_encrypt
== 1 && use_only_broken
)
990 errx (1, "encryption not supported with old style authentication");
996 if (do_unique_tkfile
&& unique_tkfile
!= NULL
)
997 errx (1, "Only one of -u and -U allowed.");
999 if (do_unique_tkfile
)
1000 strlcpy(tkfile
,"-u ", sizeof(tkfile
));
1001 else if (unique_tkfile
!= NULL
) {
1002 if (strchr(unique_tkfile
,' ') != NULL
) {
1003 warnx("Space is not allowed in tkfilename");
1006 do_unique_tkfile
= 1;
1007 snprintf (tkfile
, sizeof(tkfile
), "-U %s ", unique_tkfile
);
1012 if (argc
- argindex
< 1)
1015 host
= argv
[host_index
= argindex
++];
1018 if((tmp
= strchr(host
, '@')) != NULL
) {
1024 if (argindex
== argc
) {
1025 close (priv_socket1
);
1026 close (priv_socket2
);
1028 execvp ("rlogin", argv
);
1029 err (1, "execvp rlogin");
1032 local_user
= get_default_username ();
1033 if (local_user
== NULL
)
1034 errx (1, "who are you?");
1039 cmd_len
= construct_command(&cmd
, argc
- argindex
, argv
+ argindex
);
1042 * Try all different authentication methods
1046 if (ret
&& use_v5
) {
1047 memset (&hints
, 0, sizeof(hints
));
1048 hints
.ai_socktype
= SOCK_STREAM
;
1049 hints
.ai_protocol
= IPPROTO_TCP
;
1051 if(port_str
== NULL
) {
1052 error
= getaddrinfo(host
, "kshell", &hints
, &ai
);
1053 if(error
== EAI_NONAME
)
1054 error
= getaddrinfo(host
, "544", &hints
, &ai
);
1056 error
= getaddrinfo(host
, port_str
, &hints
, &ai
);
1059 errx (1, "getaddrinfo: %s", gai_strerror(error
));
1061 auth_method
= AUTH_KRB5
;
1063 ret
= doit (host
, ai
, user
, local_user
, cmd
, cmd_len
,
1065 if(ret
!= 0 && sendauth_version_error
&&
1066 protocol_version
== 2) {
1067 protocol_version
= 1;
1074 if (ret
&& use_v4
) {
1075 memset (&hints
, 0, sizeof(hints
));
1076 hints
.ai_socktype
= SOCK_STREAM
;
1077 hints
.ai_protocol
= IPPROTO_TCP
;
1079 if(port_str
== NULL
) {
1081 error
= getaddrinfo(host
, "ekshell", &hints
, &ai
);
1082 if(error
== EAI_NONAME
)
1083 error
= getaddrinfo(host
, "545", &hints
, &ai
);
1085 error
= getaddrinfo(host
, "kshell", &hints
, &ai
);
1086 if(error
== EAI_NONAME
)
1087 error
= getaddrinfo(host
, "544", &hints
, &ai
);
1090 error
= getaddrinfo(host
, port_str
, &hints
, &ai
);
1093 errx (1, "getaddrinfo: %s", gai_strerror(error
));
1094 auth_method
= AUTH_KRB4
;
1095 ret
= doit (host
, ai
, user
, local_user
, cmd
, cmd_len
,
1100 if (ret
&& use_broken
) {
1101 memset (&hints
, 0, sizeof(hints
));
1102 hints
.ai_socktype
= SOCK_STREAM
;
1103 hints
.ai_protocol
= IPPROTO_TCP
;
1105 if(port_str
== NULL
) {
1106 error
= getaddrinfo(host
, "shell", &hints
, &ai
);
1107 if(error
== EAI_NONAME
)
1108 error
= getaddrinfo(host
, "514", &hints
, &ai
);
1110 error
= getaddrinfo(host
, port_str
, &hints
, &ai
);
1113 errx (1, "getaddrinfo: %s", gai_strerror(error
));
1115 auth_method
= AUTH_BROKEN
;
1116 ret
= doit_broken (argc
, argv
, host_index
, ai
,
1119 do_errsock
? priv_socket2
: -1,