aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2015-07-17 13:03:35 -0400
committerTom Yu <tlyu@mit.edu>2015-12-02 13:36:53 -0500
commit6f1b25097969b4685263639a5214d440ce233793 (patch)
tree53048db04a2d1bdad37d70e810d1033af206deaa /src
parentd6d860410216c3e3186025b7ea4eb5f53643fa38 (diff)
downloadkrb5-6f1b25097969b4685263639a5214d440ce233793.zip
krb5-6f1b25097969b4685263639a5214d440ce233793.tar.gz
krb5-6f1b25097969b4685263639a5214d440ce233793.tar.bz2
Fix compatibility with pre-1.11 iprop dump files
Ticket #7223 added new policy fields and a new dump format version to marshal them, but did not add a new iprop dump format version. As a result, slave KDCs running 1.11 or later cannot receive full resyncs from master KDCs running 1.10 or earlier. (Reported by John Devitofranceschi.) Retroactively add support for pre-1.11 policy entries by making process_r1_11_policy() read the first ten fields, check whether the next whitespace character is a newline, and then read the rest if it is not. (back ported from commit 3c9ab5220bcc3f57641f6f4b6942b17aadb6613d) ticket: 8286 (new) version_fixed: 1.13.3 status: resolved
Diffstat (limited to 'src')
-rw-r--r--src/kadmin/dbutil/dump.c58
-rw-r--r--src/tests/t_dump.py12
2 files changed, 48 insertions, 22 deletions
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
index bfb8577..07f62e9 100644
--- a/src/kadmin/dbutil/dump.c
+++ b/src/kadmin/dbutil/dump.c
@@ -958,41 +958,61 @@ process_r1_11_policy(krb5_context context, const char *fname, FILE *filep,
char namebuf[1024];
char keysaltbuf[KRB5_KDB_MAX_ALLOWED_KS_LEN + 1];
unsigned int refcnt;
- int nread, ret = 0;
+ int nread, c, ret = 0;
memset(&rec, 0, sizeof(rec));
(*linenop)++;
rec.name = namebuf;
- rec.allowed_keysalts = keysaltbuf;
- nread = fscanf(filep, "%1023s\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t"
- "%u\t%u\t%u\t"
- K5CONST_WIDTH_SCANF_STR(KRB5_KDB_MAX_ALLOWED_KS_LEN)
- "\t%hd", rec.name, &rec.pw_min_life, &rec.pw_max_life,
+ /*
+ * Due to a historical error, iprop dumps use the same version before and
+ * after the 1.11 policy extensions. So we need to accept both 1.8-format
+ * and 1.11-format policy entries. Begin by reading the 1.8 fields.
+ */
+ nread = fscanf(filep, "%1023s\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u",
+ rec.name, &rec.pw_min_life, &rec.pw_max_life,
&rec.pw_min_length, &rec.pw_min_classes,
&rec.pw_history_num, &refcnt, &rec.pw_max_fail,
- &rec.pw_failcnt_interval, &rec.pw_lockout_duration,
- &rec.attributes, &rec.max_life, &rec.max_renewable_life,
- rec.allowed_keysalts, &rec.n_tl_data);
+ &rec.pw_failcnt_interval, &rec.pw_lockout_duration);
if (nread == EOF)
return -1;
- if (nread != 15) {
+ if (nread != 10) {
fprintf(stderr, _("cannot parse policy (%d read)\n"), nread);
return 1;
}
- if (rec.allowed_keysalts && !strcmp(rec.allowed_keysalts, "-"))
- rec.allowed_keysalts = NULL;
+ /* The next character should be a newline (1.8) or a tab (1.11). */
+ c = getc(filep);
+ if (c == EOF)
+ return -1;
+ if (c != '\n') {
+ /* Read the additional 1.11-format fields. */
+ rec.allowed_keysalts = keysaltbuf;
+ nread = fscanf(filep, "%u\t%u\t%u\t"
+ K5CONST_WIDTH_SCANF_STR(KRB5_KDB_MAX_ALLOWED_KS_LEN)
+ "\t%hd", &rec.attributes, &rec.max_life,
+ &rec.max_renewable_life, rec.allowed_keysalts,
+ &rec.n_tl_data);
+ if (nread == EOF)
+ return -1;
+ if (nread != 5) {
+ fprintf(stderr, _("cannot parse policy (%d read)\n"), nread);
+ return 1;
+ }
- /* Get TL data */
- ret = alloc_tl_data(rec.n_tl_data, &rec.tl_data);
- if (ret)
- goto cleanup;
+ if (rec.allowed_keysalts && !strcmp(rec.allowed_keysalts, "-"))
+ rec.allowed_keysalts = NULL;
- ret = process_tl_data(fname, filep, *linenop, rec.tl_data);
- if (ret)
- goto cleanup;
+ /* Get TL data */
+ ret = alloc_tl_data(rec.n_tl_data, &rec.tl_data);
+ if (ret)
+ goto cleanup;
+
+ ret = process_tl_data(fname, filep, *linenop, rec.tl_data);
+ if (ret)
+ goto cleanup;
+ }
ret = krb5_db_create_policy(context, &rec);
if (ret)
diff --git a/src/tests/t_dump.py b/src/tests/t_dump.py
index edf7a23..42f8f0e 100644
--- a/src/tests/t_dump.py
+++ b/src/tests/t_dump.py
@@ -12,12 +12,15 @@ realm.run_kadminl('addpol fred')
dumpfile = os.path.join(realm.testdir, 'dump')
realm.run([kdb5_util, 'dump', dumpfile])
-# Write an additional policy record to the dump.
+# Write additional policy records to the dump. Use the 1.8 format for
+# one of them, to test retroactive compatibility (for issue #8213).
f = open('testdir/dump', 'a')
+f.write('policy compat 0 0 3 4 5 0 '
+ '0 0 0\n')
f.write('policy barney 0 0 1 1 1 0 '
'0 0 0 0 0 0 - 1 '
'2 28 '
- 'fd100f5064625f6372656174696f6e404b5242544553542e434f4d00')
+ 'fd100f5064625f6372656174696f6e404b5242544553542e434f4d00\n')
f.close()
# Destroy and load the database; check that the policies exist.
@@ -33,6 +36,9 @@ if 'Expiration date: [never]' not in out or 'MKey: vno 1' not in out:
out = realm.run_kadminl('getpols')
if 'fred\n' not in out or 'barney\n' not in out:
fail('Missing policy after load')
+out = realm.run_kadminl('getpol compat')
+if 'Number of old keys kept: 5' not in out:
+ fail('Policy (1.8 format) has wrong value after load')
out = realm.run_kadminl('getpol barney')
if 'Number of old keys kept: 1' not in out:
fail('Policy has wrong value after load')
@@ -44,7 +50,7 @@ out = realm.run_kadminl('getprincs')
if realm.user_princ not in out or realm.host_princ not in out:
fail('Missing principal after load')
out = realm.run_kadminl('getpols')
-if 'fred\n' not in out or 'barney\n' not in out:
+if 'compat\n' not in out or 'fred\n' not in out or 'barney\n' not in out:
fail('Missing policy after second load')
srcdumpdir = os.path.join(srctop, 'tests', 'dumpfiles')