Hello!

pwent_mapper_find_user() searches through all available passwd db entries to 
find an user.
This takes a very long time, if you have many users (10000). Additionally, if 
you have nss-ldap
configured, it transfers a large amount of data (which is expensive on mobile 
connections...). 

Included you find a patch to speed up user finding for the pwent_mapper. It 
first tries to find a user
directly by calling getpwnam() with the found CN. If this fails, the old 
mechanism is used.
(I think the second step could probably even be removed: I can't find a 
situation where the getpwnam()
does not work.)

Please have a look at the patch. If it's OK please include it in further 
pam_pkcs11 releases (so I
don't have to patch every new pam_pkcs11 release on my own ;-) ).

Kind regards
Dominik Fischer


---8<-----8<----

Index: src/mappers/pwent_mapper.c
===================================================================
--- src/mappers/pwent_mapper.c  (Revision 488)
+++ src/mappers/pwent_mapper.c  (Arbeitskopie)
@@ -64,29 +64,45 @@
 parses the certificate and return the _first_ CN entry found, or NULL
 */
 static char * pwent_mapper_find_user(X509 *x509,void *context, int *match) {
-        char *str;
+       char *str;
+       struct passwd *pw;
        char *found_user = NULL;
-        char **entries  = cert_info(x509,CERT_CN,ALGORITHM_NULL);
-        if (!entries) {
-            DBG("get_common_name() failed");
-            return NULL;
-        }
-        /* parse list of uids until match */
-        for (str=*entries; str ; str=*++entries) {
-            DBG1("trying to find pw_entry for cn '%s'",str);
-           found_user= search_pw_entry((const char *)str,ignorecase);
-            if (!found_user) {
-                DBG1("CN entry '%s' not found in pw database. Trying 
next",str);
-                continue;
-            } else {
-                DBG1("Found CN in pw database for user '%s'",found_user);
-               *match = 1;
-               /* WJG: Usually allocated mem is returned - memleak/problem? */
-               return found_user;
-           }
-        }
+       char **entries  = cert_info(x509,CERT_CN,ALGORITHM_NULL);
+       if (!entries) {
+               DBG("get_common_name() failed");
+               return NULL;
+       }
+       DBG1("trying to find pw_entry for cn '%s'",str);
+       /* First: direct try to avoid long searchtime or massive network traffic
+        * for large amount of users in pw database.
+        * (Think of 10000 or more users, mobile connection to ldap, etc.) 
+        */
+       for (str=*entries; str ; str=*++entries) {
+               pw = getpwnam(str);
+               if (pw == NULL) {
+                       DBG1("Entry for %s not found (direct).", (const char *) 
str);
+               } else {
+                       DBG1("Found CN in pw database for user %s (direct).", 
(const char *) str);
+                       return pw->pw_name;
+               }
+       }
+
+       /* Second: search all entries (old behaviour) */
+       /* parse list of uids until match */
+       for (str=*entries; str ; str=*++entries) {
+               found_user = search_pw_entry((const char *)str,ignorecase);
+               if (!found_user) {
+                       DBG1("CN entry '%s' not found in pw database. Trying 
next",str);
+                       continue;
+               } else {
+                       DBG1("Found CN in pw database for user 
'%s'",found_user);
+                       *match = 1;
+                       /* WJG: Usually allocated mem is returned - 
memleak/problem? */
+                       return found_user;
+               }
+       }
        DBG("No pw entry maps to any provided Common Name");
-        return NULL;
+       return NULL;
 }
 
 /*

_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to