Module Name:src
Committed By: yamt
Date: Thu Apr 9 06:34:34 UTC 2009
Modified Files:
src/crypto/dist/heimdal/kpasswd: kpasswdd.c
Log Message:
restore INETD_SUPPORT. PR/40722.
To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/crypto/dist/heimdal/kpasswd/kpasswdd.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/crypto/dist/heimdal/kpasswd/kpasswdd.c
diff -u src/crypto/dist/heimdal/kpasswd/kpasswdd.c:1.10 src/crypto/dist/heimdal/kpasswd/kpasswdd.c:1.11
--- src/crypto/dist/heimdal/kpasswd/kpasswdd.c:1.10 Sat Mar 22 08:37:03 2008
+++ src/crypto/dist/heimdal/kpasswd/kpasswdd.c Thu Apr 9 06:34:34 2009
@@ -33,7 +33,7 @@
#include kpasswd_locl.h
__RCSID($Heimdal: kpasswdd.c 22252 2007-12-09 05:59:34Z lha $
-$NetBSD: kpasswdd.c,v 1.10 2008/03/22 08:37:03 mlelstv Exp $);
+$NetBSD: kpasswdd.c,v 1.11 2009/04/09 06:34:34 yamt Exp $);
#include kadm5/admin.h
#ifdef HAVE_SYS_UN_H
@@ -606,6 +606,34 @@
krb5_auth_con_free (context, auth_context);
}
+#ifdef INETD_SUPPORT
+/*
+ * XXX this code relies on getsockname() returning a valid local
+ * address for a connected DGRAM socket. This is true for most, but
+ * probably not all systems. For some systems, this could be done
+ * cleaner by using the IP_RECVDSTADDR option + recvmsg().
+ */
+static int
+get_local_addr(struct sockaddr *remote, int remlen,
+ struct sockaddr *local, socklen_t *loclen)
+{
+ int s, ret;
+
+ s = socket(remote-sa_family, SOCK_DGRAM, 0);
+ if (s 0)
+ return -1;
+
+ if (connect(s, remote, remlen) 0) {
+ close(s);
+ return -1;
+ }
+
+ ret = getsockname(s, local, loclen);
+ close(s);
+ return ret;
+}
+#endif
+
static int
doit (krb5_keytab keytab, int port)
{
@@ -614,15 +642,30 @@
int maxfd;
krb5_realm *realms;
krb5_addresses addrs;
+krb5_address *my_addrp;
unsigned n, i;
fd_set real_fdset;
struct sockaddr_storage __ss;
struct sockaddr *sa = (struct sockaddr *)__ss;
+#ifdef INETD_SUPPORT
+int fdz;
+int from_inetd;
+socklen_t fromlen;
+krb5_address my_addr;
+struct sockaddr_storage __local;
+struct sockaddr *localsa = (struct sockaddr *)__local;
+#endif
ret = krb5_get_default_realms(context, realms);
if (ret)
krb5_err (context, 1, ret, krb5_get_default_realms);
+#ifdef INETD_SUPPORT
+fromlen = sizeof __ss;
+from_inetd = (getsockname(0, sa, fromlen) == 0);
+
+if (!from_inetd) {
+#endif
if (explicit_addresses.len) {
addrs = explicit_addresses;
} else {
@@ -661,6 +704,16 @@
krb5_errx (context, 1, fd too large);
FD_SET(sockets[i], real_fdset);
}
+#ifdef INETD_SUPPORT
+} else {
+n = 1;
+maxfd = 0;
+ fdz = 0;
+sockets = fdz;
+FD_ZERO(real_fdset);
+FD_SET(0, real_fdset);
+}
+#endif
if (maxfd == -1)
krb5_errx (context, 1, No sockets!);
@@ -688,19 +741,48 @@
else
krb5_err (context, 1, errno, recvfrom);
}
+#ifdef INETD_SUPPORT
+ if (from_inetd) {
+ socklen_t loclen = sizeof(__local);
+ int ret2;
+
+ ret2 = get_local_addr(sa, addrlen, localsa, loclen);
+ if (ret2 0)
+krb5_errx (context, errno, get_local_addr);
+ ret2 = krb5_sockaddr2address(context, localsa,
+ my_addr);
+ if (ret2)
+krb5_errx (context, ret2,
+krb5_sockaddr2address);
+ my_addrp = my_addr;
+ } else
+#endif
+ my_addrp = addrs.val[i];
process (realms, keytab, sockets[i],
- addrs.val[i],
+ my_addrp,
sa, addrlen,
buf, ret);
+#ifdef INETD_SUPPORT
+ if (from_inetd) {
+ krb5_free_address(context, my_addr);
+ }
+#endif
}
+#ifdef INETD_SUPPORT
+ if (from_inetd)
+ break;
+#endif
}
for (i = 0; i n; ++i)
close(sockets[i]);
free(sockets);
-krb5_free_addresses (context, addrs);
+#ifdef INETD_SUPPORT
+if (!from_inetd)
+#endif
+ krb5_free_addresses (context, addrs);
krb5_free_host_realm (context, realms);
krb5_free_context (context);
return 0;