diff options
| author | Greg Hudson <ghudson@mit.edu> | 2013-01-22 22:29:30 -0500 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2013-01-22 22:34:48 -0500 |
| commit | 720e0f5bcf481db3b6e43652cb6577c012b5337e (patch) | |
| tree | 0e2386e47c28ebf09deb3b9c119fb4165c9a9bba /src | |
| parent | c865516764c0bc39e8c8e703db1a218a15a65ba4 (diff) | |
| download | krb5-720e0f5bcf481db3b6e43652cb6577c012b5337e.tar.gz krb5-720e0f5bcf481db3b6e43652cb6577c012b5337e.tar.xz krb5-720e0f5bcf481db3b6e43652cb6577c012b5337e.zip | |
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@alum.mit.edu>.
ticket: 7522
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/kdb/kdb5.c | 54 | ||||
| -rw-r--r-- | 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 ee20c4533..0f56595d2 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 f61279f23..bd9ab8984 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. |
