Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 31 Jul 2012 16:20:05 +0000
From:      exxo@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r239957 - in soc2012/exxo/freebsd-head: include/rpcsvc lib/libc/yp usr.sbin/ypbind
Message-ID:  <20120731162005.D84F2106566B@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: exxo
Date: Tue Jul 31 16:20:04 2012
New Revision: 239957
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=239957

Log:
  Updating ypbind

Modified:
  soc2012/exxo/freebsd-head/include/rpcsvc/yp.x
  soc2012/exxo/freebsd-head/include/rpcsvc/yp_prot.h
  soc2012/exxo/freebsd-head/lib/libc/yp/yplib.c
  soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.c
  soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.h
  soc2012/exxo/freebsd-head/usr.sbin/ypbind/ypbind.c

Modified: soc2012/exxo/freebsd-head/include/rpcsvc/yp.x
==============================================================================
--- soc2012/exxo/freebsd-head/include/rpcsvc/yp.x	Tue Jul 31 15:47:50 2012	(r239956)
+++ soc2012/exxo/freebsd-head/include/rpcsvc/yp.x	Tue Jul 31 16:20:04 2012	(r239957)
@@ -208,12 +208,12 @@
         ypbind_binding ypbind_bindinfo;
 };     
 
-/* Detailed failure reason codes for response field ypbind_error*/
+/* Detailed failure reason codes for response field ypbind_error */
  
 const YPBIND_ERR_ERR    = 1;	/* Internal error */
 const YPBIND_ERR_NOSERV = 2;	/* No bound server for passed domain */
 const YPBIND_ERR_RESC   = 3;	/* System resource allocation failure */
- 
+const YPBIND_ERR_FAMILY = 4;	/* Unsupported family */
  
 /*
  * Request data structure for ypbind "Set domain" procedure.
@@ -223,6 +223,8 @@
 	ypbind_binding ypsetdom_binding;
 	unsigned ypsetdom_vers;
 };
+%#define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr
+%#define ypsetdom_port ypsetdom_binding.ypbind_binding_port
 
 /* Backward compatibility for YPBIND protocol version 2 */
 #ifdef YPBIND_COMPAT_V2
@@ -247,8 +249,17 @@
 	unsigned ypsetdom_vers;
 };
 
+%#define yprespv2_error	ypbind_resp_v2_u.ypbind_error
+%#define yprespv2_addr	ypbind_resp_v2_u.ypbind_bindinfo.ypbind_binding_addr
+%#define yprespv2_port	ypbind_resp_v2_u.ypbind_bindinfo.ypbind_binding_port
+
 #endif
 
+%#define ypresp_error	ypbind_resp_u.ypbind_error
+%#define ypresp_family	ypbind_resp_u.ypbind_bindinfo.ypbind_binding_family
+%#define ypresp_addr	ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr
+%#define ypresp_port	ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port
+
 /*
  * NIS v1 support for backwards compatibility
  */

Modified: soc2012/exxo/freebsd-head/include/rpcsvc/yp_prot.h
==============================================================================
--- soc2012/exxo/freebsd-head/include/rpcsvc/yp_prot.h	Tue Jul 31 15:47:50 2012	(r239956)
+++ soc2012/exxo/freebsd-head/include/rpcsvc/yp_prot.h	Tue Jul 31 16:20:04 2012	(r239957)
@@ -261,6 +261,7 @@
 #define YPBIND_ERR_ERR		1	/* internal error */
 #define YPBIND_ERR_NOSERV	2	/* no bound server for passed domain */
 #define YPBIND_ERR_RESC		3	/* system resource allocation failure */
