diff options
Diffstat (limited to 'ipalib')
-rw-r--r-- | ipalib/plugins/dns.py | 79 | ||||
-rw-r--r-- | ipalib/plugins/permission.py | 43 |
2 files changed, 121 insertions, 1 deletions
diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py index 0f1014ca..c2bf13a2 100644 --- a/ipalib/plugins/dns.py +++ b/ipalib/plugins/dns.py @@ -75,6 +75,9 @@ EXAMPLES: ipa dnszone-add example.com --name-server=nameserver.example.com \\ --admin-email=admin@example.com + Add system permission that can be used for per-zone privilege delegation: + ipa dnszone-add-permission example.com + Modify the zone to allow dynamic updates for hosts own records in realm EXAMPLE.COM: ipa dnszone-mod example.com --dynamic-update=TRUE @@ -1528,6 +1531,7 @@ class dnszone(LDAPObject): object_name = _('DNS zone') object_name_plural = _('DNS zones') object_class = ['top', 'idnsrecord', 'idnszone'] + possible_objectclasses = ['ipadnszone'] default_attributes = [ 'idnsname', 'idnszoneactive', 'idnssoamname', 'idnssoarname', 'idnssoaserial', 'idnssoarefresh', 'idnssoaretry', 'idnssoaexpire', @@ -1696,6 +1700,9 @@ class dnszone(LDAPObject): return dn + def permission_name(self, zone): + return u"Manage DNS zone %s" % zone + api.register(dnszone) @@ -1752,6 +1759,14 @@ api.register(dnszone_add) class dnszone_del(LDAPDelete): __doc__ = _('Delete DNS zone (SOA record).') + def post_callback(self, ldap, dn, *keys, **options): + try: + api.Command['permission_del'](self.obj.permission_name(keys[-1]), + force=True) + except errors.NotFound: + pass + return True + api.register(dnszone_del) @@ -1851,6 +1866,70 @@ class dnszone_enable(LDAPQuery): api.register(dnszone_enable) +class dnszone_add_permission(LDAPQuery): + __doc__ = _('Add a permission for per-zone access delegation.') + + has_output = output.standard_value + msg_summary = _('Added system permission "%(value)s"') + + def execute(self, *keys, **options): + ldap = self.obj.backend + dn = self.obj.get_dn(*keys, **options) + + try: + (dn_, entry_attrs) = ldap.get_entry(dn, ['objectclass']) + except errors.NotFound: + self.obj.handle_not_found(*keys) + + permission_name = self.obj.permission_name(keys[-1]) + permission = api.Command['permission_add_noaci'](permission_name, + permissiontype=u'SYSTEM' + )['result'] + + update = {} + dnszone_ocs = entry_attrs.get('objectclass') + if dnszone_ocs: + dnszone_ocs.append('ipadnszone') + update['objectclass'] = list(set(dnszone_ocs)) + + update['managedby'] = [permission['dn']] + ldap.update_entry(dn, update) + + return dict( + result=True, + value=permission_name, + ) + +api.register(dnszone_add_permission) + +class dnszone_remove_permission(LDAPQuery): + __doc__ = _('Remove a permission for per-zone access delegation.') + + has_output = output.standard_value + msg_summary = _('Removed system permission "%(value)s"') + + def execute(self, *keys, **options): + ldap = self.obj.backend + dn = self.obj.get_dn(*keys, **options) + + try: + ldap.update_entry(dn, {'managedby': None}) + except errors.NotFound: + self.obj.handle_not_found(*keys) + except errors.EmptyModlist: + # managedBy attribute is clean, lets make sure there is also no + # dangling DNS zone permission + pass + + permission_name = self.obj.permission_name(keys[-1]) + api.Command['permission_del'](permission_name, force=True) + + return dict( + result=True, + value=permission_name, + ) + +api.register(dnszone_remove_permission) class dnsrecord(LDAPObject): """ diff --git a/ipalib/plugins/permission.py b/ipalib/plugins/permission.py index 05d19ad8..ec3d78d1 100644 --- a/ipalib/plugins/permission.py +++ b/ipalib/plugins/permission.py @@ -246,14 +246,55 @@ class permission_add(LDAPCreate): api.register(permission_add) +class permission_add_noaci(LDAPCreate): + __doc__ = _('Add a system permission without an ACI') + + msg_summary = _('Added permission "%(value)s"') + has_output_params = LDAPCreate.has_output_params + output_params + NO_CLI = True + + takes_options = ( + StrEnum('permissiontype?', + label=_('Permission type'), + values=(u'SYSTEM',), + ), + ) + + def get_args(self): + # do not validate system permission names + yield self.obj.primary_key.clone(pattern=None, pattern_errmsg=None) + + def get_options(self): + for option in super(permission_add_noaci, self).get_options(): + # filter out ACI options + if option.name in self.obj.aci_attributes: + continue + yield option + + def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): + permission_type = options.get('permissiontype') + if permission_type: + entry_attrs['ipapermissiontype'] = [ permission_type ] + return dn + +api.register(permission_add_noaci) + class permission_del(LDAPDelete): __doc__ = _('Delete a permission.') msg_summary = _('Deleted permission "%(value)s"') + takes_options = LDAPDelete.takes_options + ( + Flag('force', + label=_('Force'), + flags=['no_option', 'no_output'], + doc=_('force delete of SYSTEM permissions'), + ), + ) + def pre_callback(self, ldap, dn, *keys, **options): - if not self.obj.check_system(ldap, dn, *keys): + if not options.get('force') and not self.obj.check_system(ldap, dn, *keys): raise errors.ACIError(info='A SYSTEM permission may not be removed') # remove permission even when the underlying ACI is missing try: |