Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2010-03-20 17:01:34 +0100
committerArthur de Jong <arthur@arthurdejong.org>2010-03-20 17:01:34 +0100
commit738e6bdc61c14f3a71db1e3ae645ccc7bf65cf44 (patch)
tree7592a4096fc8a71ef2d047a9cfd018101ddc05d8
parent88326536b9d85705df64df197468ac0b21948e4e (diff)
add an nss_initgroups_ignoreusers option to ignore username to group lookups for the specified users
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd@1076 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r--man/nslcd.conf.5.xml17
-rw-r--r--nslcd/cfg.c49
-rw-r--r--nslcd/cfg.h4
-rw-r--r--nslcd/group.c9
4 files changed, 79 insertions, 0 deletions
diff --git a/man/nslcd.conf.5.xml b/man/nslcd.conf.5.xml
index 3958ea9..33314d8 100644
--- a/man/nslcd.conf.5.xml
+++ b/man/nslcd.conf.5.xml
@@ -625,6 +625,23 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>nss_initgroups_ignoreusers</option> user1,user2,...</term>
+ <listitem>
+ <para>
+ This option prevents group membership lookups through
+ <acronym>LDAP</acronym> for the specified users. This can be useful
+ in case of unavailability of the <acronym>LDAP</acronym> server.
+ This option may be specified multiple times.
+ </para>
+ <para>
+ Alternatively, the value <emphasis remap="I">ALLLOCAL</emphasis> may be
+ used. With that value nslcd builds a full list of
+ non-<acronym>LDAP</acronym> users on startup.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect2>
diff --git a/nslcd/cfg.c b/nslcd/cfg.c
index 1a3544a..4f7114d 100644
--- a/nslcd/cfg.c
+++ b/nslcd/cfg.c
@@ -118,6 +118,7 @@ static void cfg_defaults(struct ldap_config *cfg)
#endif /* LDAP_OPT_X_TLS */
cfg->ldc_restart=1;
cfg->ldc_pagesize=0;
+ cfg->ldc_nss_initgroups_ignoreusers=NULL;
}
/* simple strdup wrapper */
@@ -679,6 +680,50 @@ static void parse_map_statement(const char *filename,int lnr,
}
}
+/* this function modifies the statement argument passed */
+static void parse_nss_initgroups_ignoreusers_statement(
+ const char *filename,int lnr,const char *keyword,
+ char *line,struct ldap_config *cfg)
+{
+ char token[MAX_LINE_LENGTH];
+ char *username,*next;
+ struct passwd *pwent;
+ check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0'));
+ if (cfg->ldc_nss_initgroups_ignoreusers==NULL)
+ cfg->ldc_nss_initgroups_ignoreusers=set_new();
+ while (get_token(&line,token,sizeof(token))!=NULL)
+ {
+ if (strcasecmp(token,"alllocal")==0)
+ {
+ /* go over all users (this will work because nslcd is not yet running) */
+ setpwent();
+ while ((pwent=getpwent())!=NULL)
+ set_add(cfg->ldc_nss_initgroups_ignoreusers,pwent->pw_name);
+ endpwent();
+ }
+ else
+ {
+ next=token;
+ while (*next!='\0')
+ {
+ username=next;
+ /* find the end of the current username */
+ while ((*next!='\0')&&(*next!=',')) next++;
+ if (*next==',')
+ {
+ *next='\0';
+ next++;
+ }
+ /* check if user exists (but add anyway) */
+ pwent=getpwnam(username);
+ if (pwent==NULL)
+ log_log(LOG_ERR,"%s:%d: user '%s' does not exist",filename,lnr,username);
+ set_add(cfg->ldc_nss_initgroups_ignoreusers,username);
+ }
+ }
+ }
+}
+
static void cfg_read(const char *filename,struct ldap_config *cfg)
{
FILE *fp;
@@ -971,6 +1016,10 @@ static void cfg_read(const char *filename,struct ldap_config *cfg)
get_int(filename,lnr,keyword,&line,&cfg->ldc_pagesize);
get_eol(filename,lnr,keyword,&line);
}
+ else if (strcasecmp(keyword,"nss_initgroups_ignoreusers")==0)
+ {
+ parse_nss_initgroups_ignoreusers_statement(filename,lnr,keyword,line,cfg);
+ }
#ifdef ENABLE_CONFIGFILE_CHECKING
/* fallthrough */
else
diff --git a/nslcd/cfg.h b/nslcd/cfg.h
index 246e663..8367b45 100644
--- a/nslcd/cfg.h
+++ b/nslcd/cfg.h
@@ -32,6 +32,7 @@
#include <ldap.h>
#include "compat/attrs.h"
+#include "common/set.h"
/* values for uid and gid */
#define NOUID ((gid_t)-1)
@@ -132,6 +133,9 @@ struct ldap_config
int ldc_restart;
/* set to a greater than 0 to enable handling of paged results with the specified size */
int ldc_pagesize;
+ /* 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;
};
/* this is a pointer to the global configuration, it should be available
diff --git a/nslcd/group.c b/nslcd/group.c
index 70b4440..35522f6 100644
--- a/nslcd/group.c
+++ b/nslcd/group.c
@@ -314,6 +314,15 @@ NSLCD_HANDLE(
if (!isvalidname(name)) {
log_log(LOG_WARNING,"nslcd_group_bymember(%s): invalid user name",name);
return -1;
+ }
+ if ((nslcd_cfg->ldc_nss_initgroups_ignoreusers!=NULL)&&
+ set_contains(nslcd_cfg->ldc_nss_initgroups_ignoreusers,name))
+ {
+ /* just end the request, returning no results */
+ WRITE_INT32(fp,NSLCD_VERSION);
+ WRITE_INT32(fp,NSLCD_ACTION_GROUP_BYMEMBER);
+ WRITE_INT32(fp,NSLCD_RESULT_END);
+ return 0;
},
log_log(LOG_DEBUG,"nslcd_group_bymember(%s)",name);,
NSLCD_ACTION_GROUP_BYMEMBER,