diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2006-11-25 11:56:24 +0100 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2006-11-25 11:56:24 +0100 |
commit | 70f10e2b6c10e7e47ab3377854e61a4534af79fb (patch) | |
tree | 4bab7fb53ab220809034db70411a23711fa7417b | |
parent | 1d4906c0e367960d35bd688e85b31cb6a376f5bc (diff) |
implement server end of service name lookup and fix client end to translate between host and network byte order and to also pass protocol in request
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/libnss_ldapd@123 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r-- | nslcd-server.c | 2 | ||||
-rw-r--r-- | nss/services.c | 53 | ||||
-rw-r--r-- | server/service.c | 164 | ||||
-rw-r--r-- | testnss.c | 49 |
4 files changed, 219 insertions, 49 deletions
diff --git a/nslcd-server.c b/nslcd-server.c index eece9de..2249e8a 100644 --- a/nslcd-server.c +++ b/nslcd-server.c @@ -180,11 +180,9 @@ void nslcd_server_handlerequest(int sock) case NSLCD_ACTION_RPC_BYNAME: nslcd_rpc_byname(fp); break; case NSLCD_ACTION_RPC_BYNUMBER: nslcd_rpc_bynumber(fp); break; case NSLCD_ACTION_RPC_ALL: nslcd_rpc_all(fp); break; -/* case NSLCD_ACTION_SERVICE_BYNAME: nslcd_service_byname(fp); break; case NSLCD_ACTION_SERVICE_BYNUMBER: nslcd_service_bynumber(fp); break; case NSLCD_ACTION_SERVICE_ALL: nslcd_service_all(fp); break; -*/ case NSLCD_ACTION_SHADOW_BYNAME: nslcd_shadow_byname(fp); break; case NSLCD_ACTION_SHADOW_ALL: nslcd_shadow_all(fp); break; default: diff --git a/nss/services.c b/nss/services.c index 5da0f19..9f6047a 100644 --- a/nss/services.c +++ b/nss/services.c @@ -36,7 +36,7 @@ #define LDF_INT32(field) READ_INT32(fp,field) #define SERVICE_NAME result->s_name #define SERVICE_ALIASES result->s_aliases -#define SERVICE_NUMBER result->s_port +#define SERVICE_NUMBER port #define SERVICE_PROTOCOL result->s_proto static enum nss_status read_servent( @@ -44,21 +44,68 @@ static enum nss_status read_servent( char *buffer,size_t buflen,int *errnop) { int32_t tmpint32,tmp2int32,tmp3int32; + int port; size_t bufptr=0; /* auto-genereted read code */ LDF_SERVICE; + /* store number in network byte order */ + result->s_port=ntohs(port); /* 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) { - NSS_BYNAME(NSLCD_ACTION_SERVICE_BYNAME,name,read_servent); + 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; } enum nss_status _nss_ldap_getservbyport_r(int port,const char *protocol,struct servent *result,char *buffer,size_t buflen,int *errnop) { - NSS_BYINT32(NSLCD_ACTION_SERVICE_BYNUMBER,port,read_servent); + 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; } /* thread-local file pointer to an ongoing request */ diff --git a/server/service.c b/server/service.c index 8e3d49f..3133ae5 100644 --- a/server/service.c +++ b/server/service.c @@ -54,8 +54,26 @@ #include "ldap-nss.h" #include "util.h" +#include "nslcd-server.h" +#include "common.h" +#include "log.h" -static struct ent_context *serv_context = NULL; +/* macros for expanding the LDF_SERVICE macro */ +#define LDF_STRING(field) WRITE_STRING(fp,field) +#define LDF_STRINGLIST(field) WRITE_STRINGLIST_NULLTERM(fp,field) +#define LDF_INT32(field) WRITE_INT32(fp,field) +#define SERVICE_NAME result->s_name +#define SERVICE_ALIASES result->s_aliases +#define SERVICE_NUMBER htons(result->s_port) +#define SERVICE_PROTOCOL result->s_proto + +/* write a single host entry to the stream */ +static int write_servent(FILE *fp,struct servent *result) +{ + int32_t tmpint32,tmp2int32,tmp3int32; + LDF_SERVICE; + return 0; +} static enum nss_status _nss_ldap_parse_serv (LDAPMessage *e, struct ldap_state *state, @@ -172,56 +190,114 @@ static enum nss_status _nss_ldap_parse_serv (LDAPMessage *e, return NSS_STATUS_SUCCESS; } -enum nss_status _nss_ldap_getservbyname_r(const char *name, - const char *proto, - struct servent *result, - char *buffer,size_t buflen,int *errnop) +int nslcd_service_byname(FILE *fp) { + int32_t tmpint32; + char *name,*protocol; struct ldap_args a; - - LA_INIT (a); - LA_STRING (a) = name; - LA_TYPE (a) = (proto == NULL) ? LA_TYPE_STRING : LA_TYPE_STRING_AND_STRING; - LA_STRING2 (a) = proto; - - return _nss_ldap_getbyname (&a, result, buffer, buflen, errnop, - ((proto == NULL) ? _nss_ldap_filt_getservbyname - : _nss_ldap_filt_getservbynameproto), - LM_SERVICES, _nss_ldap_parse_serv); + /* these are here for now until we rewrite the LDAP code */ + struct servent result; + char buffer[1024]; + int errnop; + int retv; + /* read request parameters */ + READ_STRING_ALLOC(fp,name); + READ_STRING_ALLOC(fp,protocol); + /* log call */ + log_log(LOG_DEBUG,"nslcd_service_byname(%s,%s)",name,protocol); + /* write the response header */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_SERVICE_BYNAME); + /* do the LDAP request */ + LA_INIT(a); + LA_STRING(a)=name; + LA_TYPE(a)=(strlen(protocol)==0)?LA_TYPE_STRING:LA_TYPE_STRING_AND_STRING; + LA_STRING2(a)=protocol; + retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop, + ((strlen(protocol)==0)?_nss_ldap_filt_getservbyname:_nss_ldap_filt_getservbynameproto), + LM_SERVICES,_nss_ldap_parse_serv)); + /* no more need for these strings */ + free(name); + free(protocol); + /* write the response */ + WRITE_INT32(fp,retv); + if (retv==NSLCD_RESULT_SUCCESS) + write_servent(fp,&result); + WRITE_FLUSH(fp); + /* we're done */ + return 0; } -enum nss_status _nss_ldap_getservbyport_r(int port, - const char *proto, - struct servent *result, - char *buffer,size_t buflen,int *errnop) +int nslcd_service_bynumber(FILE *fp) { + int32_t tmpint32; + int number; + char *protocol; struct ldap_args a; - - LA_INIT (a); - LA_NUMBER (a) = htons (port); - LA_TYPE (a) = (proto == NULL) ? LA_TYPE_NUMBER : LA_TYPE_NUMBER_AND_STRING; - LA_STRING2 (a) = proto; - return _nss_ldap_getbyname (&a, result, buffer, buflen, errnop, - (proto == - NULL) ? _nss_ldap_filt_getservbyport : - _nss_ldap_filt_getservbyportproto, - LM_SERVICES, _nss_ldap_parse_serv); -} - -enum nss_status _nss_ldap_setservent(void) -{ - LOOKUP_SETENT(serv_context); -} - -enum nss_status _nss_ldap_getservent_r(struct servent *result,char *buffer,size_t buflen, - int *errnop) -{ - LOOKUP_GETENT(serv_context, result, buffer, buflen, errnop, - _nss_ldap_filt_getservent, LM_SERVICES, - _nss_ldap_parse_serv, LDAP_NSS_BUFLEN_DEFAULT); + /* these are here for now until we rewrite the LDAP code */ + struct servent result; + char buffer[1024]; + int errnop; + int retv; + /* read request parameters */ + READ_INT32(fp,number); + READ_STRING_ALLOC(fp,protocol); + /* log call */ + log_log(LOG_DEBUG,"nslcd_service_bynumber(%d,%s)",number,protocol); + /* write the response header */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_SERVICE_BYNUMBER); + /* do the LDAP request */ + LA_INIT(a); + LA_NUMBER(a)=number; + LA_TYPE(a)=(strlen(protocol)==0)?LA_TYPE_NUMBER:LA_TYPE_NUMBER_AND_STRING; + LA_STRING2(a)=protocol; + retv=nss2nslcd(_nss_ldap_getbyname(&a,&result,buffer,1024,&errnop, + ((strlen(protocol)==0)?_nss_ldap_filt_getservbyport:_nss_ldap_filt_getservbyportproto), + LM_SERVICES,_nss_ldap_parse_serv)); + /* no more need for this string */ + free(protocol); + /* write the response */ + WRITE_INT32(fp,retv); + if (retv==NSLCD_RESULT_SUCCESS) + write_servent(fp,&result); + WRITE_FLUSH(fp); + /* we're done */ + return 0; } -enum nss_status _nss_ldap_endservent(void) +int nslcd_service_all(FILE *fp) { - LOOKUP_ENDENT(serv_context); + int32_t tmpint32; + static struct ent_context *serv_context; + /* these are here for now until we rewrite the LDAP code */ + struct servent result; + char buffer[1024]; + int errnop; + int retv; + /* log call */ + log_log(LOG_DEBUG,"nslcd_service_all()"); + /* write the response header */ + WRITE_INT32(fp,NSLCD_VERSION); + WRITE_INT32(fp,NSLCD_ACTION_SERVICE_ALL); + /* initialize context */ + if (_nss_ldap_ent_context_init(&serv_context)==NULL) + return -1; + /* loop over all results */ + while ((retv=nss2nslcd(_nss_ldap_getent(&serv_context,&result,buffer,1024,&errnop,_nss_ldap_filt_getservent,LM_SERVICES,_nss_ldap_parse_serv)))==NSLCD_RESULT_SUCCESS) + { + /* write the result code */ + WRITE_INT32(fp,retv); + /* write the entry */ + write_servent(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(serv_context); + _nss_ldap_leave(); + /* we're done */ + return 0; } @@ -207,6 +207,22 @@ static void printrpc(struct rpcent *rpc) "}\n",i,(int)(rpc->r_number)); } +static void printserv(struct servent *serv) +{ + int i; + printf("struct servent {\n" + " s_name=\"%s\",\n", + serv->s_name); + for (i=0;serv->s_aliases[i]!=NULL;i++) + printf(" s_aliases[%d]=\"%s\",\n", + i,serv->s_aliases[i]); + printf(" s_aliases[%d]=NULL,\n" + " s_port=%d,\n" + " s_proto=\"%s\"\n" + "}\n",i,(int)(ntohs(serv->s_port)), + serv->s_proto); +} + /* the main program... */ int main(int argc,char *argv[]) { @@ -219,6 +235,7 @@ int main(int argc,char *argv[]) struct __netgrent netgroupresult; struct protoent protoresult; struct rpcent rpcresult; + struct servent servresult; char buffer[1024]; enum nss_status res; int errnocp,h_errnocp; @@ -541,5 +558,37 @@ int main(int argc,char *argv[]) res=_nss_ldap_endrpcent(); printf("status=%s\n",nssstatus(res)); + /* test getservbyname() */ + printf("\nTEST getservbyname()\n"); + res=_nss_ldap_getservbyname_r("srvfoo","udp",&servresult,buffer,1024,&errnocp); + printf("status=%s\n",nssstatus(res)); + if (res==NSS_STATUS_SUCCESS) + printserv(&servresult); + else + printf("errno=%d:%s\n",(int)errnocp,strerror(errnocp)); + + /* test getrpcbynumber() */ + printf("\nTEST getservbyport()\n"); + res=_nss_ldap_getservbyport_r(ntohs(9988),NULL,&servresult,buffer,1024,&errnocp); + printf("status=%s\n",nssstatus(res)); + if (res==NSS_STATUS_SUCCESS) + printserv(&servresult); + else + printf("errno=%d:%s\n",(int)errnocp,strerror(errnocp)); + + /* test {set,get,end}servent() */ + printf("\nTEST {set,get,end}servent()\n"); + res=_nss_ldap_setservent(1); + printf("status=%s\n",nssstatus(res)); + while ((res=_nss_ldap_getservent_r(&servresult,buffer,1024,&errnocp))==NSS_STATUS_SUCCESS) + { + printf("status=%s\n",nssstatus(res)); + printserv(&servresult); + } + printf("status=%s\n",nssstatus(res)); + printf("errno=%d:%s\n",(int)errnocp,strerror(errnocp)); + res=_nss_ldap_endservent(); + printf("status=%s\n",nssstatus(res)); + return 0; } |