diff options
-rw-r--r-- | source3/auth/auth_ntlmssp.c | 303 | ||||
-rw-r--r-- | source3/libsmb/ntlmssp.c | 4 |
2 files changed, 82 insertions, 225 deletions
diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index f165322f7a..ab594c19e3 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -23,263 +23,116 @@ #include "includes.h" -NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) +static const uint8 *auth_ntlmssp_get_challenge(void *cookie) { - NTSTATUS nt_status; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("NTLMSSP context"); - - *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); - if (!*ntlmssp_state) { - DEBUG(0,("ntlmssp_start: talloc failed!\n")); - talloc_destroy(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - - ZERO_STRUCTP(*ntlmssp_state); - - (*ntlmssp_state)->mem_ctx = mem_ctx; - - if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&(*ntlmssp_state)->auth_context))) { - return nt_status; - } - return NT_STATUS_OK; + AUTH_NTLMSSP_STATE *auth_ntlmssp_state = cookie; + return auth_ntlmssp_state->auth_context->get_ntlm_challenge(auth_ntlmssp_state->auth_context); } -NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) +static NTSTATUS auth_ntlmssp_check_password(void *cookie) { - TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - if ((*ntlmssp_state)->auth_context) { - ((*ntlmssp_state)->auth_context->free)(&(*ntlmssp_state)->auth_context); - } - if ((*ntlmssp_state)->server_info) { - free_server_info(&(*ntlmssp_state)->server_info); - } - - talloc_destroy(mem_ctx); - *ntlmssp_state = NULL; - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) -{ - uint32 ntlmssp_command; - - if (!msrpc_parse(&request, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - return NT_STATUS_LOGON_FAILURE; - } + AUTH_NTLMSSP_STATE *auth_ntlmssp_state = cookie; + uint32 auth_flags = AUTH_FLAG_NONE; + auth_usersupplied_info *user_info = NULL; + DATA_BLOB plaintext_password = data_blob(NULL, 0); + NTSTATUS nt_status; - if (ntlmssp_command == NTLMSSP_NEGOTIATE) { - return ntlmssp_negotiate(ntlmssp_state, request, reply); - } else if (ntlmssp_command == NTLMSSP_AUTH) { - return ntlmssp_auth(ntlmssp_state, request, reply); - } else { - return NT_STATUS_LOGON_FAILURE; + if (auth_ntlmssp_state->ntlmssp_state->lm_resp.length) { + auth_flags |= AUTH_FLAG_LM_RESP; } -} -static const char *ntlmssp_target_name(uint32 neg_flags, uint32 *chal_flags) -{ - if (neg_flags & NTLMSSP_REQUEST_TARGET) { - if (lp_server_role() == ROLE_STANDALONE) { - *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER; - return global_myname(); - } else { - *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN; - return lp_workgroup(); - }; - } else { - return ""; - } -} + if (auth_ntlmssp_state->ntlmssp_state->nt_resp.length == 24) { + auth_flags |= AUTH_FLAG_NTLM_RESP; + } else if (auth_ntlmssp_state->ntlmssp_state->nt_resp.length > 24) { + auth_flags |= AUTH_FLAG_NTLMv2_RESP; + }; -NTSTATUS ntlmssp_negotiate(NTLMSSP_STATE *ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) -{ - DATA_BLOB struct_blob; - fstring dnsname, dnsdomname; - uint32 ntlmssp_command, neg_flags, chal_flags; - char *cliname=NULL, *domname=NULL; - const uint8 *cryptkey; - const char *target_name; + /* the client has given us its machine name (which we otherwise would not get on port 445). + we need to possibly reload smb.conf if smb.conf includes depend on the machine name */ - /* parse the NTLMSSP packet */ -#if 0 - file_save("ntlmssp_negotiate.dat", request.data, request.length); -#endif + set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state->workstation); - if (!msrpc_parse(&request, "CddAA", - "NTLMSSP", - &ntlmssp_command, - &neg_flags, - &cliname, - &domname)) { - return NT_STATUS_LOGON_FAILURE; - } + /* setup the string used by %U */ + /* sub_set_smb_name checks for weird internally */ + sub_set_smb_name(auth_ntlmssp_state->ntlmssp_state->user); - SAFE_FREE(cliname); - SAFE_FREE(domname); - - debug_ntlmssp_flags(neg_flags); + reload_services(True); - cryptkey = ntlmssp_state->auth_context->get_ntlm_challenge(ntlmssp_state->auth_context); + nt_status = make_user_info_map(&user_info, + auth_ntlmssp_state->ntlmssp_state->user, + auth_ntlmssp_state->ntlmssp_state->domain, + auth_ntlmssp_state->ntlmssp_state->workstation, + auth_ntlmssp_state->ntlmssp_state->lm_resp, + auth_ntlmssp_state->ntlmssp_state->nt_resp, + plaintext_password, + auth_flags, True); - /* Give them the challenge. For now, ignore neg_flags and just - return the flags we want. Obviously this is not correct */ - - chal_flags = - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_CHAL_TARGET_INFO; - - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { - chal_flags |= NTLMSSP_NEGOTIATE_UNICODE; - ntlmssp_state->unicode = True; - } else { - chal_flags |= NTLMSSP_NEGOTIATE_OEM; + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; } - target_name = ntlmssp_target_name(neg_flags, &chal_flags); - - dnsdomname[0] = '\0'; - get_mydomname(dnsdomname); - strlower(dnsdomname); - - dnsname[0] = '\0'; - get_myfullname(dnsname); - strlower(dnsname); - - /* the numbers here are the string type flags */ - msrpc_gen(&struct_blob, "aaaaa", - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN, lp_workgroup(), - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER, global_myname(), - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsname, - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER_DNS, dnsdomname, - ntlmssp_state->unicode, 0, ""); - - { - const char *gen_string; - if (ntlmssp_state->unicode) { - gen_string = "CdUdbddB"; - } else { - gen_string = "CdAdbddB"; - } - - msrpc_gen(reply, gen_string, - "NTLMSSP", - NTLMSSP_CHALLENGE, - target_name, - chal_flags, - cryptkey, 8, - 0, 0, - struct_blob.data, struct_blob.length); - } - - data_blob_free(&struct_blob); + nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context, user_info, &auth_ntlmssp_state->server_info); + + free_user_info(&user_info); - return NT_STATUS_MORE_PROCESSING_REQUIRED; + return nt_status; } -NTSTATUS ntlmssp_auth(NTLMSSP_STATE *ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) +NTSTATUS auth_ntlmssp_start(AUTH_NTLMSSP_STATE **auth_ntlmssp_state) { - char *workgroup = NULL, *user = NULL, *machine = NULL; - DATA_BLOB lmhash, nthash, sess_key; - DATA_BLOB plaintext_password = data_blob(NULL, 0); - uint32 ntlmssp_command, neg_flags; NTSTATUS nt_status; - uint32 auth_flags = AUTH_FLAG_NONE; - auth_usersupplied_info *user_info = NULL; - - const char *parse_string; - - /* parse the NTLMSSP packet */ -#if 0 - file_save("ntlmssp_auth.dat", request.data, request.length); -#endif - - if (ntlmssp_state->unicode) { - parse_string = "CdBBUUUBd"; - } else { - parse_string = "CdBBAAABd"; - } - - /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(&request, parse_string, - "NTLMSSP", - &ntlmssp_command, - &lmhash, - &nthash, - &workgroup, - &user, - &machine, - &sess_key, - &neg_flags)) { - return NT_STATUS_LOGON_FAILURE; - } + TALLOC_CTX *mem_ctx; - data_blob_free(&sess_key); + mem_ctx = talloc_init("AUTH NTLMSSP context"); - DEBUG(3,("Got user=[%s] workgroup=[%s] machine=[%s] len1=%d len2=%d\n", - user, workgroup, machine, lmhash.length, nthash.length)); - - /* the client has given us its machine name (which we otherwise would not get on port 445). - we need to possibly reload smb.conf if smb.conf includes depend on the machine name */ - - set_remote_machine_name(machine); - - /* setup the string used by %U */ - sub_set_smb_name(user); + *auth_ntlmssp_state = talloc_zero(mem_ctx, sizeof(**auth_ntlmssp_state)); + if (!*auth_ntlmssp_state) { + DEBUG(0,("auth_ntlmssp_start: talloc failed!\n")); + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } - reload_services(True); + ZERO_STRUCTP(*auth_ntlmssp_state); -#if 0 - file_save("nthash1.dat", nthash.data, nthash.length); - file_save("lmhash1.dat", lmhash.data, lmhash.length); -#endif + (*auth_ntlmssp_state)->mem_ctx = mem_ctx; - if (lmhash.length) { - auth_flags |= AUTH_FLAG_LM_RESP; + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(&(*auth_ntlmssp_state)->ntlmssp_state))) { + return nt_status; } - if (nthash.length == 24) { - auth_flags |= AUTH_FLAG_NTLM_RESP; - } else if (nthash.length > 24) { - auth_flags |= AUTH_FLAG_NTLMv2_RESP; - }; - - + if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&(*auth_ntlmssp_state)->auth_context))) { + return nt_status; + } - nt_status = make_user_info_map(&user_info, user, workgroup, machine, - lmhash, nthash, plaintext_password, - auth_flags, True); + (*auth_ntlmssp_state)->ntlmssp_state->auth_context = (*auth_ntlmssp_state); + (*auth_ntlmssp_state)->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; + (*auth_ntlmssp_state)->ntlmssp_state->check_password = auth_ntlmssp_check_password; - ntlmssp_state->orig_user = talloc_strdup(ntlmssp_state->mem_ctx, user); - ntlmssp_state->orig_domain = talloc_strdup(ntlmssp_state->mem_ctx, workgroup); + return NT_STATUS_OK; +} - SAFE_FREE(user); - SAFE_FREE(workgroup); - SAFE_FREE(machine); +NTSTATUS auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state) +{ + TALLOC_CTX *mem_ctx = (*auth_ntlmssp_state)->mem_ctx; - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; + if ((*auth_ntlmssp_state)->ntlmssp_state) { + ntlmssp_server_end(&(*auth_ntlmssp_state)->ntlmssp_state); + } + if ((*auth_ntlmssp_state)->auth_context) { + ((*auth_ntlmssp_state)->auth_context->free)(&(*auth_ntlmssp_state)->auth_context); + } + if ((*auth_ntlmssp_state)->server_info) { + free_server_info(&(*auth_ntlmssp_state)->server_info); } - nt_status = ntlmssp_state->auth_context->check_ntlm_password(ntlmssp_state->auth_context, user_info, &ntlmssp_state->server_info); - - (ntlmssp_state->auth_context->free)(&ntlmssp_state->auth_context); - - free_user_info(&user_info); - - data_blob_free(&lmhash); - - data_blob_free(&nthash); - - *reply = data_blob(NULL, 0); + talloc_destroy(mem_ctx); + *auth_ntlmssp_state = NULL; + return NT_STATUS_OK; +} - return nt_status; +NTSTATUS auth_ntlmssp_update(AUTH_NTLMSSP_STATE *auth_ntlmssp_state, + DATA_BLOB request, DATA_BLOB *reply) +{ + return ntlmssp_server_update(auth_ntlmssp_state->ntlmssp_state, request, reply); } + diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 4183f3e77a..21f3612034 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -65,6 +65,7 @@ NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) { TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + data_blob_free(&(*ntlmssp_state)->chal); data_blob_free(&(*ntlmssp_state)->lm_resp); data_blob_free(&(*ntlmssp_state)->nt_resp); @@ -146,6 +147,9 @@ NTSTATUS ntlmssp_negotiate(NTLMSSP_STATE *ntlmssp_state, cryptkey = ntlmssp_state->get_challenge(ntlmssp_state->auth_context); + data_blob_free(&ntlmssp_state->chal); + ntlmssp_state->chal = data_blob(cryptkey, 8); + /* Give them the challenge. For now, ignore neg_flags and just return the flags we want. Obviously this is not correct */ |