I know this is years and years later, but we recently ran into this as well.

In our case, I'm not connecting to different servers, but we do want to stack different pam_filters.

The relevant bits from pam.d/common-account look like this:
account [success=1 default=ignore] pam_unix.so
account required pam_ldap.so config=/etc/pam_ldap.conf
account required pam_permit.so

For instance, we'd like to be able to stack our pam.d/sudo file (or whatever) like so, so that the stuff above is executed first, then the stuff below:

# Include the typical unix and ldap rules from common-account
@include common-account
# Then a subset of them that uses a different pam_filter in it's conf.
# Still skip ldap if unix auth succeeds:
account [success=1 default=ignore] pam_unix.so
account required pam_ldap.so config=/etc/pam_ldap.conf.sudo
account required pam_permit.so

The relevant difference in pam_ldap.conf's look like this:

# pam_ldap.conf
pam_filter acl=unix-server

# pam_ldap.conf.sudo
pam_filter acl=sudo


Now, why not just make an "&(...)" filter in a single pam_ldap.conf, you ask? Well, we have at least a dozen different kinds of default pam_ldap.conf files for various service hosts (mail, labs, etc.), and we may wish to tack on extra requirements for multiple different services for each of these (eg: cron, sudo, etc.). Combining all of those together with various other constraints could lead to hundreds of combinations. So, we'd prefer to stack them, as pam intended :)

The trouble is that currently the second set is just ignored since pam caches the config file details. From the pam_ldap.conf man page:

config=<path>
Specifies that pam_ldap should use the configuration file in path instead of pam_ldap.conf to retrieve its global configuration. Configuring multiple instances of pam_ldap for the same service with different configuration files is not supported, because the configuration information is cached.

I've tested the attached hackish patch and it seems to correctly work around this issue by forcing a reload of the config when the previously cached value doesn't match. I think it should also work for different ldap servers, though I haven't tested it.

I'd love to see something like this pulled in by Debian or even upstream.

Let me know if you have any questions.

Thanks,
Brian
--- pam_ldap.c.orig	2012-08-27 11:16:31.934119687 -0500
+++ pam_ldap.c	2012-08-27 11:46:22.956091908 -0500
@@ -2771,6 +2771,39 @@
 	      (strcmp (configFile, session->conf->configFile) != 0))
 	    {
 	      _release_user_info (&session->info);
+	      /* 
+	       * Release all cached data and reread the conf if the user
+	       * requested a different config file. 
+	       * This allows stacking different ldap filters together.
+	       * 2012-08-27
+	       * bpkroth
+	       */
+	      if (strcmp (configFile, session->conf->configFile) != 0) {
+		if (session->ld != NULL)
+		{
+		  ldap_unbind (session->ld);
+		  session->ld = NULL;
+		}
+	        _release_config (&session->conf);
+	        session->conf = NULL;
+	        /* Reread the conf file (copied and pasted from down below) */
+#ifdef YPLDAPD
+  rc = _ypldapd_read_config (&session->conf);
+  if (rc != PAM_SUCCESS)
+    {
+      _release_config (&session->conf);
+#endif /* YPLDAPD */
+      rc = _read_config (configFile, &session->conf);
+      if (rc != PAM_SUCCESS)
+	{
+	  _release_config (&session->conf);
+	  free (session);
+	  return rc;
+	}
+#ifdef YPLDAPD
+    }
+#endif /* YPLDAPD */
+              }
 	    }
 	}
 

Attachment: signature.asc
Description: Digital signature

Reply via email to