Bug 58828 - UDM doesn't release mailPrimaryAddress lock on modification of attribute
Summary: UDM doesn't release mailPrimaryAddress lock on modification of attribute
Status: CLOSED FIXED
Alias: None
Product: UCS
Classification: Unclassified
Component: UDM (Generic)
Version: UCS 5.2
Hardware: Other Linux
: P5 normal
Target Milestone: UCS 5.2-3-errata
Assignee: Jürn Brodersen
QA Contact: Felix Botner
URL: https://git.knut.univention.de/univen...
Keywords:
Depends on:
Blocks:
 
Reported: 2025-11-21 10:24 CET by Jürn Brodersen
Modified: 2025-11-27 13:19 CET (History)
1 user (show)

See Also:
What kind of report is it?: Bug Report
What type of bug is this?: 5: Major Usability: Impairs usability in key scenarios
Who will be affected by this bug?: 5: Will affect all installed domains
How will those affected feel about the bug?: 4: A User would return the product
User Pain: 0.571
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 Jürn Brodersen univentionstaff 2025-11-21 10:24:21 CET
udm doesn't release mailPrimaryAddress lock if address is already taken

How to reproduce:
```
udm users/user create --set username=mail1 --set lastname=mail1 --set password=univention --set mailPrimaryAddress=mail@foo.test
udm settings/lock list --filter name=mail@foo.test # Not locked
udm users/user create --set username=mail2 --set lastname=mail2 --set password=univention --set mailPrimaryAddress=mail@foo.test # Error
udm settings/lock list --filter name=mail@foo.test # Locked!
```

Changing the mailPrimaryAddress on the first user doesn't release the lock. That means that no other user can use the address until the lock has been removed manually. (Deleting the user while they still have "mail@foo.test" set, seems to clean, the lock, up)
Comment 1 Jürn Brodersen univentionstaff 2025-11-21 11:57:43 CET
Note: Customer needs a backport to 5.0
Comment 2 Florian Best univentionstaff 2025-11-21 13:45:43 CET
What is the bug/problem here?

1. user creation:
# udm users/user create --set username=mail1 --set lastname=mail1 --set password=univention --set mailPrimaryAddress=mail@ucs.test
WARNING: The object is not going to be created underneath of its default containers.
Object created: uid=mail1,dc=ucs,dc=test
# udm settings/lock list --filter name=mail@ucr.test # Not locked
name=mail@ucr.test

The lock was created and removed immediately again. Because it's not needed anymore, because the locking mechanism will also search for mailPrimaryAdress=$value and that functions as lock.

2. 
# udm users/user create --set username=mail2 --set lastname=mail2 --set password=univention --set mailPrimaryAddress=mail@ucs.test
WARNING: The object is not going to be created underneath of its default containers.
The mail address is already in use: mail@ucs.test.
# udm settings/lock list --filter name=mail@ucs.test
name=mail@ucs.test
DN: cn=mail@ucs.test,cn=mailPrimaryAddress,cn=temporary,cn=univention,dc=ucs,dc=test
  locktime: 1763700958
  name: mail@ucs.test
  univentionObjectIdentifier: None

The lock is created, because the search for existing objects with that primaryMailAddress is done afterwards. But that lock is not cleaned up again.
It has an expiry date of 5 minutes. There should not be a problem with that object existing forever (until:).

3.
# udm users/user remove --dn uid=mail1,dc=ucs,dc=test
Object removed: uid=mail1,dc=ucs,dc=test
# udm settings/lock list --filter name=mail@ucs.test
name=mail@ucs.test

The object which takes the address is removed. This also cleans up the lock.
So a new object can use that mailPrimaryAddress again.
Comment 3 Florian Best univentionstaff 2025-11-21 15:17:02 CET
Okay, the problem is the following:

When a lock object still exists, and one modifies the real object so that mailPrimaryAddress is "b" (prior "a"), the lock for "a" is not cleaned up and is therefore leftover.

So if one create an object A with mPA=a (lock created and released) and create another object with the same mPA=a, the lock is created but not released because after the lock was created a uniqueness search is done, which says that the attribute is already in use, and a noLock exception is raised. But the cleanup() / __release_locks() function doesn't remove it because it's not in the "self.alloc" due to the exception - the process is not the author of the lock. The lock therefore exists, and blocks the creation of anther object with the same value, if the value of object A is then renamed.

The real fix is in theory
```diff
+++ management/univention-directory-manager-modules/modules/univention/admin/handlers/users/user.py
@@ -1435,6 +1435,9 @@ class object(univention.admin.handlers.simpleLdap, PKIIntegration, GuardianBase)
                         if self['mailPrimaryAddress'] not in self['mailAlternativeAddress']:
                             do_request_lock = False
                 if do_request_lock:
+                    if self.exists():
+                        self.alloc.append(('mailPrimaryAddress', self['mailPrimaryAddress']))
+
                     try:
                         self.request_lock('mailPrimaryAddress', self['mailPrimaryAddress'])
                     except univention.admin.uexceptions.noLock:
```

but in practice this affects every locked attribute.
Therefore Jürn has a patch, which removed the lock, immediately in the else-branch of the uniqueness search.
Comment 4 Felix Botner univentionstaff 2025-11-22 12:22:52 CET
59_udm.61_test_udm_users_release_mailPrimaryAddress.test_release_mailPrimaryAddress

fails
Comment 5 Jürn Brodersen univentionstaff 2025-11-24 09:59:24 CET
Sorry, something went wrong for the package build :(

Should be build now
Comment 6 Felix Botner univentionstaff 2025-11-25 10:03:33 CET
OK - tests
OK - univention-directory-manager-modules
OK - advisory
Comment 7 Dirk Wiesenthal univentionstaff 2025-11-27 13:19:32 CET
<https://errata.software-univention.de/#/?erratum=5.2x297>