Minor updates. A small dose of const.
[ira/wip.git] / source3 / auth / auth.c
index d6bc8aeadcc8053107254d18433e2fa1a3b9ea58..95c97182b852ce5963ebcc7a78e5a1c144d602eb 100644 (file)
 
 #include "includes.h"
 
-extern int DEBUGLEVEL;
-
-extern pstring global_myname;
-
 /****************************************************************************
  Check user is in correct domain if required
 ****************************************************************************/
@@ -40,7 +36,7 @@ static BOOL check_domain_match(char *user, char *domain)
    */
 
   if (!lp_allow_trusted_domains() &&
-      !strequal(lp_workgroup(), domain) ) {
+      (!strequal(lp_workgroup(), domain) || strequal("", domain))) {
       DEBUG(1, ("check_domain_match: Attempt to connect as user %s from domain %s denied.\n", user, domain));
       return False;
   } else {
@@ -54,163 +50,179 @@ 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 user %s with the new password interface\n", user_info->smb_username.str));
-       if (!check_domain_match(user_info->smb_username.str, user_info->domain.str)) {
+       const char *pdb_username;
+
+       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);
+               if (NT_STATUS_IS_OK(nt_status)) {
+                       DEBUG(5, ("check_password:  checking guest-account for user [%s] suceeded\n", 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)));
+                       
+               }               
+       }
+
+       /* 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 != NT_STATUS_OK) {
+       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 != NT_STATUS_OK)) {
+       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 != NT_STATUS_OK)) {
+       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->smb_username.str, nt_status);
+               smb_user_control(user_info, *server_info, nt_status);
        }
 
-       if (nt_status != NT_STATUS_OK) {
-               if ((user_info->plaintext_password.len > 0) 
-                   && (!lp_plaintext_to_smbpasswd())) {
+       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;
-               } 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 == NT_STATUS_OK) && !done_pam) {
-               /* We might not be root if we are an RPC call */
-               become_root();
-               nt_status = smb_pam_accountcheck(user_info->smb_username.str);
-               unbecome_root();
+       if (NT_STATUS_IS_OK(nt_status)) {
+               pdb_username = pdb_get_username((*server_info)->sam_account);
+               if (!done_pam && !(*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));
+                       } else {
+                               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 == NT_STATUS_OK) {
-               DEBUG(5, ("check_password:  Password for user %s suceeded\n", user_info->smb_username.str));
-       } else {
-               DEBUG(3, ("check_password:  Password for user %s FAILED with error %s\n", user_info->smb_username.str, get_nt_error_msg(nt_status)));
 
+       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)));
+               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 *user, char *domain, 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, smb_username, wksta_name;
+       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 = user;
-       smb_username.len = strlen(smb_username.str);
-
-       user_info.requested_username = smb_username;  /* For the time-being */
-       user_info.smb_username = smb_username;
-
-       user_info.wksta_name.str = client_name();
-       user_info.wksta_name.len = strlen(client_name());
-
-       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;
-
-                       /* 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;
+               return nt_status;
+       }  
+}
 
-       }
 
-       return check_password(&user_info, &server_info);
-}
 
-NTSTATUS pass_check_smb(char *user, char *domain,
-                       uchar *lm_pwd, int lm_pwd_len,
-                       uchar *nt_pwd, int nt_pwd_len)
-{
-       uchar chal[8];
+/****************************************************************************
+ COMPATABILITY INTERFACES:
+ ***************************************************************************/
 
-       if (!last_challenge(chal)) {
-               generate_random_buffer( chal, 8, False);
-       }
+/****************************************************************************
+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 pass_check_smb_with_chal(user, domain, chal, 
-                                       lm_pwd, lm_pwd_len,
-                                       nt_pwd, nt_pwd_len);
+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 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;
 }
 
 /****************************************************************************
@@ -218,29 +230,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)
 {
 
-       /* 
-        *  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 (pass_check_smb(user, lp_workgroup(), NULL, 0, (unsigned char *)password, pwlen) == NT_STATUS_OK) {
-               return True;
-       }
+       DATA_BLOB null_password = data_blob(NULL, 0);
+       extern BOOL global_encrypted_passwords_negotiated;
 
-       if (pass_check_smb(user, lp_workgroup(), (unsigned char *)password, pwlen, NULL, 0) == NT_STATUS_OK) {
-               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;
 }
 
+