diff --git a/ChangeLog b/ChangeLog index ac2fda83..7af2f0c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-03-25 Nicolas François + + * 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 * src/su.c, src/vipw.c, src/newgrp.c: When the child is diff --git a/NEWS b/NEWS index 2e2619c3..a4a0b293 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,11 @@ shadow-4.1.4.2 -> shadow-4.1.5 UNRELEASED * initial support for tcb (http://openwall.com/tcb/) for useradd, 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 * The -l, -m, -r, -t options only act on the existing users, unless -a is specified. diff --git a/man/chpasswd.8.xml b/man/chpasswd.8.xml index 732a4643..69f1247e 100644 --- a/man/chpasswd.8.xml +++ b/man/chpasswd.8.xml @@ -67,38 +67,37 @@ user_name:password - - 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 chpasswd. Also the password age will be updated, if present. - + The default encryption algorithm can be defined for the system with - the ENCRYPT_METHOD variable of /etc/login.defs, - and can be overwiten with the , - , or options. + the or + variables of + /etc/login.defs, and can be overwitten with the + , , or + options. + + + By default, passwords are encrypted by PAM, but (even if not + recommended) you can select a different encryption method with the + , , or + options. + + + Except when PAM is used to encrypt the + passwords, chpasswd first updates all the + passwords in memory, and then commits all the changes to disk if no + errors occured for any user. + + + When PAM is used to encrypt the passwords (and update the passwords in + the system database) then if a password cannot be updated + chpasswd continues updating the passwords of the + next users, and will return an error code on exit. - - chpasswd first update the password in memory, - and then commit all the changes to disk if no errors occured for - any users. - - - - - The supplied passwords must be in clear-text. - - - PAM is used to update the password in the system database - according to the PAM chpasswd configuration. - - - When chpasswd fails to update a password, it - continues updating the passwords of the next users, and will - return an error code on exit. - - This command is intended to be used in a large system environment where many accounts are created at a single time. @@ -111,9 +110,12 @@ The options which apply to the chpasswd command are: - + - , + + , + METHOD + Use the specified method to encrypt the passwords. @@ -123,6 +125,17 @@ The available methods are DES, MD5, NONE, and SHA256 or SHA512 if your libc support these methods. + + By default, PAM is used to encrypt the passwords. + + + By default (if none of the , + , or options are + specified), the encryption method is defined by the + or + variables of + /etc/login.defs. + @@ -140,7 +153,7 @@ - + , @@ -151,7 +164,10 @@ - , + + , + ROUNDS + Use the specified number of rounds to encrypt the passwords. @@ -170,7 +186,8 @@ By default, the number of rounds is defined by the - SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS variables in + and + variables in /etc/login.defs. @@ -184,22 +201,20 @@ Remember to set permissions or umask to prevent readability of unencrypted files by other users. - - You should make sure the passwords and the encryption method respect - the system's password policy. - - + CONFIGURATION The following configuration variables in /etc/login.defs change the behavior of this tool: - + &ENCRYPT_METHOD; &MD5_CRYPT_ENAB; + + &SHA_CRYPT_MIN_ROUNDS; @@ -207,19 +222,19 @@ FILES - + /etc/passwd User account information. - + /etc/shadow Secure user account information. - + /etc/login.defs Shadow password suite configuration. @@ -243,7 +258,7 @@ newusers8 , - + login.defs5 , diff --git a/man/login.defs.5.xml b/man/login.defs.5.xml index f10c7c07..35988565 100644 --- a/man/login.defs.5.xml +++ b/man/login.defs.5.xml @@ -245,11 +245,12 @@ - + chpasswd - ENCRYPT_METHOD MD5_CRYPT_ENAB + ENCRYPT_METHOD + MD5_CRYPT_ENAB SHA_CRYPT_MAX_ROUNDS SHA_CRYPT_MIN_ROUNDS diff --git a/src/chpasswd.c b/src/chpasswd.c index 63158d1e..55f8312f 100644 --- a/src/chpasswd.c +++ b/src/chpasswd.c @@ -54,7 +54,6 @@ * Global variables */ char *Prog; -#ifndef USE_PAM static bool cflg = false; static bool eflg = false; static bool md5flg = false; @@ -70,7 +69,6 @@ static long sha_rounds = 5000; static bool is_shadow_pwd; static bool pw_locked = false; static bool spw_locked = false; -#endif /* !USE_PAM */ /* local function prototypes */ 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 check_flags (void); static void check_perms (void); -#ifndef USE_PAM static void open_files (void); static void close_files (void); -#endif /* !USE_PAM */ /* * fail_exit - exit with a failure code after unlocking the files */ static void fail_exit (int code) { -#ifndef USE_PAM if (pw_locked) { if (pw_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ()); @@ -104,7 +99,6 @@ static void fail_exit (int code) /* continue */ } } -#endif /* !USE_PAM */ exit (code); } @@ -120,9 +114,8 @@ static void usage (int status) "\n" "Options:\n"), Prog); -#ifndef USE_PAM (void) fprintf (usageout, - _(" -c, --crypt-method the crypt method (one of %s)\n"), + _(" -c, --crypt-method the crypt method (one of %s)\n"), #ifndef USE_SHA_CRYPT "NONE DES MD5" #else /* USE_SHA_CRYPT */ @@ -130,9 +123,7 @@ static void usage (int status) #endif /* USE_SHA_CRYPT */ ); (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); -#ifndef USE_PAM (void) fputs (_(" -m, --md5 encrypt the clear text password using\n" " the MD5 algorithm\n"), usageout); @@ -141,7 +132,6 @@ static void usage (int status) " crypt algorithms\n"), usageout); #endif /* USE_SHA_CRYPT */ -#endif /* !USE_PAM */ (void) fputs ("\n", usageout); exit (status); @@ -157,34 +147,27 @@ static void process_flags (int argc, char **argv) int option_index = 0; int c; static struct option long_options[] = { -#ifndef USE_PAM {"crypt-method", required_argument, NULL, 'c'}, {"encrypted", no_argument, NULL, 'e'}, {"md5", no_argument, NULL, 'm'}, #ifdef USE_SHA_CRYPT {"sha-rounds", required_argument, NULL, 's'}, #endif /* USE_SHA_CRYPT */ -#endif /* !USE_PAM */ {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, '\0'} }; while ((c = getopt_long (argc, argv, -#ifndef USE_PAM -# ifdef USE_SHA_CRYPT +#ifdef USE_SHA_CRYPT "c:ehms:", -# else /* !USE_SHA_CRYPT */ +#else /* !USE_SHA_CRYPT */ "c:ehm", -# endif /* !USE_SHA_CRYPT */ -#else - "h", -#endif /* !USE_PAM */ +#endif /* !USE_SHA_CRYPT */ long_options, &option_index)) != -1) { switch (c) { case 'h': usage (E_SUCCESS); break; -#ifndef USE_PAM case 'c': cflg = true; crypt_method = optarg; @@ -206,7 +189,6 @@ static void process_flags (int argc, char **argv) } break; #endif /* USE_SHA_CRYPT */ -#endif /* !USE_PAM */ default: usage (E_USAGE); break; @@ -224,7 +206,6 @@ static void process_flags (int argc, char **argv) */ static void check_flags (void) { -#ifndef USE_PAM #ifdef USE_SHA_CRYPT if (sflg && !cflg) { fprintf (stderr, @@ -249,7 +230,7 @@ static void check_flags (void) #ifdef USE_SHA_CRYPT && (0 != strcmp (crypt_method, "SHA256")) && (0 != strcmp (crypt_method, "SHA512")) -#endif +#endif /* USE_SHA_CRYPT */ ) { fprintf (stderr, _("%s: unsupported crypt method: %s\n"), @@ -257,7 +238,6 @@ static void check_flags (void) usage (E_USAGE); } } -#endif /* USE_PAM */ } /* @@ -274,6 +254,10 @@ static void check_perms (void) { #ifdef USE_PAM #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; int retval; struct passwd *pampw; @@ -307,7 +291,6 @@ static void check_perms (void) #endif /* USE_PAM */ } -#ifndef USE_PAM /* * open_files - lock and open the password databases */ @@ -383,7 +366,6 @@ static void close_files (void) } pw_locked = false; } -#endif int main (int argc, char **argv) { @@ -392,13 +374,9 @@ int main (int argc, char **argv) char *newpwd; char *cp; -#ifndef USE_PAM - const struct spwd *sp; - struct spwd newsp; - - const struct passwd *pw; - struct passwd newpw; -#endif /* !USE_PAM */ +#ifdef USE_PAM + bool use_pam = true; +#endif /* USE_PAM */ int errors = 0; int line = 0; @@ -411,15 +389,24 @@ int main (int argc, char **argv) process_flags (argc, argv); +#ifdef USE_PAM + if (md5flg || eflg || cflg) { + use_pam = false; + } +#endif /* USE_PAM */ + OPENLOG ("chpasswd"); check_perms (); -#ifndef USE_PAM - is_shadow_pwd = spw_file_present (); +#ifdef USE_PAM + if (!use_pam) +#endif /* USE_PAM */ + { + is_shadow_pwd = spw_file_present (); - open_files (); -#endif + open_files (); + } /* * Read each line, separating the user name from the password. The @@ -468,13 +455,21 @@ int main (int argc, char **argv) newpwd = cp; #ifdef USE_PAM + if (use_pam){ if (do_pam_passwd_non_interractive ("chpasswd", name, newpwd) != 0) { fprintf (stderr, _("%s: (line %d, user %s) password not changed\n"), Prog, line, name); errors++; } -#else /* !USE_PAM */ + } else +#endif /* USE_PAM */ + { + const struct spwd *sp; + struct spwd newsp; + const struct passwd *pw; + struct passwd newpw; + if ( !eflg && ( (NULL == crypt_method) || (0 != strcmp (crypt_method, "NONE")))) { @@ -553,7 +548,7 @@ int main (int argc, char **argv) continue; } } -#endif /* !USE_PAM */ + } } /* @@ -567,17 +562,24 @@ int main (int argc, char **argv) * password database. */ if (0 != errors) { -#ifndef USE_PAM - fprintf (stderr, - _("%s: error detected, changes ignored\n"), Prog); -#endif +#ifdef USE_PAM + if (!use_pam) +#endif /* USE_PAM */ + { + fprintf (stderr, + _("%s: error detected, changes ignored\n"), + Prog); + } fail_exit (1); } -#ifndef USE_PAM +#ifdef USE_PAM + if (!use_pam) +#endif /* USE_PAM */ + { /* Save the changes */ - close_files (); -#endif + close_files (); + } nscd_flush_cache ("passwd");