* Changelog: Update documentation of 2013-07-28 mancha entry.
* lib/prototypes.h, lib/encrypt.c: Update splint marker,
pw_encrypt can return NULL.
* lib/encrypt.c: Fix outdated statement on GNU crypt.
* src/chgpasswd.c: Improve diagnostic to user when pw_encrypt
fails and use fail_exit() instead of exit().
* src/chpasswd.c: Likewise.
* src/newusers.c: Likewise.
* src/passwd.c: Likewise when new password is encrypted.
* src/newgrp.c: Improve diagnostic to user and syslog when
pw_encrypt fails. Do not apply 1s penalty as this is not an
invalid password issue.
* src/passwd.c: Likewise when password is checked.
+2013-08-03 Nicolas François <nicolas.francois@centraliens.net>
+
+ * Changelog: Update documentation of 2013-07-28 mancha entry.
+ * lib/prototypes.h, lib/encrypt.c: Update splint marker,
+ pw_encrypt can return NULL.
+ * lib/encrypt.c: Fix outdated statement on GNU crypt.
+ * src/chgpasswd.c: Improve diagnostic to user when pw_encrypt
+ fails and use fail_exit() instead of exit().
+ * src/chpasswd.c: Likewise.
+ * src/newusers.c: Likewise.
+ * src/passwd.c: Likewise when new password is encrypted.
+ * src/newgrp.c: Improve diagnostic to user and syslog when
+ pw_encrypt fails. Do not apply 1s penalty as this is not an
+ invalid password issue.
+ * src/passwd.c: Likewise when password is checked.
+
2013-08-02 Nicolas François <nicolas.francois@centraliens.net>
* libmisc/setupenv.c: xstrdup the static char* temp_pw_dir /
2013-07-28 mancha <mancha1@hush.com>
- * lib/encrypt.c: crypt() in glibc/eglibc 2.17 now fails if passed
- a salt that violates specs. On Linux, crypt() also fails with
- DES/MD5 salts in FIPS140 mode. Rather than exit() on NULL returns
- we send them back to the caller for appropriate handling.
- Closes: alioth#314234
- * lib/pwauth.c: Handle NULL return from crypt().
- * libmisc/valid.c: Likewise.
- * src/chgpasswd.c: Likewise.
- * src/chpasswd.c: Likewise.
- * src/gpasswd.c: Likewise.
- * src/newgrp.c: Likewise.
- * src/newusers.c: Likewise.
- * src/passwd.c: Likewise.
+ * lib/encrypt.c (pw_encrypt): crypt() in glibc/eglibc 2.17 now
+ fails if passed a salt that violates specs. On Linux, crypt() also
+ fails with DES/MD5 salts in FIPS140 mode. Rather than exit() on
+ NULL returns we send them back to the caller for appropriate
+ handling (instead of exiting). Closes: alioth#314234
+ * lib/pwauth.c: Handle NULL return from pw_crypt(), return non
+ zero (as in case of failure).
+ * libmisc/valid.c: Likewise.
+ * src/chgpasswd.c: Handle NULL return from pw_crypt(), report
+ crypt error to stderr and exit.
+ * src/chpasswd.c: Likewise.
+ * src/gpasswd.c: Likewise.
+ * src/newusers.c: Likewise.
+ * src/passwd.c: Likewise when new password is encrypted.
+ * src/newgrp.c: Handle NULL return from pw_crypt(), report crypt
+ error to stderr and syslog and return to report unchanged
+ password.
+ * src/passwd.c: Likewise when password is checked.
2013-07-28 Christian Perrier <christian@perrier.eu.org>
#include "prototypes.h"
#include "defines.h"
-/*@exposed@*/char *pw_encrypt (const char *clear, const char *salt)
+/*@exposed@*//*@null@*/char *pw_encrypt (const char *clear, const char *salt)
{
static char cipher[128];
char *cp;
cp = crypt (clear, salt);
- if (!cp) {
+ if (NULL == cp) {
/*
* Single Unix Spec: crypt() may return a null pointer,
* and set errno to indicate an error. In this case return
* the NULL so the caller can handle appropriately.
*/
- return cp;
+ return NULL;
}
- /* The GNU crypt does not return NULL if the algorithm is not
+ /* Some crypt() do not return NULL if the algorithm is not
* supported, and return a DES encrypted password. */
if ((NULL != salt) && (salt[0] == '$') && (strlen (cp) <= 13))
{
gid_t old_gid, gid_t new_gid);
/* encrypt.c */
-extern /*@exposed@*/char *pw_encrypt (const char *, const char *);
+extern /*@exposed@*//*@null@*/char *pw_encrypt (const char *, const char *);
/* entry.c */
extern void pw_entry (const char *, struct passwd *);
*/
encrypted = pw_encrypt (input, cipher);
- if (encrypted!=NULL)
+ if (NULL != encrypted) {
retval = strcmp (encrypted, cipher);
- else
+ } else {
retval = -1;
+ }
#ifdef SKEY
/*
&& ( (NULL == crypt_method)
|| (0 != strcmp (crypt_method, "NONE")))) {
void *arg = NULL;
+ const char *salt;
if (md5flg) {
crypt_method = "MD5";
}
arg = &sha_rounds;
}
#endif
- cp = pw_encrypt (newpwd,
- crypt_make_salt (crypt_method, arg));
- if (cp == NULL) {
- perror ("crypt");
- exit (EXIT_FAILURE);
- }
+ salt = crypt_make_salt (crypt_method, arg);
+ cp = pw_encrypt (newpwd, salt);
+ if (NULL == cp) {
+ fprintf (stderr,
+ _("%s: failed to crypt password with salt '%s': %s\n"),
+ Prog, salt, strerror (errno));
+ fail_exit (1);
+ }
}
/*
&& ( (NULL == crypt_method)
|| (0 != strcmp (crypt_method, "NONE")))) {
void *arg = NULL;
+ const char *salt;
if (md5flg) {
crypt_method = "MD5";
}
arg = &sha_rounds;
}
#endif
- cp = pw_encrypt (newpwd,
- crypt_make_salt(crypt_method, arg));
- if (cp == NULL) {
- perror ("crypt");
- exit (EXIT_FAILURE);
+ salt = crypt_make_salt (crypt_method, arg);
+ cp = pw_encrypt (newpwd, salt);
+ if (NULL == cp) {
+ fprintf (stderr,
+ _("%s: failed to crypt password with salt '%s': %s\n"),
+ Prog, salt, strerror (errno));
+ fail_exit (1);
}
}
char *cp;
static char pass[BUFSIZ];
int retries;
+ const char *salt;
/*
* A new password is to be entered and it must be encrypted, etc.
exit (1);
}
- cp = pw_encrypt (pass, crypt_make_salt (NULL, NULL));
- if (cp==NULL) {
- perror ("crypt");
- exit (EXIT_FAILURE);
+ salt = crypt_make_salt (NULL, NULL);
+ cp = pw_encrypt (pass, salt);
+ if (NULL == cp) {
+ fprintf (stderr,
+ _("%s: failed to crypt password with salt '%s': %s\n"),
+ Prog, salt, strerror (errno));
+ exit (1);
}
memzero (pass, sizeof pass);
#ifdef SHADOWGRP
cpasswd = pw_encrypt (cp, grp->gr_passwd);
strzero (cp);
- if (cpasswd == NULL ||
- grp->gr_passwd[0] == '\0' ||
+ if (NULL == cpasswd) {
+ fprintf (stderr,
+ _("%s: failed to crypt password with previous salt: %s\n"),
+ Prog, strerror (errno));
+ SYSLOG ((LOG_INFO,
+ "Failed to crypt password with previous salt of group '%s'",
+ groupname));
+ goto failure;
+ }
+
+ if (grp->gr_passwd[0] == '\0' ||
strcmp (cpasswd, grp->gr_passwd) != 0) {
#ifdef WITH_AUDIT
snprintf (audit_buf, sizeof(audit_buf),
static int get_user_id (const char *, uid_t *);
static int add_user (const char *, uid_t, gid_t);
#ifndef USE_PAM
-static void update_passwd (struct passwd *, const char *);
+static int update_passwd (struct passwd *, const char *);
#endif /* !USE_PAM */
static int add_passwd (struct passwd *, const char *);
static void process_flags (int argc, char **argv);
}
#ifndef USE_PAM
-static void update_passwd (struct passwd *pwd, const char *password)
+/*
+ * update_passwd - update the password in the passwd entry
+ *
+ * Return 0 if successful.
+ */
+static int update_passwd (struct passwd *pwd, const char *password)
{
void *crypt_arg = NULL;
char *cp;
if ((crypt_method != NULL) && (0 == strcmp(crypt_method, "NONE"))) {
pwd->pw_passwd = (char *)password;
} else {
- cp=pw_encrypt (password, crypt_make_salt (crypt_method,
- crypt_arg));
- if (cp == NULL) {
- perror ("crypt");
- exit (EXIT_FAILURE);
+ const char *salt = crypt_make_salt (crypt_method, crypt_arg);
+ cp = pw_encrypt (password, salt);
+ if (NULL == cp) {
+ fprintf (stderr,
+ _("%s: failed to crypt password with salt '%s': %s\n"),
+ Prog, salt, strerror (errno));
+ return 1;
}
pwd->pw_passwd = cp;
}
+
+ return 0;
}
#endif /* !USE_PAM */
* harder since there are zillions of things to do ...
*/
if (!is_shadow) {
- update_passwd (pwd, password);
- return 0;
+ return update_passwd (pwd, password);
}
#endif /* USE_PAM */
const char *salt = crypt_make_salt (crypt_method,
crypt_arg);
cp = pw_encrypt (password, salt);
- if (cp == NULL) {
- perror ("crypt");
- exit (EXIT_FAILURE);
+ if (NULL == cp) {
+ fprintf (stderr,
+ _("%s: failed to crypt password with salt '%s': %s\n"),
+ Prog, salt, strerror (errno));
+ return 1;
}
spent.sp_pwdp = cp;
}
* the password set someplace else.
*/
if (strcmp (pwd->pw_passwd, "x") != 0) {
- update_passwd (pwd, password);
- return 0;
+ return update_passwd (pwd, password);
}
#else /* USE_PAM */
/*
} else {
const char *salt = crypt_make_salt (crypt_method, crypt_arg);
cp = pw_encrypt (password, salt);
- if (cp == NULL) {
- perror ("crypt");
- exit (EXIT_FAILURE);
+ if (NULL == cp) {
+ fprintf (stderr,
+ _("%s: failed to crypt password with salt '%s': %s\n"),
+ Prog, salt, strerror (errno));
+ return 1;
}
spent.sp_pwdp = cp;
}
{
char *clear; /* Pointer to clear text */
char *cipher; /* Pointer to cipher text */
+ const char *salt; /* Pointer to new salt */
char *cp; /* Pointer to getpass() response */
char orig[200]; /* Original password */
char pass[200]; /* New password */
}
cipher = pw_encrypt (clear, crypt_passwd);
- if ((cipher == NULL) || (strcmp (cipher, crypt_passwd) != 0)) {
+
+ if (NULL == cipher) {
+ strzero (clear);
+ fprintf (stderr,
+ _("%s: failed to crypt password with previous salt: %s\n"),
+ Prog, strerror (errno));
+ SYSLOG ((LOG_INFO,
+ "Failed to crypt password with previous salt of user '%s'",
+ pw->pw_name));
+ return -1;
+ }
+
+ if (strcmp (cipher, crypt_passwd) != 0) {
strzero (clear);
strzero (cipher);
SYSLOG ((LOG_WARN, "incorrect password for %s",
/*
* Encrypt the password, then wipe the cleartext password.
*/
- cp = pw_encrypt (pass, crypt_make_salt (NULL, NULL));
- if (cp == NULL) {
- perror ("crypt");
- exit (EXIT_FAILURE);
- }
+ salt = crypt_make_salt (NULL, NULL);
+ cp = pw_encrypt (pass, salt);
memzero (pass, sizeof pass);
+ if (NULL == cp) {
+ fprintf (stderr,
+ _("%s: failed to crypt password with salt '%s': %s\n"),
+ Prog, salt, strerror (errno));
+ return -1;
+ }
+
#ifdef HAVE_LIBCRACK_HIST
HistUpdate (pw->pw_name, crypt_passwd);
#endif /* HAVE_LIBCRACK_HIST */