Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37746755
en ru br
ALT Linux repos
S:0.6.12.1-alt1

Group :: System/Base
RPM: pam_pkcs11

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: pam_pkcs11-0.6.9-setpin.patch
Download


 src/common/pkcs11_lib.c      |  34 +++-
 src/common/pkcs11_lib.h      |   3 +-
 src/pam_pkcs11/pam_pkcs11.c  | 403 +++++++++++++++++++++++++++++++++++--------
 src/tools/pkcs11_inspect.c   |   2 +-
 src/tools/pkcs11_listcerts.c |   2 +-
 src/tools/pklogin_finder.c   |   2 +-
 6 files changed, 361 insertions(+), 85 deletions(-)
diff --git a/src/common/pkcs11_lib.c b/src/common/pkcs11_lib.c
index 1ca184c..d548b6e 100644
--- a/src/common/pkcs11_lib.c
+++ b/src/common/pkcs11_lib.c
@@ -1401,21 +1401,29 @@ int wait_for_token(pkcs11_handle_t *h,
   return rv;
 }
 
-int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot)
+int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot, int rw)
 {
   int rv;
-
-  DBG1("opening a new PKCS #11 session for slot %d", slot + 1);
+  
+  DBG2("opening a new %s PKCS #11 session for slot %d",
+       rw ? "R/W" : "RO", slot + 1);
   if (slot >= h->slot_count) {
     set_error("invalid slot number %d", slot);
     return -1;
   }
-  /* open a readonly user-session */
-  rv = h->fl->C_OpenSession(h->slots[slot].id, CKF_SERIAL_SESSION, NULL, NULL, &h->session);
+  
+  unsigned int flags = CKF_SERIAL_SESSION;
+  if ( rw ) {
+    flags |= CKF_RW_SESSION;
+  }
+  DBG1("C_OpenSession flags: 0x%08lX", flags);
+  
+  rv = h->fl->C_OpenSession(h->slots[slot].id, flags, NULL, NULL, &h->session);
   if (rv != CKR_OK) {
     set_error("C_OpenSession() failed: 0x%08lX", rv);
     return -1;
   }
+
   h->current_slot = slot;
   return 0;
 }
@@ -1436,6 +1444,22 @@ int pkcs11_login(pkcs11_handle_t *h, char *password)
   return 0;
 }
 
+int pkcs11_setpin(pkcs11_handle_t *h, char *old_pass, char *new_pass)
+{
+    int rv;
+
+    rv = h->fl->C_SetPIN( h->session, old_pass, strlen(old_pass),
+                          new_pass, strlen(new_pass) );
+
+    if ( rv != CKR_OK ) {
+        DBG1("C_SetPIN() failed: 0x%08lX", rv);
+        set_error("C_SetPIN() failed: 0x%08lX", rv);
+        return -1;
+    } else {
+        return 0;
+    }
+}
+
 int get_slot_login_required(pkcs11_handle_t *h)
 {
   int rv;
diff --git a/src/common/pkcs11_lib.h b/src/common/pkcs11_lib.h
index 628caa1..3d8c277 100644
--- a/src/common/pkcs11_lib.h
+++ b/src/common/pkcs11_lib.h
@@ -54,7 +54,7 @@ PKCS11_EXTERN int wait_for_token_by_slotlabel(pkcs11_handle_t *h,
                                  unsigned int *slot);
 PKCS11_EXTERN const X509 *get_X509_certificate(cert_object_t *cert);
 PKCS11_EXTERN void release_pkcs11_module(pkcs11_handle_t *h);
-PKCS11_EXTERN int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot);
+PKCS11_EXTERN int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot, int rw);
 PKCS11_EXTERN int close_pkcs11_session(pkcs11_handle_t *h);
 PKCS11_EXTERN int pkcs11_login(pkcs11_handle_t *h, char *password);
 PKCS11_EXTERN int pkcs11_pass_login(pkcs11_handle_t *h, int nullok);
@@ -68,6 +68,7 @@ PKCS11_EXTERN int sign_value(pkcs11_handle_t *h, cert_object_t *,
                unsigned char *data, unsigned long length,
                unsigned char **signature, unsigned long *signature_length);
 PKCS11_EXTERN int get_random_value(unsigned char *data, int length);
