|
Lines 221-229
_PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn,
Link Here
|
| 221 |
"supportedSASLMechanisms", |
221 |
"supportedSASLMechanisms", |
| 222 |
NULL |
222 |
NULL |
| 223 |
}; |
223 |
}; |
|
|
224 |
unsigned int logon_retries = 0; |
| 225 |
|
| 226 |
status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs, |
| 227 |
false, NULL, NULL, &sasl_mechs_msgs); |
| 228 |
if (!NT_STATUS_IS_OK(status)) { |
| 229 |
DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n", |
| 230 |
nt_errstr(status))); |
| 231 |
goto failed; |
| 232 |
} |
| 233 |
|
| 234 |
count = ildap_count_entries(conn, sasl_mechs_msgs); |
| 235 |
if (count != 1) { |
| 236 |
DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n", |
| 237 |
count)); |
| 238 |
goto failed; |
| 239 |
} |
| 240 |
|
| 241 |
tmp_ctx = talloc_new(conn); |
| 242 |
if (tmp_ctx == NULL) goto failed; |
| 243 |
|
| 244 |
search = &sasl_mechs_msgs[0]->r.SearchResultEntry; |
| 245 |
if (search->num_attributes != 1) { |
| 246 |
DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n", |
| 247 |
search->num_attributes)); |
| 248 |
goto failed; |
| 249 |
} |
| 250 |
|
| 251 |
sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1); |
| 252 |
if (!sasl_names) { |
| 253 |
DEBUG(1, ("talloc_arry(char *, %d) failed\n", |
| 254 |
count)); |
| 255 |
goto failed; |
| 256 |
} |
| 257 |
|
| 258 |
for (i=0; i<search->attributes[0].num_values; i++) { |
| 259 |
sasl_names[i] = (const char *)search->attributes[0].values[i].data; |
| 260 |
} |
| 261 |
sasl_names[i] = NULL; |
| 224 |
|
262 |
|
| 225 |
gensec_init(); |
263 |
gensec_init(); |
| 226 |
|
264 |
|
|
|
265 |
try_logon_again: |
| 266 |
/* |
| 267 |
we loop back here on a logon failure, and re-create the |
| 268 |
gensec session. The logon_retries counter ensures we don't |
| 269 |
loop forever. |
| 270 |
*/ |
| 271 |
|
| 227 |
status = gensec_client_start(conn, &conn->gensec, |
272 |
status = gensec_client_start(conn, &conn->gensec, |
| 228 |
lpcfg_gensec_settings(conn, lp_ctx)); |
273 |
lpcfg_gensec_settings(conn, lp_ctx)); |
| 229 |
if (!NT_STATUS_IS_OK(status)) { |
274 |
if (!NT_STATUS_IS_OK(status)) { |
|
Lines 266-308
_PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn,
Link Here
|
| 266 |
goto failed; |
311 |
goto failed; |
| 267 |
} |
312 |
} |
| 268 |
|
313 |
|
| 269 |
status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs, |
|
|
| 270 |
false, NULL, NULL, &sasl_mechs_msgs); |
| 271 |
if (!NT_STATUS_IS_OK(status)) { |
| 272 |
DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n", |
| 273 |
nt_errstr(status))); |
| 274 |
goto failed; |
| 275 |
} |
| 276 |
|
| 277 |
count = ildap_count_entries(conn, sasl_mechs_msgs); |
| 278 |
if (count != 1) { |
| 279 |
DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n", |
| 280 |
count)); |
| 281 |
goto failed; |
| 282 |
} |
| 283 |
|
| 284 |
tmp_ctx = talloc_new(conn); |
| 285 |
if (tmp_ctx == NULL) goto failed; |
| 286 |
|
| 287 |
search = &sasl_mechs_msgs[0]->r.SearchResultEntry; |
| 288 |
if (search->num_attributes != 1) { |
| 289 |
DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n", |
| 290 |
search->num_attributes)); |
| 291 |
goto failed; |
| 292 |
} |
| 293 |
|
| 294 |
sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1); |
| 295 |
if (!sasl_names) { |
| 296 |
DEBUG(1, ("talloc_arry(char *, %d) failed\n", |
| 297 |
count)); |
| 298 |
goto failed; |
| 299 |
} |
| 300 |
|
| 301 |
for (i=0; i<search->attributes[0].num_values; i++) { |
| 302 |
sasl_names[i] = (const char *)search->attributes[0].values[i].data; |
| 303 |
} |
| 304 |
sasl_names[i] = NULL; |
| 305 |
|
| 306 |
status = gensec_start_mech_by_sasl_list(conn->gensec, sasl_names); |
314 |
status = gensec_start_mech_by_sasl_list(conn->gensec, sasl_names); |
| 307 |
if (!NT_STATUS_IS_OK(status)) { |
315 |
if (!NT_STATUS_IS_OK(status)) { |
| 308 |
DEBUG(1, ("None of the %d proposed SASL mechs were acceptable: %s\n", |
316 |
DEBUG(1, ("None of the %d proposed SASL mechs were acceptable: %s\n", |
|
Lines 367-372
_PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn,
Link Here
|
| 367 |
|
375 |
|
| 368 |
result = response->r.BindResponse.response.resultcode; |
376 |
result = response->r.BindResponse.response.resultcode; |
| 369 |
|
377 |
|
|
|
378 |
if (result == LDAP_INVALID_CREDENTIALS) { |
| 379 |
/* |
| 380 |
try a second time on invalid credentials, to |
| 381 |
give the user a chance to re-enter the |
| 382 |
password and to handle the case where our |
| 383 |
kerberos ticket is invalid as the server |
| 384 |
password has changed |
| 385 |
*/ |
| 386 |
const char *principal; |
| 387 |
|
| 388 |
principal = gensec_get_target_principal(conn->gensec); |
| 389 |
if (principal == NULL) { |
| 390 |
const char *hostname = gensec_get_target_hostname(conn->gensec); |
| 391 |
const char *service = gensec_get_target_service(conn->gensec); |
| 392 |
if (hostname != NULL && service != NULL) { |
| 393 |
principal = talloc_asprintf(tmp_ctx, "%s/%s", service, hostname); |
| 394 |
} |
| 395 |
} |
| 396 |
|
| 397 |
if (cli_credentials_failed_kerberos_login(creds, principal, &logon_retries) || |
| 398 |
cli_credentials_wrong_password(creds)) { |
| 399 |
/* |
| 400 |
destroy our gensec session and loop |
| 401 |
back up to the top to retry, |
| 402 |
offering the user a chance to enter |
| 403 |
new credentials, or get a new ticket |
| 404 |
if using kerberos |
| 405 |
*/ |
| 406 |
talloc_free(conn->gensec); |
| 407 |
conn->gensec = NULL; |
| 408 |
goto try_logon_again; |
| 409 |
} |
| 410 |
} |
| 411 |
|
| 370 |
if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { |
412 |
if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { |
| 371 |
status = ldap_check_response(conn, |
413 |
status = ldap_check_response(conn, |
| 372 |
&response->r.BindResponse.response); |
414 |
&response->r.BindResponse.response); |
| 373 |
- |
|
|
| 374 |
change |
415 |
change |
| 375 |
-- |
|
|
| 376 |
testprogs/blackbox/test_chgdcpass.sh | 25 ++++++++++++++++++------- |
416 |
testprogs/blackbox/test_chgdcpass.sh | 25 ++++++++++++++++++------- |
| 377 |
1 file changed, 18 insertions(+), 7 deletions(-) |
417 |
1 file changed, 18 insertions(+), 7 deletions(-) |