Bug 52202 - Feature Request: Introduce a "Recycle Bin" for user objects
Summary: Feature Request: Introduce a "Recycle Bin" for user objects
Status: CLOSED FIXED
Alias: None
Product: UCS
Classification: Unclassified
Component: General
Version: UCS 5.2
Hardware: Other other
: P5 normal
Target Milestone: UCS 5.2-3-errata
Assignee: Florian Best
QA Contact: Felix Botner
URL: https://git.knut.univention.de/univen...
Keywords:
Depends on:
Blocks: 58844 58880 58912 58887
  Show dependency treegraph
 
Reported: 2020-10-09 17:26 CEST by Michael Grandjean
Modified: 2025-12-19 12:18 CET (History)
1 user (show)

See Also:
What kind of report is it?: Feature Request
What type of bug is this?: ---
Who will be affected by this bug?: ---
How will those affected feel about the bug?: ---
User Pain:
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional):
Customer ID:
Max CVSS v3 score:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Grandjean univentionstaff 2020-10-09 17:26:16 CEST
It would be great to have some kind of "Recycle Bin" functionality in UCS.

Scenario: I accidentally delete a user object via UMC or UDM. Instead of actually deleting it, the user object could be a) deactivated and b) moved to a dedicated "Recycle Bin"-tree in the LDAP tree (e.g. OU=recyclebin).
In this case the user could easily be "restored".

Moving a user to the recycle bin could be the default, but there has to be a checkbox/option to bypass the recycle bin, so we can still completely delete a user (just think "DEL" vs. "SHIFT+DEL" on your keyboard).

Variant: In UCS@school the userimport is usually configured to not directly delete users but to deactivate them now and delete them weeks later. Unfortunately, those deactivated users are still visible in all UCS@school modules, take part in the exam mode and are still present and available in external applications. By moving them to a special OU, they would disappear from most of these use cases.

Side effect: unique attributes of the user (username, SID, uidNumber ...) cannot be re-used by a new user as long as the "deleted" user exists in the recycle bin.

Possible obstacles:
- S4- and AD-Connector should probably not just move the user object in Samba/AD, but delete it there because AD has its own concepts for "Deleted objects".
- I thought about having a recycle bin for _all_ LDAP objects and not just for users, but I think there are too many special cases where this wouldn't be a good choice (e.g. objects in cn=temporary).
Comment 1 Jan-Luca Kiok univentionstaff 2025-02-05 09:29:07 CET
This issue has been filed against an older version of UCS.

With further development of our products affected components may have vastly changed while the corresponding use cases might have changed. Thus, this issue is now being closed.

If there still is a need for this feature, please use "Clone this bug" or reopen this issue. In this case please provide information on how this issue would benefit you.
Comment 2 Florian Best univentionstaff 2025-11-21 16:47:48 CET
A UDM module for a generic recyclebin object representation has been added: `recyclebin/removedobject`.
It stores all original LDAP attributes of the removed object by using the LDAP object class `extensibleObject`.
Additional some metadata is stored: original DN, object identifier, object type, entryUUID, object classes, references, remove date, and purge timestamp.
The object is stored in the second LDAP database `cn=internal`.

Currently only users/user and groups/group are supported. Supporting every object is extra effort because the reference handling must be implemented.
The referential integrity can't be assured for properties managed by extended attributes and hooks, if these use external (backwards) references.

The UDM module displays the original attributes of the objects, which is very slow in UDM CLI as for each object the property descriptions change. It could also have other side effects in libraries using UDM in a certain way. But we don't expect any lib to use recyclebin objects at the moment.
This could have been solved simpler, by creating a recyclebin type per original type (e.g. `recyclebin/user`, `recyclebin/group`), which just inherits from one generic super object. But the time constrains didn't allow.

