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);