diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2006-11-28 10:59:32 +0100 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2006-11-28 10:59:32 +0100 |
commit | d524c2cfc47a4d5217957e8e910611de9fb5b0fd (patch) | |
tree | c5c51d0b1c4e94abf0ea81a617362aaaeaf5a687 | |
parent | 74c2c4909d84fc5d9a7f082e11e50efc20d450f9 (diff) |
implement network name lookups on server side plus some fixes on the client side
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/libnss_ldapd@130 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r-- | nslcd-server.c | 2 | ||||
-rw-r--r-- | nss/networks.c | 9 | ||||
-rw-r--r-- | server/network.c | 272 | ||||
-rw-r--r-- | testnss.c | 64 |
4 files changed, 212 insertions, 135 deletions
diff --git a/nslcd-server.c b/nslcd-server.c index ca68371..7f3c10d 100644 --- a/nslcd-server.c +++ b/nslcd-server.c @@ -164,11 +164,9 @@ void nslcd_server_handlerequest(int sock) case NSLCD_ACTION_HOST_BYADDR: nslcd_host_byaddr(fp); break; case NSLCD_ACTION_HOST_ALL: nslcd_host_all(fp); break; case NSLCD_ACTION_NETGROUP_BYNAME: nslcd_netgroup_byname(fp); break; -/* case NSLCD_ACTION_NETWORK_BYNAME: nslcd_network_byname(fp); break; case NSLCD_ACTION_NETWORK_BYADDR: nslcd_network_byaddr(fp); break; case NSLCD_ACTION_NETWORK_ALL: nslcd_network_all(fp); break; -*/ case NSLCD_ACTION_PASSWD_BYNAME: nslcd_passwd_byname(fp); break; case NSLCD_ACTION_PASSWD_BYUID: nslcd_passwd_byuid(fp); break; case NSLCD_ACTION_PASSWD_ALL: nslcd_passwd_all(fp); break; diff --git a/nss/networks.c b/nss/networks.c index 4290c3e..f459f59 100644 --- a/nss/networks.c +++ b/nss/networks.c @@ -73,13 +73,15 @@ static enum nss_status read_netent( READ_INT32(fp,tmp2int32); if ((readaf==AF_INET)&&(tmp2int32==4)) { - /* read address */ - READ_INT32(fp,result->n_net); + /* read address and translate to host byte order */ + READ_TYPE(fp,tmpint32,int32_t); + result->n_net=ntohl(tmpint32); /* signal that we've read a proper entry */ retv=NSS_STATUS_SUCCESS; } else { + /* skip unsupported address families */ SKIP(fp,tmpint32); } } @@ -130,6 +132,7 @@ enum nss_status _nss_ldap_getnetbyaddr_r(uint32_t addr,int af,struct netent *res /* write the address */ WRITE_INT32(fp,AF_INET); WRITE_INT32(fp,4); + addr=htonl(addr); WRITE_INT32(fp,addr); WRITE_FLUSH(fp); /* read response */ @@ -176,7 +179,7 @@ enum nss_status _nss_ldap_getnetent_r(struct netent *result,char *buffer,size_t 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_SUCCESS)||(retv==NSS_STATUS_NOTFOUND)); + while (retv==NSS_STATUS_NOTFOUND); return retv; } diff --git a/server/network.c b/server/network.c index 7f84bb6..98f2caa 100644 --- a/server/network.c +++ b/server/network.c @@ -23,8 +23,6 @@ MA 02110-1301 USA */ -/* parts based on nss_nis */ - #include "config.h" #include <stdio.h> @@ -50,44 +48,32 @@ #include "ldap-nss.h" #include "util.h" +#include "nslcd-server.h" +#include "common.h" +#include "log.h" #if defined(HAVE_USERSEC_H) #define MAXALIASES 35 #define MAXADDRSIZE 4 #endif /* HAVE_USERSEC_H */ -#define MAP_H_ERRNO(nss_status, herr) do { \ - switch ((nss_status)) { \ - case NSS_STATUS_SUCCESS: \ - (herr) = 0; \ - break; \ - case NSS_STATUS_TRYAGAIN: \ - (herr) = TRY_AGAIN; \ - break; \ - case NSS_STATUS_NOTFOUND: \ - (herr) = HOST_NOT_FOUND;\ - break; \ - case NSS_STATUS_UNAVAIL: \ - default: \ - (herr) = NO_RECOVERY; \ - break; \ - } \ - } while (0) - -#define LOOKUP_SETENT(key) \ - if (_nss_ldap_ent_context_init(&key) == NULL) \ - return NSS_STATUS_UNAVAIL; \ - return NSS_STATUS_SUCCESS - - -#define LOOKUP_ENDENT(key) \ - _nss_ldap_enter(); \ - _nss_ldap_ent_context_release(key); \ - _nss_ldap_leave(); \ - return NSS_STATUS_SUCCESS - -static struct ent_context *net_context = NULL; - +/* write a single network entry to the stream */ +static int write_netent(FILE *fp,struct netent *result) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + /* write the network name */ + WRITE_STRING(fp,result->n_name); + /* write the alias list */ + WRITE_STRINGLIST_NULLTERM(fp,result->n_aliases); + /* write the number of addresses */ + WRITE_INT32(fp,1); + /* write the addresses in network byte order */ + WRITE_INT32(fp,result->n_addrtype); + WRITE_INT32(fp,sizeof(unsigned long int)); + result->n_net=htonl(result->n_net); + WRITE_INT32(fp,result->n_net); + return 0; +} static enum nss_status _nss_ldap_parse_net (LDAPMessage * e, struct ldap_state * pvt, @@ -123,110 +109,138 @@ _nss_ldap_parse_net (LDAPMessage * e, return NSS_STATUS_SUCCESS; } -enum nss_status _nss_ldap_getnetbyname_r(const char *name,struct netent *result, - char *buffer,size_t buflen,int *errnop, - int *herrnop) +int nslcd_network_byname(FILE *fp) { - enum nss_status status; + int32_t tmpint32; + char *name; struct ldap_args a; - - LA_INIT (a); - LA_STRING (a) = name; - LA_TYPE (a) = LA_TYPE_STRING; - - status = _nss_ldap_getbyname (&a, - result, - buffer, - buflen, - errnop, - _nss_ldap_filt_getnetbyname, - LM_NETWORKS, _nss_ldap_parse_net); - - MAP_H_ERRNO (status, *herrnop); - - return status; + int retv; + struct netent result; + char buffer[1024]; + int errnop; + /* read request parameters */ + READ_STRING_ALLOC(fp,name); + /* log call */ + log_log(LOG_DEBUG,"nslcd_network_byname(%s)",name); + /* write the response header */ + /* FIXME: free(name) when one of these writes fails */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_NETWORK_BYNAME); + /* do the LDAP request */ + LA_INIT(a); + LA_STRING(a)=name; + LA_TYPE(a)=LA_TYPE_STRING; + retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getnetbyname,LM_NETWORKS,_nss_ldap_parse_net)); + /* no more need for this string */ + free(name); + /* write the response */ + WRITE_INT32(fp,retv); + if (retv==NSLCD_RESULT_SUCCESS) + write_netent(fp,&result); + WRITE_FLUSH(fp); + /* we're done */ + return 0; } -enum nss_status _nss_ldap_getnetbyaddr_r(unsigned long addr,int type, - struct netent *result,char *buffer,size_t buflen, - int *errnop,int *herrnop) +int nslcd_network_byaddr(FILE *fp) { - struct in_addr in; - char buf[256]; - int blen; + int32_t tmpint32; + int af; + int len; + char addr[64],name[1024]; struct ldap_args a; - enum nss_status retval = NSS_STATUS_NOTFOUND; - - LA_INIT (a); - LA_TYPE (a) = LA_TYPE_STRING; - - in = inet_makeaddr (addr, 0); - strcpy (buf, inet_ntoa (in)); - blen = strlen (buf); - LA_STRING (a) = buf; - - while (1) + int retv=456; + struct netent result; + char buffer[1024]; + int errnop; + /* read address family */ + READ_INT32(fp,af); + if (af!=AF_INET) + { + log_log(LOG_WARNING,"incorrect address family specified: %d",af); + return -1; + } + /* read address length */ + READ_INT32(fp,len); + if ((len>64)||(len<=0)) + { + log_log(LOG_WARNING,"address length incorrect: %d",len); + return -1; + } + /* read address */ + READ(fp,addr,len); + /* translate the address to a string */ + if (inet_ntop(af,addr,name,1024)==NULL) + { + log_log(LOG_WARNING,"unable to convert address to string"); + return -1; + } + /* log call */ + log_log(LOG_DEBUG,"nslcd_network_byaddr(%s)",name); + /* write the response header */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_NETWORK_BYADDR); + /* prepare the LDAP request */ + LA_INIT(a); + LA_STRING(a)=name; + LA_TYPE(a)=LA_TYPE_STRING; + /* do requests until we find a result */ + /* TODO: probably do more sofisticated queries */ + while (retv==456) + { + /* do the request */ + retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop,_nss_ldap_filt_getnetbyaddr,LM_NETWORKS,_nss_ldap_parse_net)); + /* if no entry was found, retry with .0 stripped from the end */ + if ((retv==NSLCD_RESULT_NOTFOUND) && + (strlen(name)>2) && + (strncmp(name+strlen(name)-2,".0",2)==0)) { - retval = _nss_ldap_getbyname (&a, result, buffer, buflen, errnop, - _nss_ldap_filt_getnetbyaddr, - LM_NETWORKS, _nss_ldap_parse_net); - - if (retval != NSS_STATUS_SUCCESS) - { - if (retval == NSS_STATUS_NOTFOUND) - { - if (buf[blen - 2] == '.' && buf[blen - 1] == '\0') - { - buf[blen - 2] = '\0'; - blen -= 2; - continue; - } - else - { - MAP_H_ERRNO (retval, *herrnop); - return NSS_STATUS_NOTFOUND; - } - } - else - { - MAP_H_ERRNO (retval, *herrnop); - return retval; - } - } - else - { - /* retval == NSS_STATUS_SUCCESS */ - break; - } + /* strip .0 and try again */ + name[strlen(name)-2]='\0'; + retv=456; } - - MAP_H_ERRNO (NSS_STATUS_SUCCESS, *herrnop); - - return retval; -} - -enum nss_status _nss_ldap_setnetent(void) -{ - LOOKUP_SETENT (net_context); -} - -enum nss_status _nss_ldap_getnetent_r(struct netent *result,char *buffer,size_t buflen, - int *errnop,int *herrnop) -{ - enum nss_status status; - status = _nss_ldap_getent (&net_context, - result, - buffer, - buflen, - errnop, - _nss_ldap_filt_getnetent, - LM_NETWORKS, _nss_ldap_parse_net); - - MAP_H_ERRNO (status, *herrnop); - return status; + } + /* write the response */ + WRITE_INT32(fp,retv); + if (retv==NSLCD_RESULT_SUCCESS) + write_netent(fp,&result); + WRITE_FLUSH(fp); + /* we're done */ + return 0; } -enum nss_status _nss_ldap_endnetent(void) +int nslcd_network_all(FILE *fp) { - LOOKUP_ENDENT (net_context); + int32_t tmpint32; + static struct ent_context *net_context; + /* these are here for now until we rewrite the LDAP code */ + struct netent result; + char buffer[1024]; + int errnop; + int retv; + /* log call */ + log_log(LOG_DEBUG,"nslcd_network_all()"); + /* write the response header */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_NETWORK_ALL); + /* initialize context */ + if (_nss_ldap_ent_context_init(&net_context)==NULL) + return -1; + /* loop over all results */ + while ((retv=nss2nslcd(_nss_ldap_getent(&net_context,&result,buffer,1024,&errnop,_nss_ldap_filt_getnetent,LM_NETWORKS,_nss_ldap_parse_net)))==NSLCD_RESULT_SUCCESS) + { + /* write the result */ + WRITE_INT32(fp,retv); + if (retv==NSLCD_RESULT_SUCCESS) + write_netent(fp,&result); + } + /* write the final result code */ + WRITE_INT32(fp,retv); + WRITE_FLUSH(fp); + /* FIXME: if a previous call returns what happens to the context? */ + _nss_ldap_enter(); + _nss_ldap_ent_context_release(net_context); + _nss_ldap_leave(); + /* we're done */ + return 0; } @@ -20,6 +20,8 @@ MA 02110-1301 USA */ +#include "config.h" + #include <string.h> #include <stdio.h> #include <errno.h> @@ -123,6 +125,26 @@ static void printhost(struct hostent *host) "}\n",i); } +static void printnetwork(struct netent *network) +{ + int i; + printf("struct netent {\n" + " n_name=\"%s\",\n", + network->n_name); + for (i=0;network->n_aliases[i]!=NULL;i++) + printf(" n_aliases[%d]=\"%s\",\n", + i,network->n_aliases[i]); + printf(" n_aliases[%d]=NULL,\n",i); + if (network->n_addrtype==AF_INET) + printf(" n_addrtype=AF_INET,\n"); + else if (network->n_addrtype==AF_INET6) + printf(" n_addrtype=AF_INET6,\n"); + else + printf(" n_addrtype=%d,\n",network->n_addrtype); + printf(" n_net=%s\n" + "}\n",inet_ntoa(inet_makeaddr(network->n_net,0))); +} + static void printether(struct etherent *ether) { printf("struct etherent {\n" @@ -230,6 +252,7 @@ int main(int argc,char *argv[]) struct aliasent aliasresult; struct group groupresult; struct hostent hostresult; + struct netent netresult; struct etherent etherresult; struct spwd shadowresult; struct __netgrent netgroupresult; @@ -493,7 +516,7 @@ int main(int argc,char *argv[]) printf("errno=%d:%s\n",(int)errnocp,strerror(errnocp)); res=_nss_ldap_endnetgrent(&netgroupresult); printf("status=%s\n",nssstatus(res)); - + /* test getprotobyname() */ printf("\nTEST getprotobyname()\n"); res=_nss_ldap_getprotobyname_r("foo",&protoresult,buffer,1024,&errnocp); @@ -590,5 +613,44 @@ int main(int argc,char *argv[]) res=_nss_ldap_endservent(); printf("status=%s\n",nssstatus(res)); + /* test getnetbyname() */ + printf("\nTEST getnetbyname()\n"); + res=_nss_ldap_getnetbyname_r("west",&netresult,buffer,1024,&errnocp,&h_errnocp); + printf("status=%s\n",nssstatus(res)); + if (res==NSS_STATUS_SUCCESS) + printnetwork(&netresult); + else + { + printf("errno=%d:%s\n",(int)errnocp,strerror(errnocp)); + printf("h_errno=%d:%s\n",(int)h_errnocp,hstrerror(h_errnocp)); + } + + /* test getnetbyaddr() */ + printf("\nTEST getnetbyaddr()\n"); + res=_nss_ldap_getnetbyaddr_r(inet_network("192.43.210.0"),AF_INET,&netresult,buffer,1024,&errnocp,&h_errnocp); + printf("status=%s\n",nssstatus(res)); + if (res==NSS_STATUS_SUCCESS) + printnetwork(&netresult); + else + { + printf("errno=%d:%s\n",(int)errnocp,strerror(errnocp)); + printf("h_errno=%d:%s\n",(int)h_errnocp,hstrerror(h_errnocp)); + } + + /* test {set,get,end}netent() */ + printf("\nTEST {set,get,end}netent()\n"); + res=_nss_ldap_setnetent(1); + printf("status=%s\n",nssstatus(res)); + while ((res=_nss_ldap_getnetent_r(&netresult,buffer,1024,&errnocp,&h_errnocp))==NSS_STATUS_SUCCESS) + { + printf("status=%s\n",nssstatus(res)); + printnetwork(&netresult); + } + printf("status=%s\n",nssstatus(res)); + printf("errno=%d:%s\n",(int)errnocp,strerror(errnocp)); + printf("h_errno=%d:%s\n",(int)h_errnocp,hstrerror(h_errnocp)); + res=_nss_ldap_endnetent(); + printf("status=%s\n",nssstatus(res)); + return 0; } |