The recyclebin must be enabled by creating a `policies/recyclebin` policy (or use the default one) and attach it to the position, e.g. the LDAP base container.
The recyclebin objects are automatically purged by the LDAP Dynamic directory services (DDS) overlay module, after the specified amount of time in that policy.
The policy allows to exclude certain objects classes (like `ucsschoolExam`) to be ignored from being moved to the recyclebin. 

We don't ensure uniqueness of attributes used by the recyclebin. So there could be conflicts if a removed user "foo" is in the recyclebin, a new user "foo" is created and the recyclebin object is going to be restored.
For this, the administrator must configure the blocklists feature for the corresponding attributes of users/user and groups/group.

For security, correctness and performance reasons, the move-to-recyclebin action is done asynchronously in a listener module.
A better implementation would be via an OpenLDAP overlay module, which could do this as extended operation or as delete operation with certain LDAP controls, giving the information e.g. from the policy.

UMC and UDM REST API have been extended to support the restore operation.

More implementation details have been documented here:
https://github.com/univention/univention-corporate-server/blob/5.2-3/management/univention-directory-manager-modules/README-recyclcebin.md

univention-web (6.3.2)
3eb02d64e9fb | feat(umc-udm): add UMC module for recyclebin

univention-system-setup (8.0.10-1)
r52202 | Bug #35378: added another dependency / fixed switch to user nobody: keep DISPLAY env variable

univention-management-console-module-udm (12.3.4)
7d484313c8fe | fix(umc-udm): display correct LDAP database when no permissions to see exists

univention-management-console-module-udm (12.3.3)
3eb02d64e9fb | feat(umc-udm): add UMC module for recyclebin

univention-ldap (18.3.3)
5a2951099cee | fix(ldap): enable DDS overlay by default
55a38d39b5a3 | feat(ldap): adjust UCR variable names for DDS overlay

univention-ldap (18.3.2)
87da91244b85 | feat(udm): purge recyclebin objects automatically
613ad3d31d2f | feat(udm): add recyclebin for removed objects

univention-directory-manager-rest (12.3.3)
71daaf5bac08 | feat(udm-rest): add support for restore operation

univention-directory-manager-modules (17.3.8)
cf75b53f2fc0 | feat(udm): fix integration of admin diary

univention-directory-manager-modules (17.3.7)
0ddd3de7fe63 | docs(udm): add developer notes for recyclebin implemenation
87da91244b85 | feat(udm): purge recyclebin objects automatically
613ad3d31d2f | feat(udm): add recyclebin for removed objects

univention-admin-diary (4.3.2)
c945ff8474b3 | feat(admin-diary): add RESTORED events for users and groups

univention-admin-diary (4.3.1)
73085d7c7b6a | feat(admin-diary): add RESTORED event

ucs-test (12.3.39)
5a2951099cee | fix(ldap): enable DDS overlay by default
55a38d39b5a3 | feat(ldap): adjust UCR variable names for DDS overlay

ucs-test (12.3.38)
422a072f49ec | test(udm-authorization): add test_can_not_query_recyclebin

ucs-test (12.3.37)
0edf072ac663 | test(udm-rest): add tests for restore functionality
c15dcc09e43a | test(ldap): add DDS integration tests for recyclebin automatic purging
b7a89d07f482 | test(udm): add tests for UDM recyclebin

univention-web.yaml
7e831e1334a9 | chore(web): update advisory

univention-management-console-module-udm.yaml
7d484313c8fe | fix(umc-udm): display correct LDAP database when no permissions to see exists
7e831e1334a9 | chore(web): update advisory

univention-ldap.yaml
55a38d39b5a3 | feat(ldap): adjust UCR variable names for DDS overlay
7e831e1334a9 | chore(web): update advisory

univention-directory-manager-rest.yaml
7e831e1334a9 | chore(web): update advisory

univention-directory-manager-modules.yaml
cf75b53f2fc0 | feat(udm): fix integration of admin diary
7e831e1334a9 | chore(web): update advisory

