1from k5test import * 2import os 3 4realm = K5Realm(create_host=False, create_user=False) 5 6def make_client(name): 7 global realm 8 realm.addprinc(name, password(name)) 9 ccache = os.path.join(realm.testdir, 10 'kadmin_ccache_' + name.replace('/', '_')) 11 realm.kinit(name, password(name), 12 flags=['-S', 'kadmin/admin', '-c', ccache]) 13 return ccache 14 15def kadmin_as(client, query, **kwargs): 16 global realm 17 return realm.run([kadmin, '-c', client] + query, **kwargs) 18 19all_add = make_client('all_add') 20all_changepw = make_client('all_changepw') 21all_delete = make_client('all_delete') 22all_inquire = make_client('all_inquire') 23all_list = make_client('all_list') 24all_modify = make_client('all_modify') 25all_rename = make_client('all_rename') 26all_wildcard = make_client('all_wildcard') 27all_extract = make_client('all_extract') 28some_add = make_client('some_add') 29some_changepw = make_client('some_changepw') 30some_delete = make_client('some_delete') 31some_inquire = make_client('some_inquire') 32some_modify = make_client('some_modify') 33some_rename = make_client('some_rename') 34restricted_add = make_client('restricted_add') 35restricted_modify = make_client('restricted_modify') 36restricted_rename = make_client('restricted_rename') 37wctarget = make_client('wctarget') 38admin = make_client('user/admin') 39none = make_client('none') 40restrictions = make_client('restrictions') 41onetwothreefour = make_client('one/two/three/four') 42 43realm.run([kadminl, 'addpol', '-minlife', '1 day', 'minlife']) 44 45f = open(os.path.join(realm.testdir, 'acl'), 'w') 46f.write(''' 47all_add a 48all_changepw c 49all_delete d 50all_inquire i 51all_list l 52all_modify im 53all_rename ad 54all_wildcard x 55all_extract ie 56some_add a selected 57some_changepw c selected 58some_delete d selected 59some_inquire i selected 60some_modify im selected 61some_rename d from 62some_rename a to 63restricted_add a * +preauth 64restricted_modify im * +preauth 65restricted_rename ad * +preauth 66 67*/* d *2/*1 68# The next line is a regression test for #8154; it is not used directly. 69one/*/*/five l 70*/two/*/* d *3/*1/*2 71*/admin a 72wctarget a wild/* 73restrictions a type1 -policy minlife 74restrictions a type2 -clearpolicy 75restrictions a type3 -maxlife 1h -maxrenewlife 2h 76''') 77f.close() 78 79realm.start_kadmind() 80 81# cpw can generate four different RPC calls depending on options. 82realm.addprinc('selected', 'oldpw') 83realm.addprinc('unselected', 'oldpw') 84for pw in (['-pw', 'newpw'], ['-randkey']): 85 for ks in ([], ['-e', 'aes256-cts']): 86 mark('cpw: %s %s' % (repr(pw), repr(ks))) 87 args = pw + ks 88 kadmin_as(all_changepw, ['cpw'] + args + ['unselected']) 89 kadmin_as(some_changepw, ['cpw'] + args + ['selected']) 90 msg = "Operation requires ``change-password'' privilege" 91 kadmin_as(none, ['cpw'] + args + ['selected'], expected_code=1, 92 expected_msg=msg) 93 kadmin_as(some_changepw, ['cpw'] + args + ['unselected'], 94 expected_code=1, expected_msg=msg) 95 kadmin_as(none, ['cpw'] + args + ['none']) 96 realm.run([kadminl, 'modprinc', '-policy', 'minlife', 'none']) 97 msg = "Current password's minimum life has not expired" 98 kadmin_as(none, ['cpw'] + args + ['none'], expected_code=1, 99 expected_msg=msg) 100 realm.run([kadminl, 'modprinc', '-clearpolicy', 'none']) 101realm.run([kadminl, 'delprinc', 'selected']) 102realm.run([kadminl, 'delprinc', 'unselected']) 103 104mark('addpol') 105kadmin_as(all_add, ['addpol', 'policy']) 106realm.run([kadminl, 'delpol', 'policy']) 107kadmin_as(none, ['addpol', 'policy'], expected_code=1, 108 expected_msg="Operation requires ``add'' privilege") 109 110# addprinc can generate two different RPC calls depending on options. 111for ks in ([], ['-e', 'aes256-cts']): 112 mark('addprinc: %s' % repr(ks)) 113 args = ['-pw', 'pw'] + ks 114 kadmin_as(all_add, ['addprinc'] + args + ['unselected']) 115 realm.run([kadminl, 'delprinc', 'unselected']) 116 kadmin_as(some_add, ['addprinc'] + args + ['selected']) 117 realm.run([kadminl, 'delprinc', 'selected']) 118 kadmin_as(restricted_add, ['addprinc'] + args + ['unselected']) 119 realm.run([kadminl, 'getprinc', 'unselected'], 120 expected_msg='REQUIRES_PRE_AUTH') 121 realm.run([kadminl, 'delprinc', 'unselected']) 122 kadmin_as(none, ['addprinc'] + args + ['selected'], expected_code=1, 123 expected_msg="Operation requires ``add'' privilege") 124 kadmin_as(some_add, ['addprinc'] + args + ['unselected'], expected_code=1, 125 expected_msg="Operation requires ``add'' privilege") 126 127mark('delprinc') 128realm.addprinc('unselected', 'pw') 129kadmin_as(all_delete, ['delprinc', 'unselected']) 130realm.addprinc('selected', 'pw') 131kadmin_as(some_delete, ['delprinc', 'selected']) 132realm.addprinc('unselected', 'pw') 133kadmin_as(none, ['delprinc', 'unselected'], expected_code=1, 134 expected_msg="Operation requires ``delete'' privilege") 135kadmin_as(some_delete, ['delprinc', 'unselected'], expected_code=1, 136 expected_msg="Operation requires ``delete'' privilege") 137realm.run([kadminl, 'delprinc', 'unselected']) 138 139mark('getpol') 140kadmin_as(all_inquire, ['getpol', 'minlife'], expected_msg='Policy: minlife') 141kadmin_as(none, ['getpol', 'minlife'], expected_code=1, 142 expected_msg="Operation requires ``get'' privilege") 143realm.run([kadminl, 'modprinc', '-policy', 'minlife', 'none']) 144kadmin_as(none, ['getpol', 'minlife'], expected_msg='Policy: minlife') 145realm.run([kadminl, 'modprinc', '-clearpolicy', 'none']) 146 147mark('getprinc') 148realm.addprinc('selected', 'pw') 149realm.addprinc('unselected', 'pw') 150kadmin_as(all_inquire, ['getprinc', 'unselected'], 151 expected_msg='Principal: unselected@KRBTEST.COM') 152kadmin_as(some_inquire, ['getprinc', 'selected'], 153 expected_msg='Principal: selected@KRBTEST.COM') 154kadmin_as(none, ['getprinc', 'selected'], expected_code=1, 155 expected_msg="Operation requires ``get'' privilege") 156kadmin_as(some_inquire, ['getprinc', 'unselected'], expected_code=1, 157 expected_msg="Operation requires ``get'' privilege") 158kadmin_as(none, ['getprinc', 'none'], 159 expected_msg='Principal: none@KRBTEST.COM') 160realm.run([kadminl, 'delprinc', 'selected']) 161realm.run([kadminl, 'delprinc', 'unselected']) 162 163mark('listprincs') 164kadmin_as(all_list, ['listprincs'], expected_msg='K/M@KRBTEST.COM') 165kadmin_as(none, ['listprincs'], expected_code=1, 166 expected_msg="Operation requires ``list'' privilege") 167 168mark('getstrs') 169realm.addprinc('selected', 'pw') 170realm.addprinc('unselected', 'pw') 171realm.run([kadminl, 'setstr', 'selected', 'key', 'value']) 172realm.run([kadminl, 'setstr', 'unselected', 'key', 'value']) 173kadmin_as(all_inquire, ['getstrs', 'unselected'], expected_msg='key: value') 174kadmin_as(some_inquire, ['getstrs', 'selected'], expected_msg='key: value') 175kadmin_as(none, ['getstrs', 'selected'], expected_code=1, 176 expected_msg="Operation requires ``get'' privilege") 177kadmin_as(some_inquire, ['getstrs', 'unselected'], expected_code=1, 178 expected_msg="Operation requires ``get'' privilege") 179kadmin_as(none, ['getstrs', 'none'], expected_msg='(No string attributes.)') 180realm.run([kadminl, 'delprinc', 'selected']) 181realm.run([kadminl, 'delprinc', 'unselected']) 182 183mark('modpol') 184out = kadmin_as(all_modify, ['modpol', '-maxlife', '1 hour', 'policy'], 185 expected_code=1) 186if 'Operation requires' in out: 187 fail('modpol success (acl)') 188kadmin_as(none, ['modpol', '-maxlife', '1 hour', 'policy'], expected_code=1, 189 expected_msg="Operation requires ``modify'' privilege") 190 191mark('modprinc') 192realm.addprinc('selected', 'pw') 193realm.addprinc('unselected', 'pw') 194kadmin_as(all_modify, ['modprinc', '-maxlife', '1 hour', 'unselected']) 195kadmin_as(some_modify, ['modprinc', '-maxlife', '1 hour', 'selected']) 196kadmin_as(restricted_modify, ['modprinc', '-maxlife', '1 hour', 'unselected']) 197realm.run([kadminl, 'getprinc', 'unselected'], 198 expected_msg='REQUIRES_PRE_AUTH') 199kadmin_as(all_inquire, ['modprinc', '-maxlife', '1 hour', 'selected'], 200 expected_code=1, 201 expected_msg="Operation requires ``modify'' privilege") 202kadmin_as(some_modify, ['modprinc', '-maxlife', '1 hour', 'unselected'], 203 expected_code=1, expected_msg='Operation requires') 204realm.run([kadminl, 'delprinc', 'selected']) 205realm.run([kadminl, 'delprinc', 'unselected']) 206 207mark('purgekeys') 208realm.addprinc('selected', 'pw') 209realm.addprinc('unselected', 'pw') 210kadmin_as(all_modify, ['purgekeys', 'unselected']) 211kadmin_as(some_modify, ['purgekeys', 'selected']) 212kadmin_as(none, ['purgekeys', 'selected'], expected_code=1, 213 expected_msg="Operation requires ``modify'' privilege") 214kadmin_as(some_modify, ['purgekeys', 'unselected'], expected_code=1, 215 expected_msg="Operation requires ``modify'' privilege") 216kadmin_as(none, ['purgekeys', 'none']) 217realm.run([kadminl, 'delprinc', 'selected']) 218realm.run([kadminl, 'delprinc', 'unselected']) 219 220mark('renprinc') 221realm.addprinc('from', 'pw') 222kadmin_as(all_rename, ['renprinc', 'from', 'to']) 223realm.run([kadminl, 'renprinc', 'to', 'from']) 224kadmin_as(some_rename, ['renprinc', 'from', 'to']) 225realm.run([kadminl, 'renprinc', 'to', 'from']) 226kadmin_as(all_add, ['renprinc', 'from', 'to'], expected_code=1, 227 expected_msg="Insufficient authorization for operation") 228kadmin_as(all_delete, ['renprinc', 'from', 'to'], expected_code=1, 229 expected_msg="Insufficient authorization for operation") 230kadmin_as(some_rename, ['renprinc', 'from', 'notto'], expected_code=1, 231 expected_msg="Insufficient authorization for operation") 232realm.run([kadminl, 'renprinc', 'from', 'notfrom']) 233kadmin_as(some_rename, ['renprinc', 'notfrom', 'to'], expected_code=1, 234 expected_msg="Insufficient authorization for operation") 235kadmin_as(restricted_rename, ['renprinc', 'notfrom', 'to'], expected_code=1, 236 expected_msg="Insufficient authorization for operation") 237realm.run([kadminl, 'delprinc', 'notfrom']) 238 239mark('setstr') 240realm.addprinc('selected', 'pw') 241realm.addprinc('unselected', 'pw') 242kadmin_as(all_modify, ['setstr', 'unselected', 'key', 'value']) 243kadmin_as(some_modify, ['setstr', 'selected', 'key', 'value']) 244kadmin_as(none, ['setstr', 'selected', 'key', 'value'], expected_code=1, 245 expected_msg="Operation requires ``modify'' privilege") 246kadmin_as(some_modify, ['setstr', 'unselected', 'key', 'value'], 247 expected_code=1, expected_msg='Operation requires') 248realm.run([kadminl, 'delprinc', 'selected']) 249realm.run([kadminl, 'delprinc', 'unselected']) 250 251mark('addprinc/delprinc (wildcard)') 252kadmin_as(admin, ['addprinc', '-pw', 'pw', 'anytarget']) 253realm.run([kadminl, 'delprinc', 'anytarget']) 254kadmin_as(wctarget, ['addprinc', '-pw', 'pw', 'wild/card']) 255realm.run([kadminl, 'delprinc', 'wild/card']) 256kadmin_as(wctarget, ['addprinc', '-pw', 'pw', 'wild/card/extra'], 257 expected_code=1, expected_msg='Operation requires') 258realm.addprinc('admin/user', 'pw') 259kadmin_as(admin, ['delprinc', 'admin/user']) 260kadmin_as(admin, ['delprinc', 'none'], expected_code=1, 261 expected_msg='Operation requires') 262realm.addprinc('four/one/three', 'pw') 263kadmin_as(onetwothreefour, ['delprinc', 'four/one/three']) 264 265mark('addprinc (restrictions)') 266kadmin_as(restrictions, ['addprinc', '-pw', 'pw', 'type1']) 267realm.run([kadminl, 'getprinc', 'type1'], expected_msg='Policy: minlife') 268realm.run([kadminl, 'delprinc', 'type1']) 269kadmin_as(restrictions, ['addprinc', '-pw', 'pw', '-policy', 'minlife', 270 'type2']) 271realm.run([kadminl, 'getprinc', 'type2'], expected_msg='Policy: [none]') 272realm.run([kadminl, 'delprinc', 'type2']) 273kadmin_as(restrictions, ['addprinc', '-pw', 'pw', '-maxlife', '1 minute', 274 'type3']) 275out = realm.run([kadminl, 'getprinc', 'type3']) 276if ('Maximum ticket life: 0 days 00:01:00' not in out or 277 'Maximum renewable life: 0 days 02:00:00' not in out): 278 fail('restriction (maxlife low, maxrenewlife unspec)') 279realm.run([kadminl, 'delprinc', 'type3']) 280kadmin_as(restrictions, ['addprinc', '-pw', 'pw', '-maxrenewlife', '1 day', 281 'type3']) 282realm.run([kadminl, 'getprinc', 'type3'], 283 expected_msg='Maximum renewable life: 0 days 02:00:00') 284 285mark('extract') 286realm.run([kadminl, 'addprinc', '-pw', 'pw', 'extractkeys']) 287kadmin_as(all_wildcard, ['ktadd', '-norandkey', 'extractkeys'], 288 expected_code=1, 289 expected_msg="Operation requires ``extract-keys'' privilege") 290kadmin_as(all_extract, ['ktadd', '-norandkey', 'extractkeys']) 291realm.kinit('extractkeys', flags=['-k']) 292os.remove(realm.keytab) 293 294mark('lockdown_keys') 295kadmin_as(all_modify, ['modprinc', '+lockdown_keys', 'extractkeys']) 296kadmin_as(all_changepw, ['cpw', '-pw', 'newpw', 'extractkeys'], 297 expected_code=1, 298 expected_msg="Operation requires ``change-password'' privilege") 299kadmin_as(all_changepw, ['cpw', '-randkey', 'extractkeys']) 300kadmin_as(all_extract, ['ktadd', '-norandkey', 'extractkeys'], expected_code=1, 301 expected_msg="Operation requires ``extract-keys'' privilege") 302kadmin_as(all_delete, ['delprinc', 'extractkeys'], expected_code=1, 303 expected_msg="Operation requires ``delete'' privilege") 304kadmin_as(all_rename, ['renprinc', 'extractkeys', 'renamedprinc'], 305 expected_code=1, 306 expected_msg="Operation requires ``delete'' privilege") 307kadmin_as(all_modify, ['modprinc', '-lockdown_keys', 'extractkeys'], 308 expected_code=1, 309 expected_msg="Operation requires ``modify'' privilege") 310realm.run([kadminl, 'modprinc', '-lockdown_keys', 'extractkeys']) 311kadmin_as(all_extract, ['ktadd', '-norandkey', 'extractkeys']) 312realm.kinit('extractkeys', flags=['-k']) 313os.remove(realm.keytab) 314 315# Verify that self-service key changes require an initial ticket. 316mark('self-service initial ticket') 317realm.run([kadminl, 'cpw', '-pw', password('none'), 'none']) 318realm.run([kadminl, 'modprinc', '+allow_tgs_req', 'kadmin/admin']) 319realm.kinit('none', password('none')) 320realm.run([kvno, 'kadmin/admin']) 321msg = 'Operation requires initial ticket' 322realm.run([kadmin, '-c', realm.ccache, 'cpw', '-pw', 'newpw', 'none'], 323 expected_code=1, expected_msg=msg) 324realm.run([kadmin, '-c', realm.ccache, 'cpw', '-pw', 'newpw', 325 '-e', 'aes256-cts', 'none'], expected_code=1, expected_msg=msg) 326realm.run([kadmin, '-c', realm.ccache, 'cpw', '-randkey', 'none'], 327 expected_code=1, expected_msg=msg) 328realm.run([kadmin, '-c', realm.ccache, 'cpw', '-randkey', '-e', 'aes256-cts', 329 'none'], expected_code=1, expected_msg=msg) 330 331# Test authentication to kadmin/hostname. 332mark('authentication to kadmin/hostname') 333kadmin_hostname = 'kadmin/' + hostname 334realm.addprinc(kadmin_hostname) 335realm.run([kadminl, 'delprinc', 'kadmin/admin']) 336msgs = ('Getting initial credentials for user/admin@KRBTEST.COM', 337 'Setting initial creds service to kadmin/admin', 338 '/Server not found in Kerberos database', 339 'Getting initial credentials for user/admin@KRBTEST.COM', 340 'Setting initial creds service to ' + kadmin_hostname, 341 'Decrypted AS reply') 342realm.run([kadmin, '-p', 'user/admin', 'listprincs'], expected_code=1, 343 expected_msg="Operation requires ``list'' privilege", 344 input=password('user/admin'), expected_trace=msgs) 345 346# Test operations disallowed at the libkadm5 layer. 347realm.run([kadminl, 'delprinc', 'K/M'], 348 expected_code=1, expected_msg='Cannot change protected principal') 349realm.run([kadminl, 'cpw', '-pw', 'pw', 'kadmin/history'], 350 expected_code=1, expected_msg='Cannot change protected principal') 351 352success('kadmin ACL enforcement') 353