diff options
Diffstat (limited to 'crypto/heimdal/lib/kadm5/log.c')
-rw-r--r-- | crypto/heimdal/lib/kadm5/log.c | 211 |
1 files changed, 143 insertions, 68 deletions
diff --git a/crypto/heimdal/lib/kadm5/log.c b/crypto/heimdal/lib/kadm5/log.c index 5c4aaefe707c..05b84b1e07cc 100644 --- a/crypto/heimdal/lib/kadm5/log.c +++ b/crypto/heimdal/lib/kadm5/log.c @@ -1,40 +1,40 @@ /* - * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include "kadm5_locl.h" #include "heim_threads.h" -RCSID("$Id: log.c 22211 2007-12-07 19:27:27Z lha $"); +RCSID("$Id$"); /* * A log record consists of: @@ -99,13 +99,15 @@ kadm5_log_init (kadm5_server_context *context) return 0; fd = open (log_context->log_file, O_RDWR | O_CREAT, 0600); if (fd < 0) { - krb5_set_error_string(context->context, "kadm5_log_init: open %s", + ret = errno; + krb5_set_error_message(context->context, ret, "kadm5_log_init: open %s", log_context->log_file); - return errno; + return ret; } if (flock (fd, LOCK_EX) < 0) { - krb5_set_error_string(context->context, "kadm5_log_init: flock %s", - log_context->log_file); + ret = errno; + krb5_set_error_message(context->context, ret, "kadm5_log_init: flock %s", + log_context->log_file); close (fd); return errno; } @@ -191,12 +193,12 @@ kadm5_log_flush (kadm5_log_context *log_context, { krb5_data data; size_t len; - int ret; + ssize_t ret; krb5_storage_to_data(sp, &data); len = data.length; ret = write (log_context->log_fd, data.data, len); - if (ret != len) { + if (ret < 0 || (size_t)ret != len) { krb5_data_free(&data); return errno; } @@ -204,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; @@ -279,15 +291,15 @@ kadm5_log_replay_create (kadm5_server_context *context, ret = krb5_data_alloc (&data, len); if (ret) { - krb5_set_error_string(context->context, "out of memory"); + krb5_set_error_message(context->context, ret, "out of memory"); return ret; } krb5_storage_read (sp, data.data, len); ret = hdb_value2entry (context->context, &data, &ent.entry); krb5_data_free(&data); if (ret) { - krb5_set_error_string(context->context, - "Unmarshaling hdb entry failed"); + krb5_set_error_message(context->context, ret, + "Unmarshaling hdb entry failed"); return ret; } ret = context->db->hdb_store(context->context, context->db, 0, &ent); @@ -358,8 +370,8 @@ kadm5_log_replay_delete (kadm5_server_context *context, ret = krb5_ret_principal (sp, &principal); if (ret) { - krb5_set_error_string(context->context, "Failed to read deleted " - "principal from log version: %ld", (long)ver); + krb5_set_error_message(context->context, ret, "Failed to read deleted " + "principal from log version: %ld", (long)ver); return ret; } @@ -456,8 +468,8 @@ kadm5_log_replay_rename (kadm5_server_context *context, off = krb5_storage_seek(sp, 0, SEEK_CUR); ret = krb5_ret_principal (sp, &source); if (ret) { - krb5_set_error_string(context->context, "Failed to read renamed " - "principal in log, version: %ld", (long)ver); + krb5_set_error_message(context->context, ret, "Failed to read renamed " + "principal in log, version: %ld", (long)ver); return ret; } princ_len = krb5_storage_seek(sp, 0, SEEK_CUR) - off; @@ -474,7 +486,7 @@ kadm5_log_replay_rename (kadm5_server_context *context, krb5_free_principal (context->context, source); return ret; } - ret = context->db->hdb_store (context->context, context->db, + ret = context->db->hdb_store (context->context, context->db, 0, &target_ent); hdb_free_entry (context->context, &target_ent); if (ret) { @@ -561,7 +573,7 @@ kadm5_log_replay_modify (kadm5_server_context *context, len -= 4; ret = krb5_data_alloc (&value, len); if (ret) { - krb5_set_error_string(context->context, "out of memory"); + krb5_set_error_message(context->context, ret, "out of memory"); return ret; } krb5_storage_read (sp, value.data, len); @@ -571,9 +583,9 @@ kadm5_log_replay_modify (kadm5_server_context *context, return ret; memset(&ent, 0, sizeof(ent)); - ret = context->db->hdb_fetch(context->context, context->db, - log_ent.entry.principal, - HDB_F_DECRYPT|HDB_F_GET_ANY, &ent); + ret = context->db->hdb_fetch_kvno(context->context, context->db, + log_ent.entry.principal, + HDB_F_DECRYPT|HDB_F_GET_ANY|HDB_F_ADMIN_DATA, 0, &ent); if (ret) goto out; if (mask & KADM5_PRINC_EXPIRE_TIME) { @@ -583,8 +595,8 @@ kadm5_log_replay_modify (kadm5_server_context *context, if (ent.entry.valid_end == NULL) { ent.entry.valid_end = malloc(sizeof(*ent.entry.valid_end)); if (ent.entry.valid_end == NULL) { - krb5_set_error_string(context->context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context->context, ret, "out of memory"); goto out; } } @@ -598,8 +610,8 @@ kadm5_log_replay_modify (kadm5_server_context *context, if (ent.entry.pw_end == NULL) { ent.entry.pw_end = malloc(sizeof(*ent.entry.pw_end)); if (ent.entry.pw_end == NULL) { - krb5_set_error_string(context->context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context->context, ret, "out of memory"); goto out; } } @@ -619,8 +631,8 @@ kadm5_log_replay_modify (kadm5_server_context *context, if (ent.entry.max_life == NULL) { ent.entry.max_life = malloc (sizeof(*ent.entry.max_life)); if (ent.entry.max_life == NULL) { - krb5_set_error_string(context->context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context->context, ret, "out of memory"); goto out; } } @@ -631,15 +643,15 @@ kadm5_log_replay_modify (kadm5_server_context *context, if (ent.entry.modified_by == NULL) { ent.entry.modified_by = malloc(sizeof(*ent.entry.modified_by)); if (ent.entry.modified_by == NULL) { - krb5_set_error_string(context->context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context->context, ret, "out of memory"); goto out; } } else free_Event(ent.entry.modified_by); ret = copy_Event(log_ent.entry.modified_by, ent.entry.modified_by); if (ret) { - krb5_set_error_string(context->context, "out of memory"); + krb5_set_error_message(context->context, ret, "out of memory"); goto out; } } @@ -665,8 +677,8 @@ kadm5_log_replay_modify (kadm5_server_context *context, if (ent.entry.max_renew == NULL) { ent.entry.max_renew = malloc (sizeof(*ent.entry.max_renew)); if (ent.entry.max_renew == NULL) { - krb5_set_error_string(context->context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context->context, ret, "out of memory"); goto out; } } @@ -684,7 +696,7 @@ kadm5_log_replay_modify (kadm5_server_context *context, } if (mask & KADM5_KEY_DATA) { size_t num; - int i; + size_t i; for (i = 0; i < ent.entry.keys.len; ++i) free_Key(&ent.entry.keys.val[i]); @@ -695,14 +707,14 @@ kadm5_log_replay_modify (kadm5_server_context *context, ent.entry.keys.len = num; ent.entry.keys.val = malloc(len * sizeof(*ent.entry.keys.val)); if (ent.entry.keys.val == NULL) { - krb5_set_error_string(context->context, "out of memory"); + krb5_set_error_message(context->context, ENOMEM, "out of memory"); return ENOMEM; } for (i = 0; i < ent.entry.keys.len; ++i) { ret = copy_Key(&log_ent.entry.keys.val[i], &ent.entry.keys.val[i]); if (ret) { - krb5_set_error_string(context->context, "out of memory"); + krb5_set_error_message(context->context, ret, "out of memory"); goto out; } } @@ -717,7 +729,7 @@ kadm5_log_replay_modify (kadm5_server_context *context, ret = copy_HDB_extensions(log_ent.entry.extensions, ent.entry.extensions); if (ret) { - krb5_set_error_string(context->context, "out of memory"); + krb5_set_error_message(context->context, ret, "out of memory"); free(ent.entry.extensions); ent.entry.extensions = es; goto out; @@ -727,7 +739,7 @@ kadm5_log_replay_modify (kadm5_server_context *context, free(es); } } - ret = context->db->hdb_store(context->context, context->db, + ret = context->db->hdb_store(context->context, context->db, HDB_F_REPLACE, &ent); out: hdb_free_entry (context->context, &ent); @@ -834,9 +846,9 @@ kadm5_log_goto_end (int fd) /* * Return previous log entry. - * - * The pointer in `sp´ is assumed to be at the top of the entry before - * previous entry. On success, the `sp´ pointer is set to data portion + * + * The pointer in `sp´ is assumed to be at the top of the entry before + * previous entry. On success, the `sp´ pointer is set to data portion * of previous entry. In case of error, it's not changed at all. */ @@ -860,16 +872,22 @@ kadm5_log_previous (krb5_context context, goto end_of_storage; *len = tmp; ret = krb5_ret_int32 (sp, &tmp); + if (ret) + goto end_of_storage; *ver = tmp; off = 24 + *len; krb5_storage_seek(sp, -off, SEEK_CUR); ret = krb5_ret_int32 (sp, &tmp); if (ret) goto end_of_storage; - if (tmp != *ver) { + if ((uint32_t)tmp != *ver) { krb5_storage_seek(sp, oldoff, SEEK_SET); - krb5_set_error_string(context, "kadm5_log_previous: log entry " - "have consistency failure, version number wrong"); + krb5_set_error_message(context, KADM5_BAD_DB, + "kadm5_log_previous: log entry " + "have consistency failure, version number wrong " + "(tmp %lu ver %lu)", + (unsigned long)tmp, + (unsigned long)*ver); return KADM5_BAD_DB; } ret = krb5_ret_int32 (sp, &tmp); @@ -877,22 +895,25 @@ kadm5_log_previous (krb5_context context, goto end_of_storage; *timestamp = tmp; ret = krb5_ret_int32 (sp, &tmp); + if (ret) + goto end_of_storage; *op = tmp; ret = krb5_ret_int32 (sp, &tmp); if (ret) goto end_of_storage; - if (tmp != *len) { + if ((uint32_t)tmp != *len) { krb5_storage_seek(sp, oldoff, SEEK_SET); - krb5_set_error_string(context, "kadm5_log_previous: log entry " - "have consistency failure, length wrong"); + krb5_set_error_message(context, KADM5_BAD_DB, + "kadm5_log_previous: log entry " + "have consistency failure, length wrong"); return KADM5_BAD_DB; } return 0; end_of_storage: krb5_storage_seek(sp, oldoff, SEEK_SET); - krb5_set_error_string(context, "kadm5_log_previous: end of storage " - "reached before end"); + krb5_set_error_message(context, ret, "kadm5_log_previous: end of storage " + "reached before end"); return ret; } @@ -919,8 +940,8 @@ kadm5_log_replay (kadm5_server_context *context, case kadm_nop : return kadm5_log_replay_nop (context, ver, len, sp); default : - krb5_set_error_string(context->context, - "Unsupported replay op %d", (int)op); + krb5_set_error_message(context->context, KADM5_FAILURE, + "Unsupported replay op %d", (int)op); return KADM5_FAILURE; } } @@ -962,6 +983,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; @@ -980,3 +1003,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 |