freeipa/ipatests/test_xmlrpc/test_kerberos_principal_aliases.py
2016-08-16 12:13:30 +02:00

291 lines
9.4 KiB
Python

# coding: utf-8
#
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
#
import copy
import ldap
import pytest
from ipalib import errors, api
from ipapython import ipautil
from ipaplatform.paths import paths
from ipatests.util import MockLDAP
from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test
from ipatests.test_xmlrpc.tracker.user_plugin import UserTracker
from ipatests.test_xmlrpc.tracker.host_plugin import HostTracker
from ipatests.test_xmlrpc.tracker.service_plugin import ServiceTracker
from ipatests.test_xmlrpc.mock_trust import (
mocked_trust_containers, get_trust_dn, get_trusted_dom_dict,
encode_mockldap_value)
from ipatests.util import unlock_principal_password, change_principal
# Shared values for the mocked trusted domain
TRUSTED_DOMAIN_MOCK = dict(
name=u'trusted.domain.net',
sid=u'S-1-5-21-2997650941-1802118864-3094776726'
)
TRUSTED_DOMAIN_MOCK['dn'] = get_trust_dn(TRUSTED_DOMAIN_MOCK['name'])
TRUSTED_DOMAIN_MOCK['ldif'] = get_trusted_dom_dict(
TRUSTED_DOMAIN_MOCK['name'], TRUSTED_DOMAIN_MOCK['sid']
)
@pytest.yield_fixture
def trusted_domain():
"""Fixture providing mocked AD trust entries
The fixture yields after creating a mock of AD trust
entries in the directory server. After the test, the entries
are deleted from the directory.
"""
trusted_dom = TRUSTED_DOMAIN_MOCK
# Write the changes
with mocked_trust_containers(), MockLDAP() as ldap:
ldap.add_entry(trusted_dom['dn'], trusted_dom['ldif'])
yield trusted_dom
ldap.del_entry(trusted_dom['dn'])
@pytest.yield_fixture
def trusted_domain_with_suffix():
"""Fixture providing mocked AD trust entries
The fixture yields after creating a mock of AD trust
entries in the directory server. After the test, the entries
are deleted from the directory.
"""
trusted_dom = copy.deepcopy(TRUSTED_DOMAIN_MOCK)
trusted_dom['ldif']['ipaNTAdditionalSuffixes'] = (
encode_mockldap_value(trusted_dom['name'])
)
# Write the changes
with mocked_trust_containers(), MockLDAP() as ldap:
ldap.add_entry(trusted_dom['dn'], trusted_dom['ldif'])
yield trusted_dom
ldap.del_entry(trusted_dom['dn'])
@pytest.fixture(scope='function')
def krbalias_user(request):
tracker = UserTracker(u'krbalias_user', u'krbalias', u'test')
return tracker.make_fixture(request)
@pytest.fixture(scope='function')
def krbalias_user_c(request):
tracker = UserTracker(u'krbalias_user_conflict', u'krbalias', u'test')
return tracker.make_fixture(request)
@pytest.fixture(scope='function')
def krbalias_host(request):
tracker = HostTracker(u'testhost-krb')
return tracker.make_fixture(request)
@pytest.fixture
def krb_service_host(request):
tracker = HostTracker(u'krb-srv-host')
return tracker.make_fixture(request)
@pytest.fixture(scope='function')
def krbalias_service(request, krb_service_host):
krb_service_host.ensure_exists()
tracker = ServiceTracker(name=u'SRV1', host_fqdn=krb_service_host.name)
return tracker.make_fixture(request)
@pytest.fixture
def ldapservice(request):
tracker = ServiceTracker(
name=u'ldap', host_fqdn=api.env.host, options={'has_keytab': True})
tracker.track_create()
return tracker
class TestKerberosAliasManipulation(XMLRPC_test):
def test_add_user_principal_alias(self, krbalias_user):
krbalias_user.ensure_exists()
krbalias_user.add_principal([u'test-user-alias'])
krbalias_user.retrieve()
def test_remove_user_principal_alias(self, krbalias_user):
krbalias_user.ensure_exists()
krbalias_user.add_principal([u'test-user-alias'])
krbalias_user.remove_principal(u'test-user-alias')
krbalias_user.retrieve()
def test_add_host_principal_alias(self, krbalias_host):
krbalias_host.ensure_exists()
krbalias_host.add_principal([u'testhost-krb-alias'])
krbalias_host.retrieve()
def test_remove_host_principal_alias(self, krbalias_host):
krbalias_host.ensure_exists()
krbalias_host.add_principal([u'testhost-krb-alias'])
krbalias_host.retrieve()
krbalias_host.remove_principal([u'testhost-krb-alias'])
krbalias_host.retrieve()
def test_add_service_principal_alias(self, krbalias_service):
krbalias_service.ensure_exists()
krbalias_service.add_principal(
[u'SRV2/{}'.format(krbalias_service.host_fqdn)])
krbalias_service.retrieve()
def test_remove_service_principal_alias(self, krbalias_service):
krbalias_service.ensure_exists()
krbalias_service.add_principal(
[u'SRV2/{}'.format(krbalias_service.host_fqdn)])
krbalias_service.retrieve()
krbalias_service.remove_principal(
[u'SRV2/{}'.format(krbalias_service.host_fqdn)])
krbalias_service.retrieve()
def test_adding_alias_adds_canonical_name(self, krbalias_user):
"""Test adding alias on an entry without canonical name"""
krbalias_user.ensure_exists()
user_krb_principal = krbalias_user.attrs['krbprincipalname'][0]
# Delete all values of krbcanonicalname from an LDAP entry
dn = str(krbalias_user.dn)
modlist = [(ldap.MOD_DELETE, 'krbcanonicalname', None)]
with MockLDAP() as ldapconn:
ldapconn.mod_entry(dn, modlist)
# add new user principal alias
krbalias_user.add_principal(u'krbalias_principal_canonical')
# verify that the previous principal name is now krbcanonicalname
cmd = krbalias_user.make_retrieve_command()
new_canonical_name = cmd()['result']['krbcanonicalname'][0]
assert new_canonical_name == user_krb_principal
def test_authenticate_against_aliased_service(self, ldapservice):
alias = u'ldap/{newname}.{host}'.format(
newname='krbalias', host=api.env.host)
ldapservice.add_principal(alias)
rv = ipautil.run([paths.BIN_KVNO, alias],
capture_error=True, raiseonerr=False)
ldapservice.remove_principal(alias)
assert rv.returncode == 0, rv.error_output
def test_authenticate_with_user_alias(self, krbalias_user):
krbalias_user.ensure_exists()
alias = u"{name}-alias".format(name=krbalias_user.name)
krbalias_user.add_principal(alias)
oldpw, newpw = u"Secret1234", u"Secret123"
pwdmod = krbalias_user.make_update_command({'userpassword': oldpw})
pwdmod()
unlock_principal_password(krbalias_user.name, oldpw, newpw)
with change_principal(alias, newpw, canonicalize=True):
api.Command.ping()
class TestKerberosAliasExceptions(XMLRPC_test):
def test_add_user_coliding_with_alias(self, krbalias_user):
krbalias_user.ensure_exists()
user_alias = u'conflicting_name'
krbalias_user.add_principal([user_alias])
conflict_user = UserTracker(user_alias, u'test', u'conflict')
with pytest.raises(errors.DuplicateEntry):
conflict_user.create()
def test_add_alias_to_two_entries(self, krbalias_user, krbalias_user_c):
krbalias_user.ensure_exists()
krbalias_user_c.ensure_exists()
user_alias = u'krbalias-test'
krbalias_user.add_principal([user_alias])
with pytest.raises(errors.DuplicateEntry):
krbalias_user_c.add_principal([user_alias])
def test_remove_alias_matching_canonical_name(self, krbalias_user):
krbalias_user.ensure_exists()
with pytest.raises(errors.ValidationError):
krbalias_user.remove_principal(
krbalias_user.attrs.get('krbcanonicalname'))
def test_enterprise_principal_overlap_with_AD_realm(
self, krbalias_user, trusted_domain):
krbalias_user.ensure_exists()
# Add an alias overlapping the trusted domain realm
with pytest.raises(errors.ValidationError):
krbalias_user.add_principal(
u'{username}\@{trusted_domain}@{realm}'.format(
username=krbalias_user.name,
trusted_domain=trusted_domain['name'],
realm=api.env.realm
)
)
def test_enterprise_principal_UPN_overlap(
self, krbalias_user, trusted_domain_with_suffix):
krbalias_user.ensure_exists()
# Add an alias overlapping the UPN of a trusted domain
upn_suffix = (
trusted_domain_with_suffix['ldif']['ipaNTAdditionalSuffixes']
)
with pytest.raises(errors.ValidationError):
krbalias_user.add_principal(
u'{username}\@{trusted_domain}@{realm}'.format(
username=krbalias_user.name,
trusted_domain=upn_suffix,
realm=api.env.realm
)
)
def test_enterprise_principal_NETBIOS_overlap(
self, krbalias_user, trusted_domain_with_suffix):
krbalias_user.ensure_exists()
# Add an alias overlapping the NETBIOS name of a trusted domain
netbios_name = (
trusted_domain_with_suffix['ldif']['ipaNTFlatName']
)
with pytest.raises(errors.ValidationError):
krbalias_user.add_principal(
u'{username}\@{trusted_domain}@{realm}'.format(
username=krbalias_user.name,
trusted_domain=netbios_name,
realm=api.env.realm
)
)