Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
}