Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2006-10-25 17:11:36 +0200
committerArthur de Jong <arthur@arthurdejong.org>2006-10-25 17:11:36 +0200
commitb586bf84c0bd966abf5cb3d26fa956353d77f9e1 (patch)
tree1f1ea739a95397ccd9239ac28654d0699210e6e8
parentef0b1593cdb41e6cbd484bc16e02a21a2fa6b673 (diff)
add some basic minimal NSS code that can be generated from macros
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/libnss_ldapd@24 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r--Makefile.am40
-rw-r--r--nslcd-client.c40
-rw-r--r--nslcd-client.h13
-rw-r--r--nslcd.h120
-rw-r--r--nss/Makefile.am32
-rw-r--r--nss/aliases.c14
-rw-r--r--nss/common.c20
-rw-r--r--nss/common.h44
-rw-r--r--nss/exports.h108
-rw-r--r--nss/passwd.c86
10 files changed, 447 insertions, 70 deletions
diff --git a/Makefile.am b/Makefile.am
index 3a2bfa7..5cb653e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,26 +19,21 @@
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
# MA 02110-1301 USA
-noinst_PROGRAMS = nss_ldap.so nslcd ndlscdcl
-INST_UID=root
-if AIX
-INST_GID=system
-else
-INST_GID=root
-endif
+SUBDIRS = nss
+
+noinst_PROGRAMS = nss_ldap.so nslcd testnss testnslcd
+
+man_MANS = nss_ldap.5
EXTRA_DIST = CVSVersionInfo.txt ChangeLog \
AUTHORS ANNOUNCE NEWS INSTALL README COPYING \
ldap.conf nsswitch.ldap
-man_MANS = nss_ldap.5
-
nss_ldap_so_SOURCES = ldap-nss.c ldap-pwd.c ldap-grp.c ldap-netgrp.c ldap-rpc.c \
ldap-hosts.c ldap-network.c ldap-proto.c ldap-spwd.c \
ldap-alias.c ldap-service.c ldap-schema.c ldap-ethers.c \
ldap-automount.c util.c resolve.c \
dnsconfig.c pagectrl.c
-
nss_ldap_so_LDFLAGS = @nss_ldap_so_LDFLAGS@
nslcd_SOURCES = nslcd.c nslcd.h \
@@ -49,7 +44,10 @@ nslcd_SOURCES = nslcd.c nslcd.h \
dnsconfig.c pagectrl.c \
ldap-pwd.c
-ndlscdcl_SOURCES = nslcd-client.c nslcd-client.h nslcd.h
+testnslcd_SOURCES = testnslcd.c nslcd-client.c nslcd-client.h nslcd.h
+
+testnss_SOURCES = testnss.c
+testnss_LDADD = nss/libnss.a
NSS_LDAP_PATH_CONF = @NSS_LDAP_PATH_CONF@
NSS_LDAP_PATH_ROOTPASSWD = @NSS_LDAP_PATH_ROOTPASSWD@
@@ -65,16 +63,22 @@ NSS_VERS = $(shell ls /lib/libnss_files.so.? | tail -n 1 | sed -e 's/\/lib\/libn
NSS_LDAP_NSS_VERSIONED = libnss_ldap.so.$(NSS_VERS)
endif
-if USE_NATIVE_LINKER
-NATIVE_LINK = $(nss_ldap_so_LD) $(AM_LDFLAGS) -o $@
+##if USE_NATIVE_LINKER
+##NATIVE_LINK = $(nss_ldap_so_LD) $(AM_LDFLAGS) -o $@
+##else
+##GNU_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+##endif
+### This is horrible but appears to be the only way to work with
+### recent versions of automake. Any better ideas, let me know.
+##LINK = $(NATIVE_LINK) $(GNU_LINK)
+
+INST_UID=root
+if AIX
+INST_GID=system
else
-GNU_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+INST_GID=root
endif
-# This is horrible but appears to be the only way to work with
-# recent versions of automake. Any better ideas, let me know.
-LINK = $(NATIVE_LINK) $(GNU_LINK)
-
install-exec-local: nss_ldap.so
@$(NORMAL_INSTALL)
if GLIBC
diff --git a/nslcd-client.c b/nslcd-client.c
index cfb91d5..8dfbf88 100644
--- a/nslcd-client.c
+++ b/nslcd-client.c
@@ -76,7 +76,7 @@ FILE *nslcd_client_open()
/* write a request message, returns <0 in case of errors */
-int nslcd_client_writerequest(FILE *sock,int type,char *name,size_t count)
+int nslcd_client_writerequest(FILE *sock,int type,const char *name,size_t count)
{
int32_t tmpint32;
/* see nslcd.h for protocol definition */
@@ -92,41 +92,13 @@ int nslcd_client_writerequest(FILE *sock,int type,char *name,size_t count)
/* read a response message */
-int nslcd_client_readresponse(FILE *sock,void *buf,size_t bufsize)
+int nslcd_client_readresponse(FILE *sock,int type)
{
+
+
+
+
/* see nslcd.h for protocol definition */
/* TODO: validate */
return -1; /* not implemented */
}
-
-
-/* the main program... , for now just for testing */
-int main(int argc,char *argv[])
-{
- FILE *sock;
- char buf[1024];
- /* open socket */
- if ((sock=nslcd_client_open())==NULL)
- {
- fprintf(stderr,"test: socket unavailable: %s\n", strerror(errno));
- return 1;
- }
- /* write request */
- if (nslcd_client_writerequest(sock,NSLCD_RT_GETPWBYNAME,"aart",6)<0)
- {
- fprintf(stderr,"test: write failed: %s\n", strerror(errno));
- return 1;
- }
- /* read response */
- if (nslcd_client_readresponse(sock,buf,1024)<0)
- {
- fprintf(stderr,"test: read failed: %s\n", strerror(errno));
- return 1;
- }
- /* print results */
-
-
- /* close */
- fclose(sock);
- return 0;
-}
diff --git a/nslcd-client.h b/nslcd-client.h
index 4511695..8fac6be 100644
--- a/nslcd-client.h
+++ b/nslcd-client.h
@@ -27,14 +27,21 @@
#include "nslcd.h"
+/* Extra request results. */
+#define NSLCD_RS_SMALLBUF 100 /* buffer too small */
+
/* returns a socket to the server or NULL on error (see errno),
socket should be closed with fclose() */
FILE *nslcd_client_open(void);
/* write a request message, returns <0 in case of errors */
-int nslcd_client_writerequest(FILE *sock,int type,char *name,size_t count);
+int nslcd_client_writerequest(FILE *sock,int type,const char *name,size_t count);
+
+/* read a response message, returns NSLCD_RS_* */
+int nslcd_client_readresponse(FILE *sock,int type);
-/* read a response message */
-int nslcd_client_readresponse(FILE *sock,void *buf,size_t bufsize);
+/* read a response parameter, returns NSLCD_RS_*, which can include
+ the extra client status values */
+int nslcd_client_readdate(FILE *sock,int type,void *buf,size_t bufsize);
#endif /* not _NSLCD_CLIENT_H */
diff --git a/nslcd.h b/nslcd.h
index 42d7676..5c1c943 100644
--- a/nslcd.h
+++ b/nslcd.h
@@ -35,9 +35,99 @@
A response looks like:
int32 NSLCD_VERSION
int32 NSLCD_RT_* (the original request type)
+ int32 NSLCD_RS_* (response code)
+ Followed by the data for the response (if call was sucessful)
+ int32 NSLCD_DT_BUF (data type)
int32 length(result)
... result
- int32 NSLCD_MAGIC
+*/
+
+/*
+ These are the data types that can be transferred in the protocol.
+ They are defined as macros so they can be expanded to code
+ later on.
+
+ LDF_STRING:
+ int32 length
+ ... length bytes
+ LDF_TYPE:
+ sizeof(type) value
+ LDF_LOOP:
+ int32 number
+ number times the containing thing(s)
+*/
+
+#define LDF_ALIAS \
+ LDF_STRING(ALIAS_NAME) \
+ LDF_LOOP( \
+ LDF_STRING(ALIAS_RCPT) \
+ )
+
+/* AUTOMOUNT - TBD */
+
+#define LDF_ETHER \
+ LDF_TYPE(ETHER_ADDR,"123456")
+
+#define LDF_GROUP \
+ LDF_STRING(GROUP_NAME) \
+ LDF_STRING(GROUP_PASSWD) \
+ LDF_TYPE(GROUP_GIF,gid_t) \
+ LDF_LOOP( \
+ LDF_STRING(GROUP_MEMBER) \
+ )
+
+/* HOSTS - TBD - gethostbyname - struct hostent - gethostbyaddr - struct in_addr */
+
+/* NETGROUP - TBD */
+
+/* NETWORKS - TBD - struct netent */
+
+#define LDF_PASSWD \
+ LDF_STRING(PASSWD_NAME) \
+ LDF_STRING(PASSWD_PASSWD) \
+ LDF_TYPE(PASSWD_UID,uid_t) \
+ LDF_TYPE(PASSWD_GID,gid_t) \
+ LDF_STRING(PASSWD_GECOS) \
+ LDF_STRING(PASSWD_DIR) \
+ LDF_STRING(PASSWD_SHELL)
+
+/* PROTOCOLS - TBD - getprotobyname - struct protoent */
+
+#define LDF_RPC \
+ LDF_STRING(RPC_NAME) \
+ LDF_LOOP( \
+ LDF_STRING(RPC_ALIAS) \
+ ) \
+ LDF_TYPE(RPC_NUMBER,int32_t)
+
+/* SERVICES - TBD - getservbyname - struct servent */
+
+/* SHADOW - TBD - getspnam - struct spwd */
+/*
+ Data units:
+
+functions for
+read_str(FILE *fp, buf, ptr, &result, size):
+ - read string length from stream
+ - check if there is enough room in buffer:
+ - no: fail (maybe do some rollback)
+ - read string in buffer
+ - increment prt with string size
+ - store pointer in &result or NULL on error
+read_int(FILE *fp, int*i)
+ - read int32
+ - store in &i
+
+code like:
+
+ strcut foobar
+ foobar.field=0
+ return read_str(fp..,&foobar.field,...) ||
+ read_int(...)
+
+return NSLCD_RS_*
+
+
*/
/* TODO: generate this file from a .in file */
@@ -56,21 +146,21 @@
#define NSLCD_MAGIC 0x8642
/* Request types. */
-#define NSLCD_RT_GETPWBYNAME 1
-#define NSLCD_RT_GETPWBYUID 2
-#define NSLCD_RT_GETGRBYNAME 3
-#define NSLCD_RT_GETGRBYGID 4
-#define NSLCD_RT_GETHOSTBYNAME 5
-#define NSLCD_RT_GETHOSTBYNAMEv6 7
-#define NSLCD_RT_GETHOSTBYADDR 8
-#define NSLCD_RT_GETHOSTBYADDRv6 9
-#define NSLCD_RT_LASTDBREQ NSLCD_RT_GETHOSTBYADDRv6
+#define NSLCD_RT_GETPWBYNAME 1001
+#define NSLCD_RT_GETPWBYUID 1002
+#define NSLCD_RT_GETGRBYNAME 2003
+#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 */
/* Request result. */
-#define NSLCD_RS_TRYAGAIN 1
-#define NSLCD_RS_UNAVAIL 2
-#define NSLCD_RS_NOTFOUND 3
-#define NSLCD_RS_SUCCESS 0
-#define NSLCD_RS_RETURN 4
+#define NSLCD_RS_UNAVAIL 2 /* sevice unavailable */
+#define NSLCD_RS_NOTFOUND 3 /* key was not found */
+#define NSLCD_RS_SUCCESS 0 /* everything ok */
#endif /* not _NSLCD_H */
diff --git a/nss/Makefile.am b/nss/Makefile.am
new file mode 100644
index 0000000..5d7ee6f
--- /dev/null
+++ b/nss/Makefile.am
@@ -0,0 +1,32 @@
+# Makefile.am - use automake to generate Makefile.in
+#
+# 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
+
+noinst_LIBRARIES = libnss.a
+noinst_PROGRAMS = libnss_ldap.so
+
+libnss_a_SOURCES = common.c common.h exports.h ../nslcd-client.h \
+ passwd.c aliases.c
+libnss_a_LIBADD = ../nslcd-client.o
+
+libnss_ldap_so_SOURCES =
+libnss_ldap_so_LDADD = libnss.a
+libnss_ldap_so_LDFLAGS = -shared -Wl,-soname,libnss_ldap.so.2
+
+# gcc -shared -o libnss_NAME.so.2 -Wl,-soname,libnss_NAME.so.2 OBJECTS
diff --git a/nss/aliases.c b/nss/aliases.c
new file mode 100644
index 0000000..307b374
--- /dev/null
+++ b/nss/aliases.c
@@ -0,0 +1,14 @@
+
+#include "exports.h"
+
+enum nss_status _nss_ldap_getaliasbyname_r(const char *name,struct aliasent *result,char *buffer,size_t buflen,int *errnop)
+{}
+
+enum nss_status _nss_ldap_setaliasent(void)
+{}
+
+enum nss_status _nss_ldap_getaliasent_r(struct aliasent *result,char *buffer,size_t buflen,int *errnop)
+{}
+
+enum nss_status _nss_ldap_endaliasent(void)
+{}
diff --git a/nss/common.c b/nss/common.c
new file mode 100644
index 0000000..4aa1878
--- /dev/null
+++ b/nss/common.c
@@ -0,0 +1,20 @@
+
+#include <nss.h>
+
+#include "nslcd-client.h"
+#include "common.h"
+
+/* translates a nsklcd return code (as defined in nslcd.h) to
+ a nss code (as defined in nss.h) */
+enum nss_status nslcd2nss(int code)
+{
+ switch (code)
+ {
+ case NSLCD_RS_UNAVAIL: return NSS_STATUS_UNAVAIL;
+ case NSLCD_RS_NOTFOUND: return NSS_STATUS_NOTFOUND;
+ case NSLCD_RS_SUCCESS: return NSS_STATUS_SUCCESS;
+ case NSLCD_RS_SMALLBUF: return NSS_STATUS_TRYAGAIN;
+ default: return NSS_STATUS_UNAVAIL;
+ }
+}
+
diff --git a/nss/common.h b/nss/common.h
new file mode 100644
index 0000000..d54cf6e
--- /dev/null
+++ b/nss/common.h
@@ -0,0 +1,44 @@
+
+#include <nss.h>
+
+/* translates a nsklcd return code (as defined in nslcd.h) to
+ a nss code (as defined in nss.h) */
+enum nss_status nslcd2nss(int code);
+
+/* Macros for reading and writing to sockets. */
+#define OPEN_SOCK \
+ if ((fp=nslcd_client_open())==NULL) \
+ { \
+ *errnop=errno; \
+ return NSS_STATUS_UNAVAIL; \
+ }
+
+#define ERROR_OUT(status,errnoval) \
+ { \
+ fclose(fp); \
+ *errnop=errnoval; \
+ return (status); \
+ }
+
+#define READ(fp,ptr,size) \
+ if (fread(ptr,size,1,fp)<1) \
+ ERROR_OUT(NSS_STATUS_UNAVAIL,ENOENT);
+
+#define LDF_STRING(field) \
+ /* read the size of the string */ \
+ READ(fp,&sz,sizeof(int32_t)); \
+ /* FIXME: add error checking and sanity checking */ \
+ /* check if read would fit */ \
+ if ((bufptr+(size_t)sz+1)>buflen) \
+ ERROR_OUT(NSS_STATUS_TRYAGAIN,ERANGE); /* will not fit */ \
+ /* read string from the stream */ \
+ READ(fp,buffer+bufptr,(size_t)sz); \
+ /* TODO: check that string does not contain \0 */ \
+ /* null-terminate string in buffer */ \
+ buffer[bufptr+sz]='\0'; \
+ /* prepare result */ \
+ (field)=buffer+bufptr; \
+ bufptr+=sz+1;
+
+#define LDF_TYPE(field,type) \
+ READ(fp,&(field),sizeof(type))
diff --git a/nss/exports.h b/nss/exports.h
new file mode 100644
index 0000000..b6f6c48
--- /dev/null
+++ b/nss/exports.h
@@ -0,0 +1,108 @@
+/* nss.h -all functions exported by the library */
+
+#ifndef _NSS_EXPORTS_H
+#define _NSS_EXPORTS_H 1
+
+#include <nss.h>
+#include <aliases.h>
+#include <netinet/ether.h>
+#include <sys/types.h>
+#include <grp.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <shadow.h>
+
+/*
+ These are prototypes for functions exported from the ldap nss module.
+ For more complete definitions of these functions check the GLIBC
+ documentation.
+
+ Other services than those mentioned here are currently not implemented.
+ Contributions are welcome.
+*/
+
+/* aliases - mail aliases */
+enum nss_status _nss_ldap_getaliasbyname_r(const char *name,struct aliasent *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_setaliasent(void);
+enum nss_status _nss_ldap_getaliasent_r(struct aliasent *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_endaliasent(void);
+
+/* automount - automounter maps */
+enum nss_status _nss_ldap_getautomntbyname_r(void *private,const char *key,const char **canon_key,const char **value,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_setautomntent(const char *mapname,void **private);
+enum nss_status _nss_ldap_getautomntent_r(void *private,const char **key,const char **value,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_endautomntent(void **private);
+
+/* ethers - ethernet numbers */
+enum nss_status _nss_ldap_gethostton_r(const char *name,struct ether_addr *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_getntohost_r(struct ether_addr *addr,struct ether_addr *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_setetherent(void);
+enum nss_status _nss_ldap_getetherent_r(struct ether_addr *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_endetherent(void);
+
+/* group - groups of users */
+enum nss_status _nss_ldap_getgrnam_r(const char *name,struct group *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_getgrgid_r(gid_t gid,struct group *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_setgrent(void);
+enum nss_status _nss_ldap_getgrent_r(struct group *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_endgrent(void);
+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);
+
+/* hosts - host names and numbers */
+enum nss_status _nss_ldap_gethostbyname_r(const char *name,struct hostent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop);
+enum nss_status _nss_ldap_gethostbyname2_r(const char *name,int af,struct hostent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop);
+enum nss_status _nss_ldap_gethostbyaddr_r(struct in_addr *addr,int len,int type,struct hostent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop);
+enum nss_status _nss_ldap_sethostent(void);
+enum nss_status _nss_ldap_gethostent_r(struct hostent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop);
+enum nss_status _nss_ldap_endhostent(void);
+
+/* netgroup - list of host and users */
+/* DISABLED FOR NOW
+enum nss_status _nss_ldap_setnetgrent(char *group,struct __netgrent *result);
+enum nss_status _nss_ldap_getnetgrent_r(struct __netgrent *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_endnetgrent(struct __netgrent *result);
+*/
+
+/* networks - network names and numbers */
+enum nss_status _nss_ldap_getnetbyname_r(const char *name,struct netent *result,char *buffer,size_t buflen,int *errnop,int *herrnop);
+enum nss_status _nss_ldap_getnetbyaddr_r(unsigned long addr,int type,struct netent *result,char *buffer,size_t buflen,int *errnop,int *herrnop);
+enum nss_status _nss_ldap_setnetent(void);
+enum nss_status _nss_ldap_getnetent_r(struct netent *result,char *buffer,size_t buflen,int *errnop,int *herrnop);
+enum nss_status _nss_ldap_endnetent(void);
+
+/* passwd - user database and passwords */
+enum nss_status _nss_ldap_getpwnam_r(const char *name,struct passwd *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_getpwuid_r(uid_t uid,struct passwd *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_setpwent(void);
+enum nss_status _nss_ldap_getpwent_r(struct passwd *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_endpwent(void);
+
+/* protocols - network protocols */
+enum nss_status _nss_ldap_getprotobyname_r(const char *name,struct protoent *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_getprotobynumber_r(int number,struct protoent *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_setprotoent(void);
+enum nss_status _nss_ldap_getprotoent_r(struct protoent *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_endprotoent(void);
+
+/* rpc - remote procedure call names and numbers */
+enum nss_status _nss_ldap_getrpcbyname_r(const char *name,struct rpcent *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_getrpcbynumber_r(int number,struct rpcent *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_setrpcent(void);
+enum nss_status _nss_ldap_getrpcent_r(struct rpcent *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_endrpcent(void);
+
+/* services - network services */
+enum nss_status _nss_ldap_getservbyname_r(const char *name,const char *proto,struct servent *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_getservbyport_r(int port,const char *proto,struct servent *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_setservent(void);
+enum nss_status _nss_ldap_getservent_r(struct servent *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_endservent(void);
+
+/* shadow - extended user information */
+enum nss_status _nss_ldap_getspnam_r(const char *name,struct spwd *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_setspent(void);
+enum nss_status _nss_ldap_getspent_r(struct spwd *result,char *buffer,size_t buflen,int *errnop);
+enum nss_status _nss_ldap_endspent(void);
+
+#endif /* not NSS_EXPORTS */
diff --git a/nss/passwd.c b/nss/passwd.c
new file mode 100644
index 0000000..732eaaf
--- /dev/null
+++ b/nss/passwd.c
@@ -0,0 +1,86 @@
+/*
+ passwd.c - NSS lookup functions for passwd 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 <string.h>
+#include <nss.h>
+#include <errno.h>
+
+#include "exports.h"
+#include "nslcd-client.h"
+#include "common.h"
+
+/* Macros for expanding the LDF_PASSWD macro. */
+#define PASSWD_NAME res.pw_name
+#define PASSWD_PASSWD res.pw_passwd
+#define PASSWD_UID res.pw_uid
+#define PASSWD_GID res.pw_gid
+#define PASSWD_GECOS res.pw_gecos
+#define PASSWD_DIR res.pw_dir
+#define PASSWD_SHELL res.pw_shell
+
+enum nss_status _nss_ldap_getpwnam_r(const char *name,struct passwd *result,char *buffer,size_t buflen,int *errnop)
+{
+ FILE *fp;
+ size_t bufptr=0;
+ struct passwd res;
+ int32_t sz;
+
+ /* open socket */
+ OPEN_SOCK
+
+ /* write request to nslcd */
+ if (nslcd_client_writerequest(fp,NSLCD_RT_GETPWBYNAME,name,strlen(name)))
+ ERROR_OUT(NSS_STATUS_UNAVAIL,ENOENT);
+
+ /* read response header */
+ if ((sz=nslcd_client_readresponse(fp,NSLCD_RT_GETPWBYNAME))!=NSLCD_RS_SUCCESS)
+ ERROR_OUT(nslcd2nss(sz),ENOENT)
+
+ /* read struct passwd */
+ LDF_PASSWD;
+
+ /* close socket and we're done */
+ fclose(fp);
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status _nss_ldap_getpwuid_r(uid_t uid,struct passwd *result,char *buffer,size_t buflen,int *errnop)
+{
+ *errnop=ENOENT;
+ return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_ldap_setpwent(void)
+{
+ return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_ldap_getpwent_r(struct passwd *result,char *buffer,size_t buflen,int *errnop)
+{
+ *errnop=ENOENT;
+ return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_ldap_endpwent(void)
+{
+ return NSS_STATUS_UNAVAIL;
+}