diff options
author | Ian Lepore <ian@FreeBSD.org> | 2018-07-26 18:34:38 +0000 |
---|---|---|
committer | Ian Lepore <ian@FreeBSD.org> | 2018-07-26 18:34:38 +0000 |
commit | cec26ff1cefd6235cfbefd07302a918e7217b0b1 (patch) | |
tree | 19369a3f8c77d6cc7690ba6ec168bea78d936c00 | |
parent | 699a28cfd315d63c32b4c309d0b6cbd9197a6ee4 (diff) | |
download | pw-darwin-cec26ff1cefd6235cfbefd07302a918e7217b0b1.tar.gz pw-darwin-cec26ff1cefd6235cfbefd07302a918e7217b0b1.tar.zst pw-darwin-cec26ff1cefd6235cfbefd07302a918e7217b0b1.zip |
Make pw_scan(3) more compatible with getpwent(3) et. al. when processing
data from /etc/passwd rather than /etc/master.passwd.
The libc getpwent(3) and related functions automatically read master.passwd
when run by root, or passwd when run by a non-root user. When run by non-
root, getpwent() copes with the missing data by setting the corresponding
fields in the passwd struct to known values (zeroes for numbers, or a
pointer to an empty string for literals). When libutil's pw_scan(3) was
used to parse a line without the root-accessible data, it was leaving
garbage in the corresponding fields.
These changes rename the static pw_init() function used by getpwent() and
friends to __pw_initpwd(), and move it into pw_scan.c so that common init
code can be shared between libc and libutil. pw_scan(3) now calls
__pw_initpwd() before __pw_scan(), just like the getpwent() family does, so
that reading an arbitrary passwd file in either format and parsing it with
pw_scan(3) returns the same results as getpwent(3) would.
This also adds a new pw_initpwd(3) function to libutil, so that code which
creates passwd structs from scratch in some manner that doesn't involve
pw_scan() can initialize the struct to the values expected by lots of
existing code, which doesn't expect to encounter NULL pointers or garbage
values in some fields.
-rw-r--r-- | libc/gen/pw_scan.c | 16 | ||||
-rw-r--r-- | libc/gen/pw_scan.h | 1 | ||||
-rw-r--r-- | libutil/libutil.h | 1 | ||||
-rw-r--r-- | libutil/pw_util.c | 11 |
4 files changed, 28 insertions, 1 deletions
diff --git a/libc/gen/pw_scan.c b/libc/gen/pw_scan.c index a7dbdf2..619092d 100644 --- a/libc/gen/pw_scan.c +++ b/libc/gen/pw_scan.c @@ -65,6 +65,22 @@ __FBSDID("$FreeBSD$"); */ static int pw_big_ids_warning = 0; +void +__pw_initpwd(struct passwd *pwd) +{ + static char nul[] = ""; + + memset(pwd, 0, sizeof(*pwd)); + pwd->pw_uid = (uid_t)-1; /* Considered least likely to lead to */ + pwd->pw_gid = (gid_t)-1; /* a security issue. */ + pwd->pw_name = nul; + pwd->pw_passwd = nul; + pwd->pw_class = nul; + pwd->pw_gecos = nul; + pwd->pw_dir = nul; + pwd->pw_shell = nul; +} + int __pw_scan(char *bp, struct passwd *pw, int flags) { diff --git a/libc/gen/pw_scan.h b/libc/gen/pw_scan.h index 44ff818..b567036 100644 --- a/libc/gen/pw_scan.h +++ b/libc/gen/pw_scan.h @@ -35,4 +35,5 @@ #define _PWSCAN_MASTER 0x01 #define _PWSCAN_WARN 0x02 +extern void __pw_initpwd(struct passwd *); extern int __pw_scan(char *, struct passwd *, int); diff --git a/libutil/libutil.h b/libutil/libutil.h index c79eaac..2ac5e97 100644 --- a/libutil/libutil.h +++ b/libutil/libutil.h @@ -155,6 +155,7 @@ int pw_edit(int _notsetuid); int pw_equal(const struct passwd *_pw1, const struct passwd *_pw2); void pw_fini(void); int pw_init(const char *_dir, const char *_master); +void pw_initpwd(struct passwd *_pw); char *pw_make(const struct passwd *_pw); char *pw_make_v7(const struct passwd *_pw); int pw_mkdb(const char *_user); diff --git a/libutil/pw_util.c b/libutil/pw_util.c index 112b6d8..1659c97 100644 --- a/libutil/pw_util.c +++ b/libutil/pw_util.c @@ -652,8 +652,16 @@ pw_dup(const struct passwd *pw) #include "pw_scan.h" /* - * Wrapper around an internal libc function + * Wrapper around some internal libc functions. */ + +void +pw_initpwd(struct passwd *pw) +{ + + __pw_initpwd(pw); +} + struct passwd * pw_scan(const char *line, int flags) { @@ -662,6 +670,7 @@ pw_scan(const char *line, int flags) if ((bp = strdup(line)) == NULL) return (NULL); + __pw_initpwd(&pw); if (!__pw_scan(bp, &pw, flags)) { free(bp); return (NULL); |