diff options
author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2009-02-12 18:20:27 -0500 |
---|---|---|
committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2009-02-12 18:20:27 -0500 |
commit | d3891722e10fd0689577833b2d5e394a8fa78e1b (patch) | |
tree | 66833f485fe20187a96687ccdc9f94f04eae9d1d /src/plug-nis.c | |
parent | cf84389cd2d9063467d8c5fa0b66b9487d59020c (diff) | |
download | slapi-nis-d3891722e10fd0689577833b2d5e394a8fa78e1b.tar.gz slapi-nis-d3891722e10fd0689577833b2d5e394a8fa78e1b.tar.xz slapi-nis-d3891722e10fd0689577833b2d5e394a8fa78e1b.zip |
- handle argument order and count changing for portmap registration functions
- pass IPPROTO_XXX instead of SOCK_XXX to registration function
- if we're registering/unregistering IPv6, also register/unregister IPv4
Diffstat (limited to 'src/plug-nis.c')
-rw-r--r-- | src/plug-nis.c | 181 |
1 files changed, 66 insertions, 115 deletions
diff --git a/src/plug-nis.c b/src/plug-nis.c index 8e0b203..1305cf9 100644 --- a/src/plug-nis.c +++ b/src/plug-nis.c @@ -94,18 +94,25 @@ plugin_startup(Slapi_PBlock *pb) } /* Register the listener sockets with the portmapper. */ if (state->pmap_client_socket != -1) { - /* Kick off any other NIS servers on the local box. */ + /* Try to kick off any other NIS servers on the local box. */ portmap_unregister(plugin_description.spd_id, state->pmap_client_socket, - YPPROG, YPVERS, AF_INET, IPPROTO_TCP); + YPPROG, YPVERS, + AF_INET6, IPPROTO_TCP, 0); portmap_unregister(plugin_description.spd_id, state->pmap_client_socket, - YPPROG, YPVERS, AF_INET, IPPROTO_UDP); + YPPROG, YPVERS, + AF_INET6, IPPROTO_UDP, 0); + portmap_unregister(plugin_description.spd_id, + state->pmap_client_socket, + YPPROG, YPVERS, + AF_INET, IPPROTO_TCP, 0); + portmap_unregister(plugin_description.spd_id, + state->pmap_client_socket, + YPPROG, YPVERS, + AF_INET, IPPROTO_UDP, 0); /* Register our listening ports. */ for (i = 0; i < state->n_listeners; i++) { - if (state->listener[i].pf != PF_INET) { - continue; - } switch (state->listener[i].type) { case SOCK_DGRAM: protocol = IPPROTO_UDP; @@ -120,13 +127,11 @@ plugin_startup(Slapi_PBlock *pb) assert(0); break; } - if (protocol == IPPROTO_IP) { - continue; - } if (!portmap_register(plugin_description.spd_id, state->pmap_client_socket, YPPROG, YPVERS, - AF_INET, protocol, + state->listener[i].pf, + protocol, state->listener[i].port)) { slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id, @@ -137,6 +142,17 @@ plugin_startup(Slapi_PBlock *pb) plugin_description.spd_id, "registered %s service " "with portmap\n", pname); + /* If it's an IPv6 service, then it can also + * accept connections from IPv4 clients, so + * register for them, too. */ + if (state->listener[i].pf == AF_INET6) { + portmap_register(plugin_description.spd_id, + state->pmap_client_socket, + YPPROG, YPVERS, + AF_INET, + protocol, + state->listener[i].port); + } } } } @@ -150,22 +166,41 @@ static int plugin_shutdown(Slapi_PBlock *pb) { struct plugin_state *state; - int i; + int i, protocol; slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); for (i = 0; i < state->n_listeners; i++) { + if (state->pmap_client_socket != -1) { + switch (state->listener[i].type) { + case SOCK_DGRAM: + protocol = IPPROTO_UDP; + break; + case SOCK_STREAM: + protocol = IPPROTO_TCP; + break; + default: + /* never reached */ + assert(0); + break; + } + portmap_unregister(plugin_description.spd_id, + state->pmap_client_socket, + YPPROG, YPVERS, + state->listener[i].pf, + protocol, + state->listener[i].port); + if (state->listener[i].pf == AF_INET6) { + portmap_unregister(plugin_description.spd_id, + state->pmap_client_socket, + YPPROG, YPVERS, + AF_INET, + protocol, + state->listener[i].port); + } + } close(state->listener[i].fd); state->listener[i].fd = -1; } state->n_listeners = 0; - if (state->pmap_client_socket != -1) { - /* Clear our registration with the portmapper. */ - portmap_unregister(plugin_description.spd_id, - state->pmap_client_socket, - YPPROG, YPVERS, AF_INET, IPPROTO_TCP); - portmap_unregister(plugin_description.spd_id, - state->pmap_client_socket, - YPPROG, YPVERS, AF_INET, IPPROTO_UDP); - } wrap_stop_thread(state->tid); map_done(state); #ifdef HAVE_TCPD_H @@ -202,53 +237,6 @@ plugin_read_config(Slapi_PBlock *plugin_pb, int *port) } } -/* Bind to a privileged port. We don't much care which one at this point. */ -static int -plugin_bind_resvport(int fd, int family, int but_not) -{ - int i, offset, port; - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - switch (family) { - case AF_INET: - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - break; - case AF_INET6: - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_family = AF_INET6; - break; - default: - return -1; - } - offset = getpid() % 512; - for (i = 512; i < 1024; i++) { - port = ((offset + i) % 512) + 512; - if (port == but_not) { - continue; - } - switch (family) { - case AF_INET: - sin.sin_port = htons(port); - if (bind(fd, (struct sockaddr*) &sin, - sizeof(sin)) == 0) { - return port; - } - break; - case AF_INET6: - sin6.sin6_port = htons(port); - if (bind(fd, (struct sockaddr*) &sin6, - sizeof(sin6)) == 0) { - return port; - } - break; - default: - return -1; - } - } - return 0; -} - /* Handle the part of startup that needs to be done before we drop privileges: * bind to listening ports and one more for talking to the local portmapper. */ static int @@ -296,55 +284,18 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) #endif /* Create a socket for use in communicating with the portmapper. */ -#ifdef HAVE_LIBTIRPC - sockfd = socket(PF_LOCAL, SOCK_STREAM, 0); - if (sockfd == -1) { - slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id, - "error allocating portmap client socket\n"); - goto failed; - } - memset(&sockun, 0, sizeof(sockun)); - sockun.sun_family = AF_LOCAL; - strcpy(sockun.sun_path, _PATH_RPCBINDSOCK); - if (connect(sockfd, (struct sockaddr *) &sockun, sizeof(sockun)) != 0) { - if ((getenv(NIS_PLUGIN_CONTINUE_WITHOUT_PORTMAP_ENV) == NULL) || - !atol(getenv(NIS_PLUGIN_CONTINUE_WITHOUT_PORTMAP_ENV))) { - slapi_log_error(SLAPI_LOG_FATAL, - state->plugin_desc->spd_id, - "error connecting rpcbind client " - "socket to the service\n"); - close(sockfd); - sockfd = -1; - goto failed; - } - } -#else - sockfd = socket(PF_INET, SOCK_DGRAM, 0); + sockfd = portmap_create_client_socket(state->plugin_desc->spd_id, + port); if (sockfd == -1) { - slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id, - "error allocating portmap client socket\n"); - goto failed; - } - if (plugin_bind_resvport(sockfd, AF_INET, port) <= 0) { if ((getenv(NIS_PLUGIN_CONTINUE_WITHOUT_PORTMAP_ENV) == NULL) || !atol(getenv(NIS_PLUGIN_CONTINUE_WITHOUT_PORTMAP_ENV))) { slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id, - "error binding portmap client socket " - "to a privileged port\n"); - close(sockfd); - sockfd = -1; + "error creating portmap/rpcbind client " + "socket\n"); goto failed; - } else { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "warning: unable to bind portmap " - "client socket to a privileged port\n"); } - close(sockfd); - sockfd = -1; } -#endif state->pmap_client_socket = sockfd; /* We need to bind on privileged ports for both datagram and connected @@ -356,7 +307,7 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) /* Figure out what kind of socket we need, and a textual * term to use in log messages. */ pf = (i & 2) ? PF_INET : PF_INET6; - type = (i & 1) ? SOCK_STREAM : SOCK_DGRAM; + type = (i & 1) ? SOCK_DGRAM : SOCK_STREAM; sock_desc = (i & 2) ? ((i & 1) ? "tcp" : "udp") : ((i & 1) ? "tcp6" : "udp6"); /* Allocate the socket. */ @@ -386,12 +337,12 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) sin.sin_family = AF_INET; sin6.sin6_family = AF_INET6; if (port == 0) { - port = (pf == PF_INET6) ? plugin_bind_resvport(sockfd, - AF_INET6, - 0) : - plugin_bind_resvport(sockfd, - AF_INET, - 0); + port = (pf == PF_INET6) ? portmap_bind_resvport(sockfd, + AF_INET6, + 0) : + portmap_bind_resvport(sockfd, + AF_INET, + 0); ret = (port > 0) ? 0 : -1; } else { sin.sin_port = htons(port); |