--- Begin Message ---
Package: krb5-kdc
Version: 1.7dfsg~beta3-1
Severity: important
Tags: patch ipv6
kprop and kpropd do not support IPv6. Thus I could not use them to synchronize
my IPv6-only-KDC.
Attached you find two patches, one for kprop and one for kpropd. The latter one
needs the former one to be applied first, because I needed to introduce a new
function in kprop_sock.c.
Please forward these patches upstream.
-- System Information:
Debian Release: squeeze/sid
APT prefers testing
APT policy: (990, 'testing'), (500, 'stable')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.30-midna (SMP w/2 CPU cores)
Locale: LANG=C, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages krb5-kdc depends on:
ii debconf [debconf-2.0] 1.5.26 Debian configuration management sy
ii krb5-config 1.23 Configuration files for Kerberos V
ii krb5-user 1.7dfsg~beta3-1 Basic programs to authenticate usi
ii libc6 2.9-12 GNU C Library: Shared libraries
ii libcomerr2 1.41.3-1 common error description library
ii libgssapi-krb5-2 1.7dfsg~beta3-1 MIT Kerberos runtime libraries - k
ii libgssrpc4 1.7dfsg~beta3-1 MIT Kerberos runtime libraries - G
ii libk5crypto3 1.7dfsg~beta3-1 MIT Kerberos runtime libraries - C
ii libkadm5clnt6 1.7dfsg~beta3-1 MIT Kerberos runtime libraries - A
ii libkadm5srv6 1.7dfsg~beta3-1 MIT Kerberos runtime libraries - K
ii libkdb5-4 1.7dfsg~beta3-1 MIT Kerberos runtime libraries - K
ii libkeyutils1 1.2-11 Linux Key Management Utilities (li
ii libkrb5-3 1.7dfsg~beta3-1 MIT Kerberos runtime libraries
ii libkrb5support0 1.7dfsg~beta3-1 MIT Kerberos runtime libraries - S
ii lsb-base 3.2-22 Linux Standard Base 3.2 init scrip
krb5-kdc recommends no packages.
Versions of packages krb5-kdc suggests:
ii krb5-admin-server 1.7dfsg~beta3-1 MIT Kerberos master server (kadmin
pn krb5-kdc-ldap <none> (no description available)
ii openbsd-inetd [inet-supe 0.20080125-2 The OpenBSD Internet Superserver
-- debconf information excluded
>From 29b92d08b3e1bd515a0ee7b25e9da4efb7480727 Mon Sep 17 00:00:00 2001
From: Michael Stapelberg <[email protected]>
Date: Sat, 3 Oct 2009 17:59:03 +0200
Subject: [PATCH] Implement support for IPv6 (kprop)
---
src/slave/Makefile.in | 8 +++---
src/slave/kprop.c | 85 ++++++++++++++++++++++++++++++++--------------------------
src/slave/kprop.h | 2 +
src/slave/kprop_sock.c | 39 ++++++++++++++++++++++++++
5 files changed, 92 insertions(+), 42 deletions(-)
create mode 100644 src/slave/kprop_sock.c
diff --git a/src/slave/Makefile.in b/src/slave/Makefile.in
index 6ff3c71..2f24b8c 100644
--- a/src/slave/Makefile.in
+++ b/src/slave/Makefile.in
@@ -8,11 +8,11 @@ DEFS=
all:: kprop kpropd kproplog
-CLIENTSRCS= $(srcdir)/kprop.c
-CLIENTOBJS= kprop.o
+CLIENTSRCS= $(srcdir)/kprop.c $(srcdir)/kprop_sock.c
+CLIENTOBJS= kprop.o kprop_sock.o
-SERVERSRCS= $(srcdir)/kpropd.c $(srcdir)/kpropd_rpc.c
-SERVEROBJS= kpropd.o kpropd_rpc.o
+SERVERSRCS= $(srcdir)/kpropd.c $(srcdir)/kpropd_rpc.c $(srcdir)/kprop_sock.c
+SERVEROBJS= kpropd.o kpropd_rpc.o kprop_sock.o
LOGSRCS= $(srcdir)/kproplog.c
LOGOBJS= kproplog.o
diff --git a/src/slave/kprop.c b/src/slave/kprop.c
index 83082ec..d57f6dd 100644
--- a/src/slave/kprop.c
+++ b/src/slave/kprop.c
@@ -328,53 +328,58 @@ open_connection(host, fd, Errmsg, ErrmsgSz)
unsigned int ErrmsgSz;
{
int s;
- krb5_error_code retval;
-
- struct hostent *hp;
- register struct servent *sp;
- struct sockaddr_in my_sin;
+ krb5_error_code retval = 1;
GETSOCKNAME_ARG3_TYPE socket_length;
-
- hp = gethostbyname(host);
- if (hp == NULL) {
- (void) snprintf(Errmsg, ErrmsgSz, "%s: unknown host", host);
+ struct addrinfo hints, *res, *answers;
+ struct sockaddr *sa;
+ struct sockaddr_storage my_sin;
+ int error;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ if ((error = getaddrinfo(host, KPROP_SERVICE, &hints, &answers)) != 0) {
+ (void) snprintf(Errmsg, ErrmsgSz, "%s: %s", host, gai_strerror(error));
*fd = -1;
return(0);
}
- my_sin.sin_family = hp->h_addrtype;
- memcpy((char *)&my_sin.sin_addr, hp->h_addr, sizeof(my_sin.sin_addr));
- if(!port) {
- sp = getservbyname(KPROP_SERVICE, "tcp");
- if (sp == 0) {
- my_sin.sin_port = htons(KPROP_PORT);
- } else {
- my_sin.sin_port = sp->s_port;
+
+ for (res = answers; res != NULL; res = res->ai_next) {
+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (s < 0) {
+ (void) snprintf(Errmsg, ErrmsgSz, "in call to socket");
+ freeaddrinfo(answers);
+ return(errno);
}
- } else
- my_sin.sin_port = port;
- s = socket(AF_INET, SOCK_STREAM, 0);
-
- if (s < 0) {
- (void) snprintf(Errmsg, ErrmsgSz, "in call to socket");
- return(errno);
+
+ if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
+ retval = errno;
+ close(s);
+ s = -1;
+ continue;
+ }
+
+ /* We successfully connect()ed */
+ *fd = s;
+ if (sockaddr2krbaddr(res->ai_family, res->ai_addr, &receiver_addr) != 0) {
+ (void) snprintf(Errmsg, ErrmsgSz, "Bad address family");
+ *fd = -1;
+ return(0);
+ }
+
+ break;
}
- if (connect(s, (struct sockaddr *)&my_sin, sizeof my_sin) < 0) {
- retval = errno;
- close(s);
+
+ freeaddrinfo(answers);
+
+ if (s == -1) {
(void) snprintf(Errmsg, ErrmsgSz, "in call to connect");
return(retval);
}
- *fd = s;
/*
* Set receiver_addr and sender_addr.
*/
- receiver_addr.addrtype = ADDRTYPE_INET;
- receiver_addr.length = sizeof(my_sin.sin_addr);
- receiver_addr.contents = (krb5_octet *) malloc(sizeof(my_sin.sin_addr));
- memcpy((char *) receiver_addr.contents, (char *) &my_sin.sin_addr,
- sizeof(my_sin.sin_addr));
-
socket_length = sizeof(my_sin);
if (getsockname(s, (struct sockaddr *)&my_sin, &socket_length) < 0) {
retval = errno;
@@ -382,11 +387,15 @@ open_connection(host, fd, Errmsg, ErrmsgSz)
(void) snprintf(Errmsg, ErrmsgSz, "in call to getsockname");
return(retval);
}
- sender_addr.addrtype = ADDRTYPE_INET;
- sender_addr.length = sizeof(my_sin.sin_addr);
- sender_addr.contents = (krb5_octet *) malloc(sizeof(my_sin.sin_addr));
- memcpy((char *) sender_addr.contents, (char *) &my_sin.sin_addr,
- sizeof(my_sin.sin_addr));
+
+ sa = (struct sockaddr *) &my_sin;
+
+ if (sockaddr2krbaddr(sa->sa_family, sa, &sender_addr) != 0) {
+ (void) snprintf(Errmsg, ErrmsgSz, "Bad address family");
+ close(s);
+ *fd = -1;
+ return(0);
+ }
return(0);
}
diff --git a/src/slave/kprop.h b/src/slave/kprop.h
index bc601de..f7e6feb 100644
--- a/src/slave/kprop.h
+++ b/src/slave/kprop.h
@@ -36,3 +36,5 @@
#define KPROP_BUFSIZ 32768
/* pathnames are in osconf.h, included via k5-int.h */
+
+int sockaddr2krbaddr(int family, struct sockaddr *sa, krb5_address *dest);
diff --git a/src/slave/kprop_sock.c b/src/slave/kprop_sock.c
new file mode 100644
index 0000000..ed477a5
--- /dev/null
+++ b/src/slave/kprop_sock.c
@@ -0,0 +1,39 @@
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "k5-int.h"
+#include "kprop.h"
+
+int sockaddr2krbaddr(int family, struct sockaddr *sa, krb5_address *dest)
+{
+ struct sockaddr_in *sa4;
+ struct sockaddr_in6 *sa6;
+
+ if (family == AF_INET) {
+ dest->addrtype = ADDRTYPE_INET;
+ sa4 = (struct sockaddr_in *)sa;
+ dest->length = sizeof(sa4->sin_addr);
+ dest->contents = (krb5_octet *) malloc(sizeof(sa4->sin_addr));
+ if (!dest->contents) {
+ (void) fprintf(stderr, _("\nCouldn't allocate memory"));
+ exit(1);
+ }
+ memcpy(dest->contents, &sa4->sin_addr, sizeof(sa4->sin_addr));
+ return 0;
+ } else if (family == AF_INET6) {
+ dest->addrtype = ADDRTYPE_INET6;
+ sa6 = (struct sockaddr_in6 *)sa;
+ dest->length = sizeof(sa6->sin6_addr);
+ dest->contents = (krb5_octet *) malloc(sizeof(sa6->sin6_addr));
+ if (!dest->contents) {
+ (void) fprintf(stderr, _("\nCouldn't allocate memory"));
+ exit(1);
+ }
+ memcpy(dest->contents, &sa6->sin6_addr, sizeof(sa6->sin6_addr));
+ return 0;
+ }
+
+ /* Bad address family */
+ return 1;
+}
--
1.6.3.3
>From 9c13a787432ce85fb283ee0736d1248d44f29512 Mon Sep 17 00:00:00 2001
From: Michael Stapelberg <[email protected]>
Date: Sat, 3 Oct 2009 18:24:08 +0200
Subject: [PATCH] Implement IPv6 support (kpropd)
---
src/slave/kpropd.c | 186 +++++++++++++++++++++++-----------------------------
1 files changed, 81 insertions(+), 105 deletions(-)
diff --git a/src/slave/kpropd.c b/src/slave/kpropd.c
index ba63d58..b614e62 100644
--- a/src/slave/kpropd.c
+++ b/src/slave/kpropd.c
@@ -164,7 +164,7 @@ void kerberos_authenticate
int,
krb5_principal *,
krb5_enctype *,
- struct sockaddr_in);
+ struct sockaddr_storage *);
krb5_boolean authorized_principal
(krb5_context,
krb5_principal,
@@ -260,10 +260,10 @@ static void resync_alarm(int sn)
int do_standalone(iprop_role iproprole)
{
struct sockaddr_in my_sin, frominet;
- struct servent *sp;
+ struct addrinfo hints, *res, *answers;
int finet, s;
GETPEERNAME_ARG3_TYPE fromlen;
- int ret;
+ int ret, error;
/*
* Timer for accept/read calls, in case of network type errors.
*/
@@ -271,91 +271,81 @@ int do_standalone(iprop_role iproprole)
retry:
- finet = socket(AF_INET, SOCK_STREAM, 0);
- if (finet < 0) {
- com_err(progname, errno, "while obtaining socket");
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+
+ if ((error = getaddrinfo(NULL, KPROP_SERVICE, &hints, &answers)) != 0) {
+ (void) fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error));
exit(1);
}
- memset((char *) &my_sin,0, sizeof(my_sin));
- if(!port) {
- sp = getservbyname(KPROP_SERVICE, "tcp");
- if (sp == NULL) {
- com_err(progname, 0, "%s/tcp: unknown service", KPROP_SERVICE);
- my_sin.sin_port = htons(KPROP_PORT);
+
+ for (res = answers; res != NULL; res = res->ai_next) {
+ finet = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (finet < 0) {
+ com_err(progname, errno, "while obtaining socket");
+ exit(1);
}
- else my_sin.sin_port = sp->s_port;
- } else {
- my_sin.sin_port = port;
- }
- my_sin.sin_family = AF_INET;
- /*
- * We need to close the socket immediately if iprop is enabled,
- * since back-to-back full resyncs are possible, so we do not
- * linger around for too long
- */
- if (iproprole == IPROP_SLAVE) {
- int on = 1;
- struct linger linger;
+ int on = 1;
+ if (setsockopt (finet, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&on, sizeof(on)) < 0)
+ com_err(progname, errno,
+ _("while setting socket option (SO_REUSEADDR)"));
- if (setsockopt(finet, SOL_SOCKET, SO_REUSEADDR,
- (char *)&on, sizeof(on)) < 0)
- com_err(progname, errno,
- _("while setting socket option (SO_REUSEADDR)"));
- linger.l_onoff = 1;
- linger.l_linger = 2;
- if (setsockopt(finet, SOL_SOCKET, SO_LINGER,
- (void *)&linger, sizeof(linger)) < 0)
- com_err(progname, errno,
- _("while setting socket option (SO_LINGER)"));
- /*
- * We also want to set a timer so that the slave is not waiting
- * until infinity for an update from the master.
- */
- gfd = finet;
- signal(SIGALRM, resync_alarm);
- if (debug) {
- fprintf(stderr, "do_standalone: setting resync alarm to %d\n",
- backoff_timer);
- }
- if (alarm(backoff_timer) != 0) {
- if (debug) {
- fprintf(stderr,
- _("%s: alarm already set\n"), progname);
+ /*
+ * We need to close the socket immediately if iprop is enabled,
+ * since back-to-back full resyncs are possible, so we do not
+ * linger around for too long
+ */
+ if (iproprole == IPROP_SLAVE) {
+ struct linger linger;
+
+ linger.l_onoff = 1;
+ linger.l_linger = 2;
+ if (setsockopt(finet, SOL_SOCKET, SO_LINGER,
+ (void *)&linger, sizeof(linger)) < 0)
+ com_err(progname, errno,
+ _("while setting socket option (SO_LINGER)"));
+ /*
+ * We also want to set a timer so that the slave is not waiting
+ * until infinity for an update from the master.
+ */
+ gfd = finet;
+ signal(SIGALRM, resync_alarm);
+ if (debug) {
+ fprintf(stderr, "do_standalone: setting resync alarm to %d\n",
+ backoff_timer);
+ }
+ if (alarm(backoff_timer) != 0) {
+ if (debug) {
+ fprintf(stderr,
+ _("%s: alarm already set\n"), progname);
+ }
+ }
+ backoff_timer *= 2;
}
- }
- backoff_timer *= 2;
- }
- if ((ret = bind(finet, (struct sockaddr *) &my_sin, sizeof(my_sin))) < 0) {
- if (debug) {
- int on = 1;
- fprintf(stderr,
- "%s: attempting to rebind socket with SO_REUSEADDR\n",
- progname);
- if (setsockopt(finet, SOL_SOCKET, SO_REUSEADDR,
- (char *)&on, sizeof(on)) < 0)
- com_err(progname, errno, "in setsockopt(SO_REUSEADDR)");
- ret = bind(finet, (struct sockaddr *) &my_sin, sizeof(my_sin));
- }
- if (ret < 0) {
- perror("bind");
- com_err(progname, errno, "while binding listener socket");
- exit(1);
- }
- }
- if (!debug && iproprole != IPROP_SLAVE)
- daemon(1, 0);
+ if ((ret = bind(finet, res->ai_addr, res->ai_addrlen)) < 0) {
+ perror("bind");
+ com_err(progname, errno, "while binding listener socket");
+ exit(1);
+ }
+ if (!debug && iproprole != IPROP_SLAVE)
+ daemon(1, 0);
#ifdef PID_FILE
- if ((pidfile = fopen(PID_FILE, "w")) != NULL) {
- fprintf(pidfile, "%d\n", getpid());
- fclose(pidfile);
- } else
- com_err(progname, errno,
- "while opening pid file %s for writing", PID_FILE);
+ if ((pidfile = fopen(PID_FILE, "w")) != NULL) {
+ fprintf(pidfile, "%d\n", getpid());
+ fclose(pidfile);
+ } else
+ com_err(progname, errno,
+ "while opening pid file %s for writing", PID_FILE);
#endif
- if (listen(finet, 5) < 0) {
- com_err(progname, errno, "in listen call");
- exit(1);
+ if (listen(finet, 5) < 0) {
+ com_err(progname, errno, "in listen call");
+ exit(1);
+ }
+ break;
}
while (1) {
int child_pid;
@@ -437,16 +427,16 @@ retry:
void doit(fd)
int fd;
{
- struct sockaddr_in from;
+ struct sockaddr_storage from;
int on = 1;
GETPEERNAME_ARG3_TYPE fromlen;
- struct hostent *hp;
krb5_error_code retval;
krb5_data confmsg;
int lock_fd;
mode_t omask;
krb5_enctype etype;
int database_fd;
+ char host[INET6_ADDRSTRLEN+1];
if (kpropd_context->kdblog_context &&
kpropd_context->kdblog_context->iproprole == IPROP_SLAVE) {
@@ -486,23 +476,17 @@ void doit(fd)
"while attempting setsockopt (SO_KEEPALIVE)");
}
- if (!(hp = gethostbyaddr((char *) &(from.sin_addr.s_addr), fromlen,
- AF_INET))) {
- syslog(LOG_INFO, "Connection from %s",
- inet_ntoa(from.sin_addr));
- if (debug)
- printf("Connection from %s\n",
- inet_ntoa(from.sin_addr));
- } else {
- syslog(LOG_INFO, "Connection from %s", hp->h_name);
+ if (getnameinfo((const struct sockaddr *) &from, fromlen,
+ host, sizeof(host), NULL, 0, 0) == 0) {
+ syslog(LOG_INFO, "Connection from %s", host);
if (debug)
- printf("Connection from %s\n", hp->h_name);
+ printf("Connection from %s\n", host);
}
/*
* Now do the authentication
*/
- kerberos_authenticate(kpropd_context, fd, &client, &etype, from);
+ kerberos_authenticate(kpropd_context, fd, &client, &etype, &from);
/*
* Turn off alarm upon successful authentication from master.
@@ -1207,22 +1191,18 @@ kerberos_authenticate(context, fd, clientp, etype, my_sin)
int fd;
krb5_principal * clientp;
krb5_enctype * etype;
- struct sockaddr_in my_sin;
+ struct sockaddr_storage * my_sin;
{
krb5_error_code retval;
krb5_ticket * ticket;
- struct sockaddr_in r_sin;
+ struct sockaddr_storage r_sin;
GETSOCKNAME_ARG3_TYPE sin_length;
krb5_keytab keytab = NULL;
/*
* Set recv_addr and send_addr
*/
- sender_addr.addrtype = ADDRTYPE_INET;
- sender_addr.length = sizeof(my_sin.sin_addr);
- sender_addr.contents = (krb5_octet *) malloc(sizeof(my_sin.sin_addr));
- memcpy((char *) sender_addr.contents, (char *) &my_sin.sin_addr,
- sizeof(my_sin.sin_addr));
+ sockaddr2krbaddr(my_sin->ss_family, my_sin, &sender_addr);
sin_length = sizeof(r_sin);
if (getsockname(fd, (struct sockaddr *) &r_sin, &sin_length)) {
@@ -1230,11 +1210,7 @@ kerberos_authenticate(context, fd, clientp, etype, my_sin)
exit(1);
}
- receiver_addr.addrtype = ADDRTYPE_INET;
- receiver_addr.length = sizeof(r_sin.sin_addr);
- receiver_addr.contents = (krb5_octet *) malloc(sizeof(r_sin.sin_addr));
- memcpy((char *) receiver_addr.contents, (char *) &r_sin.sin_addr,
- sizeof(r_sin.sin_addr));
+ sockaddr2krbaddr(r_sin.ss_family, &r_sin, &receiver_addr);
if (debug) {
char *name;
--
1.6.3.1
--- End Message ---