Author: ian
Date: Thu Jul 26 18:34:38 2018
New Revision: 336746
URL: https://svnweb.freebsd.org/changeset/base/336746

Log:
  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.

Modified:
  head/lib/libc/gen/Symbol.map
  head/lib/libc/gen/getpwent.c
  head/lib/libc/gen/pw_scan.c
  head/lib/libc/gen/pw_scan.h
  head/lib/libutil/libutil.h
  head/lib/libutil/pw_util.3
  head/lib/libutil/pw_util.c

Modified: head/lib/libc/gen/Symbol.map
==============================================================================
--- head/lib/libc/gen/Symbol.map        Thu Jul 26 17:52:57 2018        
(r336745)
+++ head/lib/libc/gen/Symbol.map        Thu Jul 26 18:34:38 2018        
(r336746)
@@ -510,6 +510,7 @@ FBSDprivate_1.0 {
        __opendir2;
        __pause;
        _pause;
+       __pw_initpwd;   /* Used by (at least) libutil */
        __pw_scan;      /* Used by (at least) libutil */
        __raise;
        _raise;

Modified: head/lib/libc/gen/getpwent.c
==============================================================================
--- head/lib/libc/gen/getpwent.c        Thu Jul 26 17:52:57 2018        
(r336745)
+++ head/lib/libc/gen/getpwent.c        Thu Jul 26 18:34:38 2018        
(r336746)
@@ -96,8 +96,6 @@ int   __pw_match_entry(const char *, size_t, enum nss_lo
            const char *, uid_t);
 int    __pw_parse_entry(char *, size_t, struct passwd *, int, int *errnop);
 
-static void     pwd_init(struct passwd *);
-
 union key {
        const char      *name;
        uid_t            uid;
@@ -527,7 +525,7 @@ getpwent_r(struct passwd *pwd, char *buffer, size_t bu
        };
        int     rv, ret_errno;
 
-       pwd_init(pwd);
+       __pw_initpwd(pwd);
        ret_errno = 0;
        *result = NULL;
        rv = _nsdispatch(result, dtab, NSDB_PASSWD, "getpwent_r", defaultsrc,
@@ -566,7 +564,7 @@ getpwnam_r(const char *name, struct passwd *pwd, char 
        };
        int     rv, ret_errno;
 
-       pwd_init(pwd);
+       __pw_initpwd(pwd);
        ret_errno = 0;
        *result = NULL;
        rv = _nsdispatch(result, dtab, NSDB_PASSWD, "getpwnam_r", defaultsrc,
@@ -605,7 +603,7 @@ getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer
        };
        int     rv, ret_errno;
 
-       pwd_init(pwd);
+       __pw_initpwd(pwd);
        ret_errno = 0;
        *result = NULL;
        rv = _nsdispatch(result, dtab, NSDB_PASSWD, "getpwuid_r", defaultsrc,
@@ -617,23 +615,6 @@ getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer
 }
 
 
-static void
-pwd_init(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;
-}
-
-
 static struct passwd    pwd;
 static char            *pwd_storage;
 static size_t           pwd_storage_size;
@@ -1614,7 +1595,7 @@ compat_redispatch(struct compat_state *st, enum nss_lo
        for (i = 0; i < (int)(nitems(dtab) - 1); i++)
                dtab[i].mdata = (void *)lookup_how;
 more:
-       pwd_init(pwd);
+       __pw_initpwd(pwd);
        switch (lookup_how) {
        case nss_lt_all:
                rv = _nsdispatch(&discard, dtab, NSDB_PASSWD_COMPAT,

Modified: head/lib/libc/gen/pw_scan.c
==============================================================================
--- head/lib/libc/gen/pw_scan.c Thu Jul 26 17:52:57 2018        (r336745)
+++ head/lib/libc/gen/pw_scan.c Thu Jul 26 18:34:38 2018        (r336746)
@@ -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)
 {

Modified: head/lib/libc/gen/pw_scan.h
==============================================================================
--- head/lib/libc/gen/pw_scan.h Thu Jul 26 17:52:57 2018        (r336745)
+++ head/lib/libc/gen/pw_scan.h Thu Jul 26 18:34:38 2018        (r336746)
@@ -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);

Modified: head/lib/libutil/libutil.h
==============================================================================
--- head/lib/libutil/libutil.h  Thu Jul 26 17:52:57 2018        (r336745)
+++ head/lib/libutil/libutil.h  Thu Jul 26 18:34:38 2018        (r336746)
@@ -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);

Modified: head/lib/libutil/pw_util.3
==============================================================================
--- head/lib/libutil/pw_util.3  Thu Jul 26 17:52:57 2018        (r336745)
+++ head/lib/libutil/pw_util.3  Thu Jul 26 18:34:38 2018        (r336746)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 02, 2015
+.Dd July 26, 2018
 .Dt PW_UTIL 3
 .Os
 .Sh NAME
@@ -59,6 +59,8 @@
 .Fn pw_fini "void"
 .Ft int
 .Fn pw_init "const char *dir" const char *master"
+.Ft void
+.Fn pw_initpwd "struct passwd *pw"
 .Ft "char *"
 .Fn pw_make "const struct passwd *pw"
 .Ft "char *"
@@ -179,7 +181,7 @@ if any.
 .Pp
 The
 .Fn pw_init
-initialize the static variable representing the path a password file.
+initializes the static variable representing the path to a password file.
 .Fa dir
 is the directory where the password file is located.
 If set to
@@ -192,6 +194,18 @@ If set to
 .Dv NULL?
 it will default to
 .Pa master.passwd
+.Pp
+The
+.Fn pw_initpwd
+function initializes the
+.Vt passwd
+struct to canonical values.
+The entire structure is zeroed, then
+.Va pw_uid
+and
+.Va pw_gid
+are set to -1, and all string pointers are set to point at
+an internally-defined zero-length string.
 .Pp
 The
 .Fn pw_make

Modified: head/lib/libutil/pw_util.c
==============================================================================
--- head/lib/libutil/pw_util.c  Thu Jul 26 17:52:57 2018        (r336745)
+++ head/lib/libutil/pw_util.c  Thu Jul 26 18:34:38 2018        (r336746)
@@ -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);
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to