summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2007-11-29 13:15:47 -0500
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2007-11-29 13:15:47 -0500
commitf82215df2d4af8456d7228628ea5a6678ed908dd (patch)
tree941619407c77e54e88d6649918278fb9e218840b /src
parentaf4e31549b09a6cfb9774649c69c8ab769bee4ae (diff)
- split up some more
Diffstat (limited to 'src')
-rw-r--r--src/Makefile2
-rw-r--r--src/nis.c337
-rw-r--r--src/nis.h12
-rw-r--r--src/plugin.c475
-rw-r--r--src/stream.c86
-rw-r--r--src/stream.h2
6 files changed, 464 insertions, 450 deletions
diff --git a/src/Makefile b/src/Makefile
index d54f2dd..ee93e37 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -3,7 +3,7 @@ LDFLAGS = -lnsl -lpthread
all:: plugin.so portmap
-plugin.so: plugin.c portmap.c schema.c stream.c
+plugin.so: plugin.c portmap.c schema.c stream.c nis.c
$(CC) $(CFLAGS) -shared -o $@ $^ $(LDFLAGS)
portmap: portmap.c
$(CC) $(CFLAGS) -o $@ -DPORTMAP_MAIN $^ $(LDFLAGS)
diff --git a/src/nis.c b/src/nis.c
new file mode 100644
index 0000000..6090a18
--- /dev/null
+++ b/src/nis.c
@@ -0,0 +1,337 @@
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <rpcsvc/yp_prot.h>
+
+#include "nis.h"
+#include "plugin.h"
+#include "schema.h"
+
+void
+nis_process_request(struct plugin_state *state, int client,
+ struct sockaddr *client_addr, socklen_t client_addrlen,
+ char *request_buf, size_t request_buflen)
+{
+ 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, request_buf, request_buflen, XDR_DECODE);
+ if (xdr_callmsg(&request_xdrs, &request) &&
+ (request.rm_direction == CALL)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->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,
+ state->plugin_desc->spd_id,
+ "validated auth_sys creds\n");
+ superuser = 0;
+ break;
+ default:
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "validated other creds\n");
+ superuser = 0;
+ break;
+ }
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->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;
+ break;
+ 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,
+ state->plugin_desc->spd_id,
+ "domain(%s)? ", p);
+ reply.rm_reply.rp_stat = MSG_ACCEPTED;
+ reply.rm_reply.rp_acpt.ar_stat = SUCCESS;
+ bool_ret = schema_supports_domain(p);
+ 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,
+ state->plugin_desc->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,
+ state->plugin_desc->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,
+ state->plugin_desc->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,
+ state->plugin_desc->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,
+ state->plugin_desc->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,
+ state->plugin_desc->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,
+ state->plugin_desc->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,
+ state->plugin_desc->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,
+ state->plugin_desc->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,
+ state->plugin_desc->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,
+ state->plugin_desc->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,
+ state->plugin_desc->spd_id,
+ "encoding reply\n");
+ if (client_addr != NULL) {
+ xdr_replymsg(&reply_xdrs, &reply);
+ sendto(client,
+ 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,
+ state->plugin_desc->spd_id,
+ "sending %d bytes\n",
+ xdr_getpos(&reply_xdrs));
+ send(client, 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,
+ state->plugin_desc->spd_id,
+ "sending %d bytes\n",
+ xdr_getpos(&reply_xdrs));
+ send(client, reply_buf,
+ xdr_getpos(&reply_xdrs), 0);
+ }
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "sent reply\n");
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "suppressed reply\n");
+ }
+ }
+ xdr_destroy(&reply_xdrs);
+ }
+ xdr_destroy(&request_xdrs);
+}
diff --git a/src/nis.h b/src/nis.h
new file mode 100644
index 0000000..681eec7
--- /dev/null
+++ b/src/nis.h
@@ -0,0 +1,12 @@
+#ifndef nis_h
+#define nis_h
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include "plugin.h"
+
+void nis_process_request(struct plugin_state *state, int client,
+ struct sockaddr *client_addr, socklen_t client_addrlen,
+ char *request_buf, size_t request_buflen);
+
+#endif
diff --git a/src/plugin.c b/src/plugin.c
index 0b58862..da40b06 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -22,11 +22,13 @@
#include <plarenas.h>
#include <dirsrv/slapi-plugin.h>
+#include "nis.h"
+#include "plugin.h"
#include "portmap.h"
#include "schema.h"
+#include "stream.h"
#define PACKAGE_VERSION "0.0"
-#define PORT 388
/* the module initialization function */
static Slapi_PluginDesc
@@ -37,19 +39,6 @@ plugin_description = {
.spd_description = "NIS Service Plugin",
};
-struct plugin_state {
- PLArenaPool *arena;
- pthread_t tid;
- Slapi_ComponentId *plugin_identity;
- Slapi_PluginDesc *plugin_desc;
- int resvport;
- int n_listeners;
- int listenfd[4];
- int listenport[4];
- int sock_pf[4];
- int sock_type[4];
-};
-
struct search_stream_data {
struct plugin_state *state;
int client;
@@ -114,20 +103,10 @@ cb_stream_referral(char *referral, void *callback_data)
return 0;
}
-static void
-handle_stream_client(struct plugin_state *state, int client)
-{
- Slapi_PBlock *pblock;
- int i;
- char *attrs[] = {
- "ou",
- NULL,
- };
- struct search_stream_data data;
- memset(&data, 0, sizeof(data));
- data.state = state;
- data.client = client;
+#if 0
pblock = slapi_pblock_new();
+ slapi_pblock_set(pblock, SLAPI_CONN_DN, "");
+ slapi_pblock_set(pblock, SLAPI_CONN_AUTHMETHOD, SLAPD_AUTH_NONE);
slapi_search_internal_set_pb(pblock,
"dc=boston,dc=redhat,dc=com",
LDAP_SCOPE_ONE,
@@ -143,377 +122,19 @@ handle_stream_client(struct plugin_state *state, int client)
cb_stream_referral);
slapi_pblock_destroy(pblock);
close(client);
-}
-
-static void
-handle_dgram_client(struct plugin_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 = schema_supports_domain(p);
- 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 plugin_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);
-}
+#endif
static void *
-process_requests(void *p)
+listener_thread(void *p)
{
struct plugin_state *state = p;
struct pollfd fds[4];
- int client, i;
+ int client, reqsize, i;
char dgram[65536];
struct sockaddr_storage client_addr;
socklen_t client_addrlen;
for (;;) {
+ /* Set up for polling. */
memset(&fds, 0, sizeof(fds));
for (i = 0; i < state->n_listeners; i++) {
fds[i].fd = state->listenfd[i];
@@ -526,40 +147,44 @@ process_requests(void *p)
case 0:
continue;
default:
+ /* Iterate over listening sockets with work for us. */
for (i = 0; i < state->n_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) {
+ switch (state->sock_type[i]) {
+ case 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,
+ reqsize = recvfrom(fds[i].fd,
+ dgram,
+ sizeof(dgram),
+ 0,
+ (struct sockaddr *) &client_addr,
+ &client_addrlen);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "datagram request\n");
+ nis_process_request(state, fds[i].fd,
(struct sockaddr *)
&client_addr,
- client_addrlen);
+ client_addrlen,
+ dgram, reqsize);
+ break;
+ case SOCK_STREAM:
+ client = accept(fds[i].fd, NULL, NULL);
+ if (client != -1) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "new stream request\n");
+ stream_client_start(state,
+ client);
+ }
+ break;
+ default:
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "unknown request\n");
+ break;
}
}
}
@@ -577,6 +202,7 @@ plugin_start(Slapi_PBlock *pb)
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
slapi_log_error(SLAPI_LOG_PLUGIN, "plugin_start",
"plugin starting\n");
+ /* Register the listener sockets with the portmapper. */
if (state->resvport != -1) {
for (i = 0; i < state->n_listeners; i++) {
switch (state->sock_type[i]) {
@@ -606,14 +232,16 @@ plugin_start(Slapi_PBlock *pb)
}
}
}
- if (pthread_create(&state->tid, NULL, &process_requests, state) != 0) {
+ /* Start a new listening thread to handle incoming traffic. FIXME:
+ * switch to using NSPR's threading facilities. */
+ if (pthread_create(&state->tid, NULL, &listener_thread, state) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN,
plugin_description.spd_id,
"error starting listener thread\n");
return -1;
}
- slapi_log_error(SLAPI_LOG_PLUGIN, "my_init_function",
- "plugin started\n");
+ slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
+ "plugin startup completed\n");
return 0;
}
@@ -624,6 +252,7 @@ plugin_close(Slapi_PBlock *pb)
struct plugin_state *state;
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
if (state->resvport != -1) {
+ /* Clear our registration with the portmapper. */
portmap_unregister(state->resvport, YPPROG, YPVERS);
close(state->resvport);
}
@@ -631,7 +260,7 @@ plugin_close(Slapi_PBlock *pb)
}
static int
-setup_listeners(struct plugin_state **lstate)
+setup_listener_sockets(struct plugin_state **lstate)
{
int sockfd = -1, err, i;
struct plugin_state *state;
@@ -647,6 +276,9 @@ setup_listeners(struct plugin_state **lstate)
}
state->arena = arena;
+ /* Bind to a privileged port so that the portmapper will let us
+ * register after we've dropped to a non-root account. We could reuse
+ * the datagram listening socket we'll create later. */
state->resvport = socket(PF_INET, SOCK_DGRAM, 0);
if (bindresvport(state->resvport, NULL) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN,
@@ -657,6 +289,7 @@ setup_listeners(struct plugin_state **lstate)
state->resvport = -1;
}
+ /* Privileged port, datagram and stream, IPv4 and IPv6. */
for (i = 0; i < 4; i++) {
int sock_pf, sock_type, one = 1;
struct sockaddr *addr;
@@ -763,7 +396,7 @@ int
nis_plugin_init(Slapi_PBlock *pb)
{
struct plugin_state *state = NULL;
- if (setup_listeners(&state) == -1) {
+ if (setup_listener_sockets(&state) == -1) {
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
"error setting up listening sockets\n");
return -1;
diff --git a/src/stream.c b/src/stream.c
index ebf8c7f..dbb53bf 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -4,21 +4,15 @@
#include <sys/types.h>
#include <sys/socket.h>
-#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
#include <unistd.h>
-#include <nspr.h>
-#include <secport.h>
-#include <dirsrv/slapi-plugin.h>
-
+#include "nis.h"
#include "stream.h"
+#define MAX_CLIENT_IDLE (60 * 1000)
struct stream_client_thread_parms {
int client;
@@ -35,26 +29,33 @@ stream_client_thread(void *arg)
struct stream_client_thread_parms *parms = arg;
struct plugin_state *state = parms->state;
- int client = parms->client;
+ int done, client = parms->client;
free(parms);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "opened client connection %d, thread started\n",
+ client);
last = fcntl(client, F_GETFD);
if ((last == -1) ||
(fcntl(client, F_SETFD, last | O_NONBLOCK) == -1)) {
slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc.spd_id,
+ state->plugin_desc->spd_id,
"error setting new client connection to be "
"non-blocking\n");
close(client);
- client = -1;
return NULL;
}
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "set new client connection to be non-blocking\n");
frag_len = 0;
record_len = 0;
- while (client != -1) {
+ done = 0;
+ while (!done) {
pollfd.fd = client;
pollfd.events = POLLIN | POLLHUP;
- if (poll(&pollfd, 1, 60 * 1000) > 0) {
+ if (poll(&pollfd, 1, MAX_CLIENT_IDLE) > 0) {
i = read(client, fragment + frag_len,
sizeof(fragment) - frag_len);
switch (i) {
@@ -63,37 +64,57 @@ stream_client_thread(void *arg)
continue;
}
slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc.spd_id,
+ state->plugin_desc->spd_id,
"communication error\n");
- close(client);
- client = -1;
+ done = 1;
break;
case 0:
slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc.spd_id,
+ state->plugin_desc->spd_id,
"client closed connection\n");
- close(client);
- client = -1;
+ done = 1;
break;
default:
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "read %d bytes\n", i);
frag_len += i;
break;
}
if (frag_len > 4) {
memcpy(&nlen, fragment, 4);
len = ntohl(nlen);
- last = ((len >> 31) == 1);
+ last = ((len & 0x80000000) != 0);
len &= 0x7fffffff;
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "expecting %d bytes\n", len);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "in: frag_len=%d,record=%d\n",
+ frag_len, record_len);
if (frag_len >= len + 4) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "got whole fragment "
+ "(%d bytes)\n", len);
/* we have a whole fragment */
memmove(record + record_len,
fragment + 4, len);
record_len += len;
if (last) {
- /* we have a whole record */
- process_request(state, client,
- record,
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "got whole "
+ "record (%d "
+ "bytes)\n",
record_len);
+ /* we have a whole record */
+ nis_process_request(state,
+ client,
+ NULL, 0,
+ record,
+ record_len);
record_len = 0;
}
memmove(fragment,
@@ -101,16 +122,22 @@ stream_client_thread(void *arg)
frag_len - (len + 4));
frag_len -= (len + 4);
}
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "out: frag_len=%d,record=%d\n",
+ frag_len, record_len);
}
} else {
slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc.spd_id,
+ state->plugin_desc->spd_id,
"connection timeout\n");
- close(client);
- client = -1;
+ done = 1;
}
}
close(client);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "closed client connection %d, thread ending\n", client);
return NULL;
}
@@ -123,7 +150,7 @@ stream_client_start(struct plugin_state *state, int client)
parms = malloc(sizeof(*parms));
if (parms == NULL) {
slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc.spd_id,
+ state->plugin_desc->spd_id,
"out of memory\n");
close(client);
return;
@@ -133,9 +160,12 @@ stream_client_start(struct plugin_state *state, int client)
if (pthread_create(&thread, NULL, &stream_client_thread, parms) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc.spd_id,
+ state->plugin_desc->spd_id,
"error starting thread\n");
close(client);
}
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "started client-specific thread\n");
return;
}
diff --git a/src/stream.h b/src/stream.h
index 443e3cd..a5de9b9 100644
--- a/src/stream.h
+++ b/src/stream.h
@@ -1,6 +1,8 @@
#ifndef stream_h
#define stream_h
+#include "plugin.h"
+
void stream_client_start(struct plugin_state *state, int client);
#endif