summaryrefslogtreecommitdiff
path: root/source3/auth/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/auth/auth.c')
-rw-r--r--source3/auth/auth.c263
1 files changed, 118 insertions, 145 deletions
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 4bdbdf5555..4d1a566833 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -50,183 +50,160 @@ static BOOL check_domain_match(char *user, char *domain)
This functions does NOT need to be in a become_root()/unbecome_root() pair
as it makes the calls itself when needed.
+
+ The return value takes precedence over the contents of the server_info
+ struct. When the return is other than NT_STATUS_NOPROBLEMO the contents
+ of that structure is undefined.
+
****************************************************************************/
NTSTATUS check_password(const auth_usersupplied_info *user_info,
- auth_serversupplied_info *server_info)
+ auth_serversupplied_info **server_info)
{
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
BOOL done_pam = False;
-
- DEBUG(3, ("check_password: Checking password for smb user %s\\%s@%s with the new password interface\n",
- user_info->smb_username.str, user_info->requested_domain.str, user_info->wksta_name.str));
- if (!check_domain_match(user_info->smb_username.str, user_info->domain.str)) {
+
+ DEBUG(3, ("check_password: Checking password for unmapped user %s\\%s@%s with the new password interface\n",
+ user_info->smb_name.str, user_info->client_domain.str, user_info->wksta_name.str));
+
+ /* This needs to be sorted: If it doesn't match, what should we do? */
+ if (!check_domain_match(user_info->smb_name.str, user_info->domain.str)) {
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(7, ("check_password: Password (rhosts) for user %s suceeded\n", user_info->smb_name.str));
+ } else {
+ DEBUG(5, ("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)));
+
+ }
}
if (lp_security() >= SEC_SERVER) {
- smb_user_control(user_info->unix_username.str, nt_status);
+ smb_user_control(user_info, *server_info, nt_status);
}
if (!NT_STATUS_IS_OK(nt_status)) {
- if ((user_info->plaintext_password.len > 0)
- && (!lp_plaintext_to_smbpasswd())) {
+ 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;
- } else {
- nt_status = check_smbpasswd_security(user_info, server_info);
}
+
+ 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) && !done_pam) {
/* We might not be root if we are an RPC call */
become_root();
- nt_status = smb_pam_accountcheck(user_info->unix_username.str);
+ nt_status = smb_pam_accountcheck(pdb_get_username((*server_info)->sam_account));
unbecome_root();
- }
+ if (NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(5, ("check_password: PAM Account for user %s suceeded\n", user_info->smb_name.str));
+ } else {
+ DEBUG(3, ("check_password: PAM Account 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)) {
- DEBUG(5, ("check_password: Password for smb user %s suceeded\n", user_info->smb_username.str));
+ DEBUG(5, ("check_password: Password for smb user %s suceeded\n", user_info->smb_name.str));
} else {
- DEBUG(3, ("check_password: Password for smb user %s FAILED with error %s\n", user_info->smb_username.str, get_nt_error_msg(nt_status)));
-
+ DEBUG(3, ("check_password: Password for smb user %s FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
+ ZERO_STRUCTP(server_info);
}
+
return nt_status;
}
/****************************************************************************
- COMPATABILITY INTERFACES:
- ***************************************************************************/
-
-/****************************************************************************
-check if a username/password is OK assuming the password is a 24 byte
-SMB hash
-return True if the password is correct, False otherwise
+ Squash an NT_STATUS return in line with requirements for unauthenticated
+ connections. (session setups in particular)
****************************************************************************/
-NTSTATUS pass_check_smb_with_chal(char *smb_user, char *unix_user,
- char *domain, char* workstation,
- uchar chal[8],
- uchar *lm_pwd, int lm_pwd_len,
- uchar *nt_pwd, int nt_pwd_len)
+NTSTATUS nt_status_squash(NTSTATUS nt_status)
{
-
- auth_usersupplied_info user_info;
- auth_serversupplied_info server_info;
- AUTH_STR ourdomain, theirdomain, unix_username, smb_username,
- wksta_name;
- NTSTATUS result;
+ if NT_STATUS_IS_OK(nt_status) {
+ return nt_status;
+ } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
+ /* Match WinXP and don't give the game away */
+ return NT_STATUS_LOGON_FAILURE;
- ZERO_STRUCT(user_info);
- ZERO_STRUCT(ourdomain);
- ZERO_STRUCT(theirdomain);
- ZERO_STRUCT(smb_username);
- ZERO_STRUCT(wksta_name);
-
- ourdomain.str = lp_workgroup();
- ourdomain.len = strlen(ourdomain.str);
-
- theirdomain.str = domain;
- theirdomain.len = strlen(theirdomain.str);
-
- user_info.requested_domain = theirdomain;
- user_info.domain = ourdomain;
-
- smb_username.str = smb_user;
- smb_username.len = strlen(smb_username.str);
-
- /* If unix user is NULL, use smb user */
-
- unix_username.str = unix_user ? unix_user : smb_user;
- unix_username.len = strlen(unix_username.str);
-
- user_info.unix_username = unix_username;
- user_info.smb_username = smb_username;
-
- wksta_name.str = workstation;
- wksta_name.len = strlen(workstation);
-
- user_info.wksta_name = wksta_name;
-
- memcpy(user_info.chal, chal, 8);
-
- if ((lm_pwd_len >= 24 || nt_pwd_len >= 24) ||
- (lp_encrypted_passwords() && (lm_pwd_len == 0) && lp_null_passwords())) {
- /* if 24 bytes long assume it is an encrypted password */
-
- user_info.lm_resp.buffer = (uint8 *)lm_pwd;
- user_info.lm_resp.len = lm_pwd_len;
- user_info.nt_resp.buffer = (uint8 *)nt_pwd;
- user_info.nt_resp.len = nt_pwd_len;
-
+ } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
+ /* Match WinXP and don't give the game away */
+ return NT_STATUS_LOGON_FAILURE;
} else {
- unsigned char local_lm_response[24];
- unsigned char local_nt_response[24];
-
- /*
- * Not encrypted - do so.
- */
-
- DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
-
- if (lm_pwd_len > 0) {
- SMBencrypt( (uchar *)lm_pwd, user_info.chal, local_lm_response);
- user_info.lm_resp.buffer = (uint8 *)local_lm_response;
- user_info.lm_resp.len = 24;
-
-
- /* WATCH OUT. This doesn't work if the incoming password is incorrectly cased.
- We might want to add a check here and only do an LM in that case */
+ return nt_status;
+ }
+}
- /* This encrypts the lm_pwd feild, which actualy contains the password
- rather than the nt_pwd field becouse that contains nothing */
- SMBNTencrypt((uchar *)lm_pwd, user_info.chal, local_nt_response);
- user_info.nt_resp.buffer = (uint8 *)local_nt_response;
- user_info.nt_resp.len = 24;
- }
-
- user_info.plaintext_password.str = (char *)lm_pwd;
- user_info.plaintext_password.len = lm_pwd_len;
- }
- result = check_password(&user_info, &server_info);
+/****************************************************************************
+ COMPATABILITY INTERFACES:
+ ***************************************************************************/
- free_serversupplied_info(&server_info); /* No info needed */
+/****************************************************************************
+check if a username/password is OK assuming the password is a 24 byte
+SMB hash
+return True if the password is correct, False otherwise
+****************************************************************************/
- return result;
-}
+static NTSTATUS pass_check_smb(char *smb_name,
+ char *domain,
+ DATA_BLOB lm_pwd,
+ DATA_BLOB nt_pwd,
+ DATA_BLOB plaintext_password,
+ BOOL encrypted)
-NTSTATUS pass_check_smb(char *smb_user, char *unix_user,
- char *domain, char *workstation,
- uchar *lm_pwd, int lm_pwd_len,
- uchar *nt_pwd, int nt_pwd_len)
{
- uchar chal[8];
-
- if (!last_challenge(chal)) {
- generate_random_buffer( chal, 8, False);
- }
-
- return pass_check_smb_with_chal(smb_user, unix_user,
- domain, workstation, chal,
- lm_pwd, lm_pwd_len,
- nt_pwd, nt_pwd_len);
-
+ NTSTATUS nt_status;
+ auth_usersupplied_info *user_info = NULL;
+ auth_serversupplied_info *server_info = NULL;
+
+ 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);
+ free_user_info(&user_info);
+ free_server_info(&server_info);
+ return nt_status;
}
/****************************************************************************
@@ -234,36 +211,32 @@ check if a username/password pair is OK either via the system password
database or the encrypted SMB password database
return True if the password is correct, False otherwise
****************************************************************************/
-BOOL password_ok(char *user, char *password, int pwlen)
+BOOL password_ok(char *smb_name, DATA_BLOB password_blob)
{
- extern fstring remote_machine;
- /*
- * This hack must die! But until I rewrite the rest of samba
- * it must stay - abartlet 2001-08-03
- */
-
- if ((pwlen == 0) && !lp_null_passwords()) {
- DEBUG(4,("Null passwords not allowed.\n"));
- return False;
- }
-
- /* The password could be either NTLM or plain LM. Try NTLM first, but fall-through as
- required. */
- if (NT_STATUS_IS_OK(pass_check_smb(user, NULL, remote_machine, lp_workgroup(), NULL, 0, (unsigned char *)password, pwlen))) {
- return True;
- }
+ DATA_BLOB null_password = data_blob(NULL, 0);
+ extern BOOL global_encrypted_passwords_negotiated;
- if (NT_STATUS_IS_OK(pass_check_smb(user, NULL, remote_machine, lp_workgroup(), (unsigned char *)password, pwlen, NULL, 0))) {
- return True;
+ if (global_encrypted_passwords_negotiated) {
+ /*
+ * 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))) {
+ return True;
+ }
+
+ if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, global_encrypted_passwords_negotiated))) {
+ 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))) {
+ return True;
+ }
}
return False;
}
-/* Free a auth_serversupplied_info structure */
-void free_serversupplied_info(auth_serversupplied_info *server_info)
-{
- SAFE_FREE(server_info->group_rids);
-}