Return-Path: Received: from mta1.srv.hcvlny.cv.net (mta1.srv.hcvlny.cv.net [167.206.4.196]) by krbdev.mit.edu (Postfix) with ESMTP id 5368658E59 for ; Wed, 2 Jan 2013 17:50:26 -0500 (EST) Received: from tardis.internal.bright-prospects.com (ool-4a5a27d7.dyn.optonline.net [74.90.39.215]) by mta1.srv.hcvlny.cv.net (Sun Java System Messaging Server 6.2-8.04 (built Feb 28 2007)) with ESMTP id <0MG000K5PSS18W40@mta1.srv.hcvlny.cv.net> for rt@krbdev.mit.edu; Wed, 02 Jan 2013 17:50:26 -0500 (EST) Received: from localhost (localhost [127.0.0.1]) by tardis.internal.bright-prospects.com (Postfix) with ESMTP id 48FDA8A5BE for ; Wed, 02 Jan 2013 17:50:25 -0500 (EST) Received: from tardis.internal.bright-prospects.com ([127.0.0.1]) by localhost (tardis.internal.bright-prospects.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id RpkDIBlKNITb for ; Wed, 02 Jan 2013 17:50:03 -0500 (EST) Received: from BASCHT520 (unknown [192.168.15.196]) by tardis.internal.bright-prospects.com (Postfix) with ESMTPS id AACF98A5D9 for ; Wed, 02 Jan 2013 17:50:03 -0500 (EST) Date: Wed, 02 Jan 2013 17:50:03 -0500 From: Richard Basch Subject: RE: [krbdev.mit.edu #7522] AutoReply: krb5-1.11, patch 1 of 4 In-Reply-To: To: rt@krbdev.mit.edu Message-ID: <02d101cde93b$80cdb6c0$82692440$@mit.edu> MIME-Version: 1.0 X-Mailer: Microsoft Office Outlook 12.0 Content-Type: text/plain; charset=us-ascii Content-Language: en-us Content-Transfer-Encoding: 7BIT Thread-Index: Ac3kd9M/mGLx9ysmRSavDNPd2ubRlQEwjEYQ X-Virus-Scanned: amavisd-new at mail.bright-prospects.com References: RT-Send-Cc: X-RT-Original-Encoding: us-ascii Content-Length: 9932 Iprop currently can cause corruption/discrepancies between the master and slaves when policy changes occur. If you change a policy, the policy changes are not reflected to the slaves and if a slave has to be promoted to a master, there is a problem with the data. Or even worse, if a policy is created and a user is assigned to that policy, then as it propagates to the slave, it has issues with the user entry. So, patch 1 is "required" for 1.11 for data consistency (it also applies to prior versions, e.g. since iprop was introduced). This particular patch is easy to graft into current & prior Kerberos releases. Patch 1 should be treated on its own merit (I consider the corruption of data quality between the master and slaves a "serious" bug). Patches 2-4 are more targeted (and progressively move toward "enhancement", and I am sure patch 4 cannot be introduced until the "next version"). -----Original Message----- From: krb5 [mailto:rt@krbdev.mit.edu] Sent: Thursday, December 27, 2012 4:16 PM To: basch@alum.mit.edu Subject: [krbdev.mit.edu #7522] AutoReply: krb5-1.11, patch 1 of 4 Greetings, This message has been automatically generated in response to the creation of a trouble ticket regarding: "krb5-1.11, patch 1 of 4", a summary of which appears below. There is no need to reply to this message right now. Your ticket has been assigned an ID of [krbdev.mit.edu #7522]. Please include the string: [krbdev.mit.edu #7522] in the subject line of all future correspondence about this issue. To do so, you may reply to this message. Thank you, ------------------------------------------------------------------------- I will be submitting 4 patches: 1) If a Kerberos policy is changed, the iprop ulog needs to be reset otherwise inconsistencies may result. Basically, a full resync is needed by the slaves to reacquire the new policies. Otherwise incremental updates may fail because the updated policy information will not be correctly associated. 2) Kproplog should treat the ulog as a circular buffer. Patch #3 affects kproplog's behavior. Therefore, if the ulog is not fully populated, the references to the circular buffer should be computed based on the indices. 3) Allow slaves to capture ulog updates. This facilitates promoting a slave as a master without having to have all other slaves do a full resync. 4) Add an option to allow tree-based propagation of updates (it requires 1-3). Specifically, add an option to kpropd to redirect where to get its updates from and add an option to kadmind to allow it to service iprop requests only (without enabling all other update functions). Attached is patch #1 to force a full resync upon policy changes. Only in src.01/include: kadm5 diff -ru src.00/include/kdb_log.h src.01/include/kdb_log.h --- src.00/include/kdb_log.h 2012-12-17 21:47:04.000000000 -0500 +++ src.01/include/kdb_log.h 2012-12-21 19:29:13.679830223 -0500 @@ -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, uint32_t recsize); 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, Only in src.01/lib/kdb: #kdb5.c# diff -ru src.00/lib/kdb/kdb5.c src.01/lib/kdb/kdb5.c --- src.00/lib/kdb/kdb5.c 2012-12-17 21:47:05.000000000 -0500 +++ src.01/lib/kdb/kdb5.c 2012-12-21 19:27:53.319790148 -0500 @@ -2319,15 +2319,29 @@ 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; if (v->create_policy == NULL) return KRB5_PLUGIN_OP_NOTSUPP; - return v->create_policy(kcontext, policy); + status = v->create_policy(kcontext, policy); + + /* iprop does not support policy mods; force full-resync (re-init ulog) */ + if (!status && log_ctx && log_ctx->iproprole == IPROP_MASTER) { + kdb_hlog_t *ulog = NULL; + if ((ulog = log_ctx->ulog)) + (void) ulog_init_header(kcontext, 0); + } + + ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK); + return status; } krb5_error_code @@ -2347,15 +2361,58 @@ 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; + osa_policy_ent_t old_policy = NULL; status = get_vftabl(kcontext, &v); if (status) return status; if (v->put_policy == NULL) return KRB5_PLUGIN_OP_NOTSUPP; - return v->put_policy(kcontext, policy); + status = ulog_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE); + if (status) + return status; + if (log_ctx && log_ctx->iproprole == IPROP_MASTER) { + if (v->get_policy) + v->get_policy(kcontext, policy->name, &old_policy); + } + status = v->put_policy(kcontext, policy); + + /* + * iprop does not support policy mods; force full-resync (re-init ulog). + * However, for policy changes, we need to first check if there were + * any *substantive* changes to avoid unnecessary resyncs. + */ + + if (!status && log_ctx && log_ctx->iproprole == IPROP_MASTER) { + if (old_policy == NULL || + old_policy->version != policy->version || + old_policy->pw_min_life != policy->pw_min_life || + old_policy->pw_max_life != policy->pw_max_life || + old_policy->pw_min_length != policy->pw_min_length || + old_policy->pw_min_classes != policy->pw_min_classes || + old_policy->pw_history_num != policy->pw_history_num) { + + kdb_hlog_t *ulog = NULL; + if ((ulog = log_ctx->ulog)) + (void) ulog_init_header(kcontext, 0); + } else if (policy->version > 1 && + (old_policy->pw_max_fail != policy->pw_max_fail || + old_policy->pw_failcnt_interval != policy->pw_failcnt_interval || + old_policy->pw_lockout_duration != policy->pw_lockout_duration)) { + + kdb_hlog_t *ulog = NULL; + if ((ulog = log_ctx->ulog)) + (void) ulog_init_header(kcontext, 0); + } + if (old_policy) + krb5_db_free_policy(kcontext, old_policy); + } + + ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK); + return status; } krb5_error_code @@ -2376,6 +2433,7 @@ 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; @@ -2384,7 +2442,20 @@ return status; if (v->delete_policy == NULL) return KRB5_PLUGIN_OP_NOTSUPP; - return v->delete_policy(kcontext, policy); + status = ulog_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE); + if (status) + return status; + status = v->delete_policy(kcontext, policy); + + /* iprop does not support policy mods; force full-resync (re-init ulog) */ + if (!status && log_ctx && log_ctx->iproprole == IPROP_MASTER) { + kdb_hlog_t *ulog = NULL; + if ((ulog = log_ctx->ulog)) + (void) ulog_init_header(kcontext, 0); + } + + ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK); + return status; } void Only in src.01/lib/kdb: kdb5.c.~1~ diff -ru src.00/lib/kdb/kdb_log.c src.01/lib/kdb/kdb_log.c --- src.00/lib/kdb/kdb_log.c 2012-12-17 21:47:05.000000000 -0500 +++ src.01/lib/kdb/kdb_log.c 2012-12-21 19:58:17.450702557 -0500 @@ -121,8 +121,12 @@ new_size = sizeof (kdb_hlog_t); - new_block = (recsize / ULOG_BLOCK) + 1; - new_block *= ULOG_BLOCK; + if (recsize > ULOG_BLOCK) { + new_block = (recsize + ULOG_BLOCK - 1) / ULOG_BLOCK; + new_block *= ULOG_BLOCK; + } + else + new_block = ULOG_BLOCK; new_size += ulogentries * new_block; @@ -547,6 +551,35 @@ } /* + * Re-init the log header. + */ +krb5_error_code +ulog_init_header(krb5_context context, uint32_t recsize) +{ + kdb_log_context *log_ctx; + kdb_hlog_t *ulog = NULL; + krb5_error_code retval; + uint_t block_min; + + + 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; + ulog_reset(ulog); + + block_min = ULOG_BLOCK; /* Should this be min(ULOG_BLOCK, pagesize)? */ + if (recsize > block_min) + ulog->kdb_block = ((recsize + block_min - 1) & (~(block_min-1))); + + ulog_sync_header(ulog); + + /* The caller is responsible for unlocking... */ + return (0); +} + +/* * Map the log file to memory for performance and simplicity. * * Called by: if iprop_enabled then ulog_map(); Only in src.01/plugins/authdata/greet: Makefile Only in src.01/plugins/authdata/greet_client: Makefile Only in src.01/plugins/authdata/greet_server: Makefile Only in src.01/plugins/kdb/hdb: Makefile Only in src.01/plugins/locate/python: Makefile Only in src.01/plugins/preauth/cksum_body: Makefile Only in src.01/plugins/preauth/securid_sam2: Makefile Only in src.01/plugins/preauth/wpse: Makefile Only in src.01/tests/threads: Makefile Only in src.01/util/collected-client-lib: Makefile