]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Changing error handling on LDAP operations.
authorFrank Brehm <frank@brehm-online.com>
Fri, 9 Sep 2022 09:29:09 +0000 (11:29 +0200)
committerFrank Brehm <frank@brehm-online.com>
Fri, 9 Sep 2022 09:29:09 +0000 (11:29 +0200)
lib/pp_admintools/app/ldap.py
lib/pp_admintools/app/remove_ldap_user.py

index 12d5fb0dbb8e203eb6a1761d79022fe86d33b7d9..ec7391608c550c2425a4794bf0403c1c86abd692 100644 (file)
@@ -50,7 +50,7 @@ from ..config.ldap import LdapConnectionInfo, LdapConfiguration
 # rom ..config.ldap import DEFAULT_PORT_LDAP, DEFAULT_PORT_LDAPS
 from ..config.ldap import DEFAULT_TIMEOUT
 
-__version__ = '0.4.7'
+__version__ = '0.5.1'
 LOG = logging.getLogger(__name__)
 
 _ = XLATOR.gettext
@@ -69,6 +69,12 @@ class FatalLDAPError(LdapAppError):
     pass
 
 
+# =============================================================================
+class LDAPExecutionError(FatalLDAPError):
+    """Error class in case, a LDAP operation was not successful."""
+    pass
+
+
 # =============================================================================
 class WriteLDAPItemError(FatalLDAPError):
     """Error class in case, a LDAP item could not be written."""
@@ -931,10 +937,26 @@ class BaseLdapApplication(BaseDPXApplication):
             msg = _("Modification NOT successfull - {c}: {e}").format(c=e.__class__.__name__, e=e)
             msg += '\n' + _("Changes:") + '\n' + pp(changes)
             raise WriteLDAPItemError(msg)
-        LOG.debug(_('Modification successful.'))
+
+        # Example result on a not successful modification:
+        # {     'description': 'objectClassViolation',
+        #       'dn': '',
+        #       'message': 'attribute "loginShell" not allowed\n',
+        #       'referrals': None,
+        #       'result': 65,
+        #       'type': 'modifyResponse'}
+
+        if self.verbose > 1:
+            LOG.debug(_("Modification status: {!r}.").format(req_status))
         if self.verbose > 2:
             LOG.debug(_("Result of modifying:") + '\n' + pp(req_result))
 
+        if not req_status:
+            msg = _("Modification NOT successful: {desc} - {msg}").format(
+                desc=req_result['description'], msg=req_result['message'].strip())
+            raise WriteLDAPItemError(msg)
+
+        LOG.debug(_('Modification successful.'))
         return True
 
     # -------------------------------------------------------------------------
@@ -956,10 +978,19 @@ class BaseLdapApplication(BaseDPXApplication):
         except LDAPException as e:
             msg = _("Deletion NOT successfull - {c}: {e}").format(c=e.__class__.__name__, e=e)
             raise DeleteLDAPItemError(msg)
-        LOG.debug(_('Deletion successful.'))
+
+        if self.verbose > 1:
+            LOG.debug(_("Deletion status: {!r}.").format(req_status))
         if self.verbose > 2:
             LOG.debug(_("Result of deletion:") + '\n' + pp(req_result))
 
+        if not req_status:
+            msg = _("Deletion NOT successful: {desc} - {msg}").format(
+                desc=req_result['description'], msg=req_result['message'].strip())
+            raise DeleteLDAPItemError(msg)
+
+        LOG.debug(_('Deletion successful.'))
+
         return True
 
     # -------------------------------------------------------------------------
index bade2c5d869b97c77b0970bbb02ee1632e50c910..f4c52c5a3d8cceab8363fec8356c90c3532e054d 100644 (file)
@@ -22,10 +22,10 @@ from ..xlate import XLATOR
 
 from . import AbortAppError, TimeoutOnPromptError
 
-from .ldap import LdapAppError
+from .ldap import LdapAppError, FatalLDAPError
 from .ldap import BaseLdapApplication
 
