Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
path: root/nss
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2006-11-03 23:03:21 +0100
committerArthur de Jong <arthur@arthurdejong.org>2006-11-03 23:03:21 +0100
commit207c2deaa5e774dae81022a4714e8a284a316b80 (patch)
treed98885fa2b88a2bf23389dc0528ce82ed69d0a68 /nss
parent11c173f2fc6eaf67ff0a186e512de401ea20cf00 (diff)
implement initial host database lookups NSS-side
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/libnss_ldapd@69 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'nss')
-rw-r--r--nss/Makefile.am2
-rw-r--r--nss/hosts.c210
2 files changed, 211 insertions, 1 deletions
diff --git a/nss/Makefile.am b/nss/Makefile.am
index 104a100..0b099f5 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 \
- aliases.c group.c passwd.c
+ aliases.c group.c hosts.c passwd.c
diff --git a/nss/hosts.c b/nss/hosts.c
new file mode 100644
index 0000000..4ec2923
--- /dev/null
+++ b/nss/hosts.c
@@ -0,0 +1,210 @@
+/*
+ hosts.c - NSS lookup functions for hosts 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"
+
+/* Redifine some ERROR_OUT macros as we also want to set h_errnop. */
+
+#undef ERROR_OUT_BUFERROR
+#define ERROR_OUT_BUFERROR(fp) \
+ fclose(fp); \
+ fp=NULL; \
+ *errnop=ERANGE; \
+ *h_errnop=TRY_AGAIN; \
+ return NSS_STATUS_TRYAGAIN;
+
+#undef ERROR_OUT_NOSUCCESS
+#define ERROR_OUT_NOSUCCESS(fp,retv) \
+ fclose(fp); \
+ fp=NULL; \
+ *errnop=ENOENT; \
+ *h_errnop=HOST_NOT_FOUND; \
+ return nslcd2nss(retv);
+
+/* read a single host entry from the stream, filtering on the
+ specified address family, result is stored in result */
+static enum nss_status host_readhostent(
+ FILE *fp,int af,struct hostent *result,
+ char *buffer,size_t buflen,int *errnop,int *h_errnop)
+{
+ int32_t tmpint32,tmp2int32,tmp3int32;
+ int32_t numaddr,i;
+ int readaf;
+ size_t bufptr=0;
+ /* read the host entry */
+ READ_STRING_BUF(fp,result->h_name);
+ READ_STRINGLIST_NULLTERM(fp,result->h_aliases);
+ result->h_addrtype=af;
+ result->h_length=0;
+ /* read number of addresses to follow */
+ READ_TYPE(fp,numaddr,int32_t);
+ /* allocate memory for array */
+ /* Note: this may allocate too much memory (e.g. also for
+ address records of other address families) but
+ this is an easy way to do it */
+ BUF_CHECK(fp,(numaddr+1)*sizeof(char *));
+ result->h_addr_list=(char **)BUF_CUR;
+ /* go through the address list and filter on af */
+ i=0;
+ while (--numaddr>=0)
+ {
+ /* read address family and size */
+ READ_INT32(fp,readaf);
+ READ_INT32(fp,tmp2int32);
+ if (readaf==af)
+ {
+ result->h_length=tmp2int32;
+ /* allocate room in buffer */
+ BUF_CHECK(fp,tmp2int32);
+ READ(fp,BUF_CUR,tmp2int32);
+ result->h_addr_list[i++]=BUF_CUR;
+ BUF_SKIP(tmp2int32);
+ }
+ else
+ {
+ SKIP(fp,tmpint32);
+ }
+ }
+ /* null-terminate address list */
+ result->h_addr_list[i]=NULL;
+ 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)
+{
+ 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_HOST_BYNAME);
+ WRITE_STRING(fp,name);
+ WRITE_FLUSH(fp);
+ /* read response */
+ READ_RESPONSEHEADER(fp,NSLCD_ACTION_HOST_BYNAME);
+ READ_RESPONSE_CODE(fp);
+ retv=host_readhostent(fp,af,result,buffer,buflen,errnop,h_errnop);
+ if (retv!=NSS_STATUS_SUCCESS)
+ return retv;
+ /* determin h_errno value */
+ if (result->h_addr_list[0]==NULL)
+ *h_errnop=NO_ADDRESS;
+ /* close socket and we're done */
+ fclose(fp);
+ return NSS_STATUS_SUCCESS;
+}
+
+/* this function just calls the gethostbyname2() variant with the address
+ familiy set */
+enum nss_status _nss_ldap_gethostbyname_r(
+ const char *name,struct hostent *result,
+ char *buffer,size_t buflen,int *errnop,int *h_errnop)
+{
+ return _nss_ldap_gethostbyname2_r(name,AF_INET,result,buffer,buflen,errnop,h_errnop);
+}
+
+
+/* this function looks up a single host entry and returns all the addresses
+ associated with the host in a single address familiy
+ addr - IN - the address to look up
+ len - IN - the size of the addr struct
+ af - IN - address familty the address is specified as
+ 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_gethostbyaddr_r(
+ struct in_addr *addr,int 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;
+ /* 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_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=host_readhostent(fp,af,result,buffer,buflen,errnop,h_errnop);
+ if (retv!=NSS_STATUS_SUCCESS)
+ return retv;
+ /* close socket and we're done */
+ fclose(fp);
+ return NSS_STATUS_SUCCESS;
+}
+
+/* thread-local file pointer to an ongoing request */
+static __thread FILE *pwentfp;
+#define fp pwentfp
+
+enum nss_status _nss_ldap_sethostent(void)
+{
+ NSS_SETENT(NSLCD_ACTION_HOST_ALL);
+}
+
+/* this function only returns addresses of the AF_INET address family */
+enum nss_status _nss_ldap_gethostent_r(
+ struct hostent *result,
+ char *buffer,size_t buflen,int *errnop,int *h_errnop)
+{
+ int32_t tmpint32;
+ /* check that we have a valid file descriptor */
+ if (fp==NULL)
+ {
+ *errnop=ENOENT;
+ return NSS_STATUS_UNAVAIL;
+ }
+ /* read a response */
+ READ_RESPONSE_CODE(fp);
+ return host_readhostent(fp,AF_INET,result,buffer,buflen,errnop,h_errnop); \
+}
+
+enum nss_status _nss_ldap_endhostent(void)
+{
+ NSS_ENDENT();
+}