File shadow-4.8.1-add-prefix-passwd-chpasswd-chage.patch of Package shadow.30601

Patch is a backport of https://github.com/shadow-maint/shadow/pull/714
by Jaroslav Jindrak 
Index: shadow-4.8.1/configure.ac
===================================================================
--- shadow-4.8.1.orig/configure.ac
+++ shadow-4.8.1/configure.ac
@@ -682,6 +682,8 @@ if test "$enable_utmpx" = "yes"; then
 	          [Define if utmpx should be used])
 fi
 
+AC_CHECK_FUNC(fgetpwent_r, [AC_DEFINE(HAVE_FGETPWENT_R, 1, [Defined to 1 if you have the declaration of 'fgetpwent_r'])])
+
 AC_DEFINE_UNQUOTED(SHELL, ["$SHELL"], [The default shell.])
 
 AM_GNU_GETTEXT_VERSION(0.16)
Index: shadow-4.8.1/lib/prototypes.h
===================================================================
--- shadow-4.8.1.orig/lib/prototypes.h
+++ shadow-4.8.1/lib/prototypes.h
@@ -270,9 +270,7 @@ extern int do_pam_passwd_non_interactive
 #endif				/* USE_PAM */
 
 /* obscure.c */
-#ifndef USE_PAM
 extern bool obscure (const char *, const char *, const struct passwd *);
-#endif
 
 /* pam_pass.c */
 #ifdef USE_PAM
