diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2006-11-15 15:06:53 +0000 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2006-11-15 15:06:53 +0000 |
commit | fc0578b5d55645ad060f3a64697a2ed79e88e8e6 (patch) | |
tree | a8ba7d15255eac8f18a0eb0e13c3e201efb08d99 | |
parent | 7fad2aeb7d100740bdc99ba2b9b2d470a7f0dd05 (diff) |
implement network information lookups through NSS
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/libnss_ldapd@91 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r-- | nslcd.h | 12 | ||||
-rw-r--r-- | nss/Makefile.am | 2 | ||||
-rw-r--r-- | nss/networks.c | 188 | ||||
-rw-r--r-- | nss/prototypes.h | 6 |
4 files changed, 203 insertions, 5 deletions
@@ -89,7 +89,7 @@ LDF_BUF(ADDRESS_ADDR) /* the address itself in network byte order */ /* used for transferring host (/etc/hosts) information */ -/* Note: this marcos is not expanded to code, check manually */ +/* Note: this marco is not expanded to code, check manually */ #define LDF_HOST \ LDF_STRING(HOST_NAME) \ LDF_STRINGLIST(HOST_ALIASES) \ @@ -99,6 +99,13 @@ /* NETWORKS - TBD - struct netent */ +/* user for transferring network (/etc/networks) information */ +/* Note: this marco is not expanded to code, check manually */ +#define LDF_NETWORK \ + LDF_STRING(NETWORK_NAME) \ + LDF_STRINGLIST(NETWORK_ALIASES) \ + LDF_ADDRESSLIST(NETWORK_ADDRS) + /* used for transferring user (/etc/passwd) information */ #define LDF_PASSWD \ LDF_STRING(PASSWD_NAME) \ @@ -155,6 +162,9 @@ #define NSLCD_ACTION_HOST_BYNAME 6001 #define NSLCD_ACTION_HOST_BYADDR 6002 #define NSLCD_ACTION_HOST_ALL 6005 +#define NSLCD_ACTION_NETWORK_BYNAME 8001 +#define NSLCD_ACTION_NETWORK_BYADDR 8002 +#define NSLCD_ACTION_NETWORK_ALL 8005 #define NSLCD_ACTION_PASSWD_BYNAME 1001 #define NSLCD_ACTION_PASSWD_BYUID 1002 #define NSLCD_ACTION_PASSWD_ALL 1004 diff --git a/nss/Makefile.am b/nss/Makefile.am index 41c596e..d2bab7a 100644 --- a/nss/Makefile.am +++ b/nss/Makefile.am @@ -23,4 +23,4 @@ noinst_LIBRARIES = libnss.a libnss_a_SOURCES = common.c common.h prototypes.h ../nslcd-client.h \ ../nslcd.h ../nslcd-common.h \ aliases.c automount.c ethers.c group.c hosts.c \ - passwd.c shadow.c + networks.c passwd.c shadow.c diff --git a/nss/networks.c b/nss/networks.c new file mode 100644 index 0000000..fac29a0 --- /dev/null +++ b/nss/networks.c @@ -0,0 +1,188 @@ +/* + networks.c - NSS lookup functions for networks 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 "prototypes.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, ignoring entries + that are not AF_INET (IPv4), result is stored in result */ +static enum nss_status read_netent( + FILE *fp,struct netent *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; + enum nss_status retv=NSS_STATUS_NOTFOUND; + /* read the host entry */ + READ_STRING_BUF(fp,result->n_name); + READ_STRINGLIST_NULLTERM(fp,result->n_aliases); + result->n_addrtype=AF_INET; + /* read number of addresses to follow */ + READ_TYPE(fp,numaddr,int32_t); + /* 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_INET)&&(tmp2int32==4)) + { + /* read address */ + READ_INT32(fp,result->n_net); + /* signal that we've read a proper entry */ + retv=NSS_STATUS_SUCCESS; + } + else + { + SKIP(fp,tmpint32); + } + } + return retv; +} + +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; +} + +/* Note: the af parameter is ignored and is assumed to be AF_INET */ +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); + 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; +} + +/* thread-local file pointer to an ongoing request */ +static __thread FILE *hostentfp; +#define fp hostentfp + +enum nss_status _nss_ldap_setnetent(int stayopen) +{ + NSS_SETENT(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 (fp==NULL) + { + *errnop=ENOENT; + return NSS_STATUS_UNAVAIL; + } + /* check until we read an non-empty entry */ + do + { + /* read a response */ + READ_RESPONSE_CODE(fp); + retv=read_netent(fp,result,buffer,buflen,errnop,h_errnop); + /* do another loop run if we read an empty address list */ + } + while ((retv==NSS_STATUS_SUCCESS)||(retv==NSS_STATUS_NOTFOUND)); + return retv; +} + +enum nss_status _nss_ldap_endnetent(void) +{ + NSS_ENDENT(); +} diff --git a/nss/prototypes.h b/nss/prototypes.h index 5cb5f22..c11862f 100644 --- a/nss/prototypes.h +++ b/nss/prototypes.h @@ -93,10 +93,10 @@ 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(uint32_t addr,int type,struct netent *result,char *buffer,size_t buflen,int *errnop,int *herrnop); +enum nss_status _nss_ldap_getnetbyname_r(const char *name,struct netent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop); +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); enum nss_status _nss_ldap_setnetent(int stayopen); -enum nss_status _nss_ldap_getnetent_r(struct netent *result,char *buffer,size_t buflen,int *errnop,int *herrnop); +enum nss_status _nss_ldap_getnetent_r(struct netent *result,char *buffer,size_t buflen,int *errnop,int *h_errnop); enum nss_status _nss_ldap_endnetent(void); /* passwd - user database and passwords */ |