diff options
Diffstat (limited to 'source3/smbd/auth.c')
-rw-r--r-- | source3/smbd/auth.c | 165 |
1 files changed, 86 insertions, 79 deletions
diff --git a/source3/smbd/auth.c b/source3/smbd/auth.c index 95c97182b85..c62e2ed5a07 100644 --- a/source3/smbd/auth.c +++ b/source3/smbd/auth.c @@ -58,27 +58,50 @@ static BOOL check_domain_match(char *user, char *domain) ****************************************************************************/ NTSTATUS check_password(const auth_usersupplied_info *user_info, + const auth_authsupplied_info *auth_info, auth_serversupplied_info **server_info) { NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; - BOOL done_pam = False; const char *pdb_username; + auth_methods *auth_method; + + if (!user_info || !auth_info || !server_info) { + return NT_STATUS_LOGON_FAILURE; + } DEBUG(3, ("check_password: Checking password for unmapped user [%s]\\[%s]@[%s] with the new password interface\n", user_info->client_domain.str, user_info->smb_name.str, user_info->wksta_name.str)); DEBUG(3, ("check_password: mapped user is: [%s]\\[%s]@[%s]\n", user_info->domain.str, user_info->internal_username.str, user_info->wksta_name.str)); - - if (!NT_STATUS_IS_OK(nt_status)) { - nt_status = check_guest_security(user_info, server_info); + DEBUG(10, ("auth_info challange created by %s\n", auth_info->challange_set_by)); + DEBUG(10, ("challange is: \n")); + dump_data(5, (auth_info)->challange.data, (auth_info)->challange.length); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("user_info has passwords of length %d and %d\n", + user_info->lm_resp.length, user_info->nt_resp.length)); + DEBUG(100, ("lm:\n")); + dump_data(100, user_info->lm_resp.data, user_info->lm_resp.length); + DEBUG(100, ("nt:\n")); + dump_data(100, user_info->nt_resp.data, user_info->nt_resp.length); +#endif + + for (auth_method = auth_info->auth_method_list;auth_method; auth_method = auth_method->next) + { + nt_status = auth_method->auth(auth_method->private_data, user_info, auth_info, server_info); if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(5, ("check_password: checking guest-account for user [%s] suceeded\n", user_info->smb_name.str)); + DEBUG(3, ("check_password: %s authentication for user [%s] suceeded\n", + auth_method->name, user_info->smb_name.str)); } else { - DEBUG(10, ("check_password: checking gusst-account for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status))); - - } + DEBUG(5, ("check_password: %s authentication for user [%s] FAILED with error %s\n", + auth_method->name, user_info->smb_name.str, get_nt_error_msg(nt_status))); + } + + if (NT_STATUS_IS_OK(nt_status)) { + break; + } } /* This needs to be sorted: If it doesn't match, what should we do? */ @@ -86,83 +109,47 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info, return NT_STATUS_LOGON_FAILURE; } - if (!NT_STATUS_IS_OK(nt_status)) { - nt_status = check_rhosts_security(user_info, server_info); - if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(3, ("check_password: Password (rhosts) for user [%s] suceeded\n", user_info->smb_name.str)); - } else { - DEBUG(10, ("check_password: Password (rhosts) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status))); - - } - } - - if ((lp_security() == SEC_DOMAIN) && !NT_STATUS_IS_OK(nt_status)) { - nt_status = check_domain_security(user_info, server_info); - if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(7, ("check_password: Password (domain) for user [%s] suceeded\n", user_info->smb_name.str)); - } else { - DEBUG(5, ("check_password: Password (domain) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status))); - - } - } - - if ((lp_security() == SEC_SERVER) && !NT_STATUS_IS_OK(nt_status)) { - nt_status = check_server_security(user_info, server_info); - if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(7, ("check_password: Password (server) for user [%s] suceeded\n", user_info->smb_name.str)); - } else { - DEBUG(5, ("check_password: Password (server) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status))); - - } - } + /* This is one of the few places the *relies* (rather than just sets defaults + on the value of lp_security(). This needs to change. A new paramater + perhaps? */ if (lp_security() >= SEC_SERVER) { smb_user_control(user_info, *server_info, nt_status); } - if (!NT_STATUS_IS_OK(nt_status)) { - if (user_info->encrypted || lp_plaintext_to_smbpasswd()) { - nt_status = check_smbpasswd_security(user_info, server_info); - } else { - nt_status = check_unix_security(user_info, server_info); - done_pam = True; - } - - if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(7, ("check_password: Password (unix/smbpasswd) for user [%s] suceeded\n", user_info->smb_name.str)); - } else { - DEBUG(5, ("check_password: Password (unix/smbpasswd) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status))); - - } - } - if (NT_STATUS_IS_OK(nt_status)) { pdb_username = pdb_get_username((*server_info)->sam_account); - if (!done_pam && !(*server_info)->guest) { + if (!(*server_info)->guest) { /* We might not be root if we are an RPC call */ become_root(); nt_status = smb_pam_accountcheck(pdb_username); unbecome_root(); if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(5, ("check_password: PAM Account for user [%s] suceeded\n", pdb_username)); + DEBUG(5, ("check_password: PAM Account for user [%s] suceeded\n", + pdb_username)); } else { - DEBUG(3, ("check_password: PAM Account for user [%s] FAILED with error %s\n", pdb_username, get_nt_error_msg(nt_status))); + DEBUG(3, ("check_password: PAM Account for user [%s] FAILED with error %s\n", + pdb_username, get_nt_error_msg(nt_status))); } } + + if (NT_STATUS_IS_OK(nt_status)) { + DEBUG((*server_info)->guest ? 5 : 2, + ("check_password: %sauthenticaion for user [%s] -> [%s] -> [%s] suceeded\n", + (*server_info)->guest ? "guest " : "", + user_info->smb_name.str, + user_info->internal_username.str, + pdb_username)); + } } - if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(3, ("check_password: %sauthenticaion for user [%s] -> [%s] -> [%s] suceeded\n", - (*server_info)->guest ? "guest " : "", - user_info->smb_name.str, - user_info->internal_username.str, - pdb_username)); - } else { - DEBUG(3, ("check_password: Authenticaion for user [%s] -> [%s] FAILED with error %s\n", user_info->smb_name.str, user_info->internal_username.str, get_nt_error_msg(nt_status))); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(2, ("check_password: Authenticaion for user [%s] -> [%s] FAILED with error %s\n", + user_info->smb_name.str, user_info->internal_username.str, + get_nt_error_msg(nt_status))); ZERO_STRUCTP(server_info); - } - + } return nt_status; } @@ -210,16 +197,35 @@ static NTSTATUS pass_check_smb(char *smb_name, { NTSTATUS nt_status; auth_usersupplied_info *user_info = NULL; + extern auth_authsupplied_info *negprot_global_auth_info; auth_serversupplied_info *server_info = NULL; + if (encrypted) { + make_user_info_for_reply_enc(&user_info, smb_name, + domain, + lm_pwd, + nt_pwd, + plaintext_password); + nt_status = check_password(user_info, negprot_global_auth_info, &server_info); + } else { + auth_authsupplied_info *plaintext_auth_info = NULL; + DATA_BLOB chal; + if (!make_auth_info_subsystem(&plaintext_auth_info)) { + return NT_STATUS_NO_MEMORY; + } - make_user_info_for_reply(&user_info, smb_name, - domain, - lm_pwd, - nt_pwd, - plaintext_password, - encrypted); - - nt_status = check_password(user_info, &server_info); + chal = auth_get_challange(plaintext_auth_info); + + if (!make_user_info_for_reply(&user_info, + smb_name, domain, chal.data, + plaintext_password)) { + return NT_STATUS_NO_MEMORY; + } + + nt_status = check_password(user_info, plaintext_auth_info, &server_info); + + data_blob_free(&chal); + free_auth_info(&plaintext_auth_info); + } free_user_info(&user_info); free_server_info(&server_info); return nt_status; @@ -235,22 +241,23 @@ BOOL password_ok(char *smb_name, DATA_BLOB password_blob) DATA_BLOB null_password = data_blob(NULL, 0); extern BOOL global_encrypted_passwords_negotiated; - - if (global_encrypted_passwords_negotiated) { + BOOL encrypted = (global_encrypted_passwords_negotiated && password_blob.length == 24); + + if (encrypted) { /* * The password could be either NTLM or plain LM. Try NTLM first, * but fall-through as required. * NTLMv2 makes no sense here. */ - if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, global_encrypted_passwords_negotiated))) { + if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) { return True; } - if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, global_encrypted_passwords_negotiated))) { + if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) { return True; } } else { - if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, global_encrypted_passwords_negotiated))) { + if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) { return True; } } |