From d84119813e014d5c27fa05df0c46804957d1b031 Mon Sep 17 00:00:00 2001 From: Asanka Herath Date: Wed, 26 Aug 2009 12:57:15 -0400 Subject: [PATCH] No AF_UNIX on Windows and no SIGPIPE and SIGXCPU --- lib/kadm5/context_s.c | 16 ++++++++++ lib/kadm5/destroy_s.c | 8 ++++- lib/kadm5/init_s.c | 10 ++++++ lib/kadm5/ipropd_common.c | 4 +++ lib/kadm5/ipropd_master.c | 56 +++++++++++++++++++++++----------- lib/kadm5/ipropd_slave.c | 5 ++- lib/kadm5/log.c | 64 +++++++++++++++++++++++++++++++++++++++ lib/kadm5/private.h | 6 +++- 8 files changed, 149 insertions(+), 20 deletions(-) diff --git a/lib/kadm5/context_s.c b/lib/kadm5/context_s.c index b9459dd70..811921d96 100644 --- a/lib/kadm5/context_s.c +++ b/lib/kadm5/context_s.c @@ -53,6 +53,8 @@ set_funcs(kadm5_server_context *c) SET(c, rename_principal); } +#ifndef NO_UNIX_SOCKETS + static void set_socket_name(krb5_context context, struct sockaddr_un *un) { @@ -61,7 +63,17 @@ set_socket_name(krb5_context context, struct sockaddr_un *un) memset(un, 0, sizeof(*un)); un->sun_family = AF_UNIX; strlcpy (un->sun_path, fn, sizeof(un->sun_path)); + } +#else + +static void +set_socket_info(krb5_context context, struct addrinfo **info) +{ + kadm5_log_signal_socket_info(context, 0, info); +} + +#endif static kadm5_ret_t find_db_spec(kadm5_server_context *ctx) @@ -115,7 +127,11 @@ find_db_spec(kadm5_server_context *ctx) if (ctx->log_context.log_file == NULL) asprintf(&ctx->log_context.log_file, "%s/log", hdb_db_dir(context)); +#ifndef NO_UNIX_SOCKETS set_socket_name(context, &ctx->log_context.socket_name); +#else + set_socket_info(context, &ctx->log_context.socket_info); +#endif return 0; } diff --git a/lib/kadm5/destroy_s.c b/lib/kadm5/destroy_s.c index 8ddf7d06f..393ffb914 100644 --- a/lib/kadm5/destroy_s.c +++ b/lib/kadm5/destroy_s.c @@ -56,7 +56,13 @@ static void destroy_kadm5_log_context (kadm5_log_context *c) { free (c->log_file); - close (c->socket_fd); + closesocket (c->socket_fd); +#ifndef NO_UNIX_SOCKETS + if (c->socket_info) { + freeaddrinfo(c->socket_info); + c->socket_info = NULL; + } +#endif } /* diff --git a/lib/kadm5/init_s.c b/lib/kadm5/init_s.c index 967f0e9c3..1001fce6d 100644 --- a/lib/kadm5/init_s.c +++ b/lib/kadm5/init_s.c @@ -55,7 +55,11 @@ kadm5_s_init_with_context(krb5_context context, assert(ctx->config.stash_file != NULL); assert(ctx->config.acl_file != NULL); assert(ctx->log_context.log_file != NULL); +#ifndef NO_UNIX_SOCKETS assert(ctx->log_context.socket_name.sun_path[0] != '\0'); +#else + assert(ctx->log_context.socket_info != NULL); +#endif ret = hdb_create(ctx->context, &ctx->db, ctx->config.dbname); if(ret) @@ -67,7 +71,13 @@ kadm5_s_init_with_context(krb5_context context, ctx->log_context.log_fd = -1; +#ifndef NO_UNIX_SOCKETS ctx->log_context.socket_fd = socket (AF_UNIX, SOCK_DGRAM, 0); +#else + ctx->log_context.socket_fd = socket (ctx->log_context.socket_info->ai_family, + ctx->log_context.socket_info->ai_socktype, + ctx->log_context.socket_info->ai_protocol); +#endif ret = krb5_parse_name(ctx->context, client_name, &ctx->caller); if(ret) diff --git a/lib/kadm5/ipropd_common.c b/lib/kadm5/ipropd_common.c index e0df0f87a..2e3d94107 100644 --- a/lib/kadm5/ipropd_common.c +++ b/lib/kadm5/ipropd_common.c @@ -63,7 +63,11 @@ setup_signal(void) #else signal(SIGINT, sigterm); signal(SIGTERM, sigterm); +#ifndef NO_SIGXCPU signal(SIGXCPU, sigterm); +#endif +#ifndef NO_SIGPIPE signal(SIGPIPE, SIG_IGN); #endif +#endif } diff --git a/lib/kadm5/ipropd_master.c b/lib/kadm5/ipropd_master.c index 1e843338a..749040b18 100644 --- a/lib/kadm5/ipropd_master.c +++ b/lib/kadm5/ipropd_master.c @@ -45,12 +45,13 @@ static int time_before_gone; const char *master_hostname; -static int +static SOCKET make_signal_socket (krb5_context context) { +#ifndef NO_UNIX_SOCKETS struct sockaddr_un addr; const char *fn; - int fd; + SOCKET fd; fn = kadm5_log_signal_socket(context); @@ -64,18 +65,32 @@ make_signal_socket (krb5_context context) if (bind (fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) krb5_err (context, 1, errno, "bind %s", addr.sun_path); return fd; +#else + struct addrinfo *ai = NULL; + SOCKET fd; + + kadm5_log_signal_socket_info(context, 1, &ai); + + fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (IS_BAD_SOCKET(fd)) + krb5_err (context, 1, SOCK_ERRNO, "socket AF=%d", ai->ai_family); + + if (IS_SOCKET_ERROR( bind (fd, ai->ai_addr, ai->ai_addrlen) )) + krb5_err (context, 1, SOCK_ERRNO, "bind"); + return fd; +#endif } -static int +static SOCKET make_listen_socket (krb5_context context, const char *port_str) { - int fd; + SOCKET fd; int one = 1; struct sockaddr_in addr; fd = socket (AF_INET, SOCK_STREAM, 0); - if (fd < 0) - krb5_err (context, 1, errno, "socket AF_INET"); + if (IS_BAD_SOCKET(fd)) + krb5_err (context, 1, SOCK_ERRNO, "socket AF_INET"); setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one)); memset (&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; @@ -105,7 +120,7 @@ make_listen_socket (krb5_context context, const char *port_str) } struct slave { - int fd; + SOCKET fd; struct sockaddr_in addr; char *name; krb5_auth_context ac; @@ -180,9 +195,9 @@ slave_dead(krb5_context context, slave *s) { krb5_warnx(context, "slave %s dead", s->name); - if (s->fd >= 0) { - close (s->fd); - s->fd = -1; + if (!IS_BAD_SOCKET(s->fd)) { + closesocket (s->fd); + s->fd = INVALID_SOCKET; } s->flags |= SLAVE_F_DEAD; slave_seen(s); @@ -193,8 +208,8 @@ remove_slave (krb5_context context, slave *s, slave **root) { slave **p; - if (s->fd >= 0) - close (s->fd); + if (!IS_BAD_SOCKET(s->fd)) + closesocket (s->fd); if (s->name) free (s->name); if (s->ac) @@ -209,7 +224,7 @@ remove_slave (krb5_context context, slave *s, slave **root) } static void -add_slave (krb5_context context, krb5_keytab keytab, slave **root, int fd) +add_slave (krb5_context context, krb5_keytab keytab, slave **root, SOCKET fd) { krb5_principal server; krb5_error_code ret; @@ -228,7 +243,7 @@ add_slave (krb5_context context, krb5_keytab keytab, slave **root, int fd) addr_len = sizeof(s->addr); s->fd = accept (fd, (struct sockaddr *)&s->addr, &addr_len); - if (s->fd < 0) { + if (IS_BAD_SOCKET(s->fd)) { krb5_warn (context, errno, "accept"); goto error; } @@ -294,7 +309,7 @@ error: struct prop_context { krb5_auth_context auth_context; - int fd; + SOCKET fd; }; static int @@ -744,7 +759,7 @@ main(int argc, char **argv) void *kadm_handle; kadm5_server_context *server_context; kadm5_config_params conf; - int signal_fd, listen_fd; + SOCKET signal_fd, listen_fd; int log_fd; slave *slaves = NULL; uint32_t current_version = 0, old_version = 0; @@ -880,7 +895,11 @@ main(int argc, char **argv) } if (ret && FD_ISSET(signal_fd, &readset)) { +#ifndef NO_UNIX_SOCKETS struct sockaddr_un peer_addr; +#else + struct sockaddr_storage peer_addr; +#endif socklen_t peer_len = sizeof(peer_addr); if(recvfrom(signal_fd, (void *)&vers, sizeof(vers), 0, @@ -931,8 +950,11 @@ main(int argc, char **argv) write_stats(context, slaves, current_version); } - if(exit_flag == SIGXCPU) + if (0) ; +#ifndef NO_SIGXCPU + else if(exit_flag == SIGXCPU) krb5_warnx(context, "%s CPU time limit exceeded", getprogname()); +#endif else if(exit_flag == SIGINT || exit_flag == SIGTERM) krb5_warnx(context, "%s terminated", getprogname()); else diff --git a/lib/kadm5/ipropd_slave.c b/lib/kadm5/ipropd_slave.c index c6309612a..8a5658c04 100644 --- a/lib/kadm5/ipropd_slave.c +++ b/lib/kadm5/ipropd_slave.c @@ -730,8 +730,11 @@ main(int argc, char **argv) reconnect = reconnect_max; } - if(exit_flag == SIGXCPU) + if (0); +#ifndef NO_SIGXCPU + else if(exit_flag == SIGXCPU) krb5_warnx(context, "%s CPU time limit exceeded", getprogname()); +#endif else if(exit_flag == SIGINT || exit_flag == SIGTERM) krb5_warnx(context, "%s terminated", getprogname()); else diff --git a/lib/kadm5/log.c b/lib/kadm5/log.c index 51d091280..8a307023c 100644 --- a/lib/kadm5/log.c +++ b/lib/kadm5/log.c @@ -206,15 +206,25 @@ kadm5_log_flush (kadm5_log_context *log_context, krb5_data_free(&data); return errno; } + /* * Try to send a signal to any running `ipropd-master' */ +#ifndef NO_UNIX_SOCKETS sendto (log_context->socket_fd, (void *)&log_context->version, sizeof(log_context->version), 0, (struct sockaddr *)&log_context->socket_name, sizeof(log_context->socket_name)); +#else + sendto (log_context->socket_fd, + (void *)&log_context->version, + sizeof(log_context->version), + 0, + log_context->socket_info->ai_addr, + log_context->socket_info->ai_addrlen); +#endif krb5_data_free(&data); return 0; @@ -970,6 +980,8 @@ kadm5_log_truncate (kadm5_server_context *server_context) } +#ifndef NO_UNIX_SOCKETS + static char *default_signal = NULL; static HEIMDAL_MUTEX signal_mutex = HEIMDAL_MUTEX_INITIALIZER; @@ -988,3 +1000,55 @@ kadm5_log_signal_socket(krb5_context context) "signal_socket", NULL); } + +#else /* NO_UNIX_SOCKETS */ + +#define SIGNAL_SOCKET_HOST "127.0.0.1" +#define SIGNAL_SOCKET_PORT "12701" + +kadm5_ret_t +kadm5_log_signal_socket_info(krb5_context context, + int server_end, + struct addrinfo **ret_addrs) +{ + struct addrinfo hints; + struct addrinfo *addrs = NULL; + kadm5_ret_t ret = KADM5_FAILURE; + int wsret; + + memset(&hints, 0, sizeof(hints)); + + hints.ai_flags = AI_NUMERICHOST; + if (server_end) + hints.ai_flags |= AI_PASSIVE; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + wsret = getaddrinfo(SIGNAL_SOCKET_HOST, + SIGNAL_SOCKET_PORT, + &hints, &addrs); + + if (wsret != 0) { + krb5_set_error_message(context, KADM5_FAILURE, + "%s", gai_strerror(wsret)); + goto done; + } + + if (addrs == NULL) { + krb5_set_error_message(context, KADM5_FAILURE, + "getaddrinfo() failed to return address list"); + goto done; + } + + *ret_addrs = addrs; + addrs = NULL; + ret = 0; + + done: + if (addrs) + freeaddrinfo(addrs); + return ret; +} + +#endif diff --git a/lib/kadm5/private.h b/lib/kadm5/private.h index 294694af9..c1fec6feb 100644 --- a/lib/kadm5/private.h +++ b/lib/kadm5/private.h @@ -74,8 +74,12 @@ typedef struct kadm5_log_context { char *log_file; int log_fd; uint32_t version; +#ifndef NO_UNIX_SOCKETS struct sockaddr_un socket_name; - int socket_fd; +#else + struct addrinfo *socket_info; +#endif + SOCKET socket_fd; } kadm5_log_context; typedef struct kadm5_server_context {