mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Do not use extra command options in ACI, permission, selfservice
Allowing Commands to be called with ignored unknown options opens the door to problems, for example with misspelled option names. Before we start rejecting them, we need to make sure IPA itself does not use them when it calls commands internally. This patch does that for ACI-related plugins. Part of the work for https://fedorahosted.org/freeipa/ticket/2509
This commit is contained in:
parent
95bb8d0f45
commit
c5689e7faf
@ -565,21 +565,20 @@ class aci_del(crud.Delete):
|
|||||||
|
|
||||||
takes_options = (_prefix_option,)
|
takes_options = (_prefix_option,)
|
||||||
|
|
||||||
def execute(self, aciname, **kw):
|
def execute(self, aciname, aciprefix):
|
||||||
"""
|
"""
|
||||||
Execute the aci-delete operation.
|
Execute the aci-delete operation.
|
||||||
|
|
||||||
:param aciname: The name of the ACI being deleted.
|
:param aciname: The name of the ACI being deleted.
|
||||||
:param kw: unused
|
:param aciprefix: The ACI prefix.
|
||||||
"""
|
"""
|
||||||
assert 'aciname' not in kw
|
|
||||||
ldap = self.api.Backend.ldap2
|
ldap = self.api.Backend.ldap2
|
||||||
|
|
||||||
(dn, entry_attrs) = ldap.get_entry(self.api.env.basedn, ['aci'])
|
(dn, entry_attrs) = ldap.get_entry(self.api.env.basedn, ['aci'])
|
||||||
|
|
||||||
acistrs = entry_attrs.get('aci', [])
|
acistrs = entry_attrs.get('aci', [])
|
||||||
acis = _convert_strings_to_acis(acistrs)
|
acis = _convert_strings_to_acis(acistrs)
|
||||||
aci = _find_aci_by_name(acis, kw['aciprefix'], aciname)
|
aci = _find_aci_by_name(acis, aciprefix, aciname)
|
||||||
for a in acistrs:
|
for a in acistrs:
|
||||||
candidate = ACI(a)
|
candidate = ACI(a)
|
||||||
if aci.isequal(candidate):
|
if aci.isequal(candidate):
|
||||||
@ -614,28 +613,25 @@ class aci_mod(crud.Update):
|
|||||||
msg_summary = _('Modified ACI "%(value)s"')
|
msg_summary = _('Modified ACI "%(value)s"')
|
||||||
|
|
||||||
def execute(self, aciname, **kw):
|
def execute(self, aciname, **kw):
|
||||||
|
aciprefix = kw['aciprefix']
|
||||||
ldap = self.api.Backend.ldap2
|
ldap = self.api.Backend.ldap2
|
||||||
|
|
||||||
(dn, entry_attrs) = ldap.get_entry(self.api.env.basedn, ['aci'])
|
(dn, entry_attrs) = ldap.get_entry(self.api.env.basedn, ['aci'])
|
||||||
|
|
||||||
acis = _convert_strings_to_acis(entry_attrs.get('aci', []))
|
acis = _convert_strings_to_acis(entry_attrs.get('aci', []))
|
||||||
aci = _find_aci_by_name(acis, kw['aciprefix'], aciname)
|
aci = _find_aci_by_name(acis, aciprefix, aciname)
|
||||||
|
|
||||||
# The strategy here is to convert the ACI we're updating back into
|
# The strategy here is to convert the ACI we're updating back into
|
||||||
# a series of keywords. Then we replace any keywords that have been
|
# a series of keywords. Then we replace any keywords that have been
|
||||||
# updated and convert that back into an ACI and write it out.
|
# updated and convert that back into an ACI and write it out.
|
||||||
oldkw = _aci_to_kw(ldap, aci)
|
oldkw = _aci_to_kw(ldap, aci)
|
||||||
newkw = deepcopy(oldkw)
|
newkw = deepcopy(oldkw)
|
||||||
if 'selfaci' in newkw and newkw['selfaci'] == True:
|
if newkw.get('selfaci', False):
|
||||||
# selfaci is set in aci_to_kw to True only if the target is self
|
# selfaci is set in aci_to_kw to True only if the target is self
|
||||||
kw['selfaci'] = True
|
kw['selfaci'] = True
|
||||||
for k in kw.keys():
|
newkw.update(kw)
|
||||||
newkw[k] = kw[k]
|
|
||||||
for acikw in (oldkw, newkw):
|
for acikw in (oldkw, newkw):
|
||||||
try:
|
acikw.pop('aciname', None)
|
||||||
del acikw['aciname']
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# _make_aci is what is run in aci_add and validates the input.
|
# _make_aci is what is run in aci_add and validates the input.
|
||||||
# Do this before we delete the existing ACI.
|
# Do this before we delete the existing ACI.
|
||||||
@ -643,7 +639,7 @@ class aci_mod(crud.Update):
|
|||||||
if aci.isequal(newaci):
|
if aci.isequal(newaci):
|
||||||
raise errors.EmptyModlist()
|
raise errors.EmptyModlist()
|
||||||
|
|
||||||
self.api.Command['aci_del'](aciname, **kw)
|
self.api.Command['aci_del'](aciname, aciprefix=aciprefix)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = self.api.Command['aci_add'](aciname, **newkw)['result']
|
result = self.api.Command['aci_add'](aciname, **newkw)['result']
|
||||||
@ -652,7 +648,7 @@ class aci_mod(crud.Update):
|
|||||||
# report the ADD error back to user
|
# report the ADD error back to user
|
||||||
try:
|
try:
|
||||||
self.api.Command['aci_add'](aciname, **oldkw)
|
self.api.Command['aci_add'](aciname, **oldkw)
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
@ -949,7 +945,7 @@ class aci_rename(crud.Update):
|
|||||||
# Do this before we delete the existing ACI.
|
# Do this before we delete the existing ACI.
|
||||||
newaci = _make_aci(ldap, None, kw['newname'], newkw)
|
newaci = _make_aci(ldap, None, kw['newname'], newkw)
|
||||||
|
|
||||||
self.api.Command['aci_del'](aciname, **kw)
|
self.api.Command['aci_del'](aciname, aciprefix=kw['aciprefix'])
|
||||||
|
|
||||||
result = self.api.Command['aci_add'](kw['newname'], **newkw)['result']
|
result = self.api.Command['aci_add'](kw['newname'], **newkw)['result']
|
||||||
|
|
||||||
|
@ -194,10 +194,7 @@ class permission_add(LDAPCreate):
|
|||||||
opts['test'] = True
|
opts['test'] = True
|
||||||
opts['permission'] = keys[-1]
|
opts['permission'] = keys[-1]
|
||||||
opts['aciprefix'] = ACI_PREFIX
|
opts['aciprefix'] = ACI_PREFIX
|
||||||
try:
|
self.api.Command.aci_add(keys[-1], **opts)
|
||||||
self.api.Command.aci_add(keys[-1], **opts)
|
|
||||||
except Exception, e:
|
|
||||||
raise e
|
|
||||||
|
|
||||||
# Clear the aci attributes out of the permission entry
|
# Clear the aci attributes out of the permission entry
|
||||||
for o in options:
|
for o in options:
|
||||||
@ -289,24 +286,20 @@ class permission_mod(LDAPUpdate):
|
|||||||
except errors.NotFound:
|
except errors.NotFound:
|
||||||
pass # permission may be renamed, continue
|
pass # permission may be renamed, continue
|
||||||
else:
|
else:
|
||||||
raise errors.ValidationError(name='rename',error=_('New name can not be empty'))
|
raise errors.ValidationError(
|
||||||
|
name='rename',error=_('New name can not be empty'))
|
||||||
|
|
||||||
opts = copy.copy(options)
|
opts = copy.copy(options)
|
||||||
for o in ['all', 'raw', 'rights', 'rename']:
|
for o in ['all', 'raw', 'rights', 'test', 'rename']:
|
||||||
if o in opts:
|
opts.pop(o, None)
|
||||||
del opts[o]
|
|
||||||
setattr(context, 'aciupdate', False)
|
setattr(context, 'aciupdate', False)
|
||||||
# If there are no options left we don't need to do anything to the
|
# If there are no options left we don't need to do anything to the
|
||||||
# underlying ACI.
|
# underlying ACI.
|
||||||
if len(opts) > 0:
|
if len(opts) > 0:
|
||||||
opts['test'] = False
|
|
||||||
opts['permission'] = keys[-1]
|
opts['permission'] = keys[-1]
|
||||||
opts['aciprefix'] = ACI_PREFIX
|
opts['aciprefix'] = ACI_PREFIX
|
||||||
try:
|
self.api.Command.aci_mod(keys[-1], **opts)
|
||||||
self.api.Command.aci_mod(keys[-1], **opts)
|
setattr(context, 'aciupdate', True)
|
||||||
setattr(context, 'aciupdate', True)
|
|
||||||
except Exception, e:
|
|
||||||
raise e
|
|
||||||
|
|
||||||
# Clear the aci attributes out of the permission entry
|
# Clear the aci attributes out of the permission entry
|
||||||
for o in self.obj.aci_attributes:
|
for o in self.obj.aci_attributes:
|
||||||
@ -341,11 +334,12 @@ class permission_mod(LDAPUpdate):
|
|||||||
permission=options['rename'])
|
permission=options['rename'])
|
||||||
|
|
||||||
self.api.Command.aci_rename(cn, aciprefix=ACI_PREFIX,
|
self.api.Command.aci_rename(cn, aciprefix=ACI_PREFIX,
|
||||||
newname=options['rename'], newprefix=ACI_PREFIX)
|
newname=options['rename'])
|
||||||
|
|
||||||
cn = options['rename'] # rename finished
|
cn = options['rename'] # rename finished
|
||||||
|
|
||||||
result = self.api.Command.permission_show(cn, **options)['result']
|
common_options = dict((k, options[k]) for k in ('all', 'raw') if k in options)
|
||||||
|
result = self.api.Command.permission_show(cn, **common_options)['result']
|
||||||
for r in result:
|
for r in result:
|
||||||
if not r.startswith('member_'):
|
if not r.startswith('member_'):
|
||||||
entry_attrs[r] = result[r]
|
entry_attrs[r] = result[r]
|
||||||
@ -363,7 +357,7 @@ class permission_find(LDAPSearch):
|
|||||||
has_output_params = LDAPSearch.has_output_params + output_params
|
has_output_params = LDAPSearch.has_output_params + output_params
|
||||||
|
|
||||||
def post_callback(self, ldap, entries, truncated, *args, **options):
|
def post_callback(self, ldap, entries, truncated, *args, **options):
|
||||||
if options.get('pkey_only', False):
|
if options.pop('pkey_only', False):
|
||||||
return
|
return
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
(dn, attrs) = entry
|
(dn, attrs) = entry
|
||||||
@ -379,9 +373,9 @@ class permission_find(LDAPSearch):
|
|||||||
|
|
||||||
# Now find all the ACIs that match. Once we find them, add any that
|
# Now find all the ACIs that match. Once we find them, add any that
|
||||||
# aren't already in the list along with their permission info.
|
# aren't already in the list along with their permission info.
|
||||||
options['aciprefix'] = ACI_PREFIX
|
|
||||||
|
|
||||||
opts = copy.copy(options)
|
opts = copy.copy(options)
|
||||||
|
opts['aciprefix'] = ACI_PREFIX
|
||||||
try:
|
try:
|
||||||
# permission ACI attribute is needed
|
# permission ACI attribute is needed
|
||||||
del opts['raw']
|
del opts['raw']
|
||||||
@ -422,7 +416,8 @@ class permission_show(LDAPRetrieve):
|
|||||||
has_output_params = LDAPRetrieve.has_output_params + output_params
|
has_output_params = LDAPRetrieve.has_output_params + output_params
|
||||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||||
try:
|
try:
|
||||||
aci = self.api.Command.aci_show(keys[-1], aciprefix=ACI_PREFIX, **options)['result']
|
common_options = dict((k, options[k]) for k in ('all', 'raw') if k in options)
|
||||||
|
aci = self.api.Command.aci_show(keys[-1], aciprefix=ACI_PREFIX, **common_options)['result']
|
||||||
for attr in self.obj.aci_attributes:
|
for attr in self.obj.aci_attributes:
|
||||||
if attr in aci:
|
if attr in aci:
|
||||||
entry_attrs[attr] = aci[attr]
|
entry_attrs[attr] = aci[attr]
|
||||||
|
@ -149,8 +149,7 @@ class selfservice_del(crud.Delete):
|
|||||||
msg_summary = _('Deleted selfservice "%(value)s"')
|
msg_summary = _('Deleted selfservice "%(value)s"')
|
||||||
|
|
||||||
def execute(self, aciname, **kw):
|
def execute(self, aciname, **kw):
|
||||||
kw['aciprefix'] = ACI_PREFIX
|
result = api.Command['aci_del'](aciname, aciprefix=ACI_PREFIX)
|
||||||
result = api.Command['aci_del'](aciname, **kw)
|
|
||||||
self.obj.postprocess_result(result)
|
self.obj.postprocess_result(result)
|
||||||
|
|
||||||
return dict(
|
return dict(
|
||||||
|
@ -46,7 +46,8 @@ class test_selfservice(Declarative):
|
|||||||
|
|
||||||
dict(
|
dict(
|
||||||
desc='Try to update non-existent %r' % selfservice1,
|
desc='Try to update non-existent %r' % selfservice1,
|
||||||
command=('selfservice_mod', [selfservice1], dict(description=u'Foo')),
|
command=('selfservice_mod', [selfservice1],
|
||||||
|
dict(permissions=u'write')),
|
||||||
expected=errors.NotFound(
|
expected=errors.NotFound(
|
||||||
reason=u'ACI with name "%s" not found' % selfservice1),
|
reason=u'ACI with name "%s" not found' % selfservice1),
|
||||||
),
|
),
|
||||||
|
Loading…
Reference in New Issue
Block a user