+#define YPBIND_ERR_FAMILY	4	/* unsupported family */
 
 /*
  * Request data structure for ypbind "Set domain" procedure.
@@ -295,8 +296,17 @@
 	u_int ypsetdom_vers;
 };
 
+#define yprespv2_error	ypbind_resp_v2_u.ypbind_error
+#define yprespv2_addr	ypbind_resp_v2_u.ypbind_bindinfo.ypbind_binding_addr
+#define yprespv2_port	ypbind_resp_v2_u.ypbind_bindinfo.ypbind_binding_port
+
 #endif
 
+#define ypresp_error	ypbind_resp_u.ypbind_error
+#define ypresp_family	ypbind_resp_u.ypbind_bindinfo.ypbind_binding_family
+#define ypresp_addr	ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr
+#define ypresp_port	ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port
+
 /*
  * YPPUSH PROTOCOL:
  *

Modified: soc2012/exxo/freebsd-head/lib/libc/yp/yplib.c
==============================================================================
--- soc2012/exxo/freebsd-head/lib/libc/yp/yplib.c	Tue Jul 31 15:47:50 2012	(r239956)
+++ soc2012/exxo/freebsd-head/lib/libc/yp/yplib.c	Tue Jul 31 16:20:04 2012	(r239957)
@@ -278,6 +278,8 @@
 		return ("Domain not bound");
 	case YPBIND_ERR_RESC:
 		return ("System resource allocation failure");
+	case YPBIND_ERR_FAMILY:
+		return ("Unsupported family");
 	}
 	sprintf(err, "Unknown ypbind error: #%d\n", incode);
 	return (err);

Modified: soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.c
==============================================================================
--- soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.c	Tue Jul 31 15:47:50 2012	(r239956)
+++ soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.c	Tue Jul 31 16:20:04 2012	(r239957)
@@ -229,25 +229,20 @@
 # define TSP_LEN (V4 + 1)
 #endif
 
-static u_short
-__yp_getport(const struct sockaddr_storage *host, const char *netid)
+u_short
+__rpcb_getport(const char *hostname, const char *netid,
+    const rpcprog_t prognum, const rpcvers_t versnum)
 {
 	struct sockaddr_storage sst;
 	struct netconfig *nconf;
 	struct netbuf svcaddr;
 	u_short port;
-	char str[ADDRSTRLEN];
-	int family;
-	char *ptr;
 
 	svcaddr.len = 0;
 	svcaddr.maxlen = sizeof(sst);
 	svcaddr.buf = &sst;
-	if (ss_extract(host, &family, &ptr, 0))
-		return (0);
-	inet_ntop(family, ptr, str, ADDRSTRLEN);
 	if ((nconf = getnetconfigent(netid)) == NULL ||
-	    !rpcb_getaddr(YPPROG, YPVERS, nconf, &svcaddr, str))
+	    !rpcb_getaddr(prognum, versnum, nconf, &svcaddr, hostname))
 		return (0);
 	switch (svcaddr.len) {
 	case sizeof(struct sockaddr_in) :
@@ -264,6 +259,19 @@
 	return (port); /* Network byte order */
 }
 
+static u_short
+__yp_getport(const struct sockaddr_storage *host, const char *netid)
+{
+	char str[ADDRSTRLEN];
+	int family;
+	char *ptr;
+
+	if (ss_extract(host, &family, &ptr, 0))
+		return (0);
+	inet_ntop(family, ptr, str, ADDRSTRLEN);
+	return (__rpcb_getport(str, netid, YPPROG, YPVERS));
+}
+
 static int
 rpc_init(struct transport *tsp)
 {
@@ -278,13 +286,13 @@
 			continue;
 #ifdef INET6
 		if (i == V6) {
-			tsp[i]->sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+			tsp[i]->sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
 			tsp[i]->addr.len = sizeof(struct sockaddr_in6);
 		}
 		else /* V4 */
 #endif
 		{
-			tsp[i]->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+			tsp[i]->sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
 			tsp[i]->addr.len = sizeof(struct sockaddr_in);
 		}
 		if (tsp[i]->sock < 0)
@@ -322,7 +330,7 @@
 }
 
 int
