diff options
| author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2007-11-20 10:32:56 -0500 |
|---|---|---|
| committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2007-11-20 10:32:56 -0500 |
| commit | 1c3bfde9c0a8b1990ff3be15f0abf397f4df82e7 (patch) | |
| tree | d19e7a2caad5c229df0d356ba15c0d8f41e0d640 /src/plugin.c | |
| parent | 89b87092358c5f144fec29d16207b77664ff6880 (diff) | |
| download | slapi-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.c | 615 |
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"); |
