389-ds-base/SOURCES/0015-Issue-6446-on-replica-consumer-account-policy-plugin.patch

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