-
Notifications
You must be signed in to change notification settings - Fork 0
/
0003-Bug-683250-slapd-crashing-when-traffic-replayed.patch
171 lines (153 loc) · 6.89 KB
/
0003-Bug-683250-slapd-crashing-when-traffic-replayed.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
From ea9afd2b60cb69fb5479a90c60b7ed8cc3d199bc Mon Sep 17 00:00:00 2001
From: Rich Megginson <rmeggins@redhat.com>
Date: Wed, 9 Mar 2011 18:27:05 -0700
Subject: [PATCH 3/7] Bug 683250 - slapd crashing when traffic replayed
https://bugzilla.redhat.com/show_bug.cgi?id=683250
Resolves: bug 683250
Bug Description: slapd crashing when traffic replayed
Reviewed by: nkinder (Thanks!)
Branch: 389-ds-base-1.2.8
Fix Description: There was a race condition in the saslbind.c code if multiple
threads and multiple connections were doing gssapi at the same time, with
different points of failure. The solution is to increase the size of the
mutex section in saslbind.c so that all access of pb->pb_conn are protected.
Thanks to Jeremy Mates <jmates@uw.edu> for finding this issue and for his
assistance in testing.
Platforms tested: RHEL6 x86_64, Fedora 14 i386
Flag Day: no
Doc impact: no
(cherry picked from commit 2c8637c242ace8a7d61474913c861e336a7809cd)
---
ldap/servers/slapd/saslbind.c | 31 ++++++++++++++++---------------
1 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
index 5204b56..f9f51df 100644
--- a/ldap/servers/slapd/saslbind.c
+++ b/ldap/servers/slapd/saslbind.c
@@ -729,26 +729,26 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
/*
* Determine whether a given sasl mechanism is supported by
* this sasl connection. Returns true/false.
+ * NOTE: caller must lock pb->pb_conn->c_mutex
*/
static int
-ids_sasl_mech_supported(Slapi_PBlock *pb, sasl_conn_t *sasl_conn, const char *mech)
+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;
LDAPDebug( LDAP_DEBUG_TRACE, "=> ids_sasl_mech_supported\n", 0, 0, 0 );
- /* sasl_listmech is not thread-safe, so we lock here */
- PR_Lock(pb->pb_conn->c_mutex);
+ /* sasl_listmech is not thread-safe - caller must lock pb_conn */
sasl_result = sasl_listmech(sasl_conn,
NULL, /* username */
"", ",", "",
&str, NULL, NULL);
- PR_Unlock(pb->pb_conn->c_mutex);
if (sasl_result != SASL_OK) {
return 0;
}
@@ -800,13 +800,13 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
PR_ASSERT(pb);
PR_ASSERT(pb->pb_conn);
- PR_Lock(pb->pb_conn->c_mutex);
+ PR_Lock(pb->pb_conn->c_mutex); /* BIG LOCK */
continuing = pb->pb_conn->c_flags & CONN_FLAG_SASL_CONTINUE;
pb->pb_conn->c_flags &= ~CONN_FLAG_SASL_CONTINUE; /* reset flag */
sasl_conn = (sasl_conn_t*)pb->pb_conn->c_sasl_conn;
- PR_Unlock(pb->pb_conn->c_mutex);
if (sasl_conn == NULL) {
+ PR_Unlock(pb->pb_conn->c_mutex);
send_ldap_result( pb, LDAP_AUTH_METHOD_NOT_SUPPORTED, NULL,
"sasl library unavailable", 0, NULL );
return;
@@ -820,10 +820,10 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
/* Work around a bug in the sasl library. We've told the
* library that CRAM-MD5 is disabled, but it gives us a
- * different error code to SASL_NOMECH.
+ * different error code to SASL_NOMECH. Must be called
+ * while holding the pb_conn lock
*/
- /* richm - this locks and unlocks pb->pb_conn */
- if (!ids_sasl_mech_supported(pb, sasl_conn, mech)) {
+ if (!ids_sasl_mech_supported(pb, mech)) {
rc = SASL_NOMECH;
goto sasl_check_result;
}
@@ -860,7 +860,6 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
* using the new mechanism. We also need to do this if the
* mechanism changed in the middle of the SASL authentication
* process. */
- PR_Lock(pb->pb_conn->c_mutex);
if ((pb->pb_conn->c_flags & CONN_FLAG_SASL_COMPLETE) || continuing) {
Slapi_Operation *operation;
slapi_pblock_get( pb, SLAPI_OPERATION, &operation);
@@ -882,11 +881,10 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
if (sasl_conn == NULL) {
send_ldap_result( pb, LDAP_AUTH_METHOD_NOT_SUPPORTED, NULL,
"sasl library unavailable", 0, NULL );
- PR_Unlock(pb->pb_conn->c_mutex);
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
return;
}
}
- PR_Unlock(pb->pb_conn->c_mutex);
rc = sasl_server_start(sasl_conn, mech,
cred->bv_val, cred->bv_len,
@@ -899,6 +897,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
/* retrieve the authenticated username */
if (sasl_getprop(sasl_conn, SASL_USERNAME,
(const void**)&username) != SASL_OK) {
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
"could not obtain sasl username", 0, NULL);
break;
@@ -919,6 +918,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
}
}
if (dn == NULL) {
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
"could not get auth dn from sasl", 0, NULL);
break;
@@ -933,8 +933,6 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
*ssfp = 0;
}
- /* this is stuff we have to do inside the conn mutex */
- PR_Lock(pb->pb_conn->c_mutex);
/* Set a flag to signify that sasl bind is complete */
pb->pb_conn->c_flags |= CONN_FLAG_SASL_COMPLETE;
/* note - we set this here in case there are pre-bind
@@ -952,7 +950,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
bind_credentials_set_nolock(pb->pb_conn, authtype, dn,
NULL, NULL, NULL, bind_target_entry);
- PR_Unlock(pb->pb_conn->c_mutex);
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
if (plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) != 0){
break;
@@ -1042,6 +1040,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
case SASL_CONTINUE: /* another step needed */
pb->pb_conn->c_flags |= CONN_FLAG_SASL_CONTINUE;
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
if (plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) != 0){
break;
@@ -1063,6 +1062,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
case SASL_NOMECH:
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
send_ldap_result(pb, LDAP_AUTH_METHOD_NOT_SUPPORTED, NULL,
"sasl mechanism not supported", 0, NULL);
break;
@@ -1070,6 +1070,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
default: /* other error */
errstr = sasl_errdetail(sasl_conn);
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL,
(char*)errstr, 0, NULL);
break;
--
1.7.1