Bug 45468 - Wizard empties extended attribute
Wizard empties extended attribute
Product: UCS@school
Classification: Unclassified
Component: UMC - Password reset
UCS@school 4.2
Other Linux
: P5 normal (vote)
: UCS@school 4.2 v4
Assigned To: Florian Best
Daniel Tröder
: 40527 (view as bug list)
Depends on:
Blocks: 46012
  Show dependency treegraph
Reported: 2017-09-28 16:17 CEST by Hendrik Peter
Modified: 2018-01-11 16:40 CET (History)
4 users (show)

See Also:
What kind of report is it?: Bug Report
What type of bug is this?: 4: Minor Usability: Impairs usability in secondary scenarios
Who will be affected by this bug?: 2: Will only affect a few installed domains
How will those affected feel about the bug?: 3: A User would likely not purchase the product
User Pain: 0.137
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional):
Max CVSS v3 score:


Note You need to log in before you can comment on or make changes to this bug.
Description Hendrik Peter univentionstaff 2017-09-28 16:17:50 CEST
The content of extended attributes on an User object is cleared, when a password is reset by this Wizard.
This can potentially lead to big data loss over time.
Comment 1 Sönke Schwardt-Krummrich univentionstaff 2017-09-29 10:44:15 CEST
(In reply to Hendrik Peter from comment #0)
> The content of extended attributes on an User object is cleared, when a
> password is reset by this Wizard.

There are several extended attributes, that are not emptied (e.g. ucsschoolSchool). But in case of this cool solution, the affected quota LDAP attribute uses a "complex" syntax which may (not explicitly tested!) contribute to this error.

Workaround / possible fix that worked on the affected machine:

--- a/ucs-school-umc-users/umc/python/schoolusers/__init__.py
+++ b/ucs-school-umc-users/umc/python/schoolusers/__init__.py
@@ -99,6 +99,7 @@ class Instance(SchoolBaseModule):
 			ur['overridePWHistory'] = '1'
 			dn = ur.modify()
+			ur = udm_objects.get(user_module, None, lo, None, dn)
 			ur['locked'] = 'none'
 			dn = ur.modify()
Comment 2 Sönke Schwardt-Krummrich univentionstaff 2017-09-29 14:20:45 CEST
Just for completeness:
The problem ocurred with a cool solution and UCS@school. A teacher tried to reset student passwords via UMC (module "Passwörter (Schüler)") and an LDAP error due to insufficient access rights has been shown to the user.

It broke the cool solution since the password reset tried to modify the quota LDAP attribute for which teachers have no write permission (and there was no reason to alter this attribute!). It looks like after calling userobj.modify() the state of userobj is incomplete and the UDM user object has to be refetched from LDAP before another modification is possible (see provided patch above).

Since I suspect that other extended attributes/apps are affected as well, I increased the severity of this bug.
Comment 6 Florian Best univentionstaff 2017-10-05 11:15:34 CEST
Let's use that patch.
Comment 7 Florian Best univentionstaff 2017-10-05 13:28:02 CEST
This is a bug in the domainquota cool solution implementation:

hook_open() makes some broken things.
It uses the same attribute as property and modifies the value in open() to an list of values.

The error therefore happens already when a second open() is done (which is probably happen at more places than just this module):
>>> ur = udm_objects.get(user_module, None, lo, None, userdn)
>>> ur
<univention.admin.handlers.users.user.object object at 0x7f5c6e30c850>
>>> ur.info.get('domainquota')
>>> ur.open()
>>> ur.info.get('domainquota')
[['master.school.local', '/asdf', '1', 'MiB']]
>>> ur.open()
>>> ur.info.get('domainquota')

The only thing we could fix here would be to use the schoolmodels instead of plain UDM because we don't do a explicit modules.init() for the users/user module. It happens implicit by the query() for users (in the search). But if between the query and the modification the module timeout kills the module then no extended attributes, UCR syntax settings, etc. aren't evaluated. Please REOPEN if we should fix this.
Comment 8 Florian Best univentionstaff 2017-10-05 15:44:05 CEST
I decided to fix this and other flaws.

First: I moved the error handling from the frontend to the backend because the tests 04_ucs-school-reset-password-check and 17_http_proxy_auth_after_passwd_reset_check did not detect errors properly.
Then the UCS@school models lib is now used, which does the UDM initialization and the .open() call.
The properties are now set in one call. There were errors in UDM in the past which caused that they couldn't be set at once, these are meanwhile fixed so that this is working.
This causes that the error in the cool solution isn't triggered anymore.
32b28aa7b61a | YAML Bug #45468

ucs-school-umc-users (13.0.0-4):
03f3e3de5a0c | Bug #45468: Merge branch 'fbest/45468-udm-usage-in-password-reset' into 4.2
a521eb38cceb | Bug #45468: use school models instead of plain UDM

ucs-test-ucsschool (4.0.4-31):
03f3e3de5a0c | Bug #45468: Merge branch 'fbest/45468-udm-usage-in-password-reset' into 4.2
a521eb38cceb | Bug #45468: use school models instead of plain UDM
Comment 9 Florian Best univentionstaff 2017-10-09 15:47:55 CEST
I created https://univention.plan.io/issues/8970 for the cool solution which should be fixed.
Comment 10 Daniel Tröder univentionstaff 2017-10-13 12:21:19 CEST
OK: advisory
OK: manual test (resetting password)
OK: automated test 04_ucs-school-reset-password-check
OK: 17_http_proxy_auth_after_passwd_reset_check
REOPEN: 90_ucsschool/23_password_reset fails in my VM:

PasswordReset('m150', 'teacher', 'mqkggy17vz', 'univention').assert_login(('y6jaorq4lv', 'uid=y6jaorq4lv,cn=schueler,cn=users,ou=uijkzw,dc=uni,dc=dtr'), old_password='univention', new_password='mhrdngpjm2', change_password_on_next_login=True)
PasswordReset('m150', 'teacher', 'mqkggy17vz', 'univention').test_login(('y6jaorq4lv', 'uid=y6jaorq4lv,cn=schueler,cn=users,ou=uijkzw,dc=uni,dc=dtr'), 'univention')

*** UMC request: "POST auth" (None)
UMC request payload: 
{'options': {'password': 'univention',
             'username': ('y6jaorq4lv',
UMC request failed: 401 on m150 (auth): {"status": 401, "message": "The authentication has failed, please login again.", "location": "https://m150/univention/auth"}

PasswordReset('m150', 'teacher', 'mqkggy17vz', 'univention').test_login(('y6jaorq4lv', 'uid=y6jaorq4lv,cn=schueler,cn=users,ou=uijkzw,dc=uni,dc=dtr'), 'mhrdngpjm2')

*** UMC request: "POST auth" (None)
UMC request payload: 
{'options': {'password': 'mhrdngpjm2',
             'username': ('y6jaorq4lv',
UMC request failed: 401 on m150 (auth): {"status": 401, "message": "The authentication has failed, please login again.", "location": "https://m150/univention/auth"}

*** Cleanup after exception: <type 'exceptions.AttributeError'> 'NoneType' object has no attribute 'get'


Traceback (most recent call last):
  File "23_password_reset", line 227, in <module>
  File "23_password_reset", line 223, in main
    TestPasswordReset(schoolenv, school, host)
  File "23_password_reset", line 120, in __init__
  File "23_password_reset", line 214, in test_umc_authentication
    password_reset.assert_login(target, old_password, new_password, change_password_on_next_login)
  File "23_password_reset", line 75, in assert_login
    assert login.result.get('password_expired'), 'The password is not expired - as expected'
AttributeError: 'NoneType' object has no attribute 'get'
Comment 11 Florian Best univentionstaff 2017-10-16 15:37:48 CEST
Fixed the test case:

ucs-test-ucsschool (4.0.4-33)
f90fc181e9d7 | Bug #45468: fix 23password_reset
1d3de68de258 | Bug #45468: fix request arguments for auth request
0ac66af72236 | Bug #45468: fix request arguments for auth request
Comment 12 Florian Best univentionstaff 2017-10-16 15:39:00 CEST
*** Bug 40527 has been marked as a duplicate of this bug. ***
Comment 13 Daniel Tröder univentionstaff 2017-10-17 08:57:46 CEST
OK: 90_ucsschool/23_password_reset
Rest was verified in #comment10.
Comment 14 Sönke Schwardt-Krummrich univentionstaff 2017-10-20 10:17:03 CEST
UCS@school 4.2 v4 has been released.


If this error occurs again, please clone this bug.