aboutsummaryrefslogtreecommitdiff
path: root/crypto/heimdal/lib/kadm5/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/lib/kadm5/log.c')
-rw-r--r--crypto/heimdal/lib/kadm5/log.c211
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