[krbdev.mit.edu #7141] Kerberos 1.10.1 - iprop issues

Richard Basch via RT rt-comment at krbdev.mit.edu
Thu May 17 19:43:40 EDT 2012


Sorry, my original email forgot to mention the reference source... 1.10.1.

The attached patch fixes a few issues:
- Some error handlers forgot to check whether the variable was set before
trying to free memory.
- In the iprop code, there is a static variable, which makes it unsafe for
concurrent threads to perform a full resync.
- The iprop code is not scalable
	- There is an artificial limit on how soon two iprop queries may
arrive (with 30+ slaves, UPDATE_BUSY is common)
	- It is currently not possible to setup a tree hierarchy for iprop
(i.e. reduce WAN usage)
- The iprop code does not handle "policy" changes (add, update, delete).
- After a database load or other operation which re-initializes the ulog,
any slaves of that server will continually process full-resyncs until such
time as there is an "update" made in the ulog.  A zero-length ulog causes
issues.

The attached patch introduces a tree replication strategy to iprop.
- Allow kadmind to be invoked with -proponly (it does not initialize other
kadmin services), which can be used on slaves.
- Create ulog entries on slaves when ulog_replay occurs.
Note: Several code changes were required since this means the log does not
always start at 1 and there may be gaps before the first entry. Thus the
ulog index is computed solely based on ((kdb serial - 1) % ulogsize).
Various routines were modified in kproplog, ulog_check(), etc. to eliminate
the assumption the log is populated from 0 .. ulog->kdb_num.
- When a policy change occurs, reinitialize the ulog so slaves are forced to
resync. This is required to ensure there is no inconsistency if a policy is
added on the master and then principals are associated with the new policy
(the current iprop method would leave the slaves in a divergent state from
the master).
Note: it would be better to propagate the policy change, but that requires
changing the current iprop protocol.
- Eliminate the check which prohibits multiple iprop queries within a
limited time.
- Enforce only one slave can receive a full resync at a time.
	This is to ensure a production environment will not have multiple
slaves out of commission concurrently.
	Note: Tree replication will propagate faster as the limit is
enforced only at the each node level.
- If ulog is empty, iprop will return UPDATE_BUSY rather than go into an
endless cycle of UPDATE_FULL_RESYNC_NEEDED.


diff -ru src.orig/include/kdb_log.h src/include/kdb_log.h
--- src.orig/include/kdb_log.h	2010-07-06 17:53:23.000000000 -0400
+++ src/include/kdb_log.h	2012-05-17 12:52:54.000000000 -0400
@@ -71,6 +71,7 @@
                                 const char *logname, uint32_t entries,
                                 int caller,
                                 char **db_args);
