summaryrefslogtreecommitdiffstats
path: root/src/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugin.c')
-rw-r--r--src/plugin.c318
1 files changed, 157 insertions, 161 deletions
diff --git a/src/plugin.c b/src/plugin.c
index 885ccde..333dbee 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -22,155 +22,37 @@
#include <plarenas.h>
#include <dirsrv/slapi-plugin.h>
+#include "portmap.h"
+#include "schema.h"
+
#define PACKAGE_VERSION "0.0"
#define PORT 388
/* the module initialization function */
static Slapi_PluginDesc
plugin_description = {
- .spd_id = "my-plugin",
+ .spd_id = "nis-plugin",
.spd_vendor = "hamdingers.org",
.spd_version = PACKAGE_VERSION,
- .spd_description = "sample plugin",
-};
-struct domain {
- char *domain;
- struct map {
- char *name;
- char *key;
- char *format;
- } *maps;
- int n_maps;
+ .spd_description = "NIS Service Plugin",
};
-struct state {
+
+struct plugin_state {
+ PLArenaPool *arena;
pthread_t tid;
Slapi_ComponentId *plugin_identity;
- PLArenaPool *arena;
- int listeners;
+ int resvport;
+ int n_listeners;
int listenfd[4];
int sock_pf[4];
int sock_type[4];
};
+
struct search_stream_data {
- struct state *state;
+ struct plugin_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_listeners(struct state **lstate)
-{
- int sockfd = -1, err, i;
- struct sockaddr_in addr4;
- struct sockaddr_in6 addr6;
- struct state *state;
- PLArenaPool *arena = NULL;
-
- arena = PORT_NewArena(sizeof(double));
- if (arena == NULL) {
- goto failed;
- }
- state = PORT_ArenaZAlloc(arena, sizeof(*state));
- if (state == NULL) {
- goto failed;
- }
- state->arena = arena;
-
- 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:
- err = errno;
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_TRUE);
- }
- errno = err;
- return -1;
-}
-
static void
cb_stream_result(int rc, void *callback_data)
{
@@ -231,7 +113,7 @@ cb_stream_referral(char *referral, void *callback_data)
}
static void
-handle_stream_client(struct state *state, int client)
+handle_stream_client(struct plugin_state *state, int client)
{
Slapi_PBlock *pblock;
int i;
@@ -262,7 +144,7 @@ handle_stream_client(struct state *state, int client)
}
static void
-handle_dgram_client(struct state *state, int sockfd,
+handle_dgram_client(struct plugin_state *state, int sockfd,
char *dgram, int dgram_size,
struct sockaddr *client_addr, socklen_t client_addrlen)
{
@@ -375,7 +257,7 @@ handle_dgram_client(struct state *state, int sockfd,
"domain(%s)? ", p);
reply.rm_reply.rp_stat = MSG_ACCEPTED;
reply.rm_reply.rp_acpt.ar_stat = SUCCESS;
- bool_ret = strcmp(p, ".local") == 0;
+ 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) &&
@@ -580,7 +462,7 @@ handle_dgram_client(struct state *state, int sockfd,
}
static void
-handle_stream_client_new(struct state *state, int client)
+handle_stream_client_new(struct plugin_state *state, int client)
{
int i, last, ret;
int32_t len;
@@ -623,7 +505,7 @@ handle_stream_client_new(struct state *state, int client)
static void *
process_requests(void *p)
{
- struct state *state = p;
+ struct plugin_state *state = p;
struct pollfd fds[4];
int client, i;
char dgram[65536];
@@ -631,18 +513,18 @@ process_requests(void *p)
socklen_t client_addrlen;
for (;;) {
memset(&fds, 0, sizeof(fds));
- for (i = 0; i < state->listeners; i++) {
+ for (i = 0; i < state->n_listeners; i++) {
fds[i].fd = state->listenfd[i];
fds[i].events = POLLIN;
}
- switch (poll(fds, state->listeners, -1) != -1) {
+ switch (poll(fds, state->n_listeners, -1) != -1) {
case -1:
return NULL;
break;
case 0:
continue;
default:
- for (i = 0; i < state->listeners; i++) {
+ for (i = 0; i < state->n_listeners; i++) {
if ((fds[i].revents & POLLIN) == 0) {
continue;
}
@@ -683,14 +565,24 @@ process_requests(void *p)
return state;
}
-/* Set up the plugin. */
+/* Start the plugin's work thread. */
static int
plugin_start(Slapi_PBlock *pb)
{
- struct state *state;
+ struct plugin_state *state;
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
slapi_log_error(SLAPI_LOG_PLUGIN, "plugin_start",
"plugin starting\n");
+ if (portmap_register(state->resvport, YPPROG, YPVERS,
+ IPPROTO_TCP, PORT)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
+ "error registering with portmap\n");
+ }
+ if (portmap_register(state->resvport, YPPROG, YPVERS,
+ IPPROTO_UDP, PORT)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
+ "error registering with portmap\n");
+ }
if (pthread_create(&state->tid, NULL, &process_requests, state) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
"error starting listener thread\n");
@@ -700,23 +592,139 @@ plugin_start(Slapi_PBlock *pb)
"plugin started\n");
return 0;
}
-/* Prepare for shutdown. */
+
+/* Stop the plugin's work thread. */
static int
plugin_close(Slapi_PBlock *pb)
{
- if (pmap_unset(YPPROG, YPVERS) != 1) {
- slapi_log_error(SLAPI_LOG_PLUGIN, "plugin_start",
- "error unregistering ports, continuing\n");
+ struct plugin_state *state;
+ slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
+ portmap_unregister(state->resvport, YPPROG, YPVERS);
+ return 0;
+}
+
+static int
+setup_listeners(struct plugin_state **lstate)
+{
+ int sockfd = -1, err, i;
+ struct sockaddr_in addr4;
+ struct sockaddr_in6 addr6;
+ struct plugin_state *state;
+ PLArenaPool *arena = NULL;
+
+ arena = PORT_NewArena(sizeof(double));
+ if (arena == NULL) {
+ goto failed;
}
- slapi_log_error(SLAPI_LOG_PLUGIN, "my_init_function",
- "plugin closing\n");
+ state = PORT_ArenaZAlloc(arena, sizeof(*state));
+ if (state == NULL) {
+ goto failed;
+ }
+ state->arena = arena;
+ state->resvport = -1;
+
+ for (i = 0; i < 4; i++) {
+ int sock_pf, sock_type, one = 1;
+ struct sockaddr *addr;
+ socklen_t addrlen;
+ const char *sock_desc;
+ switch (i) {
+ case 0:
+ sock_pf = PF_INET;
+ sock_type = SOCK_DGRAM;
+ addr = (struct sockaddr *) &addr4;
+ addrlen = sizeof(addr4);
+ sock_desc = "udp";
+ break;
+ case 1:
+ sock_pf = PF_INET;
+ sock_type = SOCK_STREAM;
+ addr = (struct sockaddr *) &addr4;
+ addrlen = sizeof(addr4);
+ sock_desc = "tcp";
+ break;
+ case 2:
+ sock_pf = PF_INET6;
+ sock_type = SOCK_DGRAM;
+ addr = (struct sockaddr *) &addr6;
+ addrlen = sizeof(addr6);
+ sock_desc = "udp6";
+ break;
+ case 3:
+ sock_pf = PF_INET6;
+ sock_type = SOCK_STREAM;
+ addr = (struct sockaddr *) &addr6;
+ addrlen = sizeof(addr6);
+ sock_desc = "tcp6";
+ 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 %s socket\n",
+ sock_desc);
+ continue;
+ }
+ if (setsockopt(sockfd, IPPROTO_IP, SO_REUSEADDR,
+ &one, sizeof(one)) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "error marking %s socket for reuse\n",
+ sock_desc);
+ }
+ if (bind(sockfd, addr, addrlen) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "error binding %s socket to port\n",
+ sock_desc);
+ close(sockfd);
+ continue;
+ }
+ if ((sock_type == SOCK_STREAM) && (listen(sockfd, 128) == -1)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "error marking %s socket for "
+ "listening\n", sock_desc);
+ close(sockfd);
+ continue;
+ }
+ if (i == 0) {
+ state->resvport = sockfd;
+ }
+ state->listenfd[state->n_listeners] = sockfd;
+ state->sock_pf[state->n_listeners] = sock_pf;
+ state->sock_type[state->n_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->n_listeners++;
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "set up %d listening sockets\n", state->n_listeners);
+ *lstate = state;
return 0;
+failed:
+ err = errno;
+ if (arena != NULL) {
+ PORT_FreeArena(arena, PR_TRUE);
+ }
+ errno = err;
+ return -1;
}
int
-my_init_function(Slapi_PBlock *pb)
+nis_plugin_init(Slapi_PBlock *pb)
{
- struct state *state;
+ struct plugin_state *state = NULL;
if (setup_listeners(&state) == -1) {
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
"error setting up listening sockets\n");
@@ -728,19 +736,7 @@ 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");
- }
- if (pmap_set(YPPROG, YPVERS, IPPROTO_UDP, PORT) != 1) {
- slapi_log_error(SLAPI_LOG_PLUGIN, "plugin_start",
- "error registering UDP port, continuing\n");
- }
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
- "registering plugin hooks\n");
+ "registered plugin hooks\n");
return 0;
}