mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Reworked the renaming mechanism
The rename operation on *_mod commands was only allowed when the primary key of an entry was also its RDN. With these changes, it should be possible to rename the rest of the entries as well. An attribute to the base LDAPObject was added to whitelist the objects we want to allow to be renamed. It replaced an old attribute rdn_is_primary_key which was used for the very same purpose but the name was confusing because it was not set correctly for certain objects. https://pagure.io/freeipa/issue/2466 https://pagure.io/freeipa/issue/6784 Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com> Reviewed-By: Jan Cholasta <jcholast@redhat.com> Reviewed-By: Martin Basti <mbasti@redhat.com>
This commit is contained in:
committed by
Pavel Vomacka
parent
b7ae3363fd
commit
8e4408e678
@@ -456,7 +456,7 @@ class automountkey(LDAPObject):
|
||||
default_attributes = [
|
||||
'automountkey', 'automountinformation', 'description'
|
||||
]
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
rdn_separator = ' '
|
||||
|
||||
takes_params = (
|
||||
|
||||
@@ -36,7 +36,7 @@ from ipalib.text import _
|
||||
from ipalib.util import json_serialize, validate_hostname
|
||||
from ipalib.capabilities import client_has_capability
|
||||
from ipalib.messages import add_message, SearchResultTruncated
|
||||
from ipapython.dn import DN
|
||||
from ipapython.dn import DN, RDN
|
||||
from ipapython.version import API_VERSION
|
||||
|
||||
if six.PY3:
|
||||
@@ -549,7 +549,7 @@ class LDAPObject(Object):
|
||||
rdn_attribute = ''
|
||||
uuid_attribute = ''
|
||||
attribute_members = {}
|
||||
rdn_is_primary_key = False # Do we need RDN change to do a rename?
|
||||
allow_rename = False
|
||||
password_attributes = []
|
||||
# Can bind as this entry (has userPassword or krbPrincipalKey)
|
||||
bindable = False
|
||||
@@ -1384,7 +1384,7 @@ class LDAPUpdate(LDAPQuery, crud.Update):
|
||||
def get_options(self):
|
||||
for option in super(LDAPUpdate, self).get_options():
|
||||
yield option
|
||||
if self.obj.rdn_is_primary_key:
|
||||
if self.obj.allow_rename:
|
||||
yield self._get_rename_option()
|
||||
|
||||
def execute(self, *keys, **options):
|
||||
@@ -1419,15 +1419,19 @@ class LDAPUpdate(LDAPQuery, crud.Update):
|
||||
_check_limit_object_class(self.api.Backend.ldap2.schema.attribute_types(self.obj.disallow_object_classes), list(entry_attrs), allow_only=False)
|
||||
|
||||
rdnupdate = False
|
||||
try:
|
||||
if self.obj.rdn_is_primary_key and 'rename' in options:
|
||||
if 'rename' in options:
|
||||
if not options['rename']:
|
||||
raise errors.ValidationError(name='rename', error=u'can\'t be empty')
|
||||
raise errors.ValidationError(
|
||||
name='rename', error=u'can\'t be empty')
|
||||
entry_attrs[self.obj.primary_key.name] = options['rename']
|
||||
|
||||
if self.obj.rdn_is_primary_key and self.obj.primary_key.name in entry_attrs:
|
||||
# if setattr was used to change the RDN, the primary_key.name is
|
||||
# already in entry_attrs
|
||||
if self.obj.allow_rename and self.obj.primary_key.name in entry_attrs:
|
||||
# perform RDN change if the primary key is also RDN
|
||||
if (RDN((self.obj.primary_key.name, keys[-1])) ==
|
||||
entry_attrs.dn[0]):
|
||||
try:
|
||||
# RDN change
|
||||
new_dn = DN((self.obj.primary_key.name,
|
||||
entry_attrs[self.obj.primary_key.name]),
|
||||
*entry_attrs.dn[1:])
|
||||
@@ -1435,17 +1439,21 @@ class LDAPUpdate(LDAPQuery, crud.Update):
|
||||
entry_attrs.dn,
|
||||
new_dn)
|
||||
|
||||
rdnkeys = keys[:-1] + (entry_attrs[self.obj.primary_key.name], )
|
||||
rdnkeys = (keys[:-1] +
|
||||
(entry_attrs[self.obj.primary_key.name], ))
|
||||
entry_attrs.dn = self.obj.get_dn(*rdnkeys)
|
||||
options['rdnupdate'] = True
|
||||
rdnupdate = True
|
||||
except errors.EmptyModlist:
|
||||
# Attempt to rename to the current name, ignore
|
||||
pass
|
||||
except errors.NotFound:
|
||||
self.obj.handle_not_found(*keys)
|
||||
finally:
|
||||
# Delete the primary_key from entry_attrs either way
|
||||
del entry_attrs[self.obj.primary_key.name]
|
||||
|
||||
try:
|
||||
# Exception callbacks will need to test for options['rdnupdate']
|
||||
# to decide what to do. An EmptyModlist in this context doesn't
|
||||
# mean an error occurred, just that there were no other updates to
|
||||
|
||||
@@ -164,7 +164,7 @@ class baseuser(LDAPObject):
|
||||
'memberof': ['group', 'netgroup', 'role', 'hbacrule', 'sudorule'],
|
||||
'memberofindirect': ['group', 'netgroup', 'role', 'hbacrule', 'sudorule'],
|
||||
}
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
bindable = True
|
||||
password_attributes = [('userpassword', 'has_password'),
|
||||
('krbprincipalkey', 'has_keytab')]
|
||||
|
||||
@@ -68,7 +68,7 @@ class ca(LDAPObject):
|
||||
'cn', 'description', 'ipacaid', 'ipacaissuerdn', 'ipacasubjectdn',
|
||||
]
|
||||
rdn_attribute = 'cn'
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
label = _('Certificate Authorities')
|
||||
label_singular = _('Certificate Authority')
|
||||
|
||||
|
||||
@@ -3000,7 +3000,7 @@ class dnsrecord(LDAPObject):
|
||||
possible_objectclasses = ['idnsTemplateObject']
|
||||
permission_filter_objectclasses = ['idnsrecord']
|
||||
default_attributes = ['idnsname'] + _record_attributes
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
|
||||
label = _('DNS Resource Records')
|
||||
label_singular = _('DNS Resource Record')
|
||||
|
||||
@@ -173,7 +173,7 @@ class group(LDAPObject):
|
||||
'memberofindirect': ['group', 'netgroup', 'role', 'hbacrule',
|
||||
'sudorule'],
|
||||
}
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
managed_permissions = {
|
||||
'System: Read Groups': {
|
||||
'replaces_global_anonymous_aci': True,
|
||||
|
||||
@@ -97,7 +97,7 @@ class idview(LDAPObject):
|
||||
object_class = ['ipaIDView', 'top']
|
||||
possible_objectclasses = ['ipaNameResolutionData']
|
||||
default_attributes = ['cn', 'description', 'ipadomainresolutionorder']
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
|
||||
label = _('ID Views')
|
||||
label_singular = _('ID View')
|
||||
@@ -848,7 +848,7 @@ class idoverrideuser(baseidoverride):
|
||||
|
||||
label = _('User ID overrides')
|
||||
label_singular = _('User ID override')
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
|
||||
# ID user overrides are bindable because we map SASL GSSAPI
|
||||
# authentication of trusted users to ID user overrides in the
|
||||
@@ -964,7 +964,7 @@ class idoverridegroup(baseidoverride):
|
||||
|
||||
label = _('Group ID overrides')
|
||||
label_singular = _('Group ID override')
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
|
||||
permission_filter_objectclasses = ['ipaGroupOverride']
|
||||
managed_permissions = {
|
||||
|
||||
@@ -143,7 +143,7 @@ class otptoken(LDAPObject):
|
||||
relationships = {
|
||||
'managedby': ('Managed by', 'man_by_', 'not_man_by_'),
|
||||
}
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
|
||||
label = _('OTP Tokens')
|
||||
label_singular = _('OTP Token')
|
||||
|
||||
@@ -188,7 +188,7 @@ class permission(baseldap.LDAPObject):
|
||||
'member': ['privilege'],
|
||||
'memberindirect': ['role'],
|
||||
}
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
managed_permissions = {
|
||||
'System: Read Permissions': {
|
||||
'replaces_global_anonymous_aci': True,
|
||||
|
||||
@@ -101,7 +101,7 @@ class privilege(LDAPObject):
|
||||
reverse_members = {
|
||||
'member': ['permission'],
|
||||
}
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
managed_permissions = {
|
||||
'System: Read Privileges': {
|
||||
'replaces_global_anonymous_aci': True,
|
||||
|
||||
@@ -101,7 +101,7 @@ class radiusproxy(LDAPObject):
|
||||
'ipatokenradiustimeout', 'ipatokenradiusretries', 'ipatokenusermapattribute'
|
||||
]
|
||||
search_attributes = ['cn', 'description', 'ipatokenradiusserver']
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
label = _('RADIUS Servers')
|
||||
label_singular = _('RADIUS Server')
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ class role(LDAPObject):
|
||||
reverse_members = {
|
||||
'member': ['privilege'],
|
||||
}
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
managed_permissions = {
|
||||
'System: Read Roles': {
|
||||
'replaces_global_anonymous_aci': True,
|
||||
|
||||
@@ -138,7 +138,7 @@ class servicedelegation(LDAPObject):
|
||||
},
|
||||
}
|
||||
|
||||
rdn_is_primary_key = True
|
||||
allow_rename = True
|
||||
|
||||
takes_params = (
|
||||
Str(
|
||||
|
||||
Reference in New Issue
Block a user