diff --git a/liboath/global.c b/liboath/global.c index d442cf3..cfe1cee 100644 --- a/liboath/global.c +++ b/liboath/global.c @@ -25,9 +25,12 @@ #include /* For snprintf, getline. */ #include /* For strverscmp. */ +#include /* For free. */ #include "gc.h" +char *oath_lockfile_path = NULL; + /** * oath_init: * @@ -52,6 +55,8 @@ oath_init (void) if (gc_init () != GC_OK) return OATH_CRYPTO_ERROR; + oath_lockfile_path = NULL; + return OATH_OK; } @@ -71,6 +76,11 @@ oath_done (void) { gc_done (); + if (oath_lockfile_path) + { + free(oath_lockfile_path); + oath_lockfile_path = NULL; + } return OATH_OK; } @@ -99,3 +109,23 @@ oath_check_version (const char *req_version) return NULL; } + +int +oath_set_lockfile_path(const char *lockfile) +{ + int l; + + if (oath_lockfile_path) + { + free(oath_lockfile_path); + oath_lockfile_path = NULL; + } + + if (lockfile) + { + l = asprintf (&oath_lockfile_path, "%s", lockfile); + if (oath_lockfile_path == NULL || ((size_t) l) != strlen (lockfile)) + return OATH_PRINTF_ERROR; + } + return OATH_OK; +} diff --git a/liboath/liboath.map b/liboath/liboath.map index 2f247ff..e8f8cdf 100644 --- a/liboath/liboath.map +++ b/liboath/liboath.map @@ -75,6 +75,7 @@ LIBOATH_2.2.0 global: oath_totp_validate3; oath_totp_validate3_callback; + oath_set_lockfile_path; } LIBOATH_1.12.0; LIBOATH_2.6.0 diff --git a/liboath/oath.h b/liboath/oath.h index fe93b9e..6660fb3 100644 --- a/liboath/oath.h +++ b/liboath/oath.h @@ -159,11 +159,15 @@ typedef enum /* Global */ +extern char *oath_lockfile_path; + extern OATHAPI int oath_init (void); extern OATHAPI int oath_done (void); extern OATHAPI const char *oath_check_version (const char *req_version); +extern OATHAPI int oath_set_lockfile_path(const char *lockfile); + /* Error handling */ extern OATHAPI const char *oath_strerror (int err); diff --git a/liboath/oath.h.in b/liboath/oath.h.in index eee284c..536cd30 100644 --- a/liboath/oath.h.in +++ b/liboath/oath.h.in @@ -159,11 +159,15 @@ typedef enum /* Global */ +extern char *oath_lockfile_path; + extern OATHAPI int oath_init (void); extern OATHAPI int oath_done (void); extern OATHAPI const char *oath_check_version (const char *req_version); +extern OATHAPI int oath_set_lockfile_path(const char *lockfile); + /* Error handling */ extern OATHAPI const char *oath_strerror (int err); diff --git a/liboath/usersfile.c b/liboath/usersfile.c index ef03f39..7cc4347 100644 --- a/liboath/usersfile.c +++ b/liboath/usersfile.c @@ -323,9 +323,18 @@ update_usersfile (const char *usersfile, { int l; - l = asprintf (&lockfile, "%s.lock", usersfile); - if (lockfile == NULL || ((size_t) l) != strlen (usersfile) + 5) - return OATH_PRINTF_ERROR; + if (oath_lockfile_path) + { + l = asprintf (&lockfile, "%s", oath_lockfile_path); + if (lockfile == NULL || ((size_t) l) != strlen (oath_lockfile_path)) + return OATH_PRINTF_ERROR; + } + else + { + l = asprintf (&lockfile, "%s.lock", usersfile); + if (lockfile == NULL || ((size_t) l) != strlen (usersfile) + 5) + return OATH_PRINTF_ERROR; + } lockfh = fopen (lockfile, "w"); if (!lockfh) diff --git a/pam_oath/pam_oath.c b/pam_oath/pam_oath.c index b2afed7..307ffc2 100644 --- a/pam_oath/pam_oath.c +++ b/pam_oath/pam_oath.c @@ -75,6 +75,7 @@ struct cfg int try_first_pass; int use_first_pass; char *usersfile; + char *lockfile; unsigned digits; unsigned window; }; @@ -89,6 +90,7 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg) cfg->try_first_pass = 0; cfg->use_first_pass = 0; cfg->usersfile = NULL; + cfg->lockfile = NULL; cfg->digits = -1; cfg->window = 5; @@ -104,6 +106,8 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg) cfg->use_first_pass = 1; if (strncmp (argv[i], "usersfile=", 10) == 0) cfg->usersfile = (char *) argv[i] + 10; + if (strncmp (argv[i], "lockfile=", 9) == 0) + cfg->lockfile = (char *) argv[i] + 9; if (strncmp (argv[i], "digits=", 7) == 0) cfg->digits = atoi (argv[i] + 7); if (strncmp (argv[i], "window=", 7) == 0) @@ -129,6 +133,7 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg) D (("try_first_pass=%d", cfg->try_first_pass)); D (("use_first_pass=%d", cfg->use_first_pass)); D (("usersfile=%s", cfg->usersfile ? cfg->usersfile : "(null)")); + D (("lockfile=%s", cfg->lockfile ? cfg->lockfile : "(null)")); D (("digits=%d", cfg->digits)); D (("window=%d", cfg->window)); } @@ -327,6 +332,17 @@ pam_sm_authenticate (pam_handle_t * pamh, goto done; } + if (cfg.lockfile) + rc = oath_set_lockfile_path(cfg.lockfile); + else + rc = oath_set_lockfile_path("/var/lock/pam_oath.lock"); + if (rc != OATH_OK) + { + DBG (("oath_set_lockfile_path() failed (%d)", rc)); + retval = PAM_AUTHINFO_UNAVAIL; + goto done; + } + if (password == NULL) { retval = pam_get_item (pamh, PAM_CONV, (const void **) &conv);