Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
path: root/nss
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2007-01-17 23:16:09 +0100
committerArthur de Jong <arthur@arthurdejong.org>2007-01-17 23:16:09 +0100
commit9a2c3e7624985e6110634e07d6b216e96b209adb (patch)
tree3b0edaa59e8b5fbf5eca0912262451f1669fa375 /nss
parent3ac313144f880db85fdbb6a271451f2f693aab44 (diff)
ensure that all NSS functions can be generated by the marcos in common.h and spell out the read_..() function for every type
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@227 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'nss')
-rw-r--r--nss/aliases.c18
-rw-r--r--nss/common.h8
-rw-r--r--nss/ethers.c24
-rw-r--r--nss/group.c104
-rw-r--r--nss/hosts.c142
-rw-r--r--nss/netgroup.c4
-rw-r--r--nss/networks.c119
-rw-r--r--nss/passwd.c32
-rw-r--r--nss/protocols.c26
-rw-r--r--nss/rpc.c26
-rw-r--r--nss/services.c77
-rw-r--r--nss/shadow.c31
12 files changed, 252 insertions, 359 deletions
diff --git a/nss/aliases.c b/nss/aliases.c
index 10b562b..3d1a48f 100644
--- a/nss/aliases.c
+++ b/nss/aliases.c
@@ -2,7 +2,7 @@
aliases.c - NSS lookup functions for aliases database
Copyright (C) 2006 West Consulting
- Copyright (C) 2006 Arthur de Jong
+ Copyright (C) 2006, 2007 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
@@ -29,12 +29,6 @@
#include "prototypes.h"
#include "common.h"
-/* macros for expanding the NSLCD_ALIAS macro */
-#define NSLCD_STRING(field) READ_STRING_BUF(fp,field)
-#define NSLCD_STRINGLIST(field) READ_STRINGLIST_NUM(fp,field,result->alias_members_len)
-#define ALIAS_NAME result->alias_name
-#define ALIAS_RCPTS result->alias_members
-
static enum nss_status read_aliasent(
FILE *fp,struct aliasent *result,
char *buffer,size_t buflen,int *errnop)
@@ -42,7 +36,8 @@ static enum nss_status read_aliasent(
int32_t tmpint32,tmp2int32;
size_t bufptr=0;
/* auto-genereted read code */
- NSLCD_ALIAS;
+ READ_STRING_BUF(fp,result->alias_name);
+ READ_STRINGLIST_NUM(fp,result->alias_members,result->alias_members_len);
/* fill in remaining gaps in struct */
result->alias_local=0;
/* we're done */
@@ -53,7 +48,9 @@ enum nss_status _nss_ldap_getaliasbyname_r(
const char *name,struct aliasent *result,
char *buffer,size_t buflen,int *errnop)
{
- NSS_BYNAME(NSLCD_ACTION_ALIAS_BYNAME,name,read_aliasent);
+ NSS_BYNAME(NSLCD_ACTION_ALIAS_BYNAME,
+ name,
+ read_aliasent(fp,result,buffer,buflen,errnop));
}
/* thread-local file pointer to an ongoing request */
@@ -66,7 +63,8 @@ enum nss_status _nss_ldap_setaliasent(void)
enum nss_status _nss_ldap_getaliasent_r(struct aliasent *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_GETENT(aliasentfp,read_aliasent);
+ NSS_GETENT(aliasentfp,
+ read_aliasent(aliasentfp,result,buffer,buflen,errnop));
}
enum nss_status _nss_ldap_endaliasent(void)
diff --git a/nss/common.h b/nss/common.h
index 5dd229d..5866cd0 100644
--- a/nss/common.h
+++ b/nss/common.h
@@ -2,7 +2,7 @@
common.h - common functions for NSS lookups
Copyright (C) 2006 West Consulting
- Copyright (C) 2006 Arthur de Jong
+ Copyright (C) 2006, 2007 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
@@ -120,7 +120,7 @@ FILE *nslcd_client_open(void);
name for reading a single result entry. The function is assumed
to have result, buffer, buflen and errnop parameters that define
the result structure, the user buffer with length and the
- errno to return. This macro should be called with some of
+ errno to return. This macro should be called through some of
the customized ones below. */
#define NSS_BYGEN(action,param,readfn) \
FILE *fp; \
@@ -135,7 +135,7 @@ FILE *nslcd_client_open(void);
READ_RESPONSEHEADER(fp,action); \
/* read response */ \
READ_RESPONSE_CODE(fp); \
- retv=readfn(fp,result,buffer,buflen,errnop); \
+ retv=readfn; \
/* close socket and we're done */ \
if (retv==NSS_STATUS_SUCCESS) \
fclose(fp); \
@@ -188,7 +188,7 @@ FILE *nslcd_client_open(void);
} \
/* read a response */ \
READ_RESPONSE_CODE(fp); \
- retv=readfn(fp,result,buffer,buflen,errnop); \
+ retv=readfn; \
/* check read result */ \
if (retv!=NSS_STATUS_SUCCESS) \
fp=NULL; /* file should be closed by now */ \
diff --git a/nss/ethers.c b/nss/ethers.c
index f057ead..2f62b18 100644
--- a/nss/ethers.c
+++ b/nss/ethers.c
@@ -2,7 +2,7 @@
ethers.c - NSS lookup functions for ethers database
Copyright (C) 2006 West Consulting
- Copyright (C) 2006 Arthur de Jong
+ Copyright (C) 2006, 2007 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
@@ -29,21 +29,14 @@
#include "prototypes.h"
#include "common.h"
-/* macros for expanding the NSLCD_ETHER macro */
-#define NSLCD_STRING(field) READ_STRING_BUF(fp,field)
-#define NSLCD_TYPE(field,type) READ_TYPE(fp,field,type)
-#define ETHER_NAME result->e_name
-#define ETHER_ADDR result->e_addr
-
static enum nss_status read_etherent(
FILE *fp,struct etherent *result,
char *buffer,size_t buflen,int *errnop)
{
int32_t tmpint32;
size_t bufptr=0;
- /* auto-genereted read code */
- NSLCD_ETHER;
- /* we're done */
+ READ_STRING_BUF(fp,result->e_name);
+ READ_TYPE(fp,result->e_addr,u_int8_t[6]);
return NSS_STATUS_SUCCESS;
}
@@ -52,7 +45,9 @@ enum nss_status _nss_ldap_gethostton_r(
const char *name,struct etherent *result,
char *buffer,size_t buflen,int *errnop)
{
- NSS_BYNAME(NSLCD_ACTION_ETHER_BYNAME,name,read_etherent);
+ NSS_BYNAME(NSLCD_ACTION_ETHER_BYNAME,
+ name,
+ read_etherent(fp,result,buffer,buflen,errnop));
}
/* map an ethernet address to the corresponding hostname */
@@ -60,7 +55,9 @@ enum nss_status _nss_ldap_getntohost_r(
const struct ether_addr *addr,struct etherent *result,
char *buffer,size_t buflen,int *errnop)
{
- NSS_BYTYPE(NSLCD_ACTION_ETHER_BYETHER,*addr,u_int8_t[6],read_etherent);
+ NSS_BYTYPE(NSLCD_ACTION_ETHER_BYETHER,
+ *addr,u_int8_t[6],
+ read_etherent(fp,result,buffer,buflen,errnop));
}
/* thread-local file pointer to an ongoing request */
@@ -75,7 +72,8 @@ enum nss_status _nss_ldap_getetherent_r(
struct etherent *result,
char *buffer,size_t buflen,int *errnop)
{
- NSS_GETENT(etherentfp,read_etherent);
+ NSS_GETENT(etherentfp,
+ read_etherent(etherentfp,result,buffer,buflen,errnop));
}
enum nss_status _nss_ldap_endetherent(void)
diff --git a/nss/group.c b/nss/group.c
index 550c05c..e65d988 100644
--- a/nss/group.c
+++ b/nss/group.c
@@ -2,7 +2,7 @@
group.c - NSS lookup functions for group database
Copyright (C) 2006 West Consulting
- Copyright (C) 2006 Arthur de Jong
+ Copyright (C) 2006, 2007 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
@@ -29,35 +29,67 @@
#include "prototypes.h"
#include "common.h"
-/* macros for expanding the NSLCD_GROUP macro */
-#define NSLCD_STRING(field) READ_STRING_BUF(fp,field)
-#define NSLCD_TYPE(field,type) READ_TYPE(fp,field,type)
-#define NSLCD_STRINGLIST(field) READ_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
-
static enum nss_status read_group(
FILE *fp,struct group *result,
char *buffer,size_t buflen,int *errnop)
{
int32_t tmpint32,tmp2int32,tmp3int32;
size_t bufptr=0;
- /* auto-genereted read code */
- NSLCD_GROUP;
- /* we're done */
+ READ_STRING_BUF(fp,result->gr_name);
+ READ_STRING_BUF(fp,result->gr_passwd);
+ READ_TYPE(fp,result->gr_gid,gid_t);
+ READ_STRINGLIST_NULLTERM(fp,result->gr_mem);
return NSS_STATUS_SUCCESS;
}
+/* read all group entries from the stream and add
+ gids of these groups to the list */
+static enum nss_status read_gids(
+ FILE *fp,long int *start,long int *size,
+ gid_t **groupsp,long int limit,int *errnop)
+{
+ int32_t res=NSLCD_RESULT_SUCCESS;
+ int32_t tmpint32,tmp2int32,tmp3int32;
+ gid_t gid;
+ int num=0;
+ /* loop over results */
+ while (res==NSLCD_RESULT_SUCCESS)
+ {
+ /* skip group name */
+ SKIP_STRING(fp);
+ /* skip passwd entry */
+ SKIP_STRING(fp);
+ /* read gid */
+ READ_TYPE(fp,gid,gid_t);
+ /* skip members */
+ SKIP_STRINGLIST(fp);
+ /* check if entry would fit and we have not returned too many */
+ if ( ((*start)>=(*size)) || (num>=limit) )
+ { ERROR_OUT_BUFERROR(fp); }
+ /* add gid to list */
+ (*groupsp)[*start++]=gid;
+ num++;
+ /* read next response code
+ (don't bail out on not success since we just want to build
+ up a list) */
+ READ_TYPE(fp,res,int32_t);
+ }
+ /* return the proper status code */
+ return (res==NSLCD_RESULT_NOTFOUND)?NSS_STATUS_SUCCESS:nslcd2nss(res);
+}
+
enum nss_status _nss_ldap_getgrnam_r(const char *name,struct group *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_BYNAME(NSLCD_ACTION_GROUP_BYNAME,name,read_group);
+ NSS_BYNAME(NSLCD_ACTION_GROUP_BYNAME,
+ name,
+ read_group(fp,result,buffer,buflen,errnop));
}
enum nss_status _nss_ldap_getgrgid_r(gid_t gid,struct group *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_BYTYPE(NSLCD_ACTION_GROUP_BYGID,gid,gid_t,read_group);
+ NSS_BYTYPE(NSLCD_ACTION_GROUP_BYGID,
+ gid,gid_t,
+ read_group(fp,result,buffer,buflen,errnop));
}
#ifdef REENABLE_WHEN_WORKING
@@ -81,43 +113,9 @@ 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)
{
- FILE *fp;
- int32_t cd;
- int32_t tmpint32,tmp2int32,tmp3int32;
- gid_t gid;
- int num=0;
- /* open socket and write the request */
- OPEN_SOCK(fp);
- WRITE_REQUEST(fp,NSLCD_ACTION_GROUP_BYMEMBER);
- WRITE_STRING(fp,user);
- WRITE_FLUSH(fp);
- /* read response */
- READ_RESPONSEHEADER(fp,NSLCD_ACTION_GROUP_BYMEMBER);
- /* read response code */
- READ_TYPE(fp,cd,int32_t);
- /* loop over results */
- while (cd==NSLCD_RESULT_SUCCESS)
- {
- /* skip group name */
- SKIP_STRING(fp);
- /* skip passwd entry */
- SKIP_STRING(fp);
- /* read gid */
- READ_TYPE(fp,gid,gid_t);
- /* skip members */
- SKIP_STRINGLIST(fp);
- /* check if entry would fit and we have not returned too many */
- if ( ((*start)>=(*size)) || (num>=limit) )
- { ERROR_OUT_BUFERROR(fp); }
- /* add gid to list */
- (*groupsp)[*start++]=gid;
- num++;
- /* read next response code */
- READ_TYPE(fp,cd,int32_t);
- }
- /* close socket and we're done */
- fclose(fp);
- return NSS_STATUS_SUCCESS;
+ NSS_BYNAME(NSLCD_ACTION_GROUP_BYMEMBER,
+ user,
+ read_gids(fp,start,size,groupsp,limit,errnop));
}
#endif /* REENABLE_WHEN_WORKING */
@@ -131,7 +129,7 @@ enum nss_status _nss_ldap_setgrent(int stayopen)
enum nss_status _nss_ldap_getgrent_r(struct group *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_GETENT(grentfp,read_group);
+ NSS_GETENT(grentfp,read_group(grentfp,result,buffer,buflen,errnop));
}
enum nss_status _nss_ldap_endgrent(void)
diff --git a/nss/hosts.c b/nss/hosts.c
index 77bb434..72a9c6c 100644
--- a/nss/hosts.c
+++ b/nss/hosts.c
@@ -2,7 +2,7 @@
hosts.c - NSS lookup functions for hosts database
Copyright (C) 2006 West Consulting
- Copyright (C) 2006 Arthur de Jong
+ Copyright (C) 2006, 2007 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
@@ -112,33 +112,23 @@ static enum nss_status read_hostent(
return NSS_STATUS_SUCCESS;
}
-/* this function looks up a single host entry and returns all the addresses
- associated with the host in a single address familiy
- name - IN - hostname to lookup
- af - IN - address familty to present results for
- result - OUT - entry found
- buffer,buflen - OUT - buffer to store allocated stuff on
- errnop,h_errnop - OUT - for reporting errors */
-enum nss_status _nss_ldap_gethostbyname2_r(
- const char *name,int af,struct hostent *result,
+/* this is a wrapper around read_hostent() that does error handling
+ if the read address list does not contain any addresses for the
+ specified address familiy */
+static enum nss_status read_hostent_erronempty(
+ FILE *fp,int af,struct hostent *result,
char *buffer,size_t buflen,int *errnop,int *h_errnop)
{
- FILE *fp;
- int32_t tmpint32;
enum nss_status retv;
- /* open socket and write request */
- OPEN_SOCK(fp);
- WRITE_REQUEST(fp,NSLCD_ACTION_HOST_BYNAME);
- WRITE_STRING(fp,name);
- WRITE_FLUSH(fp);
- /* read response */
- READ_RESPONSEHEADER(fp,NSLCD_ACTION_HOST_BYNAME);
- READ_RESPONSE_CODE(fp);
retv=read_hostent(fp,af,result,buffer,buflen,errnop,h_errnop);
/* check result */
if (retv!=NSS_STATUS_SUCCESS)
return retv;
- /* check empty address list */
+ /* check empty address list
+ (note that we cannot do this in the read_hostent() function as closing
+ the socket there will cause problems with the {set,get,end}ent() functions
+ below)
+ */
if (result->h_addr_list[0]==NULL)
{
*errnop=ENOENT;
@@ -146,11 +136,54 @@ enum nss_status _nss_ldap_gethostbyname2_r(
fclose(fp);
return NSS_STATUS_NOTFOUND;
}
- /* close socket and we're done */
- fclose(fp);
return NSS_STATUS_SUCCESS;
}
+/* this is a wrapper around read_hostent() that skips to the
+ next address if the address list does not contain any addresses for the
+ specified address familiy */
+static enum nss_status read_hostent_nextonempty(
+ FILE *fp,int af,struct hostent *result,
+ char *buffer,size_t buflen,int *errnop,int *h_errnop)
+{
+ int32_t tmpint32;
+ enum nss_status retv;
+ /* check until we read an non-empty entry */
+ do
+ {
+ /* read a host entry */
+ retv=read_hostent(fp,AF_INET,result,buffer,buflen,errnop,h_errnop);
+ /* check result */
+ if (retv!=NSS_STATUS_SUCCESS)
+ return retv;
+ /* skip to the next entry if we read an empty address */
+ if (result->h_addr_list[0]==NULL)
+ {
+ retv=NSS_STATUS_NOTFOUND;
+ READ_RESPONSE_CODE(fp);
+ }
+ /* do another loop run if we read an empty address */
+ }
+ while (retv!=NSS_STATUS_SUCCESS);
+ return NSS_STATUS_SUCCESS;
+}
+
+/* this function looks up a single host entry and returns all the addresses
+ associated with the host in a single address familiy
+ name - IN - hostname to lookup
+ af - IN - address familty to present results for
+ result - OUT - entry found
+ buffer,buflen - OUT - buffer to store allocated stuff on
+ errnop,h_errnop - OUT - for reporting errors */
+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)
+{
+ NSS_BYNAME(NSLCD_ACTION_HOST_BYNAME,
+ name,
+ read_hostent_erronempty(fp,af,result,buffer,buflen,errnop,h_errnop));
+}
+
/* this function just calls the gethostbyname2() variant with the address
familiy set */
enum nss_status _nss_ldap_gethostbyname_r(
@@ -160,6 +193,11 @@ enum nss_status _nss_ldap_gethostbyname_r(
return _nss_ldap_gethostbyname2_r(name,AF_INET,result,buffer,buflen,errnop,h_errnop);
}
+/* write an address value */
+#define WRITE_ADDRESS(fp,af,len,addr) \
+ WRITE_INT32(fp,af); \
+ WRITE_INT32(fp,len); \
+ WRITE(fp,addr,len);
/* this function looks up a single host entry and returns all the addresses
associated with the host in a single address familiy
@@ -173,35 +211,9 @@ enum nss_status _nss_ldap_gethostbyaddr_r(
const void *addr,socklen_t len,int af,struct hostent *result,
char *buffer,size_t buflen,int *errnop,int *h_errnop)
{
- FILE *fp;
- int32_t tmpint32;
- enum nss_status retv;
- /* open socket and write request */
- OPEN_SOCK(fp);
- WRITE_REQUEST(fp,NSLCD_ACTION_HOST_BYADDR);
- /* write the address */
- WRITE_INT32(fp,af);
- WRITE_INT32(fp,len);
- WRITE(fp,addr,len);
- WRITE_FLUSH(fp);
- /* read response */
- READ_RESPONSEHEADER(fp,NSLCD_ACTION_HOST_BYADDR);
- READ_RESPONSE_CODE(fp);
- retv=read_hostent(fp,af,result,buffer,buflen,errnop,h_errnop);
- /* check read result */
- if (retv!=NSS_STATUS_SUCCESS)
- return retv;
- /* check empty address list */
- if (result->h_addr_list[0]==NULL)
- {
- *errnop=ENOENT;
- *h_errnop=NO_ADDRESS;
- fclose(fp);
- return NSS_STATUS_NOTFOUND;
- }
- /* close socket and we're done */
- fclose(fp);
- return NSS_STATUS_SUCCESS;
+ NSS_BYGEN(NSLCD_ACTION_HOST_BYADDR,
+ WRITE_ADDRESS(fp,af,len,addr),
+ read_hostent_erronempty(fp,af,result,buffer,buflen,errnop,h_errnop))
}
/* thread-local file pointer to an ongoing request */
@@ -209,10 +221,10 @@ static __thread FILE *hostentfp;
enum nss_status _nss_ldap_sethostent(int stayopen)
{
- /* temporary storage for h_errno */
+ /* temporary storage for h_errno
+ (used in NSS_SETENT error handling) */
int h_errnotmp;
int *h_errnop=&h_errnotmp;
- /* setent is normal enough */
NSS_SETENT(hostentfp,NSLCD_ACTION_HOST_ALL);
}
@@ -221,26 +233,8 @@ enum nss_status _nss_ldap_gethostent_r(
struct hostent *result,
char *buffer,size_t buflen,int *errnop,int *h_errnop)
{
- int32_t tmpint32;
- enum nss_status retv=NSS_STATUS_NOTFOUND;
- /* check that we have a valid file descriptor */
- if (hostentfp==NULL)
- {
- *errnop=ENOENT;
- return NSS_STATUS_UNAVAIL;
- }
- /* check until we read an non-empty entry */
- do
- {
- /* read a response */
- READ_RESPONSE_CODE(hostentfp);
- retv=read_hostent(hostentfp,AF_INET,result,buffer,buflen,errnop,h_errnop);
- /* do another loop run if we read an empty address */
- }
- while ((retv==NSS_STATUS_SUCCESS)&&(result->h_addr_list[0]==NULL));
- if (retv==NSS_STATUS_NOTFOUND)
- *h_errnop=HOST_NOT_FOUND;
- return retv;
+ NSS_GETENT(hostentfp,
+ read_hostent_nextonempty(hostentfp,AF_INET,result,buffer,buflen,errnop,h_errnop));
}
enum nss_status _nss_ldap_endhostent(void)
diff --git a/nss/netgroup.c b/nss/netgroup.c
index 58807d8..4781e7f 100644
--- a/nss/netgroup.c
+++ b/nss/netgroup.c
@@ -44,6 +44,7 @@
else \
return NSS_STATUS_RETURN;
+/* function for reading a single result entry */
static enum nss_status read_netgrent(
FILE *fp,struct __netgrent *result,
char *buffer,size_t buflen,int *errnop)
@@ -58,7 +59,6 @@ static enum nss_status read_netgrent(
/* the response is a reference to another netgroup */
result->type=group_val;
READ_STRING_BUF(fp,result->val.group);
-
}
else if (type==NETGROUP_TYPE_TRIPLE)
{
@@ -123,7 +123,7 @@ enum nss_status _nss_ldap_setnetgrent(const char *group,struct __netgrent *resul
enum nss_status _nss_ldap_getnetgrent_r(struct __netgrent *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_GETENT(netgrentfp,read_netgrent);
+ NSS_GETENT(netgrentfp,read_netgrent(netgrentfp,result,buffer,buflen,errnop));
}
enum nss_status _nss_ldap_endnetgrent(struct __netgrent *result)
diff --git a/nss/networks.c b/nss/networks.c
index da644a8..d4972ba 100644
--- a/nss/networks.c
+++ b/nss/networks.c
@@ -2,7 +2,7 @@
networks.c - NSS lookup functions for networks database
Copyright (C) 2006 West Consulting
- Copyright (C) 2006 Arthur de Jong
+ Copyright (C) 2006, 2007 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
@@ -31,6 +31,20 @@
/* Redifine some ERROR_OUT macros as we also want to set h_errnop. */
+#undef ERROR_OUT_OPENERROR
+#define ERROR_OUT_OPENERROR \
+ *errnop=ENOENT; \
+ *h_errnop=HOST_NOT_FOUND; \
+ return (errno==EAGAIN)?NSS_STATUS_TRYAGAIN:NSS_STATUS_UNAVAIL;
+
+#undef ERROR_OUT_READERROR
+#define ERROR_OUT_READERROR(fp) \
+ fclose(fp); \
+ fp=NULL; \
+ *errnop=ENOENT; \
+ *h_errnop=NO_RECOVERY; \
+ return NSS_STATUS_UNAVAIL;
+
#undef ERROR_OUT_BUFERROR
#define ERROR_OUT_BUFERROR(fp) \
fclose(fp); \
@@ -39,6 +53,10 @@
*h_errnop=TRY_AGAIN; \
return NSS_STATUS_TRYAGAIN;
+#undef ERROR_OUT_WRITEERROR
+#define ERROR_OUT_WRITEERROR(fp) \
+ ERROR_OUT_READERROR(fp)
+
#undef ERROR_OUT_NOSUCCESS
#define ERROR_OUT_NOSUCCESS(fp,retv) \
fclose(fp); \
@@ -47,7 +65,7 @@
*h_errnop=HOST_NOT_FOUND; \
return nslcd2nss(retv);
-/* read a single host entry from the stream, ignoring entries
+/* read a single network entry from the stream, ignoring entries
that are not AF_INET (IPv4), result is stored in result */
static enum nss_status read_netent(
FILE *fp,struct netent *result,
@@ -58,7 +76,7 @@ static enum nss_status read_netent(
int readaf;
size_t bufptr=0;
enum nss_status retv=NSS_STATUS_NOTFOUND;
- /* read the host entry */
+ /* read the network entry */
READ_STRING_BUF(fp,result->n_name);
READ_STRINGLIST_NULLTERM(fp,result->n_aliases);
result->n_addrtype=AF_INET;
@@ -78,6 +96,7 @@ static enum nss_status read_netent(
result->n_net=ntohl(tmpint32);
/* signal that we've read a proper entry */
retv=NSS_STATUS_SUCCESS;
+ /* don't return here to not upset the stream */
}
else
{
@@ -90,67 +109,24 @@ static enum nss_status read_netent(
enum nss_status _nss_ldap_getnetbyname_r(const char *name,struct netent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop)
{
- FILE *fp;
- int32_t tmpint32;
- enum nss_status retv;
- /* set to NO_RECOVERY in case some error is caught */
- *h_errnop=NO_RECOVERY;
- /* open socket and write request */
- OPEN_SOCK(fp);
- WRITE_REQUEST(fp,NSLCD_ACTION_NETWORK_BYNAME);
- WRITE_STRING(fp,name);
- WRITE_FLUSH(fp);
- /* read response */
- READ_RESPONSEHEADER(fp,NSLCD_ACTION_NETWORK_BYNAME);
- READ_RESPONSE_CODE(fp);
- retv=read_netent(fp,result,buffer,buflen,errnop,h_errnop);
- /* check read result */
- if (retv==NSS_STATUS_NOTFOUND)
- {
- *h_errnop=NO_ADDRESS;
- fclose(fp);
- return NSS_STATUS_NOTFOUND;
- }
- else if (retv!=NSS_STATUS_SUCCESS)
- return retv;
- /* close socket and we're done */
- fclose(fp);
- return NSS_STATUS_SUCCESS;
+ NSS_BYNAME(NSLCD_ACTION_HOST_BYNAME,
+ name,
+ read_netent(fp,result,buffer,buflen,errnop,h_errnop));
}
+/* write an address value */
+#define WRITE_ADDRESS(fp,af,len,addr) \
+ WRITE_INT32(fp,af); \
+ WRITE_INT32(fp,len); \
+ WRITE(fp,addr,len);
+
/* Note: the af parameter is ignored and is assumed to be AF_INET */
+/* TODO: implement handling of af parameter */
enum nss_status _nss_ldap_getnetbyaddr_r(uint32_t addr,int af,struct netent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop)
{
- FILE *fp;
- int32_t tmpint32;
- enum nss_status retv;
- /* set to NO_RECOVERY in case some error is caught */
- *h_errnop=NO_RECOVERY;
- /* open socket and write request */
- OPEN_SOCK(fp);
- WRITE_REQUEST(fp,NSLCD_ACTION_NETWORK_BYADDR);
- /* write the address */
- WRITE_INT32(fp,AF_INET);
- WRITE_INT32(fp,4);
- addr=htonl(addr);
- WRITE_INT32(fp,addr);
- WRITE_FLUSH(fp);
- /* read response */
- READ_RESPONSEHEADER(fp,NSLCD_ACTION_NETWORK_BYADDR);
- READ_RESPONSE_CODE(fp);
- retv=read_netent(fp,result,buffer,buflen,errnop,h_errnop);
- /* check read result */
- if (retv==NSS_STATUS_NOTFOUND)
- {
- *h_errnop=NO_ADDRESS;
- fclose(fp);
- return NSS_STATUS_NOTFOUND;
- }
- else if (retv!=NSS_STATUS_SUCCESS)
- return retv;
- /* close socket and we're done */
- fclose(fp);
- return NSS_STATUS_SUCCESS;
+ NSS_BYGEN(NSLCD_ACTION_HOST_BYADDR,
+ addr=htonl(addr);WRITE_ADDRESS(fp,AF_INET,4,&addr),
+ read_netent(fp,result,buffer,buflen,errnop,h_errnop))
}
/* thread-local file pointer to an ongoing request */
@@ -158,29 +134,18 @@ static __thread FILE *netentfp;
enum nss_status _nss_ldap_setnetent(int stayopen)
{
+ /* temporary storage for h_errno
+ (used in NSS_SETENT error handling) */
+ int h_errnotmp;
+ int *h_errnop=&h_errnotmp;
+ /* setent is normal enough */
NSS_SETENT(netentfp,NSLCD_ACTION_NETWORK_ALL);
}
enum nss_status _nss_ldap_getnetent_r(struct netent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop)
{
- int32_t tmpint32;
- enum nss_status retv=NSS_STATUS_NOTFOUND;
- /* check that we have a valid file descriptor */
- if (netentfp==NULL)
- {
- *errnop=ENOENT;
- return NSS_STATUS_UNAVAIL;
- }
- /* check until we read an non-empty entry */
- do
- {
- /* read a response */
- READ_RESPONSE_CODE(netentfp);
- retv=read_netent(netentfp,result,buffer,buflen,errnop,h_errnop);
- /* do another loop run if we read an empty address list */
- }
- while (retv==NSS_STATUS_NOTFOUND);
- return retv;
+ NSS_GETENT(netentfp,
+ read_netent(netentfp,result,buffer,buflen,errnop,h_errnop));
}
enum nss_status _nss_ldap_endnetent(void)
diff --git a/nss/passwd.c b/nss/passwd.c
index e3bca05..64bf2b8 100644
--- a/nss/passwd.c
+++ b/nss/passwd.c
@@ -2,7 +2,7 @@
passwd.c - NSS lookup functions for passwd database
Copyright (C) 2006 West Consulting
- Copyright (C) 2006 Arthur de Jong
+ Copyright (C) 2006, 2007 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
@@ -29,36 +29,34 @@
#include "prototypes.h"
#include "common.h"
-/* Macros for expanding the NSLCD_PASSWD macro. */
-#define NSLCD_STRING(field) READ_STRING_BUF(fp,field)
-#define NSLCD_TYPE(field,type) READ_TYPE(fp,field,type)
-#define PASSWD_NAME result->pw_name
-#define PASSWD_PASSWD result->pw_passwd
-#define PASSWD_UID result->pw_uid
-#define PASSWD_GID result->pw_gid
-#define PASSWD_GECOS result->pw_gecos
-#define PASSWD_DIR result->pw_dir
-#define PASSWD_SHELL result->pw_shell
-
-
static enum nss_status read_passwd(
FILE *fp,struct passwd *result,
char *buffer,size_t buflen,int *errnop)
{
int32_t tmpint32;
size_t bufptr=0;
- NSLCD_PASSWD;
+ READ_STRING_BUF(fp,result->pw_name);
+ READ_STRING_BUF(fp,result->pw_passwd);
+ READ_TYPE(fp,result->pw_uid,uid_t);
+ READ_TYPE(fp,result->pw_gid,gid_t);
+ READ_STRING_BUF(fp,result->pw_gecos);
+ READ_STRING_BUF(fp,result->pw_dir);
+ READ_STRING_BUF(fp,result->pw_shell);
return NSS_STATUS_SUCCESS;
}
enum nss_status _nss_ldap_getpwnam_r(const char *name,struct passwd *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_BYNAME(NSLCD_ACTION_PASSWD_BYNAME,name,read_passwd);
+ NSS_BYNAME(NSLCD_ACTION_PASSWD_BYNAME,
+ name,
+ read_passwd(fp,result,buffer,buflen,errnop));
}
enum nss_status _nss_ldap_getpwuid_r(uid_t uid,struct passwd *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_BYTYPE(NSLCD_ACTION_PASSWD_BYUID,uid,uid_t,read_passwd);
+ NSS_BYTYPE(NSLCD_ACTION_PASSWD_BYUID,
+ uid,uid_t,
+ read_passwd(fp,result,buffer,buflen,errnop));
}
/* thread-local file pointer to an ongoing request */
@@ -73,7 +71,7 @@ enum nss_status _nss_ldap_setpwent(int stayopen)
/* read password data from an opened stream */
enum nss_status _nss_ldap_getpwent_r(struct passwd *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_GETENT(pwentfp,read_passwd);
+ NSS_GETENT(pwentfp,read_passwd(pwentfp,result,buffer,buflen,errnop));
}
/* close the stream opened with setpwent() above */
diff --git a/nss/protocols.c b/nss/protocols.c
index bc8d7b3..13ed34f 100644
--- a/nss/protocols.c
+++ b/nss/protocols.c
@@ -2,7 +2,7 @@
protocols.c - NSS lookup functions for protocol database
Copyright (C) 2006 West Consulting
- Copyright (C) 2006 Arthur de Jong
+ Copyright (C) 2006, 2007 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
@@ -29,34 +29,30 @@
#include "prototypes.h"
#include "common.h"
-/* macros for expanding the NSLCD_PROTOCOL macro */
-#define NSLCD_STRING(field) READ_STRING_BUF(fp,field)
-#define NSLCD_STRINGLIST(field) READ_STRINGLIST_NULLTERM(fp,field)
-#define NSLCD_INT32(field) READ_INT32(fp,field)
-#define PROTOCOL_NAME result->p_name
-#define PROTOCOL_ALIASES result->p_aliases
-#define PROTOCOL_NUMBER result->p_proto
-
static enum nss_status read_protoent(
FILE *fp,struct protoent *result,
char *buffer,size_t buflen,int *errnop)
{
int32_t tmpint32,tmp2int32,tmp3int32;
size_t bufptr=0;
- /* auto-genereted read code */
- NSLCD_PROTOCOL;
- /* we're done */
+ READ_STRING_BUF(fp,result->p_name);
+ READ_STRINGLIST_NULLTERM(fp,result->p_aliases);
+ READ_INT32(fp,result->p_proto);
return NSS_STATUS_SUCCESS;
}
enum nss_status _nss_ldap_getprotobyname_r(const char *name,struct protoent *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_BYNAME(NSLCD_ACTION_PROTOCOL_BYNAME,name,read_protoent);
+ NSS_BYNAME(NSLCD_ACTION_PROTOCOL_BYNAME,
+ name,
+ read_protoent(fp,result,buffer,buflen,errnop));
}
enum nss_status _nss_ldap_getprotobynumber_r(int number,struct protoent *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_BYINT32(NSLCD_ACTION_PROTOCOL_BYNUMBER,number,read_protoent);
+ NSS_BYINT32(NSLCD_ACTION_PROTOCOL_BYNUMBER,
+ number,
+ read_protoent(fp,result,buffer,buflen,errnop));
}
/* thread-local file pointer to an ongoing request */
@@ -69,7 +65,7 @@ enum nss_status _nss_ldap_setprotoent(int stayopen)
enum nss_status _nss_ldap_getprotoent_r(struct protoent *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_GETENT(protoentfp,read_protoent);
+ NSS_GETENT(protoentfp,read_protoent(protoentfp,result,buffer,buflen,errnop));
}
enum nss_status _nss_ldap_endprotoent(void)
diff --git a/nss/rpc.c b/nss/rpc.c
index 2887d55..08657eb 100644
--- a/nss/rpc.c
+++ b/nss/rpc.c
@@ -2,7 +2,7 @@
rpc.c - NSS lookup functions for rpc database
Copyright (C) 2006 West Consulting
- Copyright (C) 2006 Arthur de Jong
+ Copyright (C) 2006, 2007 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
@@ -29,34 +29,30 @@
#include "prototypes.h"
#include "common.h"
-/* macros for expanding the NSLCD_RPC macro */
-#define NSLCD_STRING(field) READ_STRING_BUF(fp,field)
-#define NSLCD_STRINGLIST(field) READ_STRINGLIST_NULLTERM(fp,field)
-#define NSLCD_INT32(field) READ_INT32(fp,field)
-#define RPC_NAME result->r_name
-#define RPC_ALIASES result->r_aliases
-#define RPC_NUMBER result->r_number
-
static enum nss_status read_rpcent(
FILE *fp,struct rpcent *result,
char *buffer,size_t buflen,int *errnop)
{
int32_t tmpint32,tmp2int32,tmp3int32;
size_t bufptr=0;
- /* auto-genereted read code */
- NSLCD_RPC;
- /* we're done */
+ READ_STRING_BUF(fp,result->r_name);
+ READ_STRINGLIST_NULLTERM(fp,result->r_aliases);
+ READ_INT32(fp,result->r_number);
return NSS_STATUS_SUCCESS;
}
enum nss_status _nss_ldap_getrpcbyname_r(const char *name,struct rpcent *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_BYNAME(NSLCD_ACTION_RPC_BYNAME,name,read_rpcent);
+ NSS_BYNAME(NSLCD_ACTION_RPC_BYNAME,
+ name,
+ read_rpcent(fp,result,buffer,buflen,errnop));
}
enum nss_status _nss_ldap_getrpcbynumber_r(int number,struct rpcent *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_BYINT32(NSLCD_ACTION_RPC_BYNUMBER,number,read_rpcent);
+ NSS_BYINT32(NSLCD_ACTION_RPC_BYNUMBER,
+ number,
+ read_rpcent(fp,result,buffer,buflen,errnop));
}
/* thread-local file pointer to an ongoing request */
@@ -69,7 +65,7 @@ enum nss_status _nss_ldap_setrpcent(int stayopen)
enum nss_status _nss_ldap_getrpcent_r(struct rpcent *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_GETENT(protoentfp,read_rpcent);
+ NSS_GETENT(protoentfp,read_rpcent(protoentfp,result,buffer,buflen,errnop));
}
enum nss_status _nss_ldap_endrpcent(void)
diff --git a/nss/services.c b/nss/services.c
index 1fae4b9..36d8f1c 100644
--- a/nss/services.c
+++ b/nss/services.c
@@ -2,7 +2,7 @@
service.c - NSS lookup functions for services database
Copyright (C) 2006 West Consulting
- Copyright (C) 2006 Arthur de Jong
+ Copyright (C) 2006, 2007 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
@@ -29,82 +29,35 @@
#include "prototypes.h"
#include "common.h"
-/* macros for expanding the NSLCD_SERVICE macro */
-#define NSLCD_STRING(field) READ_STRING_BUF(fp,field)
-#define NSLCD_STRINGLIST(field) READ_STRINGLIST_NULLTERM(fp,field)
-#define NSLCD_INT32(field) READ_INT32(fp,field)
-#define SERVICE_NAME result->s_name
-#define SERVICE_ALIASES result->s_aliases
-#define SERVICE_NUMBER port
-#define SERVICE_PROTOCOL result->s_proto
-
static enum nss_status read_servent(
FILE *fp,struct servent *result,
char *buffer,size_t buflen,int *errnop)
{
int32_t tmpint32,tmp2int32,tmp3int32;
- int port;
size_t bufptr=0;
- /* auto-genereted read code */
- NSLCD_SERVICE;
- /* store number in network byte order */
- result->s_port=ntohs(port);
+ READ_STRING_BUF(fp,result->s_name);
+ READ_STRINGLIST_NULLTERM(fp,result->s_aliases);
+ /* store port number in network byte order */
+ READ_TYPE(fp,tmpint32,int32_t);
+ result->s_port=ntohs(tmpint32);
+ READ_STRING_BUF(fp,result->s_proto);
/* we're done */
return NSS_STATUS_SUCCESS;
}
enum nss_status _nss_ldap_getservbyname_r(const char *name,const char *protocol,struct servent *result,char *buffer,size_t buflen,int *errnop)
{
- FILE *fp;
- int32_t tmpint32;
- enum nss_status retv;
- /* open socket and write request */
- OPEN_SOCK(fp);
- WRITE_REQUEST(fp,NSLCD_ACTION_SERVICE_BYNAME);
- /* write the parameters */
- WRITE_STRING(fp,name);
- /* fall back to empty string in case of NULL */
- if (protocol==NULL)
- protocol="";
- WRITE_STRING(fp,protocol);
- WRITE_FLUSH(fp);
- /* read response */
- READ_RESPONSEHEADER(fp,NSLCD_ACTION_SERVICE_BYNAME);
- READ_RESPONSE_CODE(fp);
- retv=read_servent(fp,result,buffer,buflen,errnop);
- /* check read result */
- if (retv!=NSS_STATUS_SUCCESS)
- return retv;
- /* close socket and we're done */
- fclose(fp);
- return NSS_STATUS_SUCCESS;
+ NSS_BYGEN(NSLCD_ACTION_SERVICE_BYNAME,
+ WRITE_STRING(fp,name);WRITE_STRING(fp,protocol),
+ read_servent(fp,result,buffer,buflen,errnop));
+
}
enum nss_status _nss_ldap_getservbyport_r(int port,const char *protocol,struct servent *result,char *buffer,size_t buflen,int *errnop)
{
- FILE *fp;
- int32_t tmpint32;
- enum nss_status retv;
- /* open socket and write request */
- OPEN_SOCK(fp);
- WRITE_REQUEST(fp,NSLCD_ACTION_SERVICE_BYNUMBER);
- /* write the parameters */
- WRITE_INT32(fp,ntohs(port));
- /* fall back to empty string in case of NULL */
- if (protocol==NULL)
- protocol="";
- WRITE_STRING(fp,protocol);
- WRITE_FLUSH(fp);
- /* read response */
- READ_RESPONSEHEADER(fp,NSLCD_ACTION_SERVICE_BYNUMBER);
- READ_RESPONSE_CODE(fp);
- retv=read_servent(fp,result,buffer,buflen,errnop);
- /* check read result */
- if (retv!=NSS_STATUS_SUCCESS)
- return retv;
- /* close socket and we're done */
- fclose(fp);
- return NSS_STATUS_SUCCESS;
+ NSS_BYGEN(NSLCD_ACTION_SERVICE_BYNUMBER,
+ WRITE_INT32(fp,ntohs(port));WRITE_STRING(fp,protocol),
+ read_servent(fp,result,buffer,buflen,errnop));
}
/* thread-local file pointer to an ongoing request */
@@ -117,7 +70,7 @@ enum nss_status _nss_ldap_setservent(int stayopen)
enum nss_status _nss_ldap_getservent_r(struct servent *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_GETENT(protoentfp,read_servent);
+ NSS_GETENT(protoentfp,read_servent(protoentfp,result,buffer,buflen,errnop));
}
enum nss_status _nss_ldap_endservent(void)
diff --git a/nss/shadow.c b/nss/shadow.c
index 6382b69..cb57b69 100644
--- a/nss/shadow.c
+++ b/nss/shadow.c
@@ -2,7 +2,7 @@
shadow.c - NSS lookup functions for shadow database
Copyright (C) 2006 West Consulting
- Copyright (C) 2006 Arthur de Jong
+ Copyright (C) 2006, 2007 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
@@ -29,32 +29,29 @@
#include "prototypes.h"
#include "common.h"
-/* Macros for expanding the NSLCD_SHADOW macro. */
-#define NSLCD_STRING(field) READ_STRING_BUF(fp,field)
-#define NSLCD_INT32(field) READ_INT32(fp,field)
-#define SHADOW_NAME result->sp_namp
-#define SHADOW_PASSWD result->sp_pwdp
-#define SHADOW_LASTCHANGE result->sp_lstchg
-#define SHADOW_MINDAYS result->sp_min
-#define SHADOW_MAXDAYS result->sp_max
-#define SHADOW_WARN result->sp_warn
-#define SHADOW_INACT result->sp_inact
-#define SHADOW_EXPIRE result->sp_expire
-#define SHADOW_FLAG result->sp_flag
-
static enum nss_status read_spwd(
FILE *fp,struct spwd *result,
char *buffer,size_t buflen,int *errnop)
{
int32_t tmpint32;
size_t bufptr=0;
- NSLCD_SHADOW;
+ READ_STRING_BUF(fp,result->sp_namp);
+ READ_STRING_BUF(fp,result->sp_pwdp);
+ READ_INT32(fp,result->sp_lstchg);
+ READ_INT32(fp,result->sp_min);
+ READ_INT32(fp,result->sp_max);
+ READ_INT32(fp,result->sp_warn);
+ READ_INT32(fp,result->sp_inact);
+ READ_INT32(fp,result->sp_expire);
+ READ_INT32(fp,result->sp_flag);
return NSS_STATUS_SUCCESS;
}
enum nss_status _nss_ldap_getspnam_r(const char *name,struct spwd *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_BYNAME(NSLCD_ACTION_SHADOW_BYNAME,name,read_spwd);
+ NSS_BYNAME(NSLCD_ACTION_SHADOW_BYNAME,
+ name,
+ read_spwd(fp,result,buffer,buflen,errnop));
}
/* thread-local file pointer to an ongoing request */
@@ -67,7 +64,7 @@ enum nss_status _nss_ldap_setspent(int stayopen)
enum nss_status _nss_ldap_getspent_r(struct spwd *result,char *buffer,size_t buflen,int *errnop)
{
- NSS_GETENT(spentfp,read_spwd);
+ NSS_GETENT(spentfp,read_spwd(spentfp,result,buffer,buflen,errnop));
}
enum nss_status _nss_ldap_endspent(void)