4 # Module for translating KDB principal flags between string and
7 # When run as a standalone script, print out C tables to insert into
8 # lib/kadm5/str_conv.c.
10 # KDB principal flag definitions copied from kdb.h
12 KRB5_KDB_DISALLOW_POSTDATED = 0x00000001
13 KRB5_KDB_DISALLOW_FORWARDABLE = 0x00000002
14 KRB5_KDB_DISALLOW_TGT_BASED = 0x00000004
15 KRB5_KDB_DISALLOW_RENEWABLE = 0x00000008
16 KRB5_KDB_DISALLOW_PROXIABLE = 0x00000010
17 KRB5_KDB_DISALLOW_DUP_SKEY = 0x00000020
18 KRB5_KDB_DISALLOW_ALL_TIX = 0x00000040
19 KRB5_KDB_REQUIRES_PRE_AUTH = 0x00000080
20 KRB5_KDB_REQUIRES_HW_AUTH = 0x00000100
21 KRB5_KDB_REQUIRES_PWCHANGE = 0x00000200
22 KRB5_KDB_DISALLOW_SVR = 0x00001000
23 KRB5_KDB_PWCHANGE_SERVICE = 0x00002000
24 KRB5_KDB_SUPPORT_DESMD5 = 0x00004000
25 KRB5_KDB_NEW_PRINC = 0x00008000
26 KRB5_KDB_OK_AS_DELEGATE = 0x00100000
27 KRB5_KDB_OK_TO_AUTH_AS_DELEGATE = 0x00200000
28 KRB5_KDB_NO_AUTH_DATA_REQUIRED = 0x00400000
29 KRB5_KDB_LOCKDOWN_KEYS = 0x00800000
31 # Input tables -- list of tuples of the form (name, flag, invert)
33 # Input forms from kadmin.c
35 ("allow_postdated", KRB5_KDB_DISALLOW_POSTDATED, True),
36 ("allow_forwardable", KRB5_KDB_DISALLOW_FORWARDABLE, True),
37 ("allow_tgs_req", KRB5_KDB_DISALLOW_TGT_BASED, True),
38 ("allow_renewable", KRB5_KDB_DISALLOW_RENEWABLE, True),
39 ("allow_proxiable", KRB5_KDB_DISALLOW_PROXIABLE, True),
40 ("allow_dup_skey", KRB5_KDB_DISALLOW_DUP_SKEY, True),
41 ("allow_tix", KRB5_KDB_DISALLOW_ALL_TIX, True),
42 ("requires_preauth", KRB5_KDB_REQUIRES_PRE_AUTH, False),
43 ("requires_hwauth", KRB5_KDB_REQUIRES_HW_AUTH, False),
44 ("needchange", KRB5_KDB_REQUIRES_PWCHANGE, False),
45 ("allow_svr", KRB5_KDB_DISALLOW_SVR, True),
46 ("password_changing_service", KRB5_KDB_PWCHANGE_SERVICE, False),
47 ("support_desmd5", KRB5_KDB_SUPPORT_DESMD5, False),
48 ("ok_as_delegate", KRB5_KDB_OK_AS_DELEGATE, False),
49 ("ok_to_auth_as_delegate", KRB5_KDB_OK_TO_AUTH_AS_DELEGATE, False),
50 ("no_auth_data_required", KRB5_KDB_NO_AUTH_DATA_REQUIRED, False),
51 ("lockdown_keys", KRB5_KDB_LOCKDOWN_KEYS, False),
54 # Input forms from lib/kadm5/str_conv.c
56 ("postdateable", KRB5_KDB_DISALLOW_POSTDATED, True),
57 ("forwardable", KRB5_KDB_DISALLOW_FORWARDABLE, True),
58 ("tgt-based", KRB5_KDB_DISALLOW_TGT_BASED, True),
59 ("renewable", KRB5_KDB_DISALLOW_RENEWABLE, True),
60 ("proxiable", KRB5_KDB_DISALLOW_PROXIABLE, True),
61 ("dup-skey", KRB5_KDB_DISALLOW_DUP_SKEY, True),
62 ("allow-tickets", KRB5_KDB_DISALLOW_ALL_TIX, True),
63 ("preauth", KRB5_KDB_REQUIRES_PRE_AUTH, False),
64 ("hwauth", KRB5_KDB_REQUIRES_HW_AUTH, False),
65 ("ok-as-delegate", KRB5_KDB_OK_AS_DELEGATE, False),
66 ("pwchange", KRB5_KDB_REQUIRES_PWCHANGE, False),
67 ("service", KRB5_KDB_DISALLOW_SVR, True),
68 ("pwservice", KRB5_KDB_PWCHANGE_SERVICE, False),
69 ("md5", KRB5_KDB_SUPPORT_DESMD5, False),
70 ("ok-to-auth-as-delegate", KRB5_KDB_OK_TO_AUTH_AS_DELEGATE, False),
71 ("no-auth-data-required", KRB5_KDB_NO_AUTH_DATA_REQUIRED, False),
72 ("lockdown-keys", KRB5_KDB_LOCKDOWN_KEYS, False),
77 _prefixlen = len(_prefix)
79 # Names of flags, as printed by kadmin (derived from kdb.h symbols).
80 # To be filled in by _setup_tables().
83 # Translation table to map hyphens to underscores
84 _squash = string.maketrans('-', '_')
86 # Combined input-to-flag lookup table, to be filled in by
90 # Tables of ftuples, to be filled in by _setup_tables()
96 # Inverted table to look up ftuples by flag value, to be filled in by
103 # Bundle some methods that are useful for writing tests.
104 class Ftuple(object):
105 def __init__(self, name, flag, invert):
111 return "Ftuple" + str((self.name, self.flag, self.invert))
114 return _flagnames[self.flag]
117 return ('-' if self.invert else '+') + self.name
120 return ('+' if self.invert else '-') + self.name
122 def spec(self, doset):
123 return self.setspec() if doset else self.clearspec()
127 # Filter globals for 'KRB5_KDB_' prefix to create lookup tables.
128 # Make the reasonable assumption that the Python runtime doesn't
129 # define any names with that prefix by default.
131 for k, v in globals().items():
132 if k.startswith(_prefix):
133 _flagnames[v] = k[_prefixlen:]
135 # Construct an input table based on kdb.h constant names by
136 # truncating the "KRB5_KDB_" prefix and downcasing.
138 for v, k in sorted(_flagnames.items()):
139 sym_pflags.append((k.lower(), v, False))
141 global kadmin_ftuples, strconv_ftuples, sym_ftuples, all_ftuples
142 for x in _kadmin_pflags:
143 kadmin_ftuples.append(Ftuple(*x))
144 for x in _strconv_pflags:
145 strconv_ftuples.append(Ftuple(*x))
147 sym_ftuples.append(Ftuple(*x))
148 all_ftuples = kadmin_ftuples + strconv_ftuples + sym_ftuples
150 # Populate combined input-to-flag lookup table. This will
151 # eliminate some duplicates.
153 for x in all_ftuples:
154 name = x.name.translate(_squash)
157 global kadmin_itable, strconv_itable, sym_itable
158 for x in kadmin_ftuples:
159 kadmin_itable[x.flag] = x
160 for x in strconv_ftuples:
161 strconv_itable[x.flag] = x
162 for x in sym_ftuples:
163 sym_itable[x.flag] = x
166 # Convert the bit number of a flag to a string. Remove the
167 # 'KRB5_KDB_' prefix. Give an 8-digit hexadecimal number if the flag
170 s = _flagnames.get(1 << n)
172 return "0x%08x" % ((1 << n) & 0xffffffff)
176 # Return a list of flag names from a flag word.
177 def flags2namelist(flags):
181 a.append(flagnum2str(n))
185 # Given a single specifier in the form {+|-}flagname, return a tuple
186 # of the form (flagstoset, flagstoclear).
187 def flagspec2mask(s):
195 s = s.lower().translate(_squash)
198 flag, invert = x.flag, x.invert
200 # Maybe it's a hex number.
201 if not s.startswith('0x'):
203 flag, invert = int(s, 16), False
207 return (0, ~flag) if invert else (flag, ~0)
210 # Given a string containing a space/comma separated list of specifiers
211 # of the form {+|-}flagname, return a tuple of the form (flagstoset,
212 # flagstoclear). This shares the same limitation as
213 # kadm5int_acl_parse_restrictions() of losing the distinction between
214 # orderings when the same flag bit appears in both the positive and
215 # the negative sense.
216 def speclist2mask(s):
217 toset, toclear = (0, ~0)
218 for x in re.split('[\t, ]+', s):
219 fset, fclear = flagspec2mask(x)
223 return toset, toclear
226 # Print C table of input flag specifiers for lib/kadm5/str_conv.c.
228 print 'static const struct flag_table_row ftbl[] = {'
229 a = sorted(pflags.items(), key=lambda (k, v): (v.flag, -v.invert, k))
232 s2 = '%-31s KRB5_KDB_%s,' % (s1, v.flagname())
233 print '%-63s %d},' % (s2, 1 if v.invert else 0)
236 print '#define NFTBL (sizeof(ftbl) / sizeof(ftbl[0]))'
239 # Print C table of output flag names for lib/kadm5/str_conv.c.
240 def _print_outflags():
241 print 'static const char *outflags[] = {'
244 if flag > max(_flagnames.keys()):
247 s = ' "%s",' % _flagnames[flag]
250 print '%-32s/* 0x%08x */' % (s, flag)
253 print '#define NOUTFLAGS (sizeof(outflags) / sizeof(outflags[0]))'
256 # Print out C tables to insert into lib/kadm5/str_conv.c.
266 if __name__ == '__main__':