mirror of
https://git.centos.org/rpms/389-ds-base.git
synced 2025-02-23 16:22:54 +00:00
import 389-ds-base-1.3.6.1-21.el7_4
This commit is contained in:
parent
1c155e2849
commit
6405dba47e
12 changed files with 2829 additions and 6 deletions
1041
SOURCES/0062-Ticket-49330-Improve-ndn-cache-performance-1.3.6.patch
Normal file
1041
SOURCES/0062-Ticket-49330-Improve-ndn-cache-performance-1.3.6.patch
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,25 @@
|
|||
From c9817ebe42a97ac7df155582957927b4d1d08c5f Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 18 Sep 2017 14:55:14 -0400
|
||||
Subject: [PATCH] Ticket 49330 - Add endian header file
|
||||
|
||||
---
|
||||
configure.ac | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 67217af..163db7d 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -39,7 +39,7 @@ AC_PROG_LIBTOOL
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_SYS_WAIT
|
||||
-AC_CHECK_HEADERS([arpa/inet.h errno.h fcntl.h malloc.h netdb.h netinet/in.h stdlib.h string.h strings.h sys/file.h sys/socket.h sys/time.h syslog.h unistd.h inttypes.h mntent.h sys/sysinfo.h])
|
||||
+AC_CHECK_HEADERS([arpa/inet.h errno.h fcntl.h malloc.h netdb.h netinet/in.h stdlib.h string.h strings.h sys/file.h sys/socket.h sys/time.h syslog.h unistd.h mntent.h sys/sysinfo.h sys/endian.h endian.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_HEADER_STAT
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
From bbe3403a88f9adecbd5d4187ceeb080fb51d9d14 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 31 May 2017 11:15:13 -0400
|
||||
Subject: [PATCH] Ticket 49257 - only register modify callbacks
|
||||
|
||||
Bug Description: Regression. In the previous fix we called
|
||||
ldbm_instance_config_load_dse_info() to register all
|
||||
the dse preop callbacks. Previously this was only done
|
||||
when creating an instance. It was not designed to be
|
||||
used outside of that context, and it caused error 53's
|
||||
when trying to add a backend after instance creation.
|
||||
|
||||
Fix Description: Just register the "modify" DSE preop callbacks.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49257
|
||||
|
||||
Reviewed by: ?
|
||||
|
||||
(cherry picked from commit 75a32a8829297a5cab303590d049f581740cf87e)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/instance.c | 12 +++---------
|
||||
ldap/servers/slapd/back-ldbm/ldbm_config.h | 2 +-
|
||||
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 13 +++++++++++++
|
||||
3 files changed, 17 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/instance.c b/ldap/servers/slapd/back-ldbm/instance.c
|
||||
index 8b38644..f067d22 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/instance.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/instance.c
|
||||
@@ -305,15 +305,9 @@ ldbm_instance_startall(struct ldbminfo *li)
|
||||
if (rc1 != 0) {
|
||||
rc = rc1;
|
||||
} else {
|
||||
- if(ldbm_instance_config_load_dse_info(inst) != 0){
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_startall",
|
||||
- "Loading database instance configuration failed for (%s)\n",
|
||||
- inst->inst_name);
|
||||
- rc = -1;
|
||||
- } else {
|
||||
- vlv_init(inst);
|
||||
- slapi_mtn_be_started(inst->inst_be);
|
||||
- }
|
||||
+ ldbm_instance_register_modify_callback(inst);
|
||||
+ vlv_init(inst);
|
||||
+ slapi_mtn_be_started(inst->inst_be);
|
||||
}
|
||||
inst_obj = objset_next_obj(li->li_instance_set, inst_obj);
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.h b/ldap/servers/slapd/back-ldbm/ldbm_config.h
|
||||
index ddec3a8..ea59739 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.h
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.h
|
||||
@@ -157,6 +157,6 @@ int
|
||||
ldbm_instance_index_config_enable_index(ldbm_instance *inst, Slapi_Entry* e);
|
||||
int ldbm_instance_create_default_user_indexes(ldbm_instance *inst);
|
||||
void ldbm_config_destroy(struct ldbminfo *li);
|
||||
-
|
||||
+void ldbm_instance_register_modify_callback(ldbm_instance *inst);
|
||||
|
||||
#endif /* _LDBM_CONFIG_H_ */
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
index 49a6cac..8fb4119 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
@@ -554,6 +554,19 @@ static int ldbm_instance_deny_config(Slapi_PBlock *pb, Slapi_Entry *e,
|
||||
return SLAPI_DSE_CALLBACK_ERROR;
|
||||
}
|
||||
|
||||
+void
|
||||
+ldbm_instance_register_modify_callback(ldbm_instance *inst)
|
||||
+{
|
||||
+ struct ldbminfo *li = inst->inst_li;
|
||||
+ char *dn = NULL;
|
||||
+
|
||||
+ dn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
|
||||
+ inst->inst_name, li->li_plugin->plg_name);
|
||||
+ slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
|
||||
+ LDAP_SCOPE_BASE, "(objectclass=*)",
|
||||
+ ldbm_instance_modify_config_entry_callback, (void *) inst);
|
||||
+ slapi_ch_free_string(&dn);
|
||||
+}
|
||||
/* Reads in any config information held in the dse for the given
|
||||
* entry. Creates dse entries used to configure the given instance
|
||||
* if they don't already exist. Registers dse callback functions to
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
From 28529671057c95327a35c326ee99fcafccad9de9 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Wed, 14 Jun 2017 18:36:55 +0200
|
||||
Subject: [PATCH] Ticket 49291 - slapi_search_internal_callback_pb may SIGSEV
|
||||
if related pblock has not operation set
|
||||
|
||||
Bug Description:
|
||||
if slapi_search_internal_set_pb is called with an invalid (NULL) base, the pblock should not
|
||||
be used to call send_ldap_result. If it is, the send_ldap_result trying to derefence the
|
||||
operation pointer will crash
|
||||
|
||||
Fix Description:
|
||||
Check that the operation is set before derefencing it
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49291
|
||||
|
||||
Reviewed by: Mark Reynolds
|
||||
|
||||
Platforms tested: F23
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
ldap/servers/slapd/result.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
|
||||
index 56257c3..f3016ca 100644
|
||||
--- a/ldap/servers/slapd/result.c
|
||||
+++ b/ldap/servers/slapd/result.c
|
||||
@@ -350,6 +350,11 @@ send_ldap_result_ext(
|
||||
slapi_pblock_get (pb, SLAPI_BIND_METHOD, &bind_method);
|
||||
slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
|
||||
|
||||
+ if (operation == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "send_ldap_result_ext", "No operation found: slapi_search_internal_set_pb was incomplete (invalid 'base' ?)\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (operation->o_status == SLAPI_OP_STATUS_RESULT_SENT) {
|
||||
return; /* result already sent */
|
||||
}
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
From 1ec56936d29985a55f9529c1ea3e71056557b3ff Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 1 Sep 2017 09:24:55 -0400
|
||||
Subject: [PATCH] Ticket 49370 - local password policies should use the same
|
||||
defaults as the global policy
|
||||
|
||||
Description: When a local password policy (subtree/user) is created it does not use
|
||||
the same defaults as the global policy. This causes inconsistent behavior.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49370
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
---
|
||||
ldap/servers/slapd/pw.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
|
||||
index 378d148..19a863a 100644
|
||||
--- a/ldap/servers/slapd/pw.c
|
||||
+++ b/ldap/servers/slapd/pw.c
|
||||
@@ -1768,6 +1768,27 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn)
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ /* Set the default values */
|
||||
+ pwdpolicy->pw_mintokenlength = SLAPD_DEFAULT_PW_MINTOKENLENGTH;
|
||||
+ pwdpolicy->pw_minlength = SLAPD_DEFAULT_PW_MINLENGTH;
|
||||
+ pwdpolicy->pw_mindigits = SLAPD_DEFAULT_PW_MINDIGITS;
|
||||
+ pwdpolicy->pw_minalphas = SLAPD_DEFAULT_PW_MINALPHAS;
|
||||
+ pwdpolicy->pw_minuppers = SLAPD_DEFAULT_PW_MINUPPERS;
|
||||
+ pwdpolicy->pw_minlowers = SLAPD_DEFAULT_PW_MINLOWERS;
|
||||
+ pwdpolicy->pw_minspecials = SLAPD_DEFAULT_PW_MINSPECIALS;
|
||||
+ pwdpolicy->pw_min8bit = SLAPD_DEFAULT_PW_MIN8BIT;
|
||||
+ pwdpolicy->pw_maxrepeats = SLAPD_DEFAULT_PW_MAXREPEATS;
|
||||
+ pwdpolicy->pw_mincategories = SLAPD_DEFAULT_PW_MINCATEGORIES;
|
||||
+ pwdpolicy->pw_mintokenlength = SLAPD_DEFAULT_PW_MINTOKENLENGTH;
|
||||
+ pwdpolicy->pw_maxage = SLAPD_DEFAULT_PW_MAXAGE;
|
||||
+ pwdpolicy->pw_minage = SLAPD_DEFAULT_PW_MINAGE;
|
||||
+ pwdpolicy->pw_warning = SLAPD_DEFAULT_PW_WARNING;
|
||||
+ pwdpolicy->pw_inhistory = SLAPD_DEFAULT_PW_INHISTORY;
|
||||
+ pwdpolicy->pw_maxfailure = SLAPD_DEFAULT_PW_MAXFAILURE;
|
||||
+ pwdpolicy->pw_lockduration = SLAPD_DEFAULT_PW_LOCKDURATION;
|
||||
+ pwdpolicy->pw_resetfailurecount = SLAPD_DEFAULT_PW_RESETFAILURECOUNT;
|
||||
+ pwdpolicy->pw_gracelimit = SLAPD_DEFAULT_PW_GRACELIMIT;
|
||||
+
|
||||
/* set the default passwordLegacyPolicy setting */
|
||||
pwdpolicy->pw_is_legacy = 1;
|
||||
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
From af59afa03296160577e419257772d5319796a992 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 14 Sep 2017 08:32:11 -0400
|
||||
Subject: [PATCH] Ticket 49380 - Crash when adding invalid replication
|
||||
agreement
|
||||
|
||||
Bug Description: If you add a replication agreement with an invalid "replicaEnabled" value
|
||||
the server crashes when freeing the replica schedule. This is because the
|
||||
schedule never gets allocated before the rror conidtion is hit, and then
|
||||
it get dereferenced.
|
||||
|
||||
Fix Description: Check for a NULL schedule before trying to destroy it.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49380
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5_schedule.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_schedule.c b/ldap/servers/plugins/replication/repl5_schedule.c
|
||||
index 60ee6f2..4572e63 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_schedule.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_schedule.c
|
||||
@@ -130,6 +130,10 @@ schedule_destroy(Schedule *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
+ if (s == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/* unschedule update window event if exists */
|
||||
unschedule_window_state_change_event (s);
|
||||
|
||||
@@ -177,11 +181,15 @@ free_schedule_list(schedule_item **schedule_list)
|
||||
int
|
||||
schedule_set(Schedule *sch, Slapi_Attr *attr)
|
||||
{
|
||||
- int return_value;
|
||||
+ int return_value = -1;
|
||||
schedule_item *si = NULL;
|
||||
schedule_item *new_schedule_list = NULL;
|
||||
int valid = 1;
|
||||
|
||||
+ if (sch == NULL) {
|
||||
+ return return_value;
|
||||
+ }
|
||||
+
|
||||
if (NULL != attr)
|
||||
{
|
||||
int ind;
|
||||
--
|
||||
2.9.5
|
||||
|
81
SOURCES/0068-Ticket-49380-Add-CI-test.patch
Normal file
81
SOURCES/0068-Ticket-49380-Add-CI-test.patch
Normal file
|
@ -0,0 +1,81 @@
|
|||
From d336e3558655d44f8ba797392af882e33d492958 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 14 Sep 2017 14:15:25 -0400
|
||||
Subject: [PATCH] Ticket 49380 - Add CI test
|
||||
|
||||
Description: Add test to verify invalid agreement is rejected, and it
|
||||
does not cause a crash
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49380
|
||||
|
||||
Reviewed by: spichugi(Thanks!)
|
||||
|
||||
(cherry picked from commit 02d76b61489f105f81d72d4f3848e2444463289b)
|
||||
---
|
||||
.../tests/suites/replication/acceptance_test.py | 43 ++++++++++++++++++++++
|
||||
1 file changed, 43 insertions(+)
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/replication/acceptance_test.py b/dirsrvtests/tests/suites/replication/acceptance_test.py
|
||||
index e6f2ef7..2f8b180 100644
|
||||
--- a/dirsrvtests/tests/suites/replication/acceptance_test.py
|
||||
+++ b/dirsrvtests/tests/suites/replication/acceptance_test.py
|
||||
@@ -3,6 +3,12 @@ from lib389.tasks import *
|
||||
from lib389.utils import *
|
||||
from lib389.topologies import topology_m4 as topo
|
||||
|
||||
+from lib389._constants import (BACKEND_NAME, DEFAULT_SUFFIX, LOG_REPLICA, REPLICA_RUV_FILTER,
|
||||
+ ReplicaRole, REPLICATION_BIND_DN, REPLICATION_BIND_PW,
|
||||
+ REPLICATION_BIND_METHOD, REPLICATION_TRANSPORT, defaultProperties,
|
||||
+ RA_NAME, RA_BINDDN, RA_BINDPW, RA_METHOD, RA_TRANSPORT_PROT,
|
||||
+ DN_DM, PASSWORD, LOG_DEFAULT, RA_ENABLED, RA_SCHEDULE)
|
||||
+
|
||||
TEST_ENTRY_NAME = 'mmrepl_test'
|
||||
TEST_ENTRY_DN = 'uid={},{}'.format(TEST_ENTRY_NAME, DEFAULT_SUFFIX)
|
||||
|
||||
@@ -193,6 +199,43 @@ def test_modrdn_entry(topo, test_entry, delold):
|
||||
topo.ms["master1"].delete_s(newrdn_dn)
|
||||
|
||||
|
||||
+def test_invalid_agmt(topo_m4):
|
||||
+ """Test adding that an invalid agreement is properly rejected and does not crash the server
|
||||
+
|
||||
+ :id: 6c3b2a7e-edcd-4327-a003-6bd878ff722b
|
||||
+ :setup: MMR with four masters
|
||||
+ :steps:
|
||||
+ 1. Add invalid agreement (nsds5ReplicaEnabled set to invalid value)
|
||||
+ 2. Verify the server is still running
|
||||
+ :expectedresults:
|
||||
+ 1. Invalid repl agreement should be rejected
|
||||
+ 2. Server should be still running
|
||||
+ """
|
||||
+ m1 = topo_m4.ms["master1"]
|
||||
+
|
||||
+ # Add invalid agreement (nsds5ReplicaEnabled set to invalid value)
|
||||
+ AGMT_DN = 'cn=whatever,cn=replica,cn="dc=example,dc=com",cn=mapping tree,cn=config'
|
||||
+ try:
|
||||
+ invalid_props = {RA_ENABLED: 'True', # Invalid value
|
||||
+ RA_SCHEDULE: '0001-2359 0123456'}
|
||||
+ m1.agreement.create(suffix=DEFAULT_SUFFIX, host='localhost', port=389, properties=invalid_props)
|
||||
+ except ldap.UNWILLING_TO_PERFORM:
|
||||
+ m1.log.info('Invalid repl agreement correctly rejected')
|
||||
+ except ldap.LDAPError as e:
|
||||
+ m1.log.fatal('Got unexpected error adding invalid agreement: ' + str(e))
|
||||
+ assert False
|
||||
+ else:
|
||||
+ m1.log.fatal('Invalid agreement was incorrectly accepted by the server')
|
||||
+ assert False
|
||||
+
|
||||
+ # Verify the server is still running
|
||||
+ try:
|
||||
+ m1.simple_bind_s(DN_DM, PASSWORD)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ m1.log.fatal('Failed to bind: ' + str(e))
|
||||
+ assert False
|
||||
+
|
||||
+
|
||||
if __name__ == '__main__':
|
||||
# Run isolated
|
||||
# -s for DEBUG mode
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,610 @@
|
|||
From 3ab8a78cd27cc8d2ad7a2b322a4fe73c43a3db08 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 14 Sep 2017 15:47:53 -0400
|
||||
Subject: [PATCH] Ticket 49327 - password expired control not sent during grace
|
||||
logins
|
||||
|
||||
Bug Description: When a password is expired, but within the grace login limit,
|
||||
we should still send the expired control even though we allowed
|
||||
the bind.
|
||||
|
||||
Fix Description: new_new_passwd() returned a variety of result codes that required
|
||||
the caller to set the response controls. This was hard to read and
|
||||
process. Instead I added all the controls inside the function, and
|
||||
return success or failure to the caller.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49327
|
||||
|
||||
Reviewed by: gparente & tbordaz (Thanks!!)
|
||||
|
||||
(cherry picked from commit fbd32c4e27af9f331ee3a42dec944895a6efe2ad)
|
||||
---
|
||||
ldap/servers/plugins/replication/repl_extop.c | 5 +-
|
||||
ldap/servers/slapd/bind.c | 18 +-
|
||||
ldap/servers/slapd/proto-slap.h | 3 +-
|
||||
ldap/servers/slapd/pw_mgmt.c | 453 +++++++++++++-------------
|
||||
ldap/servers/slapd/saslbind.c | 20 +-
|
||||
5 files changed, 238 insertions(+), 261 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
|
||||
index a39d918..96ad7dd 100644
|
||||
--- a/ldap/servers/plugins/replication/repl_extop.c
|
||||
+++ b/ldap/servers/plugins/replication/repl_extop.c
|
||||
@@ -1173,8 +1173,9 @@ send_response:
|
||||
* On the supplier, we need to close the connection so
|
||||
* that the RA will restart a new session in a clear state
|
||||
*/
|
||||
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_extop_StartNSDS50ReplicationRequest - "
|
||||
- "already acquired replica: disconnect conn=%d\n", connid);
|
||||
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
|
||||
+ "multimaster_extop_StartNSDS50ReplicationRequest - "
|
||||
+ "already acquired replica: disconnect conn=%" PRIu64 "\n", connid);
|
||||
slapi_disconnect_server(conn);
|
||||
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
|
||||
index d6c7668..e6cad7f 100644
|
||||
--- a/ldap/servers/slapd/bind.c
|
||||
+++ b/ldap/servers/slapd/bind.c
|
||||
@@ -673,8 +673,7 @@ do_bind( Slapi_PBlock *pb )
|
||||
slapi_entry_free(referral);
|
||||
goto free_and_return;
|
||||
} else if (auto_bind || rc == SLAPI_BIND_SUCCESS || rc == SLAPI_BIND_ANONYMOUS) {
|
||||
- long t;
|
||||
- char* authtype = NULL;
|
||||
+ char *authtype = NULL;
|
||||
/* rc is SLAPI_BIND_SUCCESS or SLAPI_BIND_ANONYMOUS */
|
||||
if(auto_bind) {
|
||||
rc = SLAPI_BIND_SUCCESS;
|
||||
@@ -761,19 +760,8 @@ do_bind( Slapi_PBlock *pb )
|
||||
slapi_ch_strdup(slapi_sdn_get_ndn(sdn)),
|
||||
NULL, NULL, NULL, bind_target_entry);
|
||||
if (!slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) {
|
||||
- /* check if need new password before sending
|
||||
- the bind success result */
|
||||
- myrc = need_new_pw(pb, &t, bind_target_entry, pw_response_requested);
|
||||
- switch (myrc) {
|
||||
- case 1:
|
||||
- (void)slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- break;
|
||||
- case 2:
|
||||
- (void)slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t);
|
||||
- break;
|
||||
- default:
|
||||
- break;
|
||||
- }
|
||||
+ /* check if need new password before sending the bind success result */
|
||||
+ myrc = need_new_pw(pb, bind_target_entry, pw_response_requested);
|
||||
}
|
||||
}
|
||||
if (auth_response_requested) {
|
||||
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
||||
index 9696ead..0ba61d7 100644
|
||||
--- a/ldap/servers/slapd/proto-slap.h
|
||||
+++ b/ldap/servers/slapd/proto-slap.h
|
||||
@@ -972,7 +972,7 @@ int plugin_call_acl_verify_syntax ( Slapi_PBlock *pb, Slapi_Entry *e, char **err
|
||||
* pw_mgmt.c
|
||||
*/
|
||||
void pw_init( void );
|
||||
-int need_new_pw( Slapi_PBlock *pb, long *t, Slapi_Entry *e, int pwresponse_req );
|
||||
+int need_new_pw(Slapi_PBlock *pb, Slapi_Entry *e, int pwresponse_req);
|
||||
int update_pw_info( Slapi_PBlock *pb , char *old_pw );
|
||||
int check_pw_syntax( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals,
|
||||
char **old_pw, Slapi_Entry *e, int mod_op );
|
||||
@@ -982,7 +982,6 @@ void get_old_pw( Slapi_PBlock *pb, const Slapi_DN *sdn, char **old_pw);
|
||||
int check_account_lock( Slapi_PBlock *pb, Slapi_Entry * bind_target_entry, int pwresponse_req, int account_inactivation_only /*no wire/no pw policy*/);
|
||||
int check_pw_minage( Slapi_PBlock *pb, const Slapi_DN *sdn, struct berval **vals) ;
|
||||
void add_password_attrs( Slapi_PBlock *pb, Operation *op, Slapi_Entry *e );
|
||||
-
|
||||
int add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry **e);
|
||||
|
||||
/*
|
||||
diff --git a/ldap/servers/slapd/pw_mgmt.c b/ldap/servers/slapd/pw_mgmt.c
|
||||
index 7252c08..b06e3f1 100644
|
||||
--- a/ldap/servers/slapd/pw_mgmt.c
|
||||
+++ b/ldap/servers/slapd/pw_mgmt.c
|
||||
@@ -22,234 +22,239 @@
|
||||
/* prototypes */
|
||||
/****************************************************************************/
|
||||
|
||||
-/* need_new_pw() is called when non rootdn bind operation succeeds with authentication */
|
||||
+/*
|
||||
+ * need_new_pw() is called when non rootdn bind operation succeeds with authentication
|
||||
+ *
|
||||
+ * Return 0 - password is okay
|
||||
+ * Return -1 - password is expired, abort bind
|
||||
+ */
|
||||
int
|
||||
-need_new_pw( Slapi_PBlock *pb, long *t, Slapi_Entry *e, int pwresponse_req )
|
||||
+need_new_pw(Slapi_PBlock *pb, Slapi_Entry *e, int pwresponse_req)
|
||||
{
|
||||
- time_t cur_time, pw_exp_date;
|
||||
- Slapi_Mods smods;
|
||||
- double diff_t = 0;
|
||||
- char *cur_time_str = NULL;
|
||||
- char *passwordExpirationTime = NULL;
|
||||
- char *timestring;
|
||||
- char *dn;
|
||||
- const Slapi_DN *sdn;
|
||||
- passwdPolicy *pwpolicy = NULL;
|
||||
- int pwdGraceUserTime = 0;
|
||||
- char graceUserTime[8];
|
||||
-
|
||||
- if (NULL == e) {
|
||||
- return (-1);
|
||||
- }
|
||||
- slapi_mods_init (&smods, 0);
|
||||
- sdn = slapi_entry_get_sdn_const( e );
|
||||
- dn = slapi_entry_get_ndn( e );
|
||||
- pwpolicy = new_passwdPolicy(pb, dn);
|
||||
-
|
||||
- /* after the user binds with authentication, clear the retry count */
|
||||
- if ( pwpolicy->pw_lockout == 1)
|
||||
- {
|
||||
- if(slapi_entry_attr_get_int( e, "passwordRetryCount") > 0)
|
||||
- {
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordRetryCount", "0");
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- cur_time = current_time();
|
||||
-
|
||||
- /* get passwordExpirationTime attribute */
|
||||
- passwordExpirationTime= slapi_entry_attr_get_charptr(e, "passwordExpirationTime");
|
||||
-
|
||||
- if (passwordExpirationTime == NULL)
|
||||
- {
|
||||
- /* password expiration date is not set.
|
||||
- * This is ok for data that has been loaded via ldif2ldbm
|
||||
- * Set expiration time if needed,
|
||||
- * don't do further checking and return 0 */
|
||||
- if (pwpolicy->pw_exp == 1) {
|
||||
- pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_maxage);
|
||||
-
|
||||
- timestring = format_genTime (pw_exp_date);
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
||||
- slapi_ch_free_string(×tring);
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "0");
|
||||
-
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- } else if (pwpolicy->pw_lockout == 1) {
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- }
|
||||
- slapi_mods_done(&smods);
|
||||
- return ( 0 );
|
||||
- }
|
||||
-
|
||||
- pw_exp_date = parse_genTime(passwordExpirationTime);
|
||||
-
|
||||
- slapi_ch_free_string(&passwordExpirationTime);
|
||||
-
|
||||
- /* Check if password has been reset */
|
||||
- if ( pw_exp_date == NO_TIME ) {
|
||||
-
|
||||
- /* check if changing password is required */
|
||||
- if ( pwpolicy->pw_must_change ) {
|
||||
- /* set c_needpw for this connection to be true. this client
|
||||
- now can only change its own password */
|
||||
- pb->pb_conn->c_needpw = 1;
|
||||
- *t=0;
|
||||
- /* We need to include "changeafterreset" error in
|
||||
- * passwordpolicy response control. So, we will not be
|
||||
- * done here. We remember this scenario by (c_needpw=1)
|
||||
- * and check it before sending the control from various
|
||||
- * places. We will also add LDAP_CONTROL_PWEXPIRED control
|
||||
- * as the return value used to be (1).
|
||||
- */
|
||||
- goto skip;
|
||||
- }
|
||||
- /* Mark that first login occured */
|
||||
- pw_exp_date = NOT_FIRST_TIME;
|
||||
- timestring = format_genTime(pw_exp_date);
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
||||
- slapi_ch_free_string(×tring);
|
||||
- }
|
||||
+ time_t cur_time, pw_exp_date;
|
||||
+ Slapi_Mods smods;
|
||||
+ double diff_t = 0;
|
||||
+ char *cur_time_str = NULL;
|
||||
+ char *passwordExpirationTime = NULL;
|
||||
+ char *timestring;
|
||||
+ char *dn;
|
||||
+ const Slapi_DN *sdn;
|
||||
+ passwdPolicy *pwpolicy = NULL;
|
||||
+ int pwdGraceUserTime = 0;
|
||||
+ char graceUserTime[16] = {0};
|
||||
+ Connection *pb_conn = NULL;
|
||||
+ long t;
|
||||
+
|
||||
+ if (NULL == e) {
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ slapi_mods_init(&smods, 0);
|
||||
+ sdn = slapi_entry_get_sdn_const(e);
|
||||
+ dn = slapi_entry_get_ndn(e);
|
||||
+ pwpolicy = new_passwdPolicy(pb, dn);
|
||||
+
|
||||
+ /* after the user binds with authentication, clear the retry count */
|
||||
+ if (pwpolicy->pw_lockout == 1) {
|
||||
+ if (slapi_entry_attr_get_int(e, "passwordRetryCount") > 0) {
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordRetryCount", "0");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ cur_time = current_time();
|
||||
+
|
||||
+ /* get passwordExpirationTime attribute */
|
||||
+ passwordExpirationTime = slapi_entry_attr_get_charptr(e, "passwordExpirationTime");
|
||||
+
|
||||
+ if (passwordExpirationTime == NULL) {
|
||||
+ /* password expiration date is not set.
|
||||
+ * This is ok for data that has been loaded via ldif2ldbm
|
||||
+ * Set expiration time if needed,
|
||||
+ * don't do further checking and return 0 */
|
||||
+ if (pwpolicy->pw_exp == 1) {
|
||||
+ pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_maxage);
|
||||
+
|
||||
+ timestring = format_genTime(pw_exp_date);
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
||||
+ slapi_ch_free_string(×tring);
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "0");
|
||||
+
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ } else if (pwpolicy->pw_lockout == 1) {
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ }
|
||||
+ slapi_mods_done(&smods);
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ pw_exp_date = parse_genTime(passwordExpirationTime);
|
||||
+
|
||||
+ slapi_ch_free_string(&passwordExpirationTime);
|
||||
+
|
||||
+ slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
+
|
||||
+ /* Check if password has been reset */
|
||||
+ if (pw_exp_date == NO_TIME) {
|
||||
+
|
||||
+ /* check if changing password is required */
|
||||
+ if (pwpolicy->pw_must_change) {
|
||||
+ /* set c_needpw for this connection to be true. this client
|
||||
+ now can only change its own password */
|
||||
+ pb_conn->c_needpw = 1;
|
||||
+ t = 0;
|
||||
+ /* We need to include "changeafterreset" error in
|
||||
+ * passwordpolicy response control. So, we will not be
|
||||
+ * done here. We remember this scenario by (c_needpw=1)
|
||||
+ * and check it before sending the control from various
|
||||
+ * places. We will also add LDAP_CONTROL_PWEXPIRED control
|
||||
+ * as the return value used to be (1).
|
||||
+ */
|
||||
+ goto skip;
|
||||
+ }
|
||||
+ /* Mark that first login occured */
|
||||
+ pw_exp_date = NOT_FIRST_TIME;
|
||||
+ timestring = format_genTime(pw_exp_date);
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
||||
+ slapi_ch_free_string(×tring);
|
||||
+ }
|
||||
|
||||
skip:
|
||||
- /* if password never expires, don't need to go on; return 0 */
|
||||
- if ( pwpolicy->pw_exp == 0 ) {
|
||||
- /* check for "changeafterreset" condition */
|
||||
- if (pb->pb_conn->c_needpw == 1) {
|
||||
- if (pwresponse_req) {
|
||||
- slapi_pwpolicy_make_response_control ( pb, -1, -1, LDAP_PWPOLICY_CHGAFTERRESET );
|
||||
- }
|
||||
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- }
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- slapi_mods_done(&smods);
|
||||
- return ( 0 );
|
||||
- }
|
||||
-
|
||||
- /* check if password expired. If so, abort bind. */
|
||||
- cur_time_str = format_genTime ( cur_time );
|
||||
- if ((pw_exp_date != NO_TIME) && (pw_exp_date != NOT_FIRST_TIME) &&
|
||||
- (diff_t = difftime(pw_exp_date, parse_genTime(cur_time_str))) <= 0) {
|
||||
- slapi_ch_free_string(&cur_time_str); /* only need this above */
|
||||
- /* password has expired. Check the value of
|
||||
- * passwordGraceUserTime and compare it
|
||||
- * against the value of passwordGraceLimit */
|
||||
- pwdGraceUserTime = slapi_entry_attr_get_int( e, "passwordGraceUserTime");
|
||||
- if ( pwpolicy->pw_gracelimit > pwdGraceUserTime ) {
|
||||
- pwdGraceUserTime++;
|
||||
- sprintf ( graceUserTime, "%d", pwdGraceUserTime );
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE,
|
||||
- "passwordGraceUserTime", graceUserTime);
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- slapi_mods_done(&smods);
|
||||
- if (pwresponse_req) {
|
||||
- /* check for "changeafterreset" condition */
|
||||
- if (pb->pb_conn->c_needpw == 1) {
|
||||
- slapi_pwpolicy_make_response_control( pb, -1,
|
||||
- ((pwpolicy->pw_gracelimit) - pwdGraceUserTime),
|
||||
- LDAP_PWPOLICY_CHGAFTERRESET);
|
||||
- } else {
|
||||
- slapi_pwpolicy_make_response_control( pb, -1,
|
||||
- ((pwpolicy->pw_gracelimit) - pwdGraceUserTime),
|
||||
- -1);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (pb->pb_conn->c_needpw == 1) {
|
||||
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- }
|
||||
- return ( 0 );
|
||||
- }
|
||||
-
|
||||
- /* password expired and user exceeded limit of grace attemps.
|
||||
- * Send result and also the control */
|
||||
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- if (pwresponse_req) {
|
||||
- slapi_pwpolicy_make_response_control ( pb, -1, -1, LDAP_PWPOLICY_PWDEXPIRED );
|
||||
- }
|
||||
- slapi_send_ldap_result ( pb, LDAP_INVALID_CREDENTIALS, NULL,
|
||||
- "password expired!", 0, NULL );
|
||||
-
|
||||
- /* abort bind */
|
||||
- /* pass pb to do_unbind(). pb->pb_op->o_opid and
|
||||
- pb->pb_op->o_tag are not right but I don't see
|
||||
- do_unbind() checking for those. We might need to
|
||||
- create a pb for unbind operation. Also do_unbind calls
|
||||
- pre and post ops. Maybe we don't want to call them */
|
||||
- if (pb->pb_conn && (LDAP_VERSION2 == pb->pb_conn->c_ldapversion)) {
|
||||
- /* We close the connection only with LDAPv2 connections */
|
||||
- disconnect_server( pb->pb_conn, pb->pb_op->o_connid,
|
||||
- pb->pb_op->o_opid, SLAPD_DISCONNECT_UNBIND, 0);
|
||||
- }
|
||||
- /* Apply current modifications */
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- slapi_mods_done(&smods);
|
||||
- return (-1);
|
||||
- }
|
||||
- slapi_ch_free((void **) &cur_time_str );
|
||||
-
|
||||
- /* check if password is going to expire within "passwordWarning" */
|
||||
- /* Note that if pw_exp_date is NO_TIME or NOT_FIRST_TIME,
|
||||
- * we must send warning first and this changes the expiration time.
|
||||
- * This is done just below since diff_t is 0
|
||||
- */
|
||||
- if ( diff_t <= pwpolicy->pw_warning ) {
|
||||
- int pw_exp_warned = 0;
|
||||
-
|
||||
- pw_exp_warned = slapi_entry_attr_get_int( e, "passwordExpWarned");
|
||||
- if ( !pw_exp_warned ){
|
||||
- /* first time send out a warning */
|
||||
- /* reset the expiration time to current + warning time
|
||||
- * and set passwordExpWarned to true
|
||||
- */
|
||||
- if (pb->pb_conn->c_needpw != 1) {
|
||||
- pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_warning);
|
||||
- }
|
||||
-
|
||||
- timestring = format_genTime(pw_exp_date);
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
||||
- slapi_ch_free_string(×tring);
|
||||
-
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "1");
|
||||
-
|
||||
- *t = pwpolicy->pw_warning;
|
||||
-
|
||||
- } else {
|
||||
- *t = (long)diff_t; /* jcm: had to cast double to long */
|
||||
- }
|
||||
-
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- slapi_mods_done(&smods);
|
||||
- if (pwresponse_req) {
|
||||
- /* check for "changeafterreset" condition */
|
||||
- if (pb->pb_conn->c_needpw == 1) {
|
||||
- slapi_pwpolicy_make_response_control( pb, *t, -1,
|
||||
- LDAP_PWPOLICY_CHGAFTERRESET);
|
||||
- } else {
|
||||
- slapi_pwpolicy_make_response_control( pb, *t, -1,
|
||||
- -1);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (pb->pb_conn->c_needpw == 1) {
|
||||
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- }
|
||||
- return (2);
|
||||
- } else {
|
||||
- if (pwresponse_req && pwpolicy->pw_send_expiring) {
|
||||
- slapi_pwpolicy_make_response_control( pb, diff_t, -1, -1);
|
||||
- slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, diff_t);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- slapi_mods_done(&smods);
|
||||
- /* Leftover from "changeafterreset" condition */
|
||||
- if (pb->pb_conn->c_needpw == 1) {
|
||||
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- }
|
||||
- /* passes checking, return 0 */
|
||||
- return( 0 );
|
||||
+ /* if password never expires, don't need to go on; return 0 */
|
||||
+ if (pwpolicy->pw_exp == 0) {
|
||||
+ /* check for "changeafterreset" condition */
|
||||
+ if (pb_conn->c_needpw == 1) {
|
||||
+ if (pwresponse_req) {
|
||||
+ slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_CHGAFTERRESET);
|
||||
+ }
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
+ }
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ slapi_mods_done(&smods);
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ /* check if password expired. If so, abort bind. */
|
||||
+ cur_time_str = format_genTime(cur_time);
|
||||
+ if ((pw_exp_date != NO_TIME) && (pw_exp_date != NOT_FIRST_TIME) &&
|
||||
+ (diff_t = difftime(pw_exp_date, parse_genTime(cur_time_str))) <= 0) {
|
||||
+ slapi_ch_free_string(&cur_time_str); /* only need this above */
|
||||
+ /* password has expired. Check the value of
|
||||
+ * passwordGraceUserTime and compare it
|
||||
+ * against the value of passwordGraceLimit */
|
||||
+ pwdGraceUserTime = slapi_entry_attr_get_int(e, "passwordGraceUserTime");
|
||||
+ if (pwpolicy->pw_gracelimit > pwdGraceUserTime) {
|
||||
+ pwdGraceUserTime++;
|
||||
+ sprintf(graceUserTime, "%d", pwdGraceUserTime);
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE,
|
||||
+ "passwordGraceUserTime", graceUserTime);
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ slapi_mods_done(&smods);
|
||||
+ if (pwresponse_req) {
|
||||
+ /* check for "changeafterreset" condition */
|
||||
+ if (pb_conn->c_needpw == 1) {
|
||||
+ slapi_pwpolicy_make_response_control(pb, -1,
|
||||
+ ((pwpolicy->pw_gracelimit) - pwdGraceUserTime),
|
||||
+ LDAP_PWPOLICY_CHGAFTERRESET);
|
||||
+ } else {
|
||||
+ slapi_pwpolicy_make_response_control(pb, -1,
|
||||
+ ((pwpolicy->pw_gracelimit) - pwdGraceUserTime),
|
||||
+ -1);
|
||||
+ }
|
||||
+ }
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ /* password expired and user exceeded limit of grace attemps.
|
||||
+ * Send result and also the control */
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
+ if (pwresponse_req) {
|
||||
+ slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_PWDEXPIRED);
|
||||
+ }
|
||||
+ slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL,
|
||||
+ "password expired!", 0, NULL);
|
||||
+
|
||||
+ /* abort bind */
|
||||
+ /* pass pb to do_unbind(). pb->pb_op->o_opid and
|
||||
+ pb->pb_op->o_tag are not right but I don't see
|
||||
+ do_unbind() checking for those. We might need to
|
||||
+ create a pb for unbind operation. Also do_unbind calls
|
||||
+ pre and post ops. Maybe we don't want to call them */
|
||||
+ if (pb_conn && (LDAP_VERSION2 == pb_conn->c_ldapversion)) {
|
||||
+ Operation *pb_op = NULL;
|
||||
+ slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
||||
+ /* We close the connection only with LDAPv2 connections */
|
||||
+ disconnect_server(pb_conn, pb_op->o_connid,
|
||||
+ pb_op->o_opid, SLAPD_DISCONNECT_UNBIND, 0);
|
||||
+ }
|
||||
+ /* Apply current modifications */
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ slapi_mods_done(&smods);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ slapi_ch_free((void **)&cur_time_str);
|
||||
+
|
||||
+ /* check if password is going to expire within "passwordWarning" */
|
||||
+ /* Note that if pw_exp_date is NO_TIME or NOT_FIRST_TIME,
|
||||
+ * we must send warning first and this changes the expiration time.
|
||||
+ * This is done just below since diff_t is 0
|
||||
+ */
|
||||
+ if (diff_t <= pwpolicy->pw_warning) {
|
||||
+ int pw_exp_warned = 0;
|
||||
+
|
||||
+ pw_exp_warned = slapi_entry_attr_get_int(e, "passwordExpWarned");
|
||||
+ if (!pw_exp_warned) {
|
||||
+ /* first time send out a warning */
|
||||
+ /* reset the expiration time to current + warning time
|
||||
+ * and set passwordExpWarned to true
|
||||
+ */
|
||||
+ if (pb_conn->c_needpw != 1) {
|
||||
+ pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_warning);
|
||||
+ }
|
||||
+
|
||||
+ timestring = format_genTime(pw_exp_date);
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
||||
+ slapi_ch_free_string(×tring);
|
||||
+
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "1");
|
||||
+
|
||||
+ t = pwpolicy->pw_warning;
|
||||
+
|
||||
+ } else {
|
||||
+ t = (long)diff_t; /* jcm: had to cast double to long */
|
||||
+ }
|
||||
+
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ slapi_mods_done(&smods);
|
||||
+ if (pwresponse_req) {
|
||||
+ /* check for "changeafterreset" condition */
|
||||
+ if (pb_conn->c_needpw == 1) {
|
||||
+ slapi_pwpolicy_make_response_control(pb, t, -1, LDAP_PWPOLICY_CHGAFTERRESET);
|
||||
+ } else {
|
||||
+ slapi_pwpolicy_make_response_control(pb, t, -1, -1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (pb_conn->c_needpw == 1) {
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
+ } else {
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t);
|
||||
+ }
|
||||
+ return (0);
|
||||
+ } else {
|
||||
+ if (pwresponse_req && pwpolicy->pw_send_expiring) {
|
||||
+ slapi_pwpolicy_make_response_control(pb, diff_t, -1, -1);
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, diff_t);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ slapi_mods_done(&smods);
|
||||
+ /* Leftover from "changeafterreset" condition */
|
||||
+ if (pb_conn->c_needpw == 1) {
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
+ }
|
||||
+ /* passes checking, return 0 */
|
||||
+ return (0);
|
||||
}
|
||||
|
||||
/* Called once from main */
|
||||
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
||||
index dd0c4fb..134f5aa 100644
|
||||
--- a/ldap/servers/slapd/saslbind.c
|
||||
+++ b/ldap/servers/slapd/saslbind.c
|
||||
@@ -859,7 +859,6 @@ ids_sasl_mech_supported(Slapi_PBlock *pb, const char *mech)
|
||||
void ids_sasl_check_bind(Slapi_PBlock *pb)
|
||||
{
|
||||
int rc, isroot;
|
||||
- long t;
|
||||
sasl_conn_t *sasl_conn;
|
||||
struct propctx *propctx;
|
||||
sasl_ssf_t *ssfp;
|
||||
@@ -1096,23 +1095,8 @@ sasl_check_result:
|
||||
set_db_default_result_handlers(pb);
|
||||
|
||||
/* check password expiry */
|
||||
- if (!isroot) {
|
||||
- int pwrc;
|
||||
-
|
||||
- pwrc = need_new_pw(pb, &t, bind_target_entry, pwresponse_requested);
|
||||
-
|
||||
- switch (pwrc) {
|
||||
- case 1:
|
||||
- slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- break;
|
||||
- case 2:
|
||||
- slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t);
|
||||
- break;
|
||||
- case -1:
|
||||
- goto out;
|
||||
- default:
|
||||
- break;
|
||||
- }
|
||||
+ if (!isroot && need_new_pw(pb, bind_target_entry, pwresponse_requested) == -1) {
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
/* attach the sasl data */
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,439 @@
|
|||
From 8a7b47602acc910d2f64439b81af3299b60359c8 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 18 Sep 2017 10:35:20 -0400
|
||||
Subject: [PATCH] Ticket 49379 - Allowed sasl mapping requires restart
|
||||
|
||||
Bug Description: If allowed sasl mechanisms are configured, and the server is
|
||||
restarted, trying to add new sasl mechanisms does not get applied
|
||||
until the server is restarted again. [1]
|
||||
|
||||
We were also overwriting memory when we stripped the commas from
|
||||
the allowed machanism list. THis lead to the allowed mechanisms
|
||||
to get truncated,and permanently lose certain mechs. [2]
|
||||
|
||||
A crash with PLAIN sasl mechanism was also found. [3]
|
||||
|
||||
Fix Description: To address allowed sasl mechs, we no longer explicitly the mechanisms
|
||||
during the sasl_init at server startup. Instead we check the allowed
|
||||
list ourselves during a bind. [1]
|
||||
|
||||
When setting the allowed sasl mechs, make a copy of the value to
|
||||
apply the changes to(removing coamms), and do not change the original
|
||||
value as it's still being used. [2]
|
||||
|
||||
The crash when using sasl PLAIN was due to unlocking a rwlock that
|
||||
was not locked. [3]
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49379
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
|
||||
(cherry picked from commit c78f41db31752a99aadd6abcbf7a1d852a8e7931)
|
||||
---
|
||||
dirsrvtests/tests/suites/sasl/allowed_mechs.py | 114 ++++++++++++++++++++++--
|
||||
dirsrvtests/tests/suites/sasl/plain.py | 10 ++-
|
||||
ldap/servers/slapd/libglobs.c | 23 ++---
|
||||
ldap/servers/slapd/saslbind.c | 116 +++++++++++++------------
|
||||
4 files changed, 187 insertions(+), 76 deletions(-)
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/sasl/allowed_mechs.py b/dirsrvtests/tests/suites/sasl/allowed_mechs.py
|
||||
index 7958db4..5b1b92c 100644
|
||||
--- a/dirsrvtests/tests/suites/sasl/allowed_mechs.py
|
||||
+++ b/dirsrvtests/tests/suites/sasl/allowed_mechs.py
|
||||
@@ -8,45 +8,141 @@
|
||||
#
|
||||
|
||||
import pytest
|
||||
-import ldap
|
||||
-
|
||||
-import time
|
||||
-
|
||||
+import os
|
||||
from lib389.topologies import topology_st
|
||||
|
||||
+
|
||||
def test_sasl_allowed_mechs(topology_st):
|
||||
+ """Test the alloweed sasl mechanism feature
|
||||
+
|
||||
+ :ID: ab7d9f86-8cfe-48c3-8baa-739e599f006a
|
||||
+ :feature: Allowed sasl mechanisms
|
||||
+ :steps: 1. Get the default list of mechanisms
|
||||
+ 2. Set allowed mechanism PLAIN, and verify it's correctly listed
|
||||
+ 3. Restart server, and verify list is still correct
|
||||
+ 4. Test EXTERNAL is properly listed
|
||||
+ 5. Add GSSAPI to the existing list, and verify it's correctly listed
|
||||
+ 6. Restart server and verify list is still correct
|
||||
+ 7. Add ANONYMOUS to the existing list, and veirfy it's correctly listed
|
||||
+ 8. Restart server and verify list is still correct
|
||||
+ 9. Remove GSSAPI and verify it's correctly listed
|
||||
+ 10. Restart server and verify list is still correct
|
||||
+ 11. Reset allowed list to nothing, verify "all" the mechanisms are returned
|
||||
+ 12. Restart server and verify list is still correct
|
||||
+
|
||||
+ :expectedresults: The supported mechanisms supported what is set for the allowed
|
||||
+ mechanisms
|
||||
+ """
|
||||
standalone = topology_st.standalone
|
||||
|
||||
# Get the supported mechs. This should contain PLAIN, GSSAPI, EXTERNAL at least
|
||||
+ standalone.log.info("Test we have some of the default mechanisms")
|
||||
orig_mechs = standalone.rootdse.supported_sasl()
|
||||
print(orig_mechs)
|
||||
assert('GSSAPI' in orig_mechs)
|
||||
assert('PLAIN' in orig_mechs)
|
||||
assert('EXTERNAL' in orig_mechs)
|
||||
|
||||
- # Now edit the supported mechs. CHeck them again.
|
||||
+ # Now edit the supported mechs. Check them again.
|
||||
+ standalone.log.info("Edit mechanisms to allow just PLAIN")
|
||||
standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN')
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs) # Should always be in the allowed list, even if not set.
|
||||
+ assert('GSSAPI' not in limit_mechs) # Should not be there!
|
||||
|
||||
+ # Restart the server a few times and make sure nothing changes
|
||||
+ standalone.log.info("Restart server and make sure we still have correct allowed mechs")
|
||||
+ standalone.restart()
|
||||
+ standalone.restart()
|
||||
limit_mechs = standalone.rootdse.supported_sasl()
|
||||
assert('PLAIN' in limit_mechs)
|
||||
- # Should always be in the allowed list, even if not set.
|
||||
assert('EXTERNAL' in limit_mechs)
|
||||
- # Should not be there!
|
||||
assert('GSSAPI' not in limit_mechs)
|
||||
|
||||
+ # Set EXTERNAL, even though its always supported
|
||||
+ standalone.log.info("Edit mechanisms to allow just PLAIN and EXTERNAL")
|
||||
standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN, EXTERNAL')
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' not in limit_mechs)
|
||||
+
|
||||
+ # Now edit the supported mechs. Check them again.
|
||||
+ standalone.log.info("Edit mechanisms to allow just PLAIN and GSSAPI")
|
||||
+ standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN, GSSAPI')
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' in limit_mechs)
|
||||
+ assert(len(limit_mechs) == 3)
|
||||
+
|
||||
+ # Restart server twice and make sure the allowed list is the same
|
||||
+ standalone.restart()
|
||||
+ standalone.restart() # For ticket 49379 (test double restart)
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' in limit_mechs)
|
||||
+ assert(len(limit_mechs) == 3)
|
||||
+
|
||||
+ # Add ANONYMOUS to the supported mechs and test again.
|
||||
+ standalone.log.info("Edit mechanisms to allow just PLAIN, GSSAPI, and ANONYMOUS")
|
||||
+ standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN, GSSAPI, ANONYMOUS')
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' in limit_mechs)
|
||||
+ assert('ANONYMOUS' in limit_mechs)
|
||||
+ assert(len(limit_mechs) == 4)
|
||||
+
|
||||
+ # Restart server and make sure the allowed list is the same
|
||||
+ standalone.restart()
|
||||
+ standalone.restart() # For ticket 49379 (test double restart)
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' in limit_mechs)
|
||||
+ assert('ANONYMOUS' in limit_mechs)
|
||||
+ assert(len(limit_mechs) == 4)
|
||||
|
||||
+ # Remove GSSAPI
|
||||
+ standalone.log.info("Edit mechanisms to allow just PLAIN and ANONYMOUS")
|
||||
+ standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN, ANONYMOUS')
|
||||
limit_mechs = standalone.rootdse.supported_sasl()
|
||||
assert('PLAIN' in limit_mechs)
|
||||
assert('EXTERNAL' in limit_mechs)
|
||||
- # Should not be there!
|
||||
assert('GSSAPI' not in limit_mechs)
|
||||
+ assert('ANONYMOUS' in limit_mechs)
|
||||
+ assert(len(limit_mechs) == 3)
|
||||
+
|
||||
+ # Restart server and make sure the allowed list is the same
|
||||
+ standalone.restart()
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' not in limit_mechs)
|
||||
+ assert('ANONYMOUS' in limit_mechs)
|
||||
+ assert(len(limit_mechs) == 3)
|
||||
|
||||
# Do a config reset
|
||||
+ standalone.log.info("Reset allowed mechaisms")
|
||||
standalone.config.reset('nsslapd-allowed-sasl-mechanisms')
|
||||
|
||||
# check the supported list is the same as our first check.
|
||||
+ standalone.log.info("Check that we have the original set of mechanisms")
|
||||
final_mechs = standalone.rootdse.supported_sasl()
|
||||
- print(final_mechs)
|
||||
assert(set(final_mechs) == set(orig_mechs))
|
||||
|
||||
+ # Check it after a restart
|
||||
+ standalone.log.info("Check that we have the original set of mechanisms after a restart")
|
||||
+ standalone.restart()
|
||||
+ final_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert(set(final_mechs) == set(orig_mechs))
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ # Run isolated
|
||||
+ # -s for DEBUG mode
|
||||
+ CURRENT_FILE = os.path.realpath(__file__)
|
||||
+ pytest.main("-s %s" % CURRENT_FILE)
|
||||
diff --git a/dirsrvtests/tests/suites/sasl/plain.py b/dirsrvtests/tests/suites/sasl/plain.py
|
||||
index 91ccb02..6bf39a8 100644
|
||||
--- a/dirsrvtests/tests/suites/sasl/plain.py
|
||||
+++ b/dirsrvtests/tests/suites/sasl/plain.py
|
||||
@@ -15,9 +15,11 @@ from lib389.topologies import topology_st
|
||||
from lib389.utils import *
|
||||
from lib389.sasl import PlainSASL
|
||||
from lib389.idm.services import ServiceAccounts
|
||||
+from lib389._constants import (SECUREPORT_STANDALONE1, DEFAULT_SUFFIX)
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
+
|
||||
def test_sasl_plain(topology_st):
|
||||
|
||||
standalone = topology_st.standalone
|
||||
@@ -38,7 +40,7 @@ def test_sasl_plain(topology_st):
|
||||
standalone.rsa.create()
|
||||
# Set the secure port and nsslapd-security
|
||||
# Could this fail with selinux?
|
||||
- standalone.config.set('nsslapd-secureport', '%s' % SECUREPORT_STANDALONE1 )
|
||||
+ standalone.config.set('nsslapd-secureport', '%s' % SECUREPORT_STANDALONE1)
|
||||
standalone.config.set('nsslapd-security', 'on')
|
||||
# Do we need to restart to allow starttls?
|
||||
standalone.restart()
|
||||
@@ -65,12 +67,14 @@ def test_sasl_plain(topology_st):
|
||||
# I can not solve. I think it's leaking state across connections in start_tls_s?
|
||||
|
||||
# Check that it works with TLS
|
||||
- conn = standalone.openConnection(saslmethod='PLAIN', sasltoken=auth_tokens, starttls=True, connOnly=True, certdir=standalone.get_cert_dir(), reqcert=ldap.OPT_X_TLS_NEVER)
|
||||
+ conn = standalone.openConnection(saslmethod='PLAIN', sasltoken=auth_tokens, starttls=True, connOnly=True,
|
||||
+ certdir=standalone.get_cert_dir(), reqcert=ldap.OPT_X_TLS_NEVER)
|
||||
conn.close()
|
||||
|
||||
# Check that it correct fails our bind if we don't have the password.
|
||||
auth_tokens = PlainSASL("dn:%s" % sa.dn, 'password-wrong')
|
||||
with pytest.raises(ldap.INVALID_CREDENTIALS):
|
||||
- standalone.openConnection(saslmethod='PLAIN', sasltoken=auth_tokens, starttls=False, connOnly=True, certdir=standalone.get_cert_dir(), reqcert=ldap.OPT_X_TLS_NEVER)
|
||||
+ standalone.openConnection(saslmethod='PLAIN', sasltoken=auth_tokens, starttls=True, connOnly=True,
|
||||
+ certdir=standalone.get_cert_dir(), reqcert=ldap.OPT_X_TLS_NEVER)
|
||||
|
||||
# Done!
|
||||
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
|
||||
index bb51827..2fb4bab 100644
|
||||
--- a/ldap/servers/slapd/libglobs.c
|
||||
+++ b/ldap/servers/slapd/libglobs.c
|
||||
@@ -7137,22 +7137,25 @@ config_set_allowed_sasl_mechs(const char *attrname, char *value, char *errorbuf,
|
||||
|
||||
/* During a reset, the value is "", so we have to handle this case. */
|
||||
if (strcmp(value, "") != 0) {
|
||||
- /* cyrus sasl doesn't like comma separated lists */
|
||||
- remove_commas(value);
|
||||
+ char *nval = slapi_ch_strdup(value);
|
||||
|
||||
- if(invalid_sasl_mech(value)){
|
||||
- slapi_log_err(SLAPI_LOG_ERR,"config_set_allowed_sasl_mechs",
|
||||
- "Invalid value/character for sasl mechanism (%s). Use ASCII "
|
||||
- "characters, upto 20 characters, that are upper-case letters, "
|
||||
- "digits, hyphens, or underscores\n", value);
|
||||
+ /* cyrus sasl doesn't like comma separated lists */
|
||||
+ remove_commas(nval);
|
||||
+
|
||||
+ if (invalid_sasl_mech(nval)) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "config_set_allowed_sasl_mechs",
|
||||
+ "Invalid value/character for sasl mechanism (%s). Use ASCII "
|
||||
+ "characters, upto 20 characters, that are upper-case letters, "
|
||||
+ "digits, hyphens, or underscores\n",
|
||||
+ nval);
|
||||
+ slapi_ch_free_string(&nval);
|
||||
return LDAP_UNWILLING_TO_PERFORM;
|
||||
}
|
||||
-
|
||||
CFG_LOCK_WRITE(slapdFrontendConfig);
|
||||
slapi_ch_free_string(&slapdFrontendConfig->allowed_sasl_mechs);
|
||||
slapi_ch_array_free(slapdFrontendConfig->allowed_sasl_mechs_array);
|
||||
- slapdFrontendConfig->allowed_sasl_mechs = slapi_ch_strdup(value);
|
||||
- slapdFrontendConfig->allowed_sasl_mechs_array = slapi_str2charray_ext(value, " ", 0);
|
||||
+ slapdFrontendConfig->allowed_sasl_mechs = nval;
|
||||
+ slapdFrontendConfig->allowed_sasl_mechs_array = slapi_str2charray_ext(nval, " ", 0);
|
||||
CFG_UNLOCK_WRITE(slapdFrontendConfig);
|
||||
} else {
|
||||
/* If this value is "", we need to set the list to *all* possible mechs */
|
||||
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
||||
index 134f5aa..03e2a97 100644
|
||||
--- a/ldap/servers/slapd/saslbind.c
|
||||
+++ b/ldap/servers/slapd/saslbind.c
|
||||
@@ -169,8 +169,6 @@ static int ids_sasl_getopt(
|
||||
}
|
||||
} else if (strcasecmp(option, "auxprop_plugin") == 0) {
|
||||
*result = "iDS";
|
||||
- } else if (strcasecmp(option, "mech_list") == 0){
|
||||
- *result = config_get_allowed_sasl_mechs();
|
||||
}
|
||||
|
||||
if (*result) *len = strlen(*result);
|
||||
@@ -572,12 +570,8 @@ static int ids_sasl_userdb_checkpass(sasl_conn_t *conn, void *context, const cha
|
||||
slapi_pblock_set(pb, SLAPI_BIND_METHOD, &method);
|
||||
/* Feed it to pw_verify_be_dn */
|
||||
bind_result = pw_verify_be_dn(pb, &referral);
|
||||
- /* Now check the result, and unlock be if needed. */
|
||||
- if (bind_result == SLAPI_BIND_SUCCESS || bind_result == SLAPI_BIND_ANONYMOUS) {
|
||||
- Slapi_Backend *be = NULL;
|
||||
- slapi_pblock_get(pb, SLAPI_BACKEND, &be);
|
||||
- slapi_be_Unlock(be);
|
||||
- } else if (bind_result == SLAPI_BIND_REFERRAL) {
|
||||
+ /* Now check the result. */
|
||||
+ if (bind_result == SLAPI_BIND_REFERRAL) {
|
||||
/* If we have a referral do we ignore it for sasl? */
|
||||
slapi_entry_free(referral);
|
||||
}
|
||||
@@ -760,22 +754,25 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
sup_ret = slapi_get_supported_saslmechanisms_copy();
|
||||
|
||||
/* If we have a connection, get the provided list from SASL */
|
||||
- if (pb->pb_conn != NULL) {
|
||||
- sasl_conn = (sasl_conn_t*)pb->pb_conn->c_sasl_conn;
|
||||
-
|
||||
- /* sasl library mechanisms are connection dependent */
|
||||
- PR_EnterMonitor(pb->pb_conn->c_mutex);
|
||||
- if (sasl_listmech(sasl_conn,
|
||||
- NULL, /* username */
|
||||
- "", ",", "",
|
||||
- &str, NULL, NULL) == SASL_OK) {
|
||||
- slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_listmech", "sasl library mechs: %s\n", str);
|
||||
- /* merge into result set */
|
||||
- dupstr = slapi_ch_strdup(str);
|
||||
- others = slapi_str2charray_ext(dupstr, ",", 0 /* don't list duplicate mechanisms */);
|
||||
- charray_merge(&sup_ret, others, 1);
|
||||
- charray_free(others);
|
||||
- slapi_ch_free((void**)&dupstr);
|
||||
+ if (pb_conn != NULL) {
|
||||
+ sasl_conn = (sasl_conn_t*)pb_conn->c_sasl_conn;
|
||||
+ if (sasl_conn != NULL) {
|
||||
+ /* sasl library mechanisms are connection dependent */
|
||||
+ PR_EnterMonitor(pb_conn->c_mutex);
|
||||
+ if (sasl_listmech(sasl_conn,
|
||||
+ NULL, /* username */
|
||||
+ "", ",", "",
|
||||
+ &str, NULL, NULL) == SASL_OK) {
|
||||
+ slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_listmech", "sasl library mechs: %s\n", str);
|
||||
+ /* merge into result set */
|
||||
+ dupstr = slapi_ch_strdup(str);
|
||||
+ others = slapi_str2charray_ext(dupstr, ",", 0 /* don't list duplicate mechanisms */);
|
||||
+
|
||||
+ charray_merge(&sup_ret, others, 1);
|
||||
+ charray_free(others);
|
||||
+ slapi_ch_free((void**)&dupstr);
|
||||
+ }
|
||||
+ PR_ExitMonitor(pb_conn->c_mutex);
|
||||
}
|
||||
PR_ExitMonitor(pb->pb_conn->c_mutex);
|
||||
}
|
||||
@@ -785,7 +782,7 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
|
||||
/* Remove any content that isn't in the allowed list */
|
||||
if (config_ret != NULL) {
|
||||
- /* Get the set of supported mechs in the insection of the two */
|
||||
+ /* Get the set of supported mechs in the intersection of the two */
|
||||
ret = charray_intersection(sup_ret, config_ret);
|
||||
charray_free(sup_ret);
|
||||
charray_free(config_ret);
|
||||
@@ -816,41 +813,52 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
static int
|
||||
ids_sasl_mech_supported(Slapi_PBlock *pb, const char *mech)
|
||||
{
|
||||
- int i, ret = 0;
|
||||
- char **mechs;
|
||||
- char *dupstr;
|
||||
- const char *str;
|
||||
- int sasl_result = 0;
|
||||
- sasl_conn_t *sasl_conn = (sasl_conn_t *)pb->pb_conn->c_sasl_conn;
|
||||
-
|
||||
- slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_mech_supported", "=>\n");
|
||||
-
|
||||
-
|
||||
- /* sasl_listmech is not thread-safe - caller must lock pb_conn */
|
||||
- sasl_result = sasl_listmech(sasl_conn,
|
||||
- NULL, /* username */
|
||||
- "", ",", "",
|
||||
- &str, NULL, NULL);
|
||||
- if (sasl_result != SASL_OK) {
|
||||
- return 0;
|
||||
- }
|
||||
+ int i, ret = 0;
|
||||
+ char **mechs;
|
||||
+ char **allowed_mechs = NULL;
|
||||
+ char *dupstr;
|
||||
+ const char *str;
|
||||
+ int sasl_result = 0;
|
||||
+ Connection *pb_conn = NULL;
|
||||
+
|
||||
+ slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
+ sasl_conn_t *sasl_conn = (sasl_conn_t *)pb_conn->c_sasl_conn;
|
||||
+ slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_mech_supported", "=>\n");
|
||||
+
|
||||
+ /* sasl_listmech is not thread-safe - caller must lock pb_conn */
|
||||
+ sasl_result = sasl_listmech(sasl_conn,
|
||||
+ NULL, /* username */
|
||||
+ "", ",", "",
|
||||
+ &str, NULL, NULL);
|
||||
+ if (sasl_result != SASL_OK) {
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
- dupstr = slapi_ch_strdup(str);
|
||||
- mechs = slapi_str2charray(dupstr, ",");
|
||||
+ dupstr = slapi_ch_strdup(str);
|
||||
+ mechs = slapi_str2charray(dupstr, ",");
|
||||
+ allowed_mechs = config_get_allowed_sasl_mechs_array();
|
||||
|
||||
- for (i = 0; mechs[i] != NULL; i++) {
|
||||
- if (strcasecmp(mech, mechs[i]) == 0) {
|
||||
- ret = 1;
|
||||
- break;
|
||||
+ for (i = 0; mechs[i] != NULL; i++) {
|
||||
+ if (strcasecmp(mech, mechs[i]) == 0) {
|
||||
+ if (allowed_mechs) {
|
||||
+ if (charray_inlist(allowed_mechs, (char *)mech) == 0) {
|
||||
+ ret = 1;
|
||||
+ }
|
||||
+ break;
|
||||
+ } else {
|
||||
+ ret = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
|
||||
- charray_free(mechs);
|
||||
- slapi_ch_free((void**)&dupstr);
|
||||
+ charray_free(allowed_mechs);
|
||||
+ charray_free(mechs);
|
||||
+ slapi_ch_free((void **)&dupstr);
|
||||
|
||||
- slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_mech_supported", "<=\n");
|
||||
+ slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_mech_supported", "<=\n");
|
||||
|
||||
- return ret;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
From 4a51a17762fb4e7ce1beb0600916fed8b45a5483 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 18 Sep 2017 15:06:06 -0400
|
||||
Subject: [PATCH] Fix cherry-pick error from sasl mech commit
|
||||
|
||||
---
|
||||
ldap/servers/slapd/saslbind.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
||||
index 03e2a97..8e94ee6 100644
|
||||
--- a/ldap/servers/slapd/saslbind.c
|
||||
+++ b/ldap/servers/slapd/saslbind.c
|
||||
@@ -745,11 +745,14 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
const char *str;
|
||||
char *dupstr;
|
||||
sasl_conn_t *sasl_conn;
|
||||
+ Connection *pb_conn = NULL;
|
||||
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_listmech", "=>\n");
|
||||
|
||||
PR_ASSERT(pb);
|
||||
|
||||
+ slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
+
|
||||
/* hard-wired mechanisms and slapi plugin registered mechanisms */
|
||||
sup_ret = slapi_get_supported_saslmechanisms_copy();
|
||||
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,322 @@
|
|||
From 2741a6db134ad40662cfa0233c4542d2d4148997 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 3 Oct 2017 17:22:37 -0400
|
||||
Subject: [PATCH] Ticket 49389 - unable to retrieve specific cosAttribute when
|
||||
subtree password policy is configured
|
||||
|
||||
Bug Description: If indirect cos is being used and a subtree password
|
||||
policy is added, th orignal COS attributes aren't always
|
||||
returned. The issue is that when the subtree password
|
||||
policy attribute was encountered during the virtual
|
||||
attribute processing it set a flag that said the attribute
|
||||
was operational (which is correct for the password policy
|
||||
attr: pwdpolicysubentry).
|
||||
|
||||
However, this flag was accidentally carried over to the
|
||||
following virtual attributes that were being processed.
|
||||
Which caused those attributes to be seen as operational
|
||||
which is why it was no longer being returned to the client.
|
||||
|
||||
Fix Description: Reset the prop flags before processing the next COS attribute
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49389
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 0953e6011368bc29300990e9493ac13e5aba9586)
|
||||
---
|
||||
dirsrvtests/tests/suites/cos/__init__.py | 0
|
||||
dirsrvtests/tests/suites/cos/indirect_cos_test.py | 191 ++++++++++++++++++++++
|
||||
ldap/servers/plugins/cos/cos_cache.c | 68 ++++----
|
||||
3 files changed, 223 insertions(+), 36 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/suites/cos/__init__.py
|
||||
create mode 100644 dirsrvtests/tests/suites/cos/indirect_cos_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/cos/__init__.py b/dirsrvtests/tests/suites/cos/__init__.py
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
diff --git a/dirsrvtests/tests/suites/cos/indirect_cos_test.py b/dirsrvtests/tests/suites/cos/indirect_cos_test.py
|
||||
new file mode 100644
|
||||
index 0000000..1aac6b8
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/suites/cos/indirect_cos_test.py
|
||||
@@ -0,0 +1,191 @@
|
||||
+import logging
|
||||
+import pytest
|
||||
+import os
|
||||
+import ldap
|
||||
+import time
|
||||
+import subprocess
|
||||
+
|
||||
+from lib389 import Entry
|
||||
+from lib389.idm.user import UserAccounts
|
||||
+from lib389.topologies import topology_st as topo
|
||||
+from lib389._constants import (DEFAULT_SUFFIX, DN_DM, PASSWORD, HOST_STANDALONE,
|
||||
+ SERVERID_STANDALONE, PORT_STANDALONE)
|
||||
+
|
||||
+
|
||||
+DEBUGGING = os.getenv("DEBUGGING", default=False)
|
||||
+if DEBUGGING:
|
||||
+ logging.getLogger(__name__).setLevel(logging.DEBUG)
|
||||
+else:
|
||||
+ logging.getLogger(__name__).setLevel(logging.INFO)
|
||||
+log = logging.getLogger(__name__)
|
||||
+
|
||||
+TEST_USER_DN = "uid=test_user,ou=people,dc=example,dc=com"
|
||||
+OU_PEOPLE = 'ou=people,{}'.format(DEFAULT_SUFFIX)
|
||||
+
|
||||
+PW_POLICY_CONT_PEOPLE = 'cn="cn=nsPwPolicyEntry,' \
|
||||
+ 'ou=people,dc=example,dc=com",' \
|
||||
+ 'cn=nsPwPolicyContainer,ou=people,dc=example,dc=com'
|
||||
+
|
||||
+PW_POLICY_CONT_PEOPLE2 = 'cn="cn=nsPwPolicyEntry,' \
|
||||
+ 'dc=example,dc=com",' \
|
||||
+ 'cn=nsPwPolicyContainerdc=example,dc=com'
|
||||
+
|
||||
+
|
||||
+def check_user(inst):
|
||||
+ """Search the test user and make sure it has the execpted attrs
|
||||
+ """
|
||||
+ try:
|
||||
+ entries = inst.search_s('dc=example,dc=com', ldap.SCOPE_SUBTREE, "uid=test_user")
|
||||
+ log.debug('user: \n' + str(entries[0]))
|
||||
+ assert entries[0].hasAttr('ou'), "Entry is missing ou cos attribute"
|
||||
+ assert entries[0].hasAttr('x-department'), "Entry is missing description cos attribute"
|
||||
+ assert entries[0].hasAttr('x-en-ou'), "Entry is missing givenname cos attribute"
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to search for user: ' + str(e))
|
||||
+ raise e
|
||||
+
|
||||
+
|
||||
+def setup_subtree_policy(topo):
|
||||
+ """Set up subtree password policy
|
||||
+ """
|
||||
+ try:
|
||||
+ topo.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE,
|
||||
+ 'nsslapd-pwpolicy-local',
|
||||
+ 'on')])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to set fine-grained policy: error {}'.format(
|
||||
+ e.message['desc']))
|
||||
+ raise e
|
||||
+
|
||||
+ log.info('Create password policy for subtree {}'.format(OU_PEOPLE))
|
||||
+ try:
|
||||
+ subprocess.call(['%s/ns-newpwpolicy.pl' % topo.standalone.get_sbin_dir(),
|
||||
+ '-D', DN_DM, '-w', PASSWORD,
|
||||
+ '-p', str(PORT_STANDALONE), '-h', HOST_STANDALONE,
|
||||
+ '-S', DEFAULT_SUFFIX, '-Z', SERVERID_STANDALONE])
|
||||
+ except subprocess.CalledProcessError as e:
|
||||
+ log.error('Failed to create pw policy policy for {}: error {}'.format(
|
||||
+ OU_PEOPLE, e.message['desc']))
|
||||
+ raise e
|
||||
+
|
||||
+ log.info('Add pwdpolicysubentry attribute to {}'.format(OU_PEOPLE))
|
||||
+ try:
|
||||
+ topo.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_REPLACE,
|
||||
+ 'pwdpolicysubentry',
|
||||
+ PW_POLICY_CONT_PEOPLE2)])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to pwdpolicysubentry pw policy '
|
||||
+ 'policy for {}: error {}'.format(OU_PEOPLE, e.message['desc']))
|
||||
+ raise e
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+
|
||||
+def setup_indirect_cos(topo):
|
||||
+ """Setup indirect COS definition and template
|
||||
+ """
|
||||
+ cosDef = Entry(('cn=cosDefinition,dc=example,dc=com',
|
||||
+ {'objectclass': ['top', 'ldapsubentry',
|
||||
+ 'cossuperdefinition',
|
||||
+ 'cosIndirectDefinition'],
|
||||
+ 'cosAttribute': ['ou merge-schemes',
|
||||
+ 'x-department merge-schemes',
|
||||
+ 'x-en-ou merge-schemes'],
|
||||
+ 'cosIndirectSpecifier': 'seeAlso',
|
||||
+ 'cn': 'cosDefinition'}))
|
||||
+
|
||||
+ cosTemplate = Entry(('cn=cosTemplate,dc=example,dc=com',
|
||||
+ {'objectclass': ['top',
|
||||
+ 'extensibleObject',
|
||||
+ 'cosTemplate'],
|
||||
+ 'ou': 'My COS Org',
|
||||
+ 'x-department': 'My COS x-department',
|
||||
+ 'x-en-ou': 'my COS x-en-ou',
|
||||
+ 'cn': 'cosTemplate'}))
|
||||
+ try:
|
||||
+ topo.standalone.add_s(cosDef)
|
||||
+ topo.standalone.add_s(cosTemplate)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add cos: error ' + str(e))
|
||||
+ raise e
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+
|
||||
+@pytest.fixture(scope="module")
|
||||
+def setup(topo, request):
|
||||
+ """Add schema, and test user
|
||||
+ """
|
||||
+ log.info('Add custom schema...')
|
||||
+ try:
|
||||
+ ATTR_1 = ("( 1.3.6.1.4.1.409.389.2.189 NAME 'x-department' " +
|
||||
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )")
|
||||
+ ATTR_2 = ("( 1.3.6.1.4.1.409.389.2.187 NAME 'x-en-ou' " +
|
||||
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )")
|
||||
+ OC = ("( xPerson-oid NAME 'xPerson' DESC '' SUP person STRUCTURAL MAY " +
|
||||
+ "( x-department $ x-en-ou ) X-ORIGIN 'user defined' )")
|
||||
+ topo.standalone.modify_s("cn=schema", [(ldap.MOD_ADD, 'attributeTypes', ATTR_1),
|
||||
+ (ldap.MOD_ADD, 'attributeTypes', ATTR_2),
|
||||
+ (ldap.MOD_ADD, 'objectClasses', OC)])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add custom schema')
|
||||
+ raise e
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+ log.info('Add test user...')
|
||||
+ users = UserAccounts(topo.standalone, DEFAULT_SUFFIX)
|
||||
+
|
||||
+ user_properties = {
|
||||
+ 'uid': 'test_user',
|
||||
+ 'cn': 'test user',
|
||||
+ 'sn': 'user',
|
||||
+ 'uidNumber': '1000',
|
||||
+ 'gidNumber': '2000',
|
||||
+ 'homeDirectory': '/home/test_user',
|
||||
+ 'seeAlso': 'cn=cosTemplate,dc=example,dc=com'
|
||||
+ }
|
||||
+ users.create(properties=user_properties)
|
||||
+ try:
|
||||
+ topo.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_ADD,
|
||||
+ 'objectclass',
|
||||
+ 'xPerson')])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add objectclass to user')
|
||||
+ raise e
|
||||
+
|
||||
+ # Setup COS
|
||||
+ log.info("Setup indirect COS...")
|
||||
+ setup_indirect_cos(topo)
|
||||
+
|
||||
+
|
||||
+def test_indirect_cos(topo, setup):
|
||||
+ """Test indirect cos
|
||||
+
|
||||
+ :id: 890d5929-7d52-4a56-956e-129611b4649a
|
||||
+ :setup: standalone
|
||||
+ :steps:
|
||||
+ 1. Test cos is working for test user
|
||||
+ 2. Add subtree password policy
|
||||
+ 3. Test cos is working for test user
|
||||
+ :expectedresults:
|
||||
+ 1. User has expected cos attrs
|
||||
+ 2. Substree password policy setup is successful
|
||||
+ 3 User still has expected cos attrs
|
||||
+ """
|
||||
+
|
||||
+ # Step 1 - Search user and see if the COS attrs are included
|
||||
+ log.info('Checking user...')
|
||||
+ check_user(topo.standalone)
|
||||
+
|
||||
+ # Step 2 - Add subtree password policy (Second COS - operational attribute)
|
||||
+ setup_subtree_policy(topo)
|
||||
+
|
||||
+ # Step 3 - Check user again now hat we have a mix of vattrs
|
||||
+ log.info('Checking user...')
|
||||
+ check_user(topo.standalone)
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ # Run isolated
|
||||
+ # -s for DEBUG mode
|
||||
+ CURRENT_FILE = os.path.realpath(__file__)
|
||||
+ pytest.main("-s %s" % CURRENT_FILE)
|
||||
+
|
||||
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
|
||||
index 66c6c7f..87d4890 100644
|
||||
--- a/ldap/servers/plugins/cos/cos_cache.c
|
||||
+++ b/ldap/servers/plugins/cos/cos_cache.c
|
||||
@@ -2190,48 +2190,44 @@ bail:
|
||||
static int cos_cache_vattr_types(vattr_sp_handle *handle,Slapi_Entry *e,
|
||||
vattr_type_list_context *type_context,int flags)
|
||||
{
|
||||
- int ret = 0;
|
||||
- int index = 0;
|
||||
- cosCache *pCache;
|
||||
- char *lastattr = "thisisfakeforcos";
|
||||
- int props = 0;
|
||||
-
|
||||
- slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_cache_vattr_types\n");
|
||||
-
|
||||
- if(cos_cache_getref((cos_cache **)&pCache) < 1)
|
||||
- {
|
||||
- /* problems we are hosed */
|
||||
- slapi_log_err(SLAPI_LOG_PLUGIN, COS_PLUGIN_SUBSYSTEM, "cos_cache_vattr_types - Failed to get class of service reference\n");
|
||||
- goto bail;
|
||||
- }
|
||||
-
|
||||
- while(index < pCache->attrCount )
|
||||
- {
|
||||
- if(slapi_utf8casecmp(
|
||||
- (unsigned char *)pCache->ppAttrIndex[index]->pAttrName,
|
||||
- (unsigned char *)lastattr))
|
||||
- {
|
||||
- lastattr = pCache->ppAttrIndex[index]->pAttrName;
|
||||
+ int ret = 0;
|
||||
+ int index = 0;
|
||||
+ cosCache *pCache;
|
||||
+ char *lastattr = "thisisfakeforcos";
|
||||
|
||||
- if(1 == cos_cache_query_attr(pCache, NULL, e, lastattr, NULL, NULL,
|
||||
- NULL, &props, NULL))
|
||||
- {
|
||||
- /* entry contains this attr */
|
||||
- vattr_type_thang thang = {0};
|
||||
+ slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_cache_vattr_types\n");
|
||||
|
||||
- thang.type_name = lastattr;
|
||||
- thang.type_flags = props;
|
||||
+ if (cos_cache_getref((cos_cache **)&pCache) < 1) {
|
||||
+ /* problems we are hosed */
|
||||
+ slapi_log_err(SLAPI_LOG_PLUGIN, COS_PLUGIN_SUBSYSTEM, "cos_cache_vattr_types - Failed to get class of service reference\n");
|
||||
+ goto bail;
|
||||
+ }
|
||||
|
||||
- slapi_vattrspi_add_type(type_context,&thang,0);
|
||||
- }
|
||||
- }
|
||||
- index++;
|
||||
- }
|
||||
- cos_cache_release(pCache);
|
||||
+ while (index < pCache->attrCount) {
|
||||
+ int props = 0;
|
||||
+ if (slapi_utf8casecmp(
|
||||
+ (unsigned char *)pCache->ppAttrIndex[index]->pAttrName,
|
||||
+ (unsigned char *)lastattr)) {
|
||||
+ lastattr = pCache->ppAttrIndex[index]->pAttrName;
|
||||
+
|
||||
+ if (1 == cos_cache_query_attr(pCache, NULL, e, lastattr, NULL, NULL,
|
||||
+ NULL, &props, NULL)) {
|
||||
+ /* entry contains this attr */
|
||||
+ vattr_type_thang thang = {0};
|
||||
+
|
||||
+ thang.type_name = lastattr;
|
||||
+ thang.type_flags = props;
|
||||
+
|
||||
+ slapi_vattrspi_add_type(type_context, &thang, 0);
|
||||
+ }
|
||||
+ }
|
||||
+ index++;
|
||||
+ }
|
||||
+ cos_cache_release(pCache);
|
||||
|
||||
bail:
|
||||
|
||||
-slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "<-- cos_cache_vattr_types\n");
|
||||
+ slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "<-- cos_cache_vattr_types\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
Summary: 389 Directory Server (base)
|
||||
Name: 389-ds-base
|
||||
Version: 1.3.6.1
|
||||
Release: %{?relprefix}19%{?prerel}%{?dist}
|
||||
Release: %{?relprefix}21%{?prerel}%{?dist}
|
||||
License: GPLv3+
|
||||
URL: https://www.port389.org/
|
||||
Group: System Environment/Daemons
|
||||
|
@ -195,7 +195,17 @@ Patch58: 0058-Ticket-49336-SECURITY-Locked-account-provides-differ.patc
|
|||
Patch59: 0059-Ticket-49298-force-sync-on-shutdown.patch
|
||||
Patch60: 0060-Ticket-49334-fix-backup-restore-if-changelog-exists.patch
|
||||
Patch61: 0061-Ticket-49356-mapping-tree-crash-can-occur-during-tot.patch
|
||||
|
||||
Patch62: 0062-Ticket-49330-Improve-ndn-cache-performance-1.3.6.patch
|
||||
Patch63: 0063-Ticket-49330-Add-endian-header-file-check-to-configu.patch
|
||||
Patch64: 0064-Ticket-49257-only-register-modify-callbacks.patch
|
||||
Patch65: 0065-Ticket-49291-slapi_search_internal_callback_pb-may-S.patch
|
||||
Patch66: 0066-Ticket-49370-local-password-policies-should-use-the-.patch
|
||||
Patch67: 0067-Ticket-49380-Crash-when-adding-invalid-replication.patch
|
||||
Patch68: 0068-Ticket-49380-Add-CI-test.patch
|
||||
Patch69: 0069-Ticket-49327-password-expired-control-not-sent-durin.patch
|
||||
Patch70: 0070-Ticket-49379-Allowed-sasl-mapping-requires-restart.patch
|
||||
Patch71: 0071-Fix-cherry-pick-error-from-sasl-mech-commit.patch
|
||||
Patch72: 0072-Ticket-49389-unable-to-retrieve-specific-cosAttribut.patch
|
||||
|
||||
%description
|
||||
389 Directory Server is an LDAPv3 compliant server. The base package includes
|
||||
|
@ -327,6 +337,17 @@ cp %{SOURCE2} README.devel
|
|||
%patch59 -p1
|
||||
%patch60 -p1
|
||||
%patch61 -p1
|
||||
%patch62 -p1
|
||||
%patch63 -p1
|
||||
%patch64 -p1
|
||||
%patch65 -p1
|
||||
%patch66 -p1
|
||||
%patch67 -p1
|
||||
%patch68 -p1
|
||||
%patch69 -p1
|
||||
%patch70 -p1
|
||||
%patch71 -p1
|
||||
%patch72 -p1
|
||||
%build
|
||||
|
||||
OPENLDAP_FLAG="--with-openldap"
|
||||
|
@ -457,9 +478,9 @@ echo remove pid files . . . >> $output 2>&1 || :
|
|||
echo upgrading instances . . . >> $output 2>&1 || :
|
||||
DEBUGPOSTSETUPOPT=`/usr/bin/echo $DEBUGPOSTSETUP | /usr/bin/sed -e "s/[^d]//g"`
|
||||
if [ -n "$DEBUGPOSTSETUPOPT" ] ; then
|
||||
%{_sbindir}/setup-ds.pl -l $output2 -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || :
|
||||
%{_sbindir}/setup-ds.pl -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || :
|
||||
else
|
||||
%{_sbindir}/setup-ds.pl -l $output2 -u -s General.UpdateMode=offline >> $output 2>&1 || :
|
||||
%{_sbindir}/setup-ds.pl -u -s General.UpdateMode=offline >> $output 2>&1 || :
|
||||
fi
|
||||
|
||||
# restart instances that require it
|
||||
|
@ -558,8 +579,22 @@ fi
|
|||
%{_sysconfdir}/%{pkgname}/dirsrvtests
|
||||
|
||||
%changelog
|
||||
* Mon Aug 21 2017 Mark Reynolds <mreynolds@redhat.com> - 1.3.6.19-1
|
||||
- Bump version to 1.3.6.19-1
|
||||
* Thu Oct 5 2017 Mark Reynolds <mreynolds@redhat.com> - 1.3.6.1-21
|
||||
- Bump verions to 1.3.6.1-21
|
||||
- Resolves: Bug 1498958 - unable to retrieve specific cosAttribute when subtree password policy is configured
|
||||
|
||||
* Mon Sep 18 2017 Mark Reynolds <mreynolds@redhat.com> - 1.3.6.1-20
|
||||
- Bump verions to 1.3.6.1-20
|
||||
- Resolves: Bug 1489693 - PasswordCheckSyntax attribute fails to validate cn, sn, uid
|
||||
- Resovles: Bug 1492829 - patch should of been applied to 7.4 but got missed
|
||||
- Resolves: Bug 1486128 - Performance issues with RHDS 10 - NDN cache investigation
|
||||
- Resolves: Bug 1489694 - crash in send_ldap_result
|
||||
- Resolves: Bug 1491778 - crash when adding invalid repl agmt
|
||||
- Resolves: Bug 1492830 - password expired control not sent
|
||||
- Resolves: Bug 1492833 - sasl-mechanisms removed during upgrade
|
||||
|
||||
* Mon Aug 21 2017 Mark Reynolds <mreynolds@redhat.com> - 1.3.6.1-19
|
||||
- Bump version to 1.3.6.1-19
|
||||
- Remove old mozldap and db4 requirements
|
||||
- Resolves: Bug 1483865 - Crash while binding to a server during replication online init
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue