aboutsummaryrefslogtreecommitdiff
path: root/src/appl
diff options
context:
space:
mode:
authorRuss Allbery <rra@stanford.edu>2006-06-19 23:37:09 +0000
committerRuss Allbery <rra@stanford.edu>2006-06-19 23:37:09 +0000
commit02397303fbdc85cccd6656b831afb17be9f661e9 (patch)
treeceaf174e335a7b46db6daca6da85c39f1151eda7 /src/appl
parent93bbe1f67ed5b80da83704243837bb366560e95a (diff)
downloadkrb5-02397303fbdc85cccd6656b831afb17be9f661e9.zip
krb5-02397303fbdc85cccd6656b831afb17be9f661e9.tar.gz
krb5-02397303fbdc85cccd6656b831afb17be9f661e9.tar.bz2
Pass in the correct value for the first argument of select (one larger
than the largest file number in the select set) rather than some multiple of sizeof some struct. The latter is large enough accidentally work, but breaks on AIX. Map IPv4-mapped IPv6 addresses back to IPv4 in krshd for the purposes of connecting back to the remote system on AIX, since on AIX getnameinfo returns such addresses but connect won't accept them. Ticket: 3122 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@18166 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/appl')
-rw-r--r--src/appl/bsd/krlogin.c2
-rw-r--r--src/appl/bsd/krlogind.c2
-rw-r--r--src/appl/bsd/krsh.c4
-rw-r--r--src/appl/bsd/krshd.c26
4 files changed, 29 insertions, 5 deletions
diff --git a/src/appl/bsd/krlogin.c b/src/appl/bsd/krlogin.c
index a1e63a6..05913f6 100644
--- a/src/appl/bsd/krlogin.c
+++ b/src/appl/bsd/krlogin.c
@@ -1101,7 +1101,7 @@ static void writer()
for (;;) {
FD_ZERO(&waitread);
FD_SET(0, &waitread);
- n = select(8*sizeof(waitread), &waitread, 0, 0, 0, 0);
+ n = select(1, &waitread, 0, 0, 0, 0);
if (n < 0 && errno == EINTR)
continue;
if (n > 0)
diff --git a/src/appl/bsd/krlogind.c b/src/appl/bsd/krlogind.c
index 02bed8e..8387f18 100644
--- a/src/appl/bsd/krlogind.c
+++ b/src/appl/bsd/krlogind.c
@@ -1045,7 +1045,7 @@ void protocol(f, p)
}
}
- if (select(8*sizeof(ibits), &ibits, &obits, &ebits, 0) < 0) {
+ if (select(((p > f) ? p : f) + 1, &ibits, &obits, &ebits, 0) < 0) {
if (errno == EINTR)
continue;
fatalperror(f, "select");
diff --git a/src/appl/bsd/krsh.c b/src/appl/bsd/krsh.c
index 08b68fe..155223f 100644
--- a/src/appl/bsd/krsh.c
+++ b/src/appl/bsd/krsh.c
@@ -512,7 +512,7 @@ main(argc, argv0)
rewrite:
FD_ZERO(&rembits);
FD_SET(rem, &rembits);
- if (select(8*sizeof(rembits), 0, &rembits, 0, 0) < 0) {
+ if (select(rem + 1, 0, &rembits, 0, 0) < 0) {
if (errno != EINTR) {
perror("select");
exit(1);
@@ -550,7 +550,7 @@ main(argc, argv0)
FD_SET(rem, &readfrom);
do {
ready = readfrom;
- if (select(8*sizeof(ready), &ready, 0, 0, 0) < 0) {
+ if (select(((rfd2 > rem) ? rfd2 : rem) + 1, &ready, 0, 0, 0) < 0) {
if (errno != EINTR) {
perror("select");
exit(1);
diff --git a/src/appl/bsd/krshd.c b/src/appl/bsd/krshd.c
index 808adf5..02ab132 100644
--- a/src/appl/bsd/krshd.c
+++ b/src/appl/bsd/krshd.c
@@ -440,6 +440,22 @@ int main(argc, argv)
fd = 0;
}
+/*
+ * AIX passes an IPv4-mapped IPv6 address back from getpeername, but if
+ * that address is later used in connect(), it returns an error. Convert
+ * IPv4-mapped IPv6 addresses to simple IPv4 addresses on AIX (but don't
+ * do this everywhere since it isn't always the right thing to do, just
+ * the least wrong on AIX).
+ */
+#if defined(_AIX) && defined(KRB5_USE_INET6)
+ if (((struct sockaddr*)&from)->sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sa2sin6(&from)->sin6_addr)) {
+ sa2sin(&from)->sin_len = sizeof(struct sockaddr_in);
+ sa2sin(&from)->sin_family = AF_INET;
+ sa2sin(&from)->sin_port = sa2sin6(&from)->sin6_port;
+ memmove(&(sa2sin(&from)->sin_addr.s_addr), &(sa2sin6(&from)->sin6_addr.u6_addr.u6_addr8[12]), 4);
+ }
+#endif
+
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
sizeof (on)) < 0)
syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
@@ -1198,6 +1214,7 @@ void doit(f, fromp)
goto signout_please;
}
if (pid) {
+ int maxfd;
#ifdef POSIX_SIGNALS
sa.sa_handler = cleanup;
(void)sigaction(SIGINT, &sa, (struct sigaction *)0);
@@ -1231,11 +1248,18 @@ void doit(f, fromp)
FD_ZERO(&readfrom);
FD_SET(f, &readfrom);
+ maxfd = f;
if(port) {
FD_SET(s, &readfrom);
+ if (s > maxfd)
+ maxfd = s;
FD_SET(pv[0], &readfrom);
+ if (pv[0] > maxfd)
+ maxfd = pv[0];
}
FD_SET(pw[0], &readfrom);
+ if (pw[0] > maxfd)
+ maxfd = pw[0];
/* read from f, write to px[1] -- child stdin */
/* read from s, signal child */
@@ -1244,7 +1268,7 @@ void doit(f, fromp)
do {
ready = readfrom;
- if (select(8*sizeof(ready), &ready, (fd_set *)0,
+ if (select(maxfd + 1, &ready, (fd_set *)0,
(fd_set *)0, (struct timeval *)0) < 0) {
if (errno == EINTR) {
continue;