* modules/pam_sepermit/pam_sepermit.c (check_running): Avoid
leaking memory and dir handle on realloc failure.
- (sepermit_unlock) Cast fcntl() and close() calls to void.
+ (sepermit_unlock): Cast fcntl() and close() calls to void.
+
+ * modules/pam_pwhistory/opasswd.c (check_old_password): Do not
+ needlessly call strdupa().
+ (save_old_password): Avoid memleaks in error paths. Avoid memleak of
+ buf. Make the opasswd entry parsing more robust.
+ * modules/pam_pwhistory/pam_pwhistory.8.xml: Document the
+ special meaning of remember=0.
2011-06-14 Thorsten Kukuk <kukuk@thkukuk.de>
fclose (oldpf);
- if (found)
+ if (found && entry.old_passwords)
{
const char delimiters[] = ",";
char *running;
char *oldpass;
- running = strdupa (entry.old_passwords);
- if (running == NULL)
- return PAM_BUF_ERR;
+ running = entry.old_passwords;
do {
oldpass = strsep (&running, delimiters);
buflen = DEFAULT_BUFLEN;
buf = malloc (buflen);
if (buf == NULL)
- return PAM_BUF_ERR;
-
+ {
+ fclose (oldpf);
+ fclose (newpf);
+ retval = PAM_BUF_ERR;
+ goto error_opasswd;
+ }
}
buf[0] = '\0';
fgets (buf, buflen - 1, oldpf);
cp = buf;
save = strdup (buf); /* Copy to write the original data back. */
if (save == NULL)
- return PAM_BUF_ERR;
+ {
+ fclose (oldpf);
+ fclose (newpf);
+ retval = PAM_BUF_ERR;
+ goto error_opasswd;
+ }
if (n < 1)
break;
found = 1;
/* Don't save the current password twice */
- if (entry.old_passwords)
+ if (entry.old_passwords && entry.old_passwords[0] != '\0')
{
- /* there is only one password */
- if (strcmp (entry.old_passwords, oldpass) == 0)
- goto write_old_data;
- else
+ char *last = entry.old_passwords;
+
+ cp = entry.old_passwords;
+ entry.count = 1; /* Don't believe the count */
+ while ((cp = strchr (cp, ',')) != NULL)
{
- /* check last entry */
- cp = strstr (entry.old_passwords, oldpass);
-
- if (cp && strcmp (cp, oldpass) == 0)
- { /* the end is the same, check that there
- is a "," before. */
- --cp;
- if (*cp == ',')
- goto write_old_data;
- }
+ entry.count++;
+ last = ++cp;
}
+
+ /* compare the last password */
+ if (strcmp (last, oldpass) == 0)
+ goto write_old_data;
}
+ else
+ entry.count = 0;
/* increase count. */
entry.count++;
/* check that we don't remember to many passwords. */
- while (entry.count > howmany)
+ while (entry.count > howmany && entry.count > 1)
{
char *p = strpbrk (entry.old_passwords, ",");
if (p != NULL)
entry.count--;
}
- if (entry.old_passwords == NULL)
+ if (entry.count == 1)
{
if (asprintf (&out, "%s:%s:%d:%s\n",
entry.user, entry.uid, entry.count,
oldpass) < 0)
{
+ free (save);
retval = PAM_AUTHTOK_ERR;
fclose (oldpf);
fclose (newpf);
entry.user, entry.uid, entry.count,
entry.old_passwords, oldpass) < 0)
{
+ free (save);
retval = PAM_AUTHTOK_ERR;
fclose (oldpf);
fclose (newpf);
rename (opasswd_tmp, OLD_PASSWORDS_FILE);
error_opasswd:
unlink (opasswd_tmp);
+ free (buf);
return retval;
}