univention-admin-diary.yaml
3aefef5e6333 | chore(admin-diary): update advisory
7e831e1334a9 | chore(web): update advisory

.pre-commit-config.yaml
55a38d39b5a3 | feat(ldap): adjust UCR variable names for DDS overlay
Comment 3 Felix Botner univentionstaff 2025-11-25 11:23:14 CET
597d72f498c fix(udm): fix recyclebin listener
b19fb7da22f test(ad-connector): add recursive delete to ADConnection
1ae2fd521be test(recyclebin): fix tests on backup, use correct LDAP connection
fc82c76e897 fix(udm): fix recyclebin listener
297930e249f test(recyclebin): fix tests on backup, use correct LDAP connection
8e08db0ef24 fix(udm): fix recyclebin listener

Successful build
Package: univention-directory-manager-modules
Version: 17.3.13
Release: 5.2-0
Scope: errata5.2-3
Comment 4 Felix Botner univentionstaff 2025-11-25 12:47:14 CET
656ac88e1ba fix(udm): fix recyclebin policy

Successful build
Package: univention-directory-manager-modules
Version: 17.3.14
Release: 5.2-0
Scope: errata5.2-3
Comment 5 Felix Botner univentionstaff 2025-11-27 11:09:00 CET
OK - tests
OK - advisories
OK - packages


Still not fully complete as support for restore with AD and S4 connector is missing, but this will be released soonish.
Comment 6 Florian Best univentionstaff 2025-11-27 12:18:13 CET
How to set up and use the recyclebin:

1. Upgrade the system to latest errata updates
2. Create a recylebin policy (or use the default one)

```
eval "$(univention-config-registry shell ldap/base)"
univention-directory-manager policies/recyclebin create \
      --ignore_exists \
      --position "cn=recyclebin,cn=policies,$ldap_base" \
      --set name="my-recyclebin-settings" \
      --set retention_days="180" \
      --set enabled=TRUE \
      --append ignored_object_classes="ucsschoolExam" \
      --append udm_modules="users/user" \
      --append udm_modules="groups/group"
```

Alternatively do it via UMC: in the "Policies" module.

3. Assign the policy, e.g. to the whole domain or any subtree container (or selected objects, which should go into the recyclebin):

```
eval "$(univention-config-registry shell ldap/base)"
univention-directory-manager container/dc modify \
    --dn "$ldap_base" \
    --policy-reference "cn=my-recyclebin-settings,cn=recyclebin,cn=policies,$ldap_base"
```

4. Remove any user or group object (e.g. via UMC, UDM-CLI, UDM REST API)
The moving to the recyclebin should show up in `/var/log/univention/listener_modules/recyclebin.log`and in `/var/log/univention/listener.log` on the DC Primary(!).
Including it's DN, e.g:
Created deleted object: univentionRecycleBinOriginalDN=uid\=gszmlbilvp\,cn\=recyclebin_aiq8wlqeud\,dc\=ucs\,dc\=test+univentionRecycleBinOriginalUniventionObjectIdentifier=1037b2ad-736f-4f46-b282-3c99b1c7d9ab,cn=recyclebin,cn=internal (retention: 159 days)

5. Open the removed object in the recyclebin
Open the new UMC module "Recyclebin" (in category "Domain") or via UDM CLI: `udm recyclebin/removedobject list`

6. Restore the object via the UMC module or UDM CLI (on the DC Primary) (get the DN from `udm recyclebin/removedobject list`)
`udm recyclebin/removedobject restore --dn "$DN_OF_RECYCLEBIN_OBJECT"`

The event will also be logged in the corresponding logfile e.g. `/var/log/univention/directory-manager-cmd.log` or `/var/log/univention/management-console-module-udm.log` or `/var/log/univention/directory-manager-rest.log`.

7. Alternatively, wait 180 days (configured by your policy) and see the object being purged by OpenLDAP (DDS overlay module)