--- nss-pam-ldapd-0.7.5.vanilla/nslcd/group.c 2013-03-19 17:03:19.247474655 +0000 +++ nss-pam-ldapd-0.7.5/nslcd/group.c 2013-03-20 14:04:11.786450689 +0000 @@ -131,6 +131,22 @@ attmap_group_uniqueMember,safedn); } +static int mkfilter_group_bymemberdn(MYLDAP_SESSION *session, + const char *dn, + char *buffer,size_t buflen) +{ + char safeuid[300]; + char safedn[300]; + + /* escape DN */ + if(myldap_escape(dn,safedn,sizeof(safedn))) + return -1; + return mysnprintf(buffer,buflen, + "(&%s(%s=%s))", + group_filter, + attmap_group_uniqueMember,safedn); +} + void group_init(void) { int i; @@ -179,16 +195,15 @@ return 0; } -/* return the list of members */ -static const char **getmembers(MYLDAP_ENTRY *entry,MYLDAP_SESSION *session) +static void getmembers_set(MYLDAP_ENTRY *entry,MYLDAP_SESSION *session, SET *set) { char buf[20]; int i; const char **values; - SET *set; - set=set_new(); - if (set==NULL) - return NULL; + int j; + int rc; + MYLDAP_SEARCH * search; + MYLDAP_ENTRY * entry2; /* add the memberUid values */ values=myldap_get_values(entry,attmap_group_memberUid); if (values!=NULL) @@ -206,7 +221,26 @@ /* transform the DN into a uid (dn2uid() already checks validity) */ if (dn2uid(session,values[i],buf,sizeof(buf))!=NULL) set_add(set,buf); + /* Wasn't a UID - try handling it as a nested group */ + else if ((search=myldap_search(session,values[i],LDAP_SCOPE_BASE,group_filter,group_attrs,NULL)) != NULL) + { + while ((entry2=myldap_get_entry(search,&rc))!=NULL) + getmembers_set(entry2, session, set); + } } +} + +/* return the list of members */ +static const char **getmembers(MYLDAP_ENTRY *entry,MYLDAP_SESSION *session) +{ + char buf[20]; + int i; + const char **values; + SET *set; + set=set_new(); + if (set==NULL) + return NULL; + getmembers_set(entry, session, set); /* return the members */ values=set_tolist(set); set_free(set); @@ -286,6 +320,40 @@ return rc; } +static int write_group_and_parents(TFILE *fp,MYLDAP_ENTRY *entry, MYLDAP_SESSION *session) { + const char * dn; + int rc; + int rc2; + int i; + MYLDAP_SEARCH * search; + MYLDAP_ENTRY * entry2; + const char * base; + char filter[1024]; + + rc = write_group(fp,entry,NULL,NULL,0,session); + if (! rc) + { + dn = myldap_get_dn(entry); + log_log(LOG_DEBUG, "dn = %s", dn); + + // Make filter + mkfilter_group_bymemberdn(session, dn, filter, sizeof(filter)); + for (i=0; (base=group_bases[i])!=NULL; i++) + { + /* do the LDAP search */ \ + if ((search=myldap_search(session,base,group_scope,filter,group_attrs,NULL))==NULL) + return -1; + /* go over results */ + while ((entry2=myldap_get_entry(search,&rc2))!=NULL) + { + if (write_group_and_parents(fp,entry2,session)) + return -1; + } + } + } + return rc; +} + NSLCD_HANDLE( group,byname, char name[256]; @@ -333,7 +401,7 @@ log_log(LOG_DEBUG,"nslcd_group_bymember(%s)",name);, NSLCD_ACTION_GROUP_BYMEMBER, mkfilter_group_bymember(session,name,filter,sizeof(filter)), - write_group(fp,entry,NULL,NULL,0,session) + write_group_and_parents(fp,entry,session) ) NSLCD_HANDLE(