summaryrefslogtreecommitdiffstats
path: root/src/plugin.c
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2007-11-21 17:07:14 -0500
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2007-11-21 17:07:14 -0500
commita9346c57a05ae989ba6471ac4561643327fbf2dc (patch)
treee31247dfeae515c74a5ee98abb6644526e9879fe /src/plugin.c
parentfea069c89092d2854f3c7dc192f47a5960fa879b (diff)
downloadslapi-nis-a9346c57a05ae989ba6471ac4561643327fbf2dc.tar.gz
slapi-nis-a9346c57a05ae989ba6471ac4561643327fbf2dc.tar.xz
slapi-nis-a9346c57a05ae989ba6471ac4561643327fbf2dc.zip
- bind to privileged ports using bindresvport() and not a hard-coded value
- get portmapper registration/deregistration working
Diffstat (limited to 'src/plugin.c')
-rw-r--r--src/plugin.c99
1 files changed, 68 insertions, 31 deletions
diff --git a/src/plugin.c b/src/plugin.c
index 333dbee..e8b0e70 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -44,6 +44,7 @@ struct plugin_state {
int resvport;
int n_listeners;
int listenfd[4];
+ int listenport[4];
int sock_pf[4];
int sock_type[4];
};
@@ -570,21 +571,43 @@ static int
plugin_start(Slapi_PBlock *pb)
{
struct plugin_state *state;
+ const char *pname;
+ int i, protocol;
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 (state->resvport != -1) {
+ for (i = 0; i < state->n_listeners; i++) {
+ switch (state->sock_type[i]) {
+ case SOCK_DGRAM:
+ protocol = IPPROTO_UDP;
+ pname = "UDP";
+ break;
+ case SOCK_STREAM:
+ protocol = IPPROTO_TCP;
+ pname = "TCP";
+ break;
+ default:
+ protocol = IPPROTO_IP;
+ pname = "IP";
+ break;
+ }
+ if (protocol == IPPROTO_IP) {
+ continue;
+ }
+ if (!portmap_register(state->resvport,
+ YPPROG, YPVERS, protocol,
+ state->listenport[i])) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "error registering %s service "
+ "with portmap\n", pname);
+ }
+ }
}
if (pthread_create(&state->tid, NULL, &process_requests, state) != 0) {
- slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
"error starting listener thread\n");
return -1;
}
@@ -599,7 +622,10 @@ plugin_close(Slapi_PBlock *pb)
{
struct plugin_state *state;
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
- portmap_unregister(state->resvport, YPPROG, YPVERS);
+ if (state->resvport != -1) {
+ portmap_unregister(state->resvport, YPPROG, YPVERS);
+ close(state->resvport);
+ }
return 0;
}
@@ -607,8 +633,6 @@ 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;
@@ -621,47 +645,57 @@ setup_listeners(struct plugin_state **lstate)
goto failed;
}
state->arena = arena;
- state->resvport = -1;
+
+ state->resvport = socket(PF_INET, SOCK_DGRAM, 0);
+ if (bindresvport(state->resvport, NULL) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ plugin_description.spd_id,
+ "error setting up portmap client socket, %d\n",
+ (int)getuid());
+ close(state->resvport);
+ state->resvport = -1;
+ }
for (i = 0; i < 4; i++) {
int sock_pf, sock_type, one = 1;
struct sockaddr *addr;
socklen_t addrlen;
+ struct sockaddr_storage ss;
+ struct sockaddr_in *addr4 = (struct sockaddr_in *) &ss;
+ struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &ss;
const char *sock_desc;
+ u_int16_t *port;
+ memset(&ss, 0, sizeof(ss));
switch (i) {
case 0:
sock_pf = PF_INET;
sock_type = SOCK_DGRAM;
- addr = (struct sockaddr *) &addr4;
- addrlen = sizeof(addr4);
sock_desc = "udp";
+ addr4->sin_family = AF_INET;
+ port = &addr4->sin_port;
break;
case 1:
sock_pf = PF_INET;
sock_type = SOCK_STREAM;
- addr = (struct sockaddr *) &addr4;
- addrlen = sizeof(addr4);
sock_desc = "tcp";
+ addr4->sin_family = AF_INET;
+ port = &addr4->sin_port;
break;
case 2:
sock_pf = PF_INET6;
sock_type = SOCK_DGRAM;
- addr = (struct sockaddr *) &addr6;
- addrlen = sizeof(addr6);
sock_desc = "udp6";
+ addr6->sin6_family = AF_INET6;
+ port = &addr6->sin6_port;
break;
case 3:
sock_pf = PF_INET6;
sock_type = SOCK_STREAM;
- addr = (struct sockaddr *) &addr6;
- addrlen = sizeof(addr6);
sock_desc = "tcp6";
+ addr6->sin6_family = AF_INET6;
+ port = &addr6->sin6_port;
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,
@@ -677,11 +711,12 @@ setup_listeners(struct plugin_state **lstate)
"error marking %s socket for reuse\n",
sock_desc);
}
- if (bind(sockfd, addr, addrlen) != 0) {
+ if (bindresvport(sockfd, (struct sockaddr_in *) &ss) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN,
plugin_description.spd_id,
- "error binding %s socket to port\n",
- sock_desc);
+ "error binding %s socket to a "
+ "privileged port: %s\n",
+ sock_desc, strerror(errno));
close(sockfd);
continue;
}
@@ -689,7 +724,8 @@ setup_listeners(struct plugin_state **lstate)
slapi_log_error(SLAPI_LOG_PLUGIN,
plugin_description.spd_id,
"error marking %s socket for "
- "listening\n", sock_desc);
+ "listening: %s\n", sock_desc,
+ strerror(errno));
close(sockfd);
continue;
}
@@ -697,12 +733,13 @@ setup_listeners(struct plugin_state **lstate)
state->resvport = sockfd;
}
state->listenfd[state->n_listeners] = sockfd;
+ state->listenport[state->n_listeners] = ntohs(*port);
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,
+ state->listenport[state->n_listeners],
sock_type == SOCK_STREAM ? "tcp" : "udp",
sock_pf == PF_INET6 ? "6" : "");
state->n_listeners++;