Date: Sun, 29 May 2011 12:15:49 +0000 (UTC) From: Hiroki Sato <hrs@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r222448 - user/hrs/ipv6/usr.sbin/ypserv Message-ID: <201105291215.p4TCFnt0029384@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105291215.p4TCFnt0029384>