users: Set proper class on default password policy object

- Some trivial refactoring.

Tests:

- The default password policy works. Inactive users are unable to login via
console, SSH and cockpit.

- After the app is setup freshly and after it is upgraded from previous version,
the namedobject.schema has been ingested into the OpenLDAP configuration.

- Rerunning setup for users app works.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
Sunil Mohan Adapa 2024-09-22 08:57:54 -07:00
parent 67b6c0f9e8
commit 4b2e065304
No known key found for this signature in database
GPG Key ID: 43EA1CFF0AA7C5F2
2 changed files with 22 additions and 13 deletions

View File

@ -205,9 +205,17 @@ changetype: modify
add: olcModuleLoad
olcModuleLoad: ppolicy''')
except subprocess.CalledProcessError as error:
if error.returncode == 20: # Value already exists
pass
else:
if error.returncode != 20: # Value already exists
raise
# Add namedobject schema needed for 'objectClass: namedPolicy'.
try:
subprocess.run([
'ldapadd', '-Q', '-Y', 'EXTERNAL', '-H', 'ldapi:///', '-f',
'/etc/ldap/schema/namedobject.ldif'
], check=True, stdout=subprocess.DEVNULL)
except subprocess.CalledProcessError as error:
if error.returncode != 80: # Schema already added
raise
# Set up default password policy
@ -217,14 +225,12 @@ olcModuleLoad: ppolicy''')
dn: cn=DefaultPPolicy,ou=policies,dc=thisbox
cn: DefaultPPolicy
objectClass: pwdPolicy
objectClass: device
objectClass: namedPolicy
objectClass: top
pwdAttribute: userPassword
pwdLockout: TRUE''')
except subprocess.CalledProcessError as error:
if error.returncode == 68: # Value already exists
pass
else:
if error.returncode != 68: # Value already exists
raise
# Make DefaultPPolicy as a default ppolicy overlay
@ -288,12 +294,13 @@ def _unlock_ldap_user(username: str):
if not _get_user_ids(username):
# User not found
return None
# Replace command without providing a value will remove the attribute
# and ignores when the attribute doesn't exist.
input = '''changetype: modify
replace: pwdAccountLockedTime
'''
_run(["ldapmodifyuser", username], input=input.encode())
_run(['ldapmodifyuser', username], input=input.encode())
@privileged
@ -452,6 +459,7 @@ def _get_user_ids(username: str) -> str | None:
if error.returncode == 1:
# User doesn't exist
return None
raise
return process.stdout.decode().strip()
@ -614,7 +622,7 @@ def set_user_status(username: str, status: str, auth_user: str,
if status == 'inactive':
# Kill all user processes. This includes disconnectiong ssh, samba and
# cockpit sessions.
subprocess.run(['pkill', "--signal", "KILL", '--uid', username])
subprocess.run(['pkill', '--signal', 'KILL', '--uid', username])
def _upgrade_inactivate_users(usernames: list[str]):
@ -625,7 +633,7 @@ def _upgrade_inactivate_users(usernames: list[str]):
_flush_cache()
for username in usernames:
subprocess.run(['pkill', "--signal", "KILL", '--uid', username])
subprocess.run(['pkill', '--signal', 'KILL', '--uid', username])
def _flush_cache():

View File

@ -154,7 +154,7 @@ def test_user_states(session_browser, tmp_path_factory):
"""Test that admin users can set other users as inactive/active."""
username = 'bob2'
_non_admin_user_exists(session_browser, username,
groups=["freedombox-ssh"])
groups=['freedombox-ssh'])
_configure_ssh_keys(session_browser, tmp_path_factory, username=username)
# Test set user inactive
@ -343,10 +343,11 @@ def _set_ssh_keys(browser, ssh_keys, username=None):
def _set_user_status(browser, username, status):
functional.visit(browser, '/plinth/sys/users/{}/edit/'.format(username))
if status == "inactive":
if status == 'inactive':
browser.find_by_id('id_is_active').uncheck()
elif status == "active":
elif status == 'active':
browser.find_by_id('id_is_active').check()
browser.find_by_id('id_confirm_password').fill(_admin_password)
functional.submit(browser, form_class='form-update')