diff --git a/liboath/global.c b/liboath/global.c
index 89c18c5..7fc7b8a 100644
--- a/liboath/global.c
+++ b/liboath/global.c
@@ -25,9 +25,12 @@
 
 #include <stdio.h>		/* For snprintf, getline. */
 #include <string.h>		/* For strverscmp. */
+#include <stdlib.h>		/* 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 5e31cef..436cd65 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 9d1a277..7ceeaa7 100644
--- a/liboath/oath.h
+++ b/liboath/oath.h
@@ -136,11 +136,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 8654342..17fddd3 100644
--- a/liboath/oath.h.in
+++ b/liboath/oath.h.in
@@ -136,11 +136,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 9da30fe..d9bd943 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 89310b5..def004f 100644
--- a/pam_oath/pam_oath.c
+++ b/pam_oath/pam_oath.c
@@ -70,6 +70,7 @@ struct cfg
   int try_first_pass;
   int use_first_pass;
   char *usersfile;
+  char *lockfile;
   unsigned digits;
   unsigned window;
 };
@@ -84,6 +85,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;
 
@@ -99,6 +101,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)
@@ -124,6 +128,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));
     }
@@ -209,6 +214,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);
