nss-pam-ldapd commit: r1088 - in nss-pam-ldapd: man nslcd
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
nss-pam-ldapd commit: r1088 - in nss-pam-ldapd: man nslcd
- From: "Commits of the nss-pam-ldapd project." <nss-pam-ldapd-commits [at] lists.arthurdejong.org>
- To: nss-pam-ldapd-commits [at] lists.arthurdejong.org
- Reply-to: nss-pam-ldapd-users [at] lists.arthurdejong.org
- Subject: nss-pam-ldapd commit: r1088 - in nss-pam-ldapd: man nslcd
- Date: Fri, 7 May 2010 23:45:09 +0200 (CEST)
Author: arthur
Date: Fri May 7 23:45:06 2010
New Revision: 1088
URL: http://arthurdejong.org/viewvc/nss-pam-ldapd?view=rev&revision=1088
Log:
implement an authz_search option to test whether the user is authorised
Modified:
nss-pam-ldapd/man/nslcd.conf.5.xml
nss-pam-ldapd/man/pam_ldap.8.xml
nss-pam-ldapd/nslcd/cfg.c
nss-pam-ldapd/nslcd/cfg.h
nss-pam-ldapd/nslcd/pam.c
Modified: nss-pam-ldapd/man/nslcd.conf.5.xml
==============================================================================
--- nss-pam-ldapd/man/nslcd.conf.5.xml Fri May 7 23:25:05 2010 (r1087)
+++ nss-pam-ldapd/man/nslcd.conf.5.xml Fri May 7 23:45:06 2010 (r1088)
@@ -642,6 +642,37 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>authz_search</option>
+ <replaceable>FILTER</replaceable></term>
+ <listitem>
+ <para>
+ This option allows flexible fine tuning of the authorisation check that
+ should be performed. The search filter specified is executed and
+ if any entries match, access is granted, otherwise access is denied.
+ </para>
+ <para>
+ The search filter can contain the following variable references:
+ <literal>$username</literal>, <literal>$service</literal>,
+ <literal>$ruser</literal>, <literal>$rhost</literal>,
+ <literal>$tty</literal>, <literal>$hostname</literal>,
+ <literal>$dn</literal>, and <literal>$uid</literal>.
+ These references are substituted in the search filter using the
+ same syntax as described in the section on attribute mapping
+ expressions below.
+ </para>
+ <para>
+ For example, to check that the user has a proper authorizedService
+ value if the attribute is present:
+
<literal>(&(objectClass=posixAccount)(uid=$username)(|(authorizedService=$service)(!(authorizedService=*))))</literal>
+ </para>
+ <para>
+ The default behaviour is not to do this extra search and always
+ grant access.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect2>
Modified: nss-pam-ldapd/man/pam_ldap.8.xml
==============================================================================
--- nss-pam-ldapd/man/pam_ldap.8.xml Fri May 7 23:25:05 2010 (r1087)
+++ nss-pam-ldapd/man/pam_ldap.8.xml Fri May 7 23:45:06 2010 (r1088)
@@ -166,8 +166,8 @@
<refsect1 id="moduleservices">
<title>Module Services Provided</title>
<para>
- All services are provided by this module but currently only authentication
- (auth) and password change (password) are implemented in the nslcd daemon.
+ All services are provided by this module but currently sessions changes
+ are not implemented in the nslcd daemon.
</para>
</refsect1>
Modified: nss-pam-ldapd/nslcd/cfg.c
==============================================================================
--- nss-pam-ldapd/nslcd/cfg.c Fri May 7 23:25:05 2010 (r1087)
+++ nss-pam-ldapd/nslcd/cfg.c Fri May 7 23:45:06 2010 (r1088)
@@ -119,6 +119,7 @@
cfg->ldc_restart=1;
cfg->ldc_pagesize=0;
cfg->ldc_nss_initgroups_ignoreusers=NULL;
+ cfg->ldc_authz_search=NULL;
}
/* simple strdup wrapper */
@@ -1020,6 +1021,11 @@
{
parse_nss_initgroups_ignoreusers_statement(filename,lnr,keyword,line,cfg);
}
+ else if (strcasecmp(keyword,"authz_search")==0)
+ {
+ check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0'));
+ cfg->ldc_authz_search=xstrdup(line);
+ }
#ifdef ENABLE_CONFIGFILE_CHECKING
/* fallthrough */
else
Modified: nss-pam-ldapd/nslcd/cfg.h
==============================================================================
--- nss-pam-ldapd/nslcd/cfg.h Fri May 7 23:25:05 2010 (r1087)
+++ nss-pam-ldapd/nslcd/cfg.h Fri May 7 23:45:06 2010 (r1088)
@@ -136,6 +136,8 @@
/* the users for which no initgroups() searches should be done
Note: because we use a set here comparisons will be case-insensitive */
SET *ldc_nss_initgroups_ignoreusers;
+ /* the search that should be performed to do autorisation checks */
+ char *ldc_authz_search;
};
/* this is a pointer to the global configuration, it should be available
Modified: nss-pam-ldapd/nslcd/pam.c
==============================================================================
--- nss-pam-ldapd/nslcd/pam.c Fri May 7 23:25:05 2010 (r1087)
+++ nss-pam-ldapd/nslcd/pam.c Fri May 7 23:45:06 2010 (r1088)
@@ -28,12 +28,19 @@
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif /* HAVE_STDINT_H */
+#include <unistd.h>
#include "common.h"
#include "log.h"
#include "myldap.h"
#include "cfg.h"
#include "attmap.h"
+#include "common/dict.h"
+#include "common/expr.h"
+
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX 255
+#endif /* not HOST_NAME_MAX */
/* set up a connection and try to bind with the specified DN and password
returns a NSLCD_PAM_* error code */
@@ -170,6 +177,92 @@
return 0;
}
+static void autzsearch_var_add(DICT *dict,const char *name,const char *value)
+{
+ size_t sz;
+ char *escaped_value;
+ /* allocate memory for escaped string */
+ sz=((strlen(value)+8)*120)/100;
+ escaped_value=(char *)malloc(sz);
+ if (escaped_value==NULL)
+ {
+ log_log(LOG_CRIT,"autzsearch_var_add(): malloc() failed to allocate
memory");
+ return;
+ }
+ /* perform escaping of the value */
+ if(myldap_escape(value,escaped_value,sz))
+ {
+ log_log(LOG_CRIT,"autzsearch_var_add(): myldap_escape() failed to fit in
buffer");
+ return;
+ }
+ /* add to dict */
+ dict_put(dict,name,escaped_value);
+}
+
+static void autzsearch_vars_free(DICT *dict)
+{
+ int i;
+ const char **keys;
+ void *value;
+ /* go over all keys and free all the values
+ (they were allocated in autzsearch_var_add) */
+ /* loop over dictionary contents */
+ keys=dict_keys(dict);
+ for (i=0;keys[i]!=NULL;i++)
+ {
+ value=dict_get(dict,keys[i]);
+ if (value)
+ free(value);
+ }
+ free(keys);
+ /* after this values from the dict should obviously no longer be used */
+}
+
+static const char *autzsearch_var_get(const char *name,void *expander_attr)
+{
+ DICT *dict=(DICT *)expander_attr;
+ return (const char *)dict_get(dict,name);
+ /* TODO: if not set use entry to get attribute name (entry can be an
+ element in the dict) */
+}
+
+static int try_autzsearch(MYLDAP_SESSION *session,DICT *dict,const char
*searchfilter)
+{
+ char filter_buffer[1024];
+ MYLDAP_SEARCH *search;
+ MYLDAP_ENTRY *entry;
+ static const char *attrs[2];
+ int rc;
+ /* build the search filter */
+ if (expr_parse(searchfilter,filter_buffer,sizeof(filter_buffer),
+ autzsearch_var_get,(void *)dict)==NULL)
+ {
+ log_log(LOG_ERR,"authorisation search \"%s\" is invalid",searchfilter);
+ return -1;
+ }
+ /* perform the search */
+ attrs[0]="dn";
+ attrs[1]=NULL;
+ /* FIXME: this only searches the first base */
+ search=myldap_search(session,nslcd_cfg->ldc_bases[0],LDAP_SCOPE_SUB,
+ filter_buffer,attrs,&rc);
+ if (search==NULL)
+ {
+ log_log(LOG_ERR,"authorisation search \"%s\" failed: %s",
+ filter_buffer,ldap_err2string(rc));
+ return -1;
+ }
+ /* try to get an entry */
+ entry=myldap_get_entry(search,NULL);
+ if (entry==NULL)
+ {
+ log_log(LOG_ERR,"no entry found");
+ return -1;
+ }
+ /* we've found an entry so it's OK */
+ return 0;
+}
+
/* check authorisation of the user */
int nslcd_pam_authz(TFILE *fp,MYLDAP_SESSION *session)
{
@@ -180,6 +273,8 @@
char ruser[32];
char rhost[256];
char tty[256];
+ char hostname[HOST_NAME_MAX+1];
+ DICT *dict;
/* read request parameters */
READ_STRING(fp,username);
READ_STRING(fp,userdn);
@@ -199,7 +294,33 @@
WRITE_INT32(fp,NSLCD_RESULT_END);
return -1;
}
- /* TODO: perform any authorisation checks */
+ if (nslcd_cfg->ldc_authz_search)
+ {
+ /* TODO: perform any authorisation checks */
+ dict=dict_new();
+ autzsearch_var_add(dict,"username",username);
+ autzsearch_var_add(dict,"service",servicename);
+ autzsearch_var_add(dict,"ruser",ruser);
+ autzsearch_var_add(dict,"rhost",rhost);
+ autzsearch_var_add(dict,"tty",tty);
+ if (gethostname(hostname,sizeof(hostname))==0)
+ autzsearch_var_add(dict,"hostname",hostname);
+ /* TODO: fqdn */
+ autzsearch_var_add(dict,"dn",userdn);
+ autzsearch_var_add(dict,"uid",username);
+ if (try_autzsearch(session,dict,nslcd_cfg->ldc_authz_search))
+ {
+ log_log(LOG_DEBUG,"LDAP authorisation check failed");
+ WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
+ WRITE_STRING(fp,username);
+ WRITE_STRING(fp,userdn);
+ WRITE_INT32(fp,NSLCD_PAM_PERM_DENIED); /* authz */
+ WRITE_STRING(fp,"LDAP authorisation check failed"); /* authzmsg */
+ WRITE_INT32(fp,NSLCD_RESULT_END);
+ }
+ autzsearch_vars_free(dict);
+ dict_free(dict);
+ }
/* write response */
WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
WRITE_STRING(fp,username);
--
To unsubscribe send an email to
nss-pam-ldapd-commits-unsubscribe@lists.arthurdejong.org or see
http://lists.arthurdejong.org/nss-pam-ldapd-commits
- nss-pam-ldapd commit: r1088 - in nss-pam-ldapd: man nslcd,
Commits of the nss-pam-ldapd project.