@@ -288,6 +286,10 @@ extern struct group *prefix_getgrnam(con
 extern struct group *prefix_getgrgid(gid_t gid);
 extern struct passwd *prefix_getpwuid(uid_t uid);
 extern struct passwd *prefix_getpwnam(const char* name);
+#if HAVE_FGETPWENT_R
+extern int prefix_getpwnam_r(const char* name, struct passwd* pwd,
+                             char* buf, size_t buflen, struct passwd** result);
+#endif
 extern struct spwd *prefix_getspnam(const char* name);
 extern struct group *prefix_getgr_nam_gid(const char *grname);
 extern void prefix_setpwent();
@@ -298,9 +300,7 @@ extern struct group* prefix_getgrent();
 extern void prefix_endgrent();
 
 /* pwd2spwd.c */
-#ifndef USE_PAM
 extern struct spwd *pwd_to_spwd (const struct passwd *);
-#endif
 
 /* pwdcheck.c */
 #ifndef USE_PAM
@@ -451,6 +451,8 @@ extern /*@maynotreturn@*/ /*@only@*//*@n
 
 /* xgetpwnam.c */
 extern /*@null@*/ /*@only@*/struct passwd *xgetpwnam (const char *);
+/* xprefix_getpwnam.c */
+extern /*@null@*/ /*@only@*/struct passwd *xprefix_getpwnam (const char *);
 /* xgetpwuid.c */
 extern /*@null@*/ /*@only@*/struct passwd *xgetpwuid (uid_t);
 /* xgetgrnam.c */
Index: shadow-4.8.1/libmisc/Makefile.am
===================================================================
--- shadow-4.8.1.orig/libmisc/Makefile.am
+++ shadow-4.8.1/libmisc/Makefile.am
@@ -5,6 +5,14 @@ AM_CPPFLAGS = -I$(top_srcdir)/lib $(ECON
 
 noinst_LIBRARIES = libmisc.a
 
+if USE_PAM
+LIBCRYPT_PAM = $(LIBCRYPT)
+else
+	LIBCRYPT_PAM =
+endif
+
+libmisc_la_CFLAGS = $(LIBCRYPT_PAM)
+
 libmisc_a_SOURCES = \
 	addgrps.c \
 	age.c \
@@ -66,6 +74,7 @@ libmisc_a_SOURCES = \
 	utmp.c \
 	valid.c \
 	xgetpwnam.c \
+	xprefix_getpwnam.c \
 	xgetpwuid.c \
 	xgetgrnam.c \
 	xgetgrgid.c \
Index: shadow-4.8.1/libmisc/obscure.c
===================================================================
--- shadow-4.8.1.orig/libmisc/obscure.c
+++ shadow-4.8.1/libmisc/obscure.c
@@ -32,8 +32,6 @@
 
 #include <config.h>
 
-#ifndef USE_PAM
-
 #ident "$Id$"
 
 
@@ -321,6 +319,3 @@ bool obscure (const char *old, const cha
 	return true;
 }
 
-#else				/* !USE_PAM */
-extern int errno;		/* warning: ANSI C forbids an empty source file */
-#endif				/* !USE_PAM */
Index: shadow-4.8.1/libmisc/prefix_flag.c
===================================================================
--- shadow-4.8.1.orig/libmisc/prefix_flag.c
+++ shadow-4.8.1/libmisc/prefix_flag.c
@@ -237,6 +237,29 @@ extern struct passwd *prefix_getpwnam(co
 		return getpwnam(name);
 	}
 }
+#if HAVE_FGETPWENT_R
+extern int prefix_getpwnam_r(const char* name, struct passwd* pwd,
+        char* buf, size_t buflen, struct passwd** result)
+{
+    if (passwd_db_file) {
+        FILE* fg;
+        int ret = 0;
+
+        fg = fopen(passwd_db_file, "rt");
+        if (!fg)
+            return errno;
+        while ((ret = fgetpwent_r(fg, pwd, buf, buflen, result)) == 0) {
+            if (!strcmp(name, pwd->pw_name))
+                break;
+        }
+        fclose(fg);
+        return ret;
+    }
+    else {
+        return getpwnam_r(name, pwd, buf, buflen, result);
+    }
+}
+#endif
 extern struct spwd *prefix_getspnam(const char* name)
 {
 	if (spw_db_file) {
Index: shadow-4.8.1/libmisc/pwd2spwd.c
===================================================================
--- shadow-4.8.1.orig/libmisc/pwd2spwd.c
+++ shadow-4.8.1/libmisc/pwd2spwd.c
@@ -34,8 +34,6 @@
 
 #ident "$Id$"
 
-#ifndef USE_PAM
-
 #include <sys/types.h>
 #include "prototypes.h"
 #include "defines.h"
@@ -84,7 +82,3 @@ struct spwd *pwd_to_spwd (const struct p
 
 	return &sp;
 }
-#else				/* USE_PAM */
-extern int errno;	/* warning: ANSI C forbids an empty source file */
-#endif				/* !USE_PAM */
-
Index: shadow-4.8.1/libmisc/xprefix_getpwnam.c
===================================================================
--- /dev/null
+++ shadow-4.8.1/libmisc/xprefix_getpwnam.c
@@ -0,0 +1,41 @@
+/*
+ * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * According to the Linux-PAM documentation:
+ *
+ *  4.1. Care about standard library calls
+ *
+ *  In general, writers of authorization-granting applications should
+ *  assume that each module is likely to call any or all 'libc' functions.
+ *  For 'libc' functions that return pointers to static/dynamically
+ *  allocated structures (ie.  the library allocates the memory and the
+ *  user is not expected to 'free()' it) any module call to this function
+ *  is likely to corrupt a pointer previously obtained by the application.
+ *  The application programmer should either re-call such a 'libc'
+ *  function after a call to the Linux-PAM library, or copy the structure
+ *  contents to some safe area of memory before passing control to the
+ *  Linux-PAM library.
+ *
+ *  Two important function classes that fall into this category are
+ *  getpwnam(3) and syslog(3).
+ *
+ * This file provides wrapper to the prefix_getpwnam or prefix_getpwnam_r functions.
+ */
+
+#include <config.h>
+
+#include "pwio.h"
+
+#define LOOKUP_TYPE	struct passwd
+#define FUNCTION_NAME	prefix_getpwnam
+#define ARG_TYPE	const char *
+#define ARG_NAME	name
+#define DUP_FUNCTION	__pw_dup
+#define HAVE_FUNCTION_R HAVE_FGETPWENT_R
+
+#include "xgetXXbyYY.c"
+
Index: shadow-4.8.1/src/Makefile.am
===================================================================
--- shadow-4.8.1.orig/src/Makefile.am
+++ shadow-4.8.1/src/Makefile.am
@@ -80,7 +80,8 @@ endif
 LDADD          = $(INTLLIBS) \
 		 $(top_builddir)/libmisc/libmisc.a \
 		 $(top_builddir)/lib/libshadow.la \
-		 $(LIBTCB)
+		 $(LIBTCB) \
+		 $(LIBCRYPT)
 
 if ACCT_TOOLS_SETUID
 LIBPAM_SUID  = $(LIBPAM)
@@ -94,13 +95,13 @@ else
 LIBCRYPT_NOPAM = $(LIBCRYPT)
 endif
 
-chage_LDADD    = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
+chage_LDADD    = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
 newuidmap_LDADD    = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP)
 newgidmap_LDADD    = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP)
 chfn_LDADD     = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
 chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
 chsh_LDADD     = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
-chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
+chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) -ldl
 expiry_LDADD = $(LDADD) $(LIBECONF)
 gpasswd_LDADD  = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
 groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
