|
|
590d18 |
From 2c577bc650613f5adfcc1efed0bfa40187eb362e Mon Sep 17 00:00:00 2001
|
|
|
590d18 |
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
590d18 |
Date: Thu, 13 Aug 2015 17:18:57 +0300
|
|
|
590d18 |
Subject: [PATCH] trusts: harden trust-fetch-domains oddjobd-based script
|
|
|
590d18 |
|
|
|
590d18 |
When ipa-getkeytab is used to fetch trusted domain object credentials,
|
|
|
590d18 |
the fetched entry has always kvno 1. ipa-getkeytab always adds a key to
|
|
|
590d18 |
keytab which means older key versions will be in the SSSD keytab and
|
|
|
590d18 |
will confuse libkrb5 ccache initialization code as all kvno values are
|
|
|
590d18 |
equal to 1. Wrong key is picked up then and kinit fails.
|
|
|
590d18 |
|
|
|
590d18 |
To solve this problem, always remove existing
|
|
|
590d18 |
/var/lib/sss/keytabs/forest.keytab before retrieving a new one.
|
|
|
590d18 |
|
|
|
590d18 |
To make sure script's input cannot be used to define what should be
|
|
|
590d18 |
removed (by passing a relative path), make sure we retrieve trusted
|
|
|
590d18 |
forest name from LDAP. If it is not possible to retrieve, the script
|
|
|
590d18 |
will issue an exception and quit. If abrtd is running, this will be
|
|
|
590d18 |
recorded as a 'crash' and an attempt to use script by malicious user
|
|
|
590d18 |
would be recorded as well in the abrtd journal.
|
|
|
590d18 |
|
|
|
590d18 |
Additionally, as com.redhat.idm.trust-fetch-domains will create
|
|
|
590d18 |
ID ranges for the domains of the trusted forest if they don't exist,
|
|
|
590d18 |
it needs permissions to do so. The permission should be granted only
|
|
|
590d18 |
to cifs/ipa.master@IPA.REALM services which means they must have
|
|
|
590d18 |
krbprincipalname=cifs/*@IPA.REALM,cn=services,... DN and be members of
|
|
|
590d18 |
cn=adtrust agents,cn=sysaccounts,... group.
|
|
|
590d18 |
|
|
|
590d18 |
Solves https://bugzilla.redhat.com/show_bug.cgi?id=1250190
|
|
|
590d18 |
|
|
|
590d18 |
Ticket https://fedorahosted.org/freeipa/ticket/5182
|
|
|
590d18 |
|
|
|
590d18 |
Reviewed-By: Tomas Babej <tbabej@redhat.com>
|
|
|
590d18 |
---
|
|
|
590d18 |
install/oddjob/com.redhat.idm.trust-fetch-domains | 29 +++++++++++++++++++----
|
|
|
590d18 |
install/updates/20-aci.update | 4 ++++
|
|
|
590d18 |
2 files changed, 28 insertions(+), 5 deletions(-)
|
|
|
590d18 |
|
|
|
590d18 |
diff --git a/install/oddjob/com.redhat.idm.trust-fetch-domains b/install/oddjob/com.redhat.idm.trust-fetch-domains
|
|
|
590d18 |
index e50c81e50e73b258bf08737c2d9a13a8832eb69f..6a2171d5f1936fabd00081bbbcea562a0e7041b8 100755
|
|
|
590d18 |
--- a/install/oddjob/com.redhat.idm.trust-fetch-domains
|
|
|
590d18 |
+++ b/install/oddjob/com.redhat.idm.trust-fetch-domains
|
|
|
590d18 |
@@ -41,6 +41,9 @@ def retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal):
|
|
|
590d18 |
"-p", oneway_principal,
|
|
|
590d18 |
"-k", oneway_keytab_name,
|
|
|
590d18 |
"-r"]
|
|
|
590d18 |
+ if os.path.isfile(oneway_keytab_name):
|
|
|
590d18 |
+ os.unlink(oneway_keytab_name)
|
|
|
590d18 |
+
|
|
|
590d18 |
(stdout, stderr, retcode) = ipautil.run(getkeytab_args,
|
|
|
590d18 |
env={'KRB5CCNAME': ccache_name, 'LANG': 'C'},
|
|
|
590d18 |
raiseonerr=False)
|
|
|
590d18 |
@@ -111,7 +114,6 @@ from ipalib.plugins import trust
|
|
|
590d18 |
# retrieve the keys to oneway_keytab_name.
|
|
|
590d18 |
|
|
|
590d18 |
keytab_name = '/etc/samba/samba.keytab'
|
|
|
590d18 |
-oneway_keytab_name = '/var/lib/sss/keytabs/' + trusted_domain + '.keytab'
|
|
|
590d18 |
|
|
|
590d18 |
principal = str('cifs/' + api.env.host)
|
|
|
590d18 |
|
|
|
590d18 |
@@ -137,10 +139,20 @@ else:
|
|
|
590d18 |
old_ccache = os.environ.get('KRB5CCNAME')
|
|
|
590d18 |
api.Backend.ldap2.connect(ccache)
|
|
|
590d18 |
|
|
|
590d18 |
+# Retrieve own NetBIOS name and trusted forest's name.
|
|
|
590d18 |
+# We use script's input to retrieve the trusted forest's name to sanitize input
|
|
|
590d18 |
+# for file-level access as we might need to wipe out keytab in /var/lib/sss/keytabs
|
|
|
590d18 |
own_trust_dn = DN(('cn', api.env.domain),('cn','ad'), ('cn', 'etc'), api.env.basedn)
|
|
|
590d18 |
own_trust_entry = api.Backend.ldap2.get_entry(own_trust_dn, ['ipantflatname'])
|
|
|
590d18 |
-own_trust_flatname = own_trust_entry['ipantflatname'][0].upper()
|
|
|
590d18 |
+own_trust_flatname = own_trust_entry.single_value.get('ipantflatname').upper()
|
|
|
590d18 |
+trusted_domain_dn = DN(('cn', trusted_domain.lower()), api.env.container_adtrusts, api.env.basedn)
|
|
|
590d18 |
+trusted_domain_entry = api.Backend.ldap2.get_entry(trusted_domain_dn, ['cn'])
|
|
|
590d18 |
+trusted_domain = trusted_domain_entry.single_value.get('cn').lower()
|
|
|
590d18 |
|
|
|
590d18 |
+# At this point if we didn't find trusted forest name, an exception will be raised
|
|
|
590d18 |
+# and script will quit. This is actually intended.
|
|
|
590d18 |
+
|
|
|
590d18 |
+oneway_keytab_name = '/var/lib/sss/keytabs/' + trusted_domain + '.keytab'
|
|
|
590d18 |
oneway_principal = str('%s$@%s' % (own_trust_flatname, trusted_domain.upper()))
|
|
|
590d18 |
|
|
|
590d18 |
# If keytab does not exist, retrieve it
|
|
|
590d18 |
@@ -152,11 +164,18 @@ try:
|
|
|
590d18 |
# The keytab may have stale key material (from older trust-add run)
|
|
|
590d18 |
if not os.path.isfile(oneway_ccache_name):
|
|
|
590d18 |
oneway_ccache = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
|
|
|
590d18 |
+ else:
|
|
|
590d18 |
+ oneway_ccache_check = KRB5_CCache(oneway_ccache_name)
|
|
|
590d18 |
+ if not oneway_ccache_check.credential_is_valid(oneway_principal):
|
|
|
590d18 |
+ # If credentials were invalid, obtain them again
|
|
|
590d18 |
+ oneway_ccache = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
|
|
|
590d18 |
+ else:
|
|
|
590d18 |
+ oneway_ccache = oneway_ccache_check.ccache
|
|
|
590d18 |
except krbV.Krb5Error as e:
|
|
|
590d18 |
# If there was failure on using keytab, assume it is stale and retrieve again
|
|
|
590d18 |
retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal)
|
|
|
590d18 |
|
|
|
590d18 |
-if oneway_ccache:
|
|
|
590d18 |
+try:
|
|
|
590d18 |
# There wasn existing ccache, validate its content
|
|
|
590d18 |
oneway_ccache_check = KRB5_CCache(oneway_ccache_name)
|
|
|
590d18 |
if not oneway_ccache_check.credential_is_valid(oneway_principal):
|
|
|
590d18 |
@@ -164,7 +183,7 @@ if oneway_ccache:
|
|
|
590d18 |
oneway_ccache = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
|
|
|
590d18 |
else:
|
|
|
590d18 |
oneway_ccache = oneway_ccache_check.ccache
|
|
|
590d18 |
-else:
|
|
|
590d18 |
+except krbV.Krb5Error as e:
|
|
|
590d18 |
oneway_ccache = kinit_keytab(oneway_principal, oneway_keytab_name, oneway_ccache_name)
|
|
|
590d18 |
|
|
|
590d18 |
# We are done: we have ccache with TDO credentials and can fetch domains
|
|
|
590d18 |
@@ -193,7 +212,7 @@ if domains:
|
|
|
590d18 |
dom['range_type'] = u'ipa-ad-trust'
|
|
|
590d18 |
# Do not pass ipaserver.dcerpc.TrustInstance to trust.add_range
|
|
|
590d18 |
# to force it using existing credentials cache
|
|
|
590d18 |
- trust.add_range(None, range_name, dom['ipanttrusteddomainsid'],
|
|
|
590d18 |
+ trust.add_range(api, None, range_name, dom['ipanttrusteddomainsid'],
|
|
|
590d18 |
trusted_domain, name, **dom)
|
|
|
590d18 |
except errors.DuplicateEntry:
|
|
|
590d18 |
# Ignore updating duplicate entries
|
|
|
590d18 |
diff --git a/install/updates/20-aci.update b/install/updates/20-aci.update
|
|
|
590d18 |
index 0bdeeb6acefad4f79385a1ddaec95df2e40377fb..cba1897e1fd1136fbcbd7c6ccaf03bfa4b696a44 100644
|
|
|
590d18 |
--- a/install/updates/20-aci.update
|
|
|
590d18 |
+++ b/install/updates/20-aci.update
|
|
|
590d18 |
@@ -87,3 +87,7 @@ add:aci:(targetattr = "usercertificate")(version 3.0;acl "selfservice:Users can
|
|
|
590d18 |
# Hosts can add their own services
|
|
|
590d18 |
dn: cn=services,cn=accounts,$SUFFIX
|
|
|
590d18 |
add:aci: (target = "ldap:///krbprincipalname=*/($$dn)@$REALM,cn=services,cn=accounts,$SUFFIX")(targetfilter = "(objectClass=ipaKrbPrincipal)")(version 3.0;acl "Hosts can add own services"; allow(add) userdn="ldap:///fqdn=($$dn),cn=computers,cn=accounts,$SUFFIX";)
|
|
|
590d18 |
+
|
|
|
590d18 |
+# CIFS service on the master can manage ID ranges
|
|
|
590d18 |
+dn: cn=ranges,cn=etc,$SUFFIX
|
|
|
590d18 |
+add:aci: (target = "ldap:///cn=*,cn=ranges,cn=etc,$SUFFIX")(targetfilter = "(objectClass=ipaIDrange)")(version 3.0;acl "CIFS service can manage ID ranges for trust"; allow(all) userdn="ldap:///krbprincipalname=cifs/*@$REALM,cn=services,cn=accounts,$SUFFIX" and groupdn="ldap:///cn=adtrust agents,cn=sysaccounts,cn=etc,$SUFFIX";)
|
|
|
590d18 |
--
|
|
|
590d18 |
2.4.3
|
|
|
590d18 |
|