+PKCS11_EXTERN int pkcs11_setpin(pkcs11_handle_t *h, char *old_pass, char *new_pass);
 
 #undef PKCS11_EXTERN
 
diff --git a/src/pam_pkcs11/pam_pkcs11.c b/src/pam_pkcs11/pam_pkcs11.c
index a8be0af..1e4b15c 100644
--- a/src/pam_pkcs11/pam_pkcs11.c
+++ b/src/pam_pkcs11/pam_pkcs11.c
@@ -149,7 +149,7 @@ static int pam_pkcs11_prompt(const pam_handle_t *pamh, int style, char **resp, c
 
 
 /*
- * Gets the users password. Depending whether it was already asked, either
+ * Gets the user password. Depending whether it was already asked, either
  * a prompt is shown or the old value is returned.
  */
 static int pam_get_pwd(pam_handle_t *pamh, char **pwd, char *text, int oitem, int nitem)
@@ -204,6 +204,163 @@ static int pam_get_pwd(pam_handle_t *pamh, char **pwd, char *text, int oitem, in
   return PAM_CRED_INSUFFICIENT;
 }
 
+static void _get_pwd_error( pam_handle_t *pamh,
+                            struct configuration_st *configuration,
+                            int rv )
+{
+    if (!configuration->quiet) {
+        pam_prompt(pamh, PAM_ERROR_MSG , NULL,
+                   _("Error 2316: password could not be read"));
+        sleep(configuration->err_display_time);
+    }
+    pam_syslog(pamh, LOG_ERR,
+               "pam_get_pwd() failed: %s", pam_strerror(pamh, rv));
+}
+
+static int check_pwd( pam_handle_t *pamh,
+                      struct configuration_st *configuration,
+                      char *password )
+{
+#ifdef DEBUG_SHOW_PASSWORD
+    DBG1("password = [%s]", password);
+#endif
+
+    /* check password length */
+    if ( !configuration->nullok && strlen(password) == 0 ) {
+        memset(password, 0, strlen(password));
+        pam_syslog(pamh, LOG_ERR,
+                   "password length is zero but the 'nullok' " \
+                   "argument was not defined.");
+        if (!configuration->quiet) {
+            pam_prompt(pamh, PAM_ERROR_MSG , NULL,
+                       _("Error 2318: Empty smartcard PIN not allowed."));
+            sleep(configuration->err_display_time);
+        }
+        return PAM_AUTH_ERR;
+    }
+
+    return 0;
+}
+
+static int pkcs11_module_load_init( pam_handle_t *pamh,
+                                    struct configuration_st *configuration,
+                                    pkcs11_handle_t **ph )
+{
+    int rv;
+    
+    /* load pkcs #11 module */
+    DBG("loading pkcs #11 module...");
+    rv = load_pkcs11_module(configuration->pkcs11_modulepath, ph);
+    
+    if (rv != 0) {
+        ERR2("load_pkcs11_module() failed loading %s: %s",
+             configuration->pkcs11_modulepath, get_error());
+        if (!configuration->quiet) {
+            pam_syslog(pamh, LOG_ERR,
+                       "load_pkcs11_module() failed loading %s: %s",
+                       configuration->pkcs11_modulepath, get_error());
+            pam_prompt(pamh, PAM_ERROR_MSG , NULL,
+                       _("Error 2302: PKCS#11 module failed loading"));
+            sleep(configuration->err_display_time);
+        }
+        return PAM_AUTHINFO_UNAVAIL;
+    }
+
+    /* initialise pkcs #11 module */
+    DBG("initializing pkcs #11 module...");
+    rv = init_pkcs11_module( *ph, configuration->support_threads );
+
+    if (rv != 0) {
+        release_pkcs11_module( *ph );
+        ERR1("init_pkcs11_module() failed: %s", get_error());
+        if (!configuration->quiet) {
+            pam_syslog(pamh, LOG_ERR,
+                       "init_pkcs11_module() failed: %s",
+                       get_error());
+            pam_prompt(pamh, PAM_ERROR_MSG , NULL,
+                       _("Error 2304: PKCS#11 module could not be initialized"));
+            sleep(configuration->err_display_time);
+        }
+        return PAM_AUTHINFO_UNAVAIL;
+    }
+
+    return rv;
+}
+
+static int pkcs11_find_slot( pam_handle_t *pamh,
+                             struct configuration_st *configuration,
+                             const char *login_token_name,
+                             pkcs11_handle_t *ph,
+                             unsigned int *slot_num )
+{
+    int rv = -1;
+    
+    if (configuration->slot_description != NULL) {
+        rv = find_slot_by_slotlabel_and_tokenlabel(
+                 ph,
+                 configuration->slot_description,
+                 login_token_name,
+                 slot_num
+        );
+    } else if (configuration->slot_num != -1) {
+        rv = find_slot_by_number_and_label(ph, configuration->slot_num,
+                                           login_token_name, slot_num);
+    }
+
+    if (rv != 0) {
+        ERR("no suitable token available");
+        if (!configuration->quiet) {
+            pam_syslog(pamh, LOG_ERR, "no suitable token available");
+            pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2306: No suitable token available"));
+            sleep(configuration->err_display_time);
+        }
+    }
+
+    return rv;
+}
+
+static int pkcs11_open_session( pam_handle_t *pamh,
+                                struct configuration_st *configuration,
+                                pkcs11_handle_t *ph,
+                                unsigned int slot_num,
+                                int rw )
+{
+    int rv;
+    
+    rv = open_pkcs11_session( ph, slot_num, rw );
+    
+    if (rv != 0) {
+        ERR1("open_pkcs11_session() failed: %s", get_error());
+        if (!configuration->quiet) {
+            pam_syslog(pamh, LOG_ERR, "open_pkcs11_session() failed: %s", get_error());
+            pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2312: open PKCS#11 session failed"));
+            sleep(configuration->err_display_time);
+        }
+    }
+
+    return rv;
+}
+
+static int pkcs11_close_session( pam_handle_t *pamh,
+                                 struct configuration_st *configuration,
+                                 pkcs11_handle_t *ph )
+{
+    int rv;
+
+    rv = close_pkcs11_session(ph);
+    
+    if (rv != 0) {
+        ERR1("close_pkcs11_session() failed: %s", get_error());
+		if (!configuration->quiet) {
+			pam_syslog(pamh, LOG_ERR, "close_pkcs11_module() failed: %s", get_error());
+			pam_prompt(pamh, PAM_ERROR_MSG , NULL, ("Error 2344: Closing PKCS#11 session failed"));
+			sleep(configuration->err_display_time);
+		}
+    }
+
+    return rv;
+}
+
 PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
 {
   int i, rv;
@@ -342,43 +499,12 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, cons
     return PAM_IGNORE;
   }
 
-  /* load pkcs #11 module */
-  DBG("loading pkcs #11 module...");
-  rv = load_pkcs11_module(configuration->pkcs11_modulepath, &ph);
-  if (rv != 0) {
-    ERR2("load_pkcs11_module() failed loading %s: %s",
-		configuration->pkcs11_modulepath, get_error());
-    if (!configuration->quiet) {
-		pam_syslog(pamh, LOG_ERR, "load_pkcs11_module() failed loading %s: %s",
-			configuration->pkcs11_modulepath, get_error());
-		pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2302: PKCS#11 module failed loading"));
-		sleep(configuration->err_display_time);
-	}
-    return PAM_AUTHINFO_UNAVAIL;
-  }
-
-  /* initialise pkcs #11 module */
-  DBG("initialising pkcs #11 module...");
-  rv = init_pkcs11_module(ph,configuration->support_threads);
-  if (rv != 0) {
-    release_pkcs11_module(ph);
-    ERR1("init_pkcs11_module() failed: %s", get_error());
-    if (!configuration->quiet) {
-		pam_syslog(pamh, LOG_ERR, "init_pkcs11_module() failed: %s", get_error());
-		pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2304: PKCS#11 module could not be initialized"));
-		sleep(configuration->err_display_time);
-	}
-    return PAM_AUTHINFO_UNAVAIL;
+  rv = pkcs11_module_load_init( pamh, configuration, &ph );
+  if ( rv != 0 ) {
+      return rv;
   }
 
-  /* open pkcs #11 session */
-  if (configuration->slot_description != NULL) {
-    rv = find_slot_by_slotlabel_and_tokenlabel(ph,
-      configuration->slot_description, login_token_name, &slot_num);
-  } else if (configuration->slot_num != -1) {
-    rv = find_slot_by_number_and_label(ph, configuration->slot_num,
-                                     login_token_name, &slot_num);
-  }
+  rv = pkcs11_find_slot( pamh, configuration, login_token_name, ph, &slot_num );
 
   if (!configuration->card_only || !login_token_name) {
 	  /* Allow to pass to the next module if the auth isn't
@@ -462,14 +588,9 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, cons
       pam_prompt(pamh, PAM_TEXT_INFO, NULL,
 		  _("%s found."), _(configuration->token_type));
   }
-  rv = open_pkcs11_session(ph, slot_num);
+
+  rv = pkcs11_open_session( pamh, configuration, ph, slot_num, 0 );
   if (rv != 0) {
-    ERR1("open_pkcs11_session() failed: %s", get_error());
-    if (!configuration->quiet) {
-		pam_syslog(pamh, LOG_ERR, "open_pkcs11_session() failed: %s", get_error());
-		pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2312: open PKCS#11 session failed"));
-		sleep(configuration->err_display_time);
-	}
     release_pkcs11_module(ph);
     return pkcs11_pam_fail;
   }
@@ -676,31 +797,17 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, cons
 		} else {
 			rv = pam_get_pwd(pamh, &password, password_prompt, 0, PAM_AUTHTOK);
 		}
+        
 		if (rv != PAM_SUCCESS) {
-			if (!configuration->quiet) {
-				pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2316: password could not be read"));
-				sleep(configuration->err_display_time);
-			}
+            _get_pwd_error( pamh, configuration, rv );
 			release_pkcs11_module(ph);
-			pam_syslog(pamh, LOG_ERR,
-					"pam_get_pwd() failed: %s", pam_strerror(pamh, rv));
 			return pkcs11_pam_fail;
 		}
-#ifdef DEBUG_SHOW_PASSWORD
-		DBG1("password = [%s]", password);
-#endif
 
-		/* check password length */
-		if (!configuration->nullok && strlen(password) == 0) {
+        rv = check_pwd( pamh, configuration, password );
+		if ( rv != 0) {
 			release_pkcs11_module(ph);
-			memset(password, 0, strlen(password));
 			free(password);
-			pam_syslog(pamh, LOG_ERR,
-					"password length is zero but the 'nullok' argument was not defined.");
-			if (!configuration->quiet) {
-				pam_prompt(pamh, PAM_ERROR_MSG , NULL, _("Error 2318: Empty smartcard PIN not allowed."));
-				sleep(configuration->err_display_time);
-			}
 			return PAM_AUTH_ERR;
 		}
 	}
@@ -865,15 +972,9 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, cons
   unload_mappers();
 
   /* close pkcs #11 session */
-  rv = close_pkcs11_session(ph);
+  rv = pkcs11_close_session( pamh, configuration, ph );
   if (rv != 0) {
     release_pkcs11_module(ph);
-    ERR1("close_pkcs11_session() failed: %s", get_error());
-		if (!configuration->quiet) {
-			pam_syslog(pamh, LOG_ERR, "close_pkcs11_module() failed: %s", get_error());
-			pam_prompt(pamh, PAM_ERROR_MSG , NULL, ("Error 2344: Closing PKCS#11 session failed"));
-			sleep(configuration->err_display_time);
-		}
     return pkcs11_pam_fail;
   }
 
@@ -936,16 +1037,166 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const c
 {
   char *login_token_name;
 
-  ERR("Warning: Function pam_sm_chauthtok() is not implemented in this module");
-  pam_syslog(pamh, LOG_WARNING,
-             "Function pam_sm_chauthtok() is not implemented in this module");
-
   login_token_name = getenv("PKCS11_LOGIN_TOKEN_NAME");
-  if (login_token_name && (flags & PAM_PRELIM_CHECK)) {
-    pam_prompt(pamh, PAM_TEXT_INFO, NULL,
-               _("Cannot change the password on your smart card."));
+  if (login_token_name) {
+      char *old_pass;
+      char *new_pass;
+      int rv; unsigned int slot_num;
+      struct configuration_st *configuration;
+      pkcs11_handle_t *ph;
+      
+      if (flags & PAM_PRELIM_CHECK) {
+          return PAM_SUCCESS;
+      }
+
+      configuration = pk_configure(argc,argv);
+      if (!configuration ) {
+          ERR("Error setting configuration parameters");
+          return PAM_AUTHINFO_UNAVAIL;
+      }
+      
+      rv = pkcs11_module_load_init( pamh, configuration, &ph );
+      if ( rv != 0 ) {
+          return rv;
+      }
+
+      rv = pkcs11_find_slot( pamh, configuration, login_token_name, ph, &slot_num );
+      if ( rv != 0 ) {
+          release_pkcs11_module(ph);
+          if ( configuration->card_only ) {
+              return PAM_AUTHINFO_UNAVAIL;
+          } else {
+              return PAM_IGNORE;
+          }
+      }
+
+      rv = pkcs11_open_session( pamh, configuration, ph, slot_num, 1 );
+      if (rv != 0) {
+          release_pkcs11_module(ph);
+          return PAM_AUTHINFO_UNAVAIL;
+      }
+
+      rv = get_slot_protected_authentication_path( ph );
+      if ((-1 == rv) || (0 == rv)) {
+          /* no CKF_PROTECTED_AUTHENTICATION_PATH */
+          char password_prompt[128];
+          char *confirm;
+
+          /* Old PIN */
+          snprintf(password_prompt, sizeof(password_prompt),
+                   _("Old %s PIN: "), _(configuration->token_type));
+          rv = pam_get_pwd(pamh, &old_pass, password_prompt,
+                           0, PAM_AUTHTOK);
+
+          if (rv != PAM_SUCCESS) {
+              _get_pwd_error( pamh, configuration, rv );
+              release_pkcs11_module(ph);
+              return PAM_AUTHTOK_RECOVERY_ERR;
+          }
+
+          rv = check_pwd( pamh, configuration, old_pass );
+          if ( rv != 0 ) {
+              release_pkcs11_module(ph);
+              free(old_pass);
+              return PAM_AUTHTOK_RECOVERY_ERR;
+          }
+
+          /* New PIN */
+          snprintf(password_prompt, sizeof(password_prompt),
+                   _("New %s PIN: "), _(configuration->token_type));
+          rv = pam_get_pwd(pamh, &new_pass, password_prompt,
+                           0, PAM_AUTHTOK);
+          
+          if (rv != PAM_SUCCESS) {
+              _get_pwd_error( pamh, configuration, rv );
+              release_pkcs11_module(ph);
+              return PAM_AUTHTOK_ERR;
+          }
+
+          rv = check_pwd( pamh, configuration, new_pass );
+          if ( rv != 0 ) {
+              release_pkcs11_module(ph);
+              memset( old_pass, 0, strlen(old_pass) );
+              free( old_pass );
+              free( new_pass );
+              return PAM_AUTHTOK_ERR;
+          }
+
+          /* Confirm new PIN */
+          snprintf(password_prompt, sizeof(password_prompt),
+                   _("Confirm new PIN: "));
+          rv = pam_get_pwd(pamh, &confirm, password_prompt,
+                           0, PAM_AUTHTOK);
+          
+          if (rv != PAM_SUCCESS) {
+              _get_pwd_error( pamh, configuration, rv );
+              release_pkcs11_module(ph);
+              memset( old_pass, 0, strlen(old_pass) );
+              free( old_pass );
+              memset( new_pass, 0, strlen(new_pass) );
+              free( new_pass );
+              return PAM_AUTHTOK_ERR;
+          }
+
+          if ( strcmp(new_pass, confirm) != 0 ) {
+              ERR("Confirm PIN mismatch");
+              if (!configuration->quiet) {
+                  pam_syslog(pamh, LOG_ERR, "Confirm PIN mismatch");
+                  pam_prompt(pamh, PAM_ERROR_MSG , NULL,
+                             _("Confirm PIN mismatch"));
+                  sleep(configuration->err_display_time);
+              }
+              release_pkcs11_module(ph);
+              memset( old_pass, 0, strlen(old_pass) );              
+              free( old_pass );
+              memset( new_pass, 0, strlen(new_pass) );
+              free( new_pass );
+              memset( confirm, 0, strlen(confirm) );
+              free( confirm );
+              return PAM_AUTHTOK_ERR;
+          } else {
+              memset( confirm, 0, strlen(confirm) );
+              free( confirm );
+          }
+      } else {
+          pam_prompt(pamh, PAM_TEXT_INFO, NULL,
+                     _("Now use the pinpad to change your %s PIN"),
+                     _(configuration->token_type));
+          old_pass = NULL;
+          new_pass = NULL;
+      }
+
+      rv = pkcs11_login( ph, old_pass );
+      if ( rv == 0 ) {
+          rv = pkcs11_setpin( ph, old_pass, new_pass );
+      }
+      pkcs11_close_session( pamh, configuration, ph );
+      release_pkcs11_module( ph );
+
+      if ( old_pass ) {
+          memset( old_pass, 0, strlen(old_pass) );              
+          free( old_pass );
+      }
+      if ( new_pass) {
+          memset( new_pass, 0, strlen(new_pass) );
+          free( new_pass );
+      }
+
+      if ( rv == 0 ) {
+          return PAM_SUCCESS;
+      } else {
+          ERR("C_SetPIN error");
+          if (!configuration->quiet) {
+              pam_syslog(pamh, LOG_ERR, "C_SetPIN error");
+              pam_prompt(pamh, PAM_ERROR_MSG , NULL,
+                         _("Error: Unable to set new PIN"));
+              sleep(configuration->err_display_time);
+          }
+          return PAM_AUTHTOK_ERR;
+      }
+  } else {
+      return PAM_IGNORE;
   }
-  return PAM_SERVICE_ERR;
 }
 
 #ifdef PAM_STATIC
diff --git a/src/tools/pkcs11_inspect.c b/src/tools/pkcs11_inspect.c
index 6aac407..3cc0021 100644
--- a/src/tools/pkcs11_inspect.c
+++ b/src/tools/pkcs11_inspect.c
@@ -96,7 +96,7 @@ int main(int argc, const char **argv) {
     return 1;
   }
 
-  rv = open_pkcs11_session(ph, slot_num);
+  rv = open_pkcs11_session(ph, slot_num, 0);
   if (rv != 0) {
     release_pkcs11_module(ph);
     ERR1("open_pkcs11_session() failed: %s", get_error());
diff --git a/src/tools/pkcs11_listcerts.c b/src/tools/pkcs11_listcerts.c
index 726addf..e8b693a 100644
--- a/src/tools/pkcs11_listcerts.c
+++ b/src/tools/pkcs11_listcerts.c
@@ -95,7 +95,7 @@ int main(int argc, const char **argv) {
     return 1;
   }
 
-  rv = open_pkcs11_session(ph, slot_num);
+  rv = open_pkcs11_session(ph, slot_num, 0);
   if (rv != 0) {
     release_pkcs11_module(ph);
     DBG1("open_pkcs11_session() failed: %s", get_error());
diff --git a/src/tools/pklogin_finder.c b/src/tools/pklogin_finder.c
index 9ef04b9..e03b131 100644
--- a/src/tools/pklogin_finder.c
+++ b/src/tools/pklogin_finder.c
@@ -95,7 +95,7 @@ int main(int argc, const char **argv) {
     DBG("no token available");
     return 1;
   }
-  rv = open_pkcs11_session(ph, slot_num);
+  rv = open_pkcs11_session(ph, slot_num, 0);
   if (rv != 0) {
     release_pkcs11_module(ph);
     DBG1("open_pkcs11_session() failed: %s", get_error());
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin