summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--API.txt76
-rw-r--r--ipaserver/plugins/baseuser.py57
-rw-r--r--ipaserver/plugins/caacl.py17
-rw-r--r--ipaserver/plugins/cert.py88
-rw-r--r--ipaserver/plugins/host.py25
-rw-r--r--ipaserver/plugins/passwd.py21
-rw-r--r--ipaserver/plugins/service.py101
-rw-r--r--ipaserver/plugins/vault.py46
-rw-r--r--ipatests/test_xmlrpc/test_host_plugin.py1
-rw-r--r--ipatests/test_xmlrpc/test_service_plugin.py9
-rw-r--r--ipatests/test_xmlrpc/test_stageuser_plugin.py6
-rw-r--r--ipatests/test_xmlrpc/test_user_plugin.py5
12 files changed, 213 insertions, 239 deletions
diff --git a/API.txt b/API.txt
index c01692e17..704dcde3c 100644
--- a/API.txt
+++ b/API.txt
@@ -738,14 +738,14 @@ option: Int('max_serial_number?', autofill=False)
option: Int('min_serial_number?', autofill=False)
option: Str('no_host*', cli_name='no_hosts')
option: Flag('no_members', autofill=True, default=True)
-option: Str('no_service*', cli_name='no_services')
+option: Principal('no_service*', cli_name='no_services')
option: Str('no_user*', cli_name='no_users')
option: Flag('pkey_only?', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
option: Int('revocation_reason?', autofill=False)
option: DateTime('revokedon_from?', autofill=False)
option: DateTime('revokedon_to?', autofill=False)
-option: Str('service*', cli_name='services')
+option: Principal('service*', cli_name='services')
option: Int('sizelimit?')
option: Str('subject?', autofill=False)
option: Int('timelimit?')
@@ -771,7 +771,7 @@ arg: Str('csr', cli_name='csr_file')
option: Flag('add', autofill=True, default=False)
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('cacn?', autofill=True, cli_name='ca', default=u'ipa')
-option: Str('principal')
+option: Principal('principal')
option: Str('profile_id?')
option: Flag('raw', autofill=True, cli_name='raw', default=False)
option: Str('request_type', autofill=True, default=u'pkcs10')
@@ -2436,7 +2436,7 @@ option: Bool('ipakrbokasdelegate?', autofill=False, cli_name='ok_as_delegate')
option: Bool('ipakrbrequirespreauth?', autofill=False, cli_name='requires_pre_auth')
option: Str('ipasshpubkey*', autofill=False, cli_name='sshpubkey')
option: Str('krbprincipalauthind*', autofill=False, cli_name='auth_ind')
-option: Str('krbprincipalname?', cli_name='principalname')
+option: Principal('krbprincipalname?', cli_name='principalname')
option: Str('l?', autofill=False, cli_name='locality')
option: Str('macaddress*', autofill=False)
option: Flag('no_members', autofill=True, default=False)
@@ -3401,7 +3401,7 @@ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: passwd/1
args: 3,2,3
-arg: Str('principal', autofill=True, cli_name='user')
+arg: Principal('principal', autofill=True, cli_name='user')
arg: Password('password')
arg: Password('current_password', autofill=True, confirm=False)
option: Password('otp?', confirm=False)
@@ -4271,7 +4271,7 @@ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: service_add/1
args: 1,12,3
-arg: Str('krbprincipalname', cli_name='principal')
+arg: Principal('krbprincipalname', cli_name='principal')
option: Str('addattr*', cli_name='addattr')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Flag('force', autofill=True, default=False)
@@ -4289,7 +4289,7 @@ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: service_add_cert/1
args: 1,5,3
-arg: Str('krbprincipalname', cli_name='principal')
+arg: Principal('krbprincipalname', cli_name='principal')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
@@ -4300,7 +4300,7 @@ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: service_add_host/1
args: 1,5,3
-arg: Str('krbprincipalname', cli_name='principal')
+arg: Principal('krbprincipalname', cli_name='principal')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('host*', alwaysask=True, cli_name='hosts')
option: Flag('no_members', autofill=True, default=False)
@@ -4311,7 +4311,7 @@ output: Output('failed', type=[<type 'dict'>])
output: Entry('result')
command: service_allow_create_keytab/1
args: 1,8,3
-arg: Str('krbprincipalname', cli_name='principal')
+arg: Principal('krbprincipalname', cli_name='principal')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('group*', alwaysask=True, cli_name='groups')
option: Str('host*', alwaysask=True, cli_name='hosts')
@@ -4325,7 +4325,7 @@ output: Output('failed', type=[<type 'dict'>])
output: Entry('result')
command: service_allow_retrieve_keytab/1
args: 1,8,3
-arg: Str('krbprincipalname', cli_name='principal')
+arg: Principal('krbprincipalname', cli_name='principal')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('group*', alwaysask=True, cli_name='groups')
option: Str('host*', alwaysask=True, cli_name='hosts')
@@ -4339,7 +4339,7 @@ output: Output('failed', type=[<type 'dict'>])
output: Entry('result')
command: service_del/1
args: 1,2,3
-arg: Str('krbprincipalname+', cli_name='principal')
+arg: Principal('krbprincipalname+', cli_name='principal')
option: Flag('continue', autofill=True, cli_name='continue', default=False)
option: Str('version?')
output: Output('result', type=[<type 'dict'>])
@@ -4347,14 +4347,14 @@ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: ListOfPrimaryKeys('value')
command: service_disable/1
args: 1,1,3
-arg: Str('krbprincipalname', cli_name='principal')
+arg: Principal('krbprincipalname', cli_name='principal')
option: Str('version?')
output: Output('result', type=[<type 'bool'>])
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: service_disallow_create_keytab/1
args: 1,8,3
-arg: Str('krbprincipalname', cli_name='principal')
+arg: Principal('krbprincipalname', cli_name='principal')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('group*', alwaysask=True, cli_name='groups')
option: Str('host*', alwaysask=True, cli_name='hosts')
@@ -4368,7 +4368,7 @@ output: Output('failed', type=[<type 'dict'>])
output: Entry('result')
command: service_disallow_retrieve_keytab/1
args: 1,8,3
-arg: Str('krbprincipalname', cli_name='principal')
+arg: Principal('krbprincipalname', cli_name='principal')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('group*', alwaysask=True, cli_name='groups')
option: Str('host*', alwaysask=True, cli_name='hosts')
@@ -4386,7 +4386,7 @@ arg: Str('criteria?')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: StrEnum('ipakrbauthzdata*', autofill=False, cli_name='pac_type', values=[u'MS-PAC', u'PAD', u'NONE'])
option: Str('krbprincipalauthind*', autofill=False, cli_name='auth_ind')
-option: Str('krbprincipalname?', autofill=False, cli_name='principal')
+option: Principal('krbprincipalname?', autofill=False, cli_name='principal')
option: Str('man_by_host*', cli_name='man_by_hosts')
option: Flag('no_members', autofill=True, default=True)
option: Str('not_man_by_host*', cli_name='not_man_by_hosts')
@@ -4401,7 +4401,7 @@ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: Output('truncated', type=[<type 'bool'>])
command: service_mod/1
args: 1,13,3
-arg: Str('krbprincipalname', cli_name='principal')
+arg: Principal('krbprincipalname', cli_name='principal')
option: Str('addattr*', cli_name='addattr')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('delattr*', cli_name='delattr')
@@ -4420,7 +4420,7 @@ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: service_remove_cert/1
args: 1,5,3
-arg: Str('krbprincipalname', cli_name='principal')
+arg: Principal('krbprincipalname', cli_name='principal')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
@@ -4431,7 +4431,7 @@ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: service_remove_host/1
args: 1,5,3
-arg: Str('krbprincipalname', cli_name='principal')
+arg: Principal('krbprincipalname', cli_name='principal')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('host*', alwaysask=True, cli_name='hosts')
option: Flag('no_members', autofill=True, default=False)
@@ -4442,7 +4442,7 @@ output: Output('failed', type=[<type 'dict'>])
output: Entry('result')
command: service_show/1
args: 1,6,3
-arg: Str('krbprincipalname', cli_name='principal')
+arg: Principal('krbprincipalname', cli_name='principal')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Flag('no_members', autofill=True, default=False)
option: Str('out?')
@@ -4646,7 +4646,7 @@ option: Str('ipatokenradiusconfiglink?', cli_name='radius')
option: Str('ipatokenradiususername?', cli_name='radius_username')
option: StrEnum('ipauserauthtype*', cli_name='user_auth_type', values=[u'password', u'radius', u'otp'])
option: DateTime('krbprincipalexpiration?', cli_name='principal_expiration')
-option: Str('krbprincipalname?', autofill=True, cli_name='principal')
+option: Principal('krbprincipalname?', autofill=True, cli_name='principal')
option: Str('l?', cli_name='city')
option: Str('loginshell?', cli_name='shell')
option: Str('mail*', cli_name='email')
@@ -4717,7 +4717,7 @@ option: Str('ipatokenradiusconfiglink?', autofill=False, cli_name='radius')
option: Str('ipatokenradiususername?', autofill=False, cli_name='radius_username')
option: StrEnum('ipauserauthtype*', autofill=False, cli_name='user_auth_type', values=[u'password', u'radius', u'otp'])
option: DateTime('krbprincipalexpiration?', autofill=False, cli_name='principal_expiration')
-option: Str('krbprincipalname?', autofill=False, cli_name='principal')
+option: Principal('krbprincipalname?', autofill=False, cli_name='principal')
option: Str('l?', autofill=False, cli_name='city')
option: Str('loginshell?', autofill=False, cli_name='shell')
option: Str('mail*', autofill=False, cli_name='email')
@@ -5633,7 +5633,7 @@ option: Str('ipatokenradiusconfiglink?', cli_name='radius')
option: Str('ipatokenradiususername?', cli_name='radius_username')
option: StrEnum('ipauserauthtype*', cli_name='user_auth_type', values=[u'password', u'radius', u'otp'])
option: DateTime('krbprincipalexpiration?', cli_name='principal_expiration')
-option: Str('krbprincipalname?', autofill=True, cli_name='principal')
+option: Principal('krbprincipalname?', autofill=True, cli_name='principal')
option: Str('l?', cli_name='city')
option: Str('loginshell?', cli_name='shell')
option: Str('mail*', cli_name='email')
@@ -5732,7 +5732,7 @@ option: Str('ipatokenradiusconfiglink?', autofill=False, cli_name='radius')
option: Str('ipatokenradiususername?', autofill=False, cli_name='radius_username')
option: StrEnum('ipauserauthtype*', autofill=False, cli_name='user_auth_type', values=[u'password', u'radius', u'otp'])
option: DateTime('krbprincipalexpiration?', autofill=False, cli_name='principal_expiration')
-option: Str('krbprincipalname?', autofill=False, cli_name='principal')
+option: Principal('krbprincipalname?', autofill=False, cli_name='principal')
option: Str('l?', autofill=False, cli_name='city')
option: Str('loginshell?', autofill=False, cli_name='shell')
option: Str('mail*', autofill=False, cli_name='email')
@@ -5899,7 +5899,7 @@ option: Bytes('ipavaultsalt?', cli_name='salt')
option: StrEnum('ipavaulttype?', autofill=True, cli_name='type', default=u'symmetric', values=[u'standard', u'symmetric', u'asymmetric'])
option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
-option: Str('service?')
+option: Principal('service?')
option: Str('setattr*', cli_name='setattr')
option: Flag('shared?', autofill=True, default=False)
option: Str('username?', cli_name='user')
@@ -5914,7 +5914,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('group*', alwaysask=True, cli_name='groups')
option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
-option: Str('service?')
+option: Principal('service?')
option: Str('services*', alwaysask=True, cli_name='services')
option: Flag('shared?', autofill=True, default=False)
option: Str('user*', alwaysask=True, cli_name='users')
@@ -5930,7 +5930,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('group*', alwaysask=True, cli_name='groups')
option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
-option: Str('service?')
+option: Principal('service?')
option: Str('services*', alwaysask=True, cli_name='services')
option: Flag('shared?', autofill=True, default=False)
option: Str('user*', alwaysask=True, cli_name='users')
@@ -5945,7 +5945,7 @@ arg: Str('cn', cli_name='name')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Bytes('nonce')
option: Flag('raw', autofill=True, cli_name='raw', default=False)
-option: Str('service?')
+option: Principal('service?')
option: Bytes('session_key')
option: Flag('shared?', autofill=True, default=False)
option: Str('username?', cli_name='user')
@@ -5958,7 +5958,7 @@ command: vault_del/1
args: 1,5,3
arg: Str('cn+', cli_name='name')
option: Flag('continue', autofill=True, cli_name='continue', default=False)
-option: Str('service?')
+option: Principal('service?')
option: Flag('shared?', autofill=True, default=False)
option: Str('username?', cli_name='user')
option: Str('version?')
@@ -5975,7 +5975,7 @@ option: StrEnum('ipavaulttype?', autofill=False, cli_name='type', default=u'symm
option: Flag('no_members', autofill=True, default=True)
option: Flag('pkey_only?', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
-option: Str('service?')
+option: Principal('service?')
option: Flag('services?', autofill=True, default=False)
option: Flag('shared?', autofill=True, default=False)
option: Int('sizelimit?', autofill=False)
@@ -6000,7 +6000,7 @@ option: StrEnum('ipavaulttype?', autofill=False, cli_name='type', default=u'symm
option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
option: Flag('rights', autofill=True, default=False)
-option: Str('service?')
+option: Principal('service?')
option: Str('setattr*', cli_name='setattr')
option: Flag('shared?', autofill=True, default=False)
option: Str('username?', cli_name='user')
@@ -6015,7 +6015,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('group*', alwaysask=True, cli_name='groups')
option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
-option: Str('service?')
+option: Principal('service?')
option: Str('services*', alwaysask=True, cli_name='services')
option: Flag('shared?', autofill=True, default=False)
option: Str('user*', alwaysask=True, cli_name='users')
@@ -6031,7 +6031,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('group*', alwaysask=True, cli_name='groups')
option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
-option: Str('service?')
+option: Principal('service?')
option: Str('services*', alwaysask=True, cli_name='services')
option: Flag('shared?', autofill=True, default=False)
option: Str('user*', alwaysask=True, cli_name='users')
@@ -6045,7 +6045,7 @@ args: 1,7,3
arg: Str('cn', cli_name='name')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
-option: Str('service?')
+option: Principal('service?')
option: Bytes('session_key')
option: Flag('shared?', autofill=True, default=False)
option: Str('username?', cli_name='user')
@@ -6060,7 +6060,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False)
option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
option: Flag('rights', autofill=True, default=False)
-option: Str('service?')
+option: Principal('service?')
option: Flag('shared?', autofill=True, default=False)
option: Str('username?', cli_name='user')
option: Str('version?')
@@ -6082,7 +6082,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('group*', alwaysask=True, cli_name='groups')
option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
-option: Str('service?')
+option: Principal('service?')
option: Str('services*', alwaysask=True, cli_name='services')
option: Flag('shared?', autofill=True, default=False)
option: Str('user*', alwaysask=True, cli_name='users')
@@ -6094,7 +6094,7 @@ output: Entry('result')
command: vaultcontainer_del/1
args: 0,5,3
option: Flag('continue', autofill=True, cli_name='continue', default=False)
-option: Str('service?')
+option: Principal('service?')
option: Flag('shared?', autofill=True, default=False)
option: Str('username?', cli_name='user')
option: Str('version?')
@@ -6107,7 +6107,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('group*', alwaysask=True, cli_name='groups')
option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
-option: Str('service?')
+option: Principal('service?')
option: Str('services*', alwaysask=True, cli_name='services')
option: Flag('shared?', autofill=True, default=False)
option: Str('user*', alwaysask=True, cli_name='users')
@@ -6122,7 +6122,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False)
option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
option: Flag('rights', autofill=True, default=False)
-option: Str('service?')
+option: Principal('service?')
option: Flag('shared?', autofill=True, default=False)
option: Str('username?', cli_name='user')
option: Str('version?')
diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py
index 9c4af66f9..cbb04aaad 100644
--- a/ipaserver/plugins/baseuser.py
+++ b/ipaserver/plugins/baseuser.py
@@ -23,13 +23,16 @@ import six
from ipalib import api, errors
from ipalib import Flag, Int, Password, Str, Bool, StrEnum, DateTime, Bytes
+from ipalib.parameters import Principal
from ipalib.plugable import Registry
from .baseldap import (
DN, LDAPObject, LDAPCreate, LDAPUpdate, LDAPSearch, LDAPDelete,
LDAPRetrieve, LDAPAddMember, LDAPRemoveMember)
-from .service import validate_certificate
+from ipaserver.plugins.service import (
+ validate_certificate, validate_realm, normalize_principal)
from ipalib.request import context
from ipalib import _
+from ipapython import kerberos
from ipapython.ipautil import ipa_generate_password
from ipapython.ipavalidate import Email
from ipalib.util import (
@@ -93,45 +96,14 @@ def convert_nsaccountlock(entry_attrs):
nsaccountlock = Bool('temp')
entry_attrs['nsaccountlock'] = nsaccountlock.convert(entry_attrs['nsaccountlock'][0])
-def split_principal(principal):
- """
- Split the principal into its components and do some basic validation.
-
- Automatically append our realm if it wasn't provided.
- """
- realm = None
- parts = principal.split('@')
- user = parts[0].lower()
- if len(parts) > 2:
- raise errors.MalformedUserPrincipal(principal=principal)
-
- if len(parts) == 2:
- realm = parts[1].upper()
- # At some point we'll support multiple realms
- if realm != api.env.realm:
- raise errors.RealmMismatch()
- else:
- realm = api.env.realm
-
- return (user, realm)
-def validate_principal(ugettext, principal):
- """
- All the real work is done in split_principal.
- """
- (user, realm) = split_principal(principal)
- return None
-
-def normalize_principal(principal):
- """
- Ensure that the name in the principal is lower-case. The realm is
- upper-case by convention but it isn't required.
-
- The principal is validated at this point.
- """
- (user, realm) = split_principal(principal)
- return unicode('%s@%s' % (user, realm))
+def normalize_user_principal(value):
+ principal = kerberos.Principal(normalize_principal(value))
+ lowercase_components = ((principal.username.lower(),) +
+ principal.components[1:])
+ return unicode(
+ kerberos.Principal(lowercase_components, realm=principal.realm))
def fix_addressbook_permission_bindrule(name, template, is_new,
@@ -239,13 +211,16 @@ class baseuser(LDAPObject):
cli_name='shell',
label=_('Login shell'),
),
- Str('krbprincipalname?', validate_principal,
+ Principal(
+ 'krbprincipalname?',
+ validate_realm,
cli_name='principal',
label=_('Kerberos principal'),
- default_from=lambda uid: '%s@%s' % (uid.lower(), api.env.realm),
+ default_from=lambda uid: kerberos.Principal.from_text(
+ uid.lower(), realm=api.env.realm),
autofill=True,
flags=['no_update'],
- normalizer=lambda value: normalize_principal(value),
+ normalizer=normalize_user_principal,
),
DateTime('krbprincipalexpiration?',
cli_name='principal_expiration',
diff --git a/ipaserver/plugins/caacl.py b/ipaserver/plugins/caacl.py
index a543a1de7..3f813a7ef 100644
--- a/ipaserver/plugins/caacl.py
+++ b/ipaserver/plugins/caacl.py
@@ -3,6 +3,7 @@
#
import pyhbac
+import six
from ipalib import api, errors, output
from ipalib import Bool, Str, StrEnum
@@ -13,10 +14,11 @@ from .baseldap import (
LDAPUpdate, LDAPRetrieve, LDAPAddMember, LDAPRemoveMember,
global_output_params, pkey_to_value)
from .hbacrule import is_all
-from .service import normalize_principal, split_any_principal
from ipalib import _, ngettext
from ipapython.dn import DN
+if six.PY3:
+ unicode = str
__doc__ = _("""
Manage CA ACL rules.
@@ -58,24 +60,21 @@ register = Registry()
def _acl_make_request(principal_type, principal, ca_id, profile_id):
"""Construct HBAC request for the given principal, CA and profile"""
- service, name, realm = split_any_principal(principal)
req = pyhbac.HbacRequest()
req.targethost.name = ca_id
req.service.name = profile_id
- if principal_type == 'user':
- req.user.name = name
- elif principal_type == 'host':
- req.user.name = name
+ if principal_type == 'user' or principal_type == 'host':
+ req.user.name = principal.username
elif principal_type == 'service':
- req.user.name = normalize_principal(principal)
+ req.user.name = unicode(principal)
groups = []
if principal_type == 'user':
- user_obj = api.Command.user_show(name)['result']
+ user_obj = api.Command.user_show(principal.username)['result']
groups = user_obj.get('memberof_group', [])
groups += user_obj.get('memberofindirect_group', [])
elif principal_type == 'host':
- host_obj = api.Command.host_show(name)['result']
+ host_obj = api.Command.host_show(principal.hostname)['result']
groups = host_obj.get('memberof_hostgroup', [])
groups += host_obj.get('memberofindirect_hostgroup', [])
req.user.groups = sorted(set(groups))
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
index 4cd2ab096..2f7904cd7 100644
--- a/ipaserver/plugins/cert.py
+++ b/ipaserver/plugins/cert.py
@@ -38,18 +38,18 @@ from ipalib import ngettext
from ipalib.constants import IPA_CA_CN
from ipalib.crud import Create, PKQuery, Retrieve, Search
from ipalib.frontend import Method, Object
-from ipalib.parameters import Bytes, DateTime, DNParam
+from ipalib.parameters import Bytes, DateTime, DNParam, Principal
from ipalib.plugable import Registry
from .virtual import VirtualCommand
from .baseldap import pkey_to_value
-from .service import split_any_principal
from .certprofile import validate_profile_id
from .caacl import acl_evaluate
from ipalib.text import _
from ipalib.request import context
from ipalib import output
-from .service import validate_principal
+from ipapython import kerberos
from ipapython.dn import DN
+from ipaserver.plugins.service import normalize_principal, validate_realm
if six.PY3:
unicode = str
@@ -216,35 +216,21 @@ def normalize_serial_number(num):
return unicode(num)
-def get_host_from_principal(principal):
- """
- Given a principal with or without a realm return the
- host portion.
- """
- validate_principal(None, principal)
- realm = principal.find('@')
- slash = principal.find('/')
- if realm == -1:
- realm = len(principal)
- hostname = principal[slash+1:realm]
-
- return hostname
-
def ca_enabled_check():
if not api.Command.ca_is_enabled()['result']:
raise errors.NotFound(reason=_('CA is not configured'))
-def caacl_check(principal_type, principal_string, ca, profile_id):
+def caacl_check(principal_type, principal, ca, profile_id):
principal_type_map = {USER: 'user', HOST: 'host', SERVICE: 'service'}
if not acl_evaluate(
principal_type_map[principal_type],
- principal_string, ca, profile_id):
+ principal, ca, profile_id):
raise errors.ACIError(info=_(
"Principal '%(principal)s' "
"is not permitted to use CA '%(ca)s' "
"with profile '%(profile_id)s' for certificate issuance."
) % dict(
- principal=principal_string,
+ principal=unicode(principal),
ca=ca,
profile_id=profile_id
)
@@ -386,10 +372,12 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
operation="request certificate"
takes_options = (
- Str(
+ Principal(
'principal',
+ validate_realm,
label=_('Principal'),
doc=_('Principal for this certificate (e.g. HTTP/test.example.com)'),
+ normalizer=normalize_principal
),
Flag(
'add',
@@ -432,27 +420,29 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
taskgroup (directly or indirectly via role membership).
"""
- principal_string = kw.get('principal')
- principal = split_any_principal(principal_string)
- servicename, principal_name, realm = principal
- if servicename is None:
+ principal = kw.get('principal')
+ principal_string = unicode(principal)
+
+ if principal.is_user:
principal_type = USER
- elif servicename == 'host':
+ elif principal.is_host:
principal_type = HOST
else:
principal_type = SERVICE
- bind_principal = split_any_principal(getattr(context, 'principal'))
- bind_service, bind_name, bind_realm = bind_principal
+ bind_principal = kerberos.Principal(
+ getattr(context, 'principal'))
+ bind_principal_string = unicode(bind_principal)
- if bind_service is None:
+ if bind_principal.is_user:
bind_principal_type = USER
- elif bind_service == 'host':
+ elif bind_principal.is_host:
bind_principal_type = HOST
else:
bind_principal_type = SERVICE
- if bind_principal != principal and bind_principal_type != HOST:
+ if (bind_principal_string != principal_string and
+ bind_principal_type != HOST):
# Can the bound principal request certs for another principal?
self.check_access()
@@ -463,7 +453,7 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
bypass_caacl = False
if not bypass_caacl:
- caacl_check(principal_type, principal_string, ca, profile_id)
+ caacl_check(principal_type, principal, ca, profile_id)
try:
subject = pkcs10.get_subject(csr)
@@ -474,7 +464,8 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
error=_("Failure decoding Certificate Signing Request: %s") % e)
# self-service and host principals may bypass SAN permission check
- if bind_principal != principal and bind_principal_type != HOST:
+ if (bind_principal_string != principal_string
+ and bind_principal_type != HOST):
if '2.5.29.17' in extensions:
self.check_access('request certificate with subjectaltname')
@@ -486,9 +477,11 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
if principal_type == SERVICE:
principal_obj = api.Command['service_show'](principal_string, all=True)
elif principal_type == HOST:
- principal_obj = api.Command['host_show'](principal_name, all=True)
+ principal_obj = api.Command['host_show'](
+ principal.hostname, all=True)
elif principal_type == USER:
- principal_obj = api.Command['user_show'](principal_name, all=True)
+ principal_obj = api.Command['user_show'](
+ principal.username, all=True)
except errors.NotFound as e:
if add:
if principal_type == SERVICE:
@@ -512,14 +505,14 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
error=_("No Common Name was found in subject of request."))
if principal_type in (SERVICE, HOST):
- if cn.lower() != principal_name.lower():
+ if cn.lower() != principal.hostname.lower():
raise errors.ACIError(
info=_("hostname in subject of request '%(cn)s' "
"does not match principal hostname '%(hostname)s'")
- % dict(cn=cn, hostname=principal_name))
+ % dict(cn=cn, hostname=principal.hostname))
elif principal_type == USER:
# check user name
- if cn != principal_name:
+ if cn != principal.username:
raise errors.ValidationError(
name='csr',
error=_("DN commonName does not match user's login")
@@ -545,13 +538,11 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
if name_type == pkcs10.SAN_DNSNAME:
name = unicode(name)
alt_principal_obj = None
- alt_principal_string = None
+ alt_principal_string = unicode(principal)
try:
if principal_type == HOST:
- alt_principal_string = 'host/%s@%s' % (name, realm)
alt_principal_obj = api.Command['host_show'](name, all=True)
elif principal_type == SERVICE:
- alt_principal_string = '%s/%s@%s' % (servicename, name, realm)
alt_principal_obj = api.Command['service_show'](
alt_principal_string, all=True)
elif principal_type == USER:
@@ -574,11 +565,10 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
"Insufficient privilege to create a certificate "
"with subject alt name '%s'.") % name)
if alt_principal_string is not None and not bypass_caacl:
- caacl_check(
- principal_type, alt_principal_string, ca, profile_id)
+ caacl_check(principal_type, principal, ca, profile_id)
elif name_type in (pkcs10.SAN_OTHERNAME_KRB5PRINCIPALNAME,
pkcs10.SAN_OTHERNAME_UPN):
- if split_any_principal(name) != principal:
+ if name != principal_string:
raise errors.ACIError(
info=_("Principal '%s' in subject alt name does not "
"match requested principal") % name)
@@ -619,9 +609,9 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
if principal_type == SERVICE:
api.Command['service_mod'](principal_string, **kwargs)
elif principal_type == HOST:
- api.Command['host_mod'](principal_name, **kwargs)
+ api.Command['host_mod'](principal.hostname, **kwargs)
elif principal_type == USER:
- api.Command['user_mod'](principal_name, **kwargs)
+ api.Command['user_mod'](principal.username, **kwargs)
return dict(
result=result,
@@ -748,10 +738,10 @@ class cert_show(Retrieve, CertMethod, VirtualCommand):
self.check_access()
except errors.ACIError as acierr:
self.debug("Not granted by ACI to retrieve certificate, looking at principal")
- bind_principal = getattr(context, 'principal')
- if not bind_principal.startswith('host/'):
+ bind_principal = kerberos.Principal(getattr(context, 'principal'))
+ if not bind_principal.is_host:
raise acierr
- hostname = get_host_from_principal(bind_principal)
+ hostname = bind_principal.hostname
ca_obj = api.Command.ca_show(options['cacn'])['result']
issuer_dn = ca_obj['ipacasubjectdn'][0]
diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py
index de0aca5ca..6210e8c16 100644
--- a/ipaserver/plugins/host.py
+++ b/ipaserver/plugins/host.py
@@ -25,6 +25,7 @@ import six
from ipalib import api, errors, util
from ipalib import messages
from ipalib import Str, Flag, Bytes
+from ipalib.parameters import Principal
from ipalib.plugable import Registry
from .baseldap import (LDAPQuery, LDAPObject, LDAPCreate,
LDAPDelete, LDAPUpdate, LDAPSearch,
@@ -32,7 +33,8 @@ from .baseldap import (LDAPQuery, LDAPObject, LDAPCreate,
LDAPRemoveMember, host_is_master,
pkey_to_value, add_missing_object_class,
LDAPAddAttribute, LDAPRemoveAttribute)
-from .service import (split_principal, validate_certificate,
+from ipaserver.plugins.service import (
+ validate_realm, normalize_principal, validate_certificate,
set_certificate_attrs, ticket_flags_params, update_krbticketflags,
set_kerberos_attrs, rename_ipaallowedtoperform_from_ldap,
rename_ipaallowedtoperform_to_ldap, revoke_certs)
@@ -56,6 +58,7 @@ from ipapython.ipautil import ipa_generate_password, CheckedIPAddress
from ipapython.dnsutil import DNSName
from ipapython.ssh import SSHPublicKey
from ipapython.dn import DN
+from ipapython import kerberos
from functools import reduce
if six.PY3:
@@ -509,8 +512,11 @@ class host(LDAPObject):
label=_('Revocation reason'),
flags={'virtual_attribute', 'no_create', 'no_update', 'no_search'},
),
- Str('krbprincipalname?',
+ Principal(
+ 'krbprincipalname?',
+ validate_realm,
label=_('Principal name'),
+ normalizer=normalize_principal,
flags=['no_create', 'no_update', 'no_search'],
),
Str('macaddress*',
@@ -758,8 +764,9 @@ class host_del(LDAPDelete):
break
else:
for entry_attrs in services:
- principal = entry_attrs['krbprincipalname'][0]
- (service, hostname, realm) = split_principal(principal)
+ principal = kerberos.Principal(
+ entry_attrs['krbprincipalname'][0])
+ hostname = principal.hostname
if hostname.lower() == fqdn:
api.Command['service_del'](principal)
updatedns = options.get('updatedns', False)
@@ -830,10 +837,13 @@ class host_mod(LDAPUpdate):
member_attributes = ['managedby']
takes_options = LDAPUpdate.takes_options + (
- Str('krbprincipalname?',
+ Principal(
+ 'krbprincipalname?',
+ validate_realm,
cli_name='principalname',
label=_('Principal name'),
doc=_('Kerberos principal name for this host'),
+ normalizer=normalize_principal,
attribute=True,
),
Flag('updatedns?',
@@ -1155,8 +1165,9 @@ class host_disable(LDAPQuery):
break
else:
for entry_attrs in services:
- principal = entry_attrs['krbprincipalname'][0]
- (service, hostname, realm) = split_principal(principal)
+ principal = kerberos.Principal(
+ entry_attrs['krbprincipalname'][0])
+ hostname = principal.hostname
if hostname.lower() == fqdn:
try:
api.Command['service_disable'](principal)
diff --git a/ipaserver/plugins/passwd.py b/ipaserver/plugins/passwd.py
index 253a0d35d..1576c4ca8 100644
--- a/ipaserver/plugins/passwd.py
+++ b/ipaserver/plugins/passwd.py
@@ -17,15 +17,22 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+import six
+
from ipalib import api, errors, krb_utils
from ipalib import Command
-from ipalib import Str, Password
+from ipalib import Password
from ipalib import _
from ipalib import output
+from ipalib.parameters import Principal
from ipalib.plugable import Registry
-from .baseuser import validate_principal, normalize_principal
from ipalib.request import context
+from ipapython import kerberos
from ipapython.dn import DN
+from ipaserver.plugins.service import validate_realm, normalize_principal
+
+if six.PY3:
+ unicode = str
__doc__ = _("""
Set a user's password
@@ -59,7 +66,7 @@ def get_current_password(principal):
be ignored later.
"""
current_principal = krb_utils.get_principal()
- if current_principal == normalize_principal(principal):
+ if current_principal == unicode(normalize_principal(principal)):
return None
else:
return MAGIC_VALUE
@@ -69,12 +76,14 @@ class passwd(Command):
__doc__ = _("Set a user's password.")
takes_args = (
- Str('principal', validate_principal,
+ Principal(
+ 'principal',
+ validate_realm,
cli_name='user',
label=_('User name'),
primary_key=True,
autofill=True,
- default_from=lambda: krb_utils.get_principal(),
+ default_from=lambda: kerberos.Principal(krb_utils.get_principal()),
normalizer=lambda value: normalize_principal(value),
),
Password('password',
@@ -114,6 +123,8 @@ class passwd(Command):
"""
ldap = self.api.Backend.ldap2
+ principal = unicode(principal)
+
entry_attrs = ldap.find_entry_by_attr(
'krbprincipalname', principal, 'posixaccount', [''],
DN(api.env.container_user, api.env.basedn)
diff --git a/ipaserver/plugins/service.py b/ipaserver/plugins/service.py
index c44ad7ac2..70bf31fd4 100644
--- a/ipaserver/plugins/service.py
+++ b/ipaserver/plugins/service.py
@@ -23,6 +23,7 @@ import six
from ipalib import api, errors, messages
from ipalib import Bytes, StrEnum, Bool, Str, Flag
+from ipalib.parameters import Principal
from ipalib.plugable import Registry
from .baseldap import (
host_is_master,
@@ -43,6 +44,7 @@ from ipalib import x509
from ipalib import _, ngettext
from ipalib import util
from ipalib import output
+from ipapython import kerberos
from ipapython.dn import DN
import nss.nss as nss
@@ -176,55 +178,29 @@ _ticket_flags_map = {
_ticket_flags_default = _ticket_flags_map['ipakrbrequirespreauth']
-def split_any_principal(principal):
- service = hostname = realm = None
-
- # Break down the principal into its component parts, which may or
- # may not include the realm.
- sp = principal.split('/')
- name_and_realm = None
- if len(sp) > 2:
- raise errors.MalformedServicePrincipal(reason=_('unable to determine service'))
- elif len(sp) == 2:
- service = sp[0]
- if len(service) == 0:
- raise errors.MalformedServicePrincipal(reason=_('blank service'))
- name_and_realm = sp[1]
- else:
- name_and_realm = sp[0]
-
- sr = name_and_realm.split('@')
- if len(sr) > 2:
- raise errors.MalformedServicePrincipal(
- reason=_('unable to determine realm'))
-
- hostname = sr[0].lower()
- if len(sr) == 2:
- realm = sr[1].upper()
- # At some point we'll support multiple realms
- if realm != api.env.realm:
- raise errors.RealmMismatch()
- else:
- realm = api.env.realm
-
- # Note that realm may be None.
- return service, hostname, realm
-
-def split_principal(principal):
- service, name, realm = split_any_principal(principal)
- if service is None:
- raise errors.MalformedServicePrincipal(reason=_('missing service'))
- return service, name, realm
-
-def validate_principal(ugettext, principal):
- (service, hostname, principal) = split_principal(principal)
- return None
-
-def normalize_principal(principal):
- # The principal is already validated when it gets here
- (service, hostname, realm) = split_principal(principal)
- # Put the principal back together again
- principal = '%s/%s@%s' % (service, hostname, realm)
+
+def validate_realm(ugettext, principal):
+ """
+ Check that the principal's realm matches IPA realm if present
+ """
+ realm = principal.realm
+ if realm is not None and realm != api.env.realm:
+ raise errors.RealmMismatch()
+
+
+def normalize_principal(value):
+ """
+ Ensure that the name in the principal is lower-case. The realm is
+ upper-case by convention but it isn't required.
+
+ The principal is validated at this point.
+ """
+ try:
+ principal = kerberos.Principal(value, realm=api.env.realm)
+ except ValueError:
+ raise errors.ValidationError(
+ name='principal', reason=_("Malformed principal"))
+
return unicode(principal)
def validate_certificate(ugettext, cert):
@@ -291,16 +267,16 @@ def set_certificate_attrs(entry_attrs):
entry_attrs['md5_fingerprint'] = unicode(nss.data_to_hex(nss.md5_digest(cert.der_data), 64)[0])
entry_attrs['sha1_fingerprint'] = unicode(nss.data_to_hex(nss.sha1_digest(cert.der_data), 64)[0])
-def check_required_principal(ldap, hostname, service):
+def check_required_principal(ldap, principal):
"""
Raise an error if the host of this prinicipal is an IPA master and one
of the principals required for proper execution.
"""
try:
- host_is_master(ldap, hostname)
+ host_is_master(ldap, principal.hostname)
except errors.ValidationError as e:
service_types = ['HTTP', 'ldap', 'DNS', 'dogtagldap']
- if service in service_types:
+ if principal.service_name in service_types:
raise errors.ValidationError(name='principal', error=_('This principal is required by the IPA master'))
def update_krbticketflags(ldap, entry_attrs, attrs_list, options, existing):
@@ -457,12 +433,15 @@ class service(LDAPObject):
label_singular = _('Service')
takes_params = (
- Str('krbprincipalname', validate_principal,
+ Principal(
+ 'krbprincipalname',
+ validate_realm,
cli_name='principal',
label=_('Principal'),
doc=_('Service principal'),
primary_key=True,
- normalizer=lambda value: normalize_principal(value),
+ normalizer=normalize_principal,
+ require_service=True
),
Bytes('usercertificate*', validate_certificate,
cli_name='certificate',
@@ -560,8 +539,10 @@ class service_add(LDAPCreate):
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
assert isinstance(dn, DN)
- (service, hostname, realm) = split_principal(keys[-1])
- if service.lower() == 'host' and not options['force']:
+ principal = keys[-1]
+ hostname = principal.hostname
+
+ if principal.is_host and not options['force']:
raise errors.HostService()
try:
@@ -619,8 +600,7 @@ class service_del(LDAPDelete):
# In the case of services we don't want IPA master services to be
# deleted. This is a limited few though. If the user has their own
# custom services allow them to manage them.
- (service, hostname, realm) = split_principal(keys[-1])
- check_required_principal(ldap, hostname, service)
+ check_required_principal(ldap, keys[-1])
if self.api.Command.ca_is_enabled()['result']:
try:
entry_attrs = ldap.get_entry(dn, ['usercertificate'])
@@ -647,8 +627,6 @@ class service_mod(LDAPUpdate):
self.obj.validate_ipakrbauthzdata(entry_attrs)
- (service, hostname, realm) = split_principal(keys[-1])
-
# verify certificates
certs = entry_attrs.get('usercertificate') or []
certs_der = [x509.normalize_certificate(c) for c in certs]
@@ -873,8 +851,7 @@ class service_disable(LDAPQuery):
dn = self.obj.get_dn(*keys, **options)
entry_attrs = ldap.get_entry(dn, ['usercertificate'])
- (service, hostname, realm) = split_principal(keys[-1])
- check_required_principal(ldap, hostname, service)
+ check_required_principal(ldap, keys[-1])
# See if we do any work at all here and if not raise an exception
done_work = False
diff --git a/ipaserver/plugins/vault.py b/ipaserver/plugins/vault.py
index 380e4d478..c9b7cb942 100644
--- a/ipaserver/plugins/vault.py
+++ b/ipaserver/plugins/vault.py
@@ -17,25 +17,31 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+import six
+
from ipalib.frontend import Command, Object
from ipalib import api, errors
from ipalib import Bytes, Flag, Str, StrEnum
from ipalib import output
from ipalib.crud import PKQuery, Retrieve
+from ipalib.parameters import Principal
from ipalib.plugable import Registry
from .baseldap import LDAPObject, LDAPCreate, LDAPDelete,\
LDAPSearch, LDAPUpdate, LDAPRetrieve, LDAPAddMember, LDAPRemoveMember,\
LDAPModMember, pkey_to_value
from ipalib.request import context
-from .baseuser import split_principal
-from .service import normalize_principal
+from .service import normalize_principal, validate_realm
from ipalib import _, ngettext
+from ipapython import kerberos
from ipapython.dn import DN
if api.env.in_server:
import pki.account
import pki.key
+if six.PY3:
+ unicode = str
+
__doc__ = _("""
Vaults
""") + _("""
@@ -191,8 +197,9 @@ EXAMPLES:
register = Registry()
vault_options = (
- Str(
+ Principal(
'service?',
+ validate_realm,
doc=_('Service name of the service vault'),
normalizer=normalize_principal,
),
@@ -342,17 +349,15 @@ class vaultcontainer(LDAPObject):
parent_dn = super(vaultcontainer, self).get_dn(*keys, **options)
if not count:
- principal = getattr(context, 'principal')
+ principal = kerberos.Principal(getattr(context, 'principal'))
- if principal.startswith('host/'):
+ if principal.is_host:
raise errors.NotImplementedError(
reason=_('Host is not supported'))
-
- (name, realm) = split_principal(principal)
- if '/' in name:
- service = principal
+ elif principal.is_service:
+ service = unicode(principal)
else:
- user = name
+ user = principal.username
if service:
dn = DN(('cn', service), ('cn', 'services'), parent_dn)
@@ -660,17 +665,15 @@ class vault(LDAPObject):
rdns = DN(*dn[:-len(container_dn)])
if not count:
- principal = getattr(context, 'principal')
+ principal = kerberos.Principal(getattr(context, 'principal'))
- if principal.startswith('host/'):
+ if principal.is_host:
raise errors.NotImplementedError(
reason=_('Host is not supported'))
-
- (name, realm) = split_principal(principal)
- if '/' in name:
- service = principal
+ elif principal.is_service:
+ service = unicode(principal)
else:
- user = name
+ user = principal.username
if service:
parent_dn = DN(('cn', service), ('cn', 'services'), container_dn)
@@ -770,12 +773,11 @@ class vault_add_internal(LDAPCreate):
raise errors.InvocationError(
format=_('KRA service is not enabled'))
- principal = getattr(context, 'principal')
- (name, realm) = split_principal(principal)
- if '/' in name:
- owner_dn = self.api.Object.service.get_dn(name)
+ principal = kerberos.Principal(getattr(context, 'principal'))
+ if principal.is_service:
+ owner_dn = self.api.Object.service.get_dn(unicode(principal))
else:
- owner_dn = self.api.Object.user.get_dn(name)
+ owner_dn = self.api.Object.user.get_dn(principal.username)
parent_dn = DN(*dn[1:])
diff --git a/ipatests/test_xmlrpc/test_host_plugin.py b/ipatests/test_xmlrpc/test_host_plugin.py
index e6fc68a15..4ddabefff 100644
--- a/ipatests/test_xmlrpc/test_host_plugin.py
+++ b/ipatests/test_xmlrpc/test_host_plugin.py
@@ -357,6 +357,7 @@ class TestHostWithService(XMLRPC_test):
result=dict(
dn=service1dn,
krbprincipalname=[service1],
+ krbcanonicalname=[service1],
objectclass=objectclasses.service,
managedby_host=[host.fqdn],
ipauniqueid=[fuzzy_uuid],
diff --git a/ipatests/test_xmlrpc/test_service_plugin.py b/ipatests/test_xmlrpc/test_service_plugin.py
index 2e38b8d6b..69af06873 100644
--- a/ipatests/test_xmlrpc/test_service_plugin.py
+++ b/ipatests/test_xmlrpc/test_service_plugin.py
@@ -193,6 +193,7 @@ class test_service(Declarative):
result=dict(
dn=service1dn,
krbprincipalname=[service1],
+ krbcanonicalname=[service1],
objectclass=objectclasses.service,
ipauniqueid=[fuzzy_uuid],
managedby_host=[fqdn1],
@@ -262,6 +263,7 @@ class test_service(Declarative):
dict(
dn=service1dn,
krbprincipalname=[service1],
+ krbcanonicalname=service1,
managedby_host=[fqdn1],
has_keytab=False,
),
@@ -281,6 +283,7 @@ class test_service(Declarative):
dict(
dn=service1dn,
krbprincipalname=[service1],
+ krbcanonicalname=service1,
has_keytab=False,
),
],
@@ -619,7 +622,9 @@ class test_service(Declarative):
dict(
desc='Create service with malformed principal "foo"',
command=('service_add', [u'foo'], {}),
- expected=errors.MalformedServicePrincipal(reason='missing service')
+ expected=errors.ValidationError(
+ name='principal',
+ error='Service principal is required')
),
@@ -715,6 +720,7 @@ class test_service_in_role(Declarative):
result=dict(
dn=service1dn,
krbprincipalname=[service1],
+ krbcanonicalname=[service1],
objectclass=objectclasses.service,
ipauniqueid=[fuzzy_uuid],
managedby_host=[fqdn1],
@@ -919,6 +925,7 @@ class test_service_allowed_to(Declarative):
result=dict(
dn=service1dn,
krbprincipalname=[service1],
+ krbcanonicalname=[service1],
objectclass=objectclasses.service,
ipauniqueid=[fuzzy_uuid],
managedby_host=[fqdn1],
diff --git a/ipatests/test_xmlrpc/test_stageuser_plugin.py b/ipatests/test_xmlrpc/test_stageuser_plugin.py
index 96f7e22b3..34cfaf87a 100644
--- a/ipatests/test_xmlrpc/test_stageuser_plugin.py
+++ b/ipatests/test_xmlrpc/test_stageuser_plugin.py
@@ -345,9 +345,9 @@ class TestCreateInvalidAttributes(XMLRPC_test):
stageduser.ensure_missing()
command = stageduser.make_create_command(
options={u'krbprincipalname': invalidrealm2})
- with raises_exact(errors.MalformedUserPrincipal(
- message=u'Principal is not of the form user@REALM: \'%s\'' %
- invalidrealm2)):
+ with raises_exact(errors.ConversionError(
+ name='principal', error="Malformed principal: '{}'".format(
+ invalidrealm2))):
command()
diff --git a/ipatests/test_xmlrpc/test_user_plugin.py b/ipatests/test_xmlrpc/test_user_plugin.py
index 6d58c53aa..8245dc7f0 100644
--- a/ipatests/test_xmlrpc/test_user_plugin.py
+++ b/ipatests/test_xmlrpc/test_user_plugin.py
@@ -806,8 +806,9 @@ class TestPrincipals(XMLRPC_test):
)
command = testuser.make_create_command()
- with raises_exact(errors.MalformedUserPrincipal(
- principal=u'tuser1@BAD@NOTFOUND.ORG')):
+ with raises_exact(errors.ConversionError(
+ name='principal', error="Malformed principal: '{}'".format(
+ testuser.kwargs['krbprincipalname']))):
command()
def test_set_principal_expiration(self, user):