/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <unistd.h>
#include <fcntl.h>
#include <k5-int.h>
#include <stdlib.h>
#include <limits.h>
#include <syslog.h>
#include "kdb_log.h"
/*
* This modules includes all the necessary functions that create and
* modify the Kerberos principal update and header logs.
*/
static int pagesize = 0;
/*
* Sync update entry to disk.
*/
{
return (KRB5_LOG_ERROR);
if (!pagesize)
pagesize = getpagesize();
return (retval);
}
return (0);
}
/*
* Sync memory to disk for the update log header.
*/
void
{
if (!pagesize)
pagesize = getpagesize();
/*
* Couldn't sync to disk, let's panic
*/
abort();
}
}
/*
* Resizes the array elements. We reinitialize the update log rather than
* unrolling the the log and copying it over to a temporary log for obvious
* performance reasons. Slaves will subsequently do a full resync, but
* the need for resizing should be very small.
*/
{
return (KRB5_LOG_ERROR);
new_size = sizeof (kdb_hlog_t);
new_block *= ULOG_BLOCK;
/*
* Reinit log with new block size
*/
/*
* Time to expand log considering new block size
*/
return (errno);
}
return (errno);
}
} else {
/*
* Can't map into file larger than MAXLOGLEN
*/
return (KRB5_LOG_ERROR);
}
return (0);
}
/*
* Adds an entry to the update log.
* The layout of the update log looks like:
*
* header log -> [ update header -> xdr(kdb_incr_update_t) ], ...
*/
{
int ulogfd;
return (KRB5_LOG_ERROR);
/* Resize element array failed */
return (retval);
}
}
/*
* We need to overflow our sno, replicas will do full
* resyncs once they see their sno > than the masters.
*/
cur_sno = 1;
else
cur_sno++;
/*
* We squirrel this away for finish_update() to index
*/
return (KRB5_LOG_CONV);
return (retval);
/*
* Since this is a circular array, once we circled, kdb_first_sno is
* always kdb_entry_sno + 1.
*/
if (cur_sno > ulogentries) {
} else if (cur_sno == 1) {
}
return (0);
}
/*
* Mark the log entry as committed and sync the memory mapped log
* to file.
*/
{
uint_t i;
return (retval);
return (0);
}
/*
* Set the header log details on the slave and sync it to file.
*/
void
{
}
/*
* Delete an entry to the update log.
*/
{
}
/*
* Used by the slave or master (during ulog_check) to update it's hash db from
* the incr update log.
*/
{
int i, no_of_updates;
/*
* We reset last_sno and last_time to 0, if krb5_db_put_principal
* or krb5_db_delete_principal fail.
*/
if (krb5_db_inited(context)) {
if (retval != 0)
goto cleanup;
}
for (i = 0; i < no_of_updates; i++) {
if (!upd->kdb_commit)
continue;
if (upd->kdb_deleted) {
+ 1) * sizeof (char));
if (dbprincstr == NULL) {
goto cleanup;
}
(void) strlcpy(dbprincstr,
&dbprinc)) {
goto cleanup;
}
if (dbprincstr)
if (dbprinc)
if (retval)
goto cleanup;
} else {
if (!entry) {
goto cleanup;
}
goto cleanup;
&nentry);
if (entry) {
}
if (retval)
goto cleanup;
}
upd++;
}
if (fupd)
if (retval)
else
}
return (retval);
}
/*
* Validate the log file and resync any uncommitted update entries
* to the principal database.
*/
{
int i;
/*
* Update entry corrupted we should scream and die
*/
break;
}
incr_ret = (kdb_incr_result_t *)
malloc(sizeof (kdb_incr_result_t));
goto error;
}
upd = (kdb_incr_update_t *)
malloc(sizeof (kdb_incr_update_t));
goto error;
}
goto error;
}
/*
* We don't want to readd this update and just use the
* existing update to be propagated later on
*/
/*
* upd was freed by ulog_replay, we NULL
* the pointer in case we subsequently break from loop.
*/
if (incr_ret) {
}
if (retval)
goto error;
/*
* We flag this as committed since this was
* the last entry before kadmind crashed, ergo
* the slaves have not seen this update before
*/
if (retval)
goto error;
}
}
if (upd)
if (incr_ret)
return (retval);
}
/*
* Map the log file to memory for performance and simplicity.
*
* Called by: if iprop_enabled then ulog_map();
* Assumes that the caller will terminate on ulog_map, hence munmap and
* closing of the fd are implicitly performed by the caller.
* Returns 0 on success else failure.
*/
{
ulog_filesize = sizeof (kdb_hlog_t);
return (KRB5_LOG_ERROR);
return (KRB5_LOG_ERROR);
/*
* File doesn't exist so we exit with kproplog
*/
return (errno);
}
return (errno);
}
return (errno);
}
return (errno);
}
return (errno);
}
} else {
/*
* Can't open existing log file
*/
return (errno);
}
}
} else {
/*
* else kadmind, kpropd, & kcommands should udpate stores
*/
}
if ((int)(ulog) == -1) {
/*
* Can't map update log file to memory
*/
return (errno);
}
if (!context->kdblog_context) {
return (errno);
} else
if (ulog->kdb_hmagic == 0) {
/*
* New update log
*/
} else {
return (KRB5_LOG_CORRUPT);
}
}
case KDB_STABLE:
case KDB_UNSTABLE:
/*
*/
if (retval == KRB5_LOG_CORRUPT) {
return (retval);
}
break;
case KDB_CORRUPT:
return (KRB5_LOG_CORRUPT);
default:
/*
* Invalid db state
*/
return (KRB5_LOG_ERROR);
}
/*
* kproplog and kpropd don't need to do anything else
*/
return (0);
}
/*
* Reinit ulog if the log is being truncated or expanded after
* we have circled.
*/
}
/*
* Expand ulog if we have specified a greater size
*/
return (errno);
}
return (errno);
}
}
}
return (0);
}
/*
* Get the last set of updates seen, (last+1) to n is returned.
*/
{
/*
* Check to make sure we don't have a corrupt ulog first.
*/
return (KRB5_LOG_CORRUPT);
}
if (tdiff <= ULOG_IDLE_TIME) {
return (0);
}
/*
* We need to lock out other processes here, such as kadmin.local,
* since we are looking at the last_sno and looking up updates. So
* we can share with other readers.
*/
if (retval)
return (retval);
/*
* We may have overflowed the update log or we shrunk the log, or
* the client's ulog has just been created.
*/
(void) krb5_db_unlock(context);
return (0);
/*
* Validate the time stamp just to make sure it was the same sno
*/
/*
* If we have the same sno we return success
*/
(void) krb5_db_unlock(context);
return (0);
}
sizeof (kdb_incr_update_t) * count);
(void) krb5_db_unlock(context);
return (errno);
}
indx_log = (kdb_ent_header_t *)
sizeof (kdb_incr_update_t));
(char *)indx_log->entry_data,
(void) krb5_db_unlock(context);
return (KRB5_LOG_CONV);
}
/*
* Mark commitment since we didn't
* want to decode and encode the
* incr update record the first time.
*/
upd++;
sno++;
} /* while */
(void) krb5_db_unlock(context);
return (0);
} else {
/*
* We have time stamp mismatch or we no longer have
* the slave's last sno, so we brute force it
*/
(void) krb5_db_unlock(context);
return (0);
}
}
/*
* Should never get here, return error
*/
return (KRB5_LOG_ERROR);
}
{
if (!ctx->kdblog_context) {
return (errno);
} else
return (0);
}