Provide API for management of host, service, and user principal aliases

New commands (*-{add,remove}-principal [PKEY] [PRINCIPAL ...])
were added to manage principal aliases.

'add' commands will check the following:
* the correct principal type is supplied as an alias
* the principals have correct realm and the realm/alternative suffix (e.g.
  e-mail) do not overlap with those of trusted AD domains

If the entry does not have canonical principal name, the first returned
principal name will be set as one. This is mostly to smoothly operate on
entries created on older servers.

'remove' commands will check that there is at least one principal alias equal
to the canonical name left on the entry.

See also: http://www.freeipa.org/page/V4/Kerberos_principal_aliases

https://fedorahosted.org/freeipa/ticket/1365
https://fedorahosted.org/freeipa/ticket/3961
https://fedorahosted.org/freeipa/ticket/5413

Reviewed-By: David Kupka <dkupka@redhat.com>
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
Martin Babinsky 2016-06-23 20:06:42 +02:00 committed by Martin Basti
parent a28d312796
commit e6ff83e361
8 changed files with 299 additions and 42 deletions

View File

@ -135,6 +135,8 @@ aci: (targetattr = "krblastpwdchange || krbprincipalkey")(targetfilter = "(&(!(m
dn: cn=computers,cn=accounts,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";) 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 dn: cn=computers,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "krbcanonicalname || krbprincipalname")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Manage Host Principals";allow (write) groupdn = "ldap:///cn=System: Manage Host Principals,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=computers,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "ipasshpubkey")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Manage Host SSH Public Keys";allow (write) groupdn = "ldap:///cn=System: Manage Host SSH Public Keys,cn=permissions,cn=pbac,dc=ipa,dc=example";) aci: (targetattr = "ipasshpubkey")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Manage Host SSH Public Keys";allow (write) groupdn = "ldap:///cn=System: Manage Host SSH Public Keys,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=computers,cn=accounts,dc=ipa,dc=example dn: cn=computers,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "description || ipaassignedidview || krbprincipalauthind || l || macaddress || nshardwareplatform || nshostlocation || nsosversion || userclass")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Modify Hosts";allow (write) groupdn = "ldap:///cn=System: Modify Hosts,cn=permissions,cn=pbac,dc=ipa,dc=example";) aci: (targetattr = "description || ipaassignedidview || krbprincipalauthind || l || macaddress || nshardwareplatform || nshostlocation || nsosversion || userclass")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Modify Hosts";allow (write) groupdn = "ldap:///cn=System: Modify Hosts,cn=permissions,cn=pbac,dc=ipa,dc=example";)
@ -249,6 +251,8 @@ aci: (targetattr = "krblastpwdchange || krbprincipalkey")(targetfilter = "(objec
dn: cn=services,cn=accounts,dc=ipa,dc=example dn: cn=services,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "createtimestamp || entryusn || ipaallowedtoperform;read_keys || ipaallowedtoperform;write_keys || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaservice)")(version 3.0;acl "permission:System: Manage Service Keytab Permissions";allow (compare,read,search,write) groupdn = "ldap:///cn=System: Manage Service Keytab Permissions,cn=permissions,cn=pbac,dc=ipa,dc=example";) aci: (targetattr = "createtimestamp || entryusn || ipaallowedtoperform;read_keys || ipaallowedtoperform;write_keys || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaservice)")(version 3.0;acl "permission:System: Manage Service Keytab Permissions";allow (compare,read,search,write) groupdn = "ldap:///cn=System: Manage Service Keytab Permissions,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=services,cn=accounts,dc=ipa,dc=example dn: cn=services,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "krbcanonicalname || krbprincipalname")(targetfilter = "(objectclass=ipaservice)")(version 3.0;acl "permission:System: Manage Service Principals";allow (write) groupdn = "ldap:///cn=System: Manage Service Principals,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=services,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "krbprincipalauthind || usercertificate")(targetfilter = "(objectclass=ipaservice)")(version 3.0;acl "permission:System: Modify Services";allow (write) groupdn = "ldap:///cn=System: Modify Services,cn=permissions,cn=pbac,dc=ipa,dc=example";) aci: (targetattr = "krbprincipalauthind || usercertificate")(targetfilter = "(objectclass=ipaservice)")(version 3.0;acl "permission:System: Modify Services";allow (write) groupdn = "ldap:///cn=System: Modify Services,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=services,cn=accounts,dc=ipa,dc=example dn: cn=services,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "createtimestamp || entryusn || ipakrbauthzdata || ipakrbprincipalalias || ipauniqueid || krbcanonicalname || krblastpwdchange || krbobjectreferences || krbpasswordexpiration || krbprincipalaliases || krbprincipalauthind || krbprincipalexpiration || krbprincipalname || managedby || memberof || modifytimestamp || objectclass || usercertificate")(targetfilter = "(objectclass=ipaservice)")(version 3.0;acl "permission:System: Read Services";allow (compare,read,search) userdn = "ldap:///all";) aci: (targetattr = "createtimestamp || entryusn || ipakrbauthzdata || ipakrbprincipalalias || ipauniqueid || krbcanonicalname || krblastpwdchange || krbobjectreferences || krbpasswordexpiration || krbprincipalaliases || krbprincipalauthind || krbprincipalexpiration || krbprincipalname || managedby || memberof || modifytimestamp || objectclass || usercertificate")(targetfilter = "(objectclass=ipaservice)")(version 3.0;acl "permission:System: Read Services";allow (compare,read,search) userdn = "ldap:///all";)
@ -335,6 +339,8 @@ aci: (targetattr = "krbprincipalkey || passwordhistory || sambalmpassword || sam
dn: cn=users,cn=accounts,dc=ipa,dc=example dn: cn=users,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "usercertificate")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Manage User Certificates";allow (write) groupdn = "ldap:///cn=System: Manage User Certificates,cn=permissions,cn=pbac,dc=ipa,dc=example";) aci: (targetattr = "usercertificate")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Manage User Certificates";allow (write) groupdn = "ldap:///cn=System: Manage User Certificates,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=users,cn=accounts,dc=ipa,dc=example dn: cn=users,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "krbcanonicalname || krbprincipalname")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Manage User Principals";allow (write) groupdn = "ldap:///cn=System: Manage User Principals,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=users,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "ipasshpubkey")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Manage User SSH Public Keys";allow (write) groupdn = "ldap:///cn=System: Manage User SSH Public Keys,cn=permissions,cn=pbac,dc=ipa,dc=example";) aci: (targetattr = "ipasshpubkey")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Manage User SSH Public Keys";allow (write) groupdn = "ldap:///cn=System: Manage User SSH Public Keys,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=users,cn=accounts,dc=ipa,dc=example dn: cn=users,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "businesscategory || carlicense || cn || departmentnumber || description || displayname || employeenumber || employeetype || facsimiletelephonenumber || gecos || givenname || homephone || inetuserhttpurl || initials || l || labeleduri || loginshell || mail || manager || mepmanagedentry || mobile || objectclass || ou || pager || postalcode || preferredlanguage || roomnumber || secretary || seealso || sn || st || street || telephonenumber || title || userclass")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Modify Users";allow (write) groupdn = "ldap:///cn=System: Modify Users,cn=permissions,cn=pbac,dc=ipa,dc=example";) aci: (targetattr = "businesscategory || carlicense || cn || departmentnumber || description || displayname || employeenumber || employeetype || facsimiletelephonenumber || gecos || givenname || homephone || inetuserhttpurl || initials || l || labeleduri || loginshell || mail || manager || mepmanagedentry || mobile || objectclass || ou || pager || postalcode || preferredlanguage || roomnumber || secretary || seealso || sn || st || street || telephonenumber || title || userclass")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Modify Users";allow (write) groupdn = "ldap:///cn=System: Modify Users,cn=permissions,cn=pbac,dc=ipa,dc=example";)

93
API.txt
View File

@ -2310,6 +2310,17 @@ option: Str('version?')
output: Output('completed', type=[<type 'int'>]) output: Output('completed', type=[<type 'int'>])
output: Output('failed', type=[<type 'dict'>]) output: Output('failed', type=[<type 'dict'>])
output: Entry('result') output: Entry('result')
command: host_add_principal/1
args: 2,4,3
arg: Str('fqdn', cli_name='hostname')
arg: Principal('krbprincipalname+', alwaysask=True)
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: Str('version?')
output: Entry('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: host_allow_create_keytab/1 command: host_allow_create_keytab/1
args: 1,8,3 args: 1,8,3
arg: Str('fqdn', cli_name='hostname') arg: Str('fqdn', cli_name='hostname')
@ -2436,7 +2447,7 @@ option: Bool('ipakrbokasdelegate?', autofill=False, cli_name='ok_as_delegate')
option: Bool('ipakrbrequirespreauth?', autofill=False, cli_name='requires_pre_auth') option: Bool('ipakrbrequirespreauth?', autofill=False, cli_name='requires_pre_auth')
option: Str('ipasshpubkey*', autofill=False, cli_name='sshpubkey') option: Str('ipasshpubkey*', autofill=False, cli_name='sshpubkey')
option: Str('krbprincipalauthind*', autofill=False, cli_name='auth_ind') option: Str('krbprincipalauthind*', autofill=False, cli_name='auth_ind')
option: Principal('krbprincipalname?', cli_name='principalname') option: Principal('krbprincipalname*', autofill=False)
option: Str('l?', autofill=False, cli_name='locality') option: Str('l?', autofill=False, cli_name='locality')
option: Str('macaddress*', autofill=False) option: Str('macaddress*', autofill=False)
option: Flag('no_members', autofill=True, default=False) option: Flag('no_members', autofill=True, default=False)
@ -2477,6 +2488,17 @@ option: Str('version?')
output: Output('completed', type=[<type 'int'>]) output: Output('completed', type=[<type 'int'>])
output: Output('failed', type=[<type 'dict'>]) output: Output('failed', type=[<type 'dict'>])
output: Entry('result') output: Entry('result')
command: host_remove_principal/1
args: 2,4,3
arg: Str('fqdn', cli_name='hostname')
arg: Principal('krbprincipalname+', alwaysask=True)
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: Str('version?')
output: Entry('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: host_show/1 command: host_show/1
args: 1,6,3 args: 1,6,3
arg: Str('fqdn', cli_name='hostname') arg: Str('fqdn', cli_name='hostname')
@ -4309,6 +4331,17 @@ option: Str('version?')
output: Output('completed', type=[<type 'int'>]) output: Output('completed', type=[<type 'int'>])
output: Output('failed', type=[<type 'dict'>]) output: Output('failed', type=[<type 'dict'>])
output: Entry('result') output: Entry('result')
command: service_add_principal/1
args: 2,4,3
arg: Principal('krbcanonicalname', cli_name='canonical_principal')
arg: Principal('krbprincipalname+', alwaysask=True, 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)
option: Str('version?')
output: Entry('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: service_allow_create_keytab/1 command: service_allow_create_keytab/1
args: 1,8,3 args: 1,8,3
arg: Principal('krbcanonicalname', cli_name='canonical_principal') arg: Principal('krbcanonicalname', cli_name='canonical_principal')
@ -4387,7 +4420,7 @@ 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: StrEnum('ipakrbauthzdata*', autofill=False, cli_name='pac_type', values=[u'MS-PAC', u'PAD', u'NONE'])
option: Principal('krbcanonicalname?', autofill=False, cli_name='canonical_principal') option: Principal('krbcanonicalname?', autofill=False, cli_name='canonical_principal')
option: Str('krbprincipalauthind*', autofill=False, cli_name='auth_ind') option: Str('krbprincipalauthind*', autofill=False, cli_name='auth_ind')
option: Principal('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: Str('man_by_host*', cli_name='man_by_hosts')
option: Flag('no_members', autofill=True, default=True) option: Flag('no_members', autofill=True, default=True)
option: Str('not_man_by_host*', cli_name='not_man_by_hosts') option: Str('not_man_by_host*', cli_name='not_man_by_hosts')
@ -4401,7 +4434,7 @@ output: ListOfEntries('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>]) output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: Output('truncated', type=[<type 'bool'>]) output: Output('truncated', type=[<type 'bool'>])
command: service_mod/1 command: service_mod/1
args: 1,13,3 args: 1,14,3
arg: Principal('krbcanonicalname', cli_name='canonical_principal') arg: Principal('krbcanonicalname', cli_name='canonical_principal')
option: Str('addattr*', cli_name='addattr') option: Str('addattr*', cli_name='addattr')
option: Flag('all', autofill=True, cli_name='all', default=False) option: Flag('all', autofill=True, cli_name='all', default=False)
@ -4410,6 +4443,7 @@ option: StrEnum('ipakrbauthzdata*', autofill=False, cli_name='pac_type', values=
option: Bool('ipakrbokasdelegate?', autofill=False, cli_name='ok_as_delegate') option: Bool('ipakrbokasdelegate?', autofill=False, cli_name='ok_as_delegate')
option: Bool('ipakrbrequirespreauth?', autofill=False, cli_name='requires_pre_auth') option: Bool('ipakrbrequirespreauth?', autofill=False, cli_name='requires_pre_auth')
option: Str('krbprincipalauthind*', autofill=False, cli_name='auth_ind') option: Str('krbprincipalauthind*', autofill=False, cli_name='auth_ind')
option: Principal('krbprincipalname*', autofill=False, cli_name='principal')
option: Flag('no_members', autofill=True, default=False) option: Flag('no_members', autofill=True, default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False) option: Flag('raw', autofill=True, cli_name='raw', default=False)
option: Flag('rights', autofill=True, default=False) option: Flag('rights', autofill=True, default=False)
@ -4441,6 +4475,17 @@ option: Str('version?')
output: Output('completed', type=[<type 'int'>]) output: Output('completed', type=[<type 'int'>])
output: Output('failed', type=[<type 'dict'>]) output: Output('failed', type=[<type 'dict'>])
output: Entry('result') output: Entry('result')
command: service_remove_principal/1
args: 2,4,3
arg: Principal('krbcanonicalname', cli_name='canonical_principal')
arg: Principal('krbprincipalname+', alwaysask=True, 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)
option: Str('version?')
output: Entry('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: service_show/1 command: service_show/1
args: 1,6,3 args: 1,6,3
arg: Principal('krbcanonicalname', cli_name='canonical_principal') arg: Principal('krbcanonicalname', cli_name='canonical_principal')
@ -4647,7 +4692,7 @@ option: Str('ipatokenradiusconfiglink?', cli_name='radius')
option: Str('ipatokenradiususername?', cli_name='radius_username') option: Str('ipatokenradiususername?', cli_name='radius_username')
option: StrEnum('ipauserauthtype*', cli_name='user_auth_type', values=[u'password', u'radius', u'otp']) option: StrEnum('ipauserauthtype*', cli_name='user_auth_type', values=[u'password', u'radius', u'otp'])
option: DateTime('krbprincipalexpiration?', cli_name='principal_expiration') option: DateTime('krbprincipalexpiration?', cli_name='principal_expiration')
option: Principal('krbprincipalname?', autofill=True, cli_name='principal') option: Principal('krbprincipalname*', autofill=True, cli_name='principal')
option: Str('l?', cli_name='city') option: Str('l?', cli_name='city')
option: Str('loginshell?', cli_name='shell') option: Str('loginshell?', cli_name='shell')
option: Str('mail*', cli_name='email') option: Str('mail*', cli_name='email')
@ -4718,7 +4763,7 @@ option: Str('ipatokenradiusconfiglink?', autofill=False, cli_name='radius')
option: Str('ipatokenradiususername?', autofill=False, cli_name='radius_username') 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: 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: DateTime('krbprincipalexpiration?', autofill=False, cli_name='principal_expiration')
option: Principal('krbprincipalname?', autofill=False, cli_name='principal') option: Principal('krbprincipalname*', autofill=False, cli_name='principal')
option: Str('l?', autofill=False, cli_name='city') option: Str('l?', autofill=False, cli_name='city')
option: Str('loginshell?', autofill=False, cli_name='shell') option: Str('loginshell?', autofill=False, cli_name='shell')
option: Str('mail*', autofill=False, cli_name='email') option: Str('mail*', autofill=False, cli_name='email')
@ -4754,7 +4799,7 @@ output: ListOfEntries('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>]) output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: Output('truncated', type=[<type 'bool'>]) output: Output('truncated', type=[<type 'bool'>])
command: stageuser_mod/1 command: stageuser_mod/1
args: 1,45,3 args: 1,46,3
arg: Str('uid', cli_name='login') arg: Str('uid', cli_name='login')
option: Str('addattr*', cli_name='addattr') option: Str('addattr*', cli_name='addattr')
option: Flag('all', autofill=True, cli_name='all', default=False) option: Flag('all', autofill=True, cli_name='all', default=False)
@ -4776,6 +4821,7 @@ option: Str('ipatokenradiusconfiglink?', autofill=False, cli_name='radius')
option: Str('ipatokenradiususername?', autofill=False, cli_name='radius_username') 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: 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: DateTime('krbprincipalexpiration?', autofill=False, cli_name='principal_expiration')
option: Principal('krbprincipalname*', autofill=False, cli_name='principal')
option: Str('l?', autofill=False, cli_name='city') option: Str('l?', autofill=False, cli_name='city')
option: Str('loginshell?', autofill=False, cli_name='shell') option: Str('loginshell?', autofill=False, cli_name='shell')
option: Str('mail*', autofill=False, cli_name='email') option: Str('mail*', autofill=False, cli_name='email')
@ -5634,7 +5680,7 @@ option: Str('ipatokenradiusconfiglink?', cli_name='radius')
option: Str('ipatokenradiususername?', cli_name='radius_username') option: Str('ipatokenradiususername?', cli_name='radius_username')
option: StrEnum('ipauserauthtype*', cli_name='user_auth_type', values=[u'password', u'radius', u'otp']) option: StrEnum('ipauserauthtype*', cli_name='user_auth_type', values=[u'password', u'radius', u'otp'])
option: DateTime('krbprincipalexpiration?', cli_name='principal_expiration') option: DateTime('krbprincipalexpiration?', cli_name='principal_expiration')
option: Principal('krbprincipalname?', autofill=True, cli_name='principal') option: Principal('krbprincipalname*', autofill=True, cli_name='principal')
option: Str('l?', cli_name='city') option: Str('l?', cli_name='city')
option: Str('loginshell?', cli_name='shell') option: Str('loginshell?', cli_name='shell')
option: Str('mail*', cli_name='email') option: Str('mail*', cli_name='email')
@ -5685,6 +5731,17 @@ option: Str('version?')
output: Output('completed', type=[<type 'int'>]) output: Output('completed', type=[<type 'int'>])
output: Output('failed', type=[<type 'dict'>]) output: Output('failed', type=[<type 'dict'>])
output: Entry('result') output: Entry('result')
command: user_add_principal/1
args: 2,4,3
arg: Str('uid', cli_name='login')
arg: Principal('krbprincipalname+', alwaysask=True, autofill=True, 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)
option: Str('version?')
output: Entry('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: user_del/1 command: user_del/1
args: 1,3,3 args: 1,3,3
arg: Str('uid+', cli_name='login') arg: Str('uid+', cli_name='login')
@ -5733,7 +5790,7 @@ option: Str('ipatokenradiusconfiglink?', autofill=False, cli_name='radius')
option: Str('ipatokenradiususername?', autofill=False, cli_name='radius_username') 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: 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: DateTime('krbprincipalexpiration?', autofill=False, cli_name='principal_expiration')
option: Principal('krbprincipalname?', autofill=False, cli_name='principal') option: Principal('krbprincipalname*', autofill=False, cli_name='principal')
option: Str('l?', autofill=False, cli_name='city') option: Str('l?', autofill=False, cli_name='city')
option: Str('loginshell?', autofill=False, cli_name='shell') option: Str('loginshell?', autofill=False, cli_name='shell')
option: Str('mail*', autofill=False, cli_name='email') option: Str('mail*', autofill=False, cli_name='email')
@ -5772,7 +5829,7 @@ output: ListOfEntries('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>]) output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: Output('truncated', type=[<type 'bool'>]) output: Output('truncated', type=[<type 'bool'>])
command: user_mod/1 command: user_mod/1
args: 1,46,3 args: 1,47,3
arg: Str('uid', cli_name='login') arg: Str('uid', cli_name='login')
option: Str('addattr*', cli_name='addattr') option: Str('addattr*', cli_name='addattr')
option: Flag('all', autofill=True, cli_name='all', default=False) option: Flag('all', autofill=True, cli_name='all', default=False)
@ -5794,6 +5851,7 @@ option: Str('ipatokenradiusconfiglink?', autofill=False, cli_name='radius')
option: Str('ipatokenradiususername?', autofill=False, cli_name='radius_username') 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: 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: DateTime('krbprincipalexpiration?', autofill=False, cli_name='principal_expiration')
option: Principal('krbprincipalname*', autofill=False, cli_name='principal')
option: Str('l?', autofill=False, cli_name='city') option: Str('l?', autofill=False, cli_name='city')
option: Str('loginshell?', autofill=False, cli_name='shell') option: Str('loginshell?', autofill=False, cli_name='shell')
option: Str('mail*', autofill=False, cli_name='email') option: Str('mail*', autofill=False, cli_name='email')
@ -5845,6 +5903,17 @@ option: Str('version?')
output: Output('completed', type=[<type 'int'>]) output: Output('completed', type=[<type 'int'>])
output: Output('failed', type=[<type 'dict'>]) output: Output('failed', type=[<type 'dict'>])
output: Entry('result') output: Entry('result')
command: user_remove_principal/1
args: 2,4,3
arg: Str('uid', cli_name='login')
arg: Principal('krbprincipalname+', alwaysask=True, autofill=True, 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)
option: Str('version?')
output: Entry('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: user_show/1 command: user_show/1
args: 1,6,3 args: 1,6,3
arg: Str('uid', cli_name='login') arg: Str('uid', cli_name='login')
@ -6322,6 +6391,7 @@ default: host/1
default: host_add/1 default: host_add/1
default: host_add_cert/1 default: host_add_cert/1
default: host_add_managedby/1 default: host_add_managedby/1
default: host_add_principal/1
default: host_allow_create_keytab/1 default: host_allow_create_keytab/1
default: host_allow_retrieve_keytab/1 default: host_allow_retrieve_keytab/1
default: host_del/1 default: host_del/1
@ -6332,6 +6402,7 @@ default: host_find/1
default: host_mod/1 default: host_mod/1
default: host_remove_cert/1 default: host_remove_cert/1
default: host_remove_managedby/1 default: host_remove_managedby/1
default: host_remove_principal/1
default: host_show/1 default: host_show/1
default: hostgroup/1 default: hostgroup/1
default: hostgroup_add/1 default: hostgroup_add/1
@ -6491,6 +6562,7 @@ default: service/1
default: service_add/1 default: service_add/1
default: service_add_cert/1 default: service_add_cert/1
default: service_add_host/1 default: service_add_host/1
default: service_add_principal/1
default: service_allow_create_keytab/1 default: service_allow_create_keytab/1
default: service_allow_retrieve_keytab/1 default: service_allow_retrieve_keytab/1
default: service_del/1 default: service_del/1
@ -6501,6 +6573,7 @@ default: service_find/1
default: service_mod/1 default: service_mod/1
default: service_remove_cert/1 default: service_remove_cert/1
default: service_remove_host/1 default: service_remove_host/1
default: service_remove_principal/1
default: service_show/1 default: service_show/1
default: servicedelegationrule/1 default: servicedelegationrule/1
default: servicedelegationrule_add/1 default: servicedelegationrule_add/1
@ -6605,6 +6678,7 @@ default: user/1
default: user_add/1 default: user_add/1
default: user_add_cert/1 default: user_add_cert/1
default: user_add_manager/1 default: user_add_manager/1
default: user_add_principal/1
default: user_del/1 default: user_del/1
default: user_disable/1 default: user_disable/1
default: user_enable/1 default: user_enable/1
@ -6612,6 +6686,7 @@ default: user_find/1
default: user_mod/1 default: user_mod/1
default: user_remove_cert/1 default: user_remove_cert/1
default: user_remove_manager/1 default: user_remove_manager/1
default: user_remove_principal/1
default: user_show/1 default: user_show/1
default: user_stage/1 default: user_stage/1
default: user_status/1 default: user_status/1

View File

@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
# # # #
######################################################## ########################################################
IPA_API_VERSION_MAJOR=2 IPA_API_VERSION_MAJOR=2
IPA_API_VERSION_MINOR=207 IPA_API_VERSION_MINOR=208
# Last change: mbabinsk: Make framework consider krbcanonicalname as service primary key # Last change: mbabinsk: Provide API for management of host, service, and user principal aliases

View File

@ -912,3 +912,74 @@ def set_krbcanonicalname(entry_attrs):
if ('krbprincipalname' in entry_attrs if ('krbprincipalname' in entry_attrs
and 'krbcanonicalname' not in entry_attrs): and 'krbcanonicalname' not in entry_attrs):
entry_attrs['krbcanonicalname'] = entry_attrs['krbprincipalname'] entry_attrs['krbcanonicalname'] = entry_attrs['krbprincipalname']
def ensure_last_krbprincipalname(ldap, entry_attrs, *keys):
"""
ensure that the LDAP entry has at least one value of krbprincipalname
and that this value is equal to krbcanonicalname
:param ldap: LDAP connection object
:param entry_attrs: LDAP entry made prior to update
:param options: command options
"""
entry = ldap.get_entry(
entry_attrs.dn, ['krbcanonicalname', 'krbprincipalname'])
krbcanonicalname = entry.single_value.get('krbcanonicalname', None)
if krbcanonicalname in keys[-1]:
raise errors.ValidationError(
name='krbprincipalname',
error=_('at least one value equal to the canonical '
'principal name must be present')
)
def ensure_krbcanonicalname_set(ldap, entry_attrs):
old_entry = ldap.get_entry(
entry_attrs.dn,
['krbcanonicalname', 'krbprincipalname', 'objectclass'])
if old_entry.single_value.get('krbcanonicalname', None) is not None:
return
set_krbcanonicalname(old_entry)
old_entry.pop('krbprincipalname', None)
old_entry.pop('objectclass', None)
entry_attrs.update(old_entry)
def check_principal_realm_in_trust_namespace(api_instance, *keys):
"""
Check that principal name's suffix does not overlap with UPNs and realm
names of trusted forests.
:param api_instance: API instance
:param suffixes: principal suffixes
:raises: ValidationError if the suffix coincides with realm name, UPN
suffix or netbios name of trusted domains
"""
trust_objects = api_instance.Command.trust_find(u'', sizelimit=0)['result']
trust_suffix_namespace = set()
for obj in trust_objects:
trust_suffix_namespace.update(
set(upn.lower() for upn in obj['ipantadditionalsuffixes']))
trust_suffix_namespace.update(
set((obj['cn'][0].lower(), obj['ipantflatname'][0].lower())))
for principal in keys[-1]:
realm = principal.realm
upn = principal.upn_suffix if principal.is_enterprise else None
if realm in trust_suffix_namespace or upn in trust_suffix_namespace:
raise errors.ValidationError(
name='krbprincipalname',
error=_('realm or UPN suffix overlaps with trusted domain '
'namespace'))

View File

@ -27,7 +27,8 @@ from ipalib.parameters import Principal
from ipalib.plugable import Registry from ipalib.plugable import Registry
from .baseldap import ( from .baseldap import (
DN, LDAPObject, LDAPCreate, LDAPUpdate, LDAPSearch, LDAPDelete, DN, LDAPObject, LDAPCreate, LDAPUpdate, LDAPSearch, LDAPDelete,
LDAPRetrieve, LDAPAddMember, LDAPRemoveMember) LDAPRetrieve, LDAPAddAttribute, LDAPRemoveAttribute, LDAPAddMember,
LDAPRemoveMember)
from ipaserver.plugins.service import ( from ipaserver.plugins.service import (
validate_certificate, validate_realm, normalize_principal) validate_certificate, validate_realm, normalize_principal)
from ipalib.request import context from ipalib.request import context
@ -42,7 +43,10 @@ from ipalib.util import (
remove_sshpubkey_from_output_post, remove_sshpubkey_from_output_post,
remove_sshpubkey_from_output_list_post, remove_sshpubkey_from_output_list_post,
add_sshpubkey_to_attrs_pre, add_sshpubkey_to_attrs_pre,
set_krbcanonicalname set_krbcanonicalname,
check_principal_realm_in_trust_namespace,
ensure_last_krbprincipalname,
ensure_krbcanonicalname_set
) )
if six.PY3: if six.PY3:
@ -212,14 +216,20 @@ class baseuser(LDAPObject):
label=_('Login shell'), label=_('Login shell'),
), ),
Principal( Principal(
'krbprincipalname?', 'krbcanonicalname?',
validate_realm,
label=_('Principal name'),
flags={'no_option', 'no_create', 'no_update', 'no_search'},
normalizer=normalize_user_principal
),
Principal(
'krbprincipalname*',
validate_realm, validate_realm,
cli_name='principal', cli_name='principal',
label=_('Kerberos principal'), label=_('Principal alias'),
default_from=lambda uid: kerberos.Principal.from_text( default_from=lambda uid: kerberos.Principal(
uid.lower(), realm=api.env.realm), uid.lower(), realm=api.env.realm),
autofill=True, autofill=True,
flags=['no_update'],
normalizer=normalize_user_principal, normalizer=normalize_user_principal,
), ),
DateTime('krbprincipalexpiration?', DateTime('krbprincipalexpiration?',
@ -621,3 +631,20 @@ class baseuser_add_manager(LDAPAddMember):
class baseuser_remove_manager(LDAPRemoveMember): class baseuser_remove_manager(LDAPRemoveMember):
member_attributes = ['manager'] member_attributes = ['manager']
class baseuser_add_principal(LDAPAddAttribute):
attribute = 'krbprincipalname'
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
check_principal_realm_in_trust_namespace(self.api, *keys)
ensure_krbcanonicalname_set(ldap, entry_attrs)
return dn
class baseuser_remove_principal(LDAPRemoveAttribute):
attribute = 'krbprincipalname'
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
ensure_last_krbprincipalname(ldap, entry_attrs, *keys)
return dn

View File

@ -35,7 +35,7 @@ from .baseldap import (LDAPQuery, LDAPObject, LDAPCreate,
LDAPAddAttribute, LDAPRemoveAttribute, LDAPAddAttribute, LDAPRemoveAttribute,
LDAPAddAttributeViaOption, LDAPAddAttributeViaOption,
LDAPRemoveAttributeViaOption) LDAPRemoveAttributeViaOption)
from ipaserver.plugins.service import ( from .service import (
validate_realm, normalize_principal, validate_certificate, validate_realm, normalize_principal, validate_certificate,
set_certificate_attrs, ticket_flags_params, update_krbticketflags, set_certificate_attrs, ticket_flags_params, update_krbticketflags,
set_kerberos_attrs, rename_ipaallowedtoperform_from_ldap, set_kerberos_attrs, rename_ipaallowedtoperform_from_ldap,
@ -406,6 +406,12 @@ class host(LDAPObject):
'ipapermdefaultattr': {'usercertificate'}, 'ipapermdefaultattr': {'usercertificate'},
'default_privileges': {'Host Administrators', 'Host Enrollment'}, 'default_privileges': {'Host Administrators', 'Host Enrollment'},
}, },
'System: Manage Host Principals': {
'ipapermbindruletype': 'permission',
'ipapermright': {'write'},
'ipapermdefaultattr': {'krbprincipalname', 'krbcanonicalname'},
'default_privileges': {'Host Administrators', 'Host Enrollment'},
},
'System: Manage Host Enrollment Password': { 'System: Manage Host Enrollment Password': {
'ipapermbindruletype': 'permission', 'ipapermbindruletype': 'permission',
'ipapermright': {'write'}, 'ipapermright': {'write'},
@ -515,11 +521,18 @@ class host(LDAPObject):
flags={'virtual_attribute', 'no_create', 'no_update', 'no_search'}, flags={'virtual_attribute', 'no_create', 'no_update', 'no_search'},
), ),
Principal( Principal(
'krbprincipalname?', 'krbcanonicalname?',
validate_realm, validate_realm,
label=_('Principal name'), label=_('Principal name'),
normalizer=normalize_principal, normalizer=normalize_principal,
flags=['no_create', 'no_update', 'no_search'], flags={'no_create', 'no_update', 'no_search'},
),
Principal(
'krbprincipalname*',
validate_realm,
label=_('Principal alias'),
normalizer=normalize_principal,
flags=['no_create', 'no_search'],
), ),
Str('macaddress*', Str('macaddress*',
normalizer=lambda value: value.upper(), normalizer=lambda value: value.upper(),
@ -839,15 +852,6 @@ class host_mod(LDAPUpdate):
member_attributes = ['managedby'] member_attributes = ['managedby']
takes_options = LDAPUpdate.takes_options + ( takes_options = LDAPUpdate.takes_options + (
Principal(
'krbprincipalname?',
validate_realm,
cli_name='principalname',
label=_('Principal name'),
doc=_('Kerberos principal name for this host'),
normalizer=normalize_principal,
attribute=True,
),
Flag('updatedns?', Flag('updatedns?',
doc=_('Update DNS entries'), doc=_('Update DNS entries'),
default=False, default=False,
@ -1332,3 +1336,26 @@ class host_remove_cert(LDAPRemoveAttributeViaOption):
revoke_certs(options['usercertificate'], self.log) revoke_certs(options['usercertificate'], self.log)
return dn return dn
@register()
class host_add_principal(LDAPAddAttribute):
__doc__ = _('Add new principal alias to host entry')
msg_summary = _('Added new aliases to host "%(value)s"')
attribute = 'krbprincipalname'
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
util.check_principal_realm_in_trust_namespace(self.api, *keys)
util.ensure_krbcanonicalname_set(ldap, entry_attrs)
return dn
@register()
class host_remove_principal(LDAPRemoveAttribute):
__doc__ = _('Remove principal alias from a host entry')
msg_summary = _('Removed aliases from host "%(value)s"')
attribute = 'krbprincipalname'
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
util.ensure_last_krbprincipalname(ldap, entry_attrs, *keys)
return dn

View File

@ -422,6 +422,13 @@ class service(LDAPObject):
], ],
'default_privileges': {'Service Administrators'}, 'default_privileges': {'Service Administrators'},
}, },
'System: Manage Service Principals': {
'ipapermright': {'write'},
'ipapermdefaultattr': {'krbprincipalname', 'krbcanonicalname'},
'default_privileges': {
'Service Administrators',
},
},
'System: Remove Services': { 'System: Remove Services': {
'ipapermright': {'delete'}, 'ipapermright': {'delete'},
'replaces': [ 'replaces': [
@ -439,12 +446,22 @@ class service(LDAPObject):
'krbcanonicalname', 'krbcanonicalname',
validate_realm, validate_realm,
cli_name='canonical_principal', cli_name='canonical_principal',
label=_('Principal'), label=_('Principal name'),
doc=_('Service principal'), doc=_('Service principal'),
primary_key=True, primary_key=True,
normalizer=normalize_principal, normalizer=normalize_principal,
require_service=True require_service=True
), ),
Principal(
'krbprincipalname*',
validate_realm,
cli_name='principal',
label=_('Principal alias'),
doc=_('Service principal alias'),
normalizer=normalize_principal,
require_service=True,
flags={'no_create'}
),
Bytes('usercertificate*', validate_certificate, Bytes('usercertificate*', validate_certificate,
cli_name='certificate', cli_name='certificate',
label=_('Certificate'), label=_('Certificate'),
@ -503,16 +520,6 @@ class service(LDAPObject):
" Use 'radius' to allow RADIUS-based 2FA authentications." " Use 'radius' to allow RADIUS-based 2FA authentications."
" Other values may be used for custom configurations."), " 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 ) + ticket_flags_params
def validate_ipakrbauthzdata(self, entry): def validate_ipakrbauthzdata(self, entry):
@ -819,7 +826,6 @@ class service_show(LDAPRetrieve):
return dn return dn
@register() @register()
class service_add_host(LDAPAddMember): class service_add_host(LDAPAddMember):
__doc__ = _('Add hosts that can manage this service.') __doc__ = _('Add hosts that can manage this service.')
@ -978,3 +984,26 @@ class service_remove_cert(LDAPRemoveAttributeViaOption):
revoke_certs(options['usercertificate'], self.log) revoke_certs(options['usercertificate'], self.log)
return dn return dn
@register()
class service_add_principal(LDAPAddAttribute):
__doc__ = _('Add new principal alias to a service')
msg_summary = _('Added new aliases to the service principal "%(value)s"')
attribute = 'krbprincipalname'
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
util.check_principal_realm_in_trust_namespace(self.api, *keys)
util.ensure_krbcanonicalname_set(ldap, entry_attrs)
return dn
@register()
class service_remove_principal(LDAPRemoveAttribute):
__doc__ = _('Remove principal alias from a service')
msg_summary = _('Removed aliases to the service principal "%(value)s"')
attribute = 'krbprincipalname'
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
util.ensure_last_krbprincipalname(ldap, entry_attrs, *keys)
return dn

View File

@ -43,7 +43,9 @@ from .baseuser import (
convert_nsaccountlock, convert_nsaccountlock,
fix_addressbook_permission_bindrule, fix_addressbook_permission_bindrule,
baseuser_add_manager, baseuser_add_manager,
baseuser_remove_manager) baseuser_remove_manager,
baseuser_add_principal,
baseuser_remove_principal)
from .idviews import remove_ipaobject_overrides from .idviews import remove_ipaobject_overrides
from ipalib.plugable import Registry from ipalib.plugable import Registry
from .baseldap import ( from .baseldap import (
@ -287,6 +289,14 @@ class user(baseuser):
'Modify Users and Reset passwords', 'Modify Users and Reset passwords',
}, },
}, },
'System: Manage User Principals': {
'ipapermright': {'write'},
'ipapermdefaultattr': {'krbprincipalname', 'krbcanonicalname'},
'default_privileges': {
'User Administrators',
'Modify Users and Reset passwords',
},
},
'System: Modify Users': { 'System: Modify Users': {
'ipapermright': {'write'}, 'ipapermright': {'write'},
'ipapermdefaultattr': { 'ipapermdefaultattr': {
@ -1187,3 +1197,15 @@ class user_add_manager(baseuser_add_manager):
@register() @register()
class user_remove_manager(baseuser_remove_manager): class user_remove_manager(baseuser_remove_manager):
__doc__ = _("Remove a manager to the user entry") __doc__ = _("Remove a manager to the user entry")
@register()
class user_add_principal(baseuser_add_principal):
__doc__ = _('Add new principal alias to the user entry')
msg_summary = _('Added new aliases to user "%(value)s"')
@register()
class user_remove_principal(baseuser_remove_principal):
__doc__ = _('Remove principal alias from the user entry')
msg_summary = _('Removed aliases from user "%(value)s"')