Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2006-11-25 11:56:24 +0100
committerArthur de Jong <arthur@arthurdejong.org>2006-11-25 11:56:24 +0100
commit70f10e2b6c10e7e47ab3377854e61a4534af79fb (patch)
tree4bab7fb53ab220809034db70411a23711fa7417b
parent1d4906c0e367960d35bd688e85b31cb6a376f5bc (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.c2
-rw-r--r--nss/services.c53
-rw-r--r--server/service.c164
-rw-r--r--testnss.c49
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;
}
diff --git a/testnss.c b/testnss.c
index 9078783..85845f7 100644
--- a/testnss.c
+++ b/testnss.c
@@ -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;
}