Changeset 988 for vendor/current/source4/auth/ntlm
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/auth/ntlm
- Files:
-
- 1 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/auth/ntlm/auth.c
r740 r988 27 27 #include "param/param.h" 28 28 #include "dsdb/samdb/samdb.h" 29 29 #include "libcli/wbclient/wbclient.h" 30 #include "lib/util/samba_modules.h" 31 #include "auth/credentials/credentials.h" 32 #include "system/kerberos.h" 33 #include "auth/kerberos/kerberos.h" 34 #include "auth/kerberos/kerberos_util.h" 35 #include "libds/common/roles.h" 36 37 static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_context, 38 TALLOC_CTX *mem_ctx, 39 void *server_returned_info, 40 const char *original_user_name, 41 uint32_t session_info_flags, 42 struct auth_session_info **session_info); 30 43 31 44 /*************************************************************************** 32 45 Set a fixed challenge 33 46 ***************************************************************************/ 34 _PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth _context *auth_ctx, const uint8_t chal[8], const char *set_by)47 _PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by) 35 48 { 36 49 auth_ctx->challenge.set_by = talloc_strdup(auth_ctx, set_by); … … 41 54 42 55 return NT_STATUS_OK; 43 }44 45 /***************************************************************************46 Set a fixed challenge47 ***************************************************************************/48 _PUBLIC_ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx)49 {50 return auth_ctx->challenge.may_be_modified;51 56 } 52 57 … … 55 60 Returns a const char of length 8 bytes. 56 61 ****************************************************************************/ 57 _PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]) 58 { 59 NTSTATUS nt_status; 60 struct auth_method_context *method; 62 _PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8]) 63 { 61 64 62 65 if (auth_ctx->challenge.data.length == 8) { … … 67 70 } 68 71 69 for (method = auth_ctx->methods; method; method = method->next) {70 nt_status = method->ops->get_challenge(method, auth_ctx, chal);71 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {72 continue;73 }74 75 NT_STATUS_NOT_OK_RETURN(nt_status);76 77 auth_ctx->challenge.data = data_blob_talloc(auth_ctx, chal, 8);78 NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data);79 auth_ctx->challenge.set_by = method->ops->name;80 81 break;82 }83 84 72 if (!auth_ctx->challenge.set_by) { 85 73 generate_random_buffer(chal, 8); … … 88 76 NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data); 89 77 auth_ctx->challenge.set_by = "random"; 90 91 auth_ctx->challenge.may_be_modified = true;92 78 } 93 79 … … 104 90 Supply either a principal or a DN 105 91 ****************************************************************************/ 106 _PUBLIC_ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, 107 struct auth_context *auth_ctx, 108 const char *principal, 109 struct ldb_dn *user_dn, 110 struct auth_user_info_dc **user_info_dc) 92 static NTSTATUS auth_generate_session_info_principal(struct auth4_context *auth_ctx, 93 TALLOC_CTX *mem_ctx, 94 const char *principal, 95 struct ldb_dn *user_dn, 96 uint32_t session_info_flags, 97 struct auth_session_info **session_info) 111 98 { 112 99 NTSTATUS nt_status; 113 100 struct auth_method_context *method; 101 struct auth_user_info_dc *user_info_dc; 114 102 115 103 for (method = auth_ctx->methods; method; method = method->next) { … … 118 106 } 119 107 120 nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, user_info_dc);108 nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, &user_info_dc); 121 109 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { 122 110 continue; 123 111 } 112 if (!NT_STATUS_IS_OK(nt_status)) { 113 return nt_status; 114 } 115 116 nt_status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx, 117 user_info_dc, 118 user_info_dc->info->account_name, 119 session_info_flags, session_info); 120 talloc_free(user_info_dc); 124 121 125 122 return nt_status; … … 156 153 **/ 157 154 158 _PUBLIC_ NTSTATUS auth_check_password(struct auth _context *auth_ctx,155 _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx, 159 156 TALLOC_CTX *mem_ctx, 160 157 const struct auth_usersupplied_info *user_info, … … 188 185 } 189 186 187 _PUBLIC_ NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx, 188 TALLOC_CTX *mem_ctx, 189 const struct auth_usersupplied_info *user_info, 190 void **server_returned_info, 191 DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 192 { 193 struct auth_user_info_dc *user_info_dc; 194 NTSTATUS status = auth_check_password(auth_ctx, mem_ctx, user_info, &user_info_dc); 195 196 if (NT_STATUS_IS_OK(status)) { 197 *server_returned_info = user_info_dc; 198 199 if (user_session_key) { 200 DEBUG(10, ("Got NT session key of length %u\n", 201 (unsigned)user_info_dc->user_session_key.length)); 202 *user_session_key = user_info_dc->user_session_key; 203 talloc_steal(mem_ctx, user_session_key->data); 204 user_info_dc->user_session_key = data_blob_null; 205 } 206 207 if (lm_session_key) { 208 DEBUG(10, ("Got LM session key of length %u\n", 209 (unsigned)user_info_dc->lm_session_key.length)); 210 *lm_session_key = user_info_dc->lm_session_key; 211 talloc_steal(mem_ctx, lm_session_key->data); 212 user_info_dc->lm_session_key = data_blob_null; 213 } 214 } 215 216 return status; 217 } 218 190 219 struct auth_check_password_state { 191 struct auth _context *auth_ctx;220 struct auth4_context *auth_ctx; 192 221 const struct auth_usersupplied_info *user_info; 193 222 struct auth_user_info_dc *user_info_dc; … … 226 255 _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, 227 256 struct tevent_context *ev, 228 struct auth _context *auth_ctx,257 struct auth4_context *auth_ctx, 229 258 const struct auth_usersupplied_info *user_info) 230 259 { … … 252 281 253 282 if (!user_info->mapped_state) { 254 nt_status = map_user_info( req, lpcfg_workgroup(auth_ctx->lp_ctx),283 nt_status = map_user_info(auth_ctx->sam_ctx, req, lpcfg_workgroup(auth_ctx->lp_ctx), 255 284 user_info, &user_info_tmp); 256 285 if (tevent_req_nterror(req, nt_status)) { … … 315 344 for (method=state->auth_ctx->methods; method; method = method->next) { 316 345 346 if (state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY 347 && !(method->ops->flags & AUTH_METHOD_LOCAL_SAM)) { 348 continue; 349 } 350 317 351 /* we fill in state->method here so debug messages in 318 352 the callers know which method failed */ … … 343 377 344 378 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { 345 /* don't expose the NT_STATUS_NOT_IMPLEMENTED 346 internals */ 347 status = NT_STATUS_NO_SUCH_USER; 379 if (!(state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY)) { 380 /* don't expose the NT_STATUS_NOT_IMPLEMENTED 381 * internals, except when the caller is only probing 382 * one method, as they may do the fallback 383 */ 384 status = NT_STATUS_NO_SUCH_USER; 385 } 348 386 } 349 387 … … 407 445 } 408 446 447 /* Wrapper because we don't want to expose all callers to needing to 448 * know that session_info is generated from the main ldb, and because 449 * we need to break a depenency loop between the DCE/RPC layer and the 450 * generation of unix tokens via IRPC */ 451 static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_context, 452 TALLOC_CTX *mem_ctx, 453 void *server_returned_info, 454 const char *original_user_name, 455 uint32_t session_info_flags, 456 struct auth_session_info **session_info) 457 { 458 NTSTATUS status; 459 struct auth_user_info_dc *user_info_dc = talloc_get_type_abort(server_returned_info, struct auth_user_info_dc); 460 461 if (user_info_dc->info->authenticated) { 462 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED; 463 } 464 465 status = auth_generate_session_info(mem_ctx, auth_context->lp_ctx, 466 auth_context->sam_ctx, user_info_dc, 467 session_info_flags, session_info); 468 if (!NT_STATUS_IS_OK(status)) { 469 return status; 470 } 471 472 if ((session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN) 473 && NT_STATUS_IS_OK(status)) { 474 status = auth_session_info_fill_unix(auth_context->event_ctx, 475 auth_context->lp_ctx, 476 original_user_name, *session_info); 477 if (!NT_STATUS_IS_OK(status)) { 478 TALLOC_FREE(*session_info); 479 } 480 } 481 return status; 482 } 483 409 484 /* Wrapper because we don't want to expose all callers to needing to 410 * know that session_info is generated from the main ldb */ 411 static NTSTATUS auth_generate_session_info_wrapper(TALLOC_CTX *mem_ctx, 412 struct auth_context *auth_context, 413 struct auth_user_info_dc *user_info_dc, 414 uint32_t session_info_flags, 415 struct auth_session_info **session_info) 416 { 417 return auth_generate_session_info(mem_ctx, auth_context->lp_ctx, 418 auth_context->sam_ctx, user_info_dc, 419 session_info_flags, session_info); 485 * know anything about the PAC or auth subsystem internal structures 486 * before we output a struct auth session_info */ 487 static NTSTATUS auth_generate_session_info_pac(struct auth4_context *auth_ctx, 488 TALLOC_CTX *mem_ctx, 489 struct smb_krb5_context *smb_krb5_context, 490 DATA_BLOB *pac_blob, 491 const char *principal_name, 492 const struct tsocket_address *remote_address, 493 uint32_t session_info_flags, 494 struct auth_session_info **session_info) 495 { 496 NTSTATUS status; 497 struct auth_user_info_dc *user_info_dc; 498 TALLOC_CTX *tmp_ctx; 499 500 if (!pac_blob) { 501 return auth_generate_session_info_principal(auth_ctx, mem_ctx, principal_name, 502 NULL, session_info_flags, session_info); 503 } 504 505 tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context"); 506 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); 507 508 status = kerberos_pac_blob_to_user_info_dc(tmp_ctx, 509 *pac_blob, 510 smb_krb5_context->krb5_context, 511 &user_info_dc, NULL, NULL); 512 if (!NT_STATUS_IS_OK(status)) { 513 talloc_free(tmp_ctx); 514 return status; 515 } 516 517 if (user_info_dc->info->authenticated) { 518 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED; 519 } 520 521 status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx, 522 user_info_dc, 523 user_info_dc->info->account_name, 524 session_info_flags, session_info); 525 talloc_free(tmp_ctx); 526 return status; 420 527 } 421 528 … … 424 531 - Allow the caller to specify the methods to use, including optionally the SAM to use 425 532 ***************************************************************************/ 426 _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char * *methods,533 _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char * const *methods, 427 534 struct tevent_context *ev, 428 struct messaging_context *msg,535 struct imessaging_context *msg, 429 536 struct loadparm_context *lp_ctx, 430 537 struct ldb_context *sam_ctx, 431 struct auth _context **auth_ctx)538 struct auth4_context **auth_ctx) 432 539 { 433 540 int i; 434 struct auth _context *ctx;541 struct auth4_context *ctx; 435 542 436 543 auth4_init(); … … 441 548 } 442 549 443 ctx = talloc (mem_ctx, struct auth_context);550 ctx = talloc_zero(mem_ctx, struct auth4_context); 444 551 NT_STATUS_HAVE_NO_MEMORY(ctx); 445 ctx->challenge.set_by = NULL;446 ctx->challenge.may_be_modified = false;447 552 ctx->challenge.data = data_blob(NULL, 0); 448 553 ctx->methods = NULL; … … 471 576 method->auth_ctx = ctx; 472 577 method->depth = i; 473 DLIST_ADD_END(ctx->methods, method, struct auth_method_context *); 474 } 475 476 ctx->check_password = auth_check_password; 477 ctx->get_challenge = auth_get_challenge; 478 ctx->set_challenge = auth_context_set_challenge; 479 ctx->challenge_may_be_modified = auth_challenge_may_be_modified; 480 ctx->get_user_info_dc_principal = auth_get_user_info_dc_principal; 578 DLIST_ADD_END(ctx->methods, method); 579 } 580 581 ctx->check_ntlm_password = auth_check_password_wrapper; 582 ctx->get_ntlm_challenge = auth_get_challenge; 583 ctx->set_ntlm_challenge = auth_context_set_challenge; 481 584 ctx->generate_session_info = auth_generate_session_info_wrapper; 585 ctx->generate_session_info_pac = auth_generate_session_info_pac; 482 586 483 587 *auth_ctx = ctx; … … 488 592 const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 489 593 { 490 const char **auth_methods = NULL; 594 char **auth_methods = NULL; 595 491 596 switch (lpcfg_server_role(lp_ctx)) { 492 597 case ROLE_STANDALONE: 493 auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "standalone", NULL);598 auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain", NULL); 494 599 break; 495 600 case ROLE_DOMAIN_MEMBER: 496 auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "member server", NULL);601 auth_methods = str_list_make(mem_ctx, "anonymous sam winbind", NULL); 497 602 break; 498 case ROLE_DOMAIN_CONTROLLER: 499 auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "domain controller", NULL); 603 case ROLE_DOMAIN_BDC: 604 case ROLE_DOMAIN_PDC: 605 case ROLE_ACTIVE_DIRECTORY_DC: 606 auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain winbind", NULL); 500 607 break; 501 608 } 502 return auth_methods;609 return discard_const_p(const char *, auth_methods); 503 610 } 504 611 … … 509 616 _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, 510 617 struct tevent_context *ev, 511 struct messaging_context *msg,618 struct imessaging_context *msg, 512 619 struct loadparm_context *lp_ctx, 513 struct auth _context **auth_ctx)620 struct auth4_context **auth_ctx) 514 621 { 515 622 NTSTATUS status; … … 525 632 } 526 633 status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg, lp_ctx, NULL, auth_ctx); 527 talloc_free(tmp_ctx);528 return status;529 }530 531 /* Create an auth context from an open LDB.532 533 This allows us not to re-open the LDB when we need to do a some authentication logic (such as tokenGroups)534 535 */536 NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx)537 {538 NTSTATUS status;539 const char **auth_methods;540 struct loadparm_context *lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"), struct loadparm_context);541 struct tevent_context *ev = ldb_get_event_context(ldb);542 543 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);544 if (!tmp_ctx) {545 return NT_STATUS_NO_MEMORY;546 }547 548 auth_methods = auth_methods_from_lp(tmp_ctx, lp_ctx);549 if (!auth_methods) {550 return NT_STATUS_INVALID_PARAMETER;551 }552 status = auth_context_create_methods(mem_ctx, auth_methods, ev, NULL, lp_ctx, ldb, auth_ctx);553 634 talloc_free(tmp_ctx); 554 635 return status; … … 621 702 { 622 703 static const struct auth_critical_sizes critical_sizes = { 623 AUTH _INTERFACE_VERSION,704 AUTH4_INTERFACE_VERSION, 624 705 sizeof(struct auth_operations), 625 706 sizeof(struct auth_method_context), 626 sizeof(struct auth _context),707 sizeof(struct auth4_context), 627 708 sizeof(struct auth_usersupplied_info), 628 709 sizeof(struct auth_user_info_dc) -
vendor/current/source4/auth/ntlm/auth_anonymous.c
r740 r988 25 25 #include "param/param.h" 26 26 27 _PUBLIC_ NTSTATUS auth4_anonymous_init(void); 28 27 29 /** 28 30 * Return a anonymous logon for anonymous users (username = "") … … 38 40 if (user_info->client.account_name && *user_info->client.account_name) { 39 41 return NT_STATUS_NOT_IMPLEMENTED; 42 } 43 44 switch (user_info->password_state) { 45 case AUTH_PASSWORD_PLAIN: 46 if (user_info->password.plaintext != NULL && 47 strlen(user_info->password.plaintext) > 0) 48 { 49 return NT_STATUS_NOT_IMPLEMENTED; 50 } 51 break; 52 case AUTH_PASSWORD_HASH: 53 if (user_info->password.hash.lanman != NULL) { 54 return NT_STATUS_NOT_IMPLEMENTED; 55 } 56 if (user_info->password.hash.nt != NULL) { 57 return NT_STATUS_NOT_IMPLEMENTED; 58 } 59 break; 60 case AUTH_PASSWORD_RESPONSE: 61 if (user_info->password.response.lanman.length == 1) { 62 if (user_info->password.response.lanman.data[0] != '\0') { 63 return NT_STATUS_NOT_IMPLEMENTED; 64 } 65 } else if (user_info->password.response.lanman.length > 1) { 66 return NT_STATUS_NOT_IMPLEMENTED; 67 } 68 if (user_info->password.response.nt.length > 0) { 69 return NT_STATUS_NOT_IMPLEMENTED; 70 } 71 break; 40 72 } 41 73 … … 60 92 static const struct auth_operations anonymous_auth_ops = { 61 93 .name = "anonymous", 62 .get_challenge = auth_get_challenge_not_implemented,63 94 .want_check = anonymous_want_check, 64 95 .check_password = anonymous_check_password 65 96 }; 66 97 67 _PUBLIC_ NTSTATUS auth _anonymous_init(void)98 _PUBLIC_ NTSTATUS auth4_anonymous_init(void) 68 99 { 69 100 NTSTATUS ret; -
vendor/current/source4/auth/ntlm/auth_developer.c
r740 r988 24 24 #include "auth/ntlm/auth_proto.h" 25 25 #include "libcli/security/security.h" 26 27 _PUBLIC_ NTSTATUS auth4_developer_init(void); 26 28 27 29 static NTSTATUS name_to_ntstatus_want_check(struct auth_method_context *ctx, … … 132 134 static const struct auth_operations name_to_ntstatus_auth_ops = { 133 135 .name = "name_to_ntstatus", 134 .get_challenge = auth_get_challenge_not_implemented,135 136 .want_check = name_to_ntstatus_want_check, 136 137 .check_password = name_to_ntstatus_check_password 137 138 }; 138 139 139 /** 140 * Return a 'fixed' challenge instead of a variable one. 141 * 142 * The idea of this function is to make packet snifs consistant 143 * with a fixed challenge, so as to aid debugging. 144 * 145 * This module is of no value to end-users. 146 * 147 * This module does not actually authenticate the user, but 148 * just pretenteds to need a specified challenge. 149 * This module removes *all* security from the challenge-response system 150 * 151 * @return NT_STATUS_UNSUCCESSFUL 152 **/ 153 static NTSTATUS fixed_challenge_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]) 154 { 155 const char *challenge = "I am a teapot"; 156 157 memcpy(chal, challenge, 8); 158 159 return NT_STATUS_OK; 160 } 161 162 static NTSTATUS fixed_challenge_want_check(struct auth_method_context *ctx, 163 TALLOC_CTX *mem_ctx, 164 const struct auth_usersupplied_info *user_info) 165 { 166 /* don't handle any users */ 167 return NT_STATUS_NOT_IMPLEMENTED; 168 } 169 170 static NTSTATUS fixed_challenge_check_password(struct auth_method_context *ctx, 171 TALLOC_CTX *mem_ctx, 172 const struct auth_usersupplied_info *user_info, 173 struct auth_user_info_dc **_user_info_dc) 174 { 175 /* don't handle any users */ 176 return NT_STATUS_NO_SUCH_USER; 177 } 178 179 static const struct auth_operations fixed_challenge_auth_ops = { 180 .name = "fixed_challenge", 181 .get_challenge = fixed_challenge_get_challenge, 182 .want_check = fixed_challenge_want_check, 183 .check_password = fixed_challenge_check_password 184 }; 185 186 _PUBLIC_ NTSTATUS auth_developer_init(void) 140 _PUBLIC_ NTSTATUS auth4_developer_init(void) 187 141 { 188 142 NTSTATUS ret; … … 194 148 } 195 149 196 ret = auth_register(&fixed_challenge_auth_ops);197 if (!NT_STATUS_IS_OK(ret)) {198 DEBUG(0,("Failed to register 'fixed_challenge' auth backend!\n"));199 return ret;200 }201 202 150 return ret; 203 151 } -
vendor/current/source4/auth/ntlm/auth_sam.c
r740 r988 34 34 #include "librpc/gen_ndr/ndr_irpc_c.h" 35 35 #include "lib/messaging/irpc.h" 36 #include "libcli/auth/libcli_auth.h" 37 #include "libds/common/roles.h" 38 39 NTSTATUS auth_sam_init(void); 36 40 37 41 extern const char *user_attrs[]; … … 71 75 the lanman and NT responses. 72 76 ****************************************************************************/ 73 static NTSTATUS authsam_password_ok(struct auth _context *auth_context,77 static NTSTATUS authsam_password_ok(struct auth4_context *auth_context, 74 78 TALLOC_CTX *mem_ctx, 75 79 uint16_t acct_flags, … … 126 130 } 127 131 128 if (user_sess_key && user_sess_key->data) {129 talloc_steal(auth_context, user_sess_key->data);130 }131 if (lm_sess_key && lm_sess_key->data) {132 talloc_steal(auth_context, lm_sess_key->data);133 }134 135 132 return NT_STATUS_OK; 136 133 } … … 141 138 REPL_SECRET getncchanges extended op to fetch the users secrets 142 139 */ 143 static void auth_sam_trigger_repl_secret( TALLOC_CTX *mem_ctx, struct auth_context *auth_context,140 static void auth_sam_trigger_repl_secret(struct auth4_context *auth_context, 144 141 struct ldb_dn *user_dn) 145 142 { … … 147 144 struct drepl_trigger_repl_secret r; 148 145 struct tevent_req *req; 149 150 irpc_handle = irpc_binding_handle_by_name(mem_ctx, auth_context->msg_ctx, 146 TALLOC_CTX *tmp_ctx; 147 148 tmp_ctx = talloc_new(auth_context); 149 if (tmp_ctx == NULL) { 150 return; 151 } 152 153 irpc_handle = irpc_binding_handle_by_name(tmp_ctx, auth_context->msg_ctx, 151 154 "dreplsrv", 152 155 &ndr_table_irpc); 153 156 if (irpc_handle == NULL) { 154 157 DEBUG(1,(__location__ ": Unable to get binding handle for dreplsrv\n")); 158 TALLOC_FREE(tmp_ctx); 155 159 return; 156 160 } … … 158 162 r.in.user_dn = ldb_dn_get_linearized(user_dn); 159 163 160 req = dcerpc_drepl_trigger_repl_secret_r_send(mem_ctx, 164 /* 165 * This seem to rely on the current IRPC implementation, 166 * which delivers the message in the _send function. 167 * 168 * TODO: we need a ONE_WAY IRPC handle and register 169 * a callback and wait for it to be triggered! 170 */ 171 req = dcerpc_drepl_trigger_repl_secret_r_send(tmp_ctx, 161 172 auth_context->event_ctx, 162 173 irpc_handle, … … 165 176 /* we aren't interested in a reply */ 166 177 talloc_free(req); 167 talloc_free(irpc_handle); 168 } 169 170 171 static NTSTATUS authsam_authenticate(struct auth_context *auth_context, 172 TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, 173 struct ldb_dn *domain_dn, 174 struct ldb_message *msg, 175 const struct auth_usersupplied_info *user_info, 176 DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) 177 { 178 struct samr_Password *lm_pwd, *nt_pwd; 178 TALLOC_FREE(tmp_ctx); 179 } 180 181 182 /* 183 * Check that a password is OK, and update badPwdCount if required. 184 */ 185 186 static NTSTATUS authsam_password_check_and_record(struct auth4_context *auth_context, 187 TALLOC_CTX *mem_ctx, 188 struct ldb_dn *domain_dn, 189 struct ldb_message *msg, 190 uint16_t acct_flags, 191 const struct auth_usersupplied_info *user_info, 192 DATA_BLOB *user_sess_key, 193 DATA_BLOB *lm_sess_key) 194 { 179 195 NTSTATUS nt_status; 180 181 uint16_t acct_flags = samdb_result_acct_flags(auth_context->sam_ctx, mem_ctx, msg, domain_dn); 182 183 /* Quit if the account was locked out. */ 184 if (acct_flags & ACB_AUTOLOCK) { 185 DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", 186 user_info->mapped.account_name)); 187 return NT_STATUS_ACCOUNT_LOCKED_OUT; 188 } 189 190 /* You can only do an interactive login to normal accounts */ 191 if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) { 192 if (!(acct_flags & ACB_NORMAL)) { 193 return NT_STATUS_NO_SUCH_USER; 194 } 195 } 196 197 nt_status = samdb_result_passwords(mem_ctx, auth_context->lp_ctx, msg, &lm_pwd, &nt_pwd); 198 NT_STATUS_NOT_OK_RETURN(nt_status); 196 NTSTATUS auth_status; 197 TALLOC_CTX *tmp_ctx; 198 int i, ret; 199 int history_len = 0; 200 struct ldb_context *sam_ctx = auth_context->sam_ctx; 201 const char * const attrs[] = { "pwdHistoryLength", NULL }; 202 struct ldb_message *dom_msg; 203 struct samr_Password *lm_pwd; 204 struct samr_Password *nt_pwd; 205 206 tmp_ctx = talloc_new(mem_ctx); 207 if (tmp_ctx == NULL) { 208 return NT_STATUS_NO_MEMORY; 209 } 210 211 /* 212 * This call does more than what it appears to do, it also 213 * checks for the account lockout. 214 * 215 * It is done here so that all parts of Samba that read the 216 * password refuse to even operate on it if the account is 217 * locked out, to avoid mistakes like CVE-2013-4496. 218 */ 219 nt_status = samdb_result_passwords(tmp_ctx, auth_context->lp_ctx, 220 msg, &lm_pwd, &nt_pwd); 221 if (!NT_STATUS_IS_OK(nt_status)) { 222 TALLOC_FREE(tmp_ctx); 223 return nt_status; 224 } 199 225 200 226 if (lm_pwd == NULL && nt_pwd == NULL) { 201 227 bool am_rodc; 202 228 if (samdb_rodc(auth_context->sam_ctx, &am_rodc) == LDB_SUCCESS && am_rodc) { 203 /* we don't have passwords for this 229 /* 230 * we don't have passwords for this 204 231 * account. We are an RODC, and this account 205 232 * may be one for which we either are denied … … 212 239 * replicate the secrets for this account. 213 240 */ 214 auth_sam_trigger_repl_secret(mem_ctx, auth_context, msg->dn); 241 auth_sam_trigger_repl_secret(auth_context, msg->dn); 242 TALLOC_FREE(tmp_ctx); 215 243 return NT_STATUS_NOT_IMPLEMENTED; 216 244 } 217 245 } 218 246 219 nt_status = authsam_password_ok(auth_context, mem_ctx, 220 acct_flags, lm_pwd, nt_pwd, 221 user_info, user_sess_key, lm_sess_key); 222 NT_STATUS_NOT_OK_RETURN(nt_status); 223 224 nt_status = authsam_account_ok(mem_ctx, auth_context->sam_ctx, 247 auth_status = authsam_password_ok(auth_context, tmp_ctx, 248 acct_flags, 249 lm_pwd, nt_pwd, 250 user_info, 251 user_sess_key, lm_sess_key); 252 if (NT_STATUS_IS_OK(auth_status)) { 253 if (user_sess_key->data) { 254 talloc_steal(mem_ctx, user_sess_key->data); 255 } 256 if (lm_sess_key->data) { 257 talloc_steal(mem_ctx, lm_sess_key->data); 258 } 259 TALLOC_FREE(tmp_ctx); 260 return NT_STATUS_OK; 261 } 262 *user_sess_key = data_blob_null; 263 *lm_sess_key = data_blob_null; 264 265 if (!NT_STATUS_EQUAL(auth_status, NT_STATUS_WRONG_PASSWORD)) { 266 TALLOC_FREE(tmp_ctx); 267 return auth_status; 268 } 269 270 /* 271 * We only continue if this was a wrong password 272 * and we'll always return NT_STATUS_WRONG_PASSWORD 273 * no matter what error happens. 274 */ 275 276 /* pull the domain password property attributes */ 277 ret = dsdb_search_one(sam_ctx, tmp_ctx, &dom_msg, domain_dn, LDB_SCOPE_BASE, 278 attrs, 0, "objectClass=domain"); 279 if (ret == LDB_SUCCESS) { 280 history_len = ldb_msg_find_attr_as_uint(dom_msg, "pwdHistoryLength", 0); 281 } else if (ret == LDB_ERR_NO_SUCH_OBJECT) { 282 DEBUG(3,("Couldn't find domain %s: %s!\n", 283 ldb_dn_get_linearized(domain_dn), 284 ldb_errstring(sam_ctx))); 285 } else { 286 DEBUG(3,("error finding domain %s: %s!\n", 287 ldb_dn_get_linearized(domain_dn), 288 ldb_errstring(sam_ctx))); 289 } 290 291 for (i = 1; i < MIN(history_len, 3); i++) { 292 static const struct samr_Password zero_hash; 293 struct samr_Password zero_string_hash; 294 struct samr_Password zero_string_des_hash; 295 struct samr_Password *nt_history_pwd = NULL; 296 struct samr_Password *lm_history_pwd = NULL; 297 NTTIME pwdLastSet; 298 struct timeval tv_now; 299 NTTIME now; 300 int allowed_period_mins; 301 NTTIME allowed_period; 302 303 nt_status = samdb_result_passwords_from_history(tmp_ctx, 304 auth_context->lp_ctx, 305 msg, i, 306 &lm_history_pwd, 307 &nt_history_pwd); 308 if (!NT_STATUS_IS_OK(nt_status)) { 309 /* 310 * If we don't find element 'i' we won't find 311 * 'i+1' ... 312 */ 313 break; 314 } 315 316 /* 317 * We choose to avoid any issues 318 * around different LM and NT history 319 * lengths by only checking the NT 320 * history 321 */ 322 if (nt_history_pwd == NULL) { 323 /* 324 * If we don't find element 'i' we won't find 325 * 'i+1' ... 326 */ 327 break; 328 } 329 330 /* Skip over all-zero hashes in the history */ 331 if (memcmp(nt_history_pwd->hash, zero_hash.hash, 332 sizeof(zero_hash.hash)) == 0) { 333 continue; 334 } 335 336 /* 337 * This looks odd, but the password_hash module writes this in if 338 * (somehow) we didn't have an old NT hash 339 */ 340 341 E_md4hash("", zero_string_hash.hash); 342 if (memcmp(nt_history_pwd->hash, zero_string_hash.hash, 16) == 0) { 343 continue; 344 } 345 346 E_deshash("", zero_string_des_hash.hash); 347 if (!lm_history_pwd || memcmp(lm_history_pwd->hash, zero_string_des_hash.hash, 16) == 0) { 348 lm_history_pwd = NULL; 349 } 350 351 auth_status = authsam_password_ok(auth_context, tmp_ctx, 352 acct_flags, 353 lm_history_pwd, 354 nt_history_pwd, 355 user_info, 356 user_sess_key, 357 lm_sess_key); 358 if (!NT_STATUS_IS_OK(auth_status)) { 359 /* 360 * If this was not a correct password, try the next 361 * one from the history 362 */ 363 *user_sess_key = data_blob_null; 364 *lm_sess_key = data_blob_null; 365 continue; 366 } 367 368 if (i != 1) { 369 /* 370 * The authentication was OK, but not against 371 * the previous password, which is stored at index 1. 372 * 373 * We just return the original wrong password. 374 * This skips the update of the bad pwd count, 375 * because this is almost certainly user error 376 * (or automatic login on a computer using a cached 377 * password from before the password change), 378 * not an attack. 379 */ 380 TALLOC_FREE(tmp_ctx); 381 return NT_STATUS_WRONG_PASSWORD; 382 } 383 384 if (user_info->password_state != AUTH_PASSWORD_RESPONSE) { 385 /* 386 * The authentication was OK against the previous password, 387 * but it's not a NTLM network authentication. 388 * 389 * We just return the original wrong password. 390 * This skips the update of the bad pwd count, 391 * because this is almost certainly user error 392 * (or automatic login on a computer using a cached 393 * password from before the password change), 394 * not an attack. 395 */ 396 TALLOC_FREE(tmp_ctx); 397 return NT_STATUS_WRONG_PASSWORD; 398 } 399 400 /* 401 * If the password was OK, it's a NTLM network authentication 402 * and it was the previous password. 403 * 404 * Now we see if it is within the grace period, 405 * so that we don't break cached sessions on other computers 406 * before the user can lock and unlock their other screens 407 * (resetting their cached password). 408 * 409 * See http://support.microsoft.com/kb/906305 410 * OldPasswordAllowedPeriod ("old password allowed period") 411 * is specified in minutes. The default is 60. 412 */ 413 allowed_period_mins = lpcfg_old_password_allowed_period(auth_context->lp_ctx); 414 /* 415 * NTTIME uses 100ns units 416 */ 417 allowed_period = allowed_period_mins * 60 * 1000*1000*10; 418 pwdLastSet = samdb_result_nttime(msg, "pwdLastSet", 0); 419 tv_now = timeval_current(); 420 now = timeval_to_nttime(&tv_now); 421 422 if (now < pwdLastSet) { 423 /* 424 * time jump? 425 * 426 * We just return the original wrong password. 427 * This skips the update of the bad pwd count, 428 * because this is almost certainly user error 429 * (or automatic login on a computer using a cached 430 * password from before the password change), 431 * not an attack. 432 */ 433 TALLOC_FREE(tmp_ctx); 434 return NT_STATUS_WRONG_PASSWORD; 435 } 436 437 if ((now - pwdLastSet) >= allowed_period) { 438 /* 439 * The allowed period is over. 440 * 441 * We just return the original wrong password. 442 * This skips the update of the bad pwd count, 443 * because this is almost certainly user error 444 * (or automatic login on a computer using a cached 445 * password from before the password change), 446 * not an attack. 447 */ 448 TALLOC_FREE(tmp_ctx); 449 return NT_STATUS_WRONG_PASSWORD; 450 } 451 452 /* 453 * We finally allow the authentication with the 454 * previous password within the allowed period. 455 */ 456 if (user_sess_key->data) { 457 talloc_steal(mem_ctx, user_sess_key->data); 458 } 459 if (lm_sess_key->data) { 460 talloc_steal(mem_ctx, lm_sess_key->data); 461 } 462 463 TALLOC_FREE(tmp_ctx); 464 return auth_status; 465 } 466 467 /* 468 * If we are not in the allowed period or match an old password, 469 * we didn't return early. Now update the badPwdCount et al. 470 */ 471 nt_status = authsam_update_bad_pwd_count(auth_context->sam_ctx, 472 msg, domain_dn); 473 if (!NT_STATUS_IS_OK(nt_status)) { 474 /* 475 * We need to return the original 476 * NT_STATUS_WRONG_PASSWORD error, so there isn't 477 * anything more we can do than write something into 478 * the log 479 */ 480 DEBUG(0, ("Failed to note bad password for user [%s]: %s\n", 481 user_info->mapped.account_name, 482 nt_errstr(nt_status))); 483 } 484 485 TALLOC_FREE(tmp_ctx); 486 return NT_STATUS_WRONG_PASSWORD; 487 } 488 489 static NTSTATUS authsam_authenticate(struct auth4_context *auth_context, 490 TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, 491 struct ldb_dn *domain_dn, 492 struct ldb_message *msg, 493 const struct auth_usersupplied_info *user_info, 494 DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) 495 { 496 NTSTATUS nt_status; 497 bool interactive = (user_info->password_state == AUTH_PASSWORD_HASH); 498 uint16_t acct_flags = samdb_result_acct_flags(msg, NULL); 499 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 500 if (!tmp_ctx) { 501 return NT_STATUS_NO_MEMORY; 502 } 503 504 /* You can only do an interactive login to normal accounts */ 505 if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) { 506 if (!(acct_flags & ACB_NORMAL)) { 507 TALLOC_FREE(tmp_ctx); 508 return NT_STATUS_NO_SUCH_USER; 509 } 510 } 511 512 nt_status = authsam_password_check_and_record(auth_context, tmp_ctx, 513 domain_dn, msg, acct_flags, 514 user_info, 515 user_sess_key, lm_sess_key); 516 if (!NT_STATUS_IS_OK(nt_status)) { 517 TALLOC_FREE(tmp_ctx); 518 return nt_status; 519 } 520 521 nt_status = authsam_account_ok(tmp_ctx, auth_context->sam_ctx, 225 522 user_info->logon_parameters, 226 523 domain_dn, … … 229 526 user_info->mapped.account_name, 230 527 false, false); 231 528 if (!NT_STATUS_IS_OK(nt_status)) { 529 TALLOC_FREE(tmp_ctx); 530 return nt_status; 531 } 532 533 nt_status = authsam_logon_success_accounting(auth_context->sam_ctx, 534 msg, domain_dn, 535 interactive); 536 if (!NT_STATUS_IS_OK(nt_status)) { 537 TALLOC_FREE(tmp_ctx); 538 return nt_status; 539 } 540 541 if (user_sess_key && user_sess_key->data) { 542 talloc_steal(mem_ctx, user_sess_key->data); 543 } 544 if (lm_sess_key && lm_sess_key->data) { 545 talloc_steal(mem_ctx, lm_sess_key->data); 546 } 547 548 TALLOC_FREE(tmp_ctx); 232 549 return nt_status; 233 550 } … … 340 657 return NT_STATUS_OK; 341 658 342 case ROLE_ DOMAIN_CONTROLLER:659 case ROLE_ACTIVE_DIRECTORY_DC: 343 660 if (!is_local_name && !is_my_domain) { 344 661 DEBUG(6,("authsam_check_password: %s is not one of my local names or domain name (DC)\n", … … 356 673 /* Wrapper for the auth subsystem pointer */ 357 674 static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx, 358 struct auth _context *auth_context,675 struct auth4_context *auth_context, 359 676 const char *principal, 360 677 struct ldb_dn *user_dn, … … 366 683 static const struct auth_operations sam_ignoredomain_ops = { 367 684 .name = "sam_ignoredomain", 368 .get_challenge = auth_get_challenge_not_implemented,369 685 .want_check = authsam_ignoredomain_want_check, 370 686 .check_password = authsam_check_password_internals, 371 .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper 687 .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, 688 .flags = AUTH_METHOD_LOCAL_SAM 372 689 }; 373 690 374 691 static const struct auth_operations sam_ops = { 375 692 .name = "sam", 376 .get_challenge = auth_get_challenge_not_implemented,377 693 .want_check = authsam_want_check, 378 694 .check_password = authsam_check_password_internals, 379 .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper 695 .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, 696 .flags = AUTH_METHOD_LOCAL_SAM 380 697 }; 381 698 382 _PUBLIC_ NTSTATUS auth_sam_init(void) 699 _PUBLIC_ NTSTATUS auth4_sam_init(void); 700 _PUBLIC_ NTSTATUS auth4_sam_init(void) 383 701 { 384 702 NTSTATUS ret; -
vendor/current/source4/auth/ntlm/auth_simple.c
r740 r988 31 31 _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, 32 32 struct tevent_context *ev, 33 struct messaging_context *msg,33 struct imessaging_context *msg, 34 34 struct loadparm_context *lp_ctx, 35 35 const char *nt4_domain, … … 39 39 struct auth_session_info **session_info) 40 40 { 41 struct auth _context *auth_context;41 struct auth4_context *auth_context; 42 42 struct auth_usersupplied_info *user_info; 43 43 struct auth_user_info_dc *user_info_dc; … … 95 95 flags |= AUTH_SESSION_INFO_AUTHENTICATED; 96 96 } 97 nt_status = auth_context->generate_session_info(tmp_ctx, auth_context, 97 nt_status = auth_context->generate_session_info(auth_context, 98 tmp_ctx, 98 99 user_info_dc, 100 nt4_username, 99 101 flags, 100 102 session_info); -
vendor/current/source4/auth/ntlm/auth_unix.c
r740 r988 29 29 #include "param/param.h" 30 30 31 _PUBLIC_ NTSTATUS auth4_unix_init(void); 32 31 33 /* TODO: look at how to best fill in parms retrieveing a struct passwd info 32 34 * except in case USER_INFO_DONT_CHECK_UNIX_ACCOUNT is set … … 262 264 pam_error = pam_end(*pamh, 0); 263 265 if (pam_error != PAM_SUCCESS) { 264 /* no va ild pamh here, can we reliably call pam_strerror ? */266 /* no valid pamh here, can we reliably call pam_strerror ? */ 265 267 DEBUG(4,("smb_pam_start: clean up failed, pam_end gave error %d.\n", 266 268 pam_error)); … … 282 284 pam_error = pam_end(*pamh, 0); 283 285 if (pam_error != PAM_SUCCESS) { 284 /* no va ild pamh here, can we reliably call pam_strerror ? */286 /* no valid pamh here, can we reliably call pam_strerror ? */ 285 287 DEBUG(4,("smb_pam_start: clean up failed, pam_end gave error %d.\n", 286 288 pam_error)); … … 302 304 pam_error = pam_end(pamh, 0); 303 305 if (pam_error != PAM_SUCCESS) { 304 /* no va ild pamh here, can we reliably call pam_strerror ? */306 /* no valid pamh here, can we reliably call pam_strerror ? */ 305 307 DEBUG(4,("smb_pam_end: clean up failed, pam_end gave error %d.\n", 306 308 pam_error)); … … 512 514 bool ret; 513 515 514 #ifdef WITH_AFS 515 if (afs_auth(username, password)) 516 return NT_STATUS_OK; 517 #endif /* WITH_AFS */ 518 519 #ifdef WITH_DFS 520 if (dfs_auth(username, password)) 521 return NT_STATUS_OK; 522 #endif /* WITH_DFS */ 516 523 517 524 518 #ifdef OSF1_ENH_SEC … … 549 543 #endif /* ULTRIX_AUTH */ 550 544 551 #ifdef LINUX_BIGCRYPT 552 ret = (linux_bigcrypt(password, salt, crypted)); 553 if (ret) { 554 return NT_STATUS_OK; 555 } else { 556 return NT_STATUS_WRONG_PASSWORD; 557 } 558 #endif /* LINUX_BIGCRYPT */ 559 560 #if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS) 561 562 /* 563 * Some systems have bigcrypt in the C library but might not 564 * actually use it for the password hashes (HPUX 10.20) is 565 * a noteable example. So we try bigcrypt first, followed 566 * by crypt. 567 */ 568 569 if (strcmp(bigcrypt(password, salt), crypted) == 0) 570 return NT_STATUS_OK; 571 else 572 ret = (strcmp((char *)crypt(password, salt), crypted) == 0); 573 if (ret) { 574 return NT_STATUS_OK; 575 } else { 576 return NT_STATUS_WRONG_PASSWORD; 577 } 578 #else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */ 545 579 546 580 547 #ifdef HAVE_BIGCRYPT … … 598 565 } 599 566 #endif /* HAVE_CRYPT */ 600 #endif /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */601 567 } 602 568 … … 606 572 char *username; 607 573 char *password; 608 char *pwcopy;609 574 char *salt; 610 575 char *crypted; 611 576 struct passwd *pws; 612 577 NTSTATUS nt_status; 613 int level = lpcfg_passwordlevel(lp_ctx);614 578 615 579 *ret_passwd = NULL; … … 659 623 #endif 660 624 661 #ifdef HAVE_GETPRPWNAM662 {663 struct pr_passwd *pr_pw = getprpwnam(pws->pw_name);664 if (pr_pw && pr_pw->ufld.fd_encrypt) {665 crypted = talloc_strdup(ctx, pr_pw->ufld.fd_encrypt);666 NT_STATUS_HAVE_NO_MEMORY(crypted);667 }668 }669 #endif670 625 671 626 #ifdef HAVE_GETPWANAM … … 707 662 #endif 708 663 709 #if defined(HAVE_TRUNCATED_SALT)710 /* crypt on some platforms (HPUX in particular)711 won't work with more than 2 salt characters. */712 salt[2] = 0;713 #endif714 664 715 665 if (crypted[0] == '\0') { … … 736 686 } 737 687 738 if ( user_info->flags | USER_INFO_CASE_INSENSITIVE_PASSWORD) { 739 return nt_status; 740 } 741 742 /* if the password was given to us with mixed case then we don't 743 * need to proceed as we know it hasn't been case modified by the 744 * client */ 745 if (strhasupper(password) && strhaslower(password)) { 746 return nt_status; 747 } 748 749 /* make a copy of it */ 750 pwcopy = talloc_strdup(ctx, password); 751 if (!pwcopy) 752 return NT_STATUS_NO_MEMORY; 753 754 /* try all lowercase if it's currently all uppercase */ 755 if (strhasupper(pwcopy)) { 756 strlower(pwcopy); 757 nt_status = password_check(username, pwcopy, crypted, salt); 758 if NT_STATUS_IS_OK(nt_status) { 759 *ret_passwd = pws; 760 return nt_status; 761 } 762 } 763 764 /* give up? */ 765 if (level < 1) { 766 return NT_STATUS_WRONG_PASSWORD; 767 } 768 769 /* last chance - all combinations of up to level chars upper! */ 770 strlower(pwcopy); 771 772 #if 0 773 if (NT_STATUS_IS_OK(nt_status = string_combinations(pwcopy, password_check, level))) { 774 *ret_passwd = pws; 775 return nt_status; 776 } 777 #endif 688 /* we no longer try different case combinations here. The use 689 * of this code is now web auth, where trying different case 690 * combinations makes no sense 691 */ 692 778 693 return NT_STATUS_WRONG_PASSWORD; 779 694 } … … 833 748 static const struct auth_operations unix_ops = { 834 749 .name = "unix", 835 .get_challenge = auth_get_challenge_not_implemented,836 750 .want_check = authunix_want_check, 837 751 .check_password = authunix_check_password 838 752 }; 839 753 840 _PUBLIC_ NTSTATUS auth _unix_init(void)754 _PUBLIC_ NTSTATUS auth4_unix_init(void) 841 755 { 842 756 NTSTATUS ret; -
vendor/current/source4/auth/ntlm/auth_util.c
r740 r988 26 26 #include "libcli/auth/libcli_auth.h" 27 27 #include "param/param.h" 28 #include "auth/ntlm/auth_proto.h" 29 #include "librpc/gen_ndr/drsuapi.h" 30 #include "dsdb/samdb/samdb.h" 28 31 29 32 /* this default function can be used by mostly all backends … … 39 42 Create an auth_usersupplied_data structure after appropriate mapping. 40 43 ****************************************************************************/ 41 42 NTSTATUS map_user_info(TALLOC_CTX *mem_ctx, 44 static NTSTATUS map_user_info_cracknames(struct ldb_context *sam_ctx, 45 TALLOC_CTX *mem_ctx, 46 const char *default_domain, 47 const struct auth_usersupplied_info *user_info, 48 struct auth_usersupplied_info **user_info_mapped) 49 { 50 char *domain; 51 char *account_name; 52 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 53 WERROR werr; 54 struct drsuapi_DsNameInfo1 info1; 55 56 DEBUG(5,("map_user_info_cracknames: Mapping user [%s]\\[%s] from workstation [%s]\n", 57 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name)); 58 59 account_name = talloc_strdup(tmp_ctx, user_info->client.account_name); 60 if (!account_name) { 61 talloc_free(tmp_ctx); 62 return NT_STATUS_NO_MEMORY; 63 } 64 65 /* use cracknames to work out what domain is being 66 asked for */ 67 if (strchr_m(user_info->client.account_name, '@') != NULL) { 68 werr = DsCrackNameOneName(sam_ctx, tmp_ctx, 0, 69 DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, 70 DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, 71 user_info->client.account_name, 72 &info1); 73 if (!W_ERROR_IS_OK(werr)) { 74 DEBUG(2,("map_user_info: Failed cracknames of account '%s'\n", 75 user_info->client.account_name)); 76 talloc_free(tmp_ctx); 77 return werror_to_ntstatus(werr); 78 } 79 switch (info1.status) { 80 case DRSUAPI_DS_NAME_STATUS_OK: 81 break; 82 case DRSUAPI_DS_NAME_STATUS_NOT_FOUND: 83 DEBUG(2,("map_user_info: Cracknames of account '%s' -> NOT_FOUND\n", 84 user_info->client.account_name)); 85 talloc_free(tmp_ctx); 86 return NT_STATUS_NO_SUCH_USER; 87 case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY: 88 DEBUG(2,("map_user_info: Cracknames of account '%s' -> DOMAIN_ONLY\n", 89 user_info->client.account_name)); 90 talloc_free(tmp_ctx); 91 return NT_STATUS_NO_SUCH_USER; 92 case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE: 93 DEBUG(2,("map_user_info: Cracknames of account '%s' -> NOT_UNIQUE\n", 94 user_info->client.account_name)); 95 talloc_free(tmp_ctx); 96 return NT_STATUS_NO_SUCH_USER; 97 case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR: 98 DEBUG(2,("map_user_info: Cracknames of account '%s' -> RESOLVE_ERROR\n", 99 user_info->client.account_name)); 100 talloc_free(tmp_ctx); 101 return NT_STATUS_NO_SUCH_USER; 102 default: 103 DEBUG(2,("map_user_info: Cracknames of account '%s' -> unknown error %u\n", 104 user_info->client.account_name, info1.status)); 105 talloc_free(tmp_ctx); 106 return NT_STATUS_NO_SUCH_USER; 107 } 108 /* info1.result_name is in DOMAIN\username 109 * form, which we need to split up into the 110 * user_info_mapped structure 111 */ 112 domain = talloc_strdup(tmp_ctx, info1.result_name); 113 if (domain == NULL) { 114 talloc_free(tmp_ctx); 115 return NT_STATUS_NO_MEMORY; 116 } 117 account_name = strchr_m(domain, '\\'); 118 if (account_name == NULL) { 119 DEBUG(2,("map_user_info: Cracknames of account '%s' gave invalid result '%s'\n", 120 user_info->client.account_name, info1.result_name)); 121 talloc_free(tmp_ctx); 122 return NT_STATUS_NO_SUCH_USER; 123 } 124 *account_name = 0; 125 account_name = talloc_strdup(tmp_ctx, account_name+1); 126 if (account_name == NULL) { 127 talloc_free(tmp_ctx); 128 return NT_STATUS_NO_MEMORY; 129 } 130 } else { 131 char *domain_name; 132 if (user_info->client.domain_name && *user_info->client.domain_name) { 133 domain_name = talloc_asprintf(tmp_ctx, "%s\\", user_info->client.domain_name); 134 } else { 135 domain_name = talloc_strdup(tmp_ctx, default_domain); 136 } 137 if (domain_name == NULL) { 138 talloc_free(tmp_ctx); 139 return NT_STATUS_NO_MEMORY; 140 } 141 werr = DsCrackNameOneName(sam_ctx, mem_ctx, 0, 142 DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, 143 DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, 144 domain_name, 145 &info1); 146 if (!W_ERROR_IS_OK(werr)) { 147 DEBUG(2,("map_user_info: Failed cracknames of domain '%s'\n", 148 domain_name)); 149 talloc_free(tmp_ctx); 150 return werror_to_ntstatus(werr); 151 } 152 153 /* we use the account_name as-is, but get the 154 * domain name from cracknames if possible */ 155 account_name = talloc_strdup(mem_ctx, user_info->client.account_name); 156 if (account_name == NULL) { 157 talloc_free(tmp_ctx); 158 return NT_STATUS_NO_MEMORY; 159 } 160 161 switch (info1.status) { 162 case DRSUAPI_DS_NAME_STATUS_OK: 163 case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY: 164 domain = talloc_strdup(tmp_ctx, info1.result_name); 165 if (domain == NULL) { 166 talloc_free(tmp_ctx); 167 return NT_STATUS_NO_MEMORY; 168 } 169 if (domain[strlen_m(domain)-1] == '\\') { 170 domain[strlen_m(domain)-1] = 0; 171 } 172 break; 173 case DRSUAPI_DS_NAME_STATUS_NOT_FOUND: 174 /* the domain is unknown - use the 175 default domain */ 176 domain = talloc_strdup(tmp_ctx, default_domain); 177 break; 178 case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE: 179 DEBUG(2,("map_user_info: Cracknames of domain '%s' -> NOT_UNIQUE\n", 180 domain_name)); 181 talloc_free(tmp_ctx); 182 return NT_STATUS_NO_SUCH_USER; 183 case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR: 184 DEBUG(2,("map_user_info: Cracknames of domain '%s' -> RESOLVE_ERROR\n", 185 domain_name)); 186 talloc_free(tmp_ctx); 187 return NT_STATUS_NO_SUCH_USER; 188 default: 189 DEBUG(2,("map_user_info: Cracknames of account '%s' -> unknown error %u\n", 190 domain_name, info1.status)); 191 talloc_free(tmp_ctx); 192 return NT_STATUS_NO_SUCH_USER; 193 } 194 /* domain and account_name are filled in above */ 195 } 196 197 *user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info); 198 if (!*user_info_mapped) { 199 talloc_free(tmp_ctx); 200 return NT_STATUS_NO_MEMORY; 201 } 202 if (!talloc_reference(*user_info_mapped, user_info)) { 203 talloc_free(tmp_ctx); 204 return NT_STATUS_NO_MEMORY; 205 } 206 **user_info_mapped = *user_info; 207 (*user_info_mapped)->mapped_state = true; 208 (*user_info_mapped)->mapped.domain_name = talloc_strdup(*user_info_mapped, domain); 209 (*user_info_mapped)->mapped.account_name = talloc_strdup(*user_info_mapped, account_name); 210 talloc_free(tmp_ctx); 211 if (!(*user_info_mapped)->mapped.domain_name 212 || !(*user_info_mapped)->mapped.account_name) { 213 return NT_STATUS_NO_MEMORY; 214 } 215 216 return NT_STATUS_OK; 217 } 218 219 220 /**************************************************************************** 221 Create an auth_usersupplied_data structure after appropriate mapping. 222 ****************************************************************************/ 223 NTSTATUS map_user_info(struct ldb_context *sam_ctx, 224 TALLOC_CTX *mem_ctx, 43 225 const char *default_domain, 44 226 const struct auth_usersupplied_info *user_info, 45 227 struct auth_usersupplied_info **user_info_mapped) 46 228 { 47 c onst char *domain;229 char *domain; 48 230 char *account_name; 49 231 char *d; 50 DEBUG(5,("map_user_info: Mapping user [%s]\\[%s] from workstation [%s]\n", 51 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name)); 52 53 account_name = talloc_strdup(mem_ctx, user_info->client.account_name); 232 TALLOC_CTX *tmp_ctx; 233 234 if (sam_ctx != NULL) { 235 /* if possible, use cracknames to parse the 236 domain/account */ 237 return map_user_info_cracknames(sam_ctx, mem_ctx, default_domain, user_info, user_info_mapped); 238 } 239 240 DEBUG(0,("map_user_info: Mapping user [%s]\\[%s] from workstation [%s] default_domain=%s\n", 241 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name, 242 default_domain)); 243 244 tmp_ctx = talloc_new(mem_ctx); 245 246 account_name = talloc_strdup(tmp_ctx, user_info->client.account_name); 54 247 if (!account_name) { 248 talloc_free(tmp_ctx); 55 249 return NT_STATUS_NO_MEMORY; 56 250 } 57 251 58 /* don't allow "" as a domain, fixes a Win9X bug 59 where it doesn't supply a domain for logon script 60 'net use' commands. */ 61 62 /* Split user@realm names into user and realm components. This is TODO to fix with proper userprincipalname support */ 252 /* don't allow "" as a domain, fixes a Win9X bug where it 253 doesn't supply a domain for logon script 'net use' 254 commands. */ 255 256 /* Split user@realm names into user and realm components. 257 * This is TODO to fix with proper userprincipalname 258 * support */ 63 259 if (user_info->client.domain_name && *user_info->client.domain_name) { 64 domain = user_info->client.domain_name;260 domain = talloc_strdup(tmp_ctx, user_info->client.domain_name); 65 261 } else if (strchr_m(user_info->client.account_name, '@')) { 66 262 d = strchr_m(account_name, '@'); 67 263 if (!d) { 264 talloc_free(tmp_ctx); 68 265 return NT_STATUS_INTERNAL_ERROR; 69 266 } … … 72 269 domain = d; 73 270 } else { 74 domain = default_domain; 75 } 76 271 domain = talloc_strdup(tmp_ctx, default_domain); 272 } 273 274 if (domain == NULL) { 275 talloc_free(tmp_ctx); 276 return NT_STATUS_NO_MEMORY; 277 } 77 278 *user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info); 78 279 if (!*user_info_mapped) { 280 talloc_free(tmp_ctx); 79 281 return NT_STATUS_NO_MEMORY; 80 282 } 81 283 if (!talloc_reference(*user_info_mapped, user_info)) { 284 talloc_free(tmp_ctx); 82 285 return NT_STATUS_NO_MEMORY; 83 286 } … … 86 289 (*user_info_mapped)->mapped.domain_name = talloc_strdup(*user_info_mapped, domain); 87 290 (*user_info_mapped)->mapped.account_name = talloc_strdup(*user_info_mapped, account_name); 88 talloc_free( account_name);291 talloc_free(tmp_ctx); 89 292 if (!(*user_info_mapped)->mapped.domain_name 90 293 || !(*user_info_mapped)->mapped.account_name) { … … 99 302 ****************************************************************************/ 100 303 101 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth _context *auth_context,304 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, 102 305 enum auth_password_state to_state, 103 306 const struct auth_usersupplied_info *user_info_in, … … 148 351 user_info_in->client.account_name, 149 352 user_info_in->client.domain_name, 150 user_info_in->password.hash.nt->hash, &chall_blob, 353 user_info_in->password.hash.nt->hash, 354 &chall_blob, 355 NULL, /* server_timestamp */ 151 356 &names_blob, 152 357 &lmv2_response, &ntlmv2_response, -
vendor/current/source4/auth/ntlm/auth_winbind.c
r740 r988 25 25 #include "auth/auth.h" 26 26 #include "auth/ntlm/auth_proto.h" 27 #include "auth/auth_sam_reply.h"28 27 #include "librpc/gen_ndr/ndr_winbind_c.h" 29 28 #include "lib/messaging/irpc.h" 30 29 #include "param/param.h" 31 30 #include "nsswitch/libwbclient/wbclient.h" 31 #include "auth/auth_sam_reply.h" 32 32 #include "libcli/security/security.h" 33 33 34 static NTSTATUS get_info3_from_wbcAuthUserInfo(TALLOC_CTX *mem_ctx, 35 struct wbcAuthUserInfo *info, 36 struct netr_SamInfo3 *info3) 37 { 38 int i, j; 39 struct samr_RidWithAttribute *rids = NULL; 40 struct dom_sid *user_sid; 41 struct dom_sid *group_sid; 42 43 user_sid = (struct dom_sid *)(void *)&info->sids[0].sid; 44 group_sid = (struct dom_sid *)(void *)&info->sids[1].sid; 45 46 info3->base.last_logon = info->logon_time; 47 info3->base.last_logoff = info->logoff_time; 48 info3->base.acct_expiry = info->kickoff_time; 49 info3->base.last_password_change = info->pass_last_set_time; 50 info3->base.allow_password_change = info->pass_can_change_time; 51 info3->base.force_password_change = info->pass_must_change_time; 52 53 info3->base.account_name.string = talloc_strdup(mem_ctx, 54 info->account_name); 55 info3->base.full_name.string = talloc_strdup(mem_ctx, 56 info->full_name); 57 info3->base.logon_script.string = talloc_strdup(mem_ctx, 58 info->logon_script); 59 info3->base.profile_path.string = talloc_strdup(mem_ctx, 60 info->profile_path); 61 info3->base.home_directory.string = talloc_strdup(mem_ctx, 62 info->home_directory); 63 info3->base.home_drive.string = talloc_strdup(mem_ctx, 64 info->home_drive); 65 info3->base.logon_server.string = talloc_strdup(mem_ctx, 66 info->logon_server); 67 info3->base.domain.string = talloc_strdup(mem_ctx, 68 info->domain_name); 69 70 info3->base.logon_count = info->logon_count; 71 info3->base.bad_password_count = info->bad_password_count; 72 info3->base.user_flags = info->user_flags; 73 memcpy(info3->base.key.key, info->user_session_key, 74 sizeof(info3->base.key.key)); 75 memcpy(info3->base.LMSessKey.key, info->lm_session_key, 76 sizeof(info3->base.LMSessKey.key)); 77 info3->base.acct_flags = info->acct_flags; 78 memset(info3->base.unknown, 0, sizeof(info3->base.unknown)); 79 80 if (info->num_sids < 2) { 81 return NT_STATUS_INVALID_PARAMETER; 82 } 83 84 dom_sid_split_rid(mem_ctx, user_sid, 85 &info3->base.domain_sid, 86 &info3->base.rid); 87 dom_sid_split_rid(mem_ctx, group_sid, NULL, 88 &info3->base.primary_gid); 89 90 /* We already handled the first two, now take care of the rest */ 91 info3->base.groups.count = info->num_sids - 2; 92 93 rids = talloc_array(mem_ctx, struct samr_RidWithAttribute, 94 info3->base.groups.count); 95 NT_STATUS_HAVE_NO_MEMORY(rids); 96 97 for (i = 2, j = 0; i < info->num_sids; ++i, ++j) { 98 struct dom_sid *tmp_sid; 99 tmp_sid = (struct dom_sid *)(void *)&info->sids[1].sid; 100 101 rids[j].attributes = info->sids[i].attributes; 102 dom_sid_split_rid(mem_ctx, tmp_sid, 103 NULL, &rids[j].rid); 104 } 105 info3->base.groups.rids = rids; 106 107 return NT_STATUS_OK; 108 } 109 34 _PUBLIC_ NTSTATUS auth4_winbind_init(void); 110 35 111 36 static NTSTATUS winbind_want_check(struct auth_method_context *ctx, … … 212 137 s->req.in.validation_level = 3; 213 138 139 /* Note: this makes use of nested event loops... */ 140 dcerpc_binding_handle_set_sync_ev(irpc_handle, ctx->auth_ctx->event_ctx); 214 141 status = dcerpc_winbind_SamLogon_r(irpc_handle, s, &s->req); 215 142 NT_STATUS_NOT_OK_RETURN(status); … … 219 146 s->req.in.validation_level, 220 147 &s->req.out.validation, 148 true, /* This user was authenticated */ 221 149 user_info_dc); 222 150 NT_STATUS_NOT_OK_RETURN(status); … … 239 167 wbcErr wbc_status; 240 168 NTSTATUS nt_status; 241 struct netr_SamInfo3 info3;169 struct netr_SamInfo3 *info3; 242 170 union netr_Validation validation; 243 171 … … 266 194 params.workstation_name = user_info->workstation_name; 267 195 268 d_fprintf(stderr,"looking up %s@%s logging in from %s\n",196 DEBUG(5,("looking up %s@%s logging in from %s\n", 269 197 params.account_name, params.domain_name, 270 params.workstation_name) ;198 params.workstation_name)); 271 199 272 200 memcpy(params.password.response.challenge, … … 286 214 wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); 287 215 if (wbc_status == WBC_ERR_AUTH_ERROR) { 288 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n", 289 err->nt_string, err->nt_status, err->display_string)); 290 216 if (err) { 217 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n", 218 err->nt_string, err->nt_status, err->display_string)); 219 } 291 220 nt_status = NT_STATUS(err->nt_status); 292 221 wbcFreeMemory(err); … … 295 224 DEBUG(1, ("wbcAuthenticateUserEx: failed with %u - %s\n", 296 225 wbc_status, wbcErrorString(wbc_status))); 226 if (err) { 227 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n", 228 err->nt_string, err->nt_status, err->display_string)); 229 } 297 230 return NT_STATUS_LOGON_FAILURE; 298 231 } 299 nt_status = get_info3_from_wbcAuthUserInfo(mem_ctx, info, &info3);232 info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info); 300 233 wbcFreeMemory(info); 301 NT_STATUS_NOT_OK_RETURN(nt_status); 302 303 validation.sam3 = &info3; 234 if (!info3) { 235 DEBUG(1, ("wbcAuthUserInfo_to_netr_SamInfo3 failed\n")); 236 return NT_STATUS_NO_MEMORY; 237 } 238 239 validation.sam3 = info3; 304 240 nt_status = make_user_info_dc_netlogon_validation(mem_ctx, 305 user_info->client.account_name, 306 3, &validation, user_info_dc); 241 user_info->client.account_name, 242 3, &validation, 243 true, /* This user was authenticated */ 244 user_info_dc); 307 245 return nt_status; 308 246 … … 311 249 static const struct auth_operations winbind_ops = { 312 250 .name = "winbind", 313 .get_challenge = auth_get_challenge_not_implemented,314 251 .want_check = winbind_want_check, 315 252 .check_password = winbind_check_password … … 318 255 static const struct auth_operations winbind_wbclient_ops = { 319 256 .name = "winbind_wbclient", 320 .get_challenge = auth_get_challenge_not_implemented,321 257 .want_check = winbind_want_check, 322 258 .check_password = winbind_check_password_wbclient 323 259 }; 324 260 325 _PUBLIC_ NTSTATUS auth _winbind_init(void)261 _PUBLIC_ NTSTATUS auth4_winbind_init(void) 326 262 { 327 263 NTSTATUS ret; -
vendor/current/source4/auth/ntlm/wscript_build
r740 r988 4 4 source='auth_sam.c', 5 5 subsystem='auth4', 6 init_function='auth _sam_init',7 deps='samdb auth4_sam NTLMSSP_COMMON samba-hostconfig '6 init_function='auth4_sam_init', 7 deps='samdb auth4_sam NTLMSSP_COMMON samba-hostconfig RPC_NDR_IRPC MESSAGING' 8 8 ) 9 9 … … 12 12 source='auth_anonymous.c', 13 13 subsystem='auth4', 14 init_function='auth _anonymous_init',14 init_function='auth4_anonymous_init', 15 15 deps='talloc' 16 )17 18 19 bld.SAMBA_MODULE('auth4_server',20 source='auth_server.c',21 subsystem='auth4',22 init_function='auth_server_init',23 deps='samba-util LIBCLI_SMB CREDENTIALS_NTLM'24 16 ) 25 17 … … 28 20 source='auth_winbind.c', 29 21 subsystem='auth4', 30 init_function='auth _winbind_init',22 init_function='auth4_winbind_init', 31 23 deps='RPC_NDR_WINBIND MESSAGING wbclient' 32 24 ) … … 36 28 source='auth_developer.c', 37 29 subsystem='auth4', 38 init_function='auth _developer_init',30 init_function='auth4_developer_init', 39 31 deps='talloc' 40 32 ) … … 44 36 source='auth_unix.c', 45 37 subsystem='auth4', 46 init_function='auth _unix_init',38 init_function='auth4_unix_init', 47 39 deps='pam PAM_ERRORS LIBTSOCKET' 48 40 ) … … 52 44 source='auth.c auth_util.c auth_simple.c', 53 45 autoproto='auth_proto.h', 54 deps='samba-util s ecurity samdb credentials UTIL_TEVENT',46 deps='samba-util samba-security samdb samba-credentials tevent-util LIBWBCLIENT_OLD auth_unix_token samba-modules KERBEROS_UTIL', 55 47 private_library=True 56 48 )
Note:
See TracChangeset
for help on using the changeset viewer.