restore INETD_SUPPORT. PR/40722.

This commit is contained in:
yamt 2009-04-09 06:34:34 +00:00
parent a5e9c389e6
commit cdc5fc06ff
1 changed files with 85 additions and 3 deletions

View File

@ -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 @@ out:
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 @@ doit (krb5_keytab keytab, int port)
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 @@ doit (krb5_keytab keytab, int port)
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 @@ doit (krb5_keytab keytab, int port)
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;