sysaccount: make sure nsaccountlock is always present

Commands sysaccount-enable/sysaccount-disable allow to lock/unlock the
account.  This is exposed via operational attribute `nsAccountLock`
which has to be explicitly requested to query the state. However, if
account wasn't explicitly disabled before, `nsAccountLock` will not be
returned by the LDAP server.

Ensure the nsaccountlock attribute is always retrieved, validated, and
normalized across sysaccount operations.

- Invoke validate_nsaccountlock in create and modify pre-callbacks to
  enforce valid values

- Invoke convert_nsaccountlock in create, modify, list, reset, and
  policy post-callbacks to normalize the nsaccountlock attribute and
  default to False in case it is absent.

Fixes: https://pagure.io/freeipa/issue/9842

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
This commit is contained in:
Alexander Bokovoy
2025-11-11 14:44:00 +01:00
committed by Florence Blanc-Renaud
parent bd8288476f
commit f2fc104f06
+9
View File
@@ -15,6 +15,7 @@ from .baseldap import (
LDAPSearch,
LDAPRetrieve,
LDAPQuery)
from .baseuser import validate_nsaccountlock, convert_nsaccountlock
from ipalib import _, ngettext
from ipalib import constants
from ipalib import output
@@ -285,6 +286,7 @@ class sysaccount_add(LDAPCreate):
error=_('Either --password or --random is required')
)
check_userpassword(entry_attrs, **options)
validate_nsaccountlock(entry_attrs)
return dn
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
@@ -296,6 +298,7 @@ class sysaccount_add(LDAPCreate):
except errors.NotGroupMember:
pass
self.add_message(SystemAccountUsage(uid=keys[0], dn=dn))
convert_nsaccountlock(entry_attrs)
return dn
@@ -353,12 +356,15 @@ class sysaccount_mod(LDAPUpdate):
if 'privileged' not in options:
self.allow_empty_update = False
validate_nsaccountlock(entry_attrs)
return dn
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
assert isinstance(dn, DN)
fill_randompassword(entry_attrs, **options)
entry_attrs['privileged'] = getattr(context, 'privileged')
convert_nsaccountlock(entry_attrs)
return dn
@@ -382,6 +388,7 @@ class sysaccount_find(LDAPSearch):
self.obj.get_password_attributes(ldap, entry_attrs.dn, entry_attrs)
self.obj.handle_reset(self, self,
ldap, entry_attrs.dn, entry_attrs, **options)
convert_nsaccountlock(entry_attrs)
return truncated
@@ -398,6 +405,7 @@ class sysaccount_show(LDAPRetrieve):
self.obj.get_password_attributes(ldap, dn, entry_attrs)
self.obj.handle_reset(self, self,
ldap, dn, entry_attrs, **options)
convert_nsaccountlock(entry_attrs)
return dn
@@ -413,6 +421,7 @@ class sysaccount_policy(LDAPRetrieve):
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
self.obj.handle_reset(self, self, ldap, dn, entry_attrs, **options)
convert_nsaccountlock(entry_attrs)
return dn