summaryrefslogtreecommitdiffstats
path: root/ipaserver/plugins/service.py
diff options
context:
space:
mode:
Diffstat (limited to 'ipaserver/plugins/service.py')
-rw-r--r--ipaserver/plugins/service.py84
1 files changed, 80 insertions, 4 deletions
diff --git a/ipaserver/plugins/service.py b/ipaserver/plugins/service.py
index ec0bc5fbe..7b0832b23 100644
--- a/ipaserver/plugins/service.py
+++ b/ipaserver/plugins/service.py
@@ -436,9 +436,9 @@ class service(LDAPObject):
takes_params = (
Principal(
- 'krbprincipalname',
+ 'krbcanonicalname',
validate_realm,
- cli_name='principal',
+ cli_name='canonical_principal',
label=_('Principal'),
doc=_('Service principal'),
primary_key=True,
@@ -503,6 +503,16 @@ class service(LDAPObject):
" Use 'radius' to allow RADIUS-based 2FA authentications."
" Other values may be used for custom configurations."),
),
+ Principal(
+ 'krbprincipalname',
+ validate_realm,
+ cli_name='principal',
+ label=_('Principal Alias'),
+ doc=_('Service principal alias'),
+ normalizer=normalize_principal,
+ require_service=True,
+ flags={'no_create', 'no_update'}
+ ),
) + ticket_flags_params
def validate_ipakrbauthzdata(self, entry):
@@ -521,8 +531,51 @@ class service(LDAPObject):
error=_('NONE value cannot be combined with other PAC types'))
def get_dn(self, *keys, **kwargs):
- keys = (normalize_principal(k) for k in keys)
- return super(service, self).get_dn(*keys, **kwargs)
+ key = keys[0]
+ if isinstance(key, six.text_type):
+ key = kerberos.Principal(key)
+
+ key = unicode(normalize_principal(key))
+
+ parent_dn = DN(self.container_dn, self.api.env.basedn)
+ true_rdn = 'krbprincipalname'
+
+ return self.backend.make_dn_from_attr(
+ true_rdn, key, parent_dn
+ )
+
+ def get_primary_key_from_dn(self, dn):
+ """
+ If the entry has krbcanonicalname set return the value of the
+ attribute. If the attribute is not found, assume old-style entry which
+ should have only single value of krbprincipalname and return it.
+
+ Otherwise return input DN.
+ """
+ assert isinstance(dn, DN)
+
+ try:
+ entry_attrs = self.backend.get_entry(
+ dn, [self.primary_key.name]
+ )
+ try:
+ return entry_attrs[self.primary_key.name][0]
+ except (KeyError, IndexError):
+ return ''
+ except errors.NotFound:
+ pass
+
+ try:
+ return dn['krbprincipalname'][0]
+ except KeyError:
+ return unicode(dn)
+
+ def populate_krbcanonicalname(self, entry_attrs, options):
+ if options.get('raw', False):
+ return
+
+ entry_attrs.setdefault(
+ 'krbcanonicalname', entry_attrs['krbprincipalname'])
@register()
@@ -587,6 +640,7 @@ class service_add(LDAPCreate):
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
set_kerberos_attrs(entry_attrs, options)
rename_ipaallowedtoperform_from_ldap(entry_attrs, options)
+ self.obj.populate_krbcanonicalname(entry_attrs, options)
return dn
@@ -655,6 +709,7 @@ class service_mod(LDAPUpdate):
set_certificate_attrs(entry_attrs)
set_kerberos_attrs(entry_attrs, options)
rename_ipaallowedtoperform_from_ldap(entry_attrs, options)
+ self.obj.populate_krbcanonicalname(entry_attrs, options)
return dn
@@ -667,6 +722,8 @@ class service_find(LDAPSearch):
'%(count)d service matched', '%(count)d services matched', 0
)
member_attributes = ['managedby']
+ sort_result_entries = False
+
takes_options = LDAPSearch.takes_options
has_output_params = LDAPSearch.has_output_params + output_params
@@ -680,12 +737,25 @@ class service_find(LDAPSearch):
'(krbprincipalname=krbtgt/*))' \
')' \
')'
+ if options.get('pkey_only', False):
+ attrs_list.append('krbprincipalname')
+
return (
ldap.combine_filters((custom_filter, filter), rules=ldap.MATCH_ALL),
base_dn, scope
)
def post_callback(self, ldap, entries, truncated, *args, **options):
+ # we have to sort entries manually instead of relying on inherited
+ # mechanisms
+ def sort_key(x):
+ if 'krbcanonicalname' in x:
+ return x['krbcanonicalname'][0]
+ else:
+ return x['krbprincipalname'][0]
+
+ entries.sort(key=sort_key)
+
if options.get('pkey_only', False):
return truncated
for entry_attrs in entries:
@@ -707,6 +777,7 @@ class service_find(LDAPSearch):
set_kerberos_attrs(entry_attrs, options)
rename_ipaallowedtoperform_from_ldap(entry_attrs, options)
+ self.obj.populate_krbcanonicalname(entry_attrs, options)
return truncated
@@ -744,6 +815,7 @@ class service_show(LDAPRetrieve):
set_kerberos_attrs(entry_attrs, options)
rename_ipaallowedtoperform_from_ldap(entry_attrs, options)
+ self.obj.populate_krbcanonicalname(entry_attrs, options)
return dn
@@ -781,6 +853,7 @@ class service_allow_retrieve_keytab(LDAPAddMember):
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
rename_ipaallowedtoperform_from_ldap(entry_attrs, options)
rename_ipaallowedtoperform_from_ldap(failed, options)
+ self.obj.populate_krbcanonicalname(entry_attrs, options)
return (completed, dn)
@@ -799,6 +872,7 @@ class service_disallow_retrieve_keytab(LDAPRemoveMember):
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
rename_ipaallowedtoperform_from_ldap(entry_attrs, options)
rename_ipaallowedtoperform_from_ldap(failed, options)
+ self.obj.populate_krbcanonicalname(entry_attrs, options)
return (completed, dn)
@@ -818,6 +892,7 @@ class service_allow_create_keytab(LDAPAddMember):
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
rename_ipaallowedtoperform_from_ldap(entry_attrs, options)
rename_ipaallowedtoperform_from_ldap(failed, options)
+ self.obj.populate_krbcanonicalname(entry_attrs, options)
return (completed, dn)
@@ -836,6 +911,7 @@ class service_disallow_create_keytab(LDAPRemoveMember):
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
rename_ipaallowedtoperform_from_ldap(entry_attrs, options)
rename_ipaallowedtoperform_from_ldap(failed, options)
+ self.obj.populate_krbcanonicalname(entry_attrs, options)
return (completed, dn)