* NEWS, src/chpasswd.c, man/chpasswd.8.xml, man/login.defs.5.xml:

PAM enabled versions: restore the -e option to allow restoring
	passwords without knowing those passwords. Restore together the -m
	and -c options.
This commit is contained in:
nekral-guest 2010-03-25 20:35:59 +00:00
parent fcd5b38caf
commit 97961b8bee
5 changed files with 120 additions and 90 deletions

View File

@ -1,3 +1,10 @@
2010-03-25 Nicolas François <nicolas.francois@centraliens.net>
* NEWS, src/chpasswd.c, man/chpasswd.8.xml, man/login.defs.5.xml:
PAM enabled versions: restore the -e option to allow restoring
passwords without knowing those passwords. Restore together the -m
and -c options.
2010-03-23 Nicolas François <nicolas.francois@centraliens.net> 2010-03-23 Nicolas François <nicolas.francois@centraliens.net>
* src/su.c, src/vipw.c, src/newgrp.c: When the child is * src/su.c, src/vipw.c, src/newgrp.c: When the child is

5
NEWS
View File

@ -8,6 +8,11 @@ shadow-4.1.4.2 -> shadow-4.1.5 UNRELEASED
* initial support for tcb (http://openwall.com/tcb/) for useradd, * initial support for tcb (http://openwall.com/tcb/) for useradd,
userdel, usermod, chage, pwck, vipw. userdel, usermod, chage, pwck, vipw.
-chpasswd
* PAM enabled versions: restore the -e option to allow restoring
passwords without knowing those passwords. Restore together the -m
and -c options. (These options were removed in shadow-4.1.4 on PAM
enabled versions)
- faillog - faillog
* The -l, -m, -r, -t options only act on the existing users, unless -a is * The -l, -m, -r, -t options only act on the existing users, unless -a is
specified. specified.

View File

@ -67,38 +67,37 @@
<emphasis remap='I'>user_name</emphasis>:<emphasis <emphasis remap='I'>user_name</emphasis>:<emphasis
remap='I'>password</emphasis> remap='I'>password</emphasis>
</para> </para>
<refsect2 condition="no_pam">
<para> <para>
By default the supplied password must be in clear-text, and is By default the passwords must be supplied in clear-text, and are
encrypted by <command>chpasswd</command>. encrypted by <command>chpasswd</command>.
Also the password age will be updated, if present. Also the password age will be updated, if present.
</para> </para>
<para> <para condition="no_pam">
The default encryption algorithm can be defined for the system with The default encryption algorithm can be defined for the system with
the ENCRYPT_METHOD variable of <filename>/etc/login.defs</filename>, the <option>ENCRYPT_METHOD</option> or
and can be overwiten with the <option>-e</option>, <option>MD5_CRYPT_ENAB</option> variables of
<option>-m</option>, or <option>-c</option> options. <filename>/etc/login.defs</filename>, and can be overwitten with the
<option>-e</option>, <option>-m</option>, or <option>-c</option>
options.
</para>
<para condition="pam">
By default, passwords are encrypted by PAM, but (even if not
recommended) you can select a different encryption method with the
<option>-e</option>, <option>-m</option>, or <option>-c</option>
options.
</para>
<para>
<phrase condition="pam">Except when PAM is used to encrypt the
passwords,</phrase> <command>chpasswd</command> first updates all the
passwords in memory, and then commits all the changes to disk if no
errors occured for any user.
</para>
<para condition="pam">
When PAM is used to encrypt the passwords (and update the passwords in
the system database) then if a password cannot be updated
<command>chpasswd</command> continues updating the passwords of the
next users, and will return an error code on exit.
</para> </para>
<para>
<command>chpasswd</command> first update the password in memory,
and then commit all the changes to disk if no errors occured for
any users.
</para>
</refsect2>
<refsect2 condition="pam">
<para>
The supplied passwords must be in clear-text.
</para>
<para>
PAM is used to update the password in the system database
according to the PAM chpasswd configuration.
</para>
<para>
When <command>chpasswd</command> fails to update a password, it
continues updating the passwords of the next users, and will
return an error code on exit.
</para>
</refsect2>
<para> <para>
This command is intended to be used in a large system environment This command is intended to be used in a large system environment
where many accounts are created at a single time. where many accounts are created at a single time.
@ -111,9 +110,12 @@
The options which apply to the <command>chpasswd</command> command The options which apply to the <command>chpasswd</command> command
are: are:
</para> </para>
<variablelist remap='IP' condition="no_pam"> <variablelist remap='IP'>
<varlistentry> <varlistentry>
<term><option>-c</option>, <option>--crypt-method</option></term> <term>
<option>-c</option>, <option>--crypt-method</option>
<replaceable>METHOD</replaceable>
</term>
<listitem> <listitem>
<para>Use the specified method to encrypt the passwords.</para> <para>Use the specified method to encrypt the passwords.</para>
<para condition="no_sha_crypt"> <para condition="no_sha_crypt">
@ -123,6 +125,17 @@
The available methods are DES, MD5, NONE, and SHA256 or SHA512 The available methods are DES, MD5, NONE, and SHA256 or SHA512
if your libc support these methods. if your libc support these methods.
</para> </para>
<para condition="pam">
By default, PAM is used to encrypt the passwords.
</para>
<para condition="no_pam">
By default (if none of the <option>-c</option>,
<option>-m</option>, or <option>-e</option> options are
specified), the encryption method is defined by the
<option>ENCRYPT_METHOD</option> or
<option>MD5_CRYPT_ENAB</option> variables of
<filename>/etc/login.defs</filename>.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -140,7 +153,7 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
<variablelist remap='IP' condition="no_pam"> <variablelist remap='IP'>
<varlistentry> <varlistentry>
<term><option>-m</option>, <option>--md5</option></term> <term><option>-m</option>, <option>--md5</option></term>
<listitem> <listitem>
@ -151,7 +164,10 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry condition="sha_crypt"> <varlistentry condition="sha_crypt">
<term><option>-s</option>, <option>--sha-rounds</option></term> <term>
<option>-s</option>, <option>--sha-rounds</option>
<replaceable>ROUNDS</replaceable>
</term>
<listitem> <listitem>
<para> <para>
Use the specified number of rounds to encrypt the passwords. Use the specified number of rounds to encrypt the passwords.
@ -170,7 +186,8 @@
</para> </para>
<para> <para>
By default, the number of rounds is defined by the By default, the number of rounds is defined by the
SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS variables in <option>SHA_CRYPT_MIN_ROUNDS</option> and
<option>SHA_CRYPT_MAX_ROUNDS</option> variables in
<filename>/etc/login.defs</filename>. <filename>/etc/login.defs</filename>.
</para> </para>
</listitem> </listitem>
@ -184,22 +201,20 @@
Remember to set permissions or umask to prevent readability of Remember to set permissions or umask to prevent readability of
unencrypted files by other users. unencrypted files by other users.
</para> </para>
<para condition="no_pam">
You should make sure the passwords and the encryption method respect
the system's password policy.
</para>
</refsect1> </refsect1>
<refsect1 id='configuration' condition="no_pam"> <refsect1 id='configuration'>
<title>CONFIGURATION</title> <title>CONFIGURATION</title>
<para> <para>
The following configuration variables in The following configuration variables in
<filename>/etc/login.defs</filename> change the behavior of this <filename>/etc/login.defs</filename> change the behavior of this
tool: tool:
</para> </para>
<variablelist> <variablelist condition="no_pam">
&ENCRYPT_METHOD; &ENCRYPT_METHOD;
&MD5_CRYPT_ENAB; &MD5_CRYPT_ENAB;
</variablelist>
<variablelist>
&SHA_CRYPT_MIN_ROUNDS; <!--documents also SHA_CRYPT_MAX_ROUNDS--> &SHA_CRYPT_MIN_ROUNDS; <!--documents also SHA_CRYPT_MAX_ROUNDS-->
</variablelist> </variablelist>
</refsect1> </refsect1>
@ -207,19 +222,19 @@
<refsect1 id='files'> <refsect1 id='files'>
<title>FILES</title> <title>FILES</title>
<variablelist> <variablelist>
<varlistentry condition="no_pam"> <varlistentry>
<term><filename>/etc/passwd</filename></term> <term><filename>/etc/passwd</filename></term>
<listitem> <listitem>
<para>User account information.</para> <para>User account information.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry condition="no_pam"> <varlistentry>
<term><filename>/etc/shadow</filename></term> <term><filename>/etc/shadow</filename></term>
<listitem> <listitem>
<para>Secure user account information.</para> <para>Secure user account information.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry condition="no_pam"> <varlistentry>
<term><filename>/etc/login.defs</filename></term> <term><filename>/etc/login.defs</filename></term>
<listitem> <listitem>
<para>Shadow password suite configuration.</para> <para>Shadow password suite configuration.</para>
@ -243,7 +258,7 @@
<citerefentry> <citerefentry>
<refentrytitle>newusers</refentrytitle><manvolnum>8</manvolnum> <refentrytitle>newusers</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>, </citerefentry>,
<phrase condition="no_pam"> <phrase>
<citerefentry> <citerefentry>
<refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum> <refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum>
</citerefentry>, </citerefentry>,

View File

@ -245,11 +245,12 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry condition="no_pam"> <varlistentry>
<term>chpasswd</term> <term>chpasswd</term>
<listitem> <listitem>
<para> <para>
ENCRYPT_METHOD MD5_CRYPT_ENAB <phrase condition="no_pam">ENCRYPT_METHOD
MD5_CRYPT_ENAB </phrase>
<phrase condition="sha_crypt">SHA_CRYPT_MAX_ROUNDS <phrase condition="sha_crypt">SHA_CRYPT_MAX_ROUNDS
SHA_CRYPT_MIN_ROUNDS</phrase> SHA_CRYPT_MIN_ROUNDS</phrase>
</para> </para>

View File

@ -54,7 +54,6 @@
* Global variables * Global variables
*/ */
char *Prog; char *Prog;
#ifndef USE_PAM
static bool cflg = false; static bool cflg = false;
static bool eflg = false; static bool eflg = false;
static bool md5flg = false; static bool md5flg = false;
@ -70,7 +69,6 @@ static long sha_rounds = 5000;
static bool is_shadow_pwd; static bool is_shadow_pwd;
static bool pw_locked = false; static bool pw_locked = false;
static bool spw_locked = false; static bool spw_locked = false;
#endif /* !USE_PAM */
/* local function prototypes */ /* local function prototypes */
static void fail_exit (int code); static void fail_exit (int code);
@ -78,17 +76,14 @@ static void usage (int status);
static void process_flags (int argc, char **argv); static void process_flags (int argc, char **argv);
static void check_flags (void); static void check_flags (void);
static void check_perms (void); static void check_perms (void);
#ifndef USE_PAM
static void open_files (void); static void open_files (void);
static void close_files (void); static void close_files (void);
#endif /* !USE_PAM */
/* /*
* fail_exit - exit with a failure code after unlocking the files * fail_exit - exit with a failure code after unlocking the files
*/ */
static void fail_exit (int code) static void fail_exit (int code)
{ {
#ifndef USE_PAM
if (pw_locked) { if (pw_locked) {
if (pw_unlock () == 0) { if (pw_unlock () == 0) {
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ());
@ -104,7 +99,6 @@ static void fail_exit (int code)
/* continue */ /* continue */
} }
} }
#endif /* !USE_PAM */
exit (code); exit (code);
} }
@ -120,9 +114,8 @@ static void usage (int status)
"\n" "\n"
"Options:\n"), "Options:\n"),
Prog); Prog);
#ifndef USE_PAM
(void) fprintf (usageout, (void) fprintf (usageout,
_(" -c, --crypt-method the crypt method (one of %s)\n"), _(" -c, --crypt-method <METHOD> the crypt method (one of %s)\n"),
#ifndef USE_SHA_CRYPT #ifndef USE_SHA_CRYPT
"NONE DES MD5" "NONE DES MD5"
#else /* USE_SHA_CRYPT */ #else /* USE_SHA_CRYPT */
@ -130,9 +123,7 @@ static void usage (int status)
#endif /* USE_SHA_CRYPT */ #endif /* USE_SHA_CRYPT */
); );
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout); (void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
#endif /* !USE_PAM */
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout); (void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
#ifndef USE_PAM
(void) fputs (_(" -m, --md5 encrypt the clear text password using\n" (void) fputs (_(" -m, --md5 encrypt the clear text password using\n"
" the MD5 algorithm\n"), " the MD5 algorithm\n"),
usageout); usageout);
@ -141,7 +132,6 @@ static void usage (int status)
" crypt algorithms\n"), " crypt algorithms\n"),
usageout); usageout);
#endif /* USE_SHA_CRYPT */ #endif /* USE_SHA_CRYPT */
#endif /* !USE_PAM */
(void) fputs ("\n", usageout); (void) fputs ("\n", usageout);
exit (status); exit (status);
@ -157,34 +147,27 @@ static void process_flags (int argc, char **argv)
int option_index = 0; int option_index = 0;
int c; int c;
static struct option long_options[] = { static struct option long_options[] = {
#ifndef USE_PAM
{"crypt-method", required_argument, NULL, 'c'}, {"crypt-method", required_argument, NULL, 'c'},
{"encrypted", no_argument, NULL, 'e'}, {"encrypted", no_argument, NULL, 'e'},
{"md5", no_argument, NULL, 'm'}, {"md5", no_argument, NULL, 'm'},
#ifdef USE_SHA_CRYPT #ifdef USE_SHA_CRYPT
{"sha-rounds", required_argument, NULL, 's'}, {"sha-rounds", required_argument, NULL, 's'},
#endif /* USE_SHA_CRYPT */ #endif /* USE_SHA_CRYPT */
#endif /* !USE_PAM */
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, '\0'} {NULL, 0, NULL, '\0'}
}; };
while ((c = getopt_long (argc, argv, while ((c = getopt_long (argc, argv,
#ifndef USE_PAM #ifdef USE_SHA_CRYPT
# ifdef USE_SHA_CRYPT
"c:ehms:", "c:ehms:",
# else /* !USE_SHA_CRYPT */ #else /* !USE_SHA_CRYPT */
"c:ehm", "c:ehm",
# endif /* !USE_SHA_CRYPT */ #endif /* !USE_SHA_CRYPT */
#else
"h",
#endif /* !USE_PAM */
long_options, &option_index)) != -1) { long_options, &option_index)) != -1) {
switch (c) { switch (c) {
case 'h': case 'h':
usage (E_SUCCESS); usage (E_SUCCESS);
break; break;
#ifndef USE_PAM
case 'c': case 'c':
cflg = true; cflg = true;
crypt_method = optarg; crypt_method = optarg;
@ -206,7 +189,6 @@ static void process_flags (int argc, char **argv)
} }
break; break;
#endif /* USE_SHA_CRYPT */ #endif /* USE_SHA_CRYPT */
#endif /* !USE_PAM */
default: default:
usage (E_USAGE); usage (E_USAGE);
break; break;
@ -224,7 +206,6 @@ static void process_flags (int argc, char **argv)
*/ */
static void check_flags (void) static void check_flags (void)
{ {
#ifndef USE_PAM
#ifdef USE_SHA_CRYPT #ifdef USE_SHA_CRYPT
if (sflg && !cflg) { if (sflg && !cflg) {
fprintf (stderr, fprintf (stderr,
@ -249,7 +230,7 @@ static void check_flags (void)
#ifdef USE_SHA_CRYPT #ifdef USE_SHA_CRYPT
&& (0 != strcmp (crypt_method, "SHA256")) && (0 != strcmp (crypt_method, "SHA256"))
&& (0 != strcmp (crypt_method, "SHA512")) && (0 != strcmp (crypt_method, "SHA512"))
#endif #endif /* USE_SHA_CRYPT */
) { ) {
fprintf (stderr, fprintf (stderr,
_("%s: unsupported crypt method: %s\n"), _("%s: unsupported crypt method: %s\n"),
@ -257,7 +238,6 @@ static void check_flags (void)
usage (E_USAGE); usage (E_USAGE);
} }
} }
#endif /* USE_PAM */
} }
/* /*
@ -274,6 +254,10 @@ static void check_perms (void)
{ {
#ifdef USE_PAM #ifdef USE_PAM
#ifdef ACCT_TOOLS_SETUID #ifdef ACCT_TOOLS_SETUID
/* If chpasswd uses PAM and is SUID, check the permissions,
* otherwise, the permissions are enforced by the access to the
* passwd and shadow files.
*/
pam_handle_t *pamh = NULL; pam_handle_t *pamh = NULL;
int retval; int retval;
struct passwd *pampw; struct passwd *pampw;
@ -307,7 +291,6 @@ static void check_perms (void)
#endif /* USE_PAM */ #endif /* USE_PAM */
} }
#ifndef USE_PAM
/* /*
* open_files - lock and open the password databases * open_files - lock and open the password databases
*/ */
@ -383,7 +366,6 @@ static void close_files (void)
} }
pw_locked = false; pw_locked = false;
} }
#endif
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
@ -392,13 +374,9 @@ int main (int argc, char **argv)
char *newpwd; char *newpwd;
char *cp; char *cp;
#ifndef USE_PAM #ifdef USE_PAM
const struct spwd *sp; bool use_pam = true;
struct spwd newsp; #endif /* USE_PAM */
const struct passwd *pw;
struct passwd newpw;
#endif /* !USE_PAM */
int errors = 0; int errors = 0;
int line = 0; int line = 0;
@ -411,15 +389,24 @@ int main (int argc, char **argv)
process_flags (argc, argv); process_flags (argc, argv);
#ifdef USE_PAM
if (md5flg || eflg || cflg) {
use_pam = false;
}
#endif /* USE_PAM */
OPENLOG ("chpasswd"); OPENLOG ("chpasswd");
check_perms (); check_perms ();
#ifndef USE_PAM #ifdef USE_PAM
is_shadow_pwd = spw_file_present (); if (!use_pam)
#endif /* USE_PAM */
{
is_shadow_pwd = spw_file_present ();
open_files (); open_files ();
#endif }
/* /*
* Read each line, separating the user name from the password. The * Read each line, separating the user name from the password. The
@ -468,13 +455,21 @@ int main (int argc, char **argv)
newpwd = cp; newpwd = cp;
#ifdef USE_PAM #ifdef USE_PAM
if (use_pam){
if (do_pam_passwd_non_interractive ("chpasswd", name, newpwd) != 0) { if (do_pam_passwd_non_interractive ("chpasswd", name, newpwd) != 0) {
fprintf (stderr, fprintf (stderr,
_("%s: (line %d, user %s) password not changed\n"), _("%s: (line %d, user %s) password not changed\n"),
Prog, line, name); Prog, line, name);
errors++; errors++;
} }
#else /* !USE_PAM */ } else
#endif /* USE_PAM */
{
const struct spwd *sp;
struct spwd newsp;
const struct passwd *pw;
struct passwd newpw;
if ( !eflg if ( !eflg
&& ( (NULL == crypt_method) && ( (NULL == crypt_method)
|| (0 != strcmp (crypt_method, "NONE")))) { || (0 != strcmp (crypt_method, "NONE")))) {
@ -553,7 +548,7 @@ int main (int argc, char **argv)
continue; continue;
} }
} }
#endif /* !USE_PAM */ }
} }
/* /*
@ -567,17 +562,24 @@ int main (int argc, char **argv)
* password database. * password database.
*/ */
if (0 != errors) { if (0 != errors) {
#ifndef USE_PAM #ifdef USE_PAM
fprintf (stderr, if (!use_pam)
_("%s: error detected, changes ignored\n"), Prog); #endif /* USE_PAM */
#endif {
fprintf (stderr,
_("%s: error detected, changes ignored\n"),
Prog);
}
fail_exit (1); fail_exit (1);
} }
#ifndef USE_PAM #ifdef USE_PAM
if (!use_pam)
#endif /* USE_PAM */
{
/* Save the changes */ /* Save the changes */
close_files (); close_files ();
#endif }
nscd_flush_cache ("passwd"); nscd_flush_cache ("passwd");