krb5 commit: Propagate policy changes over iprop via full dump

Greg Hudson ghudson at MIT.EDU
Tue Jan 22 22:35:27 EST 2013


https://github.com/krb5/krb5/commit/720e0f5bcf481db3b6e43652cb6577c012b5337e
commit 720e0f5bcf481db3b6e43652cb6577c012b5337e
Author: Greg Hudson <ghudson at mit.edu>
Date:   Tue Jan 22 22:29:30 2013 -0500

    Propagate policy changes over iprop via full dump
    
    Since iprop cannot carry policy changes, force a full resync to happen
    each time a policy change occurs.  Based on a patch from
    Richard Basch <basch at alum.mit.edu>.
    
    ticket: 7522

 src/lib/kdb/kdb5.c   |   54 +++++++++++++++++++++++++++++++++++++++++++++++--
 src/tests/t_iprop.py |   30 +++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 3 deletions(-)

diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c
index ee20c45..0f56595 100644
--- a/src/lib/kdb/kdb5.c
+++ b/src/lib/kdb/kdb5.c
@@ -2310,13 +2310,29 @@ krb5_db_create_policy(krb5_context kcontext, osa_policy_ent_t policy)
 {
     krb5_error_code status = 0;
     kdb_vftabl *v;
+    int ulog_locked = 0;
 
     status = get_vftabl(kcontext, &v);
     if (status)
         return status;
     if (v->create_policy == NULL)
         return KRB5_PLUGIN_OP_NOTSUPP;
-    return v->create_policy(kcontext, policy);
+
+    if (logging(kcontext)) {
+        status = ulog_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE);
+        if (status != 0)
+            return status;
+        ulog_locked = 1;
+    }
+
+    status = v->create_policy(kcontext, policy);
+    /* iprop does not support policy mods; force full resync. */
+    if (!status && ulog_locked)
+        ulog_init_header(kcontext);
+
+    if (ulog_locked)
+        ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
+    return status;
 }
 
 krb5_error_code
@@ -2338,13 +2354,29 @@ krb5_db_put_policy(krb5_context kcontext, osa_policy_ent_t policy)
 {
     krb5_error_code status = 0;
     kdb_vftabl *v;
+    int ulog_locked = 0;
 
     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);
+
+    if (logging(kcontext)) {
+        status = ulog_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE);
+        if (status)
+            return status;
+        ulog_locked = 1;
+    }
+
+    status = v->put_policy(kcontext, policy);
+    /* iprop does not support policy mods; force full resync. */
+    if (!status && ulog_locked)
+        ulog_init_header(kcontext);
+
+    if (ulog_locked)
+        ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
+    return status;
 }
 
 krb5_error_code
@@ -2367,13 +2399,29 @@ krb5_db_delete_policy(krb5_context kcontext, char *policy)
 {
     krb5_error_code status = 0;
     kdb_vftabl *v;
+    int ulog_locked = 0;
 
     status = get_vftabl(kcontext, &v);
     if (status)
         return status;
     if (v->delete_policy == NULL)
         return KRB5_PLUGIN_OP_NOTSUPP;
-    return v->delete_policy(kcontext, policy);
+
+    if (logging(kcontext)) {
+        status = ulog_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE);
+        if (status)
+            return status;
+        ulog_locked = 1;
+    }
+
+    status = v->delete_policy(kcontext, policy);
+    /* iprop does not support policy mods; force full resync. */
+    if (!status && ulog_locked)
+        ulog_init_header(kcontext);
+
+    if (ulog_locked)
+        ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
+    return status;
 }
 
 void
diff --git a/src/tests/t_iprop.py b/src/tests/t_iprop.py
index f61279f..bd9ab89 100644
--- a/src/tests/t_iprop.py
+++ b/src/tests/t_iprop.py
@@ -147,6 +147,36 @@ out = realm.run_kadminl('getprinc w', slave)
 if 'Attributes:\n' not in out:
     fail('Slave has different state from master')
 
+# Create a policy and check that it propagates via full resync.
+realm.run_kadminl('addpol -minclasses 2 testpol')
+check_serial(realm, 'None')
+kpropd.send_signal(signal.SIGUSR1)
+wait_for_prop(kpropd, True)
+check_serial(realm, 'None', slave)
+out = realm.run_kadminl('getpol testpol', slave)
+if 'Minimum number of password character classes: 2' not in out:
+    fail('Slave does not have policy from master')
+
+# Modify the policy and test that it also propagates via full resync.
+realm.run_kadminl('modpol -minlength 17 testpol')
+check_serial(realm, 'None')
+kpropd.send_signal(signal.SIGUSR1)
+wait_for_prop(kpropd, True)
+check_serial(realm, 'None', slave)
+out = realm.run_kadminl('getpol testpol', slave)
+if 'Minimum password length: 17' not in out:
+    fail('Slave does not have policy change from master')
+
+# Delete the policy and test that it propagates via full resync.
+realm.run_kadminl('delpol -force testpol')
+check_serial(realm, 'None')
+kpropd.send_signal(signal.SIGUSR1)
+wait_for_prop(kpropd, True)
+check_serial(realm, 'None', slave)
+out = realm.run_kadminl('getpol testpol', slave)
+if 'Policy does not exist' not in out:
+    fail('Slave did not get policy deletion from master')
+
 # Reset the ulog on the master side to force a full resync to all slaves.
 # XXX Note that we only have one slave in this test, so we can't really
 # test this.


More information about the cvs-krb5 mailing list