simplify nscd lookup code for alt passwd/group backends
authorRich Felker <dalias@aerifal.cx>
Mon, 16 Mar 2015 03:33:59 +0000 (23:33 -0400)
committerRich Felker <dalias@aerifal.cx>
Mon, 16 Mar 2015 03:33:59 +0000 (23:33 -0400)
previously, a sentinel value of (FILE *)-1 was used to inform the
caller of __nscd_query that nscd is not in use. aside from being an
ugly hack, this resulted in duplicate code paths for two logically
equivalent cases: no nscd, and "not found" result from nscd.

now, __nscd_query simply skips closing the socket and returns a valid
FILE pointer when nscd is not in use, and produces a fake "not found"
response header. the caller is then responsible for closing the socket
just like it would do if it had gotten a real "not found" response.

src/passwd/getgr_a.c
src/passwd/getgrouplist.c
src/passwd/getpw_a.c
src/passwd/nscd_query.c

index 7738c3c357e1d2e6c623bdacae0301c5a3560322..afeb1eceb5f86acfe1a4b9d8da39f9bb7c8566cb 100644 (file)
@@ -63,7 +63,6 @@ int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t
 
                f = __nscd_query(req, key, groupbuf, sizeof groupbuf, &swap);
                if (!f) { rv = errno; goto done; }
-               if (f == (FILE*)-1) { rv = 0; goto done; }
 
                if (!groupbuf[GRFOUND]) { rv = 0; goto cleanup_f; }
 
index 0fddc9a148bd3e910dcf5e52033ba064dee60423..43e518245f8e6bfdafdbdb2ff5aec92a247798e4 100644 (file)
@@ -28,7 +28,7 @@ int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
 
        f = __nscd_query(GETINITGR, user, resp, sizeof resp, &swap);
        if (!f) goto cleanup;
-       if (f != (FILE*)-1 && resp[INITGRFOUND]) {
+       if (resp[INITGRFOUND]) {
                nscdbuf = calloc(resp[INITGRNGRPS], sizeof(uint32_t));
                if (!nscdbuf) goto cleanup;
                if (!fread(nscdbuf, sizeof(*nscdbuf)*resp[INITGRNGRPS], 1, f)) {
@@ -40,7 +40,7 @@ int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
                                nscdbuf[i] = bswap_32(nscdbuf[i]);
                }
        }
-       if (f != (FILE*)-1) fclose(f);
+       fclose(f);
 
        f = fopen("/etc/group", "rbe");
        if (!f && errno != ENOENT && errno != ENOTDIR)
index b04663dd1ed93f5ba92c048477413f51e3fda5be..15a70c0330c13cb4b67457b1aa0b15609721db3b 100644 (file)
@@ -64,7 +64,6 @@ int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t
 
                f = __nscd_query(req, key, passwdbuf, sizeof passwdbuf, (int[]){0});
                if (!f) { rv = errno; goto done; }
-               if (f == (FILE*)-1) { rv = 0; goto done; }
 
                if(!passwdbuf[PWFOUND]) { rv = 0; goto cleanup_f; }
 
index f8d0fc13d0fd48c59acc5890f2139b09389f2b4d..55ccc0a81954db0b58a7a26a203f5d98cafb9b4f 100644 (file)
@@ -32,32 +32,34 @@ FILE *__nscd_query(int32_t req, const char *key, int32_t *buf, size_t len, int *
                .msg_iovlen = 2
        };
 
-       if (strlen(key) > INT32_MAX - 1) {
-               return (FILE*)-1;
-       }
-
        *swap = 0;
 retry:
+       memset(buf, 0, len);
+       buf[0] = NSCDVERSION;
 
        fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
        if (fd < 0) return NULL;
 
+       if(!(f = fdopen(fd, "r"))) {
+               close(fd);
+               return 0;
+       }
+
+       if (strlen(key) > INT32_MAX - 1)
+               return f;
+
        if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
                /* If there isn't a running nscd we return -1 to indicate that
                 * that is precisely what happened
                 */
-               if (errno == EACCES || errno == ECONNREFUSED || errno == ENOENT) {
-                       close(fd);
-                       return (FILE *)-1;
-               }
+               if (errno == EACCES || errno == ECONNREFUSED || errno == ENOENT)
+                       return f;
                goto error;
        }
 
        if (sendmsg(fd, &msg, MSG_NOSIGNAL) < 0)
                goto error;
 
-       if(!(f = fdopen(fd, "r"))) goto error;
-
        if (!fread(buf, len, 1, f)) {
                /* If the VERSION entry mismatches nscd will disconnect. The
                 * most likely cause is that the endianness mismatched. So, we
@@ -95,6 +97,6 @@ retry:
 
        return f;
 error:
-       if (f) fclose(f); else close(fd);
+       fclose(f);
        return 0;
 }