+extern krb5_error_code ulog_init_header(krb5_context context);
 extern krb5_error_code ulog_add_update(krb5_context context,
                                        kdb_incr_update_t *upd);
 extern krb5_error_code ulog_delete_update(krb5_context context,
diff -ru src.orig/kadmin/server/ipropd_svc.c src/kadmin/server/ipropd_svc.c
--- src.orig/kadmin/server/ipropd_svc.c	2011-11-07 17:35:48.000000000 -0500
+++ src/kadmin/server/ipropd_svc.c	2012-05-17 15:35:44.000000000 -0400
@@ -37,6 +37,8 @@
 extern short l_port;
 static char abuf[33];
 
+static int kdb_fullresync_in_progress = 0;
+
 /* Result is stored in a static buffer and is invalidated by the next call.
*/
 static const char *client_addr(struct svc_req *svc) {
     strlcpy(abuf, inet_ntoa(svc->rq_xprt->xp_raddr.sin_addr),
sizeof(abuf));
@@ -187,6 +189,15 @@
 
     kret = ulog_get_entries(handle->context, *arg, &ret);
 
+    /*
+     * Only permit one full resync at a time.
+     * First, we do not want to disrupt the functionality of multiple
slaves.
+     * Second, static variables are used within the full resync function
+     * which limits concurrency.
+     */
+    if ((ret.ret == UPDATE_FULL_RESYNC_NEEDED) &&
kdb_fullresync_in_progress)
+        ret.ret = UPDATE_BUSY;
+
     if (ret.ret == UPDATE_OK) {
 	(void) snprintf(obuf, sizeof (obuf),
 			_("%s; Incoming SerialNo=%lu; Outgoing
SerialNo=%lu"),
@@ -270,6 +281,11 @@
 	krb5_klog_syslog(LOG_ERR,
 			 _("%s: server handle is NULL"),
 			 whoami);
+	return (&ret);
+    }
+
+    if (kdb_fullresync_in_progress++) {
+        ret.ret = UPDATE_BUSY;
 	goto out;
     }
 
@@ -421,14 +437,22 @@
     }
 
 out:
+    /* Even if we were busy, we inrecemented first; it is safe to decrement
*/
+    if (kdb_fullresync_in_progress)
+        kdb_fullresync_in_progress--;
+
     if (nofork)
 	debprret(whoami, ret.ret, 0);
-    free(client_name);
-    free(service_name);
+    if (client_name)
+        free(client_name);
+    if (service_name)
+        free(service_name);
     if (name)
 	gss_release_name(&min_stat, &name);
-    free(tmpf);
-    free(ubuf);
+    if (tmpf)
+        free(tmpf);
+    if (ubuf)
+        free(ubuf);
     return (&ret);
 }
 
diff -ru src.orig/kadmin/server/ovsec_kadmd.c
src/kadmin/server/ovsec_kadmd.c
--- src.orig/kadmin/server/ovsec_kadmd.c	2011-09-21
12:29:00.000000000 -0400
+++ src/kadmin/server/ovsec_kadmd.c	2012-05-15 15:21:29.000000000 -0400
@@ -110,6 +110,7 @@
     fprintf(stderr, _("Usage: kadmind [-x db_args]* [-r realm] [-m]
[-nofork] "
                       "[-port port-number]\n"
                       "\t\t[-P pid_file]\n"
+                      "\t\t[-proponly]\n"
                       "\nwhere,\n\t[-x db_args]* - any number of database "
                       "specific arguments.\n"
                       "\t\t\tLook at each database documentation for "
@@ -204,6 +205,7 @@
 static krb5_context hctx;
 
 int nofork = 0;
+int prop_only = 0;
 
 int main(int argc, char *argv[])
 {
@@ -287,6 +289,8 @@
         } else if (strcmp(*argv, "-passwordserver") == 0) {
             kadm5_set_use_password_server ();
 #endif
+        } else if (strcmp(*argv, "-proponly") == 0) {
+            prop_only = 1;
         } else if(strcmp(*argv, "-port") == 0) {
             argc--; argv++;
             if(!argc)
@@ -382,10 +386,15 @@
     }
 
 #define server_handle ((kadm5_server_handle_t)global_server_handle)
-    if ((ret = loop_add_udp_port(server_handle->params.kpasswd_port))
+    if (prop_only
+        || (ret = loop_add_udp_port(server_handle->params.kpasswd_port))
         || (ret = loop_add_tcp_port(server_handle->params.kpasswd_port))
         || (ret = loop_add_rpc_service(server_handle->params.kadmind_port,
                                        KADM, KADMVERS, kadm_1))
+       )
+        /* Do nothing; our error handling will follow */
+        1;
+    if (ret
 #ifndef DISABLE_IPROP
         || (server_handle->params.iprop_enabled
             ? (ret = loop_add_rpc_service(server_handle->params.iprop_port,
diff -ru src.orig/lib/kdb/kdb5.c src/lib/kdb/kdb5.c
--- src.orig/lib/kdb/kdb5.c	2011-10-04 16:16:07.000000000 -0400
+++ src/lib/kdb/kdb5.c	2012-05-17 12:51:57.000000000 -0400
@@ -41,6 +41,7 @@
 #include <string.h>
 #include <k5-int.h>
 #include <osconf.h>
+#include <sys/mman.h>
 #include "kdb5.h"
 #include "kdb_log.h"
 #include "kdb5int.h"
@@ -2254,15 +2255,30 @@
 krb5_error_code
 krb5_db_create_policy(krb5_context kcontext, osa_policy_ent_t policy)
 {
+    kdb_log_context *log_ctx = kcontext->kdblog_context;
     krb5_error_code status = 0;
     kdb_vftabl *v;
 
     status = get_vftabl(kcontext, &v);
     if (status)
         return status;
+    status = ulog_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE);
+    if (status)
+        return status;
+
+    /* Because iprop does not support policy changes; force full-resync */
+    if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
+        kdb_hlog_t *ulog = NULL;
+        if ((ulog = log_ctx->ulog))
+            (void) ulog_init_header(kcontext);
+    }
+
     if (v->create_policy == NULL)
         return KRB5_PLUGIN_OP_NOTSUPP;
-    return v->create_policy(kcontext, policy);
+    status = v->create_policy(kcontext, policy);
+
+    ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
+    return status;
 }
 
 krb5_error_code
@@ -2282,15 +2298,31 @@
 krb5_error_code
 krb5_db_put_policy(krb5_context kcontext, osa_policy_ent_t policy)
 {
+    kdb_log_context *log_ctx = kcontext->kdblog_context;
     krb5_error_code status = 0;
     kdb_vftabl *v;
 
     status = get_vftabl(kcontext, &v);
     if (status)
         return status;
+
+    status = ulog_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE);
+    if (status)
+        return status;
+
+    /* Because iprop does not support policy changes; force full-resync */
+    if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
+        kdb_hlog_t *ulog = NULL;
+        if ((ulog = log_ctx->ulog))
+            (void) ulog_init_header(kcontext);
+    }
+
     if (v->put_policy == NULL)
         return KRB5_PLUGIN_OP_NOTSUPP;
-    return v->put_policy(kcontext, policy);
+    status = v->put_policy(kcontext, policy);
+
+    ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
+    return status;
 }
 
 krb5_error_code
@@ -2311,15 +2343,31 @@
 krb5_error_code
 krb5_db_delete_policy(krb5_context kcontext, char *policy)
 {
+    kdb_log_context *log_ctx = kcontext->kdblog_context;
     krb5_error_code status = 0;
     kdb_vftabl *v;
 
     status = get_vftabl(kcontext, &v);
     if (status)
         return status;
+
+    status = ulog_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE);
+    if (status)
+        return status;
+
+    /* Because iprop does not support policy changes; force full-resync */
+    if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
+        kdb_hlog_t *ulog = NULL;
+        if ((ulog = log_ctx->ulog))
+            (void) ulog_init_header(kcontext);
+    }
+
     if (v->delete_policy == NULL)
         return KRB5_PLUGIN_OP_NOTSUPP;
-    return v->delete_policy(kcontext, policy);
+    status = v->delete_policy(kcontext, policy);
+
+    ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
+    return status;
 }
 
 void
diff -ru src.orig/lib/kdb/kdb_log.c src/lib/kdb/kdb_log.c
--- src.orig/lib/kdb/kdb_log.c	2011-06-10 14:17:37.000000000 -0400
+++ src/lib/kdb/kdb_log.c	2012-05-17 16:09:06.000000000 -0400
@@ -15,6 +15,7 @@
 #include <stdlib.h>
 #include <limits.h>
 #include <syslog.h>
+#include <errno.h>
 #include "kdb5.h"
 #include "kdb_log.h"
 #include "kdb5int.h"
@@ -413,6 +414,64 @@
                 goto cleanup;
         }
 
+	// XXX XXX
+        if (log_ctx && (log_ctx->iproprole == IPROP_SLAVE)) {
+            uint32_t ulogentries = log_ctx->ulogentries;
+            int ulogfd = log_ctx->ulogfd;
+            uint_t indx = (upd->kdb_entry_sno - 1) % ulogentries;
+            ulong_t upd_size = xdr_sizeof((xdrproc_t)xdr_kdb_incr_update_t,
upd);
+            uint_t recsize = sizeof (kdb_ent_header_t) + upd_size;
+            kdb_ent_header_t *indx_log;
+            XDR xdrs;
+
+            if (recsize > ulog->kdb_block) {
+                if ((retval = ulog_resize(ulog, ulogentries, ulogfd,
recsize)))
+                    goto cleanup;
+                ulog->kdb_first_sno = 0;
+            }
+
+            ulog->kdb_state = KDB_UNSTABLE;
+
+            indx_log = (kdb_ent_header_t *)INDEX(ulog, indx);
+            (void) memset(indx_log, 0, ulog->kdb_block);
+            
+            indx_log->kdb_umagic = KDB_ULOG_MAGIC;
+            indx_log->kdb_entry_size = upd_size;
+            indx_log->kdb_entry_sno = upd->kdb_entry_sno;
+            indx_log->kdb_time = upd->kdb_time;
+            indx_log->kdb_commit = TRUE;
+
+            xdrmem_create(&xdrs, (char *)indx_log->entry_data,
+                          indx_log->kdb_entry_size, XDR_ENCODE);
+            if (!xdr_kdb_incr_update_t(&xdrs, upd)) {
+                retval = KRB5_LOG_CONV;
+                goto cleanup;
+            }
+
+            if (ulog->kdb_num < ulogentries)
+                ulog->kdb_num++;
+
+            ulog->kdb_last_sno = upd->kdb_entry_sno;
+            ulog->kdb_last_time = upd->kdb_time;
+
+            if (! ulog->kdb_first_sno) {
+                 ulog->kdb_first_sno = upd->kdb_entry_sno;
+                 ulog->kdb_first_time = upd->kdb_time;
+            }
+            if (ulog->kdb_last_sno - ulog->kdb_first_sno >= ulogentries) {
+                 indx = upd->kdb_entry_sno % ulogentries;
+                 indx_log = (kdb_ent_header_t *)INDEX(ulog, indx);
+                 ulog->kdb_first_sno = indx_log->kdb_entry_sno;
+                 ulog->kdb_first_time = indx_log->kdb_time;
+            }
+
+            retval = ulog_finish_update(context, upd);
+            //retval = ulog_sync_update(ulog, indx_log);
+            if (retval)
+                goto cleanup;
+        }
+	// XXX XXX
+        
         upd++;
     }
 
@@ -441,17 +500,34 @@
 {
     XDR                 xdrs;
     krb5_error_code     retval = 0;
-    unsigned int        i;
+    unsigned int        i, ulogentries;
     kdb_ent_header_t    *indx_log;
     kdb_incr_update_t   *upd = NULL;
     kdb_incr_result_t   *incr_ret = NULL;
 
     ulog->kdb_state = KDB_STABLE;
 
-    for (i = 0; i < ulog->kdb_num; i++) {
-        indx_log = (kdb_ent_header_t *)INDEX(ulog, i);
+    if (ulog->kdb_num == 0)
+        goto error;	/* Nothing to check; return OK */
 
-        if (indx_log->kdb_umagic != KDB_ULOG_MAGIC) {
+    ulogentries = context->kdblog_context->ulogentries;
+
+    if ((ulogentries <= 0)
+        || (ulog->kdb_first_sno <= 0) || (ulog->kdb_last_sno <= 0)
+        || (ulog->kdb_num > ulogentries)
+        || (ulog->kdb_last_sno - ulog->kdb_first_sno + 1 != ulog->kdb_num))
+    {
+        ulog->kdb_state = KDB_CORRUPT;
+        retval = KRB5_LOG_CORRUPT;
+        goto error;
+    }
+
+    for (i = ulog->kdb_first_sno; i <= ulog->kdb_last_sno; i++) {
+        indx_log = (kdb_ent_header_t *)INDEX(ulog, ((i - 1) %
ulogentries));
+
+        if ((indx_log->kdb_umagic != KDB_ULOG_MAGIC)
+            || (indx_log->kdb_entry_sno != i))
+        {
             /*
              * Update entry corrupted we should scream and die
              */
@@ -529,7 +605,8 @@
     if (upd)
         ulog_free_entries(upd, 1);
 
-    free(incr_ret);
+    if (incr_ret)
+        free(incr_ret);
 
     ulog_sync_header(ulog);
 
@@ -574,7 +651,7 @@
             return (errno);
         }
 
-        if ((caller == FKADMIND) || (caller == FKCOMMAND))
+        if ((caller == FKADMIND) || (caller == FKPROPD) || (caller ==
FKCOMMAND))
             ulog_filesize += ulogentries * ULOG_BLOCK;
 
         if (extend_file_to(ulogfd, ulog_filesize) < 0)
@@ -643,7 +720,7 @@
         }
     }
 
-    if (caller == FKADMIND) {
+    if ((caller == FKADMIND) || (caller == FKPROPD)) {
         retval = ulog_lock(context, KRB5_LOCKMODE_EXCLUSIVE);
         if (retval)
             return retval;
@@ -683,11 +760,25 @@
     retval = ulog_lock(context, KRB5_LOCKMODE_EXCLUSIVE);
     if (retval)
         return retval;
-    if (ulog->kdb_num != ulogentries) {
-        if ((ulog->kdb_num != 0) &&
-            ((ulog->kdb_last_sno > ulog->kdb_num) ||
-             (ulog->kdb_num > ulogentries))) {
 
+    if (ulog->kdb_num > ulogentries) {
+        (void) memset(ulog, 0, sizeof (kdb_hlog_t));
+
+        ulog->kdb_hmagic = KDB_ULOG_HDR_MAGIC;
+        ulog->db_version_num = KDB_VERSION;
+        ulog->kdb_state = KDB_STABLE;
+        ulog->kdb_block = ULOG_BLOCK;
+
+        ulog_sync_header(ulog);
+    }
+    if (ulog->kdb_num && (ulog->kdb_num != ulogentries)) {
+        uint_t indx;
+        kdb_ent_header_t *indx_log;
+
+        indx = (ulog->kdb_last_sno - 1) % ulogentries;
+        indx_log = (kdb_ent_header_t *)INDEX(ulog, indx);
+
+        if (indx_log->kdb_entry_sno != ulog->kdb_last_sno) {
             (void) memset(ulog, 0, sizeof (kdb_hlog_t));
 
             ulog->kdb_hmagic = KDB_ULOG_HDR_MAGIC;
@@ -697,25 +788,57 @@
 
             ulog_sync_header(ulog);
         }
+    }
 
-        /*
-         * Expand ulog if we have specified a greater size
-         */
-        if (ulog->kdb_num < ulogentries) {
-            ulog_filesize += ulogentries * ulog->kdb_block;
+    /*
+     * Expand ulog if we have specified a greater size
+     */
+    if (ulog->kdb_num < ulogentries) {
+        ulog_filesize += ulogentries * ulog->kdb_block;
 
-            if (extend_file_to(ulogfd, ulog_filesize) < 0) {
-                ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
-                return errno;
-            }
+        if (extend_file_to(ulogfd, ulog_filesize) < 0) {
+            ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
+            return errno;
         }
     }
+
     ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
 
     return (0);
 }
 
 /*
+ *
+ */
+krb5_error_code
+ulog_init_header(krb5_context context)
+{
+    kdb_log_context     *log_ctx;
+    kdb_hlog_t          *ulog = NULL;
+    krb5_error_code     retval;
+
+
+    INIT_ULOG(context);
+
+    /* The caller should already have a lock, but ensure it is "exclusive".
*/
+    if ((retval = ulog_lock(context, KRB5_LOCKMODE_EXCLUSIVE)))
+        return retval;
+
+    (void) memset(ulog, 0, sizeof (kdb_hlog_t));
+
+    ulog->kdb_hmagic = KDB_ULOG_HDR_MAGIC;
+    ulog->db_version_num = KDB_VERSION;
+    ulog->kdb_state = KDB_STABLE;
+    ulog->kdb_block = ULOG_BLOCK;
+
+    ulog_sync_header(ulog);
+
+    /* The caller is responsible for unlocking... */
+    return (0);
+}
+
+
+/*
  * Get the last set of updates seen, (last+1) to n is returned.
  */
 krb5_error_code
@@ -737,7 +860,20 @@
     INIT_ULOG(context);
     ulogentries = log_ctx->ulogentries;
 
-    retval = ulog_lock(context, KRB5_LOCKMODE_SHARED);
+    retval = ulog_lock(context, KRB5_LOCKMODE_SHARED |
KRB5_LOCKMODE_DONTBLOCK);
+    if (0 
+#ifdef EWOULDBLOCK
+        || (retval == EWOULDBLOCK)
+#endif
+#ifdef EAGAIN
+        || (retval == EWOULDBLOCK)
+#endif
+       ) {
+        ulog_handle->ret = UPDATE_BUSY;
+        (void) ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
+        return (0);
+    }
+        
     if (retval)
         return retval;
 
@@ -750,6 +886,9 @@
         return (KRB5_LOG_CORRUPT);
     }
 
+#if 0
+    /* This code block causes deadlock issues with lots of slaves. */
+
     gettimeofday(&timestamp, NULL);
 
     tdiff = timestamp.tv_sec - ulog->kdb_last_time.seconds;
@@ -758,6 +897,18 @@
         (void) ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
         return (0);
     }
+#endif
+
+    /*
+     * Special case - no log entries. The first sync should be a full
+     * resync since we can't compare timestamps, but we don't want to
+     * loop doing full resyncs until there is a log update.
+     */
+    if (last.last_sno && (ulog->kdb_num == 0)) {
+        ulog_handle->ret = UPDATE_BUSY;
+        (void) ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
+        return (0);
+    }
 
     /*
      * We need to lock out other processes here, such as kadmin.local,
Only in src/lib/kdb: kdb_log.c.~1~
Only in src/plugins/kdb/ldap/ldap_util: RCS
diff -ru src.orig/slave/kpropd.c src/slave/kpropd.c
--- src.orig/slave/kpropd.c	2011-06-30 23:26:58.000000000 -0400
+++ src/slave/kpropd.c	2012-05-17 13:58:08.000000000 -0400
@@ -146,6 +146,7 @@
 char    *kdb5_util = KPROPD_DEFAULT_KDB5_UTIL;
 char    *kerb_database = NULL;
 char    *acl_file_name = KPROPD_ACL_FILE;
+char	*admin_server = NULL;
 
 krb5_address    *sender_addr;
 krb5_address    *receiver_addr;
@@ -179,6 +180,7 @@
             progname);
     fprintf(stderr, _("\t[-F kerberos_db_file ] [-p
kdb5_util_pathname]\n"));
     fprintf(stderr, _("\t[-x db_args]* [-P port] [-a acl_file]\n"));
+    fprintf(stderr, _("\t[-A admin_server]\n"));
     exit(1);
 }
 
@@ -1046,6 +1048,15 @@
             word++;
             while (word && (ch = *word++)) {
                 switch(ch){
+		case 'A':
+                    if (*word)
+                        admin_server = word;
+                    else
+                        admin_server = *argv++;
+                    if (!admin_server)
+                        usage();
+                    word = 0;
+		    break;
                 case 'f':
                     if (*word)
                         file = word;
@@ -1193,6 +1204,11 @@
         com_err(progname, retval, _("while initializing"));
         exit(1);
     }
+    if (admin_server) {
+        char *x = params.admin_server;
+	params.admin_server = admin_server;
+        admin_server = x;
+    }
     if (params.iprop_enabled == TRUE) {
         ulog_set_role(kpropd_context, IPROP_SLAVE);
 
diff -ru src.orig/slave/kproplog.c src/slave/kproplog.c
--- src.orig/slave/kproplog.c	2011-06-10 14:17:59.000000000 -0400
+++ src/slave/kproplog.c	2012-05-16 20:09:24.000000000 -0400
@@ -399,11 +399,13 @@
  * Print the update entry information
  */
 static void
-print_update(kdb_hlog_t *ulog, uint32_t entry, unsigned int verbose)
+print_update(krb5_context kcontext, uint32_t entry, unsigned int verbose)
 {
     XDR                 xdrs;
     uint32_t            start_sno, i, j, indx;
     char                *dbprinc;
+    uint32_t            ulogentries =
kcontext->kdblog_context->ulogentries;
+    kdb_hlog_t          *ulog = kcontext->kdblog_context->ulog;
     kdb_ent_header_t    *indx_log;
     kdb_incr_update_t   upd;
 
@@ -413,7 +415,7 @@
         start_sno = ulog->kdb_first_sno - 1;
 
     for (i = start_sno; i < ulog->kdb_last_sno; i++) {
-        indx = i % ulog->kdb_num;
+        indx = i % ulogentries;
 
         indx_log = (kdb_ent_header_t *)INDEX(ulog, indx);
 
@@ -538,7 +540,7 @@
     (void) printf(_("\nKerberos update log (%s)\n"),
                   params.iprop_logfile);
 
-    if (ulog_map(context, params.iprop_logfile, 0, FKPROPLOG, db_args)) {
+    if (ulog_map(context, params.iprop_logfile, params.iprop_ulogsize,
FKPROPLOG, db_args)) {
         (void) fprintf(stderr, _("Unable to map log file %s\n\n"),
                        params.iprop_logfile);
         exit(1);
@@ -609,7 +611,7 @@
     }
 
     if ((!headeronly) && ulog->kdb_num) {
-        print_update(ulog, entry, verbose);
+        print_update(context, entry, verbose);
     }
 
     (void) printf("\n");




More information about the krb5-bugs mailing list