svn commit: r336746 - in head/lib: libc/gen libutil

Ian Lepore ian at FreeBSD.org
Thu Jul 26 18:34:40 UTC 2018


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);


More information about the svn-src-head mailing list