File shadow-4.8.1-add-prefix-passwd-chpasswd-chage.patch of Package shadow
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);
}