summaryrefslogtreecommitdiffstats
path: root/libc
diff options
context:
space:
mode:
authorIan Lepore <ian@FreeBSD.org>2018-07-26 18:34:38 +0000
committerIan Lepore <ian@FreeBSD.org>2018-07-26 18:34:38 +0000
commitcec26ff1cefd6235cfbefd07302a918e7217b0b1 (patch)
tree19369a3f8c77d6cc7690ba6ec168bea78d936c00 /libc
parent699a28cfd315d63c32b4c309d0b6cbd9197a6ee4 (diff)
downloadpw-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.
Diffstat (limited to 'libc')
-rw-r--r--libc/gen/pw_scan.c16
-rw-r--r--libc/gen/pw_scan.h1
2 files changed, 17 insertions, 0 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);