pam_filter not working

So here is the problem you want to limit your cluster to a special user group. You have everything LDAP managed and use pam_ldap for authentication. But when you edit the /etc/ldap.conf and set a pam_filter nothing happens. First of all the the syntax of pam_filter :
(|(gidNumber=1028)(gidNumber=1160))
Will not work
Literally only
pam_filter gidNumber=1028
Will work. This is the way they stupidly implemented it
      else if (!strcasecmp (k, "pam_filter"))
{
CHECKPOINTER (result->filter = strdup (v));
}

where v is everything after the ' '

while (*v != '\0' && *v != ' ' && *v != '\t')
v++;

*(v++) = '\0';

For those that know C
So you can give it one value max. Now you have to modify the /etc/pam.d/system-auth file. The default configuration is:
[root@lxb5477 ~]# cat /etc/pam.d/system-auth.back | grep ldap
auth sufficient /lib/security/$ISA/pam_ldap.so use_first_pass
account [default=bad success=ok user_unknown=ignore] /lib/security/$ISA/pam_ldap.so
password sufficient /lib/security/$ISA/pam_ldap.so use_authtok
session optional /lib/security/$ISA/pam_ldap.so

But of course a optional is not really enough. You, of course, want that if the user doesn't fulfill your filter he should be chucked into nirvana. So change to:
[root@lxb5477 ~]# cat /etc/pam.d/system-auth | grep ldap
auth required /lib/security/$ISA/pam_ldap.so
account required /lib/security/$ISA/pam_ldap.so
password requried /lib/security/$ISA/pam_ldap.so use_authtok
session required /lib/security/$ISA/pam_ldap.so

Through this if ldap fails the login fails.

But be aware that in /etc/nsswitch.conf files is before ldap
passwd:     files ldap
shadow: files ldap
group: files ldap

Otherwise you have locked yourself out :)

3 comments:

Anonymous said...

pam_filter will support complex filters, but as you noticed, you can't use (|(gidNumber=1028)(gidNumber=1160)) due to how the module is coded. The module takes the argument to pam_filter and then inserts it as a variable into a filter string: (&(%s)(%s)(%s=%s)) where the first two variables are filter strings, the third is an attribute (uid by default), and the fourth is the user. The trick is to use |(gidNumber=1028)(gidNumber=1160) without the extra parens, because the extra parens already get added in the snprintf when the final filter is built.

Lee Revell said...

pam_filter doesn't work at all for me. I have it set to:

pam_filter gidNumber=50178

But anyone can log in. Any idea what I could be doing wrong?

Anonymous said...

Frankly, if the search string parser is coded properly, multiple layers of parenthesis should not cause issues. The outer set should be parsed as containing a single complex token which is recursively passes into another iteration for processing.

((((attr=1)))) for example should uselessly recurse 4 times and then the 5th layer should evaluate 'attr=1' which is then passed back up the 5-deep chain to the final result.