diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2010-12-20 11:18:27 +0100 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2010-12-20 11:18:27 +0100 |
commit | e3cf49d16bd719b842ac943bf4173cbda1818b87 (patch) | |
tree | 0cef19188f5a488526feda75633cb08efe71c0f8 | |
parent | 094a134119b3b1da1eef1a60121567f76544e27b (diff) |
implement a nss_min_uid option to filter user entries returned by LDAP
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd@1338 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r-- | man/nslcd.conf.5.xml | 11 | ||||
-rw-r--r-- | nslcd/cfg.c | 6 | ||||
-rw-r--r-- | nslcd/cfg.h | 2 | ||||
-rw-r--r-- | nslcd/group.c | 1 | ||||
-rw-r--r-- | nslcd/passwd.c | 89 |
5 files changed, 88 insertions, 21 deletions
diff --git a/man/nslcd.conf.5.xml b/man/nslcd.conf.5.xml index 72f0c21..7eefcb5 100644 --- a/man/nslcd.conf.5.xml +++ b/man/nslcd.conf.5.xml @@ -649,6 +649,17 @@ </varlistentry> <varlistentry> + <term><option>nss_min_uid</option> <replaceable>UID</replaceable></term> + <listitem> + <para> + This option ensures that <acronym>LDAP</acronym> users with a numeric + user id lower than the specified value are ignored. Also requests for + users with a lower user id are ignored. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><option>pam_authz_search</option> <replaceable>FILTER</replaceable></term> <listitem> diff --git a/nslcd/cfg.c b/nslcd/cfg.c index 364e726..91c8384 100644 --- a/nslcd/cfg.c +++ b/nslcd/cfg.c @@ -120,6 +120,7 @@ static void cfg_defaults(struct ldap_config *cfg) cfg->ldc_pagesize=0; cfg->ldc_nss_initgroups_ignoreusers=NULL; cfg->ldc_pam_authz_search=NULL; + cfg->ldc_nss_min_uid=0; } /* simple strdup wrapper */ @@ -1050,6 +1051,11 @@ static void cfg_read(const char *filename,struct ldap_config *cfg) check_argumentcount(filename,lnr,keyword,(line!=NULL)&&(*line!='\0')); cfg->ldc_pam_authz_search=xstrdup(line); } + else if (strcasecmp(keyword,"nss_min_uid")==0) + { + get_uid(filename,lnr,keyword,&line,&cfg->ldc_nss_min_uid); + get_eol(filename,lnr,keyword,&line); + } #ifdef ENABLE_CONFIGFILE_CHECKING /* fallthrough */ else diff --git a/nslcd/cfg.h b/nslcd/cfg.h index de43956..a44d5d2 100644 --- a/nslcd/cfg.h +++ b/nslcd/cfg.h @@ -137,6 +137,8 @@ struct ldap_config SET *ldc_nss_initgroups_ignoreusers; /* the search that should be performed to do autorisation checks */ char *ldc_pam_authz_search; + /* minimum uid for users retreived from LDAP */ + uid_t ldc_nss_min_uid; }; /* this is a pointer to the global configuration, it should be available diff --git a/nslcd/group.c b/nslcd/group.c index baf367e..e21f035 100644 --- a/nslcd/group.c +++ b/nslcd/group.c @@ -69,7 +69,6 @@ const char *attmap_group_uniqueMember = "uniqueMember"; /* default values for attributes */ static const char *default_group_userPassword = "*"; /* unmatchable */ - /* the attribute list to request with searches */ static const char *group_attrs[6]; diff --git a/nslcd/passwd.c b/nslcd/passwd.c index f0dceb0..3d734f2 100644 --- a/nslcd/passwd.c +++ b/nslcd/passwd.c @@ -138,13 +138,46 @@ struct dn2uid_cache_entry }; #define DN2UID_CACHE_TIMEOUT (15*60) +/* checks whether the entry has a valid uidNumber attribute + (>= nss_min_uid) */ +static int entry_has_valid_uid(MYLDAP_ENTRY *entry) +{ + int i; + const char **values; + char *tmp; + uid_t uid; + /* if min_uid is not set any entry should do */ + if (nslcd_cfg->ldc_nss_min_uid==0) + return 1; + /* get all uidNumber attributes */ + values=myldap_get_values(entry,attmap_passwd_uidNumber); + if ((values==NULL)||(values[0]==NULL)) + { + log_log(LOG_WARNING,"passwd entry %s does not contain %s value", + myldap_get_dn(entry),attmap_passwd_uidNumber); + return 0; + } + /* check if there is a uidNumber attributes >= min_uid */ + for (i=0;values[i]!=NULL;i++) + { + uid=(uid_t)strtol(values[i],&tmp,0); + if ((*(values[i])=='\0')||(*tmp!='\0')) + log_log(LOG_WARNING,"passwd entry %s contains non-numeric %s value", + myldap_get_dn(entry),attmap_passwd_uidNumber); + else if (uid>=nslcd_cfg->ldc_nss_min_uid) + return 1; + } + /* nothing found */ + return 0; +} + /* Perform an LDAP lookup to translate the DN into a uid. This function either returns NULL or a strdup()ed string. */ char *lookup_dn2uid(MYLDAP_SESSION *session,const char *dn,int *rcp,char *buf,size_t buflen) { MYLDAP_SEARCH *search; MYLDAP_ENTRY *entry; - static const char *attrs[2]; + static const char *attrs[3]; int rc=LDAP_SUCCESS; const char **values; char *uid=NULL; @@ -152,7 +185,8 @@ char *lookup_dn2uid(MYLDAP_SESSION *session,const char *dn,int *rcp,char *buf,si rcp=&rc; /* we have to look up the entry */ attrs[0]=attmap_passwd_uid; - attrs[1]=NULL; + attrs[1]=attmap_passwd_uidNumber; + attrs[2]=NULL; search=myldap_search(session,dn,LDAP_SCOPE_BASE,passwd_filter,attrs,rcp); if (search==NULL) { @@ -166,13 +200,17 @@ char *lookup_dn2uid(MYLDAP_SESSION *session,const char *dn,int *rcp,char *buf,si log_log(LOG_WARNING,"lookup of user %s failed: %s",dn,ldap_err2string(*rcp)); return NULL; } - /* get uid (just use first one) */ - values=myldap_get_values(entry,attmap_passwd_uid); - /* check the result for presence and validity */ - if ((values!=NULL)&&(values[0]!=NULL)&&isvalidname(values[0])&&(strlen(values[0])<buflen)) + /* check the uidNumber attribute if min_uid is set */ + if (entry_has_valid_uid(entry)) { - strcpy(buf,values[0]); - uid=buf; + /* get uid (just use first one) */ + values=myldap_get_values(entry,attmap_passwd_uid); + /* check the result for presence and validity */ + if ((values!=NULL)&&(values[0]!=NULL)&&isvalidname(values[0])&&(strlen(values[0])<buflen)) + { + strcpy(buf,values[0]); + uid=buf; + } } /* clean up and return */ myldap_search_close(search); @@ -258,14 +296,15 @@ MYLDAP_ENTRY *uid2entry(MYLDAP_SESSION *session,const char *uid,int *rcp) MYLDAP_ENTRY *entry=NULL; const char *base; int i; - static const char *attrs[2]; + static const char *attrs[3]; char filter[1024]; /* if it isn't a valid username, just bail out now */ if (!isvalidname(uid)) return NULL; /* set up attributes (we don't need much) */ attrs[0]=attmap_passwd_uid; - attrs[1]=NULL; + attrs[1]=attmap_passwd_uidNumber; + attrs[2]=NULL; /* we have to look up the entry */ mkfilter_passwd_byname(uid,filter,sizeof(filter)); for (i=0;(i<NSS_LDAP_CONFIG_MAX_BASES)&&((base=passwd_bases[i])!=NULL);i++) @@ -274,7 +313,7 @@ MYLDAP_ENTRY *uid2entry(MYLDAP_SESSION *session,const char *uid,int *rcp) if (search==NULL) return NULL; entry=myldap_get_entry(search,NULL); - if (entry!=NULL) + if ((entry!=NULL)&&(entry_has_valid_uid(entry))) return entry; } return NULL; @@ -393,14 +432,17 @@ static int write_passwd(TFILE *fp,MYLDAP_ENTRY *entry,const char *requser, { for (j=0;j<numuids;j++) { - WRITE_INT32(fp,NSLCD_RESULT_BEGIN); - WRITE_STRING(fp,usernames[i]); - WRITE_STRING(fp,passwd); - WRITE_TYPE(fp,uids[j],uid_t); - WRITE_TYPE(fp,gid,gid_t); - WRITE_STRING(fp,gecos); - WRITE_STRING(fp,homedir); - WRITE_STRING(fp,shell); + if (uids[j]>=nslcd_cfg->ldc_nss_min_uid) + { + WRITE_INT32(fp,NSLCD_RESULT_BEGIN); + WRITE_STRING(fp,usernames[i]); + WRITE_STRING(fp,passwd); + WRITE_TYPE(fp,uids[j],uid_t); + WRITE_TYPE(fp,gid,gid_t); + WRITE_STRING(fp,gecos); + WRITE_STRING(fp,homedir); + WRITE_STRING(fp,shell); + } } } } @@ -427,7 +469,14 @@ NSLCD_HANDLE_UID( uid_t uid; char filter[1024]; READ_TYPE(fp,uid,uid_t); - log_setrequest("passwd=%d",(int)uid);, + log_setrequest("passwd=%d",(int)uid); + if (uid<nslcd_cfg->ldc_nss_min_uid) + { + /* return an empty result */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_PASSWD_BYUID); + WRITE_INT32(fp,NSLCD_RESULT_END); + }, NSLCD_ACTION_PASSWD_BYUID, mkfilter_passwd_byuid(uid,filter,sizeof(filter)), write_passwd(fp,entry,NULL,&uid,calleruid) |