From 79b3d1ff2c81a750791385dbfaaa76d458027f95 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Thu, 10 Jul 2008 14:28:58 -0400 Subject: - log fatal startup errors at level fatal, not plugin - treat inability to bind to the tcp socket as fatal - close listening and portmap-client sockets at shutdown-time --- src/plug-nis.c | 105 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 84 insertions(+), 21 deletions(-) diff --git a/src/plug-nis.c b/src/plug-nis.c index 2e897a9..c088c81 100644 --- a/src/plug-nis.c +++ b/src/plug-nis.c @@ -135,7 +135,12 @@ static int plugin_shutdown(Slapi_PBlock *pb) { struct plugin_state *state; + int i; slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); + for (i = 0; i < state->n_listeners; i++) { + close(state->listener[i].fd); + } + state->n_listeners = 0; if (state->pmap_client_socket != -1) { /* Clear our registration with the portmapper. */ portmap_unregister(plugin_description.spd_id, @@ -182,7 +187,7 @@ plugin_read_config(Slapi_PBlock *plugin_pb, int *port) static int plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) { - int port, sockfd = -1, err, i; + int port, sockfd = -1, err, i, flags; struct plugin_state *state = NULL; struct sockaddr_in sin; struct sockaddr_in6 sin6; @@ -196,6 +201,7 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) state->plugin_desc = &plugin_description; state->max_value_size = DEFAULT_MAX_VALUE_SIZE; state->max_dgram_size = DEFAULT_MAX_DGRAM_SIZE; + state->pmap_client_socket = -1; slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &state->plugin_identity); slapi_pblock_get(pb, SLAPI_TARGET_DN, &state->plugin_base); slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, @@ -212,10 +218,10 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) (request_set(state->request_info, RQ_DAEMON, DEFAULT_TCPWRAP_NAME, 0) != state->request_info)) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id, "error initializing tcp_wrappers for \"%s\"\n", plugin_description.spd_id); - return -1; + goto failed; } #else state->request_info = NULL; @@ -224,20 +230,26 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) /* Create a socket for use in communicating with the portmapper. */ sockfd = socket(PF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id, "error allocating portmap client socket\n"); goto failed; } memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; if (bindresvport(sockfd, &sin) != 0) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "error binding portmap client socket to a " - "privileged port\n"); 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); 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; @@ -247,8 +259,8 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) /* We need to bind on privileged ports for both datagram and connected * listeners, over both IPv4 and IPv6. */ state->n_listeners = 0; - for (i = 0; i < 2; i++) { - int pf, type, one, flags, ret; + for (i = 0; i < 4; i++) { + int pf, type, one, ret; const char *sock_desc; /* Figure out what kind of socket we need, and a textual * term to use in log messages. */ @@ -273,10 +285,8 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) plugin_description.spd_id, "error marking %s socket for reuse, " "continuing\n", sock_desc); - } - flags = fcntl(sockfd, F_GETFL); - if ((flags & O_NONBLOCK) == 0) { - fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); + close(sockfd); + goto failed; } /* Bind to the server port, if one was specified, otherwise let * libc try to find an unused one for us. */ @@ -300,13 +310,59 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) sizeof(sin)); } if (ret != 0) { - slapi_log_error(SLAPI_LOG_PLUGIN, - plugin_description.spd_id, - "error binding %s socket to port " - "for incoming NIS requests: %s\n", - sock_desc, strerror(errno)); + char port_desc[16]; + if (port) { + sprintf(port_desc, "port %d", port); + } else { + strcpy(port_desc, "privileged port"); + } close(sockfd); - continue; + if (i < 2) { + slapi_log_error(SLAPI_LOG_FATAL, + plugin_description.spd_id, + "error binding %s socket to " + "%s for incoming NIS " + "requests: %s\n", + sock_desc, port_desc, + strerror(errno)); + goto failed; + } else { + slapi_log_error(SLAPI_LOG_PLUGIN, + plugin_description.spd_id, + "error binding %s socket to " + "%s for incoming NIS " + "requests: %s\n", + sock_desc, port_desc, + strerror(errno)); + continue; + } + } else { + /* Try to read back the bound address. */ + socklen_t socklen; + if (getsockname(sockfd, + (pf == PF_INET6) ? + (struct sockaddr*) &sin6 : + (struct sockaddr*) &sin, + &socklen) != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, + plugin_description.spd_id, + "error retrieving local " + "socket address: %s\n", + strerror(errno)); + } + if (socklen != + (pf == PF_INET6) ? sizeof(sin6) : sizeof(sin)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + plugin_description.spd_id, + "error retrieving local " + "socket address: %s\n", + strerror(errno)); + } + + } + flags = fcntl(sockfd, F_GETFL); + if ((flags & O_NONBLOCK) == 0) { + fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); } /* Read the port number that we ended up using, in case we used * bindresvport[6]. */ @@ -316,13 +372,14 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) * ready to accept client connections. */ if (type == SOCK_STREAM) { if (listen(sockfd, 128) == -1) { - slapi_log_error(SLAPI_LOG_PLUGIN, + slapi_log_error(SLAPI_LOG_FATAL, plugin_description.spd_id, "error marking %s socket for " "listening: %s\n", sock_desc, strerror(errno)); + flags = fcntl(sockfd, F_GETFL); close(sockfd); - continue; + goto failed; } } /* Save the other info. */ @@ -343,6 +400,12 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) *lstate = state; return 0; failed: + for (i = 0; i < state->n_listeners; i++) { + close(state->listener[i].fd); + } + if (state->pmap_client_socket != -1) { + close(state->pmap_client_socket); + } err = errno; free(state); errno = err; -- cgit