Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
path: root/nslcd
diff options
context:
space:
mode:
Diffstat (limited to 'nslcd')
-rw-r--r--nslcd/attmap.c6
-rw-r--r--nslcd/attmap.h6
-rw-r--r--nslcd/group.c172
3 files changed, 144 insertions, 40 deletions
diff --git a/nslcd/attmap.c b/nslcd/attmap.c
index c39283c..22a84c3 100644
--- a/nslcd/attmap.c
+++ b/nslcd/attmap.c
@@ -2,7 +2,7 @@
attmap.c - attribute mapping values and functions
This file is part of the nss-ldapd library.
- Copyright (C) 2007 Arthur de Jong
+ Copyright (C) 2007, 2008 Arthur de Jong
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -146,10 +146,8 @@ const char **attmap_get_var(enum ldap_map_selector map,const char *name)
if (strcasecmp(name,"userPassword")==0) return &attmap_group_userPassword;
if (strcasecmp(name,"gidNumber")==0) return &attmap_group_gidNumber;
if (strcasecmp(name,"memberUid")==0) return &attmap_group_memberUid;
-/*
if (strcasecmp(name,"uniqueMember")==0) return &attmap_group_uniqueMember;
- if (strcasecmp(name,"memberOf")==0) return &attmap_group_memberOf;
-*/
+/* if (strcasecmp(name,"memberOf")==0) return &attmap_group_memberOf; */
}
else if (map==LM_HOSTS)
{
diff --git a/nslcd/attmap.h b/nslcd/attmap.h
index 906f285..0c350eb 100644
--- a/nslcd/attmap.h
+++ b/nslcd/attmap.h
@@ -2,7 +2,7 @@
attmap.h - attribute mapping variables
This file is part of the nss-ldapd library.
- Copyright (C) 2007 Arthur de Jong
+ Copyright (C) 2007, 2008 Arthur de Jong
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -34,10 +34,8 @@ extern const char *attmap_group_cn;
extern const char *attmap_group_userPassword;
extern const char *attmap_group_gidNumber;
extern const char *attmap_group_memberUid;
-/*
extern const char *attmap_group_uniqueMember;
-extern const char *attmap_group_memberOf;
-*/
+/*extern const char *attmap_group_memberOf;*/
extern const char *attmap_host_cn;
extern const char *attmap_host_ipHostNumber;
extern const char *attmap_netgroup_cn;
diff --git a/nslcd/group.c b/nslcd/group.c
index feeec09..4cdba59 100644
--- a/nslcd/group.c
+++ b/nslcd/group.c
@@ -5,7 +5,7 @@
Copyright (C) 1997-2006 Luke Howard
Copyright (C) 2006 West Consulting
- Copyright (C) 2006, 2007 Arthur de Jong
+ Copyright (C) 2006, 2007, 2008 Arthur de Jong
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -64,10 +64,8 @@ const char *attmap_group_cn = "cn";
const char *attmap_group_userPassword = "userPassword";
const char *attmap_group_gidNumber = "gidNumber";
const char *attmap_group_memberUid = "memberUid";
-/*
const char *attmap_group_uniqueMember = "uniqueMember";
-const char *attmap_group_memberOf = "memberOf";
-*/
+/*const char *attmap_group_memberOf = "memberOf";*/
/* default values for attributes */
static const char *default_group_userPassword = "*"; /* unmatchable */
@@ -127,25 +125,143 @@ static void group_init(void)
group_attrs[1]=attmap_group_userPassword;
group_attrs[2]=attmap_group_memberUid;
group_attrs[3]=attmap_group_gidNumber;
- group_attrs[4]=NULL;
-/* group_attrs[4]=attmap_group_uniqueMember; */
+ group_attrs[4]=attmap_group_uniqueMember;
+ group_attrs[5]=NULL;
+}
+
+static int do_write_group(
+ TFILE *fp,const char **names,gid_t gids[],int numgids,const char *passwd,
+ const char *members)
+{
+ int32_t tmpint32;
+ int i,j;
+ int nummembers;
+ const char *tmp;
+ /* count the number of members */
+ nummembers=0;
+ if (members!=NULL)
+ for (tmp=members;*tmp!='\0';tmp+=strlen(tmp)+1)
+ nummembers++;
+ /* write entries for all names and gids */
+ for (i=0;names[i]!=NULL;i++)
+ for (j=0;j<numgids;j++)
+ {
+ WRITE_INT32(fp,NSLCD_RESULT_SUCCESS);
+ WRITE_STRING(fp,names[i]);
+ WRITE_STRING(fp,passwd);
+ WRITE_TYPE(fp,gids[j],gid_t);
+ /* write a list of values */
+ WRITE_INT32(fp,nummembers);
+ if (members!=NULL)
+ for (tmp=members;*tmp!='\0';tmp+=strlen(tmp)+1)
+ { WRITE_STRING(fp,tmp); }
+ }
+ return 0;
+}
+
+/* return the list of members as a \0 separated string with an extra \0
+ at the end (doing dn->uid lookups as needed) */
+static char *getmembers(MYLDAP_ENTRY *entry,MYLDAP_SESSION *session)
+{
+ char *buf;
+ char *nw;
+ size_t bufalloc,bufsz;
+ int i;
+ const char **values;
+ /* allocate some memory */
+ bufalloc=64;
+ bufsz=0;
+ buf=(char *)malloc(bufalloc);
+ if (buf==NULL)
+ {
+ log_log(LOG_CRIT,"get_members(): malloc() failed to allocate memory");
+ return NULL;
+ }
+ buf[0]='\0';
+ /* add the memberUid values */
+ values=myldap_get_values(entry,attmap_group_memberUid);
+ if (values!=NULL)
+ for (i=0;values[i]!=NULL;i++)
+ {
+ /* ensure that we have enough space */
+ if ((strlen(values[i])+2)>=(bufalloc-bufsz))
+ {
+ bufalloc=((bufalloc+strlen(values[i])+2)*3)/2;
+ nw=(char *)realloc(buf,bufalloc);
+ if (nw==NULL)
+ {
+ free(buf);
+ log_log(LOG_CRIT,"get_members(): realloc() failed to allocate memory");
+ return NULL;
+ }
+ buf=nw;
+ }
+ /* only add non-emtpty values */
+ if (values[i][0]!='\0')
+ {
+ strcpy(buf+bufsz,values[i]);
+ bufsz+=strlen(buf+bufsz)+1;
+ }
+ }
+ /* add the uniqueMember values */
+ values=myldap_get_values(entry,attmap_group_uniqueMember);
+ if (values!=NULL)
+ for (i=0;values[i]!=NULL;i++)
+ {
+ /* ensure that we have enough space */
+ if ((strlen(values[i])+2)>=(bufalloc-bufsz))
+ {
+ bufalloc=((bufalloc+strlen(values[i])+2)*3)/2;
+ nw=(char *)realloc(buf,bufalloc);
+ if (nw==NULL)
+ {
+ free(buf);
+ log_log(LOG_CRIT,"get_members(): realloc() failed to allocate memory");
+ return NULL;
+ }
+ }
+ /* check the value */
+ if (values[i][0]=='\0')
+ { /* silently ignore empty values */ }
+ else if (strchr(values[i],'=')==NULL)
+ {
+ /* just add the value, it doesn't look like a DN */
+ strcpy(buf+bufsz,values[i]);
+ bufsz+=strlen(buf+bufsz)+1;
+ }
+ else
+ {
+ /* transform the DN into a uid */
+ dn2uid(session,values[i],buf+bufsz,bufalloc-bufsz);
+ bufsz+=strlen(buf+bufsz)+1;
+ }
+ }
+ /* if the buffer does not contain any data, return NULL */
+ if (buf[0]=='\0')
+ {
+ free(buf);
+ return NULL;
+ }
+ /* terminate the list with an empty string */
+ strcpy(buf+bufsz,"");
+ return buf;
}
/* the maximum number of gidNumber attributes per entry */
#define MAXGIDS_PER_ENTRY 5
static int write_group(TFILE *fp,MYLDAP_ENTRY *entry,const char *reqname,
- const gid_t *reqgid,int wantmembers)
+ const gid_t *reqgid,int wantmembers,
+ MYLDAP_SESSION *session)
{
- int32_t tmpint32,tmp2int32,tmp3int32;
const char *tmparr[2];
const char **names,**gidvalues;
const char *passwd;
- const char **memberuidvalues;
+ char *members;
gid_t gids[MAXGIDS_PER_ENTRY];
int numgids;
char *tmp;
- int i,j;
+ int rc;
/* get group name (cn) */
if (reqname!=NULL)
{
@@ -193,25 +309,18 @@ static int write_group(TFILE *fp,MYLDAP_ENTRY *entry,const char *reqname,
passwd=get_userpassword(entry,attmap_group_userPassword);
if (passwd==NULL)
passwd=default_group_userPassword;
- /* get group memebers (memberUid) */
+ /* get group memebers (memberUid&uniqueMember) */
if (wantmembers)
- memberuidvalues=myldap_get_values(entry,attmap_group_memberUid);
+ members=getmembers(entry,session);
else
- memberuidvalues=NULL;
- /* write entries for all names and gids */
- for (i=0;names[i]!=NULL;i++)
- for (j=0;j<numgids;j++)
- {
- WRITE_INT32(fp,NSLCD_RESULT_SUCCESS);
- WRITE_STRING(fp,names[i]);
- WRITE_STRING(fp,passwd);
- WRITE_TYPE(fp,gids[j],gid_t);
- if (memberuidvalues!=NULL)
- { WRITE_STRINGLIST(fp,memberuidvalues); }
- else
- { WRITE_INT32(fp,0); }
- }
- return 0;
+ members=NULL;
+ /* write entries (split to a separate function so we can ensure the call
+ to free() below in case a write fails) */
+ rc=do_write_group(fp,names,gids,numgids,passwd,members);
+ /* free and return */
+ if (members!=NULL)
+ free(members);
+ return rc;
}
NSLCD_HANDLE(
@@ -222,7 +331,7 @@ NSLCD_HANDLE(
log_log(LOG_DEBUG,"nslcd_group_byname(%s)",name);,
NSLCD_ACTION_GROUP_BYNAME,
mkfilter_group_byname(name,filter,sizeof(filter)),
- write_group(fp,entry,name,NULL,1)
+ write_group(fp,entry,name,NULL,1,session)
)
NSLCD_HANDLE(
@@ -233,7 +342,7 @@ NSLCD_HANDLE(
log_log(LOG_DEBUG,"nslcd_group_bygid(%d)",(int)gid);,
NSLCD_ACTION_GROUP_BYGID,
mkfilter_group_bygid(gid,filter,sizeof(filter)),
- write_group(fp,entry,NULL,&gid,1)
+ write_group(fp,entry,NULL,&gid,1,session)
)
NSLCD_HANDLE(
@@ -244,7 +353,7 @@ NSLCD_HANDLE(
log_log(LOG_DEBUG,"nslcd_group_bymember(%s)",name);,
NSLCD_ACTION_GROUP_BYMEMBER,
mkfilter_group_bymember(name,filter,sizeof(filter)),
- write_group(fp,entry,NULL,NULL,0)
+ write_group(fp,entry,NULL,NULL,0,session)
)
NSLCD_HANDLE(
@@ -254,6 +363,5 @@ NSLCD_HANDLE(
log_log(LOG_DEBUG,"nslcd_group_all()");,
NSLCD_ACTION_GROUP_ALL,
(filter=group_filter,0),
- write_group(fp,entry,NULL,NULL,1)
+ write_group(fp,entry,NULL,NULL,1,session)
)
-