mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-22 15:13:50 -06:00
dc73813b8a
An ACI with rights of read, write, search and/or compare without attributes to apply the rights to is effectively a no-op. Allow the ACI to be created but include a warning. Ignore the add and delete rights. While they make no sense in the context of the other rights we should still warn that they are a no-op with no attributes. Use the existing make_aci() object method to create the message and update the add/mod callers to capture and add the message to the result if one is provided. When updating an existing ACI the effective attributes will not be included so fall back to the attributes in the resulting permission. Prior to checking for rights and attributes convert any deprecated names for older clients into the newer values needed by make_aci This is exercised by existing xmlrpc permission tests that create such permissions without attributes. https://pagure.io/freeipa/issue/9188 Signed-off-by: Rob Crittenden <rcritten@redhat.com> Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com> Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
133 lines
4.5 KiB
Python
133 lines
4.5 KiB
Python
#!/usr/bin/python3
|
|
# Authors:
|
|
# Petr Viktorin <pviktori@redhat.com>
|
|
# John Dennis <jdennis@redhat.com>
|
|
# Martin Kosek <mkosek@redhat.com>
|
|
#
|
|
# Copyright (C) 2011 Red Hat
|
|
# see file 'COPYING' for use and warranty information
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# Test the managed permission ACIs against a known-good ACI list
|
|
# to ensure that changes aren't made lightly.
|
|
# Can either regenerate ACI.txt, or validate against it.
|
|
|
|
from __future__ import print_function
|
|
|
|
import sys
|
|
import difflib
|
|
from argparse import ArgumentParser
|
|
|
|
from ipalib import api
|
|
from ipapython.dn import DN
|
|
from ipapython.ipaldap import LDAPClient
|
|
|
|
|
|
def parse_options():
|
|
parser = ArgumentParser()
|
|
parser.add_argument('--validate', dest='validate', action='store_true',
|
|
default=False, help='Validate the API vs the stored API')
|
|
parser.add_argument('filename', nargs='?', default='ACI.txt',
|
|
help='File to create or validate, default: ACI.txt')
|
|
|
|
options = parser.parse_args()
|
|
return options
|
|
|
|
|
|
def generate_aci_lines(api):
|
|
"""Yields ACI lines as they appear in ACI.txt, with trailing newline"""
|
|
update_plugin = api.Updater['update_managed_permissions']
|
|
perm_plugin = api.Object['permission']
|
|
fake_ldap = LDAPClient(None, force_schema_updates=False, no_schema=True)
|
|
for name, template, obj in update_plugin.get_templates():
|
|
dn = perm_plugin.get_dn(name)
|
|
entry = fake_ldap.make_entry(dn)
|
|
update_plugin.update_entry(
|
|
obj=obj,
|
|
entry=entry,
|
|
template=template,
|
|
anonymous_read_aci=None,
|
|
is_new=True,
|
|
)
|
|
aci, _msg = perm_plugin.make_aci(entry)
|
|
yield 'dn: %s\n' % entry.single_value['ipapermlocation']
|
|
yield f'aci: {aci}\n'
|
|
|
|
check_member_attrs(name, template)
|
|
|
|
|
|
def check_member_attrs(name, template):
|
|
"""Check that member* attrs are always present together for read
|
|
|
|
ldap2._process_memberofindirect reads all these attributes together;
|
|
if the user doesn't have rights to one of them, the entire entry is
|
|
left out and memberofindirect processing returns wrong a result.
|
|
So we need all of them be readable.
|
|
"""
|
|
checked_attrs = ['member', 'memberuser', 'memberhost']
|
|
perm_attrs = template.get('ipapermdefaultattr', ())
|
|
flags = [(a in perm_attrs) for a in checked_attrs]
|
|
if 'read' in template['ipapermright'] and any(flags) and not all(flags):
|
|
raise AssertionError("'%s' includes some but not all of %s" %
|
|
(name, checked_attrs))
|
|
|
|
|
|
def main(options):
|
|
api.bootstrap(
|
|
in_server=True,
|
|
in_tree=True,
|
|
debug=False,
|
|
verbose=0,
|
|
validate_api=True,
|
|
enable_ra=True,
|
|
mode='developer',
|
|
plugins_on_demand=False,
|
|
basedn=DN('dc=ipa,dc=example'),
|
|
realm='IPA.EXAMPLE',
|
|
domain="example.com",
|
|
)
|
|
|
|
from ipaserver.install.plugins import update_managed_permissions
|
|
api.add_module(update_managed_permissions)
|
|
|
|
api.finalize()
|
|
|
|
output_lines = list(generate_aci_lines(api))
|
|
|
|
if options.validate:
|
|
with open(options.filename) as file:
|
|
file_lines = file.readlines()
|
|
if file_lines != output_lines:
|
|
diff = list(difflib.unified_diff(
|
|
file_lines,
|
|
output_lines,
|
|
fromfile='existing %s' % options.filename,
|
|
tofile='new result',
|
|
))
|
|
for line in diff:
|
|
print(line, end=' ')
|
|
print(file=sys.stderr)
|
|
print('Managed permission ACI validation failed.', file=sys.stderr)
|
|
print('Re-check permission changes and run `makeaci`.', file=sys.stderr)
|
|
sys.exit('%s validation failed' % options.filename)
|
|
else:
|
|
with open(options.filename, 'w') as file:
|
|
file.writelines(output_lines)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
options = parse_options()
|
|
main(options)
|