summaryrefslogtreecommitdiffstats
path: root/src/plug-nis.c
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-07-10 14:28:58 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-07-10 14:28:58 -0400
commit79b3d1ff2c81a750791385dbfaaa76d458027f95 (patch)
tree2f6dfa87586990cdc1ed1f649d9395bac4b6ffdf /src/plug-nis.c
parent8d0590883c5d966a55f9c03d0696b7ec67dde267 (diff)
downloadslapi-nis-79b3d1ff2c81a750791385dbfaaa76d458027f95.tar.gz
slapi-nis-79b3d1ff2c81a750791385dbfaaa76d458027f95.tar.xz
slapi-nis-79b3d1ff2c81a750791385dbfaaa76d458027f95.zip
- 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
Diffstat (limited to 'src/plug-nis.c')
-rw-r--r--src/plug-nis.c105
1 files 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;