Module Name:    src
Committed By:   bouyer
Date:           Wed Feb 16 21:04:04 UTC 2011

Modified Files:
        src/usr.sbin/ypbind [netbsd-5]: ypbind.c

Log Message:
Pull up following revision(s) (requested by chuck in ticket #1549):
        usr.sbin/ypbind/ypbind.c: revision 1.58 - 1.61
in the case where ypbind is serving more than one domain (i.e.
not just the yp_get_default_domain() domain), we must remove
any old binding files from /var/yp/binding (BINDINGDIR) from
previous runs, or the non-yp_get_default_domain()'s will not
bind properly.   add a purge_bindingdir() function that basically
does "rm BINDINGDIR/*.[0-9]" at ypbind startup time.
example case of where this is an issue: bind a second (non-default)
domain.   ypbind will create and flock a /var/yp/binding/xxx.2
file for it.  stop and restart ypbind.  the old /var/yp/binding/xxx.2
file will remain from the previous run.   since it is not flock()'d
by the new instance of ypbind, libc functions like yp_master() will
fail without even bothering to talk to ypbind itself.   (and ypbind
is totally unaware of the old file...)


To generate a diff of this commit:
cvs rdiff -u -r1.57 -r1.57.18.1 src/usr.sbin/ypbind/ypbind.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/ypbind/ypbind.c
diff -u src/usr.sbin/ypbind/ypbind.c:1.57 src/usr.sbin/ypbind/ypbind.c:1.57.18.1
--- src/usr.sbin/ypbind/ypbind.c:1.57	Sat Jul  7 22:33:57 2007
+++ src/usr.sbin/ypbind/ypbind.c	Wed Feb 16 21:04:03 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ypbind.c,v 1.57 2007/07/07 22:33:57 christos Exp $	*/
+/*	$NetBSD: ypbind.c,v 1.57.18.1 2011/02/16 21:04:03 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993 Theo de Raadt <[email protected]>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifndef LINT
-__RCSID("$NetBSD: ypbind.c,v 1.57 2007/07/07 22:33:57 christos Exp $");
+__RCSID("$NetBSD: ypbind.c,v 1.57.18.1 2011/02/16 21:04:03 bouyer Exp $");
 #endif
 
 #include <sys/param.h>
@@ -129,6 +129,7 @@
 static struct _dom_binding *makebinding(const char *);
 static int makelock(struct _dom_binding *);
 static void removelock(struct _dom_binding *);
+static int purge_bindingdir(const char *);
 static void *ypbindproc_null_2(SVCXPRT *, void *);
 static void *ypbindproc_domain_2(SVCXPRT *, void *);
 static void *ypbindproc_setdom_2(SVCXPRT *, void *);
@@ -221,6 +222,50 @@
 	(void)unlink(path);
 }
 
+/*
+ * purge_bindingdir: remove old binding files (i.e. "rm BINDINGDIR\/\*.[0-9]")
+ *
+ * local YP functions [e.g. yp_master()] will fail without even talking
+ * to ypbind if there is a stale (non-flock'd) binding file present.
+ * we have to scan the entire BINDINGDIR for binding files, because
+ * ypbind may bind more than just the yp_get_default_domain() domain.
+ */
+static int
+purge_bindingdir(const char *dirpath)
+{
+	DIR *dirp;
+	int unlinkedfiles, l;
+	struct dirent *dp;
+	char pathname[MAXPATHLEN];
+
+	if ((dirp = opendir(dirpath)) == NULL)
+		return(-1);   /* at this point, shouldn't ever happen */
+
+	do {
+		unlinkedfiles = 0;
+		while ((dp = readdir(dirp)) != NULL) {
+			l = dp->d_namlen;
+			/* 'rm *.[0-9]' */
+			if (l > 2 && dp->d_name[l-2] == '.' &&
+			    dp->d_name[l-1] >= '0' && dp->d_name[l-1] <= '9') {
+				(void)snprintf(pathname, sizeof(pathname), 
+					"%s/%s", dirpath, dp->d_name);
+				if (unlink(pathname) < 0 && errno != ENOENT)
+					return(-1);
+				unlinkedfiles++;
+			}
+		}
+
+		/* rescan dir if we removed it */
+		if (unlinkedfiles)
+			rewinddir(dirp);
+
+	} while (unlinkedfiles);
+
+	closedir(dirp);
+	return(0);
+}
+
 static void *
 /*ARGSUSED*/
 ypbindproc_null_2(SVCXPRT *transp, void *argp)
@@ -507,8 +552,6 @@
 	/* initialise syslog */
 	openlog("ypbind", LOG_PERROR | LOG_PID, LOG_DAEMON);
 
-	/* blow away everything in BINDINGDIR */
-
 	lockfd = open(_PATH_YPBIND_LOCK, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644);
 	if (lockfd == -1)
 		err(1, "Cannot create %s", _PATH_YPBIND_LOCK);
@@ -559,6 +602,10 @@
 	if (_yp_invalid_domain(domainname))
 		errx(1, "bad domainname: %s", domainname);
 
+	/* blow away old bindings in BINDINGDIR */
+	if (purge_bindingdir(BINDINGDIR) < 0)
+		errx(1, "unable to purge old bindings from %s", BINDINGDIR);
+
 	/* build initial domain binding, make it "unsuccessful" */
 	ypbindlist = makebinding(domainname);
 	ypbindlist->dom_vers = YPVERS;
@@ -966,7 +1013,7 @@
 	iov[1].iov_len = sizeof(ybr);
 	bytes = readv(fd, iov, 2);
 	(void)close(fd);
-	if (bytes != (iov[0].iov_len + iov[1].iov_len)) {
+	if ((size_t)bytes != (iov[0].iov_len + iov[1].iov_len)) {
 		/* Binding file corrupt? */
 		yp_log(LOG_WARNING, "%s: %m", path);
 		been_ypset = 0;
@@ -1022,7 +1069,7 @@
 #endif
 		return RPC_CANTRECV;
 	}
-	if (inlen < sizeof(u_int32_t))
+	if ((size_t)inlen < sizeof(u_int32_t))
 		goto recv_again;
 
 	/*
@@ -1083,7 +1130,7 @@
 #endif
 		return RPC_CANTRECV;
 	}
-	if (inlen < sizeof(u_int32_t))
+	if ((size_t)inlen < sizeof(u_int32_t))
 		goto recv_again;
 
 	/*
@@ -1188,7 +1235,7 @@
 	ybr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_port =
 	    raddrp->sin_port;
 
-	if (writev(ypdb->dom_lockfd, iov, 2) !=
+	if ((size_t)writev(ypdb->dom_lockfd, iov, 2) !=
 	    iov[0].iov_len + iov[1].iov_len) {
 		yp_log(LOG_WARNING, "writev: %m");
 		(void)close(ypdb->dom_lockfd);

Reply via email to