svn commit: r222448 - user/hrs/ipv6/usr.sbin/ypserv
Hiroki Sato
hrs at FreeBSD.org
Sun May 29 12:15:49 UTC 2011
Author: hrs
Date: Sun May 29 12:15:49 2011
New Revision: 222448
URL: http://svn.freebsd.org/changeset/base/222448
Log:
- Enable transports other than INET including INET6.
- Use svc_getrpccaller() instead of svc_getcaller() to support
transports other than INET.
- Extend /var/yp/securenets to support CIDR notation and IPv6 address.
It now supports the following:
127.0.0.1 255.0.0.0
127.0.0.1/8
172.16.10.1
fe80::1%fxp0/10
2001:db8:1::1 ffff:ffff:ffff:ffff::
2001:db8:2::1/68
2001:db8:3::1
- Add -S flag to support Sorlais-compatible securenets format.
- Fix memory leak on removal of socklist and bindaddrlist.
- Remove inconsistent LINEBUFSZ, use BUFSIZ.
- Style(9) fixes.
Added:
user/hrs/ipv6/usr.sbin/ypserv/yp_access_inet.c
user/hrs/ipv6/usr.sbin/ypserv/yp_access_inet6.c
Modified:
user/hrs/ipv6/usr.sbin/ypserv/Makefile
user/hrs/ipv6/usr.sbin/ypserv/yp_access.c
user/hrs/ipv6/usr.sbin/ypserv/yp_extern.h
user/hrs/ipv6/usr.sbin/ypserv/yp_main.c
user/hrs/ipv6/usr.sbin/ypserv/ypserv.8
Modified: user/hrs/ipv6/usr.sbin/ypserv/Makefile
==============================================================================
--- user/hrs/ipv6/usr.sbin/ypserv/Makefile Sun May 29 11:10:56 2011 (r222447)
+++ user/hrs/ipv6/usr.sbin/ypserv/Makefile Sun May 29 12:15:49 2011 (r222448)
@@ -3,10 +3,18 @@
RPCDIR= ${.CURDIR}/../../include/rpcsvc
.PATH: ${RPCDIR}
+.include <bsd.own.mk>
+
PROG= ypserv
MAN= ypserv.8 ypinit.8
SRCS= yp_svc.c yp_server.c yp_dblookup.c yp_dnslookup.c \
ypxfr_clnt.c yp.h yp_main.c yp_error.c yp_access.c yp_svc_udp.c
+.if ${MK_INET_SUPPORT} != "no"
+SRCS+= yp_access_inet.c
+.endif
+.if ${MK_INET6_SUPPORT} != "no"
+SRCS+= yp_access_inet6.c
+.endif
CFLAGS+= -DDB_CACHE -DTCP_WRAPPER -I.
Modified: user/hrs/ipv6/usr.sbin/ypserv/yp_access.c
==============================================================================
--- user/hrs/ipv6/usr.sbin/ypserv/yp_access.c Sun May 29 11:10:56 2011 (r222447)
+++ user/hrs/ipv6/usr.sbin/ypserv/yp_access.c Sun May 29 12:15:49 2011 (r222448)
@@ -34,31 +34,35 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <stdlib.h>
+#include <sys/fcntl.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <rpc/rpc.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/yppasswd.h>
#include <rpcsvc/ypxfrd.h>
-#include <sys/types.h>
-#include <limits.h>
-#include <db.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
#include <arpa/inet.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <paths.h>
+#include <netinet/in.h>
+#include <db.h>
#include <errno.h>
-#include <sys/param.h>
+#include <limits.h>
+#include <netdb.h>
+#include <paths.h>
+#include <stdlib.h>
+
#include "yp_extern.h"
#ifdef TCP_WRAPPER
#include "tcpd.h"
#endif
+extern int hosts_ctl(char *, char *, char *, char *);
extern int debug;
- /* NIS v1 */
const char *yp_procs[] = {
+ /* NIS v1 */
"ypoldproc_null",
"ypoldproc_domain",
"ypoldproc_domain_nonack",
@@ -87,89 +91,424 @@ const char *yp_procs[] = {
"ypproc_maplist"
};
+static SLIST_HEAD(, securenet) securenets =
+ SLIST_HEAD_INITIALIZER(securenets);
struct securenet {
- struct in_addr net;
- struct in_addr mask;
- struct securenet *next;
+ struct sockaddr_storage sn_addr;
+ struct sockaddr_storage sn_mask;
+ SLIST_ENTRY(securenet) sn_next;
};
-struct securenet *securenets;
+static int
+mask2prefixlen(const struct sockaddr *sap, int *prefixlen)
+{
+ switch (sap->sa_family) {
+#ifdef AF_INET
+ case AF_INET:
+ return (yp_mask2prefixlen_in(sap, prefixlen));
+ break;
+#endif
+#ifdef AF_INET6
+ case AF_INET6:
+ return (yp_mask2prefixlen_in6(sap, prefixlen));
+ break;
+#endif
+ default:
+ break;
+ }
+ return (-1);
+}
-#define LINEBUFSZ 1024
+static int
+prefixlen2mask(struct sockaddr *sap, const int *prefixlen)
+{
+ switch (sap->sa_family) {
+#ifdef AF_INET
+ case AF_INET:
+ return (yp_prefixlen2mask_in(sap, prefixlen));
+ break;
+#endif
+#ifdef AF_INET6
+ case AF_INET6:
+ return (yp_prefixlen2mask_in6(sap, prefixlen));
+ break;
+#endif
+ default:
+ break;
+ }
+ return (-1);
+}
+
+void
+yp_debug_sa(const struct sockaddr *sap)
+{
+ int error;
+ char host[NI_MAXHOST + 1];
+ char serv[NI_MAXSERV + 1];
+
+ error = getnameinfo(sap, sap->sa_len, host, sizeof(host), serv,
+ sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
+ if (error)
+ yp_error("sockaddr: %s", gai_strerror(error));
+ else
+ yp_error("sockaddr: %d/%s/%s", sap->sa_family, host, serv);
+}
+
+void
+show_securenets(void)
+{
+ struct securenet *snp;
+ struct sockaddr *sap;
+ int i = 0;
+
+ yp_error("--- securenets dump start ---");
+ SLIST_FOREACH(snp, &securenets, sn_next) {
+ i++;
+ yp_error("entry %d:", i);
+ sap = (struct sockaddr *)&(snp->sn_addr);
+ yp_debug_sa(sap);
+ sap = (struct sockaddr *)&(snp->sn_mask);
+ yp_debug_sa(sap);
+ }
+ yp_error("--- securenets dump end ---");
+}
/*
* Read /var/yp/securenets file and initialize the securenets
* list. If the file doesn't exist, we set up a dummy entry that
* allows all hosts to connect.
*/
-void
+#define YP_ACL_HOSTMASK_INET "255.255.255.255"
+#define YP_ACL_HOSTMASK_INET6 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
+int
load_securenets(void)
{
FILE *fp;
- char path[MAXPATHLEN + 2];
- char linebuf[1024 + 2];
- struct securenet *tmp;
-
- /*
- * If securenets is not NULL, we are being called to reload
- * the list; free the existing list before re-reading the
- * securenets file.
- */
- while (securenets) {
- tmp = securenets->next;
- free(securenets);
- securenets = tmp;
+ char linebuf[BUFSIZ + 2];
+ struct securenet *snp;
+ struct sockaddr *sap;
+ int error = 0;
+ int line;
+ struct addrinfo hints, *res, *res0;
+
+ if (SLIST_EMPTY(&securenets))
+ SLIST_INIT(&securenets);
+ else {
+ /*
+ * If securenets is not NULL, we are being called to reload
+ * the list; free the existing list before re-reading the
+ * securenets file.
+ */
+ while (!SLIST_EMPTY(&securenets)) {
+ snp = SLIST_FIRST(&securenets);
+ SLIST_REMOVE_HEAD(&securenets, sn_next);
+ free(snp);
+ }
}
-
- snprintf(path, MAXPATHLEN, "%s/securenets", yp_dir);
-
- if ((fp = fopen(path, "r")) == NULL) {
+ if (debug)
+ yp_error("load_securenets(): loading %s", securenets_path);
+ if ((fp = fopen(securenets_path, "r")) == NULL) {
if (errno == ENOENT) {
- securenets = (struct securenet *)malloc(sizeof(struct securenet));
- securenets->net.s_addr = INADDR_ANY;
- securenets->mask.s_addr = INADDR_ANY;
- securenets->next = NULL;
- return;
+ /* Create empty access list. */
+ if (debug)
+ yp_error("load_securenets(): ENOENT");
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_socktype = SOCK_STREAM;
+ error = getaddrinfo(NULL, "0", &hints, &res0);
+ if (error) {
+ yp_error("getaddrinfo() failed: %s",
+ gai_strerror(error));
+ freeaddrinfo(res0);
+ return (1);
+ }
+ for (res = res0; res; res = res->ai_next) {
+ struct sockaddr *sap;
+ snp = malloc(sizeof(*snp));
+ memset(snp, 0, sizeof(*snp));
+ memcpy(&snp->sn_addr, res->ai_addr,
+ sizeof(res->ai_addrlen));
+ memcpy(&snp->sn_mask, res->ai_addr,
+ sizeof(res->ai_addrlen));
+ sap = (struct sockaddr *)&(snp->sn_mask);
+ prefixlen2mask(sap, 0);
+ SLIST_INSERT_HEAD(&securenets, snp, sn_next);
+ }
+ freeaddrinfo(res0);
+ return (0);
} else {
- yp_error("fopen(%s) failed: %s", path, strerror(errno));
- exit(1);
+ yp_error("fopen(%s) failed: %s", securenets_path,
+ strerror(errno));
+ return (1);
}
}
- securenets = NULL;
-
- while (fgets(linebuf, LINEBUFSZ, fp)) {
- char addr1[20], addr2[20];
-
+ line = 0;
+ while (fgets(linebuf, sizeof(linebuf), fp)) {
+ int nitems;
+ char *col_host;
+ char *col_mask;
+ char addr1[NI_MAXHOST + 1];
+ char addr2[NI_MAXHOST + 1];
+ int plen;
+ sa_family_t family;
+ char *p;
+
+ line++;
+ if (debug)
+ yp_error("load_securenets(): read line %d", line);
if ((linebuf[0] == '#')
|| (strspn(linebuf, " \t\r\n") == strlen(linebuf)))
continue;
- if (sscanf(linebuf, "%s %s", addr1, addr2) < 2) {
- yp_error("badly formatted securenets entry: %s",
- linebuf);
- continue;
- }
-
- tmp = (struct securenet *)malloc(sizeof(struct securenet));
+ nitems = sscanf(linebuf, "%s %s", addr1, addr2);
+ snp = malloc(sizeof(*snp));
+ memset(snp, 0, sizeof(*snp));
+
+ if (debug)
+ yp_error("load_securenets(): nitems = %d", nitems);
+ if (nitems == 2) {
+ switch (securenets_format) {
+ case YP_SNF_NATIVE:
+ /* ex. 127.0.0.1 255.0.0.0 */
+ col_host = addr1;
+ col_mask = addr2;
+ break;
+ case YP_SNF_SOLARIS:
+ /* ex. 255.0.0.0 127.0.0.1 */
+ col_host = addr2;
+ col_mask = addr1;
+ break;
+ default:
+ yp_error("line %d: internal error: %s",
+ line, linebuf);
+ continue;
+
+ }
+ if (debug) {
+ yp_error("load_securenets(): try mask expr");
+ yp_error("load_securenets(): host = [%s]",
+ col_host);
+ yp_error("load_securenets(): mask = [%s]",
+ col_mask);
+ }
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_NUMERICHOST;
+ error = getaddrinfo(col_host, NULL, &hints, &res0);
+ if (error) {
+ yp_error("line %d: "
+ "badly formatted securenets entry: "
+ "%s: %s: %s", line, linebuf,
+ gai_strerror(error));
+ freeaddrinfo(res0);
+ free(snp);
+ continue;
+ }
+ memcpy(&snp->sn_addr, res0->ai_addr, res0->ai_addrlen);
+ family = res0->ai_addr->sa_family;
+ freeaddrinfo(res0);
+
+ if ((securenets_format == YP_SNF_SOLARIS) &&
+ (strcmp(col_host, "host") == 0)) {
+ switch (family) {
+#ifdef AF_INET
+ case AF_INET:
+ col_host = YP_ACL_HOSTMASK_INET;
+ break;
+#endif
+#ifdef AF_INET6
+ case AF_INET6:
+ col_host = YP_ACL_HOSTMASK_INET6;
+ break;
+#endif
+ default:
+ yp_error("line %d: host keyword for "
+ "unsupported address family: "
+ "%s: %s", line, linebuf,
+ gai_strerror(error));
+ continue;
+ }
+ }
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_NUMERICHOST;
+ error = getaddrinfo(col_mask, NULL, &hints, &res0);
+ if (error) {
+ yp_error("line %d: "
+ "badly formatted securenets entry: "
+ "%s: %s: %s", line, linebuf,
+ gai_strerror(error));
+ freeaddrinfo(res0);
+ free(snp);
+ continue;
+ }
+ memcpy(&snp->sn_mask, res0->ai_addr, res0->ai_addrlen);
+ freeaddrinfo(res0);
+ } else if (nitems == 1) {
+ /* ex. 127.0.0.1/8 */
+ /* ex. fe80::/10 */
+ if (debug)
+ yp_error("load_securenets(): try CIDR expr");
+ p = strrchr(addr1, '/');
+ if (p != NULL) {
+ *p = ' ';
+ nitems = sscanf(addr1, "%s %d", addr2, &plen);
+ if (nitems < 2) {
+ yp_error("line %d: "
+ "badly formatted securenets entry:"
+ " %s", line, linebuf);
+ free(snp);
+ continue;
+ }
+ } else
+ memcpy(addr2, addr1, sizeof(addr2));
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_NUMERICHOST;
+ error = getaddrinfo(addr2, NULL, &hints, &res0);
+ if (error) {
+ yp_error("line %d: "
+ "badly formatted securenets entry: "
+ "%s: %s", line, linebuf,
+ gai_strerror(error));
+ freeaddrinfo(res0);
+ free(snp);
+ continue;
+ }
+ if (p == NULL)
+ switch (res0->ai_addr->sa_family) {
+#ifdef AF_INET
+ case AF_INET:
+ plen = 32;
+ break;
+#endif
+#ifdef AF_INET6
+ case AF_INET6:
+ plen = 128;
+ break;
+#endif
+ default:
+ yp_error("line %d: "
+ "unsupported address family: "
+ "%s: %s", line, linebuf,
+ gai_strerror(error));
+ continue;
+ }
+ if (debug) {
+ yp_error("load_securenets(): addr2 = [%s]",
+ addr2);
+ yp_error("load_securenets(): plen = [%d]",
+ plen);
+ }
+ memcpy(&snp->sn_addr, res0->ai_addr, res0->ai_addrlen);
+ memcpy(&snp->sn_mask, res0->ai_addr, res0->ai_addrlen);
+ freeaddrinfo(res0);
- if (!inet_aton((char *)&addr1, (struct in_addr *)&tmp->net)) {
- yp_error("badly formatted securenets entry: %s", addr1);
- free(tmp);
+ sap = (struct sockaddr *)&(snp->sn_mask);
+ prefixlen2mask(sap, &plen);
+ } else {
+ yp_error("line %d: "
+ "badly formatted securenets entry: "
+ "%s", line, linebuf);
continue;
}
-
- if (!inet_aton((char *)&addr2, (struct in_addr *)&tmp->mask)) {
- yp_error("badly formatted securenets entry: %s", addr2);
- free(tmp);
- continue;
+ if (debug) {
+ yp_error("load_securenets(): adding entry");
+ yp_debug_sa((struct sockaddr*)&(snp->sn_addr));
+ yp_debug_sa((struct sockaddr *)&(snp->sn_mask));
}
-
- tmp->next = securenets;
- securenets = tmp;
+ SLIST_INSERT_HEAD(&securenets, snp, sn_next);
}
-
fclose(fp);
+ if (debug)
+ show_securenets();
+ return (0);
+}
+static int
+compare_subnet(struct sockaddr *addr1,
+ struct sockaddr *addr2,
+ struct sockaddr *mask)
+{
+#ifdef AF_INET
+ struct sockaddr_in *in_addr1;
+ struct sockaddr_in *in_addr2;
+ struct sockaddr_in *in_addrm;
+#endif
+#ifdef AF_INET6
+ struct sockaddr_in6 *in6_addr1;
+ struct sockaddr_in6 *in6_addr2;
+ struct sockaddr_in6 *in6_addrm;
+#endif
+ u_char a1[sizeof(struct sockaddr_storage)];
+ u_char a2[sizeof(struct sockaddr_storage)];
+ u_char m[sizeof(struct sockaddr_storage)];
+ size_t len;
+ int i;
+ int samescope;
+
+ if (addr1->sa_family != addr2->sa_family)
+ return (1);
+
+ memset(a1, 0, sizeof(a1));
+ memset(a1, 0, sizeof(a2));
+ memset(m, 0, sizeof(m));
+
+ switch (addr1->sa_family) {
+#ifdef AF_INET
+ case AF_INET:
+ in_addr1 = (struct sockaddr_in *)(addr1);
+ in_addr2 = (struct sockaddr_in *)(addr2);
+ in_addrm = (struct sockaddr_in *)(mask);
+ len = sizeof(in_addr1->sin_addr.s_addr);
+ memcpy(a1, (u_char *)&(in_addr1->sin_addr.s_addr),
+ sizeof(in_addr1->sin_addr.s_addr));
+ memcpy(a2, (u_char *)&(in_addr2->sin_addr.s_addr),
+ sizeof(in_addr2->sin_addr.s_addr));
+ memcpy(m, (u_char *)&(in_addrm->sin_addr.s_addr),
+ sizeof(in_addrm->sin_addr.s_addr));
+ samescope = 1;
+ break;
+#endif
+#ifdef AF_INET6
+ case AF_INET6:
+ in6_addr1 = (struct sockaddr_in6 *)(addr1);
+ in6_addr2 = (struct sockaddr_in6 *)(addr2);
+ in6_addrm = (struct sockaddr_in6 *)(mask);
+ len = sizeof(in6_addr1->sin6_addr.s6_addr);
+ memcpy(a1, (u_char *)in6_addr1->sin6_addr.s6_addr,
+ sizeof(in6_addr1->sin6_addr.s6_addr));
+ memcpy(a2, (u_char *)in6_addr2->sin6_addr.s6_addr,
+ sizeof(in6_addr2->sin6_addr.s6_addr));
+ memcpy(m, (u_char *)in6_addrm->sin6_addr.s6_addr,
+ sizeof(in6_addrm->sin6_addr.s6_addr));
+ samescope = (in6_addr1->sin6_scope_id ==
+ in6_addr2->sin6_scope_id);
+ break;
+#endif
+ default:
+ return (1);
+ }
+ for (i=0; i < len; i++) {
+ a1[i] &= m[i];
+ a2[i] &= m[i];
+ }
+ if (debug) {
+ yp_error("compare_subnet(): addr1");
+ yp_debug_sa(addr1);
+ yp_error("compare_subnet(): addr2");
+ yp_debug_sa(addr2);
+ yp_error("compare_subnet(): mask");
+ yp_debug_sa(mask);
+ }
+ if (!samescope)
+ return (1);
+ return (memcmp(a1, a2, len));
}
/*
@@ -211,15 +550,21 @@ int
yp_access(const char *map, const struct svc_req *rqstp)
#endif
{
- struct sockaddr_in *rqhost;
int status_securenets = 0;
+ int error;
#ifdef TCP_WRAPPER
int status_tcpwrap;
#endif
- static unsigned long oldaddr = 0;
- struct securenet *tmp;
+ static struct sockaddr oldaddr;
+ struct securenet *snp;
+ struct sockaddr *sap;
+ struct netbuf *rqhost;
const char *yp_procedure = NULL;
char procbuf[50];
+ char host[NI_MAXHOST];
+ char serv[NI_MAXSERV];
+
+ memset(&oldaddr, 0, sizeof(oldaddr));
if (rqstp->rq_prog != YPPASSWDPROG && rqstp->rq_prog != YPPROG) {
snprintf(procbuf, sizeof(procbuf), "#%lu/#%lu",
@@ -232,12 +577,18 @@ yp_access(const char *map, const struct
yp_procs[rqstp->rq_proc + (12 * (rqstp->rq_vers - 1))];
}
- rqhost = svc_getcaller(rqstp->rq_xprt);
-
+ rqhost = svc_getrpccaller(rqstp->rq_xprt);
+ sap = (struct sockaddr *)(rqhost->buf);
+ error = getnameinfo(sap, sap->sa_len,
+ host, sizeof(host), serv, sizeof(serv),
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ if (error) {
+ yp_error("yp_access: getnameinfo(): %s", gai_strerror(error));
+ return (1);
+ }
if (debug) {
- yp_error("procedure %s called from %s:%d", yp_procedure,
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
+ yp_error("procedure %s called from %s:%s", yp_procedure,
+ host, serv);
if (map != NULL)
yp_error("client is referencing map \"%s\".", map);
}
@@ -245,11 +596,10 @@ yp_access(const char *map, const struct
/* Check the map name if one was supplied. */
if (map != NULL) {
if (strchr(map, '/')) {
- yp_error("embedded slash in map name \"%s\" -- \
-possible spoof attempt from %s:%d",
- map, inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port));
- return(1);
+ yp_error("embedded slash in map name \"%s\" "
+ "-- possible spoof attempt from %s:%s",
+ map, host, serv);
+ return (1);
}
#ifdef DB_CACHE
if ((yp_testflag((char *)map, (char *)domain, YP_SECURE) ||
@@ -260,27 +610,30 @@ possible spoof attempt from %s:%d",
rqstp->rq_proc == YPPROC_XFR) ||
(rqstp->rq_prog == YPXFRD_FREEBSD_PROG &&
rqstp->rq_proc == YPXFRD_GETMAP)) &&
- ntohs(rqhost->sin_port) >= IPPORT_RESERVED) {
- yp_error("access to %s denied -- client %s:%d \
-not privileged", map, inet_ntoa(rqhost->sin_addr), ntohs(rqhost->sin_port));
- return(1);
+ atoi(serv) >= IPPORT_RESERVED) {
+ yp_error("access to %s denied -- client %s:%s"
+ " not privileged", map, host, serv);
+ return (1);
}
}
#ifdef TCP_WRAPPER
- status_tcpwrap = hosts_ctl("ypserv", STRING_UNKNOWN,
- inet_ntoa(rqhost->sin_addr), "");
+ status_tcpwrap = hosts_ctl("ypserv", STRING_UNKNOWN, host, "");
#endif
- tmp = securenets;
- while (tmp) {
- if (((rqhost->sin_addr.s_addr & ~tmp->mask.s_addr)
- | tmp->net.s_addr) == rqhost->sin_addr.s_addr) {
+ if (debug)
+ yp_error("yp_access(): compare start");
+ SLIST_FOREACH (snp, &securenets, sn_next) {
+ if (compare_subnet(sap,
+ (struct sockaddr *)&(snp->sn_addr),
+ (struct sockaddr *)&(snp->sn_mask)) == 0) {
status_securenets = 1;
+ if (debug)
+ yp_error("yp_access(): compare success!");
break;
}
- tmp = tmp->next;
}
-
+ if (debug)
+ yp_error("yp_access(): compare end");
#ifdef TCP_WRAPPER
if (status_securenets == 0 || status_tcpwrap == 0) {
#else
@@ -296,16 +649,14 @@ not privileged", map, inet_ntoa(rqhost->
*
* In either case deny access.
*/
- if (rqhost->sin_addr.s_addr != oldaddr) {
- yp_error("connect from %s:%d to procedure %s refused",
- inet_ntoa(rqhost->sin_addr),
- ntohs(rqhost->sin_port),
- yp_procedure);
- oldaddr = rqhost->sin_addr.s_addr;
+ if (memcmp(sap, &oldaddr, sizeof(oldaddr))) {
+ yp_error("connect from %s:%s to procedure %s refused",
+ host, serv, yp_procedure);
+ memcpy(&oldaddr, sap, sizeof(oldaddr));
}
- return(1);
+ return (1);
}
- return(0);
+ return (0);
}
@@ -318,13 +669,12 @@ yp_validdomain(const char *domain)
if (domain == NULL || strstr(domain, "binding") ||
!strcmp(domain, ".") || !strcmp(domain, "..") ||
strchr(domain, '/') || strlen(domain) > YPMAXDOMAIN)
- return(1);
+ return (1);
snprintf(dompath, sizeof(dompath), "%s/%s", yp_dir, domain);
if (stat(dompath, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode))
- return(1);
-
+ return (1);
- return(0);
+ return (0);
}
Added: user/hrs/ipv6/usr.sbin/ypserv/yp_access_inet.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/hrs/ipv6/usr.sbin/ypserv/yp_access_inet.c Sun May 29 12:15:49 2011 (r222448)
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2010-2011 Hiroki Sato. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "yp_extern.h"
+
+int
+yp_mask2prefixlen_in(const struct sockaddr *sap, int *prefixlen)
+{
+ int x, y = 0;
+ const u_char *p;
+ const struct in_addr *addr;
+ const struct sockaddr_in *sainp;
+
+ sainp = (const struct sockaddr_in *)sap;
+ addr = &(sainp->sin_addr);
+ p = (const u_char *)&addr->s_addr;
+ for (x = 0; x < (int)sizeof(addr->s_addr); x++)
+ if (p[x] != 0xff)
+ break;
+ if (x < (int)sizeof(addr->s_addr))
+ for (y = 0; y < 8; y++)
+ if ((p[x] & (0x80 >> y)) == 0)
+ break;
+ *prefixlen = x * 8 + y;
+ return (0);
+}
+
+int
+yp_prefixlen2mask_in(struct sockaddr *sap, const int *prefixlen)
+{
+ int i;
+ int len;
+ u_char *p;
+ struct in_addr *addr;
+ struct sockaddr_in *sainp;
+
+ len = *prefixlen;
+ if (0 > len || len > 32)
+ return (-1);
+
+ sainp = (struct sockaddr_in *)sap;
+ memset(&sainp->sin_addr, 0, sizeof(sainp->sin_addr));
+ addr = &(sainp->sin_addr);
+ p = (u_char *)&addr->s_addr;
+ for (i = 0; i < len / 8; i++)
+ p[i] = 0xff;
+ if (len % 8)
+ p[i] = (0xff00 >> (len % 8)) & 0xff;
+ return (0);
+}
+
+struct sockaddr *
+yp_mask_in(const struct sockaddr *addr, const struct sockaddr *mask)
+{
+ int i;
+ const u_char *p, *q;
+ u_char *r;
+ const struct sockaddr_in *in_addr;
+ const struct sockaddr_in *in_mask;
+ struct sockaddr_in *in_res;
+
+ in_addr = (const struct sockaddr_in *)addr;
+ in_mask = (const struct sockaddr_in *)mask;
+
+ if ((in_res = malloc(sizeof(*in_res))) == NULL)
+ return NULL;
+ memcpy(in_res, in_addr, sizeof(*in_res));
+ p = (const u_char *)&(in_addr->sin_addr.s_addr);
+ q = (const u_char *)&(in_mask->sin_addr.s_addr);
+ r = (u_char *)&(in_res->sin_addr.s_addr);
+ for (i = 0; i < (int)sizeof(in_addr->sin_addr.s_addr); i++)
+ r[i] = p[i] & q[i];
+
+ return ((struct sockaddr *)in_res);
+}
+
+int
+yp_compare_subnet_in(const struct sockaddr *a1, const struct sockaddr *a2)
+{
+ const struct sockaddr_in *in_a1 = (const struct sockaddr_in *)a1;
+ const struct sockaddr_in *in_a2 = (const struct sockaddr_in *)a2;
+
+ if (debug) {
+ yp_error("yp_subnet_cmp_in(): a1");
+ yp_debug_sa(a1);
+ yp_error("yp_subnet_cmp_in(): a2");
+ yp_debug_sa(a2);
+ }
+ return (memcmp((const u_char *)&(in_a1->sin_addr.s_addr),
+ (const u_char *)&(in_a2->sin_addr.s_addr),
+ sizeof(in_a1->sin_addr.s_addr)));
+}
Added: user/hrs/ipv6/usr.sbin/ypserv/yp_access_inet6.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/hrs/ipv6/usr.sbin/ypserv/yp_access_inet6.c Sun May 29 12:15:49 2011 (r222448)
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2010-2011 Hiroki Sato. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "yp_extern.h"
+
+int
+yp_mask2prefixlen_in6(const struct sockaddr *sap, int *prefixlen)
+{
+ int x, y = 0;
+ const u_char *p;
+ const struct in6_addr *addr;
+ const struct sockaddr_in6 *sain6p;
+
+ sain6p = (const struct sockaddr_in6 *)sap;
+ addr = &(sain6p->sin6_addr);
+ for (x = 0; x < (int)sizeof(addr->s6_addr); x++)
+ if (addr->s6_addr[x] != 0xff)
+ break;
+ if (x < (int)sizeof(addr->s6_addr))
+ for (y = 0; y < 8; y++)
+ if ((addr->s6_addr[x] & (0x80 >> y)) == 0)
+ break;
+ if (x < (int)sizeof(addr->s6_addr)) {
+ if (y != 0 && (addr->s6_addr[x] & (0x00ff >> y)) != 0)
+ return (-1);
+ p = (const u_char *)&addr->s6_addr[x + 1];
+ for (; p < addr->s6_addr + sizeof(addr->s6_addr); p++)
+ if (*p != 0)
+ return (-1);
+ }
+ *prefixlen = x * 8 + y;
+ return (0);
+}
+
+int
+yp_prefixlen2mask_in6(struct sockaddr *sap, const int *prefixlen)
+{
+ int i;
+ int len;
+ int bytelen, bitlen;
+ u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
+ struct in6_addr *addr;
+ struct sockaddr_in6 *sain6p;
+
+ len = *prefixlen;
+ if (0 > len || len > 128)
+ return (-1);
+
+ sain6p = (struct sockaddr_in6 *)sap;
+ memset(&sain6p->sin6_addr, 0, sizeof(sain6p->sin6_addr));
+ addr = &(sain6p->sin6_addr);
+ bytelen = len / 8;
+ bitlen = len % 8;
+ for (i = 0; i < bytelen; i++)
+ addr->s6_addr[i] = 0xff;
+ if (bitlen)
+ addr->s6_addr[bytelen] = maskarray[bitlen - 1];
+ return (0);
+}
+
+struct sockaddr *
+yp_mask_in6(const struct sockaddr *addr, const struct sockaddr *mask)
+{
+ int i;
+ const u_char *p, *q;
+ u_char *r;
+ const struct sockaddr_in6 *in6_addr;
+ const struct sockaddr_in6 *in6_mask;
+ struct sockaddr_in6 *in6_res;
+
+ in6_addr = (const struct sockaddr_in6 *)addr;
+ in6_mask = (const struct sockaddr_in6 *)mask;
+
+ if ((in6_res = malloc(sizeof(*in6_res))) == NULL)
+ return NULL;
+ memcpy(in6_res, in6_addr, sizeof(*in6_res));
+ p = (const u_char *)&(in6_addr->sin6_addr.s6_addr);
+ q = (const u_char *)&(in6_mask->sin6_addr.s6_addr);
+ r = (u_char *)&(in6_res->sin6_addr.s6_addr);
+ for (i = 0; i < (int)sizeof(in6_addr->sin6_addr.s6_addr); i++)
+ r[i] = p[i] & q[i];
+
+ return ((struct sockaddr *)in6_res);
+}
+
+int
+yp_compare_subnet_in6(const struct sockaddr *a1, const struct sockaddr *a2)
+{
+ const struct sockaddr_in6 *in6_a1 = (const struct sockaddr_in6 *)a1;
+ const struct sockaddr_in6 *in6_a2 = (const struct sockaddr_in6 *)a2;
+
+ if (debug) {
+ yp_error("yp_subnet_cmp_in6(): a1");
+ yp_debug_sa(a1);
+ yp_error("yp_subnet_cmp_in6(): a2");
+ yp_debug_sa(a2);
+ yp_error("yp_subnet_cmp_in6(): scope: %d - %d",
+ in6_a1->sin6_scope_id, in6_a2->sin6_scope_id);
+ }
+
+ if (in6_a1->sin6_scope_id != in6_a2->sin6_scope_id)
+ return (-1);
+
+ return (memcmp(in6_a1->sin6_addr.s6_addr,
+ in6_a2->sin6_addr.s6_addr,
+ sizeof(in6_a1->sin6_addr.s6_addr)));
+}
Modified: user/hrs/ipv6/usr.sbin/ypserv/yp_extern.h
==============================================================================
--- user/hrs/ipv6/usr.sbin/ypserv/yp_extern.h Sun May 29 11:10:56 2011 (r222447)
+++ user/hrs/ipv6/usr.sbin/ypserv/yp_extern.h Sun May 29 12:15:49 2011 (r222448)
@@ -32,15 +32,16 @@
* $FreeBSD$
*/
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/yp.h>
#include <db.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <rpc/rpc.h>
-#include <rpcsvc/yp.h>
#ifndef _PATH_YP
#define _PATH_YP "/var/yp/"
@@ -57,6 +58,8 @@
#define YP_SECURE 0x1
#define YP_INTERDOMAIN 0x2
+#define SECURENETS_FNAME "securenets"
+
/*
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-user
mailing list