]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/idmapd/idmapd.c
Merge branch 'master' of git://linux-nfs.org/nfs-utils
[nfs-utils.git] / utils / idmapd / idmapd.c
index ca52c2c497a8a03ffa3f9f3ffc17a5bbf2d13944..21a1916ded036da2446df0c839012ca042a888d6 100644 (file)
 #define NFSD_DIR  "/proc/net/rpc"
 #endif
 
+#ifndef CLIENT_CACHE_TIMEOUT_FILE
+#define CLIENT_CACHE_TIMEOUT_FILE "/proc/sys/fs/nfs/idmap_cache_timeout"
+#endif
+
 #ifndef NFS4NOBODY_USER
 #define NFS4NOBODY_USER "nobody"
 #endif
@@ -144,6 +148,8 @@ void    mydaemon(int, int);
 void    release_parent();
 
 static int verbose = 0;
+#define DEFAULT_IDMAP_CACHE_EXPIRY 600 /* seconds */
+static int cache_entry_expiration = 0;
 static char pipefsdir[PATH_MAX];
 static char *nobodyuser, *nobodygroup;
 static uid_t nobodyuid;
@@ -291,6 +297,8 @@ main(int argc, char **argv)
        } else {
                conf_init();
                verbose = conf_get_num("General", "Verbosity", 0);
+               cache_entry_expiration = conf_get_num("General",
+                               "Cache-Expiration", DEFAULT_IDMAP_CACHE_EXPIRY);
                CONF_SAVE(xpipefsdir, conf_get_str("General", "Pipefs-Directory"));
                if (xpipefsdir != NULL)
                        strlcpy(pipefsdir, xpipefsdir, sizeof(pipefsdir));
@@ -337,7 +345,9 @@ main(int argc, char **argv)
                errx(1, "Could not find group \"%s\"", nobodygroup);
        nobodygid = gr->gr_gid;
 
+#ifdef HAVE_NFS4_SET_DEBUG
        nfs4_set_debug(verbose, idmapd_warnx);
+#endif
        if (conf_path == NULL)
                conf_path = _PATH_IDMAPDCONF;
        if (nfs4_init_name_mapping(conf_path))
@@ -348,6 +358,9 @@ main(int argc, char **argv)
 
        event_init();
 
+       if (verbose > 0)
+               idmapd_warnx("Expiration time is %d seconds.",
+                            cache_entry_expiration);
        if (serverstart) {
                nfsdret = nfsdopen();
                if (nfsdret == 0) {
@@ -364,6 +377,29 @@ main(int argc, char **argv)
                        .tv_usec = 0,
                };
 
+               if (cache_entry_expiration != DEFAULT_IDMAP_CACHE_EXPIRY) {
+                       int timeout_fd, len;
+                       char timeout_buf[12];
+                       if ((timeout_fd = open(CLIENT_CACHE_TIMEOUT_FILE,
+                                              O_RDWR)) == -1) {
+                               idmapd_warnx("Unable to open '%s' to set "
+                                            "client cache expiration time "
+                                            "to %d seconds\n",
+                                            CLIENT_CACHE_TIMEOUT_FILE,
+                                            cache_entry_expiration);
+                       } else {
+                               len = snprintf(timeout_buf, sizeof(timeout_buf),
+                                              "%d", cache_entry_expiration);
+                               if ((write(timeout_fd, timeout_buf, len)) != len)
+                                       idmapd_warnx("Error writing '%s' to "
+                                                    "'%s' to set client "
+                                                    "cache expiration time\n",
+                                                    timeout_buf,
+                                                    CLIENT_CACHE_TIMEOUT_FILE);
+                               close(timeout_fd);
+                       }
+               }
+
                if ((fd = open(pipefsdir, O_RDONLY)) == -1)
                        idmapd_err(1, "main: open(%s)", pipefsdir);
 
@@ -505,7 +541,8 @@ nfsdcb(int fd, short which, void *data)
        struct idmap_client *ic = data;
        struct idmap_msg im;
        u_char buf[IDMAP_MAXMSGSZ + 1];
-       size_t len, bsiz;
+       size_t len;
+       ssize_t bsiz;
        char *bp, typebuf[IDMAP_MAXMSGSZ],
                buf1[IDMAP_MAXMSGSZ], authbuf[IDMAP_MAXMSGSZ], *p;
        unsigned long tmp;
@@ -513,15 +550,16 @@ nfsdcb(int fd, short which, void *data)
        if (which != EV_READ)
                goto out;
 
-       if ((len = read(ic->ic_fd, buf, sizeof(buf))) == -1) {
+       if ((len = read(ic->ic_fd, buf, sizeof(buf))) <= 0) {
                idmapd_warnx("nfsdcb: read(%s) failed: errno %d (%s)",
-                            ic->ic_path, errno, strerror(errno));
+                            ic->ic_path, len?errno:0, 
+                            len?strerror(errno):"End of File");
                goto out;
        }
 
        /* Get rid of newline and terminate buffer*/
        buf[len - 1] = '\0';
-       bp = buf;
+       bp = (char *)buf;
 
        memset(&im, 0, sizeof(im));
 
@@ -571,7 +609,7 @@ nfsdcb(int fd, short which, void *data)
        imconv(ic, &im);
 
        buf[0] = '\0';
-       bp = buf;
+       bp = (char *)buf;
        bsiz = sizeof(buf);
 
        /* Authentication name */
@@ -584,9 +622,9 @@ nfsdcb(int fd, short which, void *data)
                addfield(&bp, &bsiz, p);
                /* Name */
                addfield(&bp, &bsiz, im.im_name);
-#define NFSD_EXPIRY 300 /* seconds */
                /* expiry */
-               snprintf(buf1, sizeof(buf1), "%lu", time(NULL) + NFSD_EXPIRY);
+               snprintf(buf1, sizeof(buf1), "%lu",
+                        time(NULL) + cache_entry_expiration);
                addfield(&bp, &bsiz, buf1);
                /* ID */
                snprintf(buf1, sizeof(buf1), "%u", im.im_id);
@@ -605,7 +643,8 @@ nfsdcb(int fd, short which, void *data)
                snprintf(buf1, sizeof(buf1), "%u", im.im_id);
                addfield(&bp, &bsiz, buf1);
                /* expiry */
-               snprintf(buf1, sizeof(buf1), "%lu", time(NULL) + NFSD_EXPIRY);
+               snprintf(buf1, sizeof(buf1), "%lu",
+                        time(NULL) + cache_entry_expiration);
                addfield(&bp, &bsiz, buf1);
                /* Name */
                addfield(&bp, &bsiz, im.im_name);
@@ -967,10 +1006,15 @@ mydaemon(int nochdir, int noclose)
 
        if (noclose == 0) {
                tempfd = open("/dev/null", O_RDWR);
-               dup2(tempfd, 0);
-               dup2(tempfd, 1);
-               dup2(tempfd, 2);
-               closeall(3);
+               if (tempfd < 0)
+                       tempfd = open("/", O_RDONLY);
+               if (tempfd >= 0) {
+                       dup2(tempfd, 0);
+                       dup2(tempfd, 1);
+                       dup2(tempfd, 2);
+                       closeall(3);
+               } else
+                       closeall(0);
        }
 
        return;