summaryrefslogtreecommitdiffstats
path: root/ipalib
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2013-03-18 12:31:23 +0100
committerMartin Kosek <mkosek@redhat.com>2013-03-29 16:34:46 +0100
commit5f26d2c6dbe878518963b5d8f9159ed3fcc71d58 (patch)
treed26dd5bac744b8f6110d7cd35a8201d0d312d46e /ipalib
parentcc56723151c9ebf58d891e85617319d861af14a4 (diff)
downloadfreeipa-5f26d2c6dbe878518963b5d8f9159ed3fcc71d58.tar.gz
freeipa-5f26d2c6dbe878518963b5d8f9159ed3fcc71d58.tar.xz
freeipa-5f26d2c6dbe878518963b5d8f9159ed3fcc71d58.zip
Add Kerberos ticket flags management to service and host plugins.
https://fedorahosted.org/freeipa/ticket/3329
Diffstat (limited to 'ipalib')
-rw-r--r--ipalib/plugins/host.py25
-rw-r--r--ipalib/plugins/service.py89
2 files changed, 107 insertions, 7 deletions
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index d92bc56c0..131c36e38 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -29,9 +29,9 @@ import string
from ipalib import api, errors, util
from ipalib import Str, Flag, Bytes
from ipalib.plugins.baseldap import *
-from ipalib.plugins.service import split_principal
-from ipalib.plugins.service import validate_certificate
-from ipalib.plugins.service import set_certificate_attrs
+from ipalib.plugins.service import (split_principal, validate_certificate,
+ set_certificate_attrs, ticket_flags_params, update_krbticketflags,
+ set_kerberos_attrs)
from ipalib.plugins.dns import (dns_container_exists, _record_types,
add_records_for_host_validation, add_records_for_host,
_hostname_validator, get_reverse_zone)
@@ -323,7 +323,7 @@ class host(LDAPObject):
csv=True,
flags=['no_search'],
),
- )
+ ) + ticket_flags_params
def get_dn(self, *keys, **options):
hostname = keys[-1]
@@ -439,6 +439,9 @@ class host_add(LDAPCreate):
entry_attrs['managedby'] = dn
entry_attrs['objectclass'].append('ieee802device')
entry_attrs['objectclass'].append('ipasshhost')
+ update_krbticketflags(ldap, entry_attrs, attrs_list, options, False)
+ if 'krbticketflags' in entry_attrs:
+ entry_attrs['objectclass'].append('krbticketpolicyaux')
return dn
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
@@ -473,6 +476,7 @@ class host_add(LDAPCreate):
reason=_('The host was added but the DNS update failed with: %(exc)s') % dict(exc=exc)
)
set_certificate_attrs(entry_attrs)
+ set_kerberos_attrs(entry_attrs, options)
if options.get('all', False):
entry_attrs['managing'] = self.obj.get_managed_hosts(dn)
@@ -677,6 +681,7 @@ class host_mod(LDAPUpdate):
if options.get('random'):
entry_attrs['userpassword'] = ipa_generate_password(characters=host_pwd_chars)
setattr(context, 'randompassword', entry_attrs['userpassword'])
+
if 'macaddress' in entry_attrs:
if 'objectclass' in entry_attrs:
obj_classes = entry_attrs['objectclass']
@@ -708,6 +713,15 @@ class host_mod(LDAPUpdate):
if 'ipasshhost' not in obj_classes:
obj_classes.append('ipasshhost')
+ update_krbticketflags(ldap, entry_attrs, attrs_list, options, True)
+
+ if 'krbticketflags' in entry_attrs:
+ if 'objectclass' not in entry_attrs:
+ entry_attrs_old = ldap.get_entry(dn, ['objectclass'])
+ entry_attrs['objectclass'] = entry_attrs_old['objectclass']
+ if 'krbticketpolicyaux' not in entry_attrs['objectclass']:
+ entry_attrs['objectclass'].append('krbticketpolicyaux')
+
return dn
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
@@ -715,6 +729,7 @@ class host_mod(LDAPUpdate):
if options.get('random', False):
entry_attrs['randompassword'] = unicode(getattr(context, 'randompassword'))
set_certificate_attrs(entry_attrs)
+ set_kerberos_attrs(entry_attrs, options)
self.obj.get_password_attributes(ldap, dn, entry_attrs)
if entry_attrs['has_password']:
# If an OTP is set there is no keytab, at least not one
@@ -801,6 +816,7 @@ class host_find(LDAPSearch):
for entry in entries:
(dn, entry_attrs) = entry
set_certificate_attrs(entry_attrs)
+ set_kerberos_attrs(entry_attrs, options)
self.obj.get_password_attributes(ldap, dn, entry_attrs)
self.obj.suppress_netgroup_memberof(entry_attrs)
if entry_attrs['has_password']:
@@ -839,6 +855,7 @@ class host_show(LDAPRetrieve):
entry_attrs['has_keytab'] = False
set_certificate_attrs(entry_attrs)
+ set_kerberos_attrs(entry_attrs, options)
if options.get('all', False):
entry_attrs['managing'] = self.obj.get_managed_hosts(dn)
diff --git a/ipalib/plugins/service.py b/ipalib/plugins/service.py
index 6b6634458..b10054f0d 100644
--- a/ipalib/plugins/service.py
+++ b/ipalib/plugins/service.py
@@ -23,7 +23,7 @@ import base64
import os
from ipalib import api, errors, util
-from ipalib import Str, Flag, Bytes, StrEnum
+from ipalib import Str, Flag, Bytes, StrEnum, Bool
from ipalib.plugins.baseldap import *
from ipalib import x509
from ipalib import _, ngettext
@@ -127,6 +127,28 @@ output_params = (
)
)
+ticket_flags_params = (
+ Bool('ipakrbrequirespreauth?',
+ cli_name='requires_pre_auth',
+ label=_('Requires pre-authentication'),
+ doc=_('Pre-authentication is required for the service'),
+ flags=['virtual_attribute', 'no_search'],
+ ),
+ Bool('ipakrbokasdelegate?',
+ cli_name='ok_as_delegate',
+ label=_('Trusted for delegation'),
+ doc=_('Client credentials may be delegated to the service'),
+ flags=['virtual_attribute', 'no_search'],
+ ),
+)
+
+_ticket_flags_map = {
+ 'ipakrbrequirespreauth': 0x00000080,
+ 'ipakrbokasdelegate': 0x00100000,
+}
+
+_ticket_flags_default = _ticket_flags_map['ipakrbrequirespreauth']
+
def split_principal(principal):
service = hostname = realm = None
@@ -217,6 +239,54 @@ def check_required_principal(ldap, hostname, service):
if service 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):
+ add = remove = 0
+
+ for (name, value) in _ticket_flags_map.iteritems():
+ if name not in options:
+ continue
+ if options[name]:
+ add |= value
+ else:
+ remove |= value
+
+ if not add and not remove:
+ return
+
+ if 'krbticketflags' not in entry_attrs and existing:
+ old_entry_attrs = ldap.get_entry(entry_attrs.dn, ['krbticketflags'])
+ else:
+ old_entry_attrs = entry_attrs
+
+ try:
+ ticket_flags = old_entry_attrs.single_value('krbticketflags')
+ ticket_flags = int(ticket_flags)
+ except (KeyError, ValueError):
+ ticket_flags = _ticket_flags_default
+
+ ticket_flags |= add
+ ticket_flags &= ~remove
+
+ entry_attrs['krbticketflags'] = [ticket_flags]
+ attrs_list.append('krbticketflags')
+
+def set_kerberos_attrs(entry_attrs, options):
+ if options.get('raw', False):
+ return
+
+ try:
+ ticket_flags = entry_attrs.single_value('krbticketflags',
+ _ticket_flags_default)
+ ticket_flags = int(ticket_flags)
+ except ValueError:
+ return
+
+ all_opt = options.get('all', False)
+
+ for (name, value) in _ticket_flags_map.iteritems():
+ if name in options or all_opt:
+ entry_attrs[name] = bool(ticket_flags & value)
+
class service(LDAPObject):
"""
Service object.
@@ -268,7 +338,7 @@ class service(LDAPObject):
values=(u'MS-PAC', u'PAD', u'NONE'),
csv=True,
),
- )
+ ) + ticket_flags_params
def validate_ipakrbauthzdata(self, entry):
new_value = entry.get('ipakrbauthzdata', [])
@@ -300,6 +370,7 @@ class service_add(LDAPCreate):
doc=_('force principal name even if not in DNS'),
),
)
+
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
assert isinstance(dn, DN)
(service, hostname, realm) = split_principal(keys[-1])
@@ -338,6 +409,12 @@ class service_add(LDAPCreate):
# in a list of default objectclasses, add it manually
entry_attrs['objectclass'].append('ipakrbprincipal')
+ update_krbticketflags(ldap, entry_attrs, attrs_list, options, False)
+
+ return dn
+
+ def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
+ set_kerberos_attrs(entry_attrs, options)
return dn
api.register(service_add)
@@ -397,7 +474,7 @@ class service_mod(LDAPUpdate):
member_attributes = ['managedby']
- def pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
+ def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
assert isinstance(dn, DN)
self.obj.validate_ipakrbauthzdata(entry_attrs)
@@ -422,11 +499,15 @@ class service_mod(LDAPUpdate):
entry_attrs['usercertificate'] = dercert
else:
entry_attrs['usercertificate'] = None
+
+ update_krbticketflags(ldap, entry_attrs, attrs_list, options, True)
+
return dn
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
assert isinstance(dn, DN)
set_certificate_attrs(entry_attrs)
+ set_kerberos_attrs(entry_attrs, options)
return dn
api.register(service_mod)
@@ -464,6 +545,7 @@ class service_find(LDAPSearch):
(dn, entry_attrs) = entry
self.obj.get_password_attributes(ldap, dn, entry_attrs)
set_certificate_attrs(entry_attrs)
+ set_kerberos_attrs(entry_attrs, options)
return truncated
api.register(service_find)
@@ -485,6 +567,7 @@ class service_show(LDAPRetrieve):
self.obj.get_password_attributes(ldap, dn, entry_attrs)
set_certificate_attrs(entry_attrs)
+ set_kerberos_attrs(entry_attrs, options)
return dn