https://fedorahosted.org/freeipa/ticket/4421 -- David Kupka
From 77faaa3c7887550b493f86f90f654da8e1f42eee Mon Sep 17 00:00:00 2001 From: David Kupka <dku...@redhat.com> Date: Tue, 2 Sep 2014 16:11:55 +0200 Subject: [PATCH] Allow multiple krbprincipalnames.
Allow user to specify multiple krbprincipalnames and krbcanonicalname. User must have "IT specialist" role or "Host Administrators" privilege assigned. https://fedorahosted.org/freeipa/ticket/4421 --- ACI.txt | 4 +++- API.txt | 2 +- ipalib/plugins/host.py | 21 +++++++++++++-------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ACI.txt b/ACI.txt index 1e6bec0ece554fb2457fae0462c0c673a9b24e41..2a83af6ffba230f2d6ba5ec521652dc2312ce6d0 100644 --- a/ACI.txt +++ b/ACI.txt @@ -85,7 +85,9 @@ aci: (targetattr = "businesscategory || cn || createtimestamp || description || dn: cn=computers,cn=accounts,dc=ipa,dc=example aci: (targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Add Hosts";allow (add) groupdn = "ldap:///cn=System: Add Hosts,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=computers,cn=accounts,dc=ipa,dc=example -aci: (targetattr = "krbprincipalname")(targetfilter = "(&(!(krbprincipalname=*))(objectclass=ipahost))")(version 3.0;acl "permission:System: Add krbPrincipalName to a Host";allow (write) groupdn = "ldap:///cn=System: Add krbPrincipalName to a Host,cn=permissions,cn=pbac,dc=ipa,dc=example";) +aci: (targetattr = "krbcanonicalname")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Add krbCanonicalName to a Host";allow (write) groupdn = "ldap:///cn=System: Add krbCanonicalName to a Host,cn=permissions,cn=pbac,dc=ipa,dc=example";) +dn: cn=computers,cn=accounts,dc=ipa,dc=example +aci: (targetattr = "krbprincipalname")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Add krbPrincipalName to a Host";allow (write) groupdn = "ldap:///cn=System: Add krbPrincipalName to a Host,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=computers,cn=accounts,dc=ipa,dc=example aci: (targetattr = "enrolledby || objectclass")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Enroll a Host";allow (write) groupdn = "ldap:///cn=System: Enroll a Host,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=computers,cn=accounts,dc=ipa,dc=example diff --git a/API.txt b/API.txt index bbd0f507b2faeec0239920cdcff28fe25d618e02..ef1f70397e7685161821a98a92ea575aa6eff532 100644 --- a/API.txt +++ b/API.txt @@ -1884,7 +1884,7 @@ option: Str('description', attribute=True, autofill=False, cli_name='desc', mult option: Bool('ipakrbokasdelegate', attribute=False, autofill=False, cli_name='ok_as_delegate', multivalue=False, required=False) option: Bool('ipakrbrequirespreauth', attribute=False, autofill=False, cli_name='requires_pre_auth', multivalue=False, required=False) option: Str('ipasshpubkey', attribute=True, autofill=False, cli_name='sshpubkey', csv=True, multivalue=True, required=False) -option: Str('krbprincipalname?', attribute=True, cli_name='principalname') +option: Str('krbprincipalname?', attribute=True, cli_name='principalname', multivalue=True) option: Str('l', attribute=True, autofill=False, cli_name='locality', multivalue=False, required=False) option: Str('macaddress', attribute=True, autofill=False, cli_name='macaddress', csv=True, multivalue=True, pattern='^([a-fA-F0-9]{2}[:|\\-]?){5}[a-fA-F0-9]{2}$', required=False) option: Flag('no_members', autofill=True, default=False, exclude='webui') diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py index 570bbe56aa0a315a031051f9a895702ba7c35076..53c2b95b44063049d64e8ad96bd5e52f1e1cab48 100644 --- a/ipalib/plugins/host.py +++ b/ipalib/plugins/host.py @@ -303,16 +303,17 @@ class host(LDAPObject): # This will let it be added if the client ends up enrolling with # an administrator instead. 'ipapermright': {'write'}, - 'ipapermtargetfilter': [ - '(objectclass=ipahost)', - '(!(krbprincipalname=*))', - ], 'ipapermdefaultattr': {'krbprincipalname'}, 'replaces': [ '(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(targetfilter = "(!(krbprincipalname=*))")(targetattr = "krbprincipalname")(version 3.0;acl "permission:Add krbPrincipalName to a host"; allow (write) groupdn = "ldap:///cn=Add krbPrincipalName to a host,cn=permissions,cn=pbac,$SUFFIX";)', ], 'default_privileges': {'Host Administrators', 'Host Enrollment'}, }, + 'System: Add krbCanonicalName to a Host': { + 'ipapermright': {'write'}, + 'ipapermdefaultattr': {'krbcanonicalname'}, + 'default_privileges': {'Host Administrators'}, + }, 'System: Enroll a Host': { 'ipapermright': {'write'}, 'ipapermdefaultattr': {'objectclass', 'enrolledby'}, @@ -761,6 +762,7 @@ class host_mod(LDAPUpdate): label=_('Principal name'), doc=_('Kerberos principal name for this host'), attribute=True, + multivalue=True, ), Flag('updatedns?', doc=_('Update DNS entries'), @@ -785,11 +787,14 @@ class host_mod(LDAPUpdate): entry_attrs['l'] = entry_attrs['locality'] if 'krbprincipalname' in entry_attrs: entry_attrs_old = ldap.get_entry( - dn, ['objectclass', 'krbprincipalname'] + dn, ['objectclass', 'krbprincipalname', 'krbcanonicalname'] ) - if 'krbprincipalname' in entry_attrs_old: - msg = 'Principal name already set, it is unchangeable.' - raise errors.ACIError(info=msg) + print(entry_attrs_old) + if 'krbprincipalname' in entry_attrs_old and \ + 'krbcanonicalname' not in entry_attrs and \ + 'krbcanonicalname' not in entry_attrs_old: + msg = 'must be set when specifying multiple krbPrincipalName attributes.' + raise errors.ValidationError(name='krbCanonicalName', error=msg) obj_classes = entry_attrs_old['objectclass'] if 'krbprincipalaux' not in obj_classes: obj_classes.append('krbprincipalaux') -- 1.9.3
From bedf4efd6cd88f85d99163775e805cd2d7dd81e0 Mon Sep 17 00:00:00 2001 From: David Kupka <dku...@redhat.com> Date: Thu, 18 Sep 2014 01:53:49 -0400 Subject: [PATCH] Test: Allow multiple krbPrincipalNames Allow to add multiple krbPrincipalName. krbCanonicalName must be specified when adding second and next krbPrincipalName. Related to: https://fedorahosted.org/freeipa/ticket/4421 --- ipatests/test_xmlrpc/test_host_plugin.py | 137 ++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 1 deletion(-) diff --git a/ipatests/test_xmlrpc/test_host_plugin.py b/ipatests/test_xmlrpc/test_host_plugin.py index 7c0312bae5e9e652085aac8f1970610044504281..21e9aca80b1394281650588369dee29b53bbbf3a 100644 --- a/ipatests/test_xmlrpc/test_host_plugin.py +++ b/ipatests/test_xmlrpc/test_host_plugin.py @@ -32,7 +32,7 @@ from nose.tools import raises, assert_raises from nose.plugins.skip import SkipTest from ipatests.test_xmlrpc.xmlrpc_test import (Declarative, XMLRPC_test, fuzzy_uuid, fuzzy_digits, fuzzy_hash, fuzzy_date, fuzzy_issuer, - fuzzy_hex) + fuzzy_hex, fuzzy_string) from ipatests.test_xmlrpc import objectclasses from ipatests.test_xmlrpc.testcert import get_testcert import base64 @@ -136,6 +136,18 @@ ipv6_fromip_ptr_dn = DN(('idnsname', ipv6_fromip_ptr), revipv6zone_dn) sshpubkey = u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGAX3xAeLeaJggwTqMjxNwa6XHBUAikXPGMzEpVrlLDCZtv00djsFTBi38PkgxBJVkgRWMrcBsr/35lq7P6w8KGIwA8GI48Z0qBS2NBMJ2u9WQ2hjLN6GdMlo77O0uJY3251p12pCVIS/bHRSq8kHO2No8g7KA9fGGcagPfQH+ee3t7HUkpbQkFTmbPPN++r3V8oVUk5LxbryB3UIIVzNmcSIn3JrXynlvui4MixvrtX6zx+O/bBo68o8/eZD26QrahVbA09fivrn/4h3TM019Eu/c2jOdckfU3cHUV/3Tno5d6JicibyaoDDK7S/yjdn5jhaz8MSEayQvFkZkiF0L public key test' sshpubkeyfp = u'13:67:6B:BF:4E:A2:05:8E:AE:25:8B:A1:31:DE:6F:1B public key test (ssh-rsa)' + +# multiple krbPrincipalNames test +host5 = u'test' +fqdn5 = u'%s.%s' % (host5, api.env.domain) +dn5 = DN(('fqdn',fqdn5),('cn','computers'),('cn','accounts'),api.env.basedn) +principalname1 = u'host/%s@%s' % (fqdn5, api.env.realm) +principalname2 = u'IPA01$@%s' % api.env.realm +canonicalname = principalname1 +ipaddress = u'172.16.0.1' +it_spec_role_dn = DN(('cn',u'IT Specialist'),api.env.container_rolegroup, + api.env.basedn) + class test_host(Declarative): cleanup_commands = [ @@ -1403,3 +1415,126 @@ class test_host_dns(Declarative): ), ), ] + +class test_host_multiple_krbprincipalnames(Declarative): + cleanup_commands = [ + ('host_del', [fqdn5], {'continue': True}), + ('dnsrecord_del', [api.env.domain, host5], {'del_all': True}), + ('role_remove_member', [u'IT Specialist'], {'user': u'admin'}), + ] + + tests = [ + + # TODO: remove if admin gets 'IT Specialist' role + dict( + desc='Assign role IT Specialist to user admin', + command=('role_add_member', [u'IT Specialist'], {'user': u'admin'} + ), + expected=dict( + completed=1, + result=dict( + dn=it_spec_role_dn, + description=(u'IT Specialist',), + memberofindirect=[fuzzy_string]*28, + memberof_privilege=[fuzzy_string]*4, + member_user=[u'admin'], + cn=[u'IT Specialist'], + ), + failed=dict( + member=dict( + host=(), + group=(), + hostgroup=(), + service=(), + user=(), + ), + ), + ), + ), + + dict( + desc='Add host %s' % fqdn5, + command=('host_add', [fqdn5], {'ip_address': ipaddress, 'no_reverse': True} + ), + expected=dict( + value=fqdn5, + summary=u'Added host "%s"' % fqdn5, + result=dict( + dn=dn5, + fqdn=[fqdn5], + has_keytab=False, + has_password=False, + ipauniqueid=[fuzzy_uuid], + krbprincipalname=[principalname1], + managedby_host=[fqdn5], + objectclass=objectclasses.host, + ), + ), + ), + + dict( + desc='Add krbCanonicalName %s' % canonicalname, + command=('host_mod', [fqdn5], {'addattr': u'krbcanonicalname=%s' % canonicalname} + ), + expected=dict( + value=fqdn5, + summary=u'Modified host "%s"' % fqdn5, + result=dict( + fqdn=[fqdn5], + has_keytab=False, + has_password=False, + krbcanonicalname=[canonicalname], + krbprincipalname=[principalname1], + managedby_host=[fqdn5] + ), + ), + ), + + dict( + desc='Add kbrPrincipalName %s' % principalname2, + command=('host_mod', [fqdn5], {'addattr': u'krbprincipalname=%s' % principalname2} + ), + expected=dict( + value=fqdn5, + summary=u'Modified host "%s"' % fqdn5, + result=dict( + fqdn=[fqdn5], + has_keytab=False, + has_password=False, + krbprincipalname=[principalname1, principalname2], + managedby_host=[fqdn5] + ), + ), + ), + ] + +class test_host_fail_to_add_krbprincipalname_when_krbcanonicalname_missing(XMLRPC_test): + + # TODO: Remove when/if admin is in that group by default + def test_1_assign_role_it_specialist_to_admin(self): + """ + Add 'IT Specialist' role to admin + """ + api.Command['role_add_member'](u'IT Specialist', user=[u'admin']) + + + def test_2_create_host(self): + """ + Create host + """ + api.Command['host_add'](fqdn5, ip_address=ipaddress, no_reverse=True) + + @raises(errors.ValidationError) + def test_3_try_add_second_krbPrincipalName(self): + """ + Fail to add second krbPrincipalName without krbCanonicalName + """ + api.Command['host_mod'](fqdn5, addattr=u'krbprincipalname=%s' % principalname2) + + def test_4_cleanup(self): + """ + CLEANUP: Remove host and remove 'IT Specialist' role for admin + """ + api.Command['host_del'](fqdn5) + api.Command['dnsrecord_del'](api.env.domain, host5, del_all=True) + api.Command['role_remove_member'](u'IT Specialist', user=u'admin') -- 1.9.3
_______________________________________________ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel