Index: nslcd/cfg.c =================================================================== --- nslcd/cfg.c (revision 1074) +++ nslcd/cfg.c (working copy) @@ -118,6 +118,7 @@ #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 @@ } } +/* 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 @@ 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 Index: nslcd/cfg.h =================================================================== --- nslcd/cfg.h (revision 1074) +++ nslcd/cfg.h (working copy) @@ -32,6 +32,7 @@ #include #include "compat/attrs.h" +#include "common/set.h" /* values for uid and gid */ #define NOUID ((gid_t)-1) @@ -132,6 +133,9 @@ 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 Index: nslcd/group.c =================================================================== --- nslcd/group.c (revision 1074) +++ nslcd/group.c (working copy) @@ -314,6 +314,15 @@ 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, Index: man/nslcd.conf.5.xml =================================================================== --- man/nslcd.conf.5.xml (revision 1075) +++ man/nslcd.conf.5.xml (working copy) @@ -625,6 +625,23 @@ + + user1,user2,... + + + This option prevents group membership lookups through + LDAP for the specified users. This can be useful + in case of unavailability of the LDAP server. + This option may be specified multiple times. + + + Alternatively, the value ALLLOCAL may be + used. With that value nslcd builds a full list of + non-LDAP users on startup. + + + +