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
[email protected]
http://www.opensc-project.org/mailman/listinfo/opensc-devel