-__yp_ping(struct sockaddr_storage *restricted_addrs, int cnt, char *dom, short *port)
+__yp_ping(struct sockaddr_storage *restricted_addrs, int cnt, char *dom, u_short *port)
 {
 	struct ping_req		**reqs;
 	unsigned long		i;
@@ -345,7 +353,7 @@
 	xid_seed = time(NULL) ^ getpid();
 
 	for (i = 0; i < cnt; i++) {
-		yp_port = __yp_getport(&restricted_addrs[i], "udp");
+		yp_port = __yp_getport(&restricted_addrs[i], CONNLESS_TSP);
 		if (yp_port == 0)
 			continue;
 		reqs[i] = calloc(1, sizeof(struct ping_req));

Modified: soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.h
==============================================================================
--- soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.h	Tue Jul 31 15:47:50 2012	(r239956)
+++ soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.h	Tue Jul 31 16:20:04 2012	(r239957)
@@ -2,6 +2,9 @@
  * $FreeBSD$
  */
 
+#define CONNFULL_TSP "tcp"
+#define CONNLESS_TSP "udp"
+
 #ifdef INET6
 # define ADDRSTRLEN INET6_ADDRSTRLEN
 #else
@@ -22,13 +25,13 @@
 	case AF_INET:
 		*addr = ss_to_sinaddr(ss);
 		if (len)
-			*len = sizeof(struct sockaddr_in);
+			*len = sizeof(struct in_addr);
 		break;
 #ifdef INET6
 	case AF_INET6:
 		*addr = ss_to_sin6addr(ss);
 		if (len)
-			*len = sizeof(struct sockaddr_in6);
+			*len = sizeof(struct in6_addr);
 		break;
 #endif
 	default:
@@ -37,4 +40,17 @@
 	return (0);
 }
 
-extern int __yp_ping(struct sockaddr_storage *, int, char *, short *);
+static inline u_short *
+ss_getport(const struct sockaddr_storage *ss)
+{
+#ifdef INET6
+	if (ss_family(ss) == AF_INET6)
+		return (&ss_to_sin6port(ss));
+	else
+#endif
+		return (&ss_to_sinport(ss));
+}
+
+extern int __yp_ping(struct sockaddr_storage *, int, char *, u_short *);
+extern u_short __rpcb_getport(const char *hostname, const char *netid,
+    const rpcprog_t prognum, const rpcvers_t versnum);

Modified: soc2012/exxo/freebsd-head/usr.sbin/ypbind/ypbind.c
==============================================================================
--- soc2012/exxo/freebsd-head/usr.sbin/ypbind/ypbind.c	Tue Jul 31 15:47:50 2012	(r239956)
+++ soc2012/exxo/freebsd-head/usr.sbin/ypbind/ypbind.c	Tue Jul 31 16:20:04 2012	(r239957)
@@ -69,6 +69,10 @@
 #define BINDINGDIR "/var/yp/binding"
 #endif
 
+#if !defined(BINDINGDIR_V2) && defined(YPBIND_COMPAT_V2)
+#define BINDINGDIR_V2 "/var/yp/binding.2"
+#endif
+
 #ifndef YPBINDLOCK
 #define YPBINDLOCK "/var/run/ypbind.lock"
 #endif
@@ -79,6 +83,9 @@
 	struct sockaddr_storage dom_server_addr; /* TODO */
 	long int dom_vers;
 	int dom_lockfd;
+#ifdef YPBIND_COMPAT_V2
+	int dom_lockfd_v2;
+#endif
 	int dom_alive;
 	int dom_broadcast_pid;
 	int dom_pipe_fds[2];
@@ -148,6 +155,9 @@
 #define MAX_RETRIES 30
 #endif
 
+#define CLOSE_LKS	1
+#define FREE_DOMB	2
+
 int retries = 0;
 int children = 0;
 int domains = 0;
@@ -168,7 +178,6 @@
 {
 	static struct ypbind_resp res;
 	struct _dom_binding *ypdb;
-	char path[MAXPATHLEN];
 
 	bzero(&res, sizeof res);
 	res.ypbind_status = YPBIND_FAIL_VAL;
@@ -209,9 +218,10 @@
 		ypdb->dom_alive = 0;
 		ypdb->dom_default = 0;
 		ypdb->dom_lockfd = -1;
-		sprintf(path, "%s/%s.%ld", BINDINGDIR,
-					ypdb->dom_domain, ypdb->dom_vers);
-		unlink(path);
+#ifdef YPBIND_COMPAT_V2
+		ypdb->dom_lockfd_v2 = -1;
+#endif
+		unregister_domb(ypdb, 0);
 		ypdb->dom_pnext = ypbindlist;
 		ypbindlist = ypdb;
 		domains++;
@@ -355,18 +365,14 @@
 terminate(int sig)
 {
 	struct _dom_binding *ypdb;
-	char path[MAXPATHLEN];
 
 	if (ppid != getpid())
 		exit(0);
 
 	for (ypdb = ypbindlist; ypdb; ypdb = ypdb->dom_pnext) {
-		close(ypdb->dom_lockfd);
 		if (ypdb->dom_broadcast_pid)
 			kill(ypdb->dom_broadcast_pid, SIGINT);
-		sprintf(path, "%s/%s.%ld", BINDINGDIR,
-			ypdb->dom_domain, ypdb->dom_vers);
-		unlink(path);
+		unregister_domb(ypdb, CLOSE_LKS);
 	}
 	close(yplockfd);
 	unlink(YPBINDLOCK);
@@ -396,6 +402,136 @@
 	va_end(args);
 }
 
+static int
+create_domb_file(const struct _dom_binding *ypdb, const char *binding_dir)
+{
+	char path[MAXPATHLEN];
+	int fd;
+
+	sprintf(path, "%s/%s.%ld", binding_dir,
+		ypdb->dom_domain, ypdb->dom_vers);
+#ifdef O_SHLOCK
+	if ((fd = open(path, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644)) == -1) {
+		(void)mkdir(binding_dir, 0755);
+		if ((fd = open(path, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644)) == -1)
+			return (-1);
+	}
+#else
+	if ((fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644)) == -1) {
+		(void)mkdir(binding_dir, 0755);
+		if ((fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644)) == -1)
+			return (-1);
+	}
+	flock(fd, LOCK_SH);
+#endif
+	return (fd);
+}
+
+static void
+register_domb(struct _dom_binding *ypdb, const struct sockaddr_storage *addr)
+{
+	struct iovec iov[2];
+	struct ypbind_resp ybr;
+	int family;
+	u_short port;
+
+	if (ypdb->dom_lockfd != -1)
+		close(ypdb->dom_lockfd);
+
+	ypdb->dom_lockfd = create_domb_file(ypdb, BINDINGDIR);
+	if (ypdb->dom_lockfd == -1)
+		return;
+
+	port = __rpcb_getport("127.0.0.1", CONNLESS_TSP, YPBINDPROG, YPBINDVERS);
+	iov[0].iov_base = (char *)&port
+	iov[0].iov_len = sizeof(port);
+	iov[1].iov_base = (char *)&ybr;
+	iov[1].iov_len = sizeof(ybr);
+	
+	family = ss_family(addr);
+	bzero(&ybr, sizeof(ybr));
+	ybr.ypbind_status = YPBIND_SUCC_VAL;
+	ybr.ypresp_family = family;
+	*(u_short *)&ybr.ypresp_port = *ss_getport(addr);
+#ifdef INET6
+	if (family == AF_INET6)
+		bcopy(ss_to_sin6addr(addr), (char *) ybr.ypresp_addr, sizeof(struct in6_addr));
+	else
+#endif
+		bcopy(ss_to_sinaddr(addr), (char *) ybr.ypresp_addr, sizeof(struct in_addr));
+
+	if (writev(ypdb->dom_lockfd, iov, 2) != iov[0].iov_len + iov[1].iov_len) {
+		syslog(LOG_WARNING, "write: %m");
+		close(ypdb->dom_lockfd);
+		ypdb->dom_lockfd = -1;
+	}
+}
+
+#ifdef YPBIND_COMPAT_V2
+static void
+register_domb_v2(struct _dom_binding *ypdb, const struct sockaddr_storage *addr)
+{
+	struct iovec iov[2];
+	struct ypbind_resp_v2 ybr;
+	int family;
+	u_short port;
+
+	if (ypdb->dom_lockfd_v2 != -1)
+		close(ypdb->dom_lockfd_v2);
+
+	ypdb->dom_lockfd_v2 = create_domb_file(ypdb, BINDINGDIR_V2);
+	if (ypdb->dom_lockfd_v2 == -1)
+		return;
+
+	port = __rpcb_getport("127.0.0.1", CONNLESS_TSP, YPBINDPROG, YPBINDVERS_2);
+	iov[0].iov_base = (char *)&port
+	iov[0].iov_len = sizeof(port);
+	iov[1].iov_base = (char *)&ybr;
+	iov[1].iov_len = sizeof(ybr);
+	
+	family = ss_family(addr);
+	bzero(&ybr, sizeof(ybr));
+	if (family != AF_INET) { /* AF_INET6 is not supported in version 2 */
+		ybr2.ypbind_status = YPBIND_FAIL_VAL;
+		ybr2.yprespv2_error = YPBIND_ERR_FAMILY;
+	}
+	else {
+		ybr2.ypbind_status = YPBIND_SUCC_VAL;
+		bcopy(ss_to_sinaddr(addr), (char *) ybr2.yprespv2_addr, sizeof(struct in_addr));
+		*(u_short *)&ybr2.yprespv2_port = ss_to_sinport(addr)
+	}
+
+	if (writev(ypdb->dom_lockfd_v2, iov, 2) != iov[0].iov_len + iov[1].iov_len) {
+		syslog(LOG_WARNING, "write: %m");
+		close(ypdb->dom_lockfd_v2);
+		ypdb->dom_lockfd_v2 = -1;
+	}
+}
+#endif
+
+static void
+unregister_domb(const struct _dom_binding *ypdb, unsigned char mode)
+{
+	char path[MAXPATHLEN];
+
+	sprintf(path, "%s/%s.%ld", BINDINGDIR,
+	    ypdb->dom_domain, YPVERS);
+	if ( (mode & CLOSE_LKS))
+		close(ypdb->dom_lockfd);
+	unlink(path);
+#ifdef YPBIND_COMPAT_V2
+	sprintf(path, "%s/%s.%ld", BINDINGDIR_V2,
+	    ypdb->dom_domain, YPVERS);
+	if ( (mode & CLOSE_LKS))
+		close(ypdb->dom_lockfd_v2);
+	unlink(path);
+#endif
+	if ( (mode & FREE_DOMB)) {
+		free(ypdb);
+		domains--;
+	}
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -404,6 +540,7 @@
 	DIR *dird;
 	struct dirent *dirp;
 	struct _dom_binding *ypdb, *next;
+	char path[MAXPATHLEN];
 
 	/* Check that another ypbind isn't already running. */
 	if ((yplockfd = (open(YPBINDLOCK, O_RDONLY|O_CREAT, 0444))) == -1)
@@ -432,10 +569,9 @@
 			errx(1, "unknown option: %s", argv[i]);
 	}
 