-__version__ = '0.4.5'
+__version__ = '0.5.1'
 LOG = logging.getLogger(__name__)
 
 _ = XLATOR.gettext
@@ -192,7 +192,8 @@ class RemoveLdapUserApplication(BaseLdapApplication):
             LOG.warn(msg)
 
         for inst in self.dns:
-            self.remove_users_from_inst(inst)
+            if not self.remove_users_from_inst(inst):
+                break
 
     # -------------------------------------------------------------------------
     def request_for_remove(self):
@@ -298,7 +299,10 @@ class RemoveLdapUserApplication(BaseLdapApplication):
         LOG.info(msg)
 
         for dn in self.dns[inst]:
-            self.remove_user(inst, dn)
+            if not self.remove_user(inst, dn):
+                return False
+
+        return True
 
     # -------------------------------------------------------------------------
     def remove_user(self, inst, dn):
@@ -318,17 +322,38 @@ class RemoveLdapUserApplication(BaseLdapApplication):
             msg = _("Attributes of {!r}:").format(dn)
             LOG.debug(msg + '\n' + pp(attributes.as_dict()))
 
-        self.setting_user_status(inst, dn, attributes)
-        self.remove_all_memberships(inst, dn)
-        self.remove_all_unique_memberships(inst, dn)
+        if not self.setting_user_status(inst, dn, attributes):
+            return False
+        if not self.remove_all_memberships(inst, dn):
+            return False
+        if not self.remove_all_unique_memberships(inst, dn):
+            return False
 
         if 'uid' in attributes:
             for uid in attributes['uid']:
-                self.remove_all_posixgroup_memberships(inst, uid)
-                self.remove_all_sudogroup_memberships(inst, uid)
+                if not self.remove_all_posixgroup_memberships(inst, uid):
+                    return False
+                if not self.remove_all_sudogroup_memberships(inst, uid):
+                    return False
 
         if not self.deactivate:
-            self.delete_entry(inst, dn)
+            try:
+                self.delete_entry(inst, dn)
+            except FatalLDAPError as e:
+                msg = _("{c} on removing user {dn!r}: {e}").format(
+                    c=e.__class__.__name__, dn=dn, e=e)
+                LOG.error(msg)
+                return False
+
+        if self.deactivate:
+            msg = _("User {dn!r} successful deactivated on {inst}.").format(
+                dn=dn, inst=connect_info.url)
+        else:
+            msg = _("User {dn!r} successful removed from {inst}.").format(
+                dn=dn, inst=connect_info.url)
+        LOG.info(msg)
+
+        return True
 
     # -------------------------------------------------------------------------
     def setting_user_status(self, inst, dn, attributes):
@@ -336,18 +361,12 @@ class RemoveLdapUserApplication(BaseLdapApplication):
         connect_info = self.cfg.ldap_connection[inst]
         changes = {}
 
-        is_mail_user = False
+        if 'inetUser' in attributes:
+            changes['inetUserStatus'] = [(MODIFY_REPLACE, 'inactive')]
         if 'inetMailUser' in attributes['objectClass']:
-            is_mail_user = True
-            LOG.debug(_("User {!r} is a mail user.").format(dn))
-        else:
-            LOG.debug(_("User {!r} is not a mail user.").format(dn))
-
-        changes['inetUserStatus'] = [(MODIFY_REPLACE, 'inactive')]
-        if is_mail_user:
             changes['mailUserStatus'] = [(MODIFY_REPLACE, 'inactive')]
 
-        if 'userPassword' in attributes:
+        if 'userPassword' in attributes and 'inetOrgPerson' in attributes['objectClass']:
             old_pwd_hash = attributes['userPassword'][0]
             changes['carLicense'] = [(MODIFY_ADD, old_pwd_hash)]
         changes['userPassword'] = [(MODIFY_REPLACE, self.raw_empty_passwd)]
@@ -358,7 +377,16 @@ class RemoveLdapUserApplication(BaseLdapApplication):
 
         LOG.info(_("Updating user info for {dn!r} on {inst} ...").format(
             dn=dn, inst=connect_info.url))
