summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2006-11-01 22:48:46 +0000
committerArthur de Jong <arthur@arthurdejong.org>2006-11-01 22:48:46 +0000
commit78ee48f451bca5932a446c4df202a9ff5dabfd2f (patch)
tree8f2765c46296be9eef39926294f9bb59fbcc50f7
parentfc456f58013e8aa259e6bb58d5346af5ee57b445 (diff)
implement NSS side of getgrnam(), getgrgid() and {set,get,end}grent()
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/libnss_ldapd@53 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r--nslcd.h10
-rw-r--r--nss/Makefile.am2
-rw-r--r--nss/group.c145
-rw-r--r--testnss.c73
4 files changed, 214 insertions, 16 deletions
diff --git a/nslcd.h b/nslcd.h
index b40cdc7..b58d5d0 100644
--- a/nslcd.h
+++ b/nslcd.h
@@ -78,7 +78,7 @@
#define LDF_GROUP \
LDF_STRING(GROUP_NAME) \
LDF_STRING(GROUP_PASSWD) \
- LDF_TYPE(GROUP_GIF,gid_t) \
+ LDF_TYPE(GROUP_GID,gid_t) \
LDF_LOOP( \
LDF_STRING(GROUP_MEMBER) \
)
@@ -131,11 +131,9 @@
#define NSLCD_RT_GETGRBYGID 2004
#define NSLCD_RT_GETHOSTBYNAME 3005
#define NSLCD_RT_GETHOSTBYADDR 3008
-
-/* Response data types */
-#define NSLCD_DT_BUF 1000 /* any data, blob */
-#define NSLCD_DT_HEADER 2001 /* initial response header */
-#define NSLCD_DT_PASSWD 3001 /* struct passwd */
+#define NSLCD_ACTION_GROUP_BYNAME 5001
+#define NSLCD_ACTION_GROUP_BYGID 5002
+#define NSLCD_ACTION_GROUP_ALL 5003
/* Request result. */
#define NSLCD_RS_UNAVAIL 2 /* sevice unavailable */
diff --git a/nss/Makefile.am b/nss/Makefile.am
index 0b63c31..104a100 100644
--- a/nss/Makefile.am
+++ b/nss/Makefile.am
@@ -22,4 +22,4 @@ noinst_LIBRARIES = libnss.a
libnss_a_SOURCES = common.c common.h exports.h ../nslcd-client.h \
../nslcd.h ../nslcd-common.h \
- passwd.c aliases.c
+ aliases.c group.c passwd.c
diff --git a/nss/group.c b/nss/group.c
new file mode 100644
index 0000000..ef04b8f
--- /dev/null
+++ b/nss/group.c
@@ -0,0 +1,145 @@
+/*
+ group.c - NSS lookup functions for group database
+
+ Copyright (C) 2006 West Consulting
+ Copyright (C) 2006 Arthur de Jong
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ MA 02110-1301 USA
+*/
+
+#include "config.h"
+
+#include <string.h>
+#include <nss.h>
+#include <errno.h>
+
+#include "exports.h"
+#include "nslcd-client.h"
+#include "common.h"
+
+
+/* generic macros in development here */
+#define READ_LOOP_NULLTERM(fp,arr,opr) \
+ READ_TYPE(fp,tmpint32,int32_t); \
+ /* allocate room for *char[num+1] */ \
+ tmp2int32=(tmpint32+1)*sizeof(char *); \
+ if ((bufptr+(size_t)tmp2int32)>buflen) \
+ { ERROR_OUT_BUFERROR(fp) } /* will not fit */ \
+ (arr)=(char **)(buffer+bufptr); \
+ /* set last entry to NULL */ \
+ (arr)[tmpint32]=NULL; \
+ /* read all entries */ \
+ bufptr+=(size_t)tmpint32; \
+ for (tmp2int32=0;tmp2int32<tmpint32;tmp2int32++) \
+ { \
+ opr \
+ }
+
+/* macros for expanding the LDF_GROUP macro */
+#define LDF_STRING(field) READ_STRING_BUF(fp,field)
+#define LDF_TYPE(field,type) READ_TYPE(fp,field,type)
+#define LDF_LOOP(field) READ_LOOP_NULLTERM(fp,result->gr_mem,field)
+#define GROUP_NAME result->gr_name
+#define GROUP_PASSWD result->gr_passwd
+#define GROUP_GID result->gr_gid
+#define GROUP_MEMBER result->gr_mem[tmp2int32]
+
+enum nss_status _nss_ldap_getgrnam_r(const char *name,struct group *result,char *buffer,size_t buflen,int *errnop)
+{
+ FILE *fp;
+ size_t bufptr=0;
+ int32_t tmpint32,tmp2int32;
+ /* open socket and write request */
+ OPEN_SOCK(fp);
+ WRITE_REQUEST(fp,NSLCD_ACTION_GROUP_BYNAME);
+ WRITE_STRING(fp,name);
+ WRITE_FLUSH(fp);
+ /* read response */
+ READ_RESPONSEHEADER(fp,NSLCD_ACTION_GROUP_BYNAME);
+ READ_RESPONSE(fp);
+ LDF_GROUP;
+ /* close socket and we're done */
+ fclose(fp);
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status _nss_ldap_getgrgid_r(gid_t gid,struct group *result,char *buffer,size_t buflen,int *errnop)
+{
+ FILE *fp;
+ size_t bufptr=0;
+ int32_t tmpint32,tmp2int32;
+ /* open socket and write request */
+ OPEN_SOCK(fp);
+ WRITE_REQUEST(fp,NSLCD_ACTION_GROUP_BYGID);
+ WRITE_TYPE(fp,gid,gid_t);
+ WRITE_FLUSH(fp);
+ /* read response */
+ READ_RESPONSEHEADER(fp,NSLCD_ACTION_GROUP_BYGID);
+ READ_RESPONSE(fp);
+ LDF_GROUP;
+ /* close socket and we're done */
+ fclose(fp);
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status _nss_ldap_initgroups(const char *user,gid_t group,long int *start,long int *size,gid_t *groups,long int limit,int *errnop);
+enum nss_status _nss_ldap_initgroups_dyn(const char *user,gid_t group,long int *start,long int *size,gid_t **groupsp,long int limit,int *errnop);
+
+/* thread-local file pointer to an ongoing request */
+static __thread FILE *pwentfp;
+#define fp pwentfp
+
+enum nss_status _nss_ldap_setgrent(void)
+{
+ int32_t tmpint32;
+ /* this is to satisfy our macros */
+ int errnocp;
+ int *errnop;
+ errnop=&errnocp;
+ /* close the existing stream if it is still open */
+ if (fp!=NULL)
+ _nss_ldap_endpwent();
+ /* open a new stream and write the request */
+ OPEN_SOCK(fp);
+ WRITE_REQUEST(fp,NSLCD_ACTION_GROUP_ALL);
+ WRITE_FLUSH(fp);
+ /* read response header */
+ READ_RESPONSEHEADER(fp,NSLCD_ACTION_GROUP_ALL);
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status _nss_ldap_getgrent_r(struct group *result,char *buffer,size_t buflen,int *errnop)
+{
+ int32_t tmpint32,tmp2int32;
+ size_t bufptr=0;
+ /* check that we have a valid file descriptor */
+ if (fp==NULL)
+ {
+ *errnop=ENOENT;
+ return NSS_STATUS_UNAVAIL;
+ }
+ /* read a response */
+ READ_RESPONSE(fp);
+ LDF_GROUP;
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status _nss_ldap_endgrent(void)
+{
+ if (fp!=NULL)
+ fclose(fp);
+ return NSS_STATUS_SUCCESS;
+}
diff --git a/testnss.c b/testnss.c
index 48b0da0..f9aaa15 100644
--- a/testnss.c
+++ b/testnss.c
@@ -47,21 +47,37 @@ static void printalias(struct aliasent *alias)
"}\n",(int)alias->alias_local);
}
+static void printgroup(struct group *group)
+{
+ int i;
+ printf("struct group {\n"
+ " gr_name=\"%s\",\n"
+ " gr_passwd=\"%s\",\n"
+ " gr_gid=%d,\n",
+ group->gr_name,group->gr_passwd,(int)group->gr_gid);
+ for (i=0;group->gr_mem[i]!=NULL;i++)
+ printf(" gr_mem[%d]=\"%s\",\n",
+ i,group->gr_mem[i]);
+ printf(" gr_mem[%d]=NULL\n"
+ "}\n",i);
+}
+
/* the main program... */
int main(int argc,char *argv[])
{
- struct passwd result;
+ struct passwd passwdresult;
struct aliasent aliasresult;
+ struct group groupresult;
char buffer[1024];
enum nss_status res;
int errnocp;
/* test getpwnam() */
printf("\nTEST getpwnam()\n");
- res=_nss_ldap_getpwnam_r("arthur",&result,buffer,1024,&errnocp);
+ res=_nss_ldap_getpwnam_r("arthur",&passwdresult,buffer,1024,&errnocp);
printf("status=%s\n",nssstatus(res));
if (res==NSS_STATUS_SUCCESS)
- printpasswd(&result);
+ printpasswd(&passwdresult);
else
{
printf("errno=%d:%s\n",(int)errno,strerror(errno));
@@ -70,10 +86,10 @@ int main(int argc,char *argv[])
/* test getpwnam() with non-existing user */
printf("\nTEST getpwnam()\n");
- res=_nss_ldap_getpwnam_r("arthurs",&result,buffer,1024,&errnocp);
+ res=_nss_ldap_getpwnam_r("arthurs",&passwdresult,buffer,1024,&errnocp);
printf("status=%s\n",nssstatus(res));
if (res==NSS_STATUS_SUCCESS)
- printpasswd(&result);
+ printpasswd(&passwdresult);
else
{
printf("errno=%d:%s\n",(int)errno,strerror(errno));
@@ -82,10 +98,10 @@ int main(int argc,char *argv[])
/* test getpwuid() */
printf("\nTEST getpwuid()\n");
- res=_nss_ldap_getpwuid_r(180,&result,buffer,1024,&errnocp);
+ res=_nss_ldap_getpwuid_r(180,&passwdresult,buffer,1024,&errnocp);
printf("status=%s\n",nssstatus(res));
if (res==NSS_STATUS_SUCCESS)
- printpasswd(&result);
+ printpasswd(&passwdresult);
else
{
printf("errno=%d:%s\n",(int)errno,strerror(errno));
@@ -96,10 +112,10 @@ int main(int argc,char *argv[])
printf("\nTEST {set,get,end}pwent()\n");
res=_nss_ldap_setpwent();
printf("status=%s\n",nssstatus(res));
- while ((res=_nss_ldap_getpwent_r(&result,buffer,1024,&errnocp))==NSS_STATUS_SUCCESS)
+ while ((res=_nss_ldap_getpwent_r(&passwdresult,buffer,1024,&errnocp))==NSS_STATUS_SUCCESS)
{
printf("status=%s\n",nssstatus(res));
- printpasswd(&result);
+ printpasswd(&passwdresult);
}
printf("status=%s\n",nssstatus(res));
printf("errno=%d:%s\n",(int)errno,strerror(errno));
@@ -119,5 +135,44 @@ int main(int argc,char *argv[])
printf("errnocp=%d:%s\n",(int)errnocp,strerror(errnocp));
}
+ /* test getgrnam() */
+ printf("\nTEST getgrnam()\n");
+ res=_nss_ldap_getgrnam_r("audio",&groupresult,buffer,1024,&errnocp);
+ printf("status=%s\n",nssstatus(res));
+ if (res==NSS_STATUS_SUCCESS)
+ printgroup(&groupresult);
+ else
+ {
+ printf("errno=%d:%s\n",(int)errno,strerror(errno));
+ printf("errnocp=%d:%s\n",(int)errnocp,strerror(errnocp));
+ }
+
+ /* test getgrgid() */
+ printf("\nTEST getgrgid()\n");
+ res=_nss_ldap_getgrgid_r(24,&groupresult,buffer,1024,&errnocp);
+ printf("status=%s\n",nssstatus(res));
+ if (res==NSS_STATUS_SUCCESS)
+ printgroup(&groupresult);
+ else
+ {
+ printf("errno=%d:%s\n",(int)errno,strerror(errno));
+ printf("errnocp=%d:%s\n",(int)errnocp,strerror(errnocp));
+ }
+
+ /* test {set,get,end}grent() */
+ printf("\nTEST {set,get,end}grent()\n");
+ res=_nss_ldap_setgrent();
+ printf("status=%s\n",nssstatus(res));
+ while ((res=_nss_ldap_getgrent_r(&groupresult,buffer,1024,&errnocp))==NSS_STATUS_SUCCESS)
+ {
+ printf("status=%s\n",nssstatus(res));
+ printpasswd(&groupresult);
+ }
+ printf("status=%s\n",nssstatus(res));
+ printf("errno=%d:%s\n",(int)errno,strerror(errno));
+ printf("errnocp=%d:%s\n",(int)errnocp,strerror(errnocp));
+ res=_nss_ldap_endgrent();
+ printf("status=%s\n",nssstatus(res));
+
return 0;
}