diff options
| author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2007-11-21 17:07:14 -0500 |
|---|---|---|
| committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2007-11-21 17:07:14 -0500 |
| commit | a9346c57a05ae989ba6471ac4561643327fbf2dc (patch) | |
| tree | e31247dfeae515c74a5ee98abb6644526e9879fe /src/plugin.c | |
| parent | fea069c89092d2854f3c7dc192f47a5960fa879b (diff) | |
| download | slapi-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.c | 99 |
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++; |