-        self.modify_entry(inst, dn, changes)
+        try:
+            self.modify_entry(inst, dn, changes)
+        except FatalLDAPError as e:
+            msg = _("{c} on deactivating user {dn!r}: {e}").format(
+                c=e.__class__.__name__, dn=dn, e=e)
+            msg += '\n' + _('Changes:') + '\n' + pp(changes)
+            LOG.error(msg)
+            return False
+
+        return True
 
     # -------------------------------------------------------------------------
     def remove_all_memberships(self, inst, dn):
@@ -376,7 +404,16 @@ class RemoveLdapUserApplication(BaseLdapApplication):
         for group_dn in group_dns:
             LOG.info(_("Removing user {u!r} from group {g!r} ...").format(u=dn, g=group_dn))
             changes = {'member': [(MODIFY_DELETE, dn)], }
-            self.modify_entry(inst, group_dn, changes)
+            try:
+                self.modify_entry(inst, group_dn, changes)
+            except FatalLDAPError as e:
+                msg = _("{c} on removing user {dn!r} from group {g!r}: {e}").format(
+                    c=e.__class__.__name__, dn=dn, g=group_dn, e=e)
+                msg += '\n' + _('Changes:') + '\n' + pp(changes)
+                LOG.error(msg)
+                return False
+
+        return True
 
     # -------------------------------------------------------------------------
     def remove_all_unique_memberships(self, inst, dn):
@@ -394,7 +431,16 @@ class RemoveLdapUserApplication(BaseLdapApplication):
         for group_dn in group_dns:
             LOG.info(_("Removing user {u!r} from group {g!r} ...").format(u=dn, g=group_dn))
             changes = {'uniqueMember': [(MODIFY_DELETE, dn)], }
-            self.modify_entry(inst, group_dn, changes)
+            try:
+                self.modify_entry(inst, group_dn, changes)
+            except FatalLDAPError as e:
+                msg = _("{c} on removing user {dn!r} from group {g!r}: {e}").format(
+                    c=e.__class__.__name__, dn=dn, g=group_dn, e=e)
+                msg += '\n' + _('Changes:') + '\n' + pp(changes)
+                LOG.error(msg)
+                return False
+
+        return True
 
     # -------------------------------------------------------------------------
     def remove_all_posixgroup_memberships(self, inst, uid):
@@ -416,7 +462,16 @@ class RemoveLdapUserApplication(BaseLdapApplication):
         for group_dn in group_dns:
             LOG.info(_("Removing user {u!r} from group {g!r} ...").format(u=uid, g=group_dn))
             changes = {'memberUid': [(MODIFY_DELETE, uid)], }
-            self.modify_entry(inst, group_dn, changes)
+            try:
+                self.modify_entry(inst, group_dn, changes)
+            except FatalLDAPError as e:
+                msg = _("{c} on removing user {dn!r} from group {g!r}: {e}").format(
+                    c=e.__class__.__name__, dn=uid, g=group_dn, e=e)
+                msg += '\n' + _('Changes:') + '\n' + pp(changes)
+                LOG.error(msg)
+                return False
+
+        return True
 
     # -------------------------------------------------------------------------
     def remove_all_sudogroup_memberships(self, inst, uid):
@@ -438,7 +493,16 @@ class RemoveLdapUserApplication(BaseLdapApplication):
         for group_dn in group_dns:
             LOG.info(_("Removing user {u!r} from group {g!r} ...").format(u=uid, g=group_dn))
             changes = {'sudoUser': [(MODIFY_DELETE, uid)], }
-            self.modify_entry(inst, group_dn, changes)
+            try:
+                self.modify_entry(inst, group_dn, changes)
+            except FatalLDAPError as e:
+                msg = _("{c} on removing user {dn!r} from group {g!r}: {e}").format(
+                    c=e.__class__.__name__, dn=uid, g=group_dn, e=e)
+                msg += '\n' + _('Changes:') + '\n' + pp(changes)
+                LOG.error(msg)
+                return False
+
+        return True
 
 
 # =============================================================================