@@ -118,7 +119,7 @@ login_LDADD    = $(LDADD) $(LIBPAM) $(LI
 newgrp_LDADD   = $(LDADD) $(LIBAUDIT) $(LIBCRYPT) $(LIBECONF)
 newusers_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
 nologin_LDADD  =
-passwd_LDADD   = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF)
+passwd_LDADD   = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF) -ldl
 pwck_LDADD     = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
 pwconv_LDADD   = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
 pwunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
Index: shadow-4.8.1/src/chage.c
===================================================================
--- shadow-4.8.1.orig/src/chage.c
+++ shadow-4.8.1/src/chage.c
@@ -74,6 +74,8 @@ static bool
     Wflg = false;		/* set expiration warning days */
 static bool amroot = false;
 
+static const char *prefix = "";
+
 static bool pw_locked  = false;	/* Indicate if the password file is locked */
 static bool spw_locked = false;	/* Indicate if the shadow file is locked */
 /* The name and UID of the user being worked on */
@@ -155,6 +157,7 @@ static /*@noreturn@*/void usage (int sta
 	(void) fputs (_("  -M, --maxdays MAX_DAYS        set maximum number of days before password\n"
 	                "                                change to MAX_DAYS\n"), usageout);
 	(void) fputs (_("  -R, --root CHROOT_DIR         directory to chroot into\n"), usageout);
+    (void) fputs (_(" -P, --prefix PREFIX_DIR directory prefix\n"), usageout);
 	(void) fputs (_("  -W, --warndays WARN_DAYS      set expiration warning days to WARN_DAYS\n"), usageout);
 	(void) fputs ("\n", usageout);
 	exit (status);
@@ -400,12 +403,13 @@ static void process_flags (int argc, cha
 		{"mindays",    required_argument, NULL, 'm'},
 		{"maxdays",    required_argument, NULL, 'M'},
 		{"root",       required_argument, NULL, 'R'},
+        {"prefix",     required_argument, NULL, 'P'},
 		{"warndays",   required_argument, NULL, 'W'},
 		{"iso8601",    no_argument,       NULL, 'i'},
 		{NULL, 0, NULL, '\0'}
 	};
 
-	while ((c = getopt_long (argc, argv, "d:E:hiI:lm:M:R:W:",
+	while ((c = getopt_long (argc, argv, "d:E:hiI:lm:M:R:P:W:",
 	                         long_options, NULL)) != -1) {
 		switch (c) {
 		case 'd':
@@ -469,6 +473,8 @@ static void process_flags (int argc, cha
 			break;
 		case 'R': /* no-op, handled in process_root_flag () */
 			break;
+        case 'P': /* no-op, handled in process_prefix_flag () */
+            break;
 		case 'W':
 			Wflg = true;
 			if (   (getlong (optarg, &warndays) == 0)
@@ -818,6 +824,7 @@ int main (int argc, char **argv)
 	(void) textdomain (PACKAGE);
 
 	process_root_flag ("-R", argc, argv);
+    prefix = process_prefix_flag ("-P", argc, argv);
 
 #ifdef WITH_AUDIT
 	audit_help_open ();
Index: shadow-4.8.1/src/chpasswd.c
===================================================================
--- shadow-4.8.1.orig/src/chpasswd.c
+++ shadow-4.8.1/src/chpasswd.c
@@ -71,6 +71,8 @@ static long sha_rounds = 5000;
 static long bcrypt_rounds = 13;
 #endif
 
+static const char *prefix = "";
+
 static bool is_shadow_pwd;
 static bool pw_locked = false;
 static bool spw_locked = false;
@@ -137,6 +139,7 @@ static /*@noreturn@*/void usage (int sta
 	                "                                the MD5 algorithm\n"),
 	              usageout);
 	(void) fputs (_("  -R, --root CHROOT_DIR         directory to chroot into\n"), usageout);
+    (void) fputs (_(" -P, --prefix PREFIX_DIR directory prefix\n"), usageout);
 #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
 	(void) fputs (_("  -s, --sha-rounds              number of rounds for the SHA or BCRYPT\n"
 	                "                                crypt algorithms\n"),
@@ -161,6 +164,7 @@ static void process_flags (int argc, cha
 		{"help",         no_argument,       NULL, 'h'},
 		{"md5",          no_argument,       NULL, 'm'},
 		{"root",         required_argument, NULL, 'R'},
+        {"prefix",       required_argument, NULL, 'P'},
 #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
 		{"sha-rounds",   required_argument, NULL, 's'},
 #endif				/* USE_SHA_CRYPT || USE_BCRYPT */
@@ -169,9 +173,9 @@ static void process_flags (int argc, cha
 
 	while ((c = getopt_long (argc, argv,
 #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
-	                         "c:ehmR:s:",
+	                         "c:ehmR:P:s:",
 #else
-	                         "c:ehmR:",
+	                         "c:ehmR:P:",
 #endif
 	                         long_options, NULL)) != -1) {
 		switch (c) {
@@ -189,6 +193,8 @@ static void process_flags (int argc, cha
 			break;
 		case 'R': /* no-op, handled in process_root_flag () */
 			break;
+        case 'P': /* no-op, handled in process_prefix_flag () */
+            break;
 #if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
 		case 's':
 			sflg = true;
@@ -429,11 +435,12 @@ int main (int argc, char **argv)
 	(void) textdomain (PACKAGE);
 
 	process_root_flag ("-R", argc, argv);
+    prefix = process_prefix_flag ("-P", argc, argv);
 
 	process_flags (argc, argv);
 
 #ifdef USE_PAM
-	if (md5flg || eflg || cflg) {
+	if (md5flg || eflg || cflg || prefix[0]) {
 		use_pam = false;
 	}
 #endif				/* USE_PAM */
Index: shadow-4.8.1/src/passwd.c
===================================================================
--- shadow-4.8.1.orig/src/passwd.c
+++ shadow-4.8.1/src/passwd.c
@@ -71,6 +71,8 @@ static char *name;		/* The name of user
 static char *myname;		/* The current user's name */
 static bool amroot;		/* The caller's real UID was 0 */
 
+static const char *prefix = "";
+
 static bool
     aflg = false,			/* -a - show status for all users */
     dflg = false,			/* -d - delete password */
@@ -96,14 +98,16 @@ static long age_max = 0;	/* Maximum days
 static long warn = 0;		/* Warning days before change   */
 static long inact = 0;		/* Days without change before locked */
 
-#ifndef USE_PAM
 static bool do_update_age = false;
-#endif				/* ! USE_PAM */
+#ifdef USE_PAM
+static bool use_pam = true;
+#else
+static bool use_pam = false;
+#endif            /* USE_PAM */
 
 static bool pw_locked = false;
 static bool spw_locked = false;
 
-#ifndef USE_PAM
 /*
  * Size of the biggest passwd:
  *   $6$	3
@@ -119,7 +123,6 @@ static bool spw_locked = false;
  */
 static char crypt_passwd[256];
 static bool do_update_pwd = false;
-#endif				/* !USE_PAM */
 
 /*
  * External identifiers
@@ -128,12 +131,10 @@ static bool do_update_pwd = false;
 /* local function prototypes */
 static /*@noreturn@*/void usage (int);
 
-#ifndef USE_PAM
 static bool reuse (const char *, const struct passwd *);
 static int new_password (const struct passwd *);
 
 static void check_password (const struct passwd *, const struct spwd *);
-#endif				/* !USE_PAM */
 static /*@observer@*/const char *date_to_str (time_t);
 static /*@observer@*/const char *pw_status (const char *);
 static void print_status (const struct passwd *);
@@ -168,6 +169,7 @@ static /*@noreturn@*/void usage (int sta
 	(void) fputs (_("  -q, --quiet                   quiet mode\n"), usageout);
 	(void) fputs (_("  -r, --repository REPOSITORY   change password in REPOSITORY repository\n"), usageout);
 	(void) fputs (_("  -R, --root CHROOT_DIR         directory to chroot into\n"), usageout);
+    (void) fputs (_("  -P, --prefix PREFIX_DIR directory prefix\n"), usageout);
 	(void) fputs (_("  -S, --status                  report password status on the named account\n"), usageout);
 	(void) fputs (_("  -u, --unlock                  unlock the password of the named account\n"), usageout);
 	(void) fputs (_("  -w, --warndays WARN_DAYS      set expiration warning days to WARN_DAYS\n"), usageout);
@@ -177,7 +179,6 @@ static /*@noreturn@*/void usage (int sta
 	exit (status);
 }
 
-#ifndef USE_PAM
 static bool reuse (const char *pass, const struct passwd *pw)
 {
 #ifdef HAVE_LIBCRACK_HIST
@@ -441,7 +442,6 @@ static void check_password (const struct
 		}
 	}
 }
-#endif				/* !USE_PAM */
 
 static /*@observer@*/const char *date_to_str (time_t t)
 {
@@ -476,7 +476,7 @@ static void print_status (const struct p
 {
 	struct spwd *sp;
 
-	sp = getspnam (pw->pw_name); /* local, no need for xgetspnam */
+    sp = prefix_getspnam (pw->pw_name); /* local, no need for xprefix_getspnam */
 	if (NULL != sp) {
 		(void) printf ("%s %s %s %lld %lld %lld %lld\n",
 		               pw->pw_name,
@@ -522,11 +522,12 @@ static /*@noreturn@*/void oom (void)
 
 static char *update_crypt_pw (char *cp)
 {
-#ifndef USE_PAM
-	if (do_update_pwd) {
-		cp = xstrdup (crypt_passwd);
+    if (!use_pam)
+    {
+        if (do_update_pwd) {
+            cp = xstrdup (crypt_passwd);
+        }
 	}
-#endif				/* !USE_PAM */
 
 	if (dflg) {
 		*cp = '\0';
@@ -659,17 +660,18 @@ static void update_shadow (void)
 	}
 	if (iflg) {
 		nsp->sp_inact = (inact * DAY) / SCALE;
-	}
-#ifndef USE_PAM
-	if (do_update_age) {
-		nsp->sp_lstchg = (long) gettime () / SCALE;
-		if (0 == nsp->sp_lstchg) {
-			/* Better disable aging than requiring a password
-			 * change */
-			nsp->sp_lstchg = -1;
+    }
+
+	if (!use_pam) {
+		if (do_update_age) {
+			nsp->sp_lstchg = gettime () / SCALE;
+				if (0 == nsp->sp_lstchg) {
+					/* Better disable aging than requiring a password
+					 * change */
+					nsp->sp_lstchg = -1;
+				}
+			}
 		}
-	}
-#endif				/* !USE_PAM */
 
 	/*
 	 * Force change on next login, like SunOS 4.x passwd -e or Solaris
@@ -736,11 +738,9 @@ int main (int argc, char **argv)
 {
 	const struct passwd *pw;	/* Password file entry for user      */
 
-#ifndef USE_PAM
 	char *cp;		/* Miscellaneous character pointing  */
 
 	const struct spwd *sp;	/* Shadow file entry for user   */
-#endif				/* !USE_PAM */
 
 	sanitize_env ();
 
@@ -755,6 +755,12 @@ int main (int argc, char **argv)
 	(void) textdomain (PACKAGE);
 
 	process_root_flag ("-R", argc, argv);
+	prefix = process_prefix_flag ("-P", argc, argv);
+
+	if (prefix[0]) {
+		use_pam = false;
+		do_update_age = true;
+	}
 
 	/*
 	 * The program behaves differently when executed by root than when
@@ -781,6 +787,7 @@ int main (int argc, char **argv)
 			{"quiet",       no_argument,       NULL, 'q'},
 			{"repository",  required_argument, NULL, 'r'},
 			{"root",        required_argument, NULL, 'R'},
+			{"prefix",      required_argument, NULL, 'P'},
 			{"status",      no_argument,       NULL, 'S'},
 			{"unlock",      no_argument,       NULL, 'u'},
 			{"warndays",    required_argument, NULL, 'w'},
@@ -788,7 +795,7 @@ int main (int argc, char **argv)
 			{NULL, 0, NULL, '\0'}
 		};
 
-		while ((c = getopt_long (argc, argv, "adehi:kln:qr:R:Suw:x:",
+		while ((c = getopt_long (argc, argv, "adehi:kln:qr:R:P:Suw:x:",
 		                         long_options, NULL)) != -1) {
 			switch (c) {
 			case 'a':
@@ -850,6 +857,8 @@ int main (int argc, char **argv)
 				break;
 			case 'R': /* no-op, handled in process_root_flag () */
 				break;
+			case 'P': /* no-op, handled in process_prefix_flag () */
+						break;
 			case 'S':
 				Sflg = true;	/* ok for users */
 				break;
@@ -927,11 +936,11 @@ int main (int argc, char **argv)
 			                Prog);
 			exit (E_NOPERM);
 		}
-		setpwent ();
-		while ( (pw = getpwent ()) != NULL ) {
+		prefix_setpwent ();
+		while ( (pw = prefix_getpwent ()) != NULL ) {
 			print_status (pw);
 		}
-		endpwent ();
+		prefix_endpwent ();
 		exit (E_SUCCESS);
 	}
 #if 0
@@ -968,7 +977,7 @@ int main (int argc, char **argv)
 		exit (E_NOPERM);
 	}
 
-	pw = xgetpwnam (name);
+	pw = xprefix_getpwnam (name);
 	if (NULL == pw) {
 		(void) fprintf (stderr,
 		                _("%s: user '%s' does not exist\n"),
@@ -1008,53 +1017,56 @@ int main (int argc, char **argv)
 		print_status (pw);
 		exit (E_SUCCESS);
 	}
-#ifndef USE_PAM
+
+	if (!use_pam)
+	{
 	/*
 	 * The user name is valid, so let's get the shadow file entry.
 	 */
-	sp = getspnam (name); /* !USE_PAM, no need for xgetspnam */
-	if (NULL == sp) {
-		if (errno == EACCES) {
-			(void) fprintf (stderr,
-			                _("%s: Permission denied.\n"),
-			                Prog);
-			exit (E_NOPERM);
+		sp = prefix_getspnam (name); /* !use_pam, no need for xprefix_getspnam */
+		if (NULL == sp) {
+			if (errno == EACCES) {
+				(void) fprintf (stderr,
+						_("%s: Permission denied.\n"),
+						Prog);
+				exit (E_NOPERM);
+			}
+			sp = pwd_to_spwd (pw);
 		}
-		sp = pwd_to_spwd (pw);
-	}
-
-	cp = sp->sp_pwdp;
-
-	/*
-	 * If there are no other flags, just change the password.
-	 */
-	if (!anyflag) {
-		STRFCPY (crypt_passwd, cp);
-
-		/*
-		 * See if the user is permitted to change the password. 
-		 * Otherwise, go ahead and set a new password.
-		 */
-		check_password (pw, sp);
 
+		cp = sp->sp_pwdp;
 		/*
 		 * Let the user know whose password is being changed.
+		 * If there are no other flags, just change the password.
 		 */
-		if (!qflg) {
-			(void) printf (_("Changing password for %s\n"), name);
-		}
+		if (!anyflag) {
+			STRFCPY (crypt_passwd, cp);
 
-		if (new_password (pw) != 0) {
-			(void) fprintf (stderr,
-			                _("The password for %s is unchanged.\n"),
-			                name);
-			closelog ();
-			exit (E_NOPERM);
+			/*
+			 * See if the user is permitted to change the password.
+			 * Otherwise, go ahead and set a new password.
+			 */
+			check_password (pw, sp);
+
+			/*
+			 * Let the user know whose password is being changed.
+			 */
+			if (!qflg) {
+				(void) printf (_("Changing password for %s\n"), name);
+			}
+
+			if (new_password (pw) != 0) {
+				(void) fprintf (stderr,
+						_("The password for %s is unchanged.\n"),
+						name);
+				closelog ();
+				exit (E_NOPERM);
+			}
+			do_update_pwd = true;
+			do_update_age = true;
 		}
-		do_update_pwd = true;
-		do_update_age = true;
 	}
-#endif				/* !USE_PAM */
+
 	/*
 	 * Before going any further, raise the ulimit to prevent colliding
 	 * into a lowered ulimit, and set the real UID to root to protect
@@ -1067,7 +1079,7 @@ int main (int argc, char **argv)
 	/*
 	 * Don't set the real UID for PAM...
 	 */
-	if (!anyflag) {
+	if (!anyflag && use_pam) {
 		do_pam_passwd (name, qflg, kflg);
 		exit (E_SUCCESS);
 	}
openSUSE Build Service is sponsored by