-	/* blow away everything in BINDINGDIR (if it exists) */
+	/* blow away everything in BINDINGDIR/BINDINGDIR_V2 (if they exist) */
 
 	if ((dird = opendir(BINDINGDIR)) != NULL) {
-		char path[MAXPATHLEN];
 		while ((dirp = readdir(dird)) != NULL)
 			if (strcmp(dirp->d_name, ".") &&
 			    strcmp(dirp->d_name, "..")) {
@@ -444,6 +580,17 @@
 			}
 		closedir(dird);
 	}
+#ifdef YPBIND_COMPAT_V2
+	if ((dird = opendir(BINDINGDIR_V2)) != NULL) {
+		while ((dirp = readdir(dird)) != NULL)
+			if (strcmp(dirp->d_name, ".") &&
+			    strcmp(dirp->d_name, "..")) {
+				sprintf(path,"%s/%s",BINDINGDIR_V2,dirp->d_name);
+				unlink(path);
+			}
+		closedir(dird);
+	}
+#endif
 
 #ifdef DAEMON
 	if (daemon(0,0))
@@ -454,15 +601,15 @@
 #ifdef YPBIND_COMPAT_V2
 	rpcb_unset(YPBINDPROG, YPBINDVERS_2, NULL);
 #endif
-	if (!svc_create(ypbindprog_2, YPBINDPROG, YPBINDVERS, "udp")) /* TODO see how to retrieve xp_port */
-		errx(1, "cannot create udp service");
-	if (!svc_create(ypbindprog_2, YPBINDPROG, YPBINDVERS, "tcp"))
-		errx(1, "cannot create tcp service");
-#ifdef YPBIND_COMPAT_V2
-	if (!svc_create(ypbindprog_2, YPBINDPROG, YPBINDVERS_2, "udp"))
-		errx(1, "cannot create udp service");
-	if (!svc_create(ypbindprog_2, YPBINDPROG, YPBINDVERS_2, "tcp"))
-		errx(1, "cannot create tcp service");
+	if (!svc_create(ypbindprog_2, YPBINDPROG, YPBINDVERS, CONNLESS_TSP)) /* TODO see how to retrieve xp_port */
+		errx(1, "cannot create %s service", CONNLESS_TSP);
+	if (!svc_create(ypbindprog_2, YPBINDPROG, YPBINDVERS, CONNFULL_TSP))
+		errx(1, "cannot create %s service", CONNFULL_TSP);
+#ifdef YPBIND_COMPAT_V2
+	if (!svc_create(ypbindprog_2, YPBINDPROG, YPBINDVERS_2, CONNLESS_TSP))
+		errx(1, "cannot create %s service", CONNLESS_TSP);
+	if (!svc_create(ypbindprog_2, YPBINDPROG, YPBINDVERS_2, CONNFULL_TSP))
+		errx(1, "cannot create %s service", CONNFULL_TSP);
 #endif
 
 	/* build initial domain binding, make it "unsuccessful" */
