|
Packit |
fd8b60 |
import re
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Module for translating KDB principal flags between string and
|
|
Packit |
fd8b60 |
# integer forms.
|
|
Packit |
fd8b60 |
#
|
|
Packit |
fd8b60 |
# When run as a standalone script, print out C tables to insert into
|
|
Packit |
fd8b60 |
# lib/kadm5/str_conv.c.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# KDB principal flag definitions copied from kdb.h
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
KRB5_KDB_DISALLOW_POSTDATED = 0x00000001
|
|
Packit |
fd8b60 |
KRB5_KDB_DISALLOW_FORWARDABLE = 0x00000002
|
|
Packit |
fd8b60 |
KRB5_KDB_DISALLOW_TGT_BASED = 0x00000004
|
|
Packit |
fd8b60 |
KRB5_KDB_DISALLOW_RENEWABLE = 0x00000008
|
|
Packit |
fd8b60 |
KRB5_KDB_DISALLOW_PROXIABLE = 0x00000010
|
|
Packit |
fd8b60 |
KRB5_KDB_DISALLOW_DUP_SKEY = 0x00000020
|
|
Packit |
fd8b60 |
KRB5_KDB_DISALLOW_ALL_TIX = 0x00000040
|
|
Packit |
fd8b60 |
KRB5_KDB_REQUIRES_PRE_AUTH = 0x00000080
|
|
Packit |
fd8b60 |
KRB5_KDB_REQUIRES_HW_AUTH = 0x00000100
|
|
Packit |
fd8b60 |
KRB5_KDB_REQUIRES_PWCHANGE = 0x00000200
|
|
Packit |
fd8b60 |
KRB5_KDB_DISALLOW_SVR = 0x00001000
|
|
Packit |
fd8b60 |
KRB5_KDB_PWCHANGE_SERVICE = 0x00002000
|
|
Packit |
fd8b60 |
KRB5_KDB_SUPPORT_DESMD5 = 0x00004000
|
|
Packit |
fd8b60 |
KRB5_KDB_NEW_PRINC = 0x00008000
|
|
Packit |
fd8b60 |
KRB5_KDB_OK_AS_DELEGATE = 0x00100000
|
|
Packit |
fd8b60 |
KRB5_KDB_OK_TO_AUTH_AS_DELEGATE = 0x00200000
|
|
Packit |
fd8b60 |
KRB5_KDB_NO_AUTH_DATA_REQUIRED = 0x00400000
|
|
Packit |
fd8b60 |
KRB5_KDB_LOCKDOWN_KEYS = 0x00800000
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Input tables -- list of tuples of the form (name, flag, invert)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Input forms from kadmin.c
|
|
Packit |
fd8b60 |
_kadmin_pflags = [
|
|
Packit |
fd8b60 |
("allow_postdated", KRB5_KDB_DISALLOW_POSTDATED, True),
|
|
Packit |
fd8b60 |
("allow_forwardable", KRB5_KDB_DISALLOW_FORWARDABLE, True),
|
|
Packit |
fd8b60 |
("allow_tgs_req", KRB5_KDB_DISALLOW_TGT_BASED, True),
|
|
Packit |
fd8b60 |
("allow_renewable", KRB5_KDB_DISALLOW_RENEWABLE, True),
|
|
Packit |
fd8b60 |
("allow_proxiable", KRB5_KDB_DISALLOW_PROXIABLE, True),
|
|
Packit |
fd8b60 |
("allow_dup_skey", KRB5_KDB_DISALLOW_DUP_SKEY, True),
|
|
Packit |
fd8b60 |
("allow_tix", KRB5_KDB_DISALLOW_ALL_TIX, True),
|
|
Packit |
fd8b60 |
("requires_preauth", KRB5_KDB_REQUIRES_PRE_AUTH, False),
|
|
Packit |
fd8b60 |
("requires_hwauth", KRB5_KDB_REQUIRES_HW_AUTH, False),
|
|
Packit |
fd8b60 |
("needchange", KRB5_KDB_REQUIRES_PWCHANGE, False),
|
|
Packit |
fd8b60 |
("allow_svr", KRB5_KDB_DISALLOW_SVR, True),
|
|
Packit |
fd8b60 |
("password_changing_service", KRB5_KDB_PWCHANGE_SERVICE, False),
|
|
Packit |
fd8b60 |
("support_desmd5", KRB5_KDB_SUPPORT_DESMD5, False),
|
|
Packit |
fd8b60 |
("ok_as_delegate", KRB5_KDB_OK_AS_DELEGATE, False),
|
|
Packit |
fd8b60 |
("ok_to_auth_as_delegate", KRB5_KDB_OK_TO_AUTH_AS_DELEGATE, False),
|
|
Packit |
fd8b60 |
("no_auth_data_required", KRB5_KDB_NO_AUTH_DATA_REQUIRED, False),
|
|
Packit |
fd8b60 |
("lockdown_keys", KRB5_KDB_LOCKDOWN_KEYS, False),
|
|
Packit |
fd8b60 |
]
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Input forms from lib/kadm5/str_conv.c
|
|
Packit |
fd8b60 |
_strconv_pflags = [
|
|
Packit |
fd8b60 |
("postdateable", KRB5_KDB_DISALLOW_POSTDATED, True),
|
|
Packit |
fd8b60 |
("forwardable", KRB5_KDB_DISALLOW_FORWARDABLE, True),
|
|
Packit |
fd8b60 |
("tgt-based", KRB5_KDB_DISALLOW_TGT_BASED, True),
|
|
Packit |
fd8b60 |
("renewable", KRB5_KDB_DISALLOW_RENEWABLE, True),
|
|
Packit |
fd8b60 |
("proxiable", KRB5_KDB_DISALLOW_PROXIABLE, True),
|
|
Packit |
fd8b60 |
("dup-skey", KRB5_KDB_DISALLOW_DUP_SKEY, True),
|
|
Packit |
fd8b60 |
("allow-tickets", KRB5_KDB_DISALLOW_ALL_TIX, True),
|
|
Packit |
fd8b60 |
("preauth", KRB5_KDB_REQUIRES_PRE_AUTH, False),
|
|
Packit |
fd8b60 |
("hwauth", KRB5_KDB_REQUIRES_HW_AUTH, False),
|
|
Packit |
fd8b60 |
("ok-as-delegate", KRB5_KDB_OK_AS_DELEGATE, False),
|
|
Packit |
fd8b60 |
("pwchange", KRB5_KDB_REQUIRES_PWCHANGE, False),
|
|
Packit |
fd8b60 |
("service", KRB5_KDB_DISALLOW_SVR, True),
|
|
Packit |
fd8b60 |
("pwservice", KRB5_KDB_PWCHANGE_SERVICE, False),
|
|
Packit |
fd8b60 |
("md5", KRB5_KDB_SUPPORT_DESMD5, False),
|
|
Packit |
fd8b60 |
("ok-to-auth-as-delegate", KRB5_KDB_OK_TO_AUTH_AS_DELEGATE, False),
|
|
Packit |
fd8b60 |
("no-auth-data-required", KRB5_KDB_NO_AUTH_DATA_REQUIRED, False),
|
|
Packit |
fd8b60 |
("lockdown-keys", KRB5_KDB_LOCKDOWN_KEYS, False),
|
|
Packit |
fd8b60 |
]
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# kdb.h symbol prefix
|
|
Packit |
fd8b60 |
_prefix = 'KRB5_KDB_'
|
|
Packit |
fd8b60 |
_prefixlen = len(_prefix)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Names of flags, as printed by kadmin (derived from kdb.h symbols).
|
|
Packit |
fd8b60 |
# To be filled in by _setup_tables().
|
|
Packit |
fd8b60 |
_flagnames = {}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Translation table to map hyphens to underscores
|
|
Packit |
fd8b60 |
_squash = str.maketrans('-', '_')
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Combined input-to-flag lookup table, to be filled in by
|
|
Packit |
fd8b60 |
# _setup_tables()
|
|
Packit |
fd8b60 |
pflags = {}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Tables of ftuples, to be filled in by _setup_tables()
|
|
Packit |
fd8b60 |
kadmin_ftuples = []
|
|
Packit |
fd8b60 |
strconv_ftuples = []
|
|
Packit |
fd8b60 |
sym_ftuples = []
|
|
Packit |
fd8b60 |
all_ftuples = []
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Inverted table to look up ftuples by flag value, to be filled in by
|
|
Packit |
fd8b60 |
# _setup_tables()
|
|
Packit |
fd8b60 |
kadmin_itable = {}
|
|
Packit |
fd8b60 |
strconv_itable = {}
|
|
Packit |
fd8b60 |
sym_itable = {}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Bundle some methods that are useful for writing tests.
|
|
Packit |
fd8b60 |
class Ftuple(object):
|
|
Packit |
fd8b60 |
def __init__(self, name, flag, invert):
|
|
Packit |
fd8b60 |
self.name = name
|
|
Packit |
fd8b60 |
self.flag = flag
|
|
Packit |
fd8b60 |
self.invert = invert
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def __repr__(self):
|
|
Packit |
fd8b60 |
return "Ftuple" + str((self.name, self.flag, self.invert))
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def flagname(self):
|
|
Packit |
fd8b60 |
return _flagnames[self.flag]
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def setspec(self):
|
|
Packit |
fd8b60 |
return ('-' if self.invert else '+') + self.name
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def clearspec(self):
|
|
Packit |
fd8b60 |
return ('+' if self.invert else '-') + self.name
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def spec(self, doset):
|
|
Packit |
fd8b60 |
return self.setspec() if doset else self.clearspec()
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _setup_tables():
|
|
Packit |
fd8b60 |
# Filter globals for 'KRB5_KDB_' prefix to create lookup tables.
|
|
Packit |
fd8b60 |
# Make the reasonable assumption that the Python runtime doesn't
|
|
Packit |
fd8b60 |
# define any names with that prefix by default.
|
|
Packit |
fd8b60 |
global _flagnames
|
|
Packit |
fd8b60 |
for k, v in globals().items():
|
|
Packit |
fd8b60 |
if k.startswith(_prefix):
|
|
Packit |
fd8b60 |
_flagnames[v] = k[_prefixlen:]
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Construct an input table based on kdb.h constant names by
|
|
Packit |
fd8b60 |
# truncating the "KRB5_KDB_" prefix and downcasing.
|
|
Packit |
fd8b60 |
sym_pflags = []
|
|
Packit |
fd8b60 |
for v, k in sorted(_flagnames.items()):
|
|
Packit |
fd8b60 |
sym_pflags.append((k.lower(), v, False))
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
global kadmin_ftuples, strconv_ftuples, sym_ftuples, all_ftuples
|
|
Packit |
fd8b60 |
for x in _kadmin_pflags:
|
|
Packit |
fd8b60 |
kadmin_ftuples.append(Ftuple(*x))
|
|
Packit |
fd8b60 |
for x in _strconv_pflags:
|
|
Packit |
fd8b60 |
strconv_ftuples.append(Ftuple(*x))
|
|
Packit |
fd8b60 |
for x in sym_pflags:
|
|
Packit |
fd8b60 |
sym_ftuples.append(Ftuple(*x))
|
|
Packit |
fd8b60 |
all_ftuples = kadmin_ftuples + strconv_ftuples + sym_ftuples
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Populate combined input-to-flag lookup table. This will
|
|
Packit |
fd8b60 |
# eliminate some duplicates.
|
|
Packit |
fd8b60 |
global pflags
|
|
Packit |
fd8b60 |
for x in all_ftuples:
|
|
Packit |
fd8b60 |
name = x.name.translate(_squash)
|
|
Packit |
fd8b60 |
pflags[name] = x
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
global kadmin_itable, strconv_itable, sym_itable
|
|
Packit |
fd8b60 |
for x in kadmin_ftuples:
|
|
Packit |
fd8b60 |
kadmin_itable[x.flag] = x
|
|
Packit |
fd8b60 |
for x in strconv_ftuples:
|
|
Packit |
fd8b60 |
strconv_itable[x.flag] = x
|
|
Packit |
fd8b60 |
for x in sym_ftuples:
|
|
Packit |
fd8b60 |
sym_itable[x.flag] = x
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Convert the bit number of a flag to a string. Remove the
|
|
Packit |
fd8b60 |
# 'KRB5_KDB_' prefix. Give an 8-digit hexadecimal number if the flag
|
|
Packit |
fd8b60 |
# is unknown.
|
|
Packit |
fd8b60 |
def flagnum2str(n):
|
|
Packit |
fd8b60 |
s = _flagnames.get(1 << n)
|
|
Packit |
fd8b60 |
if s is None:
|
|
Packit |
fd8b60 |
return "0x%08x" % ((1 << n) & 0xffffffff)
|
|
Packit |
fd8b60 |
return s
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Return a list of flag names from a flag word.
|
|
Packit |
fd8b60 |
def flags2namelist(flags):
|
|
Packit |
fd8b60 |
a = []
|
|
Packit |
fd8b60 |
for n in range(32):
|
|
Packit |
fd8b60 |
if flags & (1 << n):
|
|
Packit |
fd8b60 |
a.append(flagnum2str(n))
|
|
Packit |
fd8b60 |
return a
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Given a single specifier in the form {+|-}flagname, return a tuple
|
|
Packit |
fd8b60 |
# of the form (flagstoset, flagstoclear).
|
|
Packit |
fd8b60 |
def flagspec2mask(s):
|
|
Packit |
fd8b60 |
req_neg = False
|
|
Packit |
fd8b60 |
if s[0] == '-':
|
|
Packit |
fd8b60 |
req_neg = True
|
|
Packit |
fd8b60 |
s = s[1:]
|
|
Packit |
fd8b60 |
elif s[0] == '+':
|
|
Packit |
fd8b60 |
s = s[1:]
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
s = s.lower().translate(_squash)
|
|
Packit |
fd8b60 |
x = pflags.get(s)
|
|
Packit |
fd8b60 |
if x is not None:
|
|
Packit |
fd8b60 |
flag, invert = x.flag, x.invert
|
|
Packit |
fd8b60 |
else:
|
|
Packit |
fd8b60 |
# Maybe it's a hex number.
|
|
Packit |
fd8b60 |
if not s.startswith('0x'):
|
|
Packit |
fd8b60 |
raise ValueError
|
|
Packit |
fd8b60 |
flag, invert = int(s, 16), False
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if req_neg:
|
|
Packit |
fd8b60 |
invert = not invert
|
|
Packit |
fd8b60 |
return (0, ~flag) if invert else (flag, ~0)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Given a string containing a space/comma separated list of specifiers
|
|
Packit |
fd8b60 |
# of the form {+|-}flagname, return a tuple of the form (flagstoset,
|
|
Packit |
fd8b60 |
# flagstoclear). This shares the same limitation as
|
|
Packit |
fd8b60 |
# kadm5int_acl_parse_restrictions() of losing the distinction between
|
|
Packit |
fd8b60 |
# orderings when the same flag bit appears in both the positive and
|
|
Packit |
fd8b60 |
# the negative sense.
|
|
Packit |
fd8b60 |
def speclist2mask(s):
|
|
Packit |
fd8b60 |
toset, toclear = (0, ~0)
|
|
Packit |
fd8b60 |
for x in re.split('[\t, ]+', s):
|
|
Packit |
fd8b60 |
fset, fclear = flagspec2mask(x)
|
|
Packit |
fd8b60 |
toset |= fset
|
|
Packit |
fd8b60 |
toclear &= fclear
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return toset, toclear
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Print C table of input flag specifiers for lib/kadm5/str_conv.c.
|
|
Packit |
fd8b60 |
def _print_ftbl():
|
|
Packit |
fd8b60 |
print('static const struct flag_table_row ftbl[] = {')
|
|
Packit |
fd8b60 |
a = sorted(pflags.items(), key=lambda k, v: (v.flag, -v.invert, k))
|
|
Packit |
fd8b60 |
for k, v in a:
|
|
Packit |
fd8b60 |
s1 = ' {"%s",' % k
|
|
Packit |
fd8b60 |
s2 = '%-31s KRB5_KDB_%s,' % (s1, v.flagname())
|
|
Packit |
fd8b60 |
print('%-63s %d},' % (s2, 1 if v.invert else 0))
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
print('};')
|
|
Packit |
fd8b60 |
print('#define NFTBL (sizeof(ftbl) / sizeof(ftbl[0]))')
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Print C table of output flag names for lib/kadm5/str_conv.c.
|
|
Packit |
fd8b60 |
def _print_outflags():
|
|
Packit |
fd8b60 |
print('static const char *outflags[] = {')
|
|
Packit |
fd8b60 |
for i in range(32):
|
|
Packit |
fd8b60 |
flag = 1 << i
|
|
Packit |
fd8b60 |
if flag > max(_flagnames.keys()):
|
|
Packit |
fd8b60 |
break
|
|
Packit |
fd8b60 |
try:
|
|
Packit |
fd8b60 |
s = ' "%s",' % _flagnames[flag]
|
|
Packit |
fd8b60 |
except KeyError:
|
|
Packit |
fd8b60 |
s = ' NULL,'
|
|
Packit |
fd8b60 |
print('%-32s/* 0x%08x */' % (s, flag))
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
print('};')
|
|
Packit |
fd8b60 |
print('#define NOUTFLAGS (sizeof(outflags) / sizeof(outflags[0]))')
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Print out C tables to insert into lib/kadm5/str_conv.c.
|
|
Packit |
fd8b60 |
def _main():
|
|
Packit |
fd8b60 |
_print_ftbl()
|
|
Packit |
fd8b60 |
print
|
|
Packit |
fd8b60 |
_print_outflags()
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
_setup_tables()
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if __name__ == '__main__':
|
|
Packit |
fd8b60 |
_main()
|