183 lines
7.0 KiB
Diff
183 lines
7.0 KiB
Diff
From fc1d1b8c5438f29c3408adca26423fc6226f47ff Mon Sep 17 00:00:00 2001
|
|
From: tbordaz <tbordaz@redhat.com>
|
|
Date: Thu, 12 Dec 2024 16:30:50 +0100
|
|
Subject: [PATCH] Issue 6446 - on replica consumer, account policy plugin fails
|
|
to manage the last login history (#6448)
|
|
|
|
Bug description:
|
|
An internal update needs the flag SLAPI_OP_FLAG_BYPASS_REFERRALS
|
|
on a RO consumer. Else the server does not select the backend
|
|
and returns LDAP_REFERRAL to the internal operation.
|
|
In acct_update_login_history the flag is missing.
|
|
|
|
Fix description:
|
|
Use the same flags in acct_update_login_history as it is
|
|
used in acct_record_login
|
|
|
|
fixes: #6446
|
|
|
|
Reviewed by: Mark Reynolds (Thanks!)
|
|
---
|
|
.../tests/suites/plugins/accpol_test.py | 123 +++++++++++++++++-
|
|
ldap/servers/plugins/acctpolicy/acct_plugin.c | 3 +-
|
|
2 files changed, 124 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/dirsrvtests/tests/suites/plugins/accpol_test.py b/dirsrvtests/tests/suites/plugins/accpol_test.py
|
|
index 964d98ee0..f5db8e461 100644
|
|
--- a/dirsrvtests/tests/suites/plugins/accpol_test.py
|
|
+++ b/dirsrvtests/tests/suites/plugins/accpol_test.py
|
|
@@ -10,7 +10,7 @@ import pytest
|
|
import subprocess
|
|
from lib389.tasks import *
|
|
from lib389.utils import *
|
|
-from lib389.topologies import topology_st
|
|
+from lib389.topologies import topology_st, topology_m1c1
|
|
from lib389.idm.user import (UserAccount, UserAccounts)
|
|
from lib389.plugins import (AccountPolicyPlugin, AccountPolicyConfig, AccountPolicyConfigs)
|
|
from lib389.cos import (CosTemplate, CosPointerDefinition)
|
|
@@ -1298,6 +1298,127 @@ def test_locact_modrdn(topology_st, accpol_local):
|
|
account_status(topology_st, suffix, subtree, userid, 1, 0, "Enabled")
|
|
del_users(topology_st, suffix, subtree, userid, nousrs)
|
|
|
|
+def test_acct_policy_consumer(topology_m1c1, request):
|
|
+ """Test the lastLoginHistory is updated on consumer without
|
|
+ referral error
|
|
+
|
|
+ :id: 53a9a2c7-6b10-41c9-b9f9-bde412d04acb
|
|
+ :setup: Supplier Instance, Consumer Instance
|
|
+ :steps:
|
|
+ 1. Create a test entry on the supplier
|
|
+ 2. Configure lastLoginTime on supplier and consumer
|
|
+ 3. On supplier 3 binds of the test entry
|
|
+ 4. On supplier check there is 3 lastLoginHistory values
|
|
+ 5. On supplier check there is no error in error logs
|
|
+ 6. On consumer 3 binds of the test entry
|
|
+ 7. On consumer check there is 3 lastLoginHistory values
|
|
+ 8. On consumer check there is no error in error logs
|
|
+ :expectedresults:
|
|
+ 1. Success
|
|
+ 2. Success
|
|
+ 3. Success
|
|
+ 4. Success
|
|
+ 5. Success
|
|
+ 6. Success
|
|
+ 7. Success
|
|
+ 8. Success
|
|
+ """
|
|
+
|
|
+ supplier = topology_m1c1.ms['supplier1']
|
|
+ consumer = topology_m1c1.cs['consumer1']
|
|
+ USER_PW = 'password'
|
|
+
|
|
+ # Add on the supplier a test user entry and wait it is on the consumer
|
|
+ users_supplier = UserAccounts(supplier, DEFAULT_SUFFIX, rdn=None)
|
|
+ user_supplier = users_supplier.create_test_user(uid=1000, gid=2000)
|
|
+ user_supplier.replace('userPassword', USER_PW)
|
|
+
|
|
+ users_consumer = UserAccounts(consumer, DEFAULT_SUFFIX, rdn=None)
|
|
+ for i in range(0, 10):
|
|
+ try:
|
|
+ user_consumer = users_consumer.get("test_user_1000")
|
|
+ break
|
|
+ except ldap.NO_SUCH_OBJECT:
|
|
+ time.sleep(1)
|
|
+
|
|
+ # Configure lastLoginTime on supplier and consumer
|
|
+ plugin = AccountPolicyPlugin(supplier)
|
|
+ plugin.enable()
|
|
+ ACCPOL_DN = "cn={},{}".format(PLUGIN_ACCT_POLICY, DN_PLUGIN)
|
|
+ ACCP_CONF = "{},{}".format(DN_CONFIG, ACCPOL_DN)
|
|
+ plugin.set('nsslapd-pluginarg0', ACCP_CONF)
|
|
+ accp = AccountPolicyConfig(supplier, dn=ACCP_CONF)
|
|
+ accp.set('alwaysrecordlogin', 'yes')
|
|
+ accp.set('stateattrname', 'lastLoginTime')
|
|
+ supplier.restart(timeout=10)
|
|
+
|
|
+ plugin = AccountPolicyPlugin(consumer)
|
|
+ plugin.enable()
|
|
+ ACCPOL_DN = "cn={},{}".format(PLUGIN_ACCT_POLICY, DN_PLUGIN)
|
|
+ ACCP_CONF = "{},{}".format(DN_CONFIG, ACCPOL_DN)
|
|
+ plugin.set('nsslapd-pluginarg0', ACCP_CONF)
|
|
+ accp = AccountPolicyConfig(consumer, dn=ACCP_CONF)
|
|
+ accp.set('alwaysrecordlogin', 'yes')
|
|
+ accp.set('stateattrname', 'lastLoginTime')
|
|
+ consumer.restart(timeout=10)
|
|
+
|
|
+ # On supplier
|
|
+ # Do 3 binds with a delay to
|
|
+ # allow several values lastLoginHistory
|
|
+ user_supplier.bind(USER_PW)
|
|
+ time.sleep(2)
|
|
+ user_supplier = users_supplier.get("test_user_1000")
|
|
+ user_supplier.bind(USER_PW)
|
|
+ time.sleep(2)
|
|
+ user_supplier = users_supplier.get("test_user_1000")
|
|
+ user_supplier.bind(USER_PW)
|
|
+
|
|
+ # Verify there is no referral error
|
|
+ results = supplier.ds_error_log.match('.*.acct_update_login_history - Modify error 10 on entry*')
|
|
+ assert not results
|
|
+
|
|
+ # Verify that we got 3 values for lastLoginHistory
|
|
+ assert len(user_supplier.get_attr_vals_utf8_l('lastLoginHistory')) == 3
|
|
+
|
|
+ # On Consumer
|
|
+ # Do 3 binds with a delay to
|
|
+ # allow several values lastLoginHistory
|
|
+ user_supplier.bind(USER_PW)
|
|
+ user_consumer.bind(USER_PW)
|
|
+ time.sleep(2)
|
|
+ user_consumer = users_supplier.get("test_user_1000")
|
|
+ user_consumer.bind(USER_PW)
|
|
+ time.sleep(2)
|
|
+ user_consumer = users_supplier.get("test_user_1000")
|
|
+ user_consumer.bind(USER_PW)
|
|
+
|
|
+ # Verify there is no referral error
|
|
+ results = consumer.ds_error_log.match('.*.acct_update_login_history - Modify error 10 on entry*')
|
|
+ assert not results
|
|
+
|
|
+ # Verify that we got at least 3 values for lastLoginHistory
|
|
+ assert len(user_consumer.get_attr_vals_utf8_l('lastLoginHistory')) >= 3
|
|
+
|
|
+
|
|
+ def fin():
|
|
+ user_supplier.delete()
|
|
+ log.info('Disabling Global accpolicy plugin and removing pwpolicy attrs')
|
|
+ try:
|
|
+ plugin = AccountPolicyPlugin(supplier)
|
|
+ plugin.disable()
|
|
+ except ldap.LDAPError as e:
|
|
+ log.error('Failed to disable Global accpolicy plugin, {}'.format(e.message['desc']))
|
|
+ assert False
|
|
+ supplier.restart(timeout=10)
|
|
+ try:
|
|
+ plugin = AccountPolicyPlugin(consumer)
|
|
+ plugin.disable()
|
|
+ except ldap.LDAPError as e:
|
|
+ log.error('Failed to disable Global accpolicy plugin, {}'.format(e.message['desc']))
|
|
+ assert False
|
|
+ consumer.restart(timeout=10)
|
|
+
|
|
+ request.addfinalizer(fin)
|
|
|
|
if __name__ == '__main__':
|
|
# Run isolated
|
|
diff --git a/ldap/servers/plugins/acctpolicy/acct_plugin.c b/ldap/servers/plugins/acctpolicy/acct_plugin.c
|
|
index 220d0f6b2..af566b934 100644
|
|
--- a/ldap/servers/plugins/acctpolicy/acct_plugin.c
|
|
+++ b/ldap/servers/plugins/acctpolicy/acct_plugin.c
|
|
@@ -290,7 +290,8 @@ acct_update_login_history(const char *dn, char *timestr)
|
|
list_of_mods[1] = NULL;
|
|
|
|
mod_pb = slapi_pblock_new();
|
|
- slapi_modify_internal_set_pb(mod_pb, dn, list_of_mods, NULL, NULL, plugin_id, 0);
|
|
+ slapi_modify_internal_set_pb(mod_pb, dn, list_of_mods, NULL, NULL, plugin_id,
|
|
+ SLAPI_OP_FLAG_NO_ACCESS_CHECK |SLAPI_OP_FLAG_BYPASS_REFERRALS);
|
|
slapi_modify_internal_pb(mod_pb);
|
|
slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
|
|
if (rc != LDAP_SUCCESS) {
|
|
--
|
|
2.48.1
|
|
|