Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/ypbind in the case where ypbind is serving more tha...



details:   https://anonhg.NetBSD.org/src/rev/21224b8d3396
branches:  trunk
changeset: 748810:21224b8d3396
user:      chuck <chuck%NetBSD.org@localhost>
date:      Thu Nov 05 19:34:06 2009 +0000

description:
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...)

diffstat:

 usr.sbin/ypbind/ypbind.c |  54 ++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 50 insertions(+), 4 deletions(-)

diffs (96 lines):

diff -r 16da23622554 -r 21224b8d3396 usr.sbin/ypbind/ypbind.c
--- a/usr.sbin/ypbind/ypbind.c  Thu Nov 05 19:22:57 2009 +0000
+++ b/usr.sbin/ypbind/ypbind.c  Thu Nov 05 19:34:06 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ypbind.c,v 1.58 2009/01/18 10:39:17 lukem Exp $        */
+/*     $NetBSD: ypbind.c,v 1.59 2009/11/05 19:34:06 chuck Exp $        */
 
 /*
  * Copyright (c) 1992, 1993 Theo de Raadt <deraadt%fsa.ca@localhost>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifndef LINT
-__RCSID("$NetBSD: ypbind.c,v 1.58 2009/01/18 10:39:17 lukem Exp $");
+__RCSID("$NetBSD: ypbind.c,v 1.59 2009/11/05 19:34:06 chuck 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(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,49 @@
        (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(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 +551,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 +601,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;



Home | Main Index | Thread Index | Old Index