Bug 48880

Summary: Strange notification in UMC users/user after setting deactivation to a date in the past
Product: UCS Reporter: Arvid Requate <requate>
Component: UMC - UsersAssignee: UMC maintainers <umc-maintainers>
Status: NEW --- QA Contact: UMC maintainers <umc-maintainers>
Severity: normal    
Priority: P5 CC: best
Version: UCS 4.4   
Target Milestone: ---   
Hardware: Other   
OS: Linux   
See Also: https://forge.univention.org/bugzilla/show_bug.cgi?id=47199
https://forge.univention.org/bugzilla/show_bug.cgi?id=48861
https://forge.univention.org/bugzilla/show_bug.cgi?id=50202
https://forge.univention.org/bugzilla/show_bug.cgi?id=53631
What kind of report is it?: Development Internal 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):
Max CVSS v3 score:
Attachments: user6_deactivated:false.ldif

Description Arvid Requate univentionstaff 2019-03-06 15:02:39 CET
After setting deactivation to a date in the past in the UMC users/user module, a strange notification is shown every time I open the user object again.

========================================================================
Notification
The following empty properties were set to default values in the form. These values will be applied when saving.

    Account - Deactivation - Account is deactivated: false
========================================================================

Hitting save doesn't change anything.
Comment 1 Florian Best univentionstaff 2019-03-07 16:06:03 CET
This probably happens when you have an inconsistent disabled state, i.e. different things for kerberos, samba, posix.

If not, it would be a bug.
Can you attach the ldif of the user?
Comment 2 Arvid Requate univentionstaff 2019-03-08 14:23:06 CET
Created attachment 9908 [details]
user6_deactivated:false.ldif

> If not, it would be a bug.

Yeah, that's kind of the point of the communication here :-)

> Can you attach the ldif of the user?

See attached ldif. I just upened the user, Account section and used the date picker to set the "Account expiry date" to the 20th of February.

My VM was at this time:

root@master10:~# date
Do 28. Feb 09:25:40 CET 2019
Comment 3 Florian Best univentionstaff 2019-03-08 14:42:42 CET
Okay, you have:
shadowExpire: 17947

Which is the timestamp: 17947 * 3600 * 24 = 1550620800 = Wednesday, February 20, 2019 12:00:00 AM

def unmapPosixDisabled(oldattr):
    try:
        shadowExpire = int(oldattr['shadowExpire'][0])
    except (KeyError, ValueError):
        return False
    return shadowExpire == 1 or shadowExpire < int(time.time() / 3600 / 24)

Looks like "<" should be ">" ?!
Comment 4 Florian Best univentionstaff 2019-03-08 15:20:14 CET
(In reply to Florian Best from comment #3)
> Looks like "<" should be ">" ?!
Uhm, no. shadowExpire specifies the date since when the account is deactivated.
So setting a expiration date in the past should also set:
sambaAcctFlags = D
krb5KDCFlags |= 1<<7
userPassword = !userPassword
Comment 5 Florian Best univentionstaff 2019-03-08 15:40:09 CET
If you agree, here is a sketch for a patch:

diff --git a/management/univention-directory-manager-modules/modules/univention/admin/handlers/users/user.py b/management/univention-directory-manager-modules/modules/univention/admin/handlers/users/user.py
index 14f4c3ff7a..7cf25eca93 100644
--- a/management/univention-directory-manager-modules/modules/univention/admin/handlers/users/user.py
+++ b/management/univention-directory-manager-modules/modules/univention/admin/handlers/users/user.py
@@ -1905,6 +1905,15 @@ def _ldap_pre_ready(self):
         if self['disabled'] == '1':
             self['locked'] = '0'  # Samba/AD behavior

+        if self.hasChanged('userexpiry'):
+            if self['userexpiry']:
+                if not self.userexpiry_in_future(self['userexpiry']):  # past or today
+                    self['disabled'] = '1'
+                else:
+                    self['disabled'] = '0'
+            elif self['disabled'] == '1':
+                pass  # TODO: should we do something here?
+

And we should/could migrate broken users via a migration script?