@@ -474,6 +621,9 @@
 	ypbindlist->dom_vers = YPVERS;
 	ypbindlist->dom_alive = 0;
 	ypbindlist->dom_lockfd = -1;
+#ifdef YPBIND_COMPAT_V2
+	ypbindlist->dom_lockfd_v2 = -1;
+#endif
 	ypbindlist->dom_default = 1;
 	domains++;
 
@@ -547,15 +697,14 @@
 handle_children(struct _dom_binding *ypdb)
 {
 	char buf[YPMAXDOMAIN + 1];
-	struct sockaddr_in addr;
+	struct sockaddr_storage addr;
 	int d = 0, a = 0;
 	struct _dom_binding *y, *prev = NULL;
-	char path[MAXPATHLEN];
 
 	if ((d = read(READFD, &buf, sizeof(buf))) <= 0)
 		syslog(LOG_WARNING, "could not read from child: %m");
 
-	if ((a = read(READFD, &addr, sizeof(struct sockaddr_in))) < 0)
+	if ((a = read(READFD, &addr, sizeof(addr))) < 0)
 		syslog(LOG_WARNING, "could not read from child: %m");
 
 	close(READFD);
@@ -576,12 +725,7 @@
 				ypbindlist = y->dom_pnext;
 			else
 				prev->dom_pnext = y->dom_pnext;
-			sprintf(path, "%s/%s.%ld", BINDINGDIR,
-				ypdb->dom_domain, YPVERS);
-			close(ypdb->dom_lockfd);
-			unlink(path);
-			free(ypdb);
-			domains--;
+			unregister_domb(ypdb, CLOSE_LKS | FREE_DOMB);
 			return;
 		case 1:
 			ypdb->dom_broadcast_pid = 0;
@@ -600,7 +744,7 @@
  * Send our dying words back to our parent before we perish.
  */
 int
-tell_parent(char *dom, struct sockaddr_in *addr)
+tell_parent(char *dom, struct sockaddr_storage *addr)
 {
 	char buf[YPMAXDOMAIN + 1];
 	struct timeval timeout;
@@ -623,7 +767,7 @@
 	if (select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == -1)
 		return(1);
 	if (FD_ISSET(BROADFD, &fds)) {
-		if (write(BROADFD, addr, sizeof(struct sockaddr_in)) < 0)
+		if (write(BROADFD, addr, sizeof(*addr)) < 0)
 			return(1);
 	} else {
 		return(1);
@@ -633,23 +777,28 @@
 	return (0);
 }
 
-bool_t broadcast_result(out, addr)
-bool_t *out;
-struct sockaddr_in *addr;
+bool_t
+broadcast_result(bool_t *out, const struct netbuf *addr,
+    const struct netconfig * netconf)
 {
+	struct sockaddr_storage sst;
+
+	if (addr->len > sizeof(sst) || strcmp(netconf->nc_netid, CONNLESS_TSP))
+		return (FALSE);
+	bzero((char*) &sst, sizeof(sst));
 	if (retries >= MAX_RETRIES) {
-		bzero(addr, sizeof(struct sockaddr_in));
-		if (tell_parent(broad_domain->dom_domain, addr))
+		if (tell_parent(broad_domain->dom_domain, &sst))
 			syslog(LOG_WARNING, "lost connection to parent");
 		return (TRUE);
 	}
-
-	if (yp_restricted && verify(addr->sin_addr)) {
+	bcpy(addr.buf, (char *) &sst, addr.len);
+	if (yp_restricted && verify(&sst)) {
 		retries++;
-		syslog(LOG_NOTICE, "NIS server at %s not in restricted mode access list -- rejecting.\n",inet_ntoa(addr->sin_addr));
+		logwaddr(LOG_NOTICE, &sst, "NIS server at %%s not in restricted mode access list -- rejecting.\n");
 		return (FALSE);
-	} else {
-		if (tell_parent(broad_domain->dom_domain, addr))
+	}
+	else {
+		if (tell_parent(broad_domain->dom_domain, &sst))
 			syslog(LOG_WARNING, "lost connection to parent");
 		return (TRUE);
 	}
@@ -692,6 +841,9 @@
 
 	broad_domain = ypdb;
 	flock(ypdb->dom_lockfd, LOCK_UN);
+#ifdef YPBIND_COMPAT_V2
+	flock(ypdb->dom_lockfd_v2, LOCK_UN);
+#endif
 
 	switch ((ypdb->dom_broadcast_pid = fork())) {
 	case 0:
@@ -714,6 +866,9 @@
 	/* Release all locks before doing anything else. */
 	while (ypbindlist) {
 		close(ypbindlist->dom_lockfd);
+#ifdef YPBIND_COMPAT_V2
+		close(ypbindlist->dom_lockfd_v2);
+#endif
 		ypbindlist = ypbindlist->dom_pnext;
 	}
 	close(yplockfd);
@@ -727,27 +882,20 @@
 	 * operation: we transmit uni-cast datagrams only.
 	 */
 	if (yp_restricted && yp_manycast) {
-		short			port;
+		u_short			port;
 		int			i;
-		struct sockaddr_in	sin;
+		struct sockaddr_storage	sst;
 
-		i = __yp_ping(restricted_addrs, yp_restricted,
-				ypdb->dom_domain, &port);
+		i = __yp_ping(restricted_addrs, yp_restricted, ypdb->dom_domain, &port);
 		if (i == -1) {
-			bzero(&ypdb->dom_server_addr,
-			    sizeof(struct sockaddr_in));
-			if (tell_parent(ypdb->dom_domain,
-				&ypdb->dom_server_addr))
+			bzero(&ypdb->dom_server_addr, sizeof(struct sockaddr_storage));
+			if (tell_parent(ypdb->dom_domain, &ypdb->dom_server_addr))
 			syslog(LOG_WARNING, "lost connection to parent");
 		} else {
-			bzero(&sin, sizeof(struct sockaddr_in));
-			bcopy(&restricted_addrs[i],
-			    &sin.sin_addr, sizeof(struct in_addr));
-			sin.sin_family = AF_INET;
-			sin.sin_port = port;
-			if (tell_parent(broad_domain->dom_domain, &sin))
-				syslog(LOG_WARNING,
-					"lost connection to parent");
+			bcopy(&restricted_addrs[i], &sst, sizeof(sst));
+			*ss_getport(&sst) = port;
+			if (tell_parent(broad_domain->dom_domain, &sst))
+				syslog(LOG_WARNING, "lost connection to parent");
 		}
 		_exit(0);
 	}
@@ -758,15 +906,14 @@
 		char *ptr;
 
 		ptr = ypdb->dom_domain;
-		stat = clnt_broadcast(YPPROG, YPVERS, YPPROC_DOMAIN_NONACK,
+		stat = rpc_broadcast(YPPROG, YPVERS, YPPROC_DOMAIN_NONACK,
 	    		(xdrproc_t)xdr_domainname, &ptr,
 		        (xdrproc_t)xdr_bool, &out,
-	    		(resultproc_t)broadcast_result);
+	    		(resultproc_t)broadcast_result, CONNLESS_TSP);
 	}
 
 	if (stat != RPC_SUCCESS) {
-		bzero(&ypdb->dom_server_addr,
-		    sizeof(struct sockaddr_in));
+		bzero(&ypdb->dom_server_addr, sizeof(struct sockaddr_storage));
 		if (tell_parent(ypdb->dom_domain, &ypdb->dom_server_addr))
 			syslog(LOG_WARNING, "lost connection to parent");
 	}
@@ -774,6 +921,40 @@
 	_exit(0);
 }
 
+static CLIENT *
+yp_udpclient(struct sockaddr_storage *sst, int *sock)
+{
+	int		family;
+	int		s = -1;
+	CLIENT		*client = NULL;
+	struct netbuf	addr;
+	struct timeval interval;
+
+	interval.tv_sec = FAIL_THRESHOLD;
+	interval.tv_usec = 0;
+
+	family = ss_family(sst);
+	if (family == AF_INET)
+		addr.len = sizeof(struct sockaddr_sin);
+	else /* AF_INET6 */
+#ifdef INET6
+		addr.len = sizeof(struct sockaddr_sin6);
+#else
+		goto err;
+#endif
+	addr.buf = sst;
+	if ((s = socket(family, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+		goto err;
+	client = clnt_dg_create(s, &addr, YPPROG, YPVERS,
+	    RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+	clnt_control(client, CLSET_RETRY_TIMEOUT, &interval);
+err:
+	if (!client)
+		close(s);
+	*sock = s;
+	return (client);
+}
+
 /*
  * The right way to check if a server is alive.
  * Attempt to get a client handle pointing to the server and send a
@@ -790,61 +971,50 @@
 ping(struct _dom_binding *ypdb)
 {
 	bool_t out;
-	struct timeval interval, timeout;
+	struct timeval timeout;
 	enum clnt_stat stat;
-	int rpcsock = RPC_ANYSOCK;
-	CLIENT *client_handle;
+	int rpcsock, err = 0;
+	CLIENT *client;
 
-	interval.tv_sec = FAIL_THRESHOLD;
-	interval.tv_usec = 0;
 	timeout.tv_sec = FAIL_THRESHOLD;
 	timeout.tv_usec = 0;
 
 	if (ypdb->dom_broadcast_pid)
 		return(1);
 
-	if ((client_handle = clntudp_bufcreate(&ypdb->dom_server_addr,
-		YPPROG, YPVERS, interval, &rpcsock, RPCSMALLMSGSIZE,
-		RPCSMALLMSGSIZE)) == (CLIENT *)NULL) {
+	if ((client = yp_udpclient(&ypdb->dom_server_addr, &rpcsock)) == NULL) {
 		/* Can't get a handle: we're dead. */
-		ypdb->dom_alive = 0;
-		ypdb->dom_vers = -1;
-		broadcast(ypdb);
-		return(1);
+		err = 1;
+		goto err;
 	}
 
 	{
-		char *ptr;
-
-		ptr = ypdb->dom_domain;
+		char *ptr = ypdb->dom_domain;
 
-		stat = clnt_call(client_handle, YPPROC_DOMAIN,
+		stat = clnt_call(client, YPPROC_DOMAIN,
 		    (xdrproc_t)xdr_domainname, &ptr,
 		    (xdrproc_t)xdr_bool, &out, timeout);
-		if (stat != RPC_SUCCESS || out == FALSE) {
-			ypdb->dom_alive = 0;
-			ypdb->dom_vers = -1;
-			clnt_destroy(client_handle);
-			broadcast(ypdb);
-			return(1);
-		}
+		if (stat != RPC_SUCCESS || out == FALSE)
+			err = 1;
 	}
-
-	clnt_destroy(client_handle);
-	return(0);
+err:
+	if (err) {
+		ypdb->dom_alive = 0;
+		ypdb->dom_vers = -1;
+		broadcast(ypdb);
+	}
+	if (client) {
+		close(rpcsock);
+		clnt_destroy(client);
+	}
+	return(err);
 }
 
 void
-rpc_received(char *dom, struct sockaddr_in *raddrp, int force)
+rpc_received(char *dom, struct sockaddr_storage *raddrp, int force)
 {
+	static struct sockaddr_storage null_addr;
 	struct _dom_binding *ypdb, *prev = NULL;
-	struct iovec iov[2];
-	struct ypbind_resp ybr;
-	char path[MAXPATHLEN];
-	int fd;
-
-	/*printf("returned from %s/%d about %s\n", inet_ntoa(raddrp->sin_addr),
-	       ntohs(raddrp->sin_port), dom);*/
 
 	if (dom == NULL)
 		return;
@@ -865,11 +1035,10 @@
 		}
 	}
 
+	port = ntohs(*ss_getport(raddrp));
 	/* if in secure mode, check originating port number */
-	if ((ypsecuremode && (ntohs(raddrp->sin_port) >= IPPORT_RESERVED))) {
-	    syslog(LOG_WARNING, "Rejected NIS server on [%s/%d] for domain %s.",
-		   inet_ntoa(raddrp->sin_addr), ntohs(raddrp->sin_port),
-		   dom);
+	if ((ypsecuremode && port >= IPPORT_RESERVED))) {
+	    logwaddr(LOG_WARNING, raddrp, "Rejected NIS server on [%%s/%d] for domain %s.", port, dom);
 	    if (ypdb != NULL) {
 		ypdb->dom_broadcast_pid = 0;
 		ypdb->dom_alive = 0;
@@ -877,19 +1046,16 @@
 	    return;
 	}
 
-	if (raddrp->sin_addr.s_addr == (long)0) {
+	/* bcmp should be safe here due to the earlier raddrp memset which
+	 * prevents us from alignement issues */
+	if (!bcmp((char *) raddrp, (char *) null_addr, sizeof(null_addr))) {
 		switch (ypdb->dom_default) {
 		case 0:
 			if (prev == NULL)
 				ypbindlist = ypdb->dom_pnext;
 			else
 				prev->dom_pnext = ypdb->dom_pnext;
-			sprintf(path, "%s/%s.%ld", BINDINGDIR,
-				ypdb->dom_domain, YPVERS);
-			close(ypdb->dom_lockfd);
-			unlink(path);
-			free(ypdb);
-			domains--;
+			unregister_domb(ypdb, CLOSE_LKS | FREE_DOMB);
 			return;
 		case 1:
 			ypdb->dom_broadcast_pid = 0;
@@ -912,17 +1078,20 @@
 		bzero(ypdb, sizeof *ypdb);
 		strncpy(ypdb->dom_domain, dom, sizeof ypdb->dom_domain);
 		ypdb->dom_lockfd = -1;
+#ifdef YPBIND_COMPAT_V2
+		ypdb->dom_lockfd_v2 = -1;
+#endif
 		ypdb->dom_default = 0;
 		ypdb->dom_pnext = ypbindlist;
 		ypbindlist = ypdb;
 	}
 
 	/* We've recovered from a crash: inform the world. */
-	if (ypdb->dom_vers == -1 && ypdb->dom_server_addr.sin_addr.s_addr) {
+	if (ypdb->dom_vers == -1 && bcmp(&ypdb->dom_server_addr, &null_addr, sizeof(null_addr))) {
 		if (not_responding_count >= NOT_RESPONDING_HYSTERESIS) {
 			not_responding_count = 0;
-			syslog(LOG_WARNING, "NIS server [%s] for domain \"%s\" OK",
-			    inet_ntoa(raddrp->sin_addr), ypdb->dom_domain);
+			logwaddr(LOG_WARNING, raddrp, "NIS server [%%s] for domain \"%s\" OK",
+			    ypdb->dom_domain);
 		}
 	}
 
@@ -933,48 +1102,10 @@
 	ypdb->dom_alive = 1;
 	ypdb->dom_broadcast_pid = 0;
 
-	if (ypdb->dom_lockfd != -1)
-		close(ypdb->dom_lockfd);
-
-	sprintf(path, "%s/%s.%ld", BINDINGDIR,
-		ypdb->dom_domain, ypdb->dom_vers);
-#ifdef O_SHLOCK
-	if ((fd = open(path, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644)) == -1) {
-		(void)mkdir(BINDINGDIR, 0755);
-		if ((fd = open(path, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644)) == -1)
-			return;
-	}
-#else
-	if ((fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644)) == -1) {
-		(void)mkdir(BINDINGDIR, 0755);
-		if ((fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644)) == -1)
-			return;
-	}
-	flock(fd, LOCK_SH);
+	register_domb(ypdb, raddrp);
+#ifdef YPBIND_COMPAT_V2
+	register_domb_v2(ypdb, raddrp);
 #endif
-
-	/*
-	 * ok, if BINDINGDIR exists, and we can create the binding file,
-	 * then write to it..
-	 */
-	ypdb->dom_lockfd = fd;
-
-	iov[0].iov_base = (char *)&(udptransp->xp_port);
-	iov[0].iov_len = sizeof udptransp->xp_port;
-	iov[1].iov_base = (char *)&ybr;
-	iov[1].iov_len = sizeof ybr;
-
-	bzero(&ybr, sizeof ybr);
-	ybr.ypbind_status = YPBIND_SUCC_VAL;
-	*(u_int32_t *)&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr = raddrp->sin_addr.s_addr;
-	*(u_short *)&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port = raddrp->sin_port;
-
-	if (writev(ypdb->dom_lockfd, iov, 2) != iov[0].iov_len + iov[1].iov_len) {
-		syslog(LOG_WARNING, "write: %m");
-		close(ypdb->dom_lockfd);
-		ypdb->dom_lockfd = -1;
-		return;
-	}
 }
 
 /*
@@ -982,14 +1113,20 @@
  * 1 if not matched.
  */
 int
-verify(struct in_addr addr)
+verify(struct sockaddr_storage *addr)
 {
+	int restrict_family, addr_family;
+	char *restrict_ptr, *addr_ptr;
+	size_t restrict_len, addr_len;
 	int i;
 
-	for (i = 0; i < RESTRICTED_SERVERS; i++)
-		if (!bcmp(&addr, &restricted_addrs[i], sizeof(struct in_addr)))
-			return(0);
-
+	for (i = 0; i < RESTRICTED_SERVERS; i++) {
+		if (ss_extract(&restricted_addrs[i], &restrict_family, &restrict_ptr, &restrict_len)
+		    || ss_extract(addr, &addr_family, &addr_ptr, &addr_len))
+			return (1);
+		if (restrict_family == addr_family && !bcmp(addr_ptr, restrict_ptr, addr_len))
+			return (0);
+	}
 	return(1);
 }
 
@@ -1000,7 +1137,7 @@
 void
 yp_restricted_mode(char *args)
 {
-	struct hostent *h;
+	struct addrinfo hint, *res;
 	int i = 0;
 	char *s;
 
@@ -1009,12 +1146,19 @@
 		return;
 	domain_name = s;
 
+	bzero(&hint, sizeof(hint));
 	/* Get the addresses of the servers. */
 	while ((s = strsep(&args, ",")) != NULL && i < RESTRICTED_SERVERS) {
-		if ((h = gethostbyname(s)) == NULL)
+		hint.ai_flags = AI_ADDRCONFIG;
+#ifdef INET6
+		hint.ai_family = PF_UNSPEC;
+#else
+		hint.ai_family = PF_INET;
+#endif
+		if (getaddrinfo(s, 0, &hint, &res))
 			return;
-		bcopy (h->h_addr_list[0], &restricted_addrs[i],
-		    sizeof(struct in_addr));
+		bcopy ((char *) res->ai_addr, (char *) &restricted_addrs[i], res->ai_addrlen);
+		freeaddrinfo(res);
 		i++;
 	}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120731162005.D84F2106566B>