From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/6976 Path: news.gmane.org!not-for-mail From: Josiah Worcester Newsgroups: gmane.linux.lib.musl.general Subject: [PATCH 1/2] Refactor passwd file access code. Date: Tue, 10 Feb 2015 18:32:55 -0600 Message-ID: <1423614776-25579-1-git-send-email-josiahw@gmail.com> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1423614798 6798 80.91.229.3 (11 Feb 2015 00:33:18 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 11 Feb 2015 00:33:18 +0000 (UTC) Cc: Josiah Worcester To: musl@lists.openwall.com Original-X-From: musl-return-6989-gllmg-musl=m.gmane.org@lists.openwall.com Wed Feb 11 01:33:18 2015 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1YLLEz-0004KZ-Pn for gllmg-musl@m.gmane.org; Wed, 11 Feb 2015 01:33:17 +0100 Original-Received: (qmail 1821 invoked by uid 550); 11 Feb 2015 00:33:14 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 1810 invoked from network); 11 Feb 2015 00:33:14 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=nix1bMoSHKkcQ8SofXfd8Sv6Q7nZhBnhMkZgkTXlQOs=; b=Ez8rOHyG4tjFohO2SuzjVG8zFy61JsnIpDzmM+bhFegJoVYVN1Tff8p9L8Nz9YI58q 2M8+DnmNT9/6KDbpMNbWVWuy0g83yily10LhvN7cAOKb30CfmccVbjA95iG8EsxDdIXV 2G8QQ/IQd0mP0hlzR21FYXkweR9F7mmZS3uAxiq5GFxG9LgqQ/6LNy4rAee6NoSDzK2B HZ+pmsAyeVql8KXPxmmnPjo6VKxQLL4J/PZoiBwZ5LcqqchnFe7h4uWIp/g09uSVdOGs 9TYHoiOsjGyRlz/drqYGbY3yYm4Qlh0J4k+itXG22JbYeHUqfRavudMpwz3KqIBLQqf3 s5rQ== X-Received: by 10.107.164.221 with SMTP id d90mr2040965ioj.13.1423614780661; Tue, 10 Feb 2015 16:33:00 -0800 (PST) X-Mailer: git-send-email 2.1.4 Xref: news.gmane.org gmane.linux.lib.musl.general:6976 Archived-At: --- src/passwd/fgetpwent.c | 4 +++- src/passwd/getpw_a.c | 31 +++++++++++++++++++++++++++++++ src/passwd/getpw_r.c | 34 ++++++++++------------------------ src/passwd/getpwent.c | 32 ++++++++++++-------------------- src/passwd/getpwent_a.c | 8 ++++++-- src/passwd/pwf.h | 3 ++- 6 files changed, 64 insertions(+), 48 deletions(-) create mode 100644 src/passwd/getpw_a.c diff --git a/src/passwd/fgetpwent.c b/src/passwd/fgetpwent.c index eb47b2a..fd472a0 100644 --- a/src/passwd/fgetpwent.c +++ b/src/passwd/fgetpwent.c @@ -6,5 +6,7 @@ struct passwd *fgetpwent(FILE *f) static char *line; static struct passwd pw; size_t size=0; - return __getpwent_a(f, &pw, &line, &size); + struct passwd *res; + __getpwent_a(f, &pw, &line, &size, &res); + return res; } diff --git a/src/passwd/getpw_a.c b/src/passwd/getpw_a.c new file mode 100644 index 0000000..21efc5c --- /dev/null +++ b/src/passwd/getpw_a.c @@ -0,0 +1,31 @@ +#include "pwf.h" +#include + +int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res) +{ + FILE *f; + int cs; + int rv = 0; + + *res = 0; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); + + f = fopen("/etc/passwd", "rbe"); + if (!f) { + rv = errno; + goto done; + } + + while (!(rv = __getpwent_a(f, pw, buf, size, res)) && *res) { + if (name && !strcmp(name, (*res)->pw_name) + || !name && (*res)->pw_uid == uid) + break; + } + fclose(f); + +done: + pthread_setcancelstate(cs, 0); + if (rv) errno = rv; + return rv; +} diff --git a/src/passwd/getpw_r.c b/src/passwd/getpw_r.c index 2855257..1db10db 100644 --- a/src/passwd/getpw_r.c +++ b/src/passwd/getpw_r.c @@ -13,32 +13,18 @@ static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, si pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); - f = fopen("/etc/passwd", "rbe"); - if (!f) { - rv = errno; - goto done; - } - - *res = 0; - while (__getpwent_a(f, pw, &line, &len)) { - if (name && !strcmp(name, pw->pw_name) - || !name && pw->pw_uid == uid) { - if (size < len) { - rv = ERANGE; - break; - } - *res = pw; - memcpy(buf, line, len); - FIX(name); - FIX(passwd); - FIX(gecos); - FIX(dir); - FIX(shell); - break; - } + rv = __getpw_a(name, uid, pw, &line, &len, res); + if (!rv && size < len) + rv = ERANGE; + if (!rv) { + memcpy(buf, line, len); + FIX(name); + FIX(passwd); + FIX(gecos); + FIX(dir); + FIX(shell); } free(line); - fclose(f); done: pthread_setcancelstate(cs, 0); return rv; diff --git a/src/passwd/getpwent.c b/src/passwd/getpwent.c index c655135..f2bd516 100644 --- a/src/passwd/getpwent.c +++ b/src/passwd/getpwent.c @@ -1,6 +1,9 @@ #include "pwf.h" static FILE *f; +static char *line; +static struct passwd pw; +static size_t size; void setpwent() { @@ -12,34 +15,23 @@ weak_alias(setpwent, endpwent); struct passwd *getpwent() { - static char *line; - static struct passwd pw; - size_t size=0; + struct passwd *res; if (!f) f = fopen("/etc/passwd", "rbe"); if (!f) return 0; - return __getpwent_a(f, &pw, &line, &size); + __getpwent_a(f, &pw, &line, &size, &res); + return res; } struct passwd *getpwuid(uid_t uid) { - struct passwd *pw; - int errno_saved; - setpwent(); - while ((pw=getpwent()) && pw->pw_uid != uid); - errno_saved = errno; - endpwent(); - errno = errno_saved; - return pw; + struct passwd *res; + __getpw_a(0, uid, &pw, &line, &size, &res); + return res; } struct passwd *getpwnam(const char *name) { - struct passwd *pw; - int errno_saved; - setpwent(); - while ((pw=getpwent()) && strcmp(pw->pw_name, name)); - errno_saved = errno; - endpwent(); - errno = errno_saved; - return pw; + struct passwd *res; + __getpw_a(name, 0, &pw, &line, &size, &res); + return res; } diff --git a/src/passwd/getpwent_a.c b/src/passwd/getpwent_a.c index 34842a0..4d84f0d 100644 --- a/src/passwd/getpwent_a.c +++ b/src/passwd/getpwent_a.c @@ -8,14 +8,16 @@ static unsigned atou(char **s) return x; } -struct passwd *__getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size) +int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res) { ssize_t l; char *s; + int rv = 0; int cs; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); for (;;) { if ((l=getline(line, size, f)) < 0) { + rv = errno; free(*line); *line = 0; pw = 0; @@ -46,5 +48,7 @@ struct passwd *__getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *siz break; } pthread_setcancelstate(cs, 0); - return pw; + *res = pw; + if (rv) errno = rv; + return rv; } diff --git a/src/passwd/pwf.h b/src/passwd/pwf.h index 2d813ad..806ffd3 100644 --- a/src/passwd/pwf.h +++ b/src/passwd/pwf.h @@ -8,6 +8,7 @@ #include #include "libc.h" -struct passwd *__getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size); +int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res); +int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res); struct group *__getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem); int __parsespent(char *s, struct spwd *sp); -- 2.1.4