]> git.cameronkatri.com Git - pw-darwin.git/commitdiff
Make pw_scan(3) more compatible with getpwent(3) et. al. when processing
authorIan Lepore <ian@FreeBSD.org>
Thu, 26 Jul 2018 18:34:38 +0000 (18:34 +0000)
committerIan Lepore <ian@FreeBSD.org>
Thu, 26 Jul 2018 18:34:38 +0000 (18:34 +0000)
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.

libc/gen/pw_scan.c
libc/gen/pw_scan.h
libutil/libutil.h
libutil/pw_util.c

index a7dbdf2cb5b98fd6a866de50c4dca51e1aa55c5e..619092d3d4bcd728e1a0cadbb3c355e873f89a61 100644 (file)
@@ -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)
 {
index 44ff8185bc9e8717839991128d80d54e42797e24..b56703677ac0c9ab353798def70bee1293e8f683 100644 (file)
@@ -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);
index c79eaac5a5fafef54a82d395d691705a9aa30f98..2ac5e975a2d713e46903f2a6471d460d691a2002 100644 (file)
@@ -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);
index 112b6d8af45a026ccc2b005f1b80c48108d35d10..1659c97a7fcd4e4274a546a66e34be7be4d69ff5 100644 (file)
@@ -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);