diff options
-rw-r--r-- | auth/common_auth.h | 6 | ||||
-rw-r--r-- | source3/auth/auth.c | 6 | ||||
-rw-r--r-- | source3/auth/auth_compat.c | 48 | ||||
-rw-r--r-- | source3/auth/auth_domain.c | 4 | ||||
-rw-r--r-- | source3/auth/auth_netlogond.c | 4 | ||||
-rw-r--r-- | source3/auth/auth_ntlmssp.c | 2 | ||||
-rw-r--r-- | source3/auth/auth_script.c | 8 | ||||
-rw-r--r-- | source3/auth/auth_server.c | 26 | ||||
-rw-r--r-- | source3/auth/auth_unix.c | 3 | ||||
-rw-r--r-- | source3/auth/auth_util.c | 79 | ||||
-rw-r--r-- | source3/auth/auth_wbc.c | 40 | ||||
-rw-r--r-- | source3/auth/auth_winbind.c | 8 | ||||
-rw-r--r-- | source3/auth/check_samsec.c | 55 | ||||
-rw-r--r-- | source3/auth/pass_check.c | 8 | ||||
-rw-r--r-- | source3/auth/user_info.c | 52 | ||||
-rw-r--r-- | source3/include/auth.h | 25 | ||||
-rw-r--r-- | source3/include/proto.h | 26 | ||||
-rw-r--r-- | source3/web/cgi.c | 2 | ||||
-rw-r--r-- | source3/winbindd/winbindd_pam.c | 2 |
19 files changed, 213 insertions, 191 deletions
diff --git a/auth/common_auth.h b/auth/common_auth.h index 5bade6915f..4ae5df9a6b 100644 --- a/auth/common_auth.h +++ b/auth/common_auth.h @@ -25,9 +25,9 @@ #define USER_INFO_INTERACTIVE_LOGON 0x08 /* don't check unix account status */ enum auth_password_state { - AUTH_PASSWORD_RESPONSE, - AUTH_PASSWORD_HASH, - AUTH_PASSWORD_PLAIN + AUTH_PASSWORD_PLAIN = 1, + AUTH_PASSWORD_HASH = 2, + AUTH_PASSWORD_RESPONSE = 3 }; struct auth_usersupplied_info diff --git a/source3/auth/auth.c b/source3/auth/auth.c index 5dc1d970d6..5c50bb8826 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -233,11 +233,11 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, #ifdef DEBUG_PASSWORD DEBUG(100, ("user_info has passwords of length %d and %d\n", - (int)user_info->lm_resp.length, (int)user_info->nt_resp.length)); + (int)user_info->password.response.lanman.length, (int)user_info->password.response.nt.length)); DEBUG(100, ("lm:\n")); - dump_data(100, user_info->lm_resp.data, user_info->lm_resp.length); + dump_data(100, user_info->password.response.lanman.data, user_info->password.response.lanman.length); DEBUG(100, ("nt:\n")); - dump_data(100, user_info->nt_resp.data, user_info->nt_resp.length); + dump_data(100, user_info->password.response.nt.data, user_info->password.response.nt.length); #endif /* This needs to be sorted: If it doesn't match, what should we do? */ diff --git a/source3/auth/auth_compat.c b/source3/auth/auth_compat.c index cdd4096654..bd4c433ab9 100644 --- a/source3/auth/auth_compat.c +++ b/source3/auth/auth_compat.c @@ -30,13 +30,12 @@ extern bool global_encrypted_passwords_negotiated; ***************************************************************************/ /**************************************************************************** -check if a username/password is OK assuming the password is a 24 byte -SMB hash +check if a username/password is OK assuming the password is in plaintext return True if the password is correct, False otherwise ****************************************************************************/ NTSTATUS check_plaintext_password(const char *smb_name, - DATA_BLOB plaintext_password, + DATA_BLOB plaintext_blob, struct auth_serversupplied_info **server_info) { struct auth_context *plaintext_auth_context = NULL; @@ -52,7 +51,7 @@ NTSTATUS check_plaintext_password(const char *smb_name, if (!make_user_info_for_reply(&user_info, smb_name, lp_workgroup(), chal, - plaintext_password)) { + plaintext_blob)) { return NT_STATUS_NO_MEMORY; } @@ -68,27 +67,21 @@ static NTSTATUS pass_check_smb(struct auth_context *actx, const char *smb_name, const char *domain, DATA_BLOB lm_pwd, - DATA_BLOB nt_pwd, - DATA_BLOB plaintext_password, - bool encrypted) + DATA_BLOB nt_pwd) { NTSTATUS nt_status; struct auth_serversupplied_info *server_info = NULL; - if (encrypted) { - struct auth_usersupplied_info *user_info = NULL; - if (actx == NULL) { - return NT_STATUS_INTERNAL_ERROR; - } - make_user_info_for_reply_enc(&user_info, smb_name, - domain, - lm_pwd, - nt_pwd); - nt_status = actx->check_ntlm_password(actx, user_info, &server_info); - free_user_info(&user_info); - } else { - nt_status = check_plaintext_password(smb_name, plaintext_password, &server_info); - } + struct auth_usersupplied_info *user_info = NULL; + if (actx == NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + make_user_info_for_reply_enc(&user_info, smb_name, + domain, + lm_pwd, + nt_pwd); + nt_status = actx->check_ntlm_password(actx, user_info, &server_info); + free_user_info(&user_info); TALLOC_FREE(server_info); return nt_status; } @@ -113,23 +106,26 @@ bool password_ok(struct auth_context *actx, bool global_encrypted, * Vista sends NTLMv2 here - we need to try the client given workgroup. */ if (session_workgroup) { - if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, null_password, password_blob, null_password, encrypted))) { + if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, null_password, password_blob))) { return True; } - if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, password_blob, null_password, null_password, encrypted))) { + if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, password_blob, null_password))) { return True; } } - if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) { + if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, password_blob))) { return True; } - if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) { + if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), password_blob, null_password))) { return True; } } else { - if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) { + struct auth_serversupplied_info *server_info = NULL; + NTSTATUS nt_status = check_plaintext_password(smb_name, password_blob, &server_info); + TALLOC_FREE(server_info); + if (NT_STATUS_IS_OK(nt_status)) { return True; } } diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 0fc6410fec..824618c63d 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -313,8 +313,8 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, user_info->client.domain_name, /* domain name */ user_info->workstation_name,/* workstation name */ chal, /* 8 byte challenge. */ - user_info->lm_resp, /* lanman 24 byte response */ - user_info->nt_resp, /* nt 24 byte response */ + user_info->password.response.lanman, /* lanman 24 byte response */ + user_info->password.response.nt, /* nt 24 byte response */ &info3); /* info3 out */ /* Let go as soon as possible so we avoid any potential deadlocks diff --git a/source3/auth/auth_netlogond.c b/source3/auth/auth_netlogond.c index 8be2c6a00c..446b9e2ee4 100644 --- a/source3/auth/auth_netlogond.c +++ b/source3/auth/auth_netlogond.c @@ -88,8 +88,8 @@ static NTSTATUS netlogond_validate(TALLOC_CTX *mem_ctx, user_info->client.domain_name, /* domain name */ user_info->workstation_name, /* workstation name */ (uchar *)auth_context->challenge.data, /* 8 byte challenge. */ - user_info->lm_resp, /* lanman 24 byte response */ - user_info->nt_resp, /* nt 24 byte response */ + user_info->password.response.lanman, /* lanman 24 byte response */ + user_info->password.response.nt, /* nt 24 byte response */ &info3); /* info3 out */ DEBUG(10, ("rpccli_netlogon_sam_network_logon_ex returned %s\n", diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index bc0e9d276a..a910201fcf 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -131,7 +131,7 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, auth_ntlmssp_state->ntlmssp_state->lm_resp.data ? &auth_ntlmssp_state->ntlmssp_state->lm_resp : NULL, auth_ntlmssp_state->ntlmssp_state->nt_resp.data ? &auth_ntlmssp_state->ntlmssp_state->nt_resp : NULL, NULL, NULL, NULL, - True); + AUTH_PASSWORD_RESPONSE); user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT; diff --git a/source3/auth/auth_script.c b/source3/auth/auth_script.c index 2b83f80d98..ee01733514 100644 --- a/source3/auth/auth_script.c +++ b/source3/auth/auth_script.c @@ -84,17 +84,17 @@ static NTSTATUS script_check_user_credentials(const struct auth_context *auth_co safe_strcat( secret_str, hex_str, secret_str_len - 1); safe_strcat( secret_str, "\n", secret_str_len - 1); - if (user_info->lm_resp.data) { + if (user_info->password.response.lanman.data) { for (i = 0; i < 24; i++) { - slprintf(&hex_str[i*2], 3, "%02X", user_info->lm_resp.data[i]); + slprintf(&hex_str[i*2], 3, "%02X", user_info->password.response.lanman.data[i]); } safe_strcat( secret_str, hex_str, secret_str_len - 1); } safe_strcat( secret_str, "\n", secret_str_len - 1); - if (user_info->nt_resp.data) { + if (user_info->password.response.nt.data) { for (i = 0; i < 24; i++) { - slprintf(&hex_str[i*2], 3, "%02X", user_info->nt_resp.data[i]); + slprintf(&hex_str[i*2], 3, "%02X", user_info->password.response.nt.data[i]); } safe_strcat( secret_str, hex_str, secret_str_len - 1); } diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c index 8f0f98b350..76cafc6d69 100644 --- a/source3/auth/auth_server.c +++ b/source3/auth/auth_server.c @@ -297,7 +297,7 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context } if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { - if (user_info->encrypted) { + if (user_info->password_state != AUTH_PASSWORD_PLAIN) { DEBUG(1,("password server %s is plaintext, but we are encrypted. This just can't work :-(\n", cli->desthost)); return NT_STATUS_LOGON_FAILURE; } @@ -326,8 +326,8 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context memset(badpass, 0x1f, sizeof(badpass)); - if((user_info->nt_resp.length == sizeof(badpass)) && - !memcmp(badpass, user_info->nt_resp.data, sizeof(badpass))) { + if((user_info->password.response.nt.length == sizeof(badpass)) && + !memcmp(badpass, user_info->password.response.nt.data, sizeof(badpass))) { /* * Very unlikely, our random bad password is the same as the users * password. @@ -391,22 +391,24 @@ use this machine as the password server.\n")); * Now we know the password server will correctly set the guest bit, or is * not guest enabled, we can try with the real password. */ - - if (!user_info->encrypted) { + switch (user_info->password_state) { + case AUTH_PASSWORD_PLAIN: /* Plaintext available */ nt_status = cli_session_setup( cli, user_info->client.account_name, - (char *)user_info->plaintext_password.data, - user_info->plaintext_password.length, + user_info->password.plaintext, + strlen(user_info->password.plaintext), NULL, 0, user_info->mapped.domain_name); - } else { + /* currently the hash values include a challenge-response as well */ + case AUTH_PASSWORD_HASH: + case AUTH_PASSWORD_RESPONSE: nt_status = cli_session_setup( cli, user_info->client.account_name, - (char *)user_info->lm_resp.data, - user_info->lm_resp.length, - (char *)user_info->nt_resp.data, - user_info->nt_resp.length, + (char *)user_info->password.response.lanman.data, + user_info->password.response.lanman.length, + (char *)user_info->password.response.nt.data, + user_info->password.response.nt.length, user_info->mapped.domain_name); } diff --git a/source3/auth/auth_unix.c b/source3/auth/auth_unix.c index 053cad9707..a9a4c53704 100644 --- a/source3/auth/auth_unix.c +++ b/source3/auth/auth_unix.c @@ -101,8 +101,7 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context, done. We may need to revisit this **/ nt_status = pass_check(pass, pass ? pass->pw_name : user_info->mapped.account_name, - (char *)user_info->plaintext_password.data, - user_info->plaintext_password.length-1, + user_info->password.plaintext, lp_update_encrypted() ? update_smbpassword_file : NULL, True); diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 16fa421f8b..371087e449 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -86,10 +86,10 @@ NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info, const char *workstation_name, DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd, - DATA_BLOB *lm_interactive_pwd, - DATA_BLOB *nt_interactive_pwd, - DATA_BLOB *plaintext, - bool encrypted) + const struct samr_Password *lm_interactive_pwd, + const struct samr_Password *nt_interactive_pwd, + const char *plaintext, + enum auth_password_state password_state) { const char *domain; NTSTATUS result; @@ -131,8 +131,11 @@ NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info, client_domain, domain, workstation_name, lm_pwd, nt_pwd, lm_interactive_pwd, nt_interactive_pwd, - plaintext, encrypted); + plaintext, password_state); if (NT_STATUS_IS_OK(result)) { + /* We have tried mapping */ + (*user_info)->mapped_state = True; + /* did we actually map the user to a different name? */ (*user_info)->was_mapped = was_mapped; } return result; @@ -164,7 +167,7 @@ bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info, lm_pwd_len ? &lm_blob : NULL, nt_pwd_len ? &nt_blob : NULL, NULL, NULL, NULL, - True); + AUTH_PASSWORD_RESPONSE); if (NT_STATUS_IS_OK(status)) { (*user_info)->logon_parameters = logon_parameters; @@ -191,8 +194,8 @@ bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_in const uchar nt_interactive_pwd[16], const uchar *dc_sess_key) { - unsigned char lm_pwd[16]; - unsigned char nt_pwd[16]; + struct samr_Password lm_pwd; + struct samr_Password nt_pwd; unsigned char local_lm_response[24]; unsigned char local_nt_response[24]; unsigned char key[16]; @@ -200,42 +203,42 @@ bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_in memcpy(key, dc_sess_key, 16); if (lm_interactive_pwd) - memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd)); + memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash)); if (nt_interactive_pwd) - memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd)); + memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash)); #ifdef DEBUG_PASSWORD DEBUG(100,("key:")); dump_data(100, key, sizeof(key)); DEBUG(100,("lm owf password:")); - dump_data(100, lm_pwd, sizeof(lm_pwd)); + dump_data(100, lm_pwd.hash, sizeof(lm_pwd.hash)); DEBUG(100,("nt owf password:")); - dump_data(100, nt_pwd, sizeof(nt_pwd)); + dump_data(100, nt_pwd.hash, sizeof(nt_pwd.hash)); #endif if (lm_interactive_pwd) - arcfour_crypt(lm_pwd, key, sizeof(lm_pwd)); + arcfour_crypt(lm_pwd.hash, key, sizeof(lm_pwd.hash)); if (nt_interactive_pwd) - arcfour_crypt(nt_pwd, key, sizeof(nt_pwd)); + arcfour_crypt(nt_pwd.hash, key, sizeof(nt_pwd.hash)); #ifdef DEBUG_PASSWORD DEBUG(100,("decrypt of lm owf password:")); - dump_data(100, lm_pwd, sizeof(lm_pwd)); + dump_data(100, lm_pwd.hash, sizeof(lm_pwd)); DEBUG(100,("decrypt of nt owf password:")); - dump_data(100, nt_pwd, sizeof(nt_pwd)); + dump_data(100, nt_pwd.hash, sizeof(nt_pwd)); #endif if (lm_interactive_pwd) - SMBOWFencrypt(lm_pwd, chal, + SMBOWFencrypt(lm_pwd.hash, chal, local_lm_response); if (nt_interactive_pwd) - SMBOWFencrypt(nt_pwd, chal, + SMBOWFencrypt(nt_pwd.hash, chal, local_nt_response); /* Password info paranoia */ @@ -247,23 +250,14 @@ bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_in DATA_BLOB local_lm_blob; DATA_BLOB local_nt_blob; - DATA_BLOB lm_interactive_blob; - DATA_BLOB nt_interactive_blob; - if (lm_interactive_pwd) { local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response)); - lm_interactive_blob = data_blob(lm_pwd, - sizeof(lm_pwd)); - ZERO_STRUCT(lm_pwd); } if (nt_interactive_pwd) { local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response)); - nt_interactive_blob = data_blob(nt_pwd, - sizeof(nt_pwd)); - ZERO_STRUCT(nt_pwd); } nt_status = make_user_info_map( @@ -271,9 +265,9 @@ bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_in smb_name, client_domain, workstation_name, lm_interactive_pwd ? &local_lm_blob : NULL, nt_interactive_pwd ? &local_nt_blob : NULL, - lm_interactive_pwd ? &lm_interactive_blob : NULL, - nt_interactive_pwd ? &nt_interactive_blob : NULL, - NULL, True); + lm_interactive_pwd ? &lm_pwd : NULL, + nt_interactive_pwd ? &nt_pwd : NULL, + NULL, AUTH_PASSWORD_HASH); if (NT_STATUS_IS_OK(nt_status)) { (*user_info)->logon_parameters = logon_parameters; @@ -282,8 +276,6 @@ bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_in ret = NT_STATUS_IS_OK(nt_status) ? True : False; data_blob_free(&local_lm_blob); data_blob_free(&local_nt_blob); - data_blob_free(&lm_interactive_blob); - data_blob_free(&nt_interactive_blob); return ret; } } @@ -303,14 +295,13 @@ bool make_user_info_for_reply(struct auth_usersupplied_info **user_info, DATA_BLOB local_lm_blob; DATA_BLOB local_nt_blob; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - + char *plaintext_password_string; /* * Not encrypted - do so. */ DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted " "format.\n")); - if (plaintext_password.data && plaintext_password.length) { unsigned char local_lm_response[24]; @@ -333,14 +324,26 @@ bool make_user_info_for_reply(struct auth_usersupplied_info **user_info, local_nt_blob = data_blob_null; } + plaintext_password_string = talloc_strndup(talloc_tos(), + (const char *)plaintext_password.data, + plaintext_password.length); + if (!plaintext_password_string) { + return False; + } + ret = make_user_info_map( user_info, smb_name, client_domain, get_remote_machine_name(), local_lm_blob.data ? &local_lm_blob : NULL, local_nt_blob.data ? &local_nt_blob : NULL, NULL, NULL, - plaintext_password.data && plaintext_password.length ? &plaintext_password : NULL, - False); + plaintext_password_string, + AUTH_PASSWORD_PLAIN); + + if (plaintext_password_string) { + memset(plaintext_password_string, '\0', strlen(plaintext_password_string)); + talloc_free(plaintext_password_string); + } data_blob_free(&local_lm_blob); return NT_STATUS_IS_OK(ret) ? True : False; @@ -361,7 +364,7 @@ NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info, lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL, nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL, NULL, NULL, NULL, - True); + AUTH_PASSWORD_RESPONSE); } /**************************************************************************** @@ -379,7 +382,7 @@ bool make_user_info_guest(struct auth_usersupplied_info **user_info) NULL, NULL, NULL, NULL, NULL, - True); + AUTH_PASSWORD_RESPONSE); return NT_STATUS_IS_OK(nt_status) ? True : False; } diff --git a/source3/auth/auth_wbc.c b/source3/auth/auth_wbc.c index 05097ee39f..e4fffc7cf8 100644 --- a/source3/auth/auth_wbc.c +++ b/source3/auth/auth_wbc.c @@ -71,13 +71,18 @@ static NTSTATUS check_wbc_security(const struct auth_context *auth_context, params.parameter_control= user_info->logon_parameters; /* Handle plaintext */ - if (!user_info->encrypted) { + switch (user_info->password_state) { + case AUTH_PASSWORD_PLAIN: + { DEBUG(3,("Checking plaintext password for %s.\n", user_info->mapped.account_name)); params.level = WBC_AUTH_USER_LEVEL_PLAIN; - params.password.plaintext = (char *)user_info->plaintext_password.data; - } else { + params.password.plaintext = user_info->password.plaintext; + } + case AUTH_PASSWORD_RESPONSE: + case AUTH_PASSWORD_HASH: + { DEBUG(3,("Checking encrypted password for %s.\n", user_info->mapped.account_name)); params.level = WBC_AUTH_USER_LEVEL_RESPONSE; @@ -86,12 +91,33 @@ static NTSTATUS check_wbc_security(const struct auth_context *auth_context, auth_context->challenge.data, sizeof(params.password.response.challenge)); - params.password.response.nt_length = user_info->nt_resp.length; - params.password.response.nt_data = user_info->nt_resp.data; - params.password.response.lm_length = user_info->lm_resp.length; - params.password.response.lm_data = user_info->lm_resp.data; + params.password.response.nt_length = user_info->password.response.nt.length; + params.password.response.nt_data = user_info->password.response.nt.data; + params.password.response.lm_length = user_info->password.response.lanman.length; + params.password.response.lm_data = user_info->password.response.lanman.data; + } +#if 0 + case AUTH_PASSWORD_HASH: + { + DEBUG(3,("Checking logon (hash) password for %s.\n", + user_info->mapped.account_name)); + params.level = WBC_AUTH_USER_LEVEL_HASH; + + if (user_info->password.hash.nt) { + memcpy(params.password.hash.nt_hash, user_info->password.hash.nt, sizeof(* user_info->password.hash.nt)); + } else { + memset(params.password.hash.nt_hash, '\0', sizeof(params.password.hash.nt_hash)); + } + + if (user_info->password.hash.lanman) { + memcpy(params.password.hash.lm_hash, user_info->password.hash.lanman, sizeof(* user_info->password.hash.lanman)); + } else { + memset(params.password.hash.lm_hash, '\0', sizeof(params.password.hash.lm_hash)); + } } +#endif + } /* we are contacting the privileged pipe */ become_root(); diff --git a/source3/auth/auth_winbind.c b/source3/auth/auth_winbind.c index f8678d5aed..dcf7e419c1 100644 --- a/source3/auth/auth_winbind.c +++ b/source3/auth/auth_winbind.c @@ -72,10 +72,10 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, auth_context->challenge.data, sizeof(params.password.response.challenge)); - params.password.response.nt_length = user_info->nt_resp.length; - params.password.response.nt_data = user_info->nt_resp.data; - params.password.response.lm_length = user_info->lm_resp.length; - params.password.response.lm_data = user_info->lm_resp.data; + params.password.response.nt_length = user_info->password.response.nt.length; + params.password.response.nt_data = user_info->password.response.nt.data; + params.password.response.lm_length = user_info->password.response.lanman.length; + params.password.response.lm_data = user_info->password.response.lanman.data; /* we are contacting the privileged pipe */ become_root(); diff --git a/source3/auth/check_samsec.c b/source3/auth/check_samsec.c index 5228811422..df5dc31b9c 100644 --- a/source3/auth/check_samsec.c +++ b/source3/auth/check_samsec.c @@ -41,11 +41,10 @@ static NTSTATUS sam_password_ok(TALLOC_CTX *mem_ctx, DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) { - struct samr_Password _lm_hash, _nt_hash, _client_lm_hash, _client_nt_hash; + NTSTATUS status; + struct samr_Password _lm_hash, _nt_hash; struct samr_Password *lm_hash = NULL; struct samr_Password *nt_hash = NULL; - struct samr_Password *client_lm_hash = NULL; - struct samr_Password *client_nt_hash = NULL; *user_sess_key = data_blob_null; *lm_sess_key = data_blob_null; @@ -68,36 +67,35 @@ static NTSTATUS sam_password_ok(TALLOC_CTX *mem_ctx, memcpy(_nt_hash.hash, nt_pw, sizeof(_nt_hash.hash)); nt_hash = &_nt_hash; } - if (user_info->lm_interactive_pwd.data && sizeof(_client_lm_hash.hash) == user_info->lm_interactive_pwd.length) { - memcpy(_client_lm_hash.hash, user_info->lm_interactive_pwd.data, sizeof(_lm_hash.hash)); - client_lm_hash = &_client_lm_hash; - } - if (user_info->nt_interactive_pwd.data && sizeof(_client_nt_hash.hash) == user_info->nt_interactive_pwd.length) { - memcpy(_client_nt_hash.hash, user_info->nt_interactive_pwd.data, sizeof(_nt_hash.hash)); - client_nt_hash = &_client_nt_hash; - } - - if (client_lm_hash || client_nt_hash) { - if (!nt_pw) { - return NT_STATUS_WRONG_PASSWORD; - } - *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16); - if (!user_sess_key->data) { - return NT_STATUS_NO_MEMORY; + switch (user_info->password_state) { + case AUTH_PASSWORD_HASH: + status = hash_password_check(mem_ctx, lp_lanman_auth(), + user_info->password.hash.lanman, + user_info->password.hash.nt, + username, + lm_hash, + nt_hash); + if (NT_STATUS_IS_OK(status)) { + if (nt_pw) { + *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16); + if (!user_sess_key->data) { + return NT_STATUS_NO_MEMORY; + } + SMBsesskeygen_ntv1(nt_pw, user_sess_key->data); + } } - SMBsesskeygen_ntv1(nt_pw, user_sess_key->data); - return hash_password_check(mem_ctx, lp_lanman_auth(), - client_lm_hash, - client_nt_hash, - username, - lm_hash, - nt_hash); - } else { + return status; + + /* Eventually we should test plaintext passwords in their own + * function, not assuming the caller has done a + * mapping */ + case AUTH_PASSWORD_PLAIN: + case AUTH_PASSWORD_RESPONSE: return ntlm_password_check(mem_ctx, lp_lanman_auth(), lp_ntlm_auth(), user_info->logon_parameters, challenge, - &user_info->lm_resp, &user_info->nt_resp, + &user_info->password.response.lanman, &user_info->password.response.nt, username, user_info->client.account_name, user_info->client.domain_name, @@ -105,6 +103,7 @@ static NTSTATUS sam_password_ok(TALLOC_CTX *mem_ctx, nt_hash, user_sess_key, lm_sess_key); } + return NT_STATUS_INVALID_PARAMETER; } /**************************************************************************** diff --git a/source3/auth/pass_check.c b/source3/auth/pass_check.c index 813540d9fa..d1b720c922 100644 --- a/source3/auth/pass_check.c +++ b/source3/auth/pass_check.c @@ -648,7 +648,7 @@ return NT_STATUS_OK on correct match, appropriate error otherwise ****************************************************************************/ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *password, - int pwlen, bool (*fn) (const char *, const char *), bool run_cracker) + bool (*fn) (const char *, const char *), bool run_cracker) { char *pass2 = NULL; int level = lp_passwordlevel(); @@ -662,7 +662,7 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas if (!password) return NT_STATUS_LOGON_FAILURE; - if (((!*password) || (!pwlen)) && !lp_null_passwords()) + if ((!*password) && !lp_null_passwords()) return NT_STATUS_LOGON_FAILURE; #if defined(WITH_PAM) @@ -676,11 +676,11 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas return NT_STATUS_NO_MEMORY; } - DEBUG(4, ("pass_check: Checking (PAM) password for user %s (l=%d)\n", user, pwlen)); + DEBUG(4, ("pass_check: Checking (PAM) password for user %s\n", user)); #else /* Not using PAM */ - DEBUG(4, ("pass_check: Checking password for user %s (l=%d)\n", user, pwlen)); + DEBUG(4, ("pass_check: Checking password for user %s\n", user)); if (!pass) { DEBUG(3, ("Couldn't find user %s\n", user)); diff --git a/source3/auth/user_info.c b/source3/auth/user_info.c index ea0073ad0c..55a6f96e40 100644 --- a/source3/auth/user_info.c +++ b/source3/auth/user_info.c @@ -34,10 +34,10 @@ NTSTATUS make_user_info(struct auth_usersupplied_info **user_info, const char *workstation_name, const DATA_BLOB *lm_pwd, const DATA_BLOB *nt_pwd, - const DATA_BLOB *lm_interactive_pwd, - const DATA_BLOB *nt_interactive_pwd, - const DATA_BLOB *plaintext, - bool encrypted) + const struct samr_Password *lm_interactive_pwd, + const struct samr_Password *nt_interactive_pwd, + const char *plaintext_password, + enum auth_password_state password_state) { DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name)); @@ -85,22 +85,27 @@ NTSTATUS make_user_info(struct auth_usersupplied_info **user_info, DEBUG(5,("making blobs for %s's user_info struct\n", internal_username)); if (lm_pwd) - (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length); + (*user_info)->password.response.lanman = data_blob(lm_pwd->data, lm_pwd->length); if (nt_pwd) - (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length); - if (lm_interactive_pwd) - (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length); - if (nt_interactive_pwd) - (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length); + (*user_info)->password.response.nt = data_blob(nt_pwd->data, nt_pwd->length); + if (lm_interactive_pwd) { + (*user_info)->password.hash.lanman = SMB_MALLOC_P(struct samr_Password); + memcpy((*user_info)->password.hash.lanman->hash, lm_interactive_pwd->hash, sizeof((*user_info)->password.hash.lanman->hash)); + } + + if (nt_interactive_pwd) { + (*user_info)->password.hash.nt = SMB_MALLOC_P(struct samr_Password); + memcpy((*user_info)->password.hash.nt->hash, nt_interactive_pwd->hash, sizeof((*user_info)->password.hash.nt->hash)); + } - if (plaintext) - (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length); + if (plaintext_password) + (*user_info)->password.plaintext = SMB_STRDUP(plaintext_password); - (*user_info)->encrypted = encrypted; + (*user_info)->password_state = password_state; (*user_info)->logon_parameters = 0; - DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name)); + DEBUG(10,("made a user_info for %s (%s)\n", internal_username, smb_name)); return NT_STATUS_OK; } @@ -122,11 +127,20 @@ void free_user_info(struct auth_usersupplied_info **user_info) SAFE_FREE((*user_info)->client.domain_name); SAFE_FREE((*user_info)->mapped.domain_name); SAFE_FREE((*user_info)->workstation_name); - data_blob_free(&(*user_info)->lm_resp); - data_blob_free(&(*user_info)->nt_resp); - data_blob_clear_free(&(*user_info)->lm_interactive_pwd); - data_blob_clear_free(&(*user_info)->nt_interactive_pwd); - data_blob_clear_free(&(*user_info)->plaintext_password); + data_blob_free(&(*user_info)->password.response.lanman); + data_blob_free(&(*user_info)->password.response.nt); + if ((*user_info)->password.hash.lanman) { + ZERO_STRUCTP((*user_info)->password.hash.lanman); + SAFE_FREE((*user_info)->password.hash.lanman); + } + if ((*user_info)->password.hash.nt) { + ZERO_STRUCTP((*user_info)->password.hash.nt); + SAFE_FREE((*user_info)->password.hash.nt); + } + if ((*user_info)->password.plaintext) { + memset((*user_info)->password.plaintext, '\0', strlen(((*user_info)->password.plaintext))); + SAFE_FREE((*user_info)->password.plaintext); + } ZERO_STRUCT(**user_info); } SAFE_FREE(*user_info); diff --git a/source3/include/auth.h b/source3/include/auth.h index b7089b8c0a..659c6be103 100644 --- a/source3/include/auth.h +++ b/source3/include/auth.h @@ -19,27 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -struct auth_usersupplied_info { - DATA_BLOB lm_resp; - DATA_BLOB nt_resp; - DATA_BLOB lm_interactive_pwd; - DATA_BLOB nt_interactive_pwd; - DATA_BLOB plaintext_password; - - bool encrypted; - struct { - char *account_name; /* username before/after mapping */ - char *domain_name; /* username before/after mapping */ - } client, mapped; - - bool was_mapped; /* Did the username map actually match? */ - char *internal_username; /* username after mapping */ - const char *workstation_name; /* workstation name (netbios calling - * name) unicode string */ - - uint32 logon_parameters; - -}; +#include "../auth/common_auth.h" struct extra_auth_info { struct dom_sid user_sid; @@ -155,6 +135,7 @@ struct auth_init_function_entry { struct auth_ntlmssp_state; /* Changed from 1 -> 2 to add the logon_parameters field. */ -#define AUTH_INTERFACE_VERSION 2 +/* Changed from 2 -> 3 when we reworked many auth structures to use IDL or be in common with Samba4 */ +#define AUTH_INTERFACE_VERSION 3 #endif /* _SMBAUTH_H_ */ diff --git a/source3/include/proto.h b/source3/include/proto.h index bc55eaff07..02faf880ec 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -79,13 +79,15 @@ NTSTATUS auth_unix_init(void); /* The following definitions come from auth/auth_util.c */ NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info, - const char *smb_name, - const char *client_domain, + const char *smb_name, + const char *client_domain, const char *workstation_name, - DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd, - DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd, - DATA_BLOB *plaintext, - bool encrypted); + DATA_BLOB *lm_pwd, + DATA_BLOB *nt_pwd, + const struct samr_Password *lm_interactive_pwd, + const struct samr_Password *nt_interactive_pwd, + const char *plaintext, + enum auth_password_state password_state); bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info, const char *smb_name, const char *client_domain, @@ -160,7 +162,7 @@ bool is_trusted_domain(const char* dom_name); /* The following definitions come from auth/user_info.c */ -NTSTATUS make_user_info(struct auth_usersupplied_info **user_info, +NTSTATUS make_user_info(struct auth_usersupplied_info **ret_user_info, const char *smb_name, const char *internal_username, const char *client_domain, @@ -168,10 +170,10 @@ NTSTATUS make_user_info(struct auth_usersupplied_info **user_info, const char *workstation_name, const DATA_BLOB *lm_pwd, const DATA_BLOB *nt_pwd, - const DATA_BLOB *lm_interactive_pwd, - const DATA_BLOB *nt_interactive_pwd, - const DATA_BLOB *plaintext, - bool encrypted); + const struct samr_Password *lm_interactive_pwd, + const struct samr_Password *nt_interactive_pwd, + const char *plaintext_password, + enum auth_password_state password_state); void free_user_info(struct auth_usersupplied_info **user_info); /* The following definitions come from auth/auth_winbind.c */ @@ -226,7 +228,7 @@ bool smb_pam_close_session(char *in_user, char *tty, char *rhost); void dfs_unlogin(void); NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *password, - int pwlen, bool (*fn) (const char *, const char *), bool run_cracker); + bool (*fn) (const char *, const char *), bool run_cracker); /* The following definitions come from auth/token_util.c */ diff --git a/source3/web/cgi.c b/source3/web/cgi.c index c81ef87e1a..0c1c80e724 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -374,7 +374,7 @@ static bool cgi_handle_authorization(char *line) */ if NT_STATUS_IS_OK(pass_check(pass, user, user_pass, - strlen(user_pass), NULL, False)) { + NULL, False)) { if (pass) { /* diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 70adc29b1e..e2c1d0d1b9 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1139,7 +1139,7 @@ static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx, status = make_user_info(&user_info, user, user, domain, domain, global_myname(), lm_resp, nt_resp, NULL, NULL, - NULL, True); + NULL, AUTH_PASSWORD_RESPONSE); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("make_user_info failed: %s\n", nt_errstr(status))); return status; |