summaryrefslogtreecommitdiff
path: root/modules/pam_pwhistory/opasswd.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/pam_pwhistory/opasswd.c')
-rw-r--r--modules/pam_pwhistory/opasswd.c78
1 files changed, 49 insertions, 29 deletions
diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c
index a6cd3d2a..859b3da4 100644
--- a/modules/pam_pwhistory/opasswd.c
+++ b/modules/pam_pwhistory/opasswd.c
@@ -44,6 +44,7 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
@@ -67,6 +68,7 @@
#include <security/pam_ext.h>
#endif
#include <security/pam_modules.h>
+#include "pam_inline.h"
#include "opasswd.h"
@@ -74,8 +76,7 @@
#define RANDOM_DEVICE "/dev/urandom"
#endif
-#define OLD_PASSWORDS_FILE "/etc/security/opasswd"
-#define TMP_PASSWORDS_FILE OLD_PASSWORDS_FILE".tmpXXXXXX"
+#define DEFAULT_OLD_PASSWORDS_FILE SCONFIGDIR "/opasswd"
#define DEFAULT_BUFLEN 4096
@@ -129,6 +130,7 @@ compare_password(const char *newpass, const char *oldpass)
char *outval;
#ifdef HAVE_CRYPT_R
struct crypt_data output;
+ int retval;
output.initialized = 0;
@@ -137,12 +139,14 @@ compare_password(const char *newpass, const char *oldpass)
outval = crypt (newpass, oldpass);
#endif
- return outval != NULL && strcmp(outval, oldpass) == 0;
+ retval = outval != NULL && strcmp(outval, oldpass) == 0;
+ pam_overwrite_string(outval);
+ return retval;
}
/* Check, if the new password is already in the opasswd file. */
PAMH_ARG_DECL(int
-check_old_pass, const char *user, const char *newpass, int debug)
+check_old_pass, const char *user, const char *newpass, const char *filename, int debug)
{
int retval = PAM_SUCCESS;
FILE *oldpf;
@@ -156,10 +160,13 @@ check_old_pass, const char *user, const char *newpass, int debug)
return PAM_PWHISTORY_RUN_HELPER;
#endif
- if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL)
+ const char *opasswd_file =
+ (filename != NULL ? filename : DEFAULT_OLD_PASSWORDS_FILE);
+
+ if ((oldpf = fopen (opasswd_file, "r")) == NULL)
{
if (errno != ENOENT)
- pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", OLD_PASSWORDS_FILE);
+ pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", opasswd_file);
return PAM_SUCCESS;
}
@@ -235,16 +242,15 @@ check_old_pass, const char *user, const char *newpass, int debug)
} while (oldpass != NULL);
}
- if (buf)
- free (buf);
+ pam_overwrite_n(buf, buflen);
+ free (buf);
return retval;
}
PAMH_ARG_DECL(int
-save_old_pass, const char *user, int howmany, int debug UNUSED)
+save_old_pass, const char *user, int howmany, const char *filename, int debug UNUSED)
{
- char opasswd_tmp[] = TMP_PASSWORDS_FILE;
struct stat opasswd_stat;
FILE *oldpf, *newpf;
int newpf_fd;
@@ -256,6 +262,15 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
struct passwd *pwd;
const char *oldpass;
+ /* Define opasswd file and temp file for opasswd */
+ const char *opasswd_file =
+ (filename != NULL ? filename : DEFAULT_OLD_PASSWORDS_FILE);
+ char opasswd_tmp[PATH_MAX];
+
+ if ((size_t) snprintf (opasswd_tmp, sizeof (opasswd_tmp), "%s.tmpXXXXXX",
+ opasswd_file) >= sizeof (opasswd_tmp))
+ return PAM_BUF_ERR;
+
pwd = pam_modutil_getpwnam (pamh, user);
if (pwd == NULL)
return PAM_USER_UNKNOWN;
@@ -285,24 +300,22 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
if (oldpass == NULL || *oldpass == '\0')
return PAM_SUCCESS;
- if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL)
+ if ((oldpf = fopen (opasswd_file, "r")) == NULL)
{
if (errno == ENOENT)
{
- pam_syslog (pamh, LOG_NOTICE, "Creating %s",
- OLD_PASSWORDS_FILE);
+ pam_syslog (pamh, LOG_NOTICE, "Creating %s", opasswd_file);
do_create = 1;
}
else
{
- pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m",
- OLD_PASSWORDS_FILE);
+ pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", opasswd_file);
return PAM_AUTHTOK_ERR;
}
}
else if (fstat (fileno (oldpf), &opasswd_stat) < 0)
{
- pam_syslog (pamh, LOG_ERR, "Cannot stat %s: %m", OLD_PASSWORDS_FILE);
+ pam_syslog (pamh, LOG_ERR, "Cannot stat %s: %m", opasswd_file);
fclose (oldpf);
return PAM_AUTHTOK_ERR;
}
@@ -312,7 +325,7 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
if (newpf_fd == -1)
{
pam_syslog (pamh, LOG_ERR, "Cannot create %s temp file: %m",
- OLD_PASSWORDS_FILE);
+ opasswd_file);
if (oldpf)
fclose (oldpf);
return PAM_AUTHTOK_ERR;
@@ -321,23 +334,19 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
{
if (fchmod (newpf_fd, S_IRUSR|S_IWUSR) != 0)
pam_syslog (pamh, LOG_ERR,
- "Cannot set permissions of %s temp file: %m",
- OLD_PASSWORDS_FILE);
+ "Cannot set permissions of %s temp file: %m", opasswd_file);
if (fchown (newpf_fd, 0, 0) != 0)
pam_syslog (pamh, LOG_ERR,
- "Cannot set owner/group of %s temp file: %m",
- OLD_PASSWORDS_FILE);
+ "Cannot set owner/group of %s temp file: %m", opasswd_file);
}
else
{
if (fchmod (newpf_fd, opasswd_stat.st_mode) != 0)
pam_syslog (pamh, LOG_ERR,
- "Cannot set permissions of %s temp file: %m",
- OLD_PASSWORDS_FILE);
+ "Cannot set permissions of %s temp file: %m", opasswd_file);
if (fchown (newpf_fd, opasswd_stat.st_uid, opasswd_stat.st_gid) != 0)
pam_syslog (pamh, LOG_ERR,
- "Cannot set owner/group of %s temp file: %m",
- OLD_PASSWORDS_FILE);
+ "Cannot set owner/group of %s temp file: %m", opasswd_file);
}
newpf = fdopen (newpf_fd, "w+");
if (newpf == NULL)
@@ -514,6 +523,7 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
}
if (fputs (out, newpf) < 0)
{
+ pam_overwrite_string(out);
free (out);
retval = PAM_AUTHTOK_ERR;
if (oldpf)
@@ -521,6 +531,7 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
fclose (newpf);
goto error_opasswd;
}
+ pam_overwrite_string(out);
free (out);
}
@@ -550,14 +561,23 @@ save_old_pass, const char *user, int howmany, int debug UNUSED)
goto error_opasswd;
}
- unlink (OLD_PASSWORDS_FILE".old");
- if (link (OLD_PASSWORDS_FILE, OLD_PASSWORDS_FILE".old") != 0 &&
+ char opasswd_backup[PATH_MAX];
+ if ((size_t) snprintf (opasswd_backup, sizeof (opasswd_backup), "%s.old",
+ opasswd_file) >= sizeof (opasswd_backup))
+ {
+ retval = PAM_BUF_ERR;
+ goto error_opasswd;
+ }
+
+ unlink (opasswd_backup);
+ if (link (opasswd_file, opasswd_backup) != 0 &&
errno != ENOENT)
pam_syslog (pamh, LOG_ERR, "Cannot create backup file of %s: %m",
- OLD_PASSWORDS_FILE);
- rename (opasswd_tmp, OLD_PASSWORDS_FILE);
+ opasswd_file);
+ rename (opasswd_tmp, opasswd_file);
error_opasswd:
unlink (opasswd_tmp);
+ pam_overwrite_n(buf, buflen);
free (buf);
return retval;