From 3842116185de6ae8714f30b57bd75c7eddde53d8 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Jan 15 2024 13:50:10 +0000 Subject: host: update System: Manage Host Keytab permission Since commit 5c0e7a5fb420377dcc06a956695afdcb35196444, a new extended operation to get a keytab is supposed to be used. This keytab setting/retrieval extended operation checks access rights of the bound DN to write to a virtual attribute 'ipaProtectedOperation;write_keys'. If the write isn't allowed, the operation is rejected and ipa-getkeytab tool falls back to an older code that generates the keytab on the client and forcibly sets to the LDAP entry. For the latter, a check is done to make sure the bound DN is allowed to write to 'krbPrincipalKey' attribute. This fallback should never happen for newer deployments. When enrollemnt operation is delegated to non-administrative user with the help of 'Host Enrollment' role, a host can be pre-created or created at enrollment time, if this non-administrative user has 'Host Administrators' role. In the latter case a system permission 'System: Manage Host Keytab' grants write access to 'krbPrincipalKey' attribute but lacks any access to the virtual attributes expected by the new extended operation. There is a second virtual attribute, 'ipaProtectedOperation;read_keys', that allows to retrieve existing keys for a host. However, during initial enrollment we do not allow to retrieve and reuse existing Kerberos key: while 'ipa-getkeytab -r' would give ability to retrieve the existing key, 'ipa-join' has no way to trigger that operation. Hence, permission 'System: Manage Host Keytab' will not grant the right to read the Kerberos key via extended operation used by 'ipa-getkeytab -r'. Such operation can be done later by utilizing 'ipa service/host-allow-retrieve-keytab' commands. Fix 'System: Manage Host Keytab' permission and extend a permission test to see that we do not fallback to the old extended operation. Fixes: https://pagure.io/freeipa/issue/9496 Signed-off-by: Alexander Bokovoy Reviewed-By: Rob Crittenden --- diff --git a/ACI.txt b/ACI.txt index e6d6e3d..236bb43 100644 --- a/ACI.txt +++ b/ACI.txt @@ -147,7 +147,7 @@ aci: (targetattr = "usercertificate")(targetfilter = "(objectclass=ipahost)")(ve dn: cn=computers,cn=accounts,dc=ipa,dc=example aci: (targetattr = "userpassword")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Manage Host Enrollment Password";allow (write) groupdn = "ldap:///cn=System: Manage Host Enrollment Password,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=computers,cn=accounts,dc=ipa,dc=example -aci: (targetattr = "krblastpwdchange || krbprincipalkey")(targetfilter = "(&(!(memberOf=cn=ipaservers,cn=hostgroups,cn=accounts,dc=ipa,dc=example))(objectclass=ipahost))")(version 3.0;acl "permission:System: Manage Host Keytab";allow (write) groupdn = "ldap:///cn=System: Manage Host Keytab,cn=permissions,cn=pbac,dc=ipa,dc=example";) +aci: (targetattr = "ipaprotectedoperation;write_keys || krblastpwdchange || krbprincipalkey")(targetfilter = "(&(!(memberOf=cn=ipaservers,cn=hostgroups,cn=accounts,dc=ipa,dc=example))(objectclass=ipahost))")(version 3.0;acl "permission:System: Manage Host Keytab";allow (write) groupdn = "ldap:///cn=System: Manage Host Keytab,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=computers,cn=accounts,dc=ipa,dc=example aci: (targetattr = "createtimestamp || entryusn || ipaallowedtoperform;read_keys || ipaallowedtoperform;write_keys || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Manage Host Keytab Permissions";allow (compare,read,search,write) groupdn = "ldap:///cn=System: Manage Host Keytab Permissions,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=computers,cn=accounts,dc=ipa,dc=example diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py index 3ef510e..b02c8b5 100644 --- a/ipaserver/plugins/host.py +++ b/ipaserver/plugins/host.py @@ -409,7 +409,8 @@ class host(LDAPObject): api.env.container_hostgroup, api.env.basedn), ], - 'ipapermdefaultattr': {'krblastpwdchange', 'krbprincipalkey'}, + 'ipapermdefaultattr': {'krblastpwdchange', 'krbprincipalkey', + 'ipaprotectedoperation;write_keys'}, 'replaces': [ '(targetattr = "krbprincipalkey || krblastpwdchange")(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(version 3.0;acl "permission:Manage host keytab";allow (write) groupdn = "ldap:///cn=Manage host keytab,cn=permissions,cn=pbac,$SUFFIX";)', ], diff --git a/ipatests/test_integration/test_user_permissions.py b/ipatests/test_integration/test_user_permissions.py index 3333a4f..cd1096f 100644 --- a/ipatests/test_integration/test_user_permissions.py +++ b/ipatests/test_integration/test_user_permissions.py @@ -277,6 +277,9 @@ class TestInstallClientNoAdmin(IntegrationTest): self.master.run_command(['ipa', 'privilege-add-permission', '--permissions', 'System: Add Hosts', 'Add Hosts']) + self.master.run_command(['ipa', 'privilege-add-permission', + '--permissions', 'System: Manage Host Keytab', + 'Add Hosts']) self.master.run_command(['ipa', 'role-add-privilege', 'useradmin', '--privileges', 'Host Enrollment']) @@ -301,6 +304,10 @@ class TestInstallClientNoAdmin(IntegrationTest): encoding='utf-8') assert msg in install_log + # Make sure we do not fallback to an old keytab retrieval method anymore + msg = "Retrying with pre-4.0 keytab retrieval method..." + assert msg not in install_log + # check that user is able to request a host cert, too result = tasks.run_certutil(client, ['-L'], paths.IPA_NSSDB_DIR) assert 'Local IPA host' in result.stdout_text