summaryrefslogtreecommitdiffstats
path: root/src/plugin.c
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2007-11-20 10:32:56 -0500
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2007-11-20 10:32:56 -0500
commit1c3bfde9c0a8b1990ff3be15f0abf397f4df82e7 (patch)
treed19e7a2caad5c229df0d356ba15c0d8f41e0d640 /src/plugin.c
parent89b87092358c5f144fec29d16207b77664ff6880 (diff)
downloadslapi-nis-1c3bfde9c0a8b1990ff3be15f0abf397f4df82e7.tar.gz
slapi-nis-1c3bfde9c0a8b1990ff3be15f0abf397f4df82e7.tar.xz
slapi-nis-1c3bfde9c0a8b1990ff3be15f0abf397f4df82e7.zip
- dummy version runs(!)
Diffstat (limited to 'src/plugin.c')
-rw-r--r--src/plugin.c615
1 files changed, 530 insertions, 85 deletions
diff --git a/src/plugin.c b/src/plugin.c
index 1f19e93..885ccde 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -15,7 +15,7 @@
#include <rpc/rpc.h>
#include <rpc/pmap_clnt.h>
-#include <rpcsvc/yp.h>
+#include <rpcsvc/yp_prot.h>
#include <nspr.h>
#include <secport.h>
@@ -23,7 +23,7 @@
#include <dirsrv/slapi-plugin.h>
#define PACKAGE_VERSION "0.0"
-#define PORT 3280
+#define PORT 388
/* the module initialization function */
static Slapi_PluginDesc
@@ -33,66 +33,48 @@ plugin_description = {
.spd_version = PACKAGE_VERSION,
.spd_description = "sample plugin",
};
-
+struct domain {
+ char *domain;
+ struct map {
+ char *name;
+ char *key;
+ char *format;
+ } *maps;
+ int n_maps;
+};
struct state {
pthread_t tid;
Slapi_ComponentId *plugin_identity;
PLArenaPool *arena;
- int listenfd[2];
+ int listeners;
+ int listenfd[4];
+ int sock_pf[4];
+ int sock_type[4];
};
-struct search_data {
+struct search_stream_data {
struct state *state;
int client;
};
+struct map default_maps[] = {
+ {"passwd.byname", "uid", "uid"},
+ {"passwd.bynumber", "uidNumber", "uid"},
+};
+struct domain local_domains = {
+ ".local",
+ default_maps,
+ sizeof(default_maps) / sizeof(default_maps[0]),
+};
+
static int
-setup_listener(struct state **lstate)
+setup_listeners(struct state **lstate)
{
- int sockfd = -1, sockfd6 = -1, err;
- struct sockaddr_in addr;
+ int sockfd = -1, err, i;
+ struct sockaddr_in addr4;
struct sockaddr_in6 addr6;
struct state *state;
PLArenaPool *arena = NULL;
- sockfd = socket(PF_INET, SOCK_STREAM, 0);
- if (sockfd == -1) {
- slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
- "error creating ipv4 listening socket\n");
- goto failed;
- }
- sockfd6 = socket(PF_INET6, SOCK_STREAM, 0);
- if (sockfd6 == -1) {
- slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
- "error creating ipv6 listening socket\n");
- goto failed;
- }
- memset(&addr, 0, sizeof(addr));
- addr.sin_port = htons(PORT);
- if (bind(sockfd, (struct sockaddr*) &addr,
- sizeof(struct sockaddr_in)) == -1) {
- slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
- "error binding to ipv4 port\n");
- goto failed;
- }
- memset(&addr6, 0, sizeof(addr6));
- addr6.sin6_port = htons(PORT);
- if (bind(sockfd6, (struct sockaddr*) &addr6,
- sizeof(struct sockaddr_in6)) == -1) {
- slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
- "error binding to ipv6 port\n");
- close(sockfd6);
- sockfd6 = -1;
- }
- if (listen(sockfd, 128) == -1) {
- slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
- "error marking ipv4 socket for listening\n");
- goto failed;
- }
- if ((sockfd6 != -1) && (listen(sockfd6, 128) == -1)) {
- slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
- "error marking ipv6 socket for listening\n");
- goto failed;
- }
arena = PORT_NewArena(sizeof(double));
if (arena == NULL) {
goto failed;
@@ -102,8 +84,82 @@ setup_listener(struct state **lstate)
goto failed;
}
state->arena = arena;
- state->listenfd[0] = sockfd;
- state->listenfd[1] = sockfd6;
+
+ for (i = 0; i < 4; i++) {
+ int sock_pf, sock_type, one = 1;
+ struct sockaddr *addr;
+ socklen_t addrlen;
+ switch (i) {
+ case 0:
+ sock_pf = PF_INET;
+ sock_type = SOCK_DGRAM;
+ addr = (struct sockaddr *) &addr4;
+ addrlen = sizeof(addr4);
+ break;
+ case 1:
+ sock_pf = PF_INET;
+ sock_type = SOCK_STREAM;
+ addr = (struct sockaddr *) &addr4;
+ addrlen = sizeof(addr4);
+ break;
+ case 2:
+ sock_pf = PF_INET6;
+ sock_type = SOCK_DGRAM;
+ addr = (struct sockaddr *) &addr6;
+ addrlen = sizeof(addr6);
+ break;
+ case 3:
+ sock_pf = PF_INET6;
+ sock_type = SOCK_STREAM;
+ addr = (struct sockaddr *) &addr6;
+ addrlen = sizeof(addr6);
+ break;
+ }
+ memset(&addr4, 0, sizeof(addr4));
+ addr4.sin_port = htons(PORT);
+ memset(&addr6, 0, sizeof(addr6));
+ addr6.sin6_port = htons(PORT);
+ sockfd = socket(sock_pf, sock_type, 0);
+ if (sockfd == -1) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "error creating a listening socket\n");
+ continue;
+ }
+ if (setsockopt(sockfd, IPPROTO_IP, SO_REUSEADDR,
+ &one, sizeof(one)) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "error marking socket for reuse\n");
+ }
+ if (bind(sockfd, addr, addrlen) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "error binding to listening port\n");
+ close(sockfd);
+ continue;
+ }
+ if ((sock_type == SOCK_STREAM) && (listen(sockfd, 128) == -1)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "error marking socket for listening\n");
+ close(sockfd);
+ continue;
+ }
+ state->listenfd[state->listeners] = sockfd;
+ state->sock_pf[state->listeners] = sock_pf;
+ state->sock_type[state->listeners] = sock_type;
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "listening on port %d for %s%s clients\n",
+ PORT,
+ sock_type == SOCK_STREAM ? "tcp" : "udp",
+ sock_pf == PF_INET6 ? "6" : "");
+ state->listeners++;
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "set up %d listening sockets\n", state->listeners);
*lstate = state;
return 0;
failed:
@@ -111,20 +167,14 @@ failed:
if (arena != NULL) {
PORT_FreeArena(arena, PR_TRUE);
}
- if (sockfd != -1) {
- close(sockfd);
- }
- if (sockfd != -1) {
- close(sockfd6);
- }
errno = err;
return -1;
}
static void
-cb_result(int rc, void *callback_data)
+cb_stream_result(int rc, void *callback_data)
{
- struct search_data *data = callback_data;
+ struct search_stream_data *data = callback_data;
char buf[sizeof(rc) * 4 + 1];
slapi_log_error(SLAPI_LOG_PLUGIN, "cb_result",
"returning result %d\n", rc);
@@ -133,9 +183,9 @@ cb_result(int rc, void *callback_data)
}
static int
-cb_entry(Slapi_Entry *e, void *callback_data)
+cb_stream_entry(Slapi_Entry *e, void *callback_data)
{
- struct search_data *data = callback_data;
+ struct search_stream_data *data = callback_data;
Slapi_Attr *attr;
Slapi_ValueSet *values;
Slapi_Value *value;
@@ -143,7 +193,7 @@ cb_entry(Slapi_Entry *e, void *callback_data)
const struct berval *val;
int i;
attr = NULL;
- if (slapi_entry_attr_find(e, "namingContexts", &attr) == 0) {
+ if (slapi_entry_attr_find(e, "ou", &attr) == 0) {
dn = slapi_entry_get_dn(e);
slapi_log_error(SLAPI_LOG_PLUGIN, "cb_entry",
"returning entry \"%s\"\n", dn);
@@ -169,9 +219,9 @@ cb_entry(Slapi_Entry *e, void *callback_data)
}
static int
-cb_referral(char *referral, void *callback_data)
+cb_stream_referral(char *referral, void *callback_data)
{
- struct search_data *data = callback_data;
+ struct search_stream_data *data = callback_data;
slapi_log_error(SLAPI_LOG_PLUGIN, "cb_referral",
"returning referral to \"%s\"\n", referral);
write(data->client, "See also ", 9);
@@ -181,62 +231,453 @@ cb_referral(char *referral, void *callback_data)
}
static void
-handle_client(struct state *state, int client)
+handle_stream_client(struct state *state, int client)
{
Slapi_PBlock *pblock;
int i;
char *attrs[] = {
- "namingContexts",
+ "ou",
NULL,
};
- struct search_data data;
+ struct search_stream_data data;
memset(&data, 0, sizeof(data));
data.state = state;
data.client = client;
pblock = slapi_pblock_new();
slapi_search_internal_set_pb(pblock,
- "", LDAP_SCOPE_BASE, "(objectclass=*)",
+ "dc=boston,dc=redhat,dc=com",
+ LDAP_SCOPE_ONE,
+ "(objectclass=*)",
attrs, 0,
NULL,
NULL,
state->plugin_identity,
0);
i = slapi_search_internal_callback_pb(pblock, &data,
- cb_result, cb_entry, cb_referral);
+ cb_stream_result,
+ cb_stream_entry,
+ cb_stream_referral);
slapi_pblock_destroy(pblock);
close(client);
}
+static void
+handle_dgram_client(struct state *state, int sockfd,
+ char *dgram, int dgram_size,
+ struct sockaddr *client_addr, socklen_t client_addrlen)
+{
+ XDR request_xdrs, reply_xdrs, auth_xdrs;
+ AUTH *request_auth, *reply_auth;
+ char reply_buf[64000], auth_buf[64000];
+ struct rpc_msg request, reply;
+ int superuser, send_reply, auth_flavor, auth_len;
+ memset(&request_xdrs, 0, sizeof(request_xdrs));
+ memset(&reply_xdrs, 0, sizeof(reply_xdrs));
+ memset(&request, 0, sizeof(request));
+ memset(&reply, 0, sizeof(reply));
+ xdrmem_create(&request_xdrs, dgram, dgram_size, XDR_DECODE);
+ if (xdr_callmsg(&request_xdrs, &request) &&
+ (request.rm_direction == CALL)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "client request prog=%d,ver=%d,proc=%d\n",
+ request.rm_call.cb_prog,
+ request.rm_call.cb_vers,
+ request.rm_call.cb_proc);
+ /* verify the client's creds */
+ auth_flavor = request.rm_call.cb_cred.oa_flavor;
+ switch (auth_flavor) {
+ case AUTH_SYS:
+ request_auth = authunix_create_default();
+ break;
+ case AUTH_NONE:
+ default:
+ request_auth = authnone_create();
+ break;
+ }
+ if (auth_validate(request_auth, &request.rm_call.cb_cred)) {
+ switch (auth_flavor) {
+ case AUTH_SYS:
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "validated auth_sys creds\n");
+ superuser = 0;
+ break;
+ default:
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "validated other creds\n");
+ superuser = 0;
+ break;
+ }
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "failed to validate client creds\n");
+ superuser = 0;
+ }
+ auth_destroy(request_auth);
+ /* setup authentication for our reply */
+ xdrmem_create(&auth_xdrs, auth_buf, sizeof(auth_buf),
+ XDR_ENCODE);
+ switch (auth_flavor) {
+ case AUTH_SYS:
+ reply_auth = authunix_create_default();
+ break;
+ case AUTH_NONE:
+ default:
+ reply_auth = authnone_create();
+ break;
+ }
+ auth_marshall(reply_auth, &auth_xdrs);
+ auth_destroy(reply_auth);
+ auth_len = xdr_getpos(&auth_xdrs);
+ xdr_destroy(&auth_xdrs);
+ /* fill out the common fields */
+ reply.rm_xid = request.rm_xid;
+ reply.rm_direction = REPLY;
+ send_reply = 1;
+ xdrmem_create(&reply_xdrs, reply_buf, sizeof(reply_buf),
+ XDR_ENCODE);
+ /* check if the request is meant for us */
+ if ((request.rm_direction != CALL) ||
+ (request.rm_call.cb_rpcvers != 2) ||
+ (request.rm_call.cb_prog != YPPROG) ||
+ (request.rm_call.cb_vers != YPVERS)) {
+ reply.rm_reply.rp_stat = MSG_DENIED;
+ reply.rm_reply.rp_rjct.rj_stat = RPC_MISMATCH;
+ xdr_replymsg(&reply_xdrs, &reply);
+ } else {
+ char domainname[YPMAXDOMAIN], *p = domainname;
+ bool_t bool_ret = 1;
+ struct ypreq_key req_key;
+ struct ypreq_nokey req_nokey;
+ struct ypresp_val resp_val;
+ struct ypresp_key_val resp_key_val;
+ struct ypresp_master resp_master;
+ struct ypresp_order resp_order;
+ struct ypresp_all resp_all;
+ switch (request.rm_call.cb_proc) {
+ case YPPROC_NULL:
+ case YPPROC_XFR:
+ case YPPROC_CLEAR:
+ /* do nothing */
+ reply.rm_reply.rp_stat = MSG_ACCEPTED;
+ reply.rm_reply.rp_acpt.ar_stat = SUCCESS;
+ case YPPROC_DOMAIN:
+ case YPPROC_DOMAIN_NONACK:
+ /* indicate whether or not we support a
+ * specified domain */
+ if (xdr_string(&request_xdrs,
+ &p, sizeof(domainname))) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "domain(%s)? ", p);
+ reply.rm_reply.rp_stat = MSG_ACCEPTED;
+ reply.rm_reply.rp_acpt.ar_stat = SUCCESS;
+ bool_ret = strcmp(p, ".local") == 0;
+ reply.rm_reply.rp_acpt.ar_results.where = &bool_ret;
+ reply.rm_reply.rp_acpt.ar_results.proc = xdr_bool;
+ if ((request.rm_call.cb_proc == YPPROC_DOMAIN_NONACK) &&
+ (bool_ret == 0)) {
+ send_reply = 0;
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "-> %d\n", bool_ret);
+ }
+ break;
+ case YPPROC_MATCH:
+ /* match one key */
+ if (xdr_ypreq_key(&request_xdrs, &req_key)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "match(%s/%s/%.*s)? ",
+ req_key.domain,
+ req_key.map,
+ (int) req_key.keydat.keydat_len,
+ req_key.keydat.keydat_val);
+ memset(&resp_val, 0, sizeof(resp_val));
+ resp_val.status = YP_TRUE;
+ resp_val.valdat.valdat_val = "jimbo:*K*:1234:5678:Leeroy Jenkins:/home/leeroy:/bin/bash";
+ resp_val.valdat.valdat_len = strlen(resp_val.valdat.valdat_val);
+ reply.rm_reply.rp_stat = MSG_ACCEPTED;
+ reply.rm_reply.rp_acpt.ar_stat = SUCCESS;
+ reply.rm_reply.rp_acpt.ar_results.where = &resp_val;
+ reply.rm_reply.rp_acpt.ar_results.proc = xdr_ypresp_val;
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "-> %d\n",
+ resp_val.status);
+ }
+ break;
+ case YPPROC_FIRST:
+ /* get first key/val */
+ if (xdr_ypreq_nokey(&request_xdrs, &req_nokey)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "first(%s/%s)? ",
+ req_nokey.domain,
+ req_nokey.map);
+ memset(&resp_val, 0, sizeof(resp_val));
+ resp_key_val.status = YP_TRUE;
+ resp_key_val.keydat.keydat_val = "jimbo";
+ resp_key_val.keydat.keydat_len = strlen(resp_key_val.keydat.keydat_val);
+ resp_key_val.valdat.valdat_val = "jimbo:*K*:1234:5678:Leeroy Jenkins:/home/leeroy:/bin/bash";
+ resp_key_val.valdat.valdat_len = strlen(resp_key_val.valdat.valdat_val);
+ reply.rm_reply.rp_stat = MSG_ACCEPTED;
+ reply.rm_reply.rp_acpt.ar_stat = SUCCESS;
+ reply.rm_reply.rp_acpt.ar_results.where = &resp_key_val;
+ reply.rm_reply.rp_acpt.ar_results.proc = xdr_ypresp_key_val;
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "-> %d\n",
+ resp_key_val.status);
+ }
+ break;
+ case YPPROC_NEXT:
+ /* XXX */
+ break;
+ case YPPROC_ALL:
+ /* get all keys/vals */
+ if (xdr_ypreq_nokey(&request_xdrs, &req_nokey)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "all(%s/%s)? ",
+ req_nokey.domain,
+ req_nokey.map);
+ bool_ret = 1;
+ reply.rm_reply.rp_stat = MSG_ACCEPTED;
+ reply.rm_reply.rp_acpt.ar_stat = SUCCESS;
+ reply.rm_reply.rp_acpt.ar_results.where = NULL;
+ reply.rm_reply.rp_acpt.ar_results.proc = xdr_void;
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "-> %d\n",
+ bool_ret);
+ }
+ break;
+ case YPPROC_MASTER:
+ /* get the master */
+ if (xdr_ypreq_nokey(&request_xdrs, &req_nokey)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "master(%s/%s)? ",
+ req_nokey.domain,
+ req_nokey.map);
+ memset(&resp_val, 0, sizeof(resp_val));
+ resp_master.status = YP_TRUE;
+ resp_master.master = "";
+ reply.rm_reply.rp_stat = MSG_ACCEPTED;
+ reply.rm_reply.rp_acpt.ar_stat = SUCCESS;
+ reply.rm_reply.rp_acpt.ar_results.where = &resp_master;
+ reply.rm_reply.rp_acpt.ar_results.proc = xdr_ypresp_master;
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "-> %d\n",
+ resp_master.status);
+ }
+ break;
+ case YPPROC_ORDER:
+ /* get the order */
+ if (xdr_ypreq_nokey(&request_xdrs, &req_nokey)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "all(%s/%s)? ",
+ req_nokey.domain,
+ req_nokey.map);
+ memset(&resp_val, 0, sizeof(resp_val));
+ resp_order.status = YP_TRUE;
+ resp_order.ordernum = 0;
+ reply.rm_reply.rp_stat = MSG_ACCEPTED;
+ reply.rm_reply.rp_acpt.ar_stat = SUCCESS;
+ reply.rm_reply.rp_acpt.ar_results.where = &resp_order;
+ reply.rm_reply.rp_acpt.ar_results.proc = xdr_ypresp_order;
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "-> %d\n", resp_order.status);
+ }
+ break;
+ case YPPROC_MAPLIST:
+ break;
+ default:
+ reply.rm_reply.rp_stat = MSG_DENIED;
+ reply.rm_reply.rp_rjct.rj_stat = RPC_MISMATCH;
+ break;
+ }
+ if (send_reply) {
+ if (reply.rm_reply.rp_stat == MSG_ACCEPTED) {
+ struct opaque_auth oa;
+ oa.oa_flavor = auth_flavor;
+ oa.oa_base = auth_buf;
+ oa.oa_length = auth_len;
+ reply.rm_reply.rp_acpt.ar_verf = oa;
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "encoding reply\n");
+ if (client_addr != NULL) {
+ xdr_replymsg(&reply_xdrs, &reply);
+ sendto(sockfd,
+ reply_buf,
+ xdr_getpos(&reply_xdrs),
+ 0, client_addr, client_addrlen);
+ } else {
+ uint32_t len;
+ if (request.rm_call.cb_proc == YPPROC_ALL) {
+ resp_key_val.status = YP_TRUE;
+ resp_key_val.keydat.keydat_val = "jimbo";
+ resp_key_val.keydat.keydat_len = strlen(resp_key_val.keydat.keydat_val);
+ resp_key_val.valdat.valdat_val = "jimbo:*K*:1234:5678:Leeroy Jenkins:/home/leeroy:/bin/bash";
+ resp_key_val.valdat.valdat_len = strlen(resp_key_val.valdat.valdat_val);
+
+ xdr_setpos(&reply_xdrs, 4);
+ xdr_replymsg(&reply_xdrs, &reply);
+ bool_ret = 1;
+ xdr_bool(&reply_xdrs, &bool_ret);
+ xdr_ypresp_key_val(&reply_xdrs,
+ &resp_key_val);
+ xdr_bool(&reply_xdrs, &bool_ret);
+ xdr_ypresp_key_val(&reply_xdrs,
+ &resp_key_val);
+ len = htonl(xdr_getpos(&reply_xdrs) - 4);
+ memcpy(reply_buf, &len, 4);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "sending %d bytes\n",
+ xdr_getpos(&reply_xdrs));
+ send(sockfd, reply_buf,
+ xdr_getpos(&reply_xdrs), 0);
+ xdr_setpos(&reply_xdrs, 4);
+ bool_ret = 1;
+ xdr_bool(&reply_xdrs, &bool_ret);
+ xdr_ypresp_key_val(&reply_xdrs,
+ &resp_key_val);
+ bool_ret = 0;
+ xdr_bool(&reply_xdrs, &bool_ret);
+ len = htonl((xdr_getpos(&reply_xdrs) - 4) | 0x80000000);
+ memcpy(reply_buf, &len, 4);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "sending %d bytes\n",
+ xdr_getpos(&reply_xdrs));
+ send(sockfd, reply_buf,
+ xdr_getpos(&reply_xdrs), 0);
+ }
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "sent reply\n");
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "suppressed reply\n");
+ }
+ }
+ xdr_destroy(&reply_xdrs);
+ }
+ xdr_destroy(&request_xdrs);
+}
+
+static void
+handle_stream_client_new(struct state *state, int client)
+{
+ int i, last, ret;
+ int32_t len;
+ char buf[LINE_MAX];
+ do {
+ i = read(client, &len, sizeof(len));
+ if (i == 4) {
+ len = htonl(len);
+ last = ((len >> 31) == 1);
+ len &= 0x7fffffff;
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "client request has %d bytes\n",
+ len);
+ i = 0;
+ while (i < len) {
+ ret = read(client, buf + i, len - i);
+ if (ret <= 0) {
+ close(client);
+ return;
+ }
+ i += ret;
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "processing %d byte request %s\n",
+ len, last ? "(last)" : "(more)");
+ handle_dgram_client(state, client, buf, len, NULL, 0);
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "read %d bytes, expected 4, closing\n",
+ i);
+ last = 1;
+ }
+ } while (!last);
+ close(client);
+}
+
static void *
process_requests(void *p)
{
struct state *state = p;
- struct pollfd fds[2];
- int client;
+ struct pollfd fds[4];
+ int client, i;
+ char dgram[65536];
+ struct sockaddr_storage client_addr;
+ socklen_t client_addrlen;
for (;;) {
memset(&fds, 0, sizeof(fds));
- fds[0].fd = state->listenfd[0];
- fds[0].events = POLLIN;
- fds[1].fd = state->listenfd[1];
- fds[1].events = POLLIN;
- switch (poll(fds, fds[1].fd == -1 ? 1 : 2, -1) != -1) {
+ for (i = 0; i < state->listeners; i++) {
+ fds[i].fd = state->listenfd[i];
+ fds[i].events = POLLIN;
+ }
+ switch (poll(fds, state->listeners, -1) != -1) {
case -1:
return NULL;
break;
case 0:
continue;
default:
- if (fds[0].revents & POLLIN) {
- client = accept(fds[0].fd, NULL, NULL);
- } else
- if (fds[1].revents & POLLIN) {
- client = accept(fds[1].fd, NULL, NULL);
+ for (i = 0; i < state->listeners; i++) {
+ if ((fds[i].revents & POLLIN) == 0) {
+ continue;
+ }
+ client = -1;
+ if (state->sock_type[i] == SOCK_STREAM){
+ client = accept(fds[i].fd,
+ NULL,
+ NULL);
+ }
+ if (state->sock_type [i]== SOCK_DGRAM) {
+ client_addrlen = sizeof(client_addr);
+ client = recvfrom(fds[i].fd,
+ dgram,
+ sizeof(dgram),
+ 0,
+ (struct sockaddr *) &client_addr,
+ &client_addrlen);
+ }
+ if (client == -1) {
+ continue;
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "answering client request\n");
+ if (state->sock_type[i] == SOCK_STREAM) {
+ handle_stream_client_new(state, client);
+ }
+ if (state->sock_type[i] == SOCK_DGRAM) {
+ handle_dgram_client(state, fds[i].fd,
+ dgram, client,
+ (struct sockaddr *)
+ &client_addr,
+ client_addrlen);
+ }
}
- slapi_log_error(SLAPI_LOG_PLUGIN,
- plugin_description.spd_id,
- "answering client request %d\n",
- client);
- handle_client(state, client);
}
}
return state;
@@ -276,7 +717,7 @@ int
my_init_function(Slapi_PBlock *pb)
{
struct state *state;
- if (setup_listener(&state) == -1) {
+ if (setup_listeners(&state) == -1) {
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
"error setting up listening sockets\n");
return -1;
@@ -287,6 +728,10 @@ my_init_function(Slapi_PBlock *pb)
slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, &plugin_close);
slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &state->plugin_identity);
slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, state);
+ if (pmap_unset(YPPROG, YPVERS) != 1) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, "plugin_start",
+ "error clearing registrations, continuing\n");
+ }
if (pmap_set(YPPROG, YPVERS, IPPROTO_TCP, PORT) != 1) {
slapi_log_error(SLAPI_LOG_PLUGIN, "plugin_start",
"error registering TCP port, continuing\n");