summaryrefslogtreecommitdiffstats
path: root/src/lib/apputils
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2010-06-26 03:32:55 +0000
committerGreg Hudson <ghudson@mit.edu>2010-06-26 03:32:55 +0000
commit0080380b3b3e945c5eb84504771d9d01ee76a611 (patch)
tree39234f0c55f0a9304b935e0f38c7c9b14aa0c7cf /src/lib/apputils
parent5191e163a9a39ae11e1e62f4a2e191f2d26fbb7a (diff)
downloadkrb5-0080380b3b3e945c5eb84504771d9d01ee76a611.tar.gz
krb5-0080380b3b3e945c5eb84504771d9d01ee76a611.tar.xz
krb5-0080380b3b3e945c5eb84504771d9d01ee76a611.zip
Make kadmin work over IPv6
Make gssrpc work over IPv6 TCP sockets provided that the client creates and connects/binds the sockets and doesn't query their addresses or use bindresvport(). Make kadmin work within those constraints and handle IPv6. Specific changes: * Make svctcp_create() able to extract the port from an IPv6 socket, using a new helper function getport(). * Make clnttcp_create() handle a null raddr value if *sockp is set. * Make kadm5_get_service_name() use getaddrinfo() to canonicalize the admin server name. * Make libkadm5clnt's init_any() responsible for connecting its socket using a new helper function connect_to_server(), which uses getaddrinfo instead of gethostbyname. Pass a null address to clnttcp_create(). * Make libapputil's net-server.c set up IPv6 as well as IPv4 listener ports for RPC connections. * Adjust the error code expected in a libkadm5 unit test. ticket: 6746 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24147 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/apputils')
-rw-r--r--src/lib/apputils/net-server.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/src/lib/apputils/net-server.c b/src/lib/apputils/net-server.c
index 18582e272..dfae9d1f5 100644
--- a/src/lib/apputils/net-server.c
+++ b/src/lib/apputils/net-server.c
@@ -575,6 +575,20 @@ setup_a_rpc_listener(struct socksetup *data, struct sockaddr *addr)
if (setreuseaddr(sock, 1) < 0)
com_err(data->prog, errno,
"Cannot enable SO_REUSEADDR on fd %d", sock);
+#ifdef KRB5_USE_INET6
+ if (addr->sa_family == AF_INET6) {
+#ifdef IPV6_V6ONLY
+ if (setv6only(sock, 1))
+ com_err(data->prog, errno,
+ "setsockopt(%d,IPV6_V6ONLY,1) failed", sock);
+ else
+ com_err(data->prog, 0, "setsockopt(%d,IPV6_V6ONLY,1) worked",
+ sock);
+#else
+ krb5_klog_syslog(LOG_INFO, "no IPV6_V6ONLY socket option support");
+#endif /* IPV6_V6ONLY */
+ }
+#endif /* KRB5_USE_INET6 */
if (bind(sock, addr, socklen(addr)) == -1) {
com_err(data->prog, errno,
"Cannot bind RPC server socket on %s", paddr(addr));
@@ -671,6 +685,9 @@ static int
setup_rpc_listener_ports(struct socksetup *data)
{
struct sockaddr_in sin4;
+#ifdef KRB5_USE_INET6
+ struct sockaddr_in6 sin6;
+#endif
int i;
struct rpc_svc_data svc;
@@ -681,24 +698,54 @@ setup_rpc_listener_ports(struct socksetup *data)
#endif
sin4.sin_addr.s_addr = INADDR_ANY;
+#ifdef KRB5_USE_INET6
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_family = AF_INET6;
+#ifdef HAVE_SA_LEN
+ sin6.sin6_len = sizeof(sin6);
+#endif
+ sin6.sin6_addr = in6addr_any;
+#endif
+
FOREACH_ELT (rpc_svc_data, i, svc) {
int s4;
+#ifdef KRB5_USE_INET6
+ int s6;
+#endif
set_sa_port((struct sockaddr *)&sin4, htons(svc.port));
s4 = setup_a_rpc_listener(data, (struct sockaddr *)&sin4);
if (s4 < 0)
return -1;
+
+ if (add_rpc_listener_fd(data, &svc, s4) == NULL)
+ close(s4);
else {
- if (add_rpc_listener_fd(data, &svc, s4) == NULL)
- close(s4);
+ FD_SET(s4, &sstate.rfds);
+ if (s4 >= sstate.max)
+ sstate.max = s4 + 1;
+ krb5_klog_syslog(LOG_INFO, "listening on fd %d: rpc %s",
+ s4, paddr((struct sockaddr *)&sin4));
+ }
+
+#ifdef KRB5_USE_INET6
+ if (ipv6_enabled()) {
+ set_sa_port((struct sockaddr *)&sin6, htons(svc.port));
+ s6 = setup_a_tcp_listener(data, (struct sockaddr *)&sin6);
+ if (s6 < 0)
+ return -1;
+
+ if (add_rpc_listener_fd(data, &svc, s6) == NULL)
+ close(s6);
else {
- FD_SET(s4, &sstate.rfds);
- if (s4 >= sstate.max)
- sstate.max = s4 + 1;
+ FD_SET(s6, &sstate.rfds);
+ if (s6 >= sstate.max)
+ sstate.max = s6 + 1;
krb5_klog_syslog(LOG_INFO, "listening on fd %d: rpc %s",
- s4, paddr((struct sockaddr *)&sin4));
+ s6, paddr((struct sockaddr *)&sin6));
}
}
+#endif
}
FD_ZERO(&rpc_listenfds);
rpc_listenfds = svc_fdset;