set errno when getpw*_r, getgr*_r, and getspnam_r fail
authorRich Felker <dalias@aerifal.cx>
Thu, 15 Jun 2017 17:01:34 +0000 (13:01 -0400)
committerRich Felker <dalias@aerifal.cx>
Thu, 15 Jun 2017 17:01:34 +0000 (13:01 -0400)
these functions return an error code, and are not explicitly
documented to set errno, but they are nonstandard and the historical
implementations do set errno as well, and some applications expect
this behavior. do likewise for compatibility.

patch by Rudolph Pereira.

src/passwd/getgr_r.c
src/passwd/getpw_r.c
src/passwd/getspnam_r.c

index 7246e8a42d38793917def24e1dcd3f6c8caec85a..f3e8f603a32832505538c60e1d210c2e529df9c5 100644 (file)
@@ -34,6 +34,7 @@ static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, siz
        free(mem);
        free(line);
        pthread_setcancelstate(cs, 0);
+       if (rv) errno = rv;
        return rv;
 }
 
index e8cc811e4d898f91c26d05b16b4456fda9d6601b..0c87ab05d2700fdbe3ec727d824718f84ba8ba93 100644 (file)
@@ -27,6 +27,7 @@ static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, si
        }
        free(line);
        pthread_setcancelstate(cs, 0);
+       if (rv) errno = rv;
        return rv;
 }
 
index 92339528ad170f2ed76d3bc3ba03a14b8e98c30e..e488b67f5d850d33ae703dcfc0aa350611479c72 100644 (file)
@@ -72,14 +72,15 @@ int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct
 
        /* Disallow potentially-malicious user names */
        if (*name=='.' || strchr(name, '/') || !l)
-               return EINVAL;
+               return errno = EINVAL;
 
        /* Buffer size must at least be able to hold name, plus some.. */
-       if (size < l+100) return ERANGE;
+       if (size < l+100)
+               return errno = EINVAL;
 
        /* Protect against truncation */
        if (snprintf(path, sizeof path, "/etc/tcb/%s/shadow", name) >= sizeof path)
-               return EINVAL;
+               return errno = EINVAL;
 
        fd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK|O_CLOEXEC);
        if (fd >= 0) {
@@ -112,5 +113,6 @@ int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct
                break;
        }
        pthread_cleanup_pop(1);
+       if (rv) errno = rv;
        return rv;
 }