Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
path: root/nslcd/group.c
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2007-12-09 15:49:56 +0100
committerArthur de Jong <arthur@arthurdejong.org>2007-12-09 15:49:56 +0100
commit534c504364428682deaa2704c3f9ae4cf7f6ab39 (patch)
treeae85847944cd9ef2fc6ae9b5072661696e82bedf /nslcd/group.c
parent432cb4f71939e9675f9e29a610124a2cd687352b (diff)
switch to new LDAP entry parsing code that is much simpler and more readable
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@488 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'nslcd/group.c')
-rw-r--r--nslcd/group.c261
1 files changed, 93 insertions, 168 deletions
diff --git a/nslcd/group.c b/nslcd/group.c
index 434c1c8..32a0c60 100644
--- a/nslcd/group.c
+++ b/nslcd/group.c
@@ -1,6 +1,6 @@
/*
group.c - group entry lookup routines
- This file was part of the nss_ldap library (as ldap-grp.c) which
+ Parts of this file were part of the nss_ldap library (as ldap-grp.c) which
has been forked into the nss-ldapd library.
Copyright (C) 1997-2006 Luke Howard
@@ -25,88 +25,18 @@
#include "config.h"
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/param.h>
+/* for gid_t */
#include <grp.h>
-#include <errno.h>
-#ifdef HAVE_LBER_H
-#include <lber.h>
-#endif
-#ifdef HAVE_LDAP_H
-#include <ldap.h>
-#endif
-#if defined(HAVE_THREAD_H)
-#include <thread.h>
-#elif defined(HAVE_PTHREAD_H)
-#include <pthread.h>
-#endif
-#include "ldap-nss.h"
#include "common.h"
#include "log.h"
#include "myldap.h"
#include "cfg.h"
#include "attmap.h"
-/* FIXME: fix following problem:
- if the entry has multiple cn fields we may end up
- sending the wrong cn, we should return the requested
- cn instead, otherwise write an entry for each cn */
-
-struct name_list
-{
- char *name;
- struct name_list *next;
-};
-
-#ifdef HAVE_USERSEC_H
-typedef struct ldap_initgroups_args
-{
- char *grplist;
- size_t listlen;
- int depth;
- struct name_list *known_groups;
- int backlink;
-}
-ldap_initgroups_args_t;
-#else
-typedef struct ldap_initgroups_args
-{
- gid_t group;
- long int *start;
- long int *size;
- gid_t **groups;
- long int limit;
- int depth;
- struct name_list *known_groups;
- int backlink;
-}
-ldap_initgroups_args_t;
-#endif /* HAVE_USERSEC_H */
-
-#define LDAP_NSS_MAXGR_DEPTH 16 /* maximum depth of group nesting for getgrent()/initgroups() */
-
-#if LDAP_NSS_NGROUPS > 64
-#define LDAP_NSS_BUFLEN_GROUP (1024 + (LDAP_NSS_NGROUPS * (sizeof (char *) + LOGNAME_MAX)))
-#else
-#define LDAP_NSS_BUFLEN_GROUP 1024
-#endif /* LDAP_NSS_NGROUPS > 64 */
-
-#ifndef LOGNAME_MAX
-#define LOGNAME_MAX 8
-#endif /* LOGNAME_MAX */
-
-#ifndef UID_NOBODY
-#define UID_NOBODY (-2)
-#endif
-
-#ifndef GID_NOBODY
-#define GID_NOBODY UID_NOBODY
-#endif
-
/* ( nisSchema.2.2 NAME 'posixGroup' SUP top STRUCTURAL
* DESC 'Abstraction of a group of accounts'
* MUST ( cn $ gidNumber )
@@ -139,6 +69,10 @@ const char *attmap_group_uniqueMember = "uniqueMember";
const char *attmap_group_memberOf = "memberOf";
*/
+/* default values for attributes */
+static const char *default_group_userPassword = "*"; /* unmatchable */
+
+
/* the attribute list to request with searches */
static const char *group_attrs[6];
@@ -169,6 +103,17 @@ static int mkfilter_group_bygid(gid_t gid,
attmap_group_gidNumber,gid);
}
+/* create a search filter for searching a group entry
+ by member uid, return -1 on errors */
+static int mkfilter_group_bymember(const char *uid,
+ char *buffer,size_t buflen)
+{
+ return mysnprintf(buffer,buflen,
+ "(&%s(%s=%s))",
+ group_filter,
+ attmap_group_memberUid,uid);
+}
+
static void group_init(void)
{
/* set up base */
@@ -186,105 +131,87 @@ static void group_init(void)
/* group_attrs[4]=attmap_group_uniqueMember; */
}
-static enum nss_status _nss_ldap_parse_gr(
- MYLDAP_ENTRY *entry,
- struct group *gr,char *buffer,size_t buflen)
-{
- char *gid;
- enum nss_status stat;
- /* get group gid (gidNumber) */
- stat=_nss_ldap_assign_attrval(entry,attmap_group_gidNumber,&gid,&buffer,&buflen);
- if (stat != NSS_STATUS_SUCCESS)
- return stat;
- gr->gr_gid=(*gid=='\0')?(unsigned)GID_NOBODY:(gid_t)strtoul(gid,NULL,10);
- /* get group name (cn) */
- stat=_nss_ldap_getrdnvalue(entry,attmap_group_cn,&gr->gr_name,&buffer,&buflen);
- if (stat != NSS_STATUS_SUCCESS)
- return stat;
- /* get group passwd (userPassword) */
- stat=_nss_ldap_assign_userpassword(entry,attmap_group_userPassword,&gr->gr_passwd,&buffer,&buflen);
- if (stat != NSS_STATUS_SUCCESS)
- return stat;
- /* get group memebers (memberUid) */
- stat=_nss_ldap_assign_attrvals(entry,attmap_group_memberUid,NULL,
- &gr->gr_mem,&buffer,&buflen,NULL);
- return stat;
-}
-
-/* macros for expanding the NSLCD_GROUP macro */
-#define NSLCD_STRING(field) WRITE_STRING(fp,field)
-#define NSLCD_TYPE(field,type) WRITE_TYPE(fp,field,type)
-#define NSLCD_STRINGLIST(field) WRITE_STRINGLIST_NULLTERM(fp,field)
-#define GROUP_NAME result.gr_name
-#define GROUP_PASSWD result.gr_passwd
-#define GROUP_GID result.gr_gid
-#define GROUP_MEMBERS result.gr_mem
+/* the maximum number of gidNumber attributes per entry */
+#define MAXGIDS_PER_ENTRY 5
-static int write_group(TFILE *fp,MYLDAP_ENTRY *entry)
+static int write_group(TFILE *fp,MYLDAP_ENTRY *entry,const char *reqname,
+ const gid_t *reqgid,int wantmembers)
{
int32_t tmpint32,tmp2int32,tmp3int32;
- struct group result;
- char buffer[1024];
- if (_nss_ldap_parse_gr(entry,&result,buffer,sizeof(buffer))!=NSS_STATUS_SUCCESS)
- return 0;
- /* write the result code */
- WRITE_INT32(fp,NSLCD_RESULT_SUCCESS);
- /* write the entry */
- NSLCD_GROUP;
- return 0;
-}
-
-int nslcd_group_bymember(TFILE *fp,MYLDAP_SESSION *session)
-{
- int32_t tmpint32;
- char name[256];
- /* these are here for now until we rewrite the LDAP code */
- int retv;
- long int start=0,size=1024;
- long int i;
- gid_t groupsp[1024];
- /* read request parameters */
- READ_STRING_BUF2(fp,name,sizeof(name));
- /* log call */
- log_log(LOG_DEBUG,"nslcd_group_bymember(%s)",name);
- /* do the LDAP request */
- retv=NSLCD_RESULT_NOTFOUND;
- /*
- retv=group_bymember(name,&start,&size,size);
- */
- /* Note: we write some garbadge here to ensure protocol error as this
- function currently returns incorrect data */
- /* Note: what to do with group ids that are not listed as supplemental
- groups but are the user's primary group id? */
- WRITE_INT32(fp,1234);
- start=0;
- /* TODO: fix this to actually work */
- /* write the response header */
- WRITE_INT32(fp,NSLCD_VERSION);
- WRITE_INT32(fp,NSLCD_ACTION_GROUP_BYNAME);
- if (retv==NSLCD_RESULT_SUCCESS)
+ const char *tmparr[2];
+ const char **names,**gidvalues;
+ const char *passwd;
+ const char **memberuidvalues;
+ gid_t gids[MAXGIDS_PER_ENTRY];
+ int numgids;
+ char *tmp;
+ int i,j;
+ /* get group name (cn) */
+ if (reqname!=NULL)
+ {
+ names=tmparr;
+ names[0]=reqname;
+ names[1]=NULL;
+ }
+ else
{
- /* loop over the returned gids */
- for (i=0;i<start;i++)
+ names=myldap_get_values(entry,attmap_group_cn);
+ if ((names==NULL)||(names[0]==NULL))
{
- WRITE_INT32(fp,NSLCD_RESULT_SUCCESS);
- /* Note: we will write a fake record here for now. This is because
- we want to keep the protocol but currently the only
- client application available discards non-gid information */
- WRITE_STRING(fp,""); /* group name */
- WRITE_STRING(fp,"*"); /* group passwd */
- WRITE_TYPE(fp,groupsp[i],gid_t); /* gid */
- WRITE_INT32(fp,1); /* number of members */
- WRITE_STRING(fp,name); /* member=user requested */
+ log_log(LOG_WARNING,"alias entry %s does not contain %s value",
+ myldap_get_dn(entry),attmap_group_cn);
+ return 0;
}
- WRITE_INT32(fp,NSLCD_RESULT_NOTFOUND);
+ }
+ /* get the group id(s) */
+ if (reqgid!=NULL)
+ {
+ gids[0]=*reqgid;
+ numgids=1;
}
else
{
- /* some error occurred */
- WRITE_INT32(fp,retv);
+ gidvalues=myldap_get_values(entry,attmap_group_gidNumber);
+ if ((gidvalues==NULL)||(gidvalues[0]==NULL))
+ {
+ log_log(LOG_WARNING,"alias entry %s does not contain %s value",
+ myldap_get_dn(entry),attmap_group_gidNumber);
+ return 0;
+ }
+ for (numgids=0;(gidvalues[numgids]!=NULL)&&(numgids<=MAXGIDS_PER_ENTRY);numgids++)
+ {
+ gids[numgids]=(gid_t)strtol(gidvalues[numgids],&tmp,0);
+ if ((*(gidvalues[numgids])=='\0')||(*tmp!='\0'))
+ {
+ log_log(LOG_WARNING,"group entry %s contains non-numeric %s value",
+ myldap_get_dn(entry),attmap_group_gidNumber);
+ return 0;
+ }
+ }
}
- /* we're done */
+ /* get group passwd (userPassword) (use only first entry) */
+ passwd=get_userpassword(entry,attmap_group_userPassword);
+ if (passwd==NULL)
+ passwd=default_group_userPassword;
+ /* TODO: translate passwd value into something returnable */
+ /* get group memebers (memberUid) */
+ if (wantmembers)
+ memberuidvalues=myldap_get_values(entry,attmap_group_memberUid);
+ 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_NULLTERM(fp,memberuidvalues); }
+ else
+ { WRITE_INT32(fp,0); }
+ }
return 0;
}
@@ -296,7 +223,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)
+ write_group(fp,entry,name,NULL,1)
)
NSLCD_HANDLE(
@@ -307,10 +234,9 @@ 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)
+ write_group(fp,entry,NULL,&gid,1)
)
-/*
NSLCD_HANDLE(
group,bymember,
char name[256];
@@ -319,9 +245,8 @@ 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)
+ write_group(fp,entry,NULL,NULL,0)
)
-*/
NSLCD_HANDLE(
group,all,
@@ -330,6 +255,6 @@ NSLCD_HANDLE(
log_log(LOG_DEBUG,"nslcd_group_all()");,
NSLCD_ACTION_GROUP_ALL,
(filter=group_filter,0),
- write_group(fp,entry)
+ write_group(fp,entry,NULL,NULL,1)
)