From 93a50310154b4fae572c8fbf7a8c1e8ba7c0b49a Mon Sep 17 00:00:00 2001 From: Simon Pichugin Date: Mon, 5 Feb 2024 20:04:40 -0800 Subject: [PATCH] Add basedn functionality check --- src/lib389/cli/dsidm | 21 +++++++------- src/lib389/lib389/cli_idm/__init__.py | 41 ++++++++++++++++++++++++++- src/lib389/lib389/cli_idm/account.py | 4 +-- src/lib389/lib389/idm/group.py | 10 ++++--- src/lib389/lib389/idm/posixgroup.py | 5 ++-- src/lib389/lib389/idm/services.py | 5 ++-- src/lib389/lib389/idm/user.py | 5 ++-- 7 files changed, 67 insertions(+), 24 deletions(-) diff --git a/src/lib389/cli/dsidm b/src/lib389/cli/dsidm index 1b6762646a..80b5a14554 100755 --- a/src/lib389/cli/dsidm +++ b/src/lib389/cli/dsidm @@ -2,7 +2,7 @@ # --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2016, William Brown -# Copyright (C) 2023 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -19,6 +19,7 @@ import argparse import argcomplete from lib389.utils import get_instance_list, instance_choices from lib389._constants import DSRC_HOME +from lib389.cli_idm import _get_basedn_arg from lib389.cli_idm import account as cli_account from lib389.cli_idm import initialise as cli_init from lib389.cli_idm import organizationalunit as cli_ou @@ -124,14 +125,6 @@ if __name__ == '__main__': parser.print_help() sys.exit(1) - if dsrc_inst['basedn'] is None: - errmsg = "Must provide a basedn!" - if args.json: - sys.stderr.write('{"desc": "%s"}\n' % errmsg) - else: - log.error(errmsg) - sys.exit(1) - if not args.verbose: signal.signal(signal.SIGINT, signal_handler) @@ -142,7 +135,15 @@ if __name__ == '__main__': result = False try: inst = connect_instance(dsrc_inst=dsrc_inst, verbose=args.verbose, args=args) - result = args.func(inst, dsrc_inst['basedn'], log, args) + basedn = _get_basedn_arg(inst, args, log, msg="Enter basedn") + if basedn is None: + errmsg = "Must provide a basedn!" + if args.json: + sys.stderr.write('{"desc": "%s"}\n' % errmsg) + else: + log.error(errmsg) + sys.exit(1) + result = args.func(inst, basedn, log, args) if args.verbose: log.info("Command successful.") except Exception as e: diff --git a/src/lib389/lib389/cli_idm/__init__.py b/src/lib389/lib389/cli_idm/__init__.py index 0dab54847e..aa626bb3f4 100644 --- a/src/lib389/lib389/cli_idm/__init__.py +++ b/src/lib389/lib389/cli_idm/__init__.py @@ -1,15 +1,30 @@ # --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2016, William Brown -# Copyright (C) 2023 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). # See LICENSE for details. # --- END COPYRIGHT BLOCK --- +import sys import ldap from getpass import getpass import json +from lib389._mapped_object import DSLdapObject +from lib389.cli_base import _get_dn_arg +from lib389.idm.user import DEFAULT_BASEDN_RDN as DEFAULT_BASEDN_RDN_USER +from lib389.idm.group import DEFAULT_BASEDN_RDN as DEFAULT_BASEDN_RDN_GROUP +from lib389.idm.posixgroup import DEFAULT_BASEDN_RDN as DEFAULT_BASEDN_RDN_POSIXGROUP +from lib389.idm.services import DEFAULT_BASEDN_RDN as DEFAULT_BASEDN_RDN_SERVICES + +# Create a dict where key is module and value is an rpm to search +BASEDN_RDNS = { + 'user': DEFAULT_BASEDN_RDN_USER, + 'group': DEFAULT_BASEDN_RDN_GROUP, + 'posixgroup': DEFAULT_BASEDN_RDN_POSIXGROUP, + 'services': DEFAULT_BASEDN_RDN_SERVICES, +} def _get_arg(args, msg=None): @@ -37,6 +52,30 @@ def _get_args(args, kws): return kwargs +def _get_basedn_arg(inst, args, log, msg=None): + basedn_arg = _get_dn_arg(args.basedn, msg="Enter basedn") + + # Get the RDN based on the last part of the module name (lib389.cli_idm.user -> user) + try: + command_name = args.func.__module__.split('.')[-1] + object_rdn = BASEDN_RDNS[command_name] + # Check if the base DN for our command exists + command_basedn = f'{object_rdn},{basedn_arg}' + if not DSLdapObject(inst, command_basedn).exists(): + # split the line + errmsg = f'The DN "{command_basedn}" does not exist.' + errmsg += f' It is required for "{command_name}" command. Please create it first.' + + if args.json: + sys.stderr.write('{"desc": "%s"}\n' % errmsg) + else: + log.error(errmsg) + sys.exit(1) + except KeyError: + pass + return basedn_arg + + # This is really similar to get_args, but generates from an array def _get_attributes(args, attrs): kwargs = {} diff --git a/src/lib389/lib389/cli_idm/account.py b/src/lib389/lib389/cli_idm/account.py index 6c7aebce19..cbdeec5c9c 100644 --- a/src/lib389/lib389/cli_idm/account.py +++ b/src/lib389/lib389/cli_idm/account.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2023, Red Hat inc, +# Copyright (C) 2024, Red Hat inc, # Copyright (C) 2018, William Brown # All rights reserved. # @@ -90,7 +90,6 @@ def entry_status(inst, basedn, log, args): def subtree_status(inst, basedn, log, args): - basedn = _get_dn_arg(args.basedn, msg="Enter basedn to check") filter = "" scope = ldap.SCOPE_SUBTREE epoch_inactive_time = None @@ -120,7 +119,6 @@ def subtree_status(inst, basedn, log, args): def bulk_update(inst, basedn, log, args): - basedn = _get_dn_arg(args.basedn, msg="Enter basedn to search") search_filter = "(objectclass=*)" scope = ldap.SCOPE_SUBTREE scope_str = "sub" diff --git a/src/lib389/lib389/idm/group.py b/src/lib389/lib389/idm/group.py index 560a2c6974..1e6c2a3ef2 100644 --- a/src/lib389/lib389/idm/group.py +++ b/src/lib389/lib389/idm/group.py @@ -1,6 +1,6 @@ # --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2016, William Brown -# Copyright (C) 2023 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -16,6 +16,8 @@ 'cn', ] RDN = 'cn' +DEFAULT_BASEDN_RDN = 'ou=Groups' +DEFAULT_BASEDN_RDN_ADMIN_GROUPS = 'ou=People' class Group(DSLdapObject): @@ -93,7 +95,7 @@ class Groups(DSLdapObjects): :type basedn: str """ - def __init__(self, instance, basedn, rdn='ou=Groups'): + def __init__(self, instance, basedn, rdn=DEFAULT_BASEDN_RDN): super(Groups, self).__init__(instance) self._objectclasses = [ 'groupOfNames', @@ -140,7 +142,7 @@ def remove_member(self, dn): class UniqueGroups(DSLdapObjects): # WARNING!!! # Use group, not unique group!!! - def __init__(self, instance, basedn, rdn='ou=Groups'): + def __init__(self, instance, basedn, rdn=DEFAULT_BASEDN_RDN): super(UniqueGroups, self).__init__(instance) self._objectclasses = [ 'groupOfUniqueNames', @@ -203,7 +205,7 @@ class nsAdminGroups(DSLdapObjects): :type rdn: str """ - def __init__(self, instance, basedn, rdn='ou=People'): + def __init__(self, instance, basedn, rdn=DEFAULT_BASEDN_RDN_ADMIN_GROUPS): super(nsAdminGroups, self).__init__(instance) self._objectclasses = [ 'nsAdminGroup' diff --git a/src/lib389/lib389/idm/posixgroup.py b/src/lib389/lib389/idm/posixgroup.py index 90fb00fb62..e1dba10704 100644 --- a/src/lib389/lib389/idm/posixgroup.py +++ b/src/lib389/lib389/idm/posixgroup.py @@ -1,6 +1,6 @@ # --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2016, William Brown -# Copyright (C) 2023 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -17,6 +17,7 @@ 'gidNumber', ] RDN = 'cn' +DEFAULT_BASEDN_RDN = 'ou=Groups' class PosixGroup(DSLdapObject): @@ -72,7 +73,7 @@ class PosixGroups(DSLdapObjects): :type basedn: str """ - def __init__(self, instance, basedn, rdn='ou=Groups'): + def __init__(self, instance, basedn, rdn=DEFAULT_BASEDN_RDN): super(PosixGroups, self).__init__(instance) self._objectclasses = [ 'groupOfNames', diff --git a/src/lib389/lib389/idm/services.py b/src/lib389/lib389/idm/services.py index 0439cf8f31..74b389a51f 100644 --- a/src/lib389/lib389/idm/services.py +++ b/src/lib389/lib389/idm/services.py @@ -1,6 +1,6 @@ # --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2016, William Brown -# Copyright (C) 2021 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -16,6 +16,7 @@ MUST_ATTRIBUTES = [ 'cn', ] +DEFAULT_BASEDN_RDN = 'ou=Services' class ServiceAccount(Account): """A single instance of Service entry @@ -59,7 +60,7 @@ class ServiceAccounts(DSLdapObjects): :type basedn: str """ - def __init__(self, instance, basedn, rdn='ou=Services'): + def __init__(self, instance, basedn, rdn=DEFAULT_BASEDN_RDN): super(ServiceAccounts, self).__init__(instance) self._objectclasses = [ 'applicationProcess', diff --git a/src/lib389/lib389/idm/user.py b/src/lib389/lib389/idm/user.py index 1206a6e082..3b21ccf1c2 100644 --- a/src/lib389/lib389/idm/user.py +++ b/src/lib389/lib389/idm/user.py @@ -1,6 +1,6 @@ # --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2016, William Brown -# Copyright (C) 2023 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -23,6 +23,7 @@ 'homeDirectory', ] RDN = 'uid' +DEFAULT_BASEDN_RDN = 'ou=People' TEST_USER_PROPERTIES = { 'uid': 'testuser', @@ -201,7 +202,7 @@ class UserAccounts(DSLdapObjects): :type rdn: str """ - def __init__(self, instance, basedn, rdn='ou=People'): + def __init__(self, instance, basedn, rdn=DEFAULT_BASEDN_RDN): super(UserAccounts, self).__init__(instance) self._objectclasses = [ 'account',