This is a farily large patch (3300 lines) and reworks most of the AuthRewrite
authorAndrew Bartlett <abartlet@samba.org>
Wed, 31 Oct 2001 10:46:25 +0000 (10:46 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 31 Oct 2001 10:46:25 +0000 (10:46 +0000)
code.

In particular this assists tpot in some of his work, becouse it provides the
connection between the authenticaion and the vuid generation.

Major Changes:
- Fully malloc'ed structures.
  - Massive rework of the code so that all structures are made and destroyed
    using malloc and free, rather than hanging around on the stack.
- SAM_ACCOUNT unix uids and gids are now pointers to the same, to allow them
   to be declared 'invalid' without the chance that people might get ROOT by
   default.

- kill off some of the "DOMAIN\user" lookups.  These can be readded at a more
  appropriate place (probably domain_client_validate.c) in the future. They
  don't belong in session setups.

- Massive introduction of DATA_BLOB structures, particularly for passwords.

- Use NTLMSSP flags to tell the backend what its getting, rather than magic
  lenghths.

- Fix winbind back up again, but tpot is redoing this soon anyway.

- Abstract much of the work in srv_netlog_nt back into auth helper functions.

This is a LARGE change, and any assistance is testing it is appriciated.

Domain logons are still broken (as far as I can tell) but other functionality
seems
intact.

Needs testing with a wide variety of MS clients.

Andrew Bartlett
(This used to be commit f70fb819b2f57bd57232b51808345e2319d52f6c)

32 files changed:
source3/Makefile.in
source3/auth/auth.c
source3/auth/auth_domain.c
source3/auth/auth_rhosts.c
source3/auth/auth_sam.c
source3/auth/auth_server.c
source3/auth/auth_unix.c
source3/auth/auth_util.c
source3/include/auth.h
source3/include/smb.h
source3/libsmb/domain_client_validate.c
source3/libsmb/smbencrypt.c
source3/nsswitch/winbindd_pam.c
source3/passdb/passdb.c
source3/passdb/pdb_smbpasswd.c
source3/printing/nt_printing.c
source3/rpc_client/cli_login.c
source3/rpc_parse/parse_net.c
source3/rpc_server/srv_netlog_nt.c
source3/rpc_server/srv_pipe.c
source3/rpc_server/srv_srvsvc_nt.c
source3/smbd/auth.c
source3/smbd/auth_domain.c
source3/smbd/auth_rhosts.c
source3/smbd/auth_server.c
source3/smbd/auth_smbpasswd.c
source3/smbd/auth_unix.c
source3/smbd/auth_util.c
source3/smbd/password.c
source3/smbd/reply.c
source3/smbd/service.c
source3/smbd/sesssetup.c

index f582bd8e190d091acbe36c5c5e44c36e5d0d05f5..ea15da5ca3c944edae80fcd6f7de0566b2b6123a 100644 (file)
@@ -398,7 +398,7 @@ WINBINDD_OBJ1 = \
                nsswitch/winbindd_cm.o
 
 NECESSARY_BECAUSE_SAMBA_DEPENDENCIES_ARE_SO_BROKEN_OBJ = \
-               libsmb/domain_client_validate.o \
+               libsmb/domain_client_validate.o smbd/auth_util.o \
                rpc_client/cli_netlogon.o rpc_client/cli_login.o 
 
 WINBINDD_OBJ = \
index 4bdbdf5555ecb66341792e98ce6e303afa78b0a9..4d1a5668337d8ef8a920db8970d912222772dfbd 100644 (file)
@@ -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);
-}
index bcd41bacdba35d7064f83f82fbb301970b1db005..f20da196076bbe72d3e2d8894848c3dd0651882b 100644 (file)
@@ -29,7 +29,7 @@ BOOL global_machine_password_needs_changing = False;
 ****************************************************************************/
 
 NTSTATUS check_domain_security(const auth_usersupplied_info *user_info, 
-                              auth_serversupplied_info *server_info)
+                              auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
        char *p, *pserver;
index 9f5f1e10e50e864fbf601a7334ffa9237d1ba90f..9c07e48a9b673d6ebc0748a575612c58461b3b61 100644 (file)
@@ -131,11 +131,11 @@ static BOOL check_user_equiv(const char *user, const char *remote, const char *e
 /****************************************************************************
 check for a possible hosts equiv or rhosts entry for the user
 ****************************************************************************/
-static BOOL check_hosts_equiv(char *user) /* should be const... */
+
+static BOOL check_hosts_equiv(struct passwd *pass)
 {
   char *fname = NULL;
   pstring rhostsfile;
-  struct passwd *pass = Get_Pwnam(user);
 
   if (!pass) 
     return(False);
@@ -149,15 +149,15 @@ static BOOL check_hosts_equiv(char *user) /* should be const... */
   }
   
   if (lp_use_rhosts())
-    {
-      char *home = pass->pw_dir;
-      if (home) {
-             slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
-             if (check_user_equiv(pass->pw_name,client_name(),rhostsfile))
-                     return(True);
-      }
-    }
-
+  {
+         char *home = pass->pw_dir;
+         if (home) {
+                 slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
+                 if (check_user_equiv(pass->pw_name,client_name(),rhostsfile))
+                         return(True);
+         }
+  }
+  
   return(False);
 }
 
@@ -166,15 +166,21 @@ static BOOL check_hosts_equiv(char *user) /* should be const... */
 ****************************************************************************/
 
 NTSTATUS check_rhosts_security(const auth_usersupplied_info *user_info, 
-                            auth_serversupplied_info *server_info)
+                            auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
-
-       become_root();
-       if (check_hosts_equiv(user_info->unix_username.str)) {
-               nt_status = NT_STATUS_OK;
+       struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
+       
+       if (pass) {
+               become_root();
+               if (check_hosts_equiv(pass)) {
+                       nt_status = NT_STATUS_OK;
+                       make_server_info_pw(server_info, pass);
+               }
+               unbecome_root();
+       } else {
+               nt_status = NT_STATUS_NO_SUCH_USER;
        }
-       unbecome_root();
 
        return nt_status;
 }
index 84ca8d03be9add23b5729969d43246fd811b2234..d4283429ce2162425fa015a0c553aad952040bdc 100644 (file)
 /****************************************************************************
 core of smb password checking routine.
 ****************************************************************************/
-static BOOL smb_pwd_check_ntlmv1(const uchar *password,
+static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
                                const uchar *part_passwd,
-                               const uchar *c8,
-                               char user_sess_key[16])
+                               DATA_BLOB sec_blob,
+                               uint8 user_sess_key[16])
 {
-  /* Finish the encryption of part_passwd. */
-  uchar p24[24];
-
-  if (part_passwd == NULL) {
-         DEBUG(10,("No password set - DISALLOWING access\n"));
-         /* No password set - always false ! */
-         return False;
-  }
+       /* Finish the encryption of part_passwd. */
+       uchar p24[24];
+       
+       if (part_passwd == NULL) {
+               DEBUG(10,("No password set - DISALLOWING access\n"));
+               /* No password set - always false ! */
+               return False;
+       }
+       
+       if (sec_blob.length != 8) {
+               DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challange size (%d)\n", sec_blob.length));
+               return False;
+       }
+       
+       if (nt_response.length != 24) {
+               DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", nt_response.length));
+               return False;
+       }
 
-  SMBOWFencrypt(part_passwd, c8, p24);
+       SMBOWFencrypt(part_passwd, sec_blob.data, p24);
        if (user_sess_key != NULL)
        {
                SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key);
        }
-
-
-
+       
+       
+       
 #if DEBUG_PASSWORD
        DEBUG(100,("Part password (P16) was |"));
        dump_data(100, part_passwd, 16);
        DEBUG(100,("Password from client was |"));
-       dump_data(100, password, 24);
+       dump_data(100, nt_response.data, nt_response.length);
        DEBUG(100,("Given challenge was |"));
-       dump_data(100, c8, 8);
+       dump_data(100, sec_blob.data, sec_blob.length);
        DEBUG(100,("Value from encryption was |"));
        dump_data(100, p24, 24);
 #endif
-  return (memcmp(p24, password, 24) == 0);
+  return (memcmp(p24, nt_response.data, 24) == 0);
 }
 
 /****************************************************************************
 core of smb password checking routine.
 ****************************************************************************/
-static BOOL smb_pwd_check_ntlmv2(const uchar *password, size_t pwd_len,
+static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
                                const uchar *part_passwd,
-                               const uchar *c8,
+                               const DATA_BLOB sec_blob,
                                const char *user, const char *domain,
-                               char user_sess_key[16])
+                               uint8 user_sess_key[16])
 {
        /* Finish the encryption of part_passwd. */
        uchar kr[16];
-       uchar resp[16];
+       uchar value_from_encryption[16];
+       uchar client_response[16];
+       DATA_BLOB client_key_data;
 
        if (part_passwd == NULL)
        {
@@ -81,25 +93,42 @@ static BOOL smb_pwd_check_ntlmv2(const uchar *password, size_t pwd_len,
                return False;
        }
 
+       if (ntv2_response.length < 16) {
+               /* We MUST have more than 16 bytes, or the stuff below will go
+                  crazy... */
+               DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", 
+                         ntv2_response.length));
+               return False;
+       }
+
+       client_key_data = data_blob(ntv2_response.data+16, ntv2_response.length-16);
+       memcpy(client_response, ntv2_response.data, ntv2_response.length);
+
+       if (!client_key_data.data) {
+               return False;
+       }
+
        ntv2_owf_gen(part_passwd, user, domain, kr);
-       SMBOWFencrypt_ntv2(kr, c8, 8, password+16, pwd_len-16, (char *)resp);
+       SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, (char *)value_from_encryption);
        if (user_sess_key != NULL)
        {
-               SMBsesskeygen_ntv2(kr, resp, user_sess_key);
+               SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key);
        }
 
 #if DEBUG_PASSWORD
        DEBUG(100,("Part password (P16) was |"));
        dump_data(100, part_passwd, 16);
        DEBUG(100,("Password from client was |"));
-       dump_data(100, password, pwd_len);
+       dump_data(100, ntv2_response.data, ntv2_response.length);
+       DEBUG(100,("Variable data from client was |"));
+       dump_data(100, ntv2_response.data, ntv2_response.length);
        DEBUG(100,("Given challenge was |"));
-       dump_data(100, c8, 8);
+       dump_data(100, sec_blob.data, sec_blob.length);
        DEBUG(100,("Value from encryption was |"));
-       dump_data(100, resp, 16);
+       dump_data(100, value_from_encryption, 16);
 #endif
-
-       return (memcmp(resp, password, 16) == 0);
+       data_blob_clear_free(&client_key_data);
+       return (memcmp(value_from_encryption, client_response, 16) == 0);
 }
 
 
@@ -107,11 +136,12 @@ static BOOL smb_pwd_check_ntlmv2(const uchar *password, size_t pwd_len,
  Do a specific test for an smb password being correct, given a smb_password and
  the lanman and NT responses.
 ****************************************************************************/
-NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info, char user_sess_key[16])
+NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info, uint8 user_sess_key[16])
 {
        const uint8 *nt_pw, *lm_pw;
        uint16  acct_ctrl = pdb_get_acct_ctrl(sampass);
-       
+       uint32 ntlmssp_flags;
+
        if (!user_info || !sampass) 
                return NT_STATUS_LOGON_FAILURE;
 
@@ -119,12 +149,12 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
        {
                if (lp_null_passwords()) 
                {
-                       DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", sampass->username));
+                       DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", pdb_get_username(sampass)));
                        return(NT_STATUS_OK);
                } 
                else 
                {
-                       DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", sampass->username));
+                       DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", pdb_get_username(sampass)));
                        return(NT_STATUS_LOGON_FAILURE);
                }               
        }
@@ -132,61 +162,84 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
        nt_pw = pdb_get_nt_passwd(sampass);
        lm_pw = pdb_get_lanman_passwd(sampass);
        
-       if (nt_pw != NULL && user_info->nt_resp.len > 0) {
-               if ((user_info->nt_resp.len > 24 )) {
+       ntlmssp_flags = user_info->ntlmssp_flags;
+
+       if (nt_pw == NULL) {
+               DEBUG(3,("smb_password_ok: NO NT password stored for user %s.\n", 
+                        pdb_get_username(sampass)));
+               /* No return, we want to check the LM hash below in this case */
+               ntlmssp_flags &= (~(NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2));
+       }
+
+       if (ntlmssp_flags & NTLMSSP_NEGOTIATE_NTLM2) {
                        /* We have the NT MD4 hash challenge available - see if we can
                           use it (ie. does it exist in the smbpasswd file).
                        */
                        DEBUG(4,("smb_password_ok: Checking NTLMv2 password\n"));
-                       if (smb_pwd_check_ntlmv2( user_info->nt_resp.buffer, 
-                                                 user_info->nt_resp.len, 
+                       if (smb_pwd_check_ntlmv2( user_info->nt_resp, 
                                                  nt_pw, 
-                                                 user_info->chal, user_info->smb_username.str, 
-                                                 user_info->requested_domain.str,
+                                                 user_info->sec_blob, user_info->smb_name.str, 
+                                                 user_info->client_domain.str,
                                                  user_sess_key))
                        {
                                return NT_STATUS_OK;
                        } else {
-                               DEBUG(4,("smb_password_ok: NTLMv2 password check failed\n"));
-                                       return NT_STATUS_WRONG_PASSWORD;
+                               DEBUG(3,("smb_password_ok: NTLMv2 password check failed\n"));
+                               return NT_STATUS_WRONG_PASSWORD;
                        }
-                               
-               } else if (lp_ntlm_auth() && (user_info->nt_resp.len == 24)) {
+       } else if (ntlmssp_flags & NTLMSSP_NEGOTIATE_NTLM) {
+                       if (lp_ntlm_auth()) {                           
                                /* We have the NT MD4 hash challenge available - see if we can
                                   use it (ie. does it exist in the smbpasswd file).
                                */
-                       DEBUG(4,("smb_password_ok: Checking NT MD4 password\n"));
-                       if (smb_pwd_check_ntlmv1(user_info->nt_resp.buffer, 
-                                                nt_pw, user_info->chal,
-                                                user_sess_key)) 
-                       {
-                               return NT_STATUS_OK;
+                               DEBUG(4,("smb_password_ok: Checking NT MD4 password\n"));
+                               if (smb_pwd_check_ntlmv1(user_info->nt_resp, 
+                                                        nt_pw, user_info->sec_blob,
+                                                        user_sess_key)) 
+                               {
+                                       return NT_STATUS_OK;
+                               } else {
+                                       DEBUG(3,("smb_password_ok: NT MD4 password check failed for user %s\n",pdb_get_username(sampass)));
+                                       return NT_STATUS_WRONG_PASSWORD;
+                               }
                        } else {
-                               DEBUG(4,("smb_password_ok: NT MD4 password check failed\n"));
-                               return NT_STATUS_WRONG_PASSWORD;
+                               DEBUG(2,("smb_password_ok: NTLMv1 passwords NOT PERMITTED for user %s\n",pdb_get_username(sampass)));                   
+                               /* No return, we want to check the LM hash below in this case */
                        }
-               } else {
-                       return NT_STATUS_LOGON_FAILURE;
-               }
        } 
 
-       if (lm_pw != NULL && user_info->lm_resp.len == 24) {
-               if (lp_lanman_auth()) {
-                       DEBUG(4,("smb_password_ok: Checking LM password\n"));
-                       if (smb_pwd_check_ntlmv1(user_info->lm_resp.buffer, 
-                                                lm_pw, user_info->chal,
-                                                user_sess_key)) 
-                       {
-                               return NT_STATUS_OK;
-                       } else {
-                               DEBUG(4,("smb_password_ok: LM password check failed\n"));
-                               return NT_STATUS_WRONG_PASSWORD;
-                       }       
+       if (lm_pw == NULL) {
+               DEBUG(3,("smb_password_ok: NO LanMan password set for user %s (and no NT password supplied)\n",pdb_get_username(sampass)));
+               ntlmssp_flags &= (~NTLMSSP_NEGOTIATE_OEM);              
+       }
+       
+       if (ntlmssp_flags & NTLMSSP_NEGOTIATE_OEM) {
+               
+               if (user_info->lm_resp.length != 24) {
+                       DEBUG(2,("smb_password_ok: invalid LanMan password length (%d) for user %s\n", 
+                                user_info->nt_resp.length, pdb_get_username(sampass)));                
                }
+               
+               if (!lp_lanman_auth()) {
+                       DEBUG(3,("smb_password_ok: Lanman passwords NOT PERMITTED for user %s\n",pdb_get_username(sampass)));                   
+                       return NT_STATUS_LOGON_FAILURE;
+               }
+               
+               DEBUG(4,("smb_password_ok: Checking LM password\n"));
+               if (smb_pwd_check_ntlmv1(user_info->lm_resp, 
+                                        lm_pw, user_info->sec_blob,
+                                        user_sess_key)) 
+               {
+                       return NT_STATUS_OK;
+               } else {
+                       DEBUG(4,("smb_password_ok: LM password check failed for user %s\n",pdb_get_username(sampass)));
+                       return NT_STATUS_WRONG_PASSWORD;
+               } 
        }
 
-       /* Should not be reached */
-       return NT_STATUS_LOGON_FAILURE;
+       /* Should not be reached, but if they send nothing... */
+       DEBUG(3,("smb_password_ok: NEITHER LanMan nor NT password supplied for user %s\n",pdb_get_username(sampass)));
+       return NT_STATUS_WRONG_PASSWORD;
 }
 
 /****************************************************************************
@@ -290,33 +343,58 @@ SMB hash supplied in the user_info structure
 return an NT_STATUS constant.
 ****************************************************************************/
 
-NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info)
+NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
 {
        SAM_ACCOUNT *sampass=NULL;
        BOOL ret;
        NTSTATUS nt_status;
+       uint8 user_sess_key[16];
+       const uint8* lm_hash;
 
        pdb_init_sam(&sampass);
 
        /* get the account information */
 
        become_root();
-       ret = pdb_getsampwnam(sampass, user_info->unix_username.str);
+       ret = pdb_getsampwnam(sampass, user_info->internal_username.str);
        unbecome_root();
 
        if (ret == False)
        {
-               DEBUG(1,("Couldn't find user '%s' in passdb file.\n", user_info->unix_username.str));
+               DEBUG(1,("Couldn't find user '%s' in passdb file.\n", user_info->internal_username.str));
                pdb_free_sam(&sampass);
                return NT_STATUS_NO_SUCH_USER;
        }
 
-       nt_status = sam_password_ok(sampass, user_info, (char *)(server_info->session_key));
+       nt_status = sam_password_ok(sampass, user_info, user_sess_key);
 
-       if NT_STATUS_IS_OK(nt_status) {
-               nt_status = sam_account_ok(sampass, user_info);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               pdb_free_sam(&sampass);
+               return nt_status;
        }
 
-       pdb_free_sam(&sampass);
+       nt_status = sam_account_ok(sampass, user_info);
+       
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               pdb_free_sam(&sampass);
+               return nt_status;
+       }
+
+       if (!make_server_info_sam(server_info, sampass)) {              
+               DEBUG(0,("failed to malloc memory for server_info\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       lm_hash = pdb_get_lanman_passwd((*server_info)->sam_account);
+       if (lm_hash) {
+               memcpy((*server_info)->first_8_lm_hash, lm_hash, 8);
+       }
+       
+       memcpy((*server_info)->session_key, user_sess_key, sizeof(user_sess_key));
+
        return nt_status;
 }
+
+
+
+
index 520417e3e09ac193b22415fa0c0da3c86cf154b8..ddbc284d50ce02bd79795edc83dfab197c364e79 100644 (file)
@@ -115,7 +115,7 @@ struct cli_state *server_cryptkey(void)
   - Validate a password with the password server.
 ****************************************************************************/
 
-NTSTATUS check_server_security(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info)
+NTSTATUS check_server_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
 {
        struct cli_state *cli;
        static unsigned char badpass[24];
@@ -134,8 +134,8 @@ NTSTATUS check_server_security(const auth_usersupplied_info *user_info, auth_ser
        if(badpass[0] == 0)
                memset(badpass, 0x1f, sizeof(badpass));
 
-       if((user_info->nt_resp.len == sizeof(badpass)) && 
-          !memcmp(badpass, user_info->nt_resp.buffer, sizeof(badpass))) {
+       if((user_info->nt_resp.length == sizeof(badpass)) && 
+          !memcmp(badpass, user_info->nt_resp.data, sizeof(badpass))) {
                /* 
                 * Very unlikely, our random bad password is the same as the users
                 * password.
@@ -206,11 +206,11 @@ use this machine as the password server.\n"));
         * not guest enabled, we can try with the real password.
         */
 
-       if (!cli_session_setup(cli, user_info->smb_username.str, 
-                              (char *)user_info->lm_resp.buffer
-                              user_info->lm_resp.len, 
-                              (char *)user_info->nt_resp.buffer
-                              user_info->nt_resp.len, 
+       if (!cli_session_setup(cli, user_info->smb_name.str, 
+                              (char *)user_info->lm_resp.data
+                              user_info->lm_resp.length
+                              (char *)user_info->nt_resp.data
+                              user_info->nt_resp.length
                               user_info->domain.str)) {
                DEBUG(1,("password server %s rejected the password\n", cli->desthost));
                /* Make this cli_nt_error() when the conversion is in */
@@ -227,5 +227,16 @@ use this machine as the password server.\n"));
 
        cli_ulogoff(cli);
 
+       if NT_STATUS_IS_OK(nt_status) {
+               struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
+               if (pass) {
+                       if (!make_server_info_pw(server_info, pass)) { 
+                               nt_status = NT_STATUS_NO_MEMORY;
+                       }
+               } else {
+                       nt_status = NT_STATUS_NO_SUCH_USER;
+               }
+       }
+
        return(nt_status);
 }
index 29a2a6eafb13505ba57a2db5c9b7eb52d28555a3..d456da1fdf7a85cab86a3dab0849472cbf6d912c 100644 (file)
@@ -82,22 +82,27 @@ check if a username/password is OK assuming the password
 in PLAIN TEXT
 ****************************************************************************/
 
-NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info)
+NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status;
        struct passwd *pass = NULL;
 
        become_root();
-       
-       pass = Get_Pwnam(user_info->unix_username.str);
+       pass = Get_Pwnam(user_info->internal_username.str);
 
        nt_status = pass_check(pass,
-                               pass ? pass->pw_name : user_info->unix_username.str, 
-                               user_info->plaintext_password.str,
-                               user_info->plaintext_password.len,
+                               pass ? pass->pw_name : user_info->internal_username.str, 
+                               (char *)user_info->plaintext_password.data,
+                               user_info->plaintext_password.length-1,
                                lp_update_encrypted() ? 
                                update_smbpassword_file : NULL,
                                True);
+       
+       if NT_STATUS_IS_OK(nt_status) {
+               if (pass) {
+                       make_server_info_pw(server_info, pass);
+               }
+       }
 
        unbecome_root();
 
index d3b9aa7001e75cebd1795ef1ffc266850395d548..297c482af52f43b0cad82e7410c14091f8e46c85 100644 (file)
@@ -25,6 +25,8 @@
 /* Data to do lanman1/2 password challenge. */
 static unsigned char saved_challenge[8];
 static BOOL challenge_sent=False;
+extern fstring remote_machine;
+extern pstring global_myname;
 
 /*******************************************************************
 Get the next challenge value - no repeats.
@@ -64,7 +66,7 @@ BOOL last_challenge(unsigned char *challenge)
  Create a UNIX user on demand.
 ****************************************************************************/
 
-static int smb_create_user(char *unix_user, char *homedir)
+static int smb_create_user(const char *unix_user, const char *homedir)
 {
        pstring add_script;
        int ret;
@@ -100,40 +102,560 @@ static int smb_delete_user(char *unix_user)
  Add and Delete UNIX users on demand, based on NTSTATUS codes.
 ****************************************************************************/
 
-void smb_user_control(char *unix_user, NTSTATUS nt_status) 
+void smb_user_control(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, NTSTATUS nt_status) 
 {
        struct passwd *pwd=NULL;
 
        if (NT_STATUS_IS_OK(nt_status)) {
-               /*
-                * User validated ok against Domain controller.
-                * If the admin wants us to try and create a UNIX
-                * user on the fly, do so.
-                */
-               if(lp_adduser_script() && !(pwd = smb_getpwnam(unix_user,True)))
-                       smb_create_user(unix_user, NULL);
-
-               if(lp_adduser_script() && pwd) {
-                       SMB_STRUCT_STAT st;
 
+               if (!(server_info->sam_fill_level & SAM_FILL_UNIX)) {
+                       
                        /*
-                        * Also call smb_create_user if the users home directory
-                        * doesn't exist. Used with winbindd to allow the script to
-                        * create the home directory for a user mapped with winbindd.
+                        * User validated ok against Domain controller.
+                        * If the admin wants us to try and create a UNIX
+                        * user on the fly, do so.
                         */
+                       
+                       if(lp_adduser_script() && !(pwd = Get_Pwnam(user_info->internal_username.str))) {
+                               smb_create_user(user_info->internal_username.str, NULL);
+                       }
+               } else {                        
+                       if(lp_adduser_script()) {
+                               SMB_STRUCT_STAT st;
+                               const char *home_dir = pdb_get_homedir(server_info->sam_account);
+                               /*
+                                * Also call smb_create_user if the users home directory
+                                * doesn't exist. Used with winbindd to allow the script to
+                                * create the home directory for a user mapped with winbindd.
+                                */
 
-                       if (pwd->pw_dir && (sys_stat(pwd->pw_dir, &st) == -1) && (errno == ENOENT))
-                               smb_create_user(unix_user, pwd->pw_dir);
+                               if (home_dir && 
+                                   (sys_stat(home_dir, &st) == -1) && (errno == ENOENT)) {
+                                       smb_create_user(user_info->internal_username.str, home_dir);
+                               }
+                       }
                }
-
-       } else if (NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_NO_SUCH_USER)) {
+       } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
                /*
                 * User failed to validate ok against Domain controller.
                 * If the failure was "user doesn't exist" and admin 
                 * wants us to try and delete that UNIX user on the fly,
                 * do so.
                 */
-               if(lp_deluser_script() && smb_getpwnam(unix_user,True))
-                       smb_delete_user(unix_user);
+               if (lp_deluser_script()) {
+                       smb_delete_user(user_info->internal_username.str);
+               }
+       }
+}
+
+/****************************************************************************
+ Create an auth_usersupplied_data structure
+****************************************************************************/
+
+BOOL make_user_info(auth_usersupplied_info **user_info, 
+                   char *smb_name, char *internal_username,
+                   char *client_domain, char *domain,
+                   char *wksta_name, DATA_BLOB sec_blob, 
+                   DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
+                   DATA_BLOB plaintext, 
+                   uint32 ntlmssp_flags, BOOL encrypted)
+{
+
+       DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
+
+       *user_info = malloc(sizeof(**user_info));
+       if (!user_info) {
+               DEBUG(0,("malloc failed for user_info (size %d)\n", sizeof(*user_info)));
+               return False;
+       }
+
+       ZERO_STRUCTP(*user_info);
+
+       DEBUG(5,("makeing strings for %s's user_info struct\n", internal_username));
+
+       (*user_info)->smb_name.str = strdup(smb_name);
+       if ((*user_info)->smb_name.str) { 
+               (*user_info)->smb_name.len = strlen(smb_name);
+       } else {
+               free_user_info(user_info);
+               return False;
+       }
+       
+       (*user_info)->internal_username.str = strdup(internal_username);
+       if ((*user_info)->internal_username.str) { 
+               (*user_info)->internal_username.len = strlen(internal_username);
+       } else {
+               free_user_info(user_info);
+               return False;
+       }
+
+       (*user_info)->domain.str = strdup(domain);
+       if ((*user_info)->domain.str) { 
+               (*user_info)->domain.len = strlen(domain);
+       } else {
+               free_user_info(user_info);
+               return False;
+       }
+
+       (*user_info)->client_domain.str = strdup(client_domain);
+       if ((*user_info)->client_domain.str) { 
+               (*user_info)->client_domain.len = strlen(client_domain);
+       } else {
+               free_user_info(user_info);
+               return False;
+       }
+
+       (*user_info)->wksta_name.str = strdup(wksta_name);
+       if ((*user_info)->wksta_name.str) { 
+               (*user_info)->wksta_name.len = strlen(wksta_name);
+       } else {
+               free_user_info(user_info);
+               return False;
        }
+
+       DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username));
+
+       (*user_info)->sec_blob = data_blob(sec_blob.data, sec_blob.length);
+       (*user_info)->lm_resp = data_blob(lm_pwd.data, lm_pwd.length);
+       (*user_info)->nt_resp = data_blob(nt_pwd.data, nt_pwd.length);
+       (*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length);
+
+       (*user_info)->encrypted = encrypted;
+       (*user_info)->ntlmssp_flags = ntlmssp_flags;
+
+       DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
+
+       return True;
 }
+
+/****************************************************************************
+ Create an auth_usersupplied_data structure after appropriate mapping.
+****************************************************************************/
+
+BOOL make_user_info_map(auth_usersupplied_info **user_info, 
+                       char *smb_name, 
+                       char *client_domain, 
+                       char *wksta_name, DATA_BLOB sec_blob, 
+                       DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
+                       DATA_BLOB plaintext, 
+                       uint32 ntlmssp_flags, BOOL encrypted)
+{
+       char *domain;
+       fstring internal_username;
+       fstrcpy(internal_username, smb_name);
+       map_username(internal_username); 
+       
+       if (lp_allow_trusted_domains()) {
+               domain = client_domain;
+       } else {
+               domain = lp_workgroup();
+       }
+       
+       return make_user_info(user_info, 
+                             smb_name, internal_username,
+                             client_domain, domain,
+                             wksta_name, sec_blob,
+                             lm_pwd, nt_pwd,
+                             plaintext, 
+                             ntlmssp_flags, encrypted);
+       
+}
+
+/****************************************************************************
+ Create an auth_usersupplied_data, making the DATA_BLOBs here. 
+ Decrupt and encrypt the passwords.
+****************************************************************************/
+
+BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
+                                    char *smb_name, 
+                                    char *client_domain, 
+                                    char *wksta_name, uchar chal[8],
+                                    uchar *lm_network_pwd, int lm_pwd_len,
+                                    uchar *nt_network_pwd, int nt_pwd_len)
+{
+       BOOL ret;
+       DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
+       DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
+       DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
+       DATA_BLOB plaintext_blob = data_blob(NULL, 0);
+       uint32 ntlmssp_flags = 0;
+
+       if (lm_pwd_len)
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+       if (nt_pwd_len)
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM; 
+       
+       ret = make_user_info_map(user_info, 
+                                smb_name, client_domain, 
+                                wksta_name, sec_blob, 
+                                nt_blob, lm_blob,
+                                plaintext_blob, 
+                                ntlmssp_flags, True);
+               
+       data_blob_free(&lm_blob);
+       data_blob_free(&nt_blob);
+       return ret;
+}
+
+/****************************************************************************
+ Create an auth_usersupplied_data, making the DATA_BLOBs here. 
+ Decrupt and encrypt the passwords.
+****************************************************************************/
+
+BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
+                               char *smb_name, 
+                               char *client_domain, 
+                               char *wksta_name, 
+                               uchar *lm_interactive_pwd, int lm_pwd_len,
+                               uchar *nt_interactive_pwd, int nt_pwd_len,
+                               uchar *dc_sess_key)
+{
+       char nt_pwd[16];
+       char lm_pwd[16];
+       unsigned char local_lm_response[24];
+       unsigned char local_nt_response[24];
+       unsigned char key[16];
+       uint8 chal[8];
+       uint32 ntlmssp_flags = 0;
+       
+       generate_random_buffer(chal, 8, False);
+
+       memset(key, 0, 16);
+       memcpy(key, dc_sess_key, 8);
+       
+       memcpy(lm_pwd, lm_interactive_pwd, 16);
+       memcpy(nt_pwd, nt_interactive_pwd, 16);
+       
+#ifdef DEBUG_PASSWORD
+       DEBUG(100,("key:"));
+       dump_data(100, (char *)key, 16);
+       
+       DEBUG(100,("lm owf password:"));
+       dump_data(100, lm_pwd, 16);
+       
+       DEBUG(100,("nt owf password:"));
+       dump_data(100, nt_pwd, 16);
+#endif
+       
+       SamOEMhash((uchar *)lm_pwd, key, 16);
+       SamOEMhash((uchar *)nt_pwd, key, 16);
+       
+#ifdef DEBUG_PASSWORD
+       DEBUG(100,("decrypt of lm owf password:"));
+       dump_data(100, lm_pwd, 16);
+       
+       DEBUG(100,("decrypt of nt owf password:"));
+       dump_data(100, nt_pwd, 16);
+#endif
+       
+       generate_random_buffer(chal, 8, False);
+       SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
+       SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
+       
+       /* Password info parinoia */
+       ZERO_STRUCT(lm_pwd);
+       ZERO_STRUCT(nt_pwd);
+       ZERO_STRUCT(key);
+
+       {
+               BOOL ret;
+               DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
+               DATA_BLOB local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
+               DATA_BLOB local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
+               DATA_BLOB plaintext_blob = data_blob(NULL, 0);
+
+               ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM;         
+               ret = make_user_info_map(user_info, 
+                                        smb_name, client_domain, 
+                                        wksta_name, sec_blob, 
+                                        local_nt_blob,
+                                        local_lm_blob,
+                                        plaintext_blob, 
+                                        ntlmssp_flags, True);
+               
+               data_blob_free(&local_lm_blob);
+               data_blob_free(&local_nt_blob);
+               return ret;
+       }
+}
+
+/****************************************************************************
+ Create an auth_usersupplied_data structure
+****************************************************************************/
+
+BOOL make_user_info_for_winbind(auth_usersupplied_info **user_info, 
+                               char *username,
+                               char *domain, 
+                               char *password)
+{
+       unsigned char local_lm_response[24];
+       unsigned char local_nt_response[24];
+       char chal[8];
+       DATA_BLOB local_lm_blob;
+       DATA_BLOB local_nt_blob;
+       DATA_BLOB plaintext_blob;
+       uint32 ntlmssp_flags = 0;
+
+       /*
+        * Not encrypted - do so.
+        */
+       
+       DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
+       
+       generate_random_buffer(chal, 8, False);
+
+       if (*password) {
+               SMBencrypt( (uchar *)password, chal, local_lm_response);
+               
+               /* This encrypts the lm_pwd feild, which actualy contains the password
+                  rather than the nt_pwd field becouse that contains nothing */
+               
+               /* 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 */
+               
+               SMBNTencrypt((uchar *)password, chal, local_nt_response);
+
+               local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
+               local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
+               plaintext_blob = data_blob(password, strlen(password)+1);
+               if ((!local_lm_blob.data) || (!local_nt_blob.data)|| (!plaintext_blob.data)) {
+                       data_blob_free(&local_lm_blob);
+                       data_blob_free(&local_nt_blob);
+                       data_blob_clear_free(&plaintext_blob);
+                       return False;
+               }
+               ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM;
+       } else {
+               local_lm_blob = data_blob(NULL, 0);
+               local_nt_blob = data_blob(NULL, 0);
+               plaintext_blob = data_blob(NULL, 0);
+       }
+
+       {
+               BOOL ret;
+               DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
+               
+               if (!sec_blob.data) {
+                       return False;
+               }
+
+               ret = make_user_info(user_info, 
+                                    username, username,
+                                    domain, domain, 
+                                    global_myname, sec_blob, 
+                                    local_nt_blob,
+                                    local_lm_blob,
+                                    plaintext_blob, 
+                                    ntlmssp_flags, False);
+               
+               data_blob_free(&local_lm_blob);
+               data_blob_free(&local_nt_blob);
+               data_blob_clear_free(&plaintext_blob);
+               return ret;
+       }
+}
+
+/****************************************************************************
+ Create an auth_usersupplied_data, making the DATA_BLOBs here. 
+ Decrupt and encrypt the passwords.
+****************************************************************************/
+
+BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info, 
+                                char *smb_name, 
+                                char *client_domain, 
+                                uchar chal[8],
+                                uchar *lm_network_pwd, int lm_pwd_len,
+                                uchar *nt_network_pwd, int nt_pwd_len)
+{
+       BOOL ret;
+       DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
+       DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
+       DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
+       DATA_BLOB plaintext_blob = data_blob(NULL, 0);
+       uint32 ntlmssp_flags = 0;
+
+       if (lm_pwd_len)
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+       if (nt_pwd_len)
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM; 
+       
+       ret = make_user_info(user_info, 
+                            smb_name, smb_name, 
+                            client_domain, client_domain, 
+                            global_myname, sec_blob, 
+                            nt_blob, lm_blob,
+                            plaintext_blob, 
+                            ntlmssp_flags, True);
+
+       data_blob_free(&lm_blob);
+       data_blob_free(&nt_blob);
+       return ret;
+}
+
+/****************************************************************************
+ Create an auth_usersupplied_data structure
+****************************************************************************/
+
+BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
+                             char *smb_name,
+                             char *client_domain, 
+                             DATA_BLOB lm_resp, DATA_BLOB nt_resp,
+                             DATA_BLOB plaintext_password,
+                             BOOL encrypted)
+{
+       uchar chal[8];
+
+       DATA_BLOB local_lm_blob;
+       DATA_BLOB local_nt_blob;
+       DATA_BLOB sec_blob;
+       BOOL ret = False;
+       uint32 ntlmssp_flags = 0;
+                       
+       if (encrypted) {
+               DATA_BLOB no_plaintext_blob = data_blob(NULL, 0); 
+               if (!last_challenge(chal)) {
+                       DEBUG(0,("Encrypted login but no challange set!\n"));
+                       return False;
+               }
+               sec_blob = data_blob(chal, 8);
+               
+               if (lm_resp.length == 24) {
+                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+               }
+               if (nt_resp.length == 0) {
+               } else if (nt_resp.length == 24) {
+                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
+               } else {
+                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
+               }
+
+               return make_user_info_map(user_info, smb_name, 
+                                         client_domain, 
+                                         remote_machine, sec_blob,
+                                         lm_resp, 
+                                         nt_resp, 
+                                         no_plaintext_blob, 
+                                         ntlmssp_flags, encrypted);
+       }
+
+       generate_random_buffer(chal, 8, False);
+
+       sec_blob = data_blob(chal, 8);
+       
+       /*
+        * Not encrypted - do so.
+        */
+       
+       DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
+       
+       if (plaintext_password.data) {
+               unsigned char local_lm_response[24];
+
+               SMBencrypt( (uchar *)plaintext_password.data, chal, local_lm_response);
+               local_lm_blob = data_blob(local_lm_response, 24);
+               
+               /* We can't do an NT hash here, as the password needs to be case insensitive */
+               local_nt_blob = data_blob(NULL, 0); 
+               
+               ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM;
+       } else {
+               local_lm_blob = data_blob(NULL, 0); 
+               local_nt_blob = data_blob(NULL, 0); 
+       }
+       
+       ret = make_user_info_map(user_info, smb_name,
+                                client_domain, 
+                                remote_machine,
+                                sec_blob,
+                                local_lm_blob,
+                                local_nt_blob,
+                                plaintext_password, 
+                                ntlmssp_flags, encrypted);
+       
+       data_blob_free(&local_lm_blob);
+       return ret;
+}
+
+BOOL make_server_info(auth_serversupplied_info **server_info) 
+{
+       *server_info = malloc(sizeof(**server_info));
+       if (!*server_info) {
+               DEBUG(0,("make_server_info_sam: malloc failed!\n"));
+               return False;
+       }
+       ZERO_STRUCTP(*server_info);
+       return True;
+}
+
+BOOL make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass) 
+{
+       if (!make_server_info(server_info)) {
+               return False;
+       }
+
+       (*server_info)->sam_fill_level = SAM_FILL_ALL;
+       (*server_info)->sam_account = sampass;
+
+       DEBUG(5,("make_server_info_sam: made sever info for user %s\n",
+                pdb_get_username((*server_info)->sam_account)));
+       return True;
+}
+
+BOOL make_server_info_pw(auth_serversupplied_info **server_info, struct passwd *pwd)
+{
+       SAM_ACCOUNT *sampass = NULL;
+       if (!pdb_init_sam_pw(&sampass, pwd)) {          
+               return False;
+       }
+       return make_server_info_sam(server_info, sampass);
+}
+
+void free_user_info(auth_usersupplied_info **user_info)
+{
+       DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
+       if (*user_info != NULL) {
+               if ((*user_info)->smb_name.str) {
+                       DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
+               }
+               SAFE_FREE((*user_info)->smb_name.str);
+               SAFE_FREE((*user_info)->internal_username.str);
+               SAFE_FREE((*user_info)->client_domain.str);
+               SAFE_FREE((*user_info)->domain.str);
+               data_blob_free(&(*user_info)->sec_blob);
+               data_blob_free(&(*user_info)->lm_resp);
+               data_blob_free(&(*user_info)->nt_resp);
+               SAFE_FREE((*user_info)->interactive_password);
+               data_blob_clear_free(&(*user_info)->plaintext_password);
+               ZERO_STRUCT(**user_info);
+       }
+       SAFE_FREE(*user_info);
+}
+
+/***************************************************************************
+ Clear out a server_info struct that has been allocated
+***************************************************************************/
+void free_server_info(auth_serversupplied_info **server_info)
+{
+       if (*server_info != NULL) {
+               pdb_free_sam(&(*server_info)->sam_account);
+               
+               /* call pam_end here, unless we know we are keeping it */
+               SAFE_FREE((*server_info)->group_rids);
+
+               ZERO_STRUCT(**server_info);
+       }
+       SAFE_FREE(*server_info);
+}
+
+/***************************************************************************
+ Make a server_info struct for a guest user 
+***************************************************************************/
+void make_server_info_guest(auth_serversupplied_info **server_info) 
+{
+       struct passwd *pass = sys_getpwnam(lp_guestaccount(-1));
+       
+       if (pass) {
+               make_server_info_pw(server_info, pass);
+       }
+}
+
index 9e99600e98f8730337051929d48922d1ce6e4865..427cb8b489958014c1cc490795551dad3cb729ff 100644 (file)
@@ -35,58 +35,44 @@ typedef struct unicode_string
        uchar *unistr;
 } AUTH_UNISTR;
 
-/* AUTH_BUFFER - 8-bit byte buffer */
-typedef struct auth_buffer
-{
-       int len;
-       uint8 *buffer;
-} AUTH_BUFFER;
-
-typedef struct net_password
-{
-       AUTH_BUFFER lm_resp;
-       AUTH_BUFFER nt_resp;
-} auth_net_password;
-
 typedef struct interactive_password
 {
        OWF_INFO          lm_owf;              /* LM OWF Password */
        OWF_INFO          nt_owf;              /* NT OWF Password */
 } auth_interactive_password;
 
-typedef struct plaintext_password
-{
-       AUTH_STR password;
-} auth_plaintext_password;
-
 typedef struct usersupplied_info
 {
        
-       AUTH_BUFFER lm_resp;
-       AUTH_BUFFER nt_resp;
+       DATA_BLOB lm_resp;
+       DATA_BLOB nt_resp;
        auth_interactive_password * interactive_password;
-        AUTH_STR plaintext_password;
+       DATA_BLOB plaintext_password;
        
-       uint8 chal[8];
+       BOOL encrypted;
+       
+       uint32 ntlmssp_flags;
+
+       DATA_BLOB sec_blob;
 
-       AUTH_STR           requested_domain;     /* domain name string */
+       AUTH_STR           client_domain;          /* domain name string */
        AUTH_STR           domain;               /* domain name after mapping */
-       AUTH_STR           unix_username;        /* username after mapping */
-       AUTH_STR           smb_username;         /* username before mapping */
+       AUTH_STR           internal_username;    /* username after mapping */
+       AUTH_STR           smb_name;        /* username before mapping */
        AUTH_STR           wksta_name;           /* workstation name (netbios calling name) unicode string */
        
 } auth_usersupplied_info;
 
+#define SAM_FILL_NAME  0x01
+#define SAM_FILL_INFO3 0x02
+#define SAM_FILL_SAM   0x04
+#define SAM_FILL_UNIX  0x08
+#define SAM_FILL_ALL (SAM_FILL_NAME | SAM_FILL_INFO3 | SAM_FILL_SAM | SAM_FILL_UNIX)
+
 typedef struct serversupplied_info
 {
-       AUTH_STR full_name;
-       AUTH_STR unix_user;
-       
        BOOL guest;
        
-       uid_t unix_uid;
-       gid_t unix_gid;
-       
        /* This groups info is needed for when we become_user() for this uid */
        int n_groups;
        gid_t *groups;
@@ -98,6 +84,11 @@ typedef struct serversupplied_info
        
        uchar session_key[16];
        
+       uint8 first_8_lm_hash[8];
+
+       uint32 sam_fill_level;  /* How far is this structure filled? */
+
+       SAM_ACCOUNT *sam_account;
 } auth_serversupplied_info;
 
 #endif /* _SMBAUTH_H_ */
index dea5bb66df64d98cfe282c738352df36ece76338..0e48b4c6c0a60959476e72a66a7cd9d1680377fd 100644 (file)
@@ -591,8 +591,8 @@ typedef struct sam_passwd
        pstring unknown_str ; /* don't know what this is, yet. */
        pstring munged_dial ; /* munged path name and dial-back tel number */
 
-        uid_t uid;          /* this is actually the unix uid_t */
-        gid_t gid;          /* this is actually the unix gid_t */
+        uid_t *uid;          /* this is a pointer to the unix uid_t */
+        gid_t *gid;          /* this is a pointer to the unix gid_t */
         uint32 user_rid;    /* Primary User ID */
         uint32 group_rid;   /* Primary Group ID */
 
index 26a727b1f199cd7c401e4a5c81210cfed3981a35..20db1ee4d682b5c3b1dac2fa547899364f783601 100644 (file)
@@ -271,7 +271,7 @@ static BOOL find_connect_pdc(struct cli_state *pcli,
 ************************************************************************/
 
 NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, 
-                             auth_serversupplied_info *server_info, 
+                             auth_serversupplied_info **server_info, 
                              char *server, unsigned char *trust_passwd,
                              time_t last_change_time)
 {
@@ -282,6 +282,7 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info,
        uint32 smb_uid_low;
        BOOL connected_ok = False;
        NTSTATUS status;
+       struct passwd *pass;
 
        /* 
         * Check that the requested domain is not our own machine name.
@@ -330,34 +331,48 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info,
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("domain_client_validate: unable to validate password "
                          "for user %s in domain %s to Domain controller %s. "
-                         "Error was %s.\n", user_info->smb_username.str,
+                         "Error was %s.\n", user_info->smb_name.str,
                          user_info->domain.str, cli.srv_name_slash, 
                          get_nt_error_msg(status)));
-       }
+       } else {
 
-       /*
-        * Here, if we really want it, we have lots of info about the user
-        * in info3.  
-         */
+               /*
+                * Here, if we really want it, we have lots of info about the user
+                * in info3.  
+                */
+
+               pass = Get_Pwnam(user_info->internal_username.str);
+               if (pass) {
+                       make_server_info_pw(server_info, pass);
+                       if (!server_info) {
+                               status = NT_STATUS_NO_MEMORY;
+                       }
+               } else {
+                       status = NT_STATUS_NO_SUCH_USER;
+               }
+       }
 
         /* Store the user group information in the server_info returned to
            the caller. */
-
-        if ((server_info->group_rids = malloc(info3.num_groups2 *
-                                        sizeof(uint32))) == NULL) {
-                DEBUG(1, ("out of memory allocating rid group membership\n"));
-                status = NT_STATUS_NO_MEMORY;
-        } else {
-                int i;
-
-                server_info->n_rids = info3.num_groups2;
-                
-                for (i = 0; i < server_info->n_rids; i++) {
-                        server_info->group_rids[i] = info3.gids[i].g_rid;
-                        DEBUG(5, ("** adding group rid 0x%x\n",
-                                  info3.gids[i].g_rid));
-                }
-        }
+       
+       if (NT_STATUS_IS_OK(status)) {
+               if (((*server_info)->group_rids = malloc(info3.num_groups2 *
+                                                     sizeof(uint32))) == NULL) {
+                       DEBUG(1, ("out of memory allocating rid group membership\n"));
+                       status = NT_STATUS_NO_MEMORY;
+                       free_server_info(server_info);
+               } else {
+                       int i;
+                       
+                       (*server_info)->n_rids = info3.num_groups2;
+                       
+                       for (i = 0; i < (*server_info)->n_rids; i++) {
+                               (*server_info)->group_rids[i] = info3.gids[i].g_rid;
+                               DEBUG(5, ("** adding group rid 0x%x\n",
+                                         info3.gids[i].g_rid));
+                       }
+               }
+       }
 
 #if 0
        /* 
index 2868b02ed9e7f194555807ac3165f81106a09793..c1c4750e051f6e218c3e8c0225da9e743a11d7bf 100644 (file)
@@ -216,27 +216,27 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
 
 /* Does the md5 encryption from the NT hash for NTLMv2. */
 void SMBOWFencrypt_ntv2(const uchar kr[16],
-                       const uchar * srv_chal, int srv_chal_len,
-                       const uchar * cli_chal, int cli_chal_len,
+                       const DATA_BLOB srv_chal,
+                       const DATA_BLOB cli_chal,
                        char resp_buf[16])
 {
        HMACMD5Context ctx;
 
        hmac_md5_init_limK_to_64(kr, 16, &ctx);
-       hmac_md5_update(srv_chal, srv_chal_len, &ctx);
-       hmac_md5_update(cli_chal, cli_chal_len, &ctx);
+       hmac_md5_update(srv_chal.data, srv_chal.length, &ctx);
+       hmac_md5_update(cli_chal.data, cli_chal.length, &ctx);
        hmac_md5_final((unsigned char *)resp_buf, &ctx);
 
 #ifdef DEBUG_PASSWORD
        DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
-       dump_data(100, srv_chal, srv_chal_len);
-       dump_data(100, cli_chal, cli_chal_len);
+       dump_data(100, srv_chal.data, srv_chal.length);
+       dump_data(100, cli_chal.data, cli_chal.length);
        dump_data(100, resp_buf, 16);
 #endif
 }
 
 void SMBsesskeygen_ntv2(const uchar kr[16],
-                       const uchar * nt_resp, char sess_key[16])
+                       const uchar * nt_resp, uint8 sess_key[16])
 {
        HMACMD5Context ctx;
 
@@ -251,7 +251,7 @@ void SMBsesskeygen_ntv2(const uchar kr[16],
 }
 
 void SMBsesskeygen_ntv1(const uchar kr[16],
-                       const uchar * nt_resp, char sess_key[16])
+                       const uchar * nt_resp, uint8 sess_key[16])
 {
        mdfour((unsigned char *)sess_key, kr, 16);
 
index 5cf819a19da673a444e5c3677112cdc9a34130f0..59623b9f046997a2bca1e0cf56bffd1011c524fb 100644 (file)
@@ -60,12 +60,8 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
        unsigned char trust_passwd[16];
        time_t last_change_time;
 
-       unsigned char local_lm_response[24];
-       unsigned char local_nt_response[24];
-
-       auth_usersupplied_info user_info;
-       auth_serversupplied_info server_info;
-       AUTH_STR theirdomain, smb_username, wksta_name;
+       auth_usersupplied_info *user_info;
+       auth_serversupplied_info *server_info;
 
        DEBUG(3, ("[%5d]: pam auth %s\n", state->pid,
                  state->request.data.auth.user));
@@ -82,37 +78,10 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
 
        passlen = strlen(state->request.data.auth.pass);
                
-       ZERO_STRUCT(user_info);
-       ZERO_STRUCT(theirdomain);
-       ZERO_STRUCT(smb_username);
-       ZERO_STRUCT(wksta_name);
-       
-       theirdomain.str = name_domain;
-       theirdomain.len = strlen(theirdomain.str);
-
-       user_info.requested_domain = theirdomain;
-       user_info.domain = theirdomain;
-       
-       user_info.smb_username.str = name_user;
-       user_info.smb_username.len = strlen(name_user);
-
-       user_info.unix_username.str = name_user;
-       user_info.unix_username.len = strlen(name_user);
-
-       user_info.wksta_name.str = global_myname;
-       user_info.wksta_name.len = strlen(user_info.wksta_name.str);
-
-       user_info.wksta_name = wksta_name;
-
-       generate_random_buffer( user_info.chal, 8, False);
-
        if (state->request.data.auth.pass[0]) {
-               SMBencrypt((uchar *)state->request.data.auth.pass, user_info.chal, local_lm_response);
-               user_info.lm_resp.buffer = (uint8 *)local_lm_response;
-               user_info.lm_resp.len = 24;
-               SMBNTencrypt((uchar *)state->request.data.auth.pass, user_info.chal, local_nt_response);
-               user_info.nt_resp.buffer = (uint8 *)local_nt_response;
-               user_info.nt_resp.len = 24;
+               make_user_info_for_winbind(&user_info, 
+                                          name_user, name_domain,
+                                          state->request.data.auth.pass);
        } else {
                return WINBINDD_ERROR;
        }
@@ -137,11 +106,11 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
           for each authentication performed.  This can theoretically
           be optimised to use an already open IPC$ connection. */
 
-       result = domain_client_validate(&user_info, &server_info,
+       result = domain_client_validate(user_info, &server_info,
                                         auth_dc, trust_passwd, 
                                         last_change_time);
 
-        free_serversupplied_info(&server_info); /* No info needed */
+        free_server_info(&server_info); /* No info needed */
 
        return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
 }
@@ -154,9 +123,8 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
        fstring name_domain, name_user, auth_dc;
        unsigned char trust_passwd[16];
        time_t last_change_time;
-       auth_usersupplied_info user_info;
-       auth_serversupplied_info server_info;
-       AUTH_STR theirdomain, smb_username, wksta_name;
+       auth_usersupplied_info *user_info;
+       auth_serversupplied_info *server_info;
 
        DEBUG(3, ("[%5d]: pam auth crap %s\n", state->pid,
                  state->request.data.auth_crap.user));
@@ -166,36 +134,11 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
        parse_domain_user(state->request.data.auth_crap.user, name_domain, 
                           name_user);
 
-       ZERO_STRUCT(user_info);
-       ZERO_STRUCT(theirdomain);
-       ZERO_STRUCT(smb_username);
-       ZERO_STRUCT(wksta_name);
+               make_user_info_winbind_crap(&user_info, name_user, 
+                                   name_domain, state->request.data.auth_crap.chal,
+                                   (uchar *)state->request.data.auth_crap.lm_resp, 24,
+                                   (uchar *)state->request.data.auth_crap.nt_resp, 24);
        
-       theirdomain.str = name_domain;
-       theirdomain.len = strlen(theirdomain.str);
-
-       user_info.requested_domain = theirdomain;
-       user_info.domain = theirdomain;
-       
-       user_info.smb_username.str = name_user;
-       user_info.smb_username.len = strlen(name_user);
-
-       user_info.unix_username.str = name_user;
-       user_info.unix_username.len = strlen(name_user);
-
-       user_info.wksta_name.str = global_myname;
-       user_info.wksta_name.len = strlen(user_info.wksta_name.str);
-
-       user_info.wksta_name = wksta_name;
-
-        memcpy(user_info.chal, state->request.data.auth_crap.chal, 8);
-
-        user_info.lm_resp.buffer = (uchar *)state->request.data.auth_crap.lm_resp;
-        user_info.nt_resp.buffer = (uchar *)state->request.data.auth_crap.nt_resp;
-        
-        user_info.lm_resp.len = 24;
-        user_info.nt_resp.len = 24;
-
        /*
         * Get the machine account password for our primary domain
         */
@@ -216,11 +159,11 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
           for each authentication performed.  This can theoretically
           be optimised to use an already open IPC$ connection. */
 
-       result = domain_client_validate(&user_info, &server_info,
+       result = domain_client_validate(user_info, &server_info,
                                         auth_dc, trust_passwd,
                                         last_change_time);
 
-        free_serversupplied_info(&server_info); /* No info needed */        
+        free_server_info(&server_info); /* No info needed */        
 
        return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
 }
index 6a96426a9f123720163094fad7979ce7e002708c..05d448f963f3ae063032a6be9b49a2ca35374e21 100644 (file)
@@ -135,8 +135,9 @@ BOOL pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, struct passwd *pwd)
 
        pdb_set_username(*new_sam_acct, pwd->pw_name);
        pdb_set_fullname(*new_sam_acct, pwd->pw_gecos);
-       pdb_set_uid(*new_sam_acct, pwd->pw_uid);
-       pdb_set_gid(*new_sam_acct, pwd->pw_gid);
+
+       pdb_set_uid(*new_sam_acct, &pwd->pw_uid);
+       pdb_set_gid(*new_sam_acct, &pwd->pw_gid);
 
        pdb_set_user_rid(*new_sam_acct, pdb_uid_to_user_rid(pwd->pw_uid));
        pdb_set_group_rid(*new_sam_acct, pdb_gid_to_group_rid(pwd->pw_gid));
@@ -186,6 +187,9 @@ static BOOL pdb_free_sam_contents(SAM_ACCOUNT *user)
 
        SAFE_FREE(user->nt_pw);
        SAFE_FREE(user->lm_pw);
+
+       SAFE_FREE(user->uid);
+       SAFE_FREE(user->gid);
        
        return True;    
 }
@@ -1113,20 +1117,20 @@ uint32 pdb_get_group_rid (const SAM_ACCOUNT *sampass)
                return (-1);
 }
 
-uid_t pdb_get_uid (const SAM_ACCOUNT *sampass)
+uid_t *pdb_get_uid (const SAM_ACCOUNT *sampass)
 {
        if (sampass)
                return (sampass->uid);
        else
-               return ((uid_t)-1);
+               return (NULL);
 }
 
-gid_t pdb_get_gid (const SAM_ACCOUNT *sampass)
+gid_t *pdb_get_gid (const SAM_ACCOUNT *sampass)
 {
        if (sampass)
                return (sampass->gid);
        else
-               return ((gid_t)-1);
+               return (NULL);
 }
 
 const char* pdb_get_username (const SAM_ACCOUNT *sampass)
@@ -1330,22 +1334,62 @@ BOOL pdb_set_logons_divs (SAM_ACCOUNT *sampass, uint16 hours)
        return True;
 }
 
-BOOL pdb_set_uid (SAM_ACCOUNT *sampass, uid_t uid)
+/*********************************************************************
+ Set the user's UNIX uid, as a pointer to malloc'ed memory.
+ ********************************************************************/
+
+BOOL pdb_set_uid (SAM_ACCOUNT *sampass, const uid_t *uid)
 {
        if (!sampass)
                return False;
+       
+       if (!uid) {
+               /* Allow setting to NULL */
+               SAFE_FREE(sampass->uid);
+               return True;
+       }
+
+       if (sampass->uid!=NULL)
+               DEBUG(4,("pdb_set_nt_passwd: uid non NULL overwritting ?\n"));
+       else
+               sampass->uid=(uid_t *)malloc(sizeof(uid_t));
+       
+       if (sampass->uid==NULL)
+               return False;
+
+       *sampass->uid = *uid; 
 
-       sampass->uid = uid;
        return True;
+
 }
 
-BOOL pdb_set_gid (SAM_ACCOUNT *sampass, gid_t gid)
+/*********************************************************************
+ Set the user's UNIX gid, as a pointer to malloc'ed memory.
+ ********************************************************************/
+
+BOOL pdb_set_gid (SAM_ACCOUNT *sampass, const gid_t *gid)
 {
        if (!sampass)
                return False;
+       
+       if (!gid) {
+               /* Allow setting to NULL */
+               SAFE_FREE(sampass->gid);
+               return True;
+       }
+
+       if (sampass->gid!=NULL)
+               DEBUG(4,("pdb_set_nt_passwd: gid non NULL overwritting ?\n"));
+       else
+               sampass->gid=(gid_t *)malloc(sizeof(gid_t));
+       
+       if (sampass->gid==NULL)
+               return False;
+
+       *sampass->gid = *gid; 
 
-       sampass->gid = gid;
        return True;
+
 }
 
 BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid)
index 8524275f1255c036f7e442f683644beeaae8e096..e190be99a56ef15fc093c5f372a253b65709e38b 100644 (file)
@@ -1135,12 +1135,22 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
  ********************************************************************/
 static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampass)
 {
+       uid_t *uid;
+       gid_t *gid;
+
        if (sampass == NULL) 
                return False;
+       uid = pdb_get_uid(sampass);
+       gid = pdb_get_gid(sampass);
+
+       if (!uid || !gid) {
+               DEBUG(0,("build_sam_pass: Failing attempt to store user without a UNIX uid or gid. \n"));
+               return False;
+       }
 
        ZERO_STRUCTP(smb_pw);
 
-       smb_pw->smb_userid=pdb_get_uid(sampass);
+       smb_pw->smb_userid=*uid;
        smb_pw->smb_name=pdb_get_username(sampass);
 
        smb_pw->smb_passwd=pdb_get_lanman_passwd(sampass);
@@ -1149,12 +1159,12 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
        smb_pw->acct_ctrl=pdb_get_acct_ctrl(sampass);
        smb_pw->pass_last_set_time=pdb_get_pass_last_set_time(sampass);
 
-       if (smb_pw->smb_userid != pdb_user_rid_to_uid(pdb_get_user_rid(sampass))) {
+       if (*uid != pdb_user_rid_to_uid(pdb_get_user_rid(sampass))) {
                DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
                return False;
        }
 
-       if (pdb_get_gid(sampass) != pdb_group_rid_to_gid(pdb_get_group_rid(sampass))) {
+       if (*gid != pdb_group_rid_to_gid(pdb_get_group_rid(sampass))) {
                DEBUG(0,("build_sam_pass: Failing attempt to store user with non-gid based primary group RID. \n"));
                return False;
        }
@@ -1184,14 +1194,15 @@ static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw
                return False;
        }
 
+       pdb_set_uid (sam_pass, &pwfile->pw_uid);
+       pdb_set_gid (sam_pass, &pwfile->pw_gid);
+
        /* FIXME!!  This doesn't belong here.  Should be set in net_sam_logon() 
           --jerry */
+
        pstrcpy(samlogon_user, pw_buf->smb_name);
-       
        sam_logon_in_ssb = True;
                
-       pdb_set_uid (sam_pass, pwfile->pw_uid);
-       pdb_set_gid (sam_pass, pwfile->pw_gid);
        pdb_set_fullname(sam_pass, pwfile->pw_gecos);           
        
        pdb_set_user_rid(sam_pass, pdb_uid_to_user_rid (pwfile->pw_uid));
index 9b5f7379f541f4bf4cc2b3087b46fc00b2093a96..e4e33d257fd6566b0f728e71327f25a52989eadc 100644 (file)
@@ -927,7 +927,7 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
        int               action;
        NTSTATUS          nt_status;
        pstring           driverpath;
-       fstring           null_pw;
+       DATA_BLOB         null_pw;
        files_struct      *fsp = NULL;
        BOOL              bad_path;
        SMB_STRUCT_STAT   st;
@@ -943,10 +943,10 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
 
        /* connect to the print$ share under the same account as the user connected to the rpc pipe */  
        /* Null password is ok - we are already an authenticated user... */
-       *null_pw = '\0';
+       null_pw = data_blob(NULL, 0);
 
        become_root();
-       conn = make_connection("print$", null_pw, 0, "A:", user->vuid, &nt_status);
+       conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
        unbecome_root();
 
        if (conn == NULL) {
@@ -1230,7 +1230,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
        pstring new_dir;
        pstring old_name;
        pstring new_name;
-       fstring null_pw;
+       DATA_BLOB null_pw;
        connection_struct *conn;
        NTSTATUS nt_status;
        int ver = 0;
@@ -1252,8 +1252,8 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
 
        /* connect to the print$ share under the same account as the user connected to the rpc pipe */  
        /* Null password is ok - we are already an authenticated user... */
-       *null_pw = '\0';
-       conn = make_connection("print$", null_pw, 0, "A:", user->vuid, &nt_status);
+       null_pw = data_blob(NULL, 0);
+       conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
 
        if (conn == NULL) {
                DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
index 0f54d5512cc376da065885c493bbf3fe2fd16407..eaedb1613a527f83807f78d4505e08036025b77e 100644 (file)
@@ -169,14 +169,14 @@ NTSTATUS cli_nt_login_network(struct cli_state *cli,
 
   /* Create the structure needed for SAM logon. */
   init_id_info2(&ctr->auth.id2, user_info->domain.str, 0, smb_userid_low, 0,
-                user_info->smb_username.str, 
+                user_info->smb_name.str, 
                /* Send our cleint's workstaion name if we have it, otherwise ours */
                ((user_info->wksta_name.len > 0) ?
                 user_info->wksta_name.str :
                 cli->clnt_name_slash),
-               user_info->chal
-               user_info->lm_resp.buffer, user_info->lm_resp.len,
-               user_info->nt_resp.buffer, user_info->nt_resp.len);
+               user_info->sec_blob.data
+               user_info->lm_resp.data, user_info->lm_resp.length,
+               user_info->nt_resp.data, user_info->nt_resp.length);
 
   /* Send client sam-logon request - update credentials on success. */
   return cli_net_sam_logon(cli, ctr, user_info3);
index 2f0dd1eb6221dfa27506d2470713da7fa404f96a..c546213173f675ac431db1852e4d1fff1b70eb0d 100644 (file)
@@ -1193,7 +1193,7 @@ static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int d
 void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sampw,
                         uint16 logon_count, uint16 bad_pw_count,
                         uint32 num_groups, DOM_GID *gids,
-                        uint32 user_flgs, char *sess_key,
+                        uint32 user_flgs, uchar *sess_key,
                         char *logon_srv, char *logon_dom,
                         DOM_SID *dom_sid, char *other_sids)
 {
index 0f2b672d38089dd851512639120158706be8ac58..26054117fb7fcec711881f9bf9221d9afe51383b 100644 (file)
@@ -484,123 +484,6 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF
        return r_u->status;
 }
 
-/*************************************************************************
- _net_logon_any:  Use the new authentications subsystem to log in.
- *************************************************************************/
-
-static NTSTATUS _net_logon_any(NET_ID_INFO_CTR *ctr, char *user, char *domain, char *workstation, char *sess_key)
-{
-       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
-
-       unsigned char local_lm_response[24];
-       unsigned char local_nt_response[24];
-
-       auth_usersupplied_info user_info;
-       auth_serversupplied_info server_info;
-       AUTH_STR ourdomain, theirdomain, smb_username, wksta_name;
-
-       DEBUG(5, ("_net_logon_any: entered with user %s and domain %s\n", user, domain));
-               
-       ZERO_STRUCT(user_info);
-       ZERO_STRUCT(server_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.unix_username = smb_username;  /* For the time-being */
-       user_info.smb_username = smb_username;
-
-       user_info.wksta_name.str = workstation;
-       user_info.wksta_name.len = strlen(workstation);
-
-       user_info.wksta_name = wksta_name;
-
-       DEBUG(10,("_net_logon_any: Attempting validation level %d.\n", ctr->switch_value));
-       switch (ctr->switch_value) {
-       case NET_LOGON_TYPE:
-               /* Standard challange/response authenticaion */
-
-               user_info.lm_resp.buffer = (uint8 *)ctr->auth.id2.lm_chal_resp.buffer;
-               user_info.lm_resp.len = ctr->auth.id2.lm_chal_resp.str_str_len;
-               user_info.nt_resp.buffer = (uint8 *)ctr->auth.id2.nt_chal_resp.buffer;
-               user_info.nt_resp.len = ctr->auth.id2.nt_chal_resp.str_str_len;
-               memcpy(user_info.chal, ctr->auth.id2.lm_chal, 8);
-               break;
-       case INTERACTIVE_LOGON_TYPE:
-               /* 'Interactive' autheticaion, supplies the password in its MD4 form, encrypted
-                  with the session key.  We will convert this to challange/responce for the 
-                  auth subsystem to chew on */
-       {
-               char nt_pwd[16];
-               char lm_pwd[16];
-               unsigned char key[16];
-               
-               memset(key, 0, 16);
-               memcpy(key, sess_key, 8);
-               
-               memcpy(lm_pwd, ctr->auth.id1.lm_owf.data, 16);
-               memcpy(nt_pwd, ctr->auth.id1.nt_owf.data, 16);
-
-#ifdef DEBUG_PASSWORD
-               DEBUG(100,("key:"));
-               dump_data(100, (char *)key, 16);
-               
-               DEBUG(100,("lm owf password:"));
-               dump_data(100, lm_pwd, 16);
-               
-               DEBUG(100,("nt owf password:"));
-               dump_data(100, nt_pwd, 16);
-#endif
-               
-               SamOEMhash((uchar *)lm_pwd, key, 16);
-               SamOEMhash((uchar *)nt_pwd, key, 16);
-               
-#ifdef DEBUG_PASSWORD
-               DEBUG(100,("decrypt of lm owf password:"));
-               dump_data(100, lm_pwd, 16);
-               
-               DEBUG(100,("decrypt of nt owf password:"));
-               dump_data(100, nt_pwd, 16);
-#endif
-
-               generate_random_buffer(user_info.chal, 8, False);
-               SMBOWFencrypt((const unsigned char *)lm_pwd, user_info.chal, local_lm_response);
-               SMBOWFencrypt((const unsigned char *)nt_pwd, user_info.chal, local_nt_response);
-               user_info.lm_resp.buffer = (uint8 *)local_lm_response;
-               user_info.lm_resp.len = 24;
-               user_info.nt_resp.buffer = (uint8 *)local_nt_response;
-               user_info.nt_resp.len = 24;
-               break;
-       }
-       default:
-               DEBUG(2,("SAM Logon: unsupported switch value\n"));
-               return NT_STATUS_INVALID_INFO_CLASS;
-       } /* end switch */
-       
-       nt_status = check_password(&user_info, &server_info);
-
-       DEBUG(5, ("_net_logon_any: exited with status %s\n", 
-                 get_nt_error_msg(nt_status)));
-
-        free_serversupplied_info(&server_info); /* No info needed */
-
-       return nt_status;
-}
-
-
 
 /*************************************************************************
  _net_sam_logon
@@ -610,15 +493,16 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
 {
        NTSTATUS status = NT_STATUS_OK;
        NET_USER_INFO_3 *usr_info = NULL;
+       NET_ID_INFO_CTR *ctr = q_u->sam_id.ctr;
        DOM_CRED srv_cred;
        SAM_ACCOUNT *sampass = NULL;
        UNISTR2 *uni_samlogon_user = NULL;
        UNISTR2 *uni_samlogon_domain = NULL;
        UNISTR2 *uni_samlogon_workstation = NULL;
        fstring nt_username, nt_domain, nt_workstation;
-        
-       BOOL ret;
-
+       auth_usersupplied_info *user_info;
+       auth_serversupplied_info *server_info;
+               
        usr_info = (NET_USER_INFO_3 *)talloc(p->mem_ctx, sizeof(NET_USER_INFO_3));
        if (!usr_info)
                return NT_STATUS_NO_MEMORY;
@@ -647,16 +531,17 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
     
        switch (q_u->sam_id.logon_level) {
        case INTERACTIVE_LOGON_TYPE:
-               uni_samlogon_user = &q_u->sam_id.ctr->auth.id1.uni_user_name;
-               uni_samlogon_domain = &q_u->sam_id.ctr->auth.id1.uni_domain_name;
-                uni_samlogon_workstation = &q_u->sam_id.ctr->auth.id1.uni_wksta_name;
+               uni_samlogon_user = &ctr->auth.id1.uni_user_name;
+               uni_samlogon_domain = &ctr->auth.id1.uni_domain_name;
+
+                uni_samlogon_workstation = &ctr->auth.id1.uni_wksta_name;
             
                DEBUG(3,("SAM Logon (Interactive). Domain:[%s].  ", lp_workgroup()));
                break;
        case NET_LOGON_TYPE:
-               uni_samlogon_user = &q_u->sam_id.ctr->auth.id2.uni_user_name;
-               uni_samlogon_domain = &q_u->sam_id.ctr->auth.id2.uni_domain_name;
-               uni_samlogon_workstation = &q_u->sam_id.ctr->auth.id2.uni_wksta_name;
+               uni_samlogon_user = &ctr->auth.id2.uni_user_name;
+               uni_samlogon_domain = &ctr->auth.id2.uni_domain_name;
+               uni_samlogon_workstation = &ctr->auth.id2.uni_wksta_name;
             
                DEBUG(3,("SAM Logon (Network). Domain:[%s].  ", lp_workgroup()));
                break;
@@ -678,29 +563,51 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
         * Convert to a UNIX username.
         */
 
-       map_username(nt_username);
+       DEBUG(5,("Attempting validation level %d for unmapped username %s.\n", q_u->sam_id.ctr->switch_value, nt_username));
 
-       DEBUG(10,("Attempting validation level %d for mapped username %s.\n", q_u->sam_id.ctr->switch_value, nt_username));
+       switch (ctr->switch_value) {
+       case NET_LOGON_TYPE:
+               /* Standard challange/response authenticaion */
+               make_user_info_netlogon_network(&user_info, 
+                                               nt_username, nt_domain, 
+                                               nt_workstation, ctr->auth.id2.lm_chal, 
+                                               ctr->auth.id2.lm_chal_resp.buffer,
+                                               ctr->auth.id2.lm_chal_resp.str_str_len,
+                                               ctr->auth.id2.nt_chal_resp.buffer,
+                                               ctr->auth.id2.nt_chal_resp.str_str_len);
+               break;
+       case INTERACTIVE_LOGON_TYPE:
+               /* 'Interactive' autheticaion, supplies the password in its MD4 form, encrypted
+                  with the session key.  We will convert this to challange/responce for the 
+                  auth subsystem to chew on */
+       {
+               make_user_info_netlogon_interactive(&user_info, 
+                                          nt_username, nt_domain, 
+                                          nt_workstation, 
+                                          ctr->auth.id1.lm_owf.data, 16, 
+                                          ctr->auth.id1.lm_owf.data, 16, 
+                                          p->dc.sess_key);
+               break;
+       }
+       default:
+               DEBUG(2,("SAM Logon: unsupported switch value\n"));
+               return NT_STATUS_INVALID_INFO_CLASS;
+       } /* end switch */
+       
+       status = check_password(user_info, &server_info);
 
-       status = _net_logon_any(q_u->sam_id.ctr, nt_username, nt_domain, nt_workstation, (char *)p->dc.sess_key);
+       free_user_info(&user_info);
+       
+       DEBUG(5, ("_net_sam_logon: exiting with status %s\n", 
+                 get_nt_error_msg(status)));
 
        /* Check account and password */
     
-       if (NT_STATUS_IS_ERR(status))
+       if (NT_STATUS_IS_ERR(status)) {
+               free_server_info(&server_info);
                return status;
-
-       pdb_init_sam(&sampass);
-
-       /* get the account information */
-       become_root();
-       ret = pdb_getsampwnam(sampass, nt_username);
-       unbecome_root();
-
-       if (ret == False) {
-               pdb_free_sam(&sampass);
-               return NT_STATUS_NO_SUCH_USER;
        }
-        
+
        /* This is the point at which, if the login was successful, that
            the SAM Local Security Authority should record that the user is
            logged in to the domain.  */
@@ -748,12 +655,14 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
                             num_gids,    /* uint32 num_groups */
                             gids    , /* DOM_GID *gids */
                             0x20    , /* uint32 user_flgs (?) */
-                            NULL, /* char sess_key[16] */
+                            NULL, /* uchar sess_key[16] */
                             my_name     , /* char *logon_srv */
                             my_workgroup, /* char *logon_dom */
                             &global_sam_sid,     /* DOM_SID *dom_sid */
                             NULL); /* char *other_sids */
        }
-       pdb_free_sam(&sampass);
+       free_server_info(&server_info);
        return status;
 }
+
+
index 6f3c050519323aeea7a15e3a47c7037a6323529e..21de4d3d2bbfe854d6c3c0245e610b5da3feb525 100644 (file)
@@ -269,10 +269,16 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
        fstring domain;
        fstring wks;
        BOOL guest_user = False;
-       SAM_ACCOUNT *sampass = NULL;
        uchar null_smb_passwd[16];
+
        const uchar *smb_passwd_ptr = NULL;
        
+       auth_usersupplied_info *user_info;
+       auth_serversupplied_info *server_info;
+
+       uid_t *puid;
+       uid_t *pgid;
+
        DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
 
        memset(p->user_name, '\0', sizeof(p->user_name));
@@ -336,14 +342,6 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
                
        } else {
 
-               /*
-                * Pass the user through the NT -> unix user mapping
-                * function.
-                */
-               
-               fstrcpy(pipe_user_name, user_name);
-               (void)map_username(pipe_user_name);
-               
                /* 
                 * Do the length checking only if user is not NULL.
                 */
@@ -362,41 +360,28 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
        }
 
        if(!guest_user) {
+               NTSTATUS nt_status;
 
-               become_root();
-
-               p->ntlmssp_auth_validated = 
-                       NT_STATUS_IS_OK(pass_check_smb_with_chal(pipe_user_name, NULL, 
-                                                                domain, wks, 
-                                                                (uchar*)p->challenge, 
-                                                                lm_owf, lm_pw_len, 
-                                                                nt_owf, nt_pw_len));
-               if (!p->ntlmssp_auth_validated) {
-                       DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \
-failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name ));
-                       unbecome_root();
+               if (!make_user_info_netlogon_network(&user_info, 
+                                                    user_name, domain, wks,  (uchar*)p->challenge, 
+                                                    lm_owf, lm_pw_len, 
+                                                    nt_owf, nt_pw_len)) {
+                       DEBUG(0,("make_user_info_netlogon_network failed!  Failing authenticaion.\n"));
                        return False;
                }
 
-               pdb_init_sam(&sampass);
-
-               if(!pdb_getsampwnam(sampass, pipe_user_name)) {
-                       DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n",
-                               pipe_user_name));
-                       pdb_free_sam(&sampass);
-                       unbecome_root();
-                       return False;
-               }
+               nt_status = check_password(user_info, &server_info); 
+               
+               free_user_info(&user_info);
 
-               unbecome_root();
+               p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status);
 
-               if(!pdb_get_nt_passwd(sampass)) {
-                       DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name));
-                       pdb_free_sam(&sampass);
+               if (!p->ntlmssp_auth_validated) {
+                       DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \
+failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name ));
+                       free_server_info(&server_info);
                        return False;
-               }
-               smb_passwd_ptr = pdb_get_lanman_passwd(sampass);
+               }
        }
 
        /*
@@ -405,7 +390,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name
 
        {
                uchar p24[24];
-               NTLMSSPOWFencrypt(smb_passwd_ptr, lm_owf, p24);
+               NTLMSSPOWFencrypt(server_info->first_8_lm_hash, lm_owf, p24);
                {
                        unsigned char j = 0;
                        int ind;
@@ -447,8 +432,17 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name
         * Store the UNIX credential data (uid/gid pair) in the pipe structure.
         */
 
-       p->pipe_user.uid = pdb_get_uid(sampass);
-       p->pipe_user.gid = pdb_get_gid(sampass);
+       puid = pdb_get_uid(server_info->sam_account);
+       pgid = pdb_get_gid(server_info->sam_account);
+       
+       if (!puid || !pgid) {
+               DEBUG(0,("Attempted authenticated pipe with invalid user.  No uid/gid in SAM_ACCOUNT\n"));
+               free_server_info(&server_info);
+               return False;
+       }
+       
+       p->pipe_user.uid = *puid;
+       p->pipe_user.gid = *pgid;
 
        /* Set up pipe user group membership. */
        initialise_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid);
@@ -461,7 +455,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name
 
        p->ntlmssp_auth_validated = True;
 
-       pdb_free_sam(&sampass);
+       pdb_free_sam(&server_info->sam_account);
        return True;
 }
 
index 44e44cfa3ae1f873593c21bd2749510638f30b9d..7369c9d37d28aa031e5ae78ce28154c4b424b374 100644 (file)
@@ -1574,7 +1574,7 @@ NTSTATUS _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDE
 {
        SEC_DESC *psd = NULL;
        size_t sd_size;
-       fstring null_pw;
+       DATA_BLOB null_pw;
        pstring filename;
        pstring qualname;
        files_struct *fsp = NULL;
@@ -1594,12 +1594,12 @@ NTSTATUS _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDE
        unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
 
        /* Null password is ok - we are already an authenticated user... */
-       *null_pw = '\0';
+       null_pw = data_blob(NULL, 0);
 
        get_current_user(&user, p);     
        
        become_root();
-       conn = make_connection(qualname, null_pw, 0, "A:", user.vuid, &nt_status);
+       conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
        unbecome_root();
 
        if (conn == NULL) {
@@ -1678,7 +1678,7 @@ NTSTATUS _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *
                                                                        SRV_R_NET_FILE_SET_SECDESC *r_u)
 {
        BOOL ret;
-       fstring null_pw;
+       DATA_BLOB null_pw;
        pstring filename;
        pstring qualname;
        files_struct *fsp = NULL;
@@ -1698,12 +1698,12 @@ NTSTATUS _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *
        unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
 
        /* Null password is ok - we are already an authenticated user... */
-       *null_pw = '\0';
+       null_pw = data_blob(NULL, 0);
 
        get_current_user(&user, p);     
        
        become_root();
-       conn = make_connection(qualname, null_pw, 0, "A:", user.vuid, &nt_status);
+       conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
        unbecome_root();
 
        if (conn == NULL) {
index 4bdbdf5555ecb66341792e98ce6e303afa78b0a9..4d1a5668337d8ef8a920db8970d912222772dfbd 100644 (file)
@@ -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);
-}
index bcd41bacdba35d7064f83f82fbb301970b1db005..f20da196076bbe72d3e2d8894848c3dd0651882b 100644 (file)
@@ -29,7 +29,7 @@ BOOL global_machine_password_needs_changing = False;
 ****************************************************************************/
 
 NTSTATUS check_domain_security(const auth_usersupplied_info *user_info, 
-                              auth_serversupplied_info *server_info)
+                              auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
        char *p, *pserver;
index 9f5f1e10e50e864fbf601a7334ffa9237d1ba90f..9c07e48a9b673d6ebc0748a575612c58461b3b61 100644 (file)
@@ -131,11 +131,11 @@ static BOOL check_user_equiv(const char *user, const char *remote, const char *e
 /****************************************************************************
 check for a possible hosts equiv or rhosts entry for the user
 ****************************************************************************/
-static BOOL check_hosts_equiv(char *user) /* should be const... */
+
+static BOOL check_hosts_equiv(struct passwd *pass)
 {
   char *fname = NULL;
   pstring rhostsfile;
-  struct passwd *pass = Get_Pwnam(user);
 
   if (!pass) 
     return(False);
@@ -149,15 +149,15 @@ static BOOL check_hosts_equiv(char *user) /* should be const... */
   }
   
   if (lp_use_rhosts())
-    {
-      char *home = pass->pw_dir;
-      if (home) {
-             slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
-             if (check_user_equiv(pass->pw_name,client_name(),rhostsfile))
-                     return(True);
-      }
-    }
-
+  {
+         char *home = pass->pw_dir;
+         if (home) {
+                 slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
+                 if (check_user_equiv(pass->pw_name,client_name(),rhostsfile))
+                         return(True);
+         }
+  }
+  
   return(False);
 }
 
@@ -166,15 +166,21 @@ static BOOL check_hosts_equiv(char *user) /* should be const... */
 ****************************************************************************/
 
 NTSTATUS check_rhosts_security(const auth_usersupplied_info *user_info, 
-                            auth_serversupplied_info *server_info)
+                            auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
-
-       become_root();
-       if (check_hosts_equiv(user_info->unix_username.str)) {
-               nt_status = NT_STATUS_OK;
+       struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
+       
+       if (pass) {
+               become_root();
+               if (check_hosts_equiv(pass)) {
+                       nt_status = NT_STATUS_OK;
+                       make_server_info_pw(server_info, pass);
+               }
+               unbecome_root();
+       } else {
+               nt_status = NT_STATUS_NO_SUCH_USER;
        }
-       unbecome_root();
 
        return nt_status;
 }
index 520417e3e09ac193b22415fa0c0da3c86cf154b8..ddbc284d50ce02bd79795edc83dfab197c364e79 100644 (file)
@@ -115,7 +115,7 @@ struct cli_state *server_cryptkey(void)
   - Validate a password with the password server.
 ****************************************************************************/
 
-NTSTATUS check_server_security(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info)
+NTSTATUS check_server_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
 {
        struct cli_state *cli;
        static unsigned char badpass[24];
@@ -134,8 +134,8 @@ NTSTATUS check_server_security(const auth_usersupplied_info *user_info, auth_ser
        if(badpass[0] == 0)
                memset(badpass, 0x1f, sizeof(badpass));
 
-       if((user_info->nt_resp.len == sizeof(badpass)) && 
-          !memcmp(badpass, user_info->nt_resp.buffer, sizeof(badpass))) {
+       if((user_info->nt_resp.length == sizeof(badpass)) && 
+          !memcmp(badpass, user_info->nt_resp.data, sizeof(badpass))) {
                /* 
                 * Very unlikely, our random bad password is the same as the users
                 * password.
@@ -206,11 +206,11 @@ use this machine as the password server.\n"));
         * not guest enabled, we can try with the real password.
         */
 
-       if (!cli_session_setup(cli, user_info->smb_username.str, 
-                              (char *)user_info->lm_resp.buffer
-                              user_info->lm_resp.len, 
-                              (char *)user_info->nt_resp.buffer
-                              user_info->nt_resp.len, 
+       if (!cli_session_setup(cli, user_info->smb_name.str, 
+                              (char *)user_info->lm_resp.data
+                              user_info->lm_resp.length
+                              (char *)user_info->nt_resp.data
+                              user_info->nt_resp.length
                               user_info->domain.str)) {
                DEBUG(1,("password server %s rejected the password\n", cli->desthost));
                /* Make this cli_nt_error() when the conversion is in */
@@ -227,5 +227,16 @@ use this machine as the password server.\n"));
 
        cli_ulogoff(cli);
 
+       if NT_STATUS_IS_OK(nt_status) {
+               struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
+               if (pass) {
+                       if (!make_server_info_pw(server_info, pass)) { 
+                               nt_status = NT_STATUS_NO_MEMORY;
+                       }
+               } else {
+                       nt_status = NT_STATUS_NO_SUCH_USER;
+               }
+       }
+
        return(nt_status);
 }
index 84ca8d03be9add23b5729969d43246fd811b2234..d4283429ce2162425fa015a0c553aad952040bdc 100644 (file)
 /****************************************************************************
 core of smb password checking routine.
 ****************************************************************************/
-static BOOL smb_pwd_check_ntlmv1(const uchar *password,
+static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
                                const uchar *part_passwd,
-                               const uchar *c8,
-                               char user_sess_key[16])
+                               DATA_BLOB sec_blob,
+                               uint8 user_sess_key[16])
 {
-  /* Finish the encryption of part_passwd. */
-  uchar p24[24];
-
-  if (part_passwd == NULL) {
-         DEBUG(10,("No password set - DISALLOWING access\n"));
-         /* No password set - always false ! */
-         return False;
-  }
+       /* Finish the encryption of part_passwd. */
+       uchar p24[24];
+       
+       if (part_passwd == NULL) {
+               DEBUG(10,("No password set - DISALLOWING access\n"));
+               /* No password set - always false ! */
+               return False;
+       }
+       
+       if (sec_blob.length != 8) {
+               DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challange size (%d)\n", sec_blob.length));
+               return False;
+       }
+       
+       if (nt_response.length != 24) {
+               DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", nt_response.length));
+               return False;
+       }
 
-  SMBOWFencrypt(part_passwd, c8, p24);
+       SMBOWFencrypt(part_passwd, sec_blob.data, p24);
        if (user_sess_key != NULL)
        {
                SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key);
        }
-
-
-
+       
+       
+       
 #if DEBUG_PASSWORD
        DEBUG(100,("Part password (P16) was |"));
        dump_data(100, part_passwd, 16);
        DEBUG(100,("Password from client was |"));
-       dump_data(100, password, 24);
+       dump_data(100, nt_response.data, nt_response.length);
        DEBUG(100,("Given challenge was |"));
-       dump_data(100, c8, 8);
+       dump_data(100, sec_blob.data, sec_blob.length);
        DEBUG(100,("Value from encryption was |"));
        dump_data(100, p24, 24);
 #endif
-  return (memcmp(p24, password, 24) == 0);
+  return (memcmp(p24, nt_response.data, 24) == 0);
 }
 
 /****************************************************************************
 core of smb password checking routine.
 ****************************************************************************/
-static BOOL smb_pwd_check_ntlmv2(const uchar *password, size_t pwd_len,
+static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
                                const uchar *part_passwd,
-                               const uchar *c8,
+                               const DATA_BLOB sec_blob,
                                const char *user, const char *domain,
-                               char user_sess_key[16])
+                               uint8 user_sess_key[16])
 {
        /* Finish the encryption of part_passwd. */
        uchar kr[16];
-       uchar resp[16];
+       uchar value_from_encryption[16];
+       uchar client_response[16];
+       DATA_BLOB client_key_data;
 
        if (part_passwd == NULL)
        {
@@ -81,25 +93,42 @@ static BOOL smb_pwd_check_ntlmv2(const uchar *password, size_t pwd_len,
                return False;
        }
 
+       if (ntv2_response.length < 16) {
+               /* We MUST have more than 16 bytes, or the stuff below will go
+                  crazy... */
+               DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", 
+                         ntv2_response.length));
+               return False;
+       }
+
+       client_key_data = data_blob(ntv2_response.data+16, ntv2_response.length-16);
+       memcpy(client_response, ntv2_response.data, ntv2_response.length);
+
+       if (!client_key_data.data) {
+               return False;
+       }
+
        ntv2_owf_gen(part_passwd, user, domain, kr);
-       SMBOWFencrypt_ntv2(kr, c8, 8, password+16, pwd_len-16, (char *)resp);
+       SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, (char *)value_from_encryption);
        if (user_sess_key != NULL)
        {
-               SMBsesskeygen_ntv2(kr, resp, user_sess_key);
+               SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key);
        }
 
 #if DEBUG_PASSWORD
        DEBUG(100,("Part password (P16) was |"));
        dump_data(100, part_passwd, 16);
        DEBUG(100,("Password from client was |"));
-       dump_data(100, password, pwd_len);
+       dump_data(100, ntv2_response.data, ntv2_response.length);
+       DEBUG(100,("Variable data from client was |"));
+       dump_data(100, ntv2_response.data, ntv2_response.length);
        DEBUG(100,("Given challenge was |"));
-       dump_data(100, c8, 8);
+       dump_data(100, sec_blob.data, sec_blob.length);
        DEBUG(100,("Value from encryption was |"));
-       dump_data(100, resp, 16);
+       dump_data(100, value_from_encryption, 16);
 #endif
-
-       return (memcmp(resp, password, 16) == 0);
+       data_blob_clear_free(&client_key_data);
+       return (memcmp(value_from_encryption, client_response, 16) == 0);
 }
 
 
@@ -107,11 +136,12 @@ static BOOL smb_pwd_check_ntlmv2(const uchar *password, size_t pwd_len,
  Do a specific test for an smb password being correct, given a smb_password and
  the lanman and NT responses.
 ****************************************************************************/
-NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info, char user_sess_key[16])
+NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info, uint8 user_sess_key[16])
 {
        const uint8 *nt_pw, *lm_pw;
        uint16  acct_ctrl = pdb_get_acct_ctrl(sampass);
-       
+       uint32 ntlmssp_flags;
+
        if (!user_info || !sampass) 
                return NT_STATUS_LOGON_FAILURE;
 
@@ -119,12 +149,12 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
        {
                if (lp_null_passwords()) 
                {
-                       DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", sampass->username));
+                       DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", pdb_get_username(sampass)));
                        return(NT_STATUS_OK);
                } 
                else 
                {
-                       DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", sampass->username));
+                       DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", pdb_get_username(sampass)));
                        return(NT_STATUS_LOGON_FAILURE);
                }               
        }
@@ -132,61 +162,84 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
        nt_pw = pdb_get_nt_passwd(sampass);
        lm_pw = pdb_get_lanman_passwd(sampass);
        
-       if (nt_pw != NULL && user_info->nt_resp.len > 0) {
-               if ((user_info->nt_resp.len > 24 )) {
+       ntlmssp_flags = user_info->ntlmssp_flags;
+
+       if (nt_pw == NULL) {
+               DEBUG(3,("smb_password_ok: NO NT password stored for user %s.\n", 
+                        pdb_get_username(sampass)));
+               /* No return, we want to check the LM hash below in this case */
+               ntlmssp_flags &= (~(NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2));
+       }
+
+       if (ntlmssp_flags & NTLMSSP_NEGOTIATE_NTLM2) {
                        /* We have the NT MD4 hash challenge available - see if we can
                           use it (ie. does it exist in the smbpasswd file).
                        */
                        DEBUG(4,("smb_password_ok: Checking NTLMv2 password\n"));
-                       if (smb_pwd_check_ntlmv2( user_info->nt_resp.buffer, 
-                                                 user_info->nt_resp.len, 
+                       if (smb_pwd_check_ntlmv2( user_info->nt_resp, 
                                                  nt_pw, 
-                                                 user_info->chal, user_info->smb_username.str, 
-                                                 user_info->requested_domain.str,
+                                                 user_info->sec_blob, user_info->smb_name.str, 
+                                                 user_info->client_domain.str,
                                                  user_sess_key))
                        {
                                return NT_STATUS_OK;
                        } else {
-                               DEBUG(4,("smb_password_ok: NTLMv2 password check failed\n"));
-                                       return NT_STATUS_WRONG_PASSWORD;
+                               DEBUG(3,("smb_password_ok: NTLMv2 password check failed\n"));
+                               return NT_STATUS_WRONG_PASSWORD;
                        }
-                               
-               } else if (lp_ntlm_auth() && (user_info->nt_resp.len == 24)) {
+       } else if (ntlmssp_flags & NTLMSSP_NEGOTIATE_NTLM) {
+                       if (lp_ntlm_auth()) {                           
                                /* We have the NT MD4 hash challenge available - see if we can
                                   use it (ie. does it exist in the smbpasswd file).
                                */
-                       DEBUG(4,("smb_password_ok: Checking NT MD4 password\n"));
-                       if (smb_pwd_check_ntlmv1(user_info->nt_resp.buffer, 
-                                                nt_pw, user_info->chal,
-                                                user_sess_key)) 
-                       {
-                               return NT_STATUS_OK;
+                               DEBUG(4,("smb_password_ok: Checking NT MD4 password\n"));
+                               if (smb_pwd_check_ntlmv1(user_info->nt_resp, 
+                                                        nt_pw, user_info->sec_blob,
+                                                        user_sess_key)) 
+                               {
+                                       return NT_STATUS_OK;
+                               } else {
+                                       DEBUG(3,("smb_password_ok: NT MD4 password check failed for user %s\n",pdb_get_username(sampass)));
+                                       return NT_STATUS_WRONG_PASSWORD;
+                               }
                        } else {
-                               DEBUG(4,("smb_password_ok: NT MD4 password check failed\n"));
-                               return NT_STATUS_WRONG_PASSWORD;
+                               DEBUG(2,("smb_password_ok: NTLMv1 passwords NOT PERMITTED for user %s\n",pdb_get_username(sampass)));                   
+                               /* No return, we want to check the LM hash below in this case */
                        }
-               } else {
-                       return NT_STATUS_LOGON_FAILURE;
-               }
        } 
 
-       if (lm_pw != NULL && user_info->lm_resp.len == 24) {
-               if (lp_lanman_auth()) {
-                       DEBUG(4,("smb_password_ok: Checking LM password\n"));
-                       if (smb_pwd_check_ntlmv1(user_info->lm_resp.buffer, 
-                                                lm_pw, user_info->chal,
-                                                user_sess_key)) 
-                       {
-                               return NT_STATUS_OK;
-                       } else {
-                               DEBUG(4,("smb_password_ok: LM password check failed\n"));
-                               return NT_STATUS_WRONG_PASSWORD;
-                       }       
+       if (lm_pw == NULL) {
+               DEBUG(3,("smb_password_ok: NO LanMan password set for user %s (and no NT password supplied)\n",pdb_get_username(sampass)));
+               ntlmssp_flags &= (~NTLMSSP_NEGOTIATE_OEM);              
+       }
+       
+       if (ntlmssp_flags & NTLMSSP_NEGOTIATE_OEM) {
+               
+               if (user_info->lm_resp.length != 24) {
+                       DEBUG(2,("smb_password_ok: invalid LanMan password length (%d) for user %s\n", 
+                                user_info->nt_resp.length, pdb_get_username(sampass)));                
                }
+               
+               if (!lp_lanman_auth()) {
+                       DEBUG(3,("smb_password_ok: Lanman passwords NOT PERMITTED for user %s\n",pdb_get_username(sampass)));                   
+                       return NT_STATUS_LOGON_FAILURE;
+               }
+               
+               DEBUG(4,("smb_password_ok: Checking LM password\n"));
+               if (smb_pwd_check_ntlmv1(user_info->lm_resp, 
+                                        lm_pw, user_info->sec_blob,
+                                        user_sess_key)) 
+               {
+                       return NT_STATUS_OK;
+               } else {
+                       DEBUG(4,("smb_password_ok: LM password check failed for user %s\n",pdb_get_username(sampass)));
+                       return NT_STATUS_WRONG_PASSWORD;
+               } 
        }
 
-       /* Should not be reached */
-       return NT_STATUS_LOGON_FAILURE;
+       /* Should not be reached, but if they send nothing... */
+       DEBUG(3,("smb_password_ok: NEITHER LanMan nor NT password supplied for user %s\n",pdb_get_username(sampass)));
+       return NT_STATUS_WRONG_PASSWORD;
 }
 
 /****************************************************************************
@@ -290,33 +343,58 @@ SMB hash supplied in the user_info structure
 return an NT_STATUS constant.
 ****************************************************************************/
 
-NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info)
+NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
 {
        SAM_ACCOUNT *sampass=NULL;
        BOOL ret;
        NTSTATUS nt_status;
+       uint8 user_sess_key[16];
+       const uint8* lm_hash;
 
        pdb_init_sam(&sampass);
 
        /* get the account information */
 
        become_root();
-       ret = pdb_getsampwnam(sampass, user_info->unix_username.str);
+       ret = pdb_getsampwnam(sampass, user_info->internal_username.str);
        unbecome_root();
 
        if (ret == False)
        {
-               DEBUG(1,("Couldn't find user '%s' in passdb file.\n", user_info->unix_username.str));
+               DEBUG(1,("Couldn't find user '%s' in passdb file.\n", user_info->internal_username.str));
                pdb_free_sam(&sampass);
                return NT_STATUS_NO_SUCH_USER;
        }
 
-       nt_status = sam_password_ok(sampass, user_info, (char *)(server_info->session_key));
+       nt_status = sam_password_ok(sampass, user_info, user_sess_key);
 
-       if NT_STATUS_IS_OK(nt_status) {
-               nt_status = sam_account_ok(sampass, user_info);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               pdb_free_sam(&sampass);
+               return nt_status;
        }
 
-       pdb_free_sam(&sampass);
+       nt_status = sam_account_ok(sampass, user_info);
+       
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               pdb_free_sam(&sampass);
+               return nt_status;
+       }
+
+       if (!make_server_info_sam(server_info, sampass)) {              
+               DEBUG(0,("failed to malloc memory for server_info\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       lm_hash = pdb_get_lanman_passwd((*server_info)->sam_account);
+       if (lm_hash) {
+               memcpy((*server_info)->first_8_lm_hash, lm_hash, 8);
+       }
+       
+       memcpy((*server_info)->session_key, user_sess_key, sizeof(user_sess_key));
+
        return nt_status;
 }
+
+
+
+
index 29a2a6eafb13505ba57a2db5c9b7eb52d28555a3..d456da1fdf7a85cab86a3dab0849472cbf6d912c 100644 (file)
@@ -82,22 +82,27 @@ check if a username/password is OK assuming the password
 in PLAIN TEXT
 ****************************************************************************/
 
-NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info)
+NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status;
        struct passwd *pass = NULL;
 
        become_root();
-       
-       pass = Get_Pwnam(user_info->unix_username.str);
+       pass = Get_Pwnam(user_info->internal_username.str);
 
        nt_status = pass_check(pass,
-                               pass ? pass->pw_name : user_info->unix_username.str, 
-                               user_info->plaintext_password.str,
-                               user_info->plaintext_password.len,
+                               pass ? pass->pw_name : user_info->internal_username.str, 
+                               (char *)user_info->plaintext_password.data,
+                               user_info->plaintext_password.length-1,
                                lp_update_encrypted() ? 
                                update_smbpassword_file : NULL,
                                True);
+       
+       if NT_STATUS_IS_OK(nt_status) {
+               if (pass) {
+                       make_server_info_pw(server_info, pass);
+               }
+       }
 
        unbecome_root();
 
index d3b9aa7001e75cebd1795ef1ffc266850395d548..297c482af52f43b0cad82e7410c14091f8e46c85 100644 (file)
@@ -25,6 +25,8 @@
 /* Data to do lanman1/2 password challenge. */
 static unsigned char saved_challenge[8];
 static BOOL challenge_sent=False;
+extern fstring remote_machine;
+extern pstring global_myname;
 
 /*******************************************************************
 Get the next challenge value - no repeats.
@@ -64,7 +66,7 @@ BOOL last_challenge(unsigned char *challenge)
  Create a UNIX user on demand.
 ****************************************************************************/
 
-static int smb_create_user(char *unix_user, char *homedir)
+static int smb_create_user(const char *unix_user, const char *homedir)
 {
        pstring add_script;
        int ret;
@@ -100,40 +102,560 @@ static int smb_delete_user(char *unix_user)
  Add and Delete UNIX users on demand, based on NTSTATUS codes.
 ****************************************************************************/
 
-void smb_user_control(char *unix_user, NTSTATUS nt_status) 
+void smb_user_control(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, NTSTATUS nt_status) 
 {
        struct passwd *pwd=NULL;
 
        if (NT_STATUS_IS_OK(nt_status)) {
-               /*
-                * User validated ok against Domain controller.
-                * If the admin wants us to try and create a UNIX
-                * user on the fly, do so.
-                */
-               if(lp_adduser_script() && !(pwd = smb_getpwnam(unix_user,True)))
-                       smb_create_user(unix_user, NULL);
-
-               if(lp_adduser_script() && pwd) {
-                       SMB_STRUCT_STAT st;
 
+               if (!(server_info->sam_fill_level & SAM_FILL_UNIX)) {
+                       
                        /*
-                        * Also call smb_create_user if the users home directory
-                        * doesn't exist. Used with winbindd to allow the script to
-                        * create the home directory for a user mapped with winbindd.
+                        * User validated ok against Domain controller.
+                        * If the admin wants us to try and create a UNIX
+                        * user on the fly, do so.
                         */
+                       
+                       if(lp_adduser_script() && !(pwd = Get_Pwnam(user_info->internal_username.str))) {
+                               smb_create_user(user_info->internal_username.str, NULL);
+                       }
+               } else {                        
+                       if(lp_adduser_script()) {
+                               SMB_STRUCT_STAT st;
+                               const char *home_dir = pdb_get_homedir(server_info->sam_account);
+                               /*
+                                * Also call smb_create_user if the users home directory
+                                * doesn't exist. Used with winbindd to allow the script to
+                                * create the home directory for a user mapped with winbindd.
+                                */
 
-                       if (pwd->pw_dir && (sys_stat(pwd->pw_dir, &st) == -1) && (errno == ENOENT))
-                               smb_create_user(unix_user, pwd->pw_dir);
+                               if (home_dir && 
+                                   (sys_stat(home_dir, &st) == -1) && (errno == ENOENT)) {
+                                       smb_create_user(user_info->internal_username.str, home_dir);
+                               }
+                       }
                }
-
-       } else if (NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_NO_SUCH_USER)) {
+       } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
                /*
                 * User failed to validate ok against Domain controller.
                 * If the failure was "user doesn't exist" and admin 
                 * wants us to try and delete that UNIX user on the fly,
                 * do so.
                 */
-               if(lp_deluser_script() && smb_getpwnam(unix_user,True))
-                       smb_delete_user(unix_user);
+               if (lp_deluser_script()) {
+                       smb_delete_user(user_info->internal_username.str);
+               }
+       }
+}
+
+/****************************************************************************
+ Create an auth_usersupplied_data structure
+****************************************************************************/
+
+BOOL make_user_info(auth_usersupplied_info **user_info, 
+                   char *smb_name, char *internal_username,
+                   char *client_domain, char *domain,
+                   char *wksta_name, DATA_BLOB sec_blob, 
+                   DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
+                   DATA_BLOB plaintext, 
+                   uint32 ntlmssp_flags, BOOL encrypted)
+{
+
+       DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
+
+       *user_info = malloc(sizeof(**user_info));
+       if (!user_info) {
+               DEBUG(0,("malloc failed for user_info (size %d)\n", sizeof(*user_info)));
+               return False;
+       }
+
+       ZERO_STRUCTP(*user_info);
+
+       DEBUG(5,("makeing strings for %s's user_info struct\n", internal_username));
+
+       (*user_info)->smb_name.str = strdup(smb_name);
+       if ((*user_info)->smb_name.str) { 
+               (*user_info)->smb_name.len = strlen(smb_name);
+       } else {
+               free_user_info(user_info);
+               return False;
+       }
+       
+       (*user_info)->internal_username.str = strdup(internal_username);
+       if ((*user_info)->internal_username.str) { 
+               (*user_info)->internal_username.len = strlen(internal_username);
+       } else {
+               free_user_info(user_info);
+               return False;
+       }
+
+       (*user_info)->domain.str = strdup(domain);
+       if ((*user_info)->domain.str) { 
+               (*user_info)->domain.len = strlen(domain);
+       } else {
+               free_user_info(user_info);
+               return False;
+       }
+
+       (*user_info)->client_domain.str = strdup(client_domain);
+       if ((*user_info)->client_domain.str) { 
+               (*user_info)->client_domain.len = strlen(client_domain);
+       } else {
+               free_user_info(user_info);
+               return False;
+       }
+
+       (*user_info)->wksta_name.str = strdup(wksta_name);
+       if ((*user_info)->wksta_name.str) { 
+               (*user_info)->wksta_name.len = strlen(wksta_name);
+       } else {
+               free_user_info(user_info);
+               return False;
        }
+
+       DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username));
+
+       (*user_info)->sec_blob = data_blob(sec_blob.data, sec_blob.length);
+       (*user_info)->lm_resp = data_blob(lm_pwd.data, lm_pwd.length);
+       (*user_info)->nt_resp = data_blob(nt_pwd.data, nt_pwd.length);
+       (*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length);
+
+       (*user_info)->encrypted = encrypted;
+       (*user_info)->ntlmssp_flags = ntlmssp_flags;
+
+       DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
+
+       return True;
 }
+
+/****************************************************************************
+ Create an auth_usersupplied_data structure after appropriate mapping.
+****************************************************************************/
+
+BOOL make_user_info_map(auth_usersupplied_info **user_info, 
+                       char *smb_name, 
+                       char *client_domain, 
+                       char *wksta_name, DATA_BLOB sec_blob, 
+                       DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
+                       DATA_BLOB plaintext, 
+                       uint32 ntlmssp_flags, BOOL encrypted)
+{
+       char *domain;
+       fstring internal_username;
+       fstrcpy(internal_username, smb_name);
+       map_username(internal_username); 
+       
+       if (lp_allow_trusted_domains()) {
+               domain = client_domain;
+       } else {
+               domain = lp_workgroup();
+       }
+       
+       return make_user_info(user_info, 
+                             smb_name, internal_username,
+                             client_domain, domain,
+                             wksta_name, sec_blob,
+                             lm_pwd, nt_pwd,
+                             plaintext, 
+                             ntlmssp_flags, encrypted);
+       
+}
+
+/****************************************************************************
+ Create an auth_usersupplied_data, making the DATA_BLOBs here. 
+ Decrupt and encrypt the passwords.
+****************************************************************************/
+
+BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
+                                    char *smb_name, 
+                                    char *client_domain, 
+                                    char *wksta_name, uchar chal[8],
+                                    uchar *lm_network_pwd, int lm_pwd_len,
+                                    uchar *nt_network_pwd, int nt_pwd_len)
+{
+       BOOL ret;
+       DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
+       DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
+       DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
+       DATA_BLOB plaintext_blob = data_blob(NULL, 0);
+       uint32 ntlmssp_flags = 0;
+
+       if (lm_pwd_len)
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+       if (nt_pwd_len)
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM; 
+       
+       ret = make_user_info_map(user_info, 
+                                smb_name, client_domain, 
+                                wksta_name, sec_blob, 
+                                nt_blob, lm_blob,
+                                plaintext_blob, 
+                                ntlmssp_flags, True);
+               
+       data_blob_free(&lm_blob);
+       data_blob_free(&nt_blob);
+       return ret;
+}
+
+/****************************************************************************
+ Create an auth_usersupplied_data, making the DATA_BLOBs here. 
+ Decrupt and encrypt the passwords.
+****************************************************************************/
+
+BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
+                               char *smb_name, 
+                               char *client_domain, 
+                               char *wksta_name, 
+                               uchar *lm_interactive_pwd, int lm_pwd_len,
+                               uchar *nt_interactive_pwd, int nt_pwd_len,
+                               uchar *dc_sess_key)
+{
+       char nt_pwd[16];
+       char lm_pwd[16];
+       unsigned char local_lm_response[24];
+       unsigned char local_nt_response[24];
+       unsigned char key[16];
+       uint8 chal[8];
+       uint32 ntlmssp_flags = 0;
+       
+       generate_random_buffer(chal, 8, False);
+
+       memset(key, 0, 16);
+       memcpy(key, dc_sess_key, 8);
+       
+       memcpy(lm_pwd, lm_interactive_pwd, 16);
+       memcpy(nt_pwd, nt_interactive_pwd, 16);
+       
+#ifdef DEBUG_PASSWORD
+       DEBUG(100,("key:"));
+       dump_data(100, (char *)key, 16);
+       
+       DEBUG(100,("lm owf password:"));
+       dump_data(100, lm_pwd, 16);
+       
+       DEBUG(100,("nt owf password:"));
+       dump_data(100, nt_pwd, 16);
+#endif
+       
+       SamOEMhash((uchar *)lm_pwd, key, 16);
+       SamOEMhash((uchar *)nt_pwd, key, 16);
+       
+#ifdef DEBUG_PASSWORD
+       DEBUG(100,("decrypt of lm owf password:"));
+       dump_data(100, lm_pwd, 16);
+       
+       DEBUG(100,("decrypt of nt owf password:"));
+       dump_data(100, nt_pwd, 16);
+#endif
+       
+       generate_random_buffer(chal, 8, False);
+       SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
+       SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
+       
+       /* Password info parinoia */
+       ZERO_STRUCT(lm_pwd);
+       ZERO_STRUCT(nt_pwd);
+       ZERO_STRUCT(key);
+
+       {
+               BOOL ret;
+               DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
+               DATA_BLOB local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
+               DATA_BLOB local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
+               DATA_BLOB plaintext_blob = data_blob(NULL, 0);
+
+               ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM;         
+               ret = make_user_info_map(user_info, 
+                                        smb_name, client_domain, 
+                                        wksta_name, sec_blob, 
+                                        local_nt_blob,
+                                        local_lm_blob,
+                                        plaintext_blob, 
+                                        ntlmssp_flags, True);
+               
+               data_blob_free(&local_lm_blob);
+               data_blob_free(&local_nt_blob);
+               return ret;
+       }
+}
+
+/****************************************************************************
+ Create an auth_usersupplied_data structure
+****************************************************************************/
+
+BOOL make_user_info_for_winbind(auth_usersupplied_info **user_info, 
+                               char *username,
+                               char *domain, 
+                               char *password)
+{
+       unsigned char local_lm_response[24];
+       unsigned char local_nt_response[24];
+       char chal[8];
+       DATA_BLOB local_lm_blob;
+       DATA_BLOB local_nt_blob;
+       DATA_BLOB plaintext_blob;
+       uint32 ntlmssp_flags = 0;
+
+       /*
+        * Not encrypted - do so.
+        */
+       
+       DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
+       
+       generate_random_buffer(chal, 8, False);
+
+       if (*password) {
+               SMBencrypt( (uchar *)password, chal, local_lm_response);
+               
+               /* This encrypts the lm_pwd feild, which actualy contains the password
+                  rather than the nt_pwd field becouse that contains nothing */
+               
+               /* 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 */
+               
+               SMBNTencrypt((uchar *)password, chal, local_nt_response);
+
+               local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
+               local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
+               plaintext_blob = data_blob(password, strlen(password)+1);
+               if ((!local_lm_blob.data) || (!local_nt_blob.data)|| (!plaintext_blob.data)) {
+                       data_blob_free(&local_lm_blob);
+                       data_blob_free(&local_nt_blob);
+                       data_blob_clear_free(&plaintext_blob);
+                       return False;
+               }
+               ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM;
+       } else {
+               local_lm_blob = data_blob(NULL, 0);
+               local_nt_blob = data_blob(NULL, 0);
+               plaintext_blob = data_blob(NULL, 0);
+       }
+
+       {
+               BOOL ret;
+               DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
+               
+               if (!sec_blob.data) {
+                       return False;
+               }
+
+               ret = make_user_info(user_info, 
+                                    username, username,
+                                    domain, domain, 
+                                    global_myname, sec_blob, 
+                                    local_nt_blob,
+                                    local_lm_blob,
+                                    plaintext_blob, 
+                                    ntlmssp_flags, False);
+               
+               data_blob_free(&local_lm_blob);
+               data_blob_free(&local_nt_blob);
+               data_blob_clear_free(&plaintext_blob);
+               return ret;
+       }
+}
+
+/****************************************************************************
+ Create an auth_usersupplied_data, making the DATA_BLOBs here. 
+ Decrupt and encrypt the passwords.
+****************************************************************************/
+
+BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info, 
+                                char *smb_name, 
+                                char *client_domain, 
+                                uchar chal[8],
+                                uchar *lm_network_pwd, int lm_pwd_len,
+                                uchar *nt_network_pwd, int nt_pwd_len)
+{
+       BOOL ret;
+       DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
+       DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
+       DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
+       DATA_BLOB plaintext_blob = data_blob(NULL, 0);
+       uint32 ntlmssp_flags = 0;
+
+       if (lm_pwd_len)
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+       if (nt_pwd_len)
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM; 
+       
+       ret = make_user_info(user_info, 
+                            smb_name, smb_name, 
+                            client_domain, client_domain, 
+                            global_myname, sec_blob, 
+                            nt_blob, lm_blob,
+                            plaintext_blob, 
+                            ntlmssp_flags, True);
+
+       data_blob_free(&lm_blob);
+       data_blob_free(&nt_blob);
+       return ret;
+}
+
+/****************************************************************************
+ Create an auth_usersupplied_data structure
+****************************************************************************/
+
+BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
+                             char *smb_name,
+                             char *client_domain, 
+                             DATA_BLOB lm_resp, DATA_BLOB nt_resp,
+                             DATA_BLOB plaintext_password,
+                             BOOL encrypted)
+{
+       uchar chal[8];
+
+       DATA_BLOB local_lm_blob;
+       DATA_BLOB local_nt_blob;
+       DATA_BLOB sec_blob;
+       BOOL ret = False;
+       uint32 ntlmssp_flags = 0;
+                       
+       if (encrypted) {
+               DATA_BLOB no_plaintext_blob = data_blob(NULL, 0); 
+               if (!last_challenge(chal)) {
+                       DEBUG(0,("Encrypted login but no challange set!\n"));
+                       return False;
+               }
+               sec_blob = data_blob(chal, 8);
+               
+               if (lm_resp.length == 24) {
+                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+               }
+               if (nt_resp.length == 0) {
+               } else if (nt_resp.length == 24) {
+                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
+               } else {
+                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
+               }
+
+               return make_user_info_map(user_info, smb_name, 
+                                         client_domain, 
+                                         remote_machine, sec_blob,
+                                         lm_resp, 
+                                         nt_resp, 
+                                         no_plaintext_blob, 
+                                         ntlmssp_flags, encrypted);
+       }
+
+       generate_random_buffer(chal, 8, False);
+
+       sec_blob = data_blob(chal, 8);
+       
+       /*
+        * Not encrypted - do so.
+        */
+       
+       DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
+       
+       if (plaintext_password.data) {
+               unsigned char local_lm_response[24];
+
+               SMBencrypt( (uchar *)plaintext_password.data, chal, local_lm_response);
+               local_lm_blob = data_blob(local_lm_response, 24);
+               
+               /* We can't do an NT hash here, as the password needs to be case insensitive */
+               local_nt_blob = data_blob(NULL, 0); 
+               
+               ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM;
+       } else {
+               local_lm_blob = data_blob(NULL, 0); 
+               local_nt_blob = data_blob(NULL, 0); 
+       }
+       
+       ret = make_user_info_map(user_info, smb_name,
+                                client_domain, 
+                                remote_machine,
+                                sec_blob,
+                                local_lm_blob,
+                                local_nt_blob,
+                                plaintext_password, 
+                                ntlmssp_flags, encrypted);
+       
+       data_blob_free(&local_lm_blob);
+       return ret;
+}
+
+BOOL make_server_info(auth_serversupplied_info **server_info) 
+{
+       *server_info = malloc(sizeof(**server_info));
+       if (!*server_info) {
+               DEBUG(0,("make_server_info_sam: malloc failed!\n"));
+               return False;
+       }
+       ZERO_STRUCTP(*server_info);
+       return True;
+}
+
+BOOL make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass) 
+{
+       if (!make_server_info(server_info)) {
+               return False;
+       }
+
+       (*server_info)->sam_fill_level = SAM_FILL_ALL;
+       (*server_info)->sam_account = sampass;
+
+       DEBUG(5,("make_server_info_sam: made sever info for user %s\n",
+                pdb_get_username((*server_info)->sam_account)));
+       return True;
+}
+
+BOOL make_server_info_pw(auth_serversupplied_info **server_info, struct passwd *pwd)
+{
+       SAM_ACCOUNT *sampass = NULL;
+       if (!pdb_init_sam_pw(&sampass, pwd)) {          
+               return False;
+       }
+       return make_server_info_sam(server_info, sampass);
+}
+
+void free_user_info(auth_usersupplied_info **user_info)
+{
+       DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
+       if (*user_info != NULL) {
+               if ((*user_info)->smb_name.str) {
+                       DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
+               }
+               SAFE_FREE((*user_info)->smb_name.str);
+               SAFE_FREE((*user_info)->internal_username.str);
+               SAFE_FREE((*user_info)->client_domain.str);
+               SAFE_FREE((*user_info)->domain.str);
+               data_blob_free(&(*user_info)->sec_blob);
+               data_blob_free(&(*user_info)->lm_resp);
+               data_blob_free(&(*user_info)->nt_resp);
+               SAFE_FREE((*user_info)->interactive_password);
+               data_blob_clear_free(&(*user_info)->plaintext_password);
+               ZERO_STRUCT(**user_info);
+       }
+       SAFE_FREE(*user_info);
+}
+
+/***************************************************************************
+ Clear out a server_info struct that has been allocated
+***************************************************************************/
+void free_server_info(auth_serversupplied_info **server_info)
+{
+       if (*server_info != NULL) {
+               pdb_free_sam(&(*server_info)->sam_account);
+               
+               /* call pam_end here, unless we know we are keeping it */
+               SAFE_FREE((*server_info)->group_rids);
+
+               ZERO_STRUCT(**server_info);
+       }
+       SAFE_FREE(*server_info);
+}
+
+/***************************************************************************
+ Make a server_info struct for a guest user 
+***************************************************************************/
+void make_server_info_guest(auth_serversupplied_info **server_info) 
+{
+       struct passwd *pass = sys_getpwnam(lp_guestaccount(-1));
+       
+       if (pass) {
+               make_server_info_pw(server_info, pass);
+       }
+}
+
index e8f40f1fa39356649a14e255ed9388120b92984f..01eabfda5ebd1c9348db4e26b8d452ae37b5e87e 100644 (file)
@@ -197,10 +197,11 @@ has been given. vuid is biased by an offset. This allows us to
 tell random client vuid's (normally zero) from valid vuids.
 ****************************************************************************/
 
-int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, 
-                 char *domain,BOOL guest, char *full_name)
+int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL guest)
 {
        user_struct *vuser = NULL;
+       uid_t *puid;
+       gid_t *pgid;
 
        /* Ensure no vuid gets registered in share level security. */
        if(lp_security() == SEC_SHARE)
@@ -217,8 +218,14 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
 
        ZERO_STRUCTP(vuser);
 
-       DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)uid, (unsigned int)gid,
-                               unix_name, requested_name, domain, guest ));
+        puid = pdb_get_uid(server_info->sam_account);
+        pgid = pdb_get_gid(server_info->sam_account);
+
+       if (!puid || !pgid) {
+               DEBUG(0,("Attempted session setup with invalid user.  No uid/gid in SAM_ACCOUNT\n"));
+               free(vuser);
+               return UID_FIELD_INVALID;
+       }
 
        /* Allocate a free vuid. Yes this is a linear search... :-) */
        while( get_valid_user_struct(next_vuid) != NULL ) {
@@ -231,13 +238,19 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
        DEBUG(10,("register_vuid: allocated vuid = %u\n", (unsigned int)next_vuid ));
 
        vuser->vuid = next_vuid;
-       vuser->uid = uid;
-       vuser->gid = gid;
+       vuser->uid = *puid;
+       vuser->gid = *pgid;
        vuser->guest = guest;
-       fstrcpy(vuser->user.unix_name,unix_name);
-       fstrcpy(vuser->user.smb_name,requested_name);
-       fstrcpy(vuser->user.domain,domain);
-       fstrcpy(vuser->user.full_name, full_name);
+       fstrcpy(vuser->user.unix_name, pdb_get_username(server_info->sam_account));
+       fstrcpy(vuser->user.smb_name, smb_name);
+       fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account));
+       fstrcpy(vuser->user.full_name, pdb_get_fullname(server_info->sam_account));
+
+       DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", 
+                 (unsigned int)vuser->uid, 
+                 (unsigned int)vuser->gid,
+                 vuser->user.unix_name, vuser->user.smb_name, vuser->user.domain, guest ));
+
        DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,vuser->user.full_name));       
 
        vuser->n_groups = 0;
@@ -332,7 +345,7 @@ BOOL user_ok(char *user,int snum)
 /****************************************************************************
 validate a group username entry. Return the username or NULL
 ****************************************************************************/
-static char *validate_group(char *group,char *password,int pwlen,int snum)
+static char *validate_group(char *group, DATA_BLOB password,int snum)
 {
 #ifdef HAVE_NETGROUP
        {
@@ -341,7 +354,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum)
                while (getnetgrent(&host, &user, &domain)) {
                        if (user) {
                                if (user_ok(user, snum) && 
-                                   password_ok(user,password,pwlen)) {
+                                   password_ok(user,password)) {
                                        endnetgrent();
                                        return(user);
                                }
@@ -396,7 +409,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum)
                                static fstring name;
                                fstrcpy(name,member);
                                if (user_ok(name,snum) &&
-                                   password_ok(name,password,pwlen)) {
+                                   password_ok(name,password)) {
                                        endgrent();
                                        return(&name[0]);
                                }
@@ -419,7 +432,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum)
  Note this is *NOT* used when logging on using sessionsetup_and_X.
 ****************************************************************************/
 
-BOOL authorise_login(int snum,char *user,char *password, int pwlen
+BOOL authorise_login(int snum,char *user, DATA_BLOB password
                     BOOL *guest,BOOL *force,uint16 vuid)
 {
        BOOL ok = False;
@@ -427,7 +440,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
 
 #if DEBUG_PASSWORD
        DEBUG(100,("authorise_login: checking authorisation on user=%s pass=%s\n",
-                       user,password));
+                       user,password.data));
 #endif
 
        *guest = False;
@@ -472,7 +485,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
                /* check for a previously registered guest username */
                if (!ok && (vuser != 0) && vuser->guest) {        
                        if (user_ok(vuser->user.unix_name,snum) &&
-                                       password_ok(vuser->user.unix_name, password, pwlen)) {
+                                       password_ok(vuser->user.unix_name, password)) {
                                fstrcpy(user, vuser->user.unix_name);
                                vuser->guest = False;
                                DEBUG(3,("authorise_login: ACCEPTED: given password with registered user %s\n", user));
@@ -494,7 +507,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
                                if (!user_ok(user2,snum))
                                        continue;
                  
-                               if (password_ok(user2,password, pwlen)) {
+                               if (password_ok(user2,password)) {
                                        ok = True;
                                        fstrcpy(user,user2);
                                        DEBUG(3,("authorise_login: ACCEPTED: session list username (%s) \
@@ -526,7 +539,7 @@ and given password ok\n", user));
                        for (auser=strtok(user_list,LIST_SEP); auser && !ok;
                                                                                        auser = strtok(NULL,LIST_SEP)) {
                                if (*auser == '@') {
-                                       auser = validate_group(auser+1,password,pwlen,snum);
+                                       auser = validate_group(auser+1,password,snum);
                                        if (auser) {
                                                ok = True;
                                                fstrcpy(user,auser);
@@ -536,7 +549,7 @@ and given password ok (%s)\n", user));
                                } else {
                                        fstring user2;
                                        fstrcpy(user2,auser);
-                                       if (user_ok(user2,snum) && password_ok(user2,password,pwlen)) {
+                                       if (user_ok(user2,snum) && password_ok(user2,password)) {
                                                ok = True;
                                                fstrcpy(user,user2);
                                                DEBUG(3,("authorise_login: ACCEPTED: user list username \
index ca7bcb9c5f6837e52e003af006ad9ffa8d325d3a..b60738d23d600b22ef80e475b18936f1145716aa 100644 (file)
@@ -159,14 +159,16 @@ int reply_tcon(connection_struct *conn,
        int pwlen=0;
        NTSTATUS nt_status;
        char *p;
-
+       DATA_BLOB password_blob;
+       
        START_PROFILE(SMBtcon);
 
        *service = *password = *dev = 0;
 
        p = smb_buf(inbuf)+1;
        p += srvstr_pull(inbuf, service, p, sizeof(service), -1, STR_TERMINATE) + 1;
-       p += srvstr_pull(inbuf, password, p, sizeof(password), -1, STR_TERMINATE) + 1;
+       pwlen = srvstr_pull(inbuf, password, p, sizeof(password), -1, STR_TERMINATE) + 1;
+       p += pwlen;
        p += srvstr_pull(inbuf, dev, p, sizeof(dev), -1, STR_TERMINATE) + 1;
 
        p = strrchr_m(service,'\\');
@@ -174,7 +176,9 @@ int reply_tcon(connection_struct *conn,
                pstrcpy(service, p+1);
        }
 
-       conn = make_connection(service,password,pwlen,dev,vuid,&nt_status);
+       password_blob = data_blob(password, pwlen+1);
+
+       conn = make_connection(service,password_blob,dev,vuid,&nt_status);
   
        if (!conn) {
                END_PROFILE(SMBtcon);
@@ -200,16 +204,17 @@ int reply_tcon(connection_struct *conn,
 int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
        fstring service;
-       pstring password;
+       DATA_BLOB password;
        pstring devicename;
        NTSTATUS nt_status;
        uint16 vuid = SVAL(inbuf,smb_uid);
        int passlen = SVAL(inbuf,smb_vwv3);
        pstring path;
        char *p, *q;
-       START_PROFILE(SMBtconX);
-       
-       *service = *password = *devicename = 0;
+       extern BOOL global_encrypted_passwords_negotiated;
+       START_PROFILE(SMBtconX);        
+
+       *service = *devicename = 0;
 
        /* we might have to close an old one */
        if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
@@ -220,17 +225,17 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
                return ERROR_DOS(ERRDOS,ERRbuftoosmall);
        }
  
-       memcpy(password,smb_buf(inbuf),passlen);
-       password[passlen]=0;    
+       if (global_encrypted_passwords_negotiated) {
+               password = data_blob(smb_buf(inbuf),passlen);
+       } else {
+               password = data_blob(smb_buf(inbuf),passlen+1);
+               /* Ensure correct termination */
+               password.data[passlen]=0;    
+       }
+
        p = smb_buf(inbuf) + passlen;
        p += srvstr_pull(inbuf, path, p, sizeof(path), -1, STR_TERMINATE);
 
-       if (passlen != 24) {
-               if (strequal(password," "))
-                       *password = 0;
-               passlen = strlen(password);
-       }
-       
        /*
         * the service name can be either: \\server\share
         * or share directly like on the DELL PowerVault 705
@@ -250,7 +255,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
 
        DEBUG(4,("Got device type %s\n",devicename));
 
-       conn = make_connection(service,password,passlen,devicename,vuid,&nt_status);
+       conn = make_connection(service,password,devicename,vuid,&nt_status);
        
        if (!conn) {
                END_PROFILE(SMBtconX);
index 37f4610b9d4ca6a38e4eea1c1e530318a5dd9537..f6296201ae4245b40756662bf01e1da4c5fbf1b5 100644 (file)
@@ -79,7 +79,7 @@ BOOL set_current_service(connection_struct *conn,BOOL do_chdir)
  Add a home service. Returns the new service number or -1 if fail.
 ****************************************************************************/
 
-int add_home_service(char *service, char *homedir)
+int add_home_service(const char *service, const char *homedir)
 {
        int iHomeService;
        int iService;
@@ -320,8 +320,8 @@ static void set_admin_user(connection_struct *conn)
  Make a connection to a service.
 ****************************************************************************/
 
-connection_struct *make_connection(char *service,char *password, 
-                                  int pwlen, char *dev,uint16 vuid, NTSTATUS *status)
+connection_struct *make_connection(char *service, DATA_BLOB password, 
+                                  char *dev,uint16 vuid, NTSTATUS *status)
 {
        int snum;
        struct passwd *pass = NULL;
@@ -361,7 +361,7 @@ connection_struct *make_connection(char *service,char *password,
                        if (validated_username(vuid)) {
                                fstring unix_username;
                                fstrcpy(unix_username,validated_username(vuid));
-                               return(make_connection(unix_username,password,pwlen,dev,vuid,status));
+                               return(make_connection(unix_username,password,dev,vuid,status));
                        }
                } else {
                        /* Security = share. Try with current_user_info.smb_name
@@ -370,7 +370,7 @@ connection_struct *make_connection(char *service,char *password,
                                fstring unix_username;
                                fstrcpy(unix_username,current_user_info.smb_name);
                                map_username(unix_username);
-                               return(make_connection(unix_username,password,pwlen,dev,vuid,status));
+                               return(make_connection(unix_username,password,dev,vuid,status));
                        }
                }
        }
@@ -387,7 +387,7 @@ connection_struct *make_connection(char *service,char *password,
 
 
        /* shall we let them in? */
-       if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid)) {
+       if (!authorise_login(snum,user,password,&guest,&force,vuid)) {
                DEBUG( 2, ( "Invalid username/password for %s [%s]\n", service, user ) );
                *status = NT_STATUS_WRONG_PASSWORD;
                return NULL;
index 2d9f624b800f1fefb964d286b76bfdd2d1465939..5331127cb595043dd287db2f403e42a63b36ac5e 100644 (file)
@@ -264,14 +264,16 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
        DATA_BLOB auth;
        char *workgroup, *user, *machine;
        DATA_BLOB lmhash, nthash, sess_key;
+       DATA_BLOB plaintext_password = data_blob(NULL, 0);
+       DATA_BLOB sec_blob;
        uint32 ntlmssp_command, neg_flags;
        NTSTATUS nt_status;
        int sess_vuid;
-       gid_t gid;
-       uid_t uid;
-       char *full_name;
        char *p;
-       const struct passwd *pw;
+       char chal[8];
+
+       auth_usersupplied_info *user_info = NULL;
+       auth_serversupplied_info *server_info = NULL;
 
        if (!spnego_parse_auth(blob1, &auth)) {
 #if 0
@@ -305,36 +307,40 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
        file_save("lmhash1.dat", lmhash.data, lmhash.length);
 #endif
 
-       nt_status = pass_check_smb(user, user, 
-                                  workgroup, machine,
-                                  lmhash.data,
-                                  lmhash.length,
-                                  nthash.data,
-                                  nthash.length);
-
-       data_blob_free(&nthash);
+       if (!last_challenge(chal)) {
+               DEBUG(0,("Encrypted login but no challange set!\n"));
+               return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+       }
+       sec_blob = data_blob(chal, 8);
+       if (!sec_blob.data) {
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
+       
+       if (!make_user_info_map(&user_info, 
+                               user, workgroup, 
+                               machine, sec_blob,
+                               lmhash, nthash,
+                               plaintext_password, 
+                               neg_flags, True)) {
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
+       
+       nt_status = check_password(user_info, &server_info); 
+       
+       free_user_info(&user_info);
+       
        data_blob_free(&lmhash);
-
+       
+       data_blob_free(&nthash);
+       
        if (!NT_STATUS_IS_OK(nt_status)) {
-               return ERROR_NT(nt_status);
+               return ERROR_NT(nt_status_squash(nt_status));
        }
 
-       /* the password is good - let them in */
-       pw = smb_getpwnam(user,False);
-       if (!pw) {
-               DEBUG(1,("Username %s is invalid on this system\n",user));
-               return ERROR_NT(NT_STATUS_LOGON_FAILURE);
-       }
-       gid = pw->pw_gid;
-       uid = pw->pw_uid;
-       full_name = pw->pw_gecos;
-
-       sess_vuid = register_vuid(uid,gid,user,user,workgroup,False, full_name);
+       sess_vuid = register_vuid(server_info, user, False);
 
-       free(user);
-       free(workgroup);
-       free(machine);
-       
+       free_server_info(&server_info);
+  
        if (sess_vuid == -1) {
                return ERROR_NT(NT_STATUS_LOGON_FAILURE);
        }
@@ -360,30 +366,16 @@ reply to a session setup spnego anonymous packet
 static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *outbuf,
                                  int length, int bufsize)
 {
-       char *user;
        int sess_vuid;
-       gid_t gid;
-       uid_t uid;
-       char *full_name;
        char *p;
-       const struct passwd *pw;
+       auth_serversupplied_info *server_info = NULL;
 
        DEBUG(3,("Got anonymous request\n"));
 
-       user = lp_guestaccount(-1);
-
-       /* the password is good - let them in */
-       pw = smb_getpwnam(user,False);
-       if (!pw) {
-               DEBUG(1,("Guest username %s is invalid on this system\n",user));
-               return ERROR_NT(NT_STATUS_LOGON_FAILURE);
-       }
-       gid = pw->pw_gid;
-       uid = pw->pw_uid;
-       full_name = pw->pw_gecos;
-
-       sess_vuid = register_vuid(uid,gid,user,user,lp_workgroup(),True,full_name);
-       
+       make_server_info_guest(&server_info);
+       sess_vuid = register_vuid(server_info, lp_guestaccount(-1), False);
+       free_server_info(&server_info);
+  
        if (sess_vuid == -1) {
                return ERROR_NT(NT_STATUS_LOGON_FAILURE);
        }
@@ -414,7 +406,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha
        extern uint32 global_client_caps;
        int ret;
 
-       DEBUG(3,("Doing spego session setup\n"));
+       DEBUG(3,("Doing spnego session setup\n"));
 
        if (global_client_caps == 0) {
                global_client_caps = IVAL(inbuf,smb_vwv10);
@@ -464,16 +456,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                          int length,int bufsize)
 {
        int sess_vuid;
-       gid_t gid;
-       uid_t uid;
-       char* full_name;
        int   smb_bufsize;    
-       int   smb_apasslen = 0;   
-       pstring smb_apasswd;
-       int   smb_ntpasslen = 0;   
-       pstring smb_ntpasswd;
+       DATA_BLOB lm_resp;
+       DATA_BLOB nt_resp;
+       DATA_BLOB plaintext_password;
        pstring user;
-       pstring orig_user;
        fstring domain;
        fstring native_os;
        fstring native_lanman;
@@ -486,9 +473,18 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
        extern fstring remote_machine;
        extern userdom_struct current_user_info;
        extern int max_send;
+
+       auth_usersupplied_info *user_info = NULL;
+       auth_serversupplied_info *server_info = NULL;
+
        BOOL doencrypt = global_encrypted_passwords_negotiated;
+
        START_PROFILE(SMBsesssetupX);
 
+       ZERO_STRUCT(lm_resp);
+       ZERO_STRUCT(nt_resp);
+       ZERO_STRUCT(plaintext_password);
+
        DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), SVAL(inbuf, smb_flg2)));
        
        /* a SPNEGO session setup has 12 command words, whereas a normal
@@ -503,28 +499,35 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
        }
 
-       *smb_apasswd = *smb_ntpasswd = 0;
-       
        smb_bufsize = SVAL(inbuf,smb_vwv2);
-       
+
        if (Protocol < PROTOCOL_NT1) {
-               smb_apasslen = SVAL(inbuf,smb_vwv7);
-               if (smb_apasslen > MAX_PASS_LEN) {
+               uint16 passlen1 = SVAL(inbuf,smb_vwv7);
+               if (passlen1 > MAX_PASS_LEN) {
                        return ERROR_DOS(ERRDOS,ERRbuftoosmall);
                }
 
-               memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
-               srvstr_pull(inbuf, user, smb_buf(inbuf)+smb_apasslen, sizeof(user), -1, STR_TERMINATE);
-               
-               if (!doencrypt && (lp_security() != SEC_SERVER)) {
-                       smb_apasslen = strlen(smb_apasswd);
+               if (doencrypt) {
+                       lm_resp = data_blob(smb_buf(inbuf), passlen1);
+               } else {
+                       plaintext_password = data_blob(smb_buf(inbuf), passlen1+1);
+                       if (!plaintext_password.data) {
+                               DEBUG(0,("reply_sesssetup_and_X: malloc failed for plaintext_password!\n"));
+                               return ERROR_NT(NT_STATUS_NO_MEMORY);
+                       } else {
+                               /* Ensure null termination */
+                               plaintext_password.data[passlen1] = 0;
+                       }
                }
+
+               srvstr_pull(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), -1, STR_TERMINATE);
+  
        } else {
                uint16 passlen1 = SVAL(inbuf,smb_vwv7);
                uint16 passlen2 = SVAL(inbuf,smb_vwv8);
                enum remote_arch_types ra_type = get_remote_arch();
                char *p = smb_buf(inbuf);    
-               
+
                if(global_client_caps == 0)
                        global_client_caps = IVAL(inbuf,smb_vwv11);
                
@@ -539,16 +542,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                        }
                }
                
-               if (passlen1 != 24 && passlen2 < 24)
-                       doencrypt = False;
-               
                if (passlen1 > MAX_PASS_LEN) {
                        return ERROR_DOS(ERRDOS,ERRbuftoosmall);
                }
-               
+
                passlen1 = MIN(passlen1, MAX_PASS_LEN);
                passlen2 = MIN(passlen2, MAX_PASS_LEN);
-               
+
                if (!doencrypt) {
                        /* both Win95 and WinNT stuff up the password lengths for
                           non-encrypting systems. Uggh. 
@@ -591,23 +591,20 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                                passlen1 = 1;
                        }
                }
-
+               
                /* Save the lanman2 password and the NT md4 password. */
-               smb_apasslen = passlen1;
-               memcpy(smb_apasswd,p,smb_apasslen);
-
-               smb_ntpasslen = passlen2;
-               memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen);
-
-               if (smb_apasslen != 24 || !doencrypt) {
-                       /* trim the password */
-                       smb_apasslen = strlen(smb_apasswd);
-                       
-                       /* wfwg sometimes uses a space instead of a null */
-                       if (strequal(smb_apasswd," ")) {
-                               smb_apasslen = 0;
-                               *smb_apasswd = 0;
-                       }
+               
+               if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
+                       doencrypt = False;
+               }
+               
+               if (doencrypt) {
+                       lm_resp = data_blob(p, passlen1);
+                       nt_resp = data_blob(p+passlen1, passlen2);
+               } else {
+                       plaintext_password = data_blob(p, passlen1+1);
+                       /* Ensure null termination */
+                       plaintext_password.data[passlen1] = 0;
                }
                
                p += passlen1 + passlen2;
@@ -630,15 +627,29 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                return ERROR_NT(NT_STATUS_LOGON_FAILURE);
        }
 
-       if (lp_security() == SEC_SHARE) {
-               /* in share level we should ignore any passwords */
-               smb_ntpasslen = 0;
-               smb_apasslen = 0;
+       DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, remote_machine));
+
+       /* If no username is sent use the guest account */
+       if (!*user) {
+               pstrcpy(user,lp_guestaccount(-1));
                guest = True;
        }
 
+       pstrcpy(current_user_info.smb_name,user);
+
+       reload_services(True);
+       
+       if (lp_security() == SEC_SHARE) {
+               /* in share level we should ignore any passwords */
+
+               data_blob_free(&lm_resp);
+               data_blob_free(&nt_resp);
+               data_blob_free(&plaintext_password);
 
-       DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",user, domain, remote_machine));
+               guest = True;
+               map_username(user);
+               add_session_user(user);
+       }
        
        if (done_sesssetup && lp_restrict_anonymous()) {
                /* tests show that even if browsing is done over
@@ -649,106 +660,61 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                 * only deny connections that have no session
                 * information.  If a domain has been provided, then
                 * it's not a purely anonymous connection. AAB */
-               if (!*user && !*smb_apasswd && !*domain) {
+               if (!*user && !*domain) {
                        DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n"));
+                       
+                       data_blob_free(&lm_resp);
+                       data_blob_free(&nt_resp);
+                       data_blob_free(&plaintext_password);
+
                        END_PROFILE(SMBsesssetupX);
                        return ERROR_DOS(ERRDOS,ERRnoaccess);
                }
        }
-
-       /* If no username is sent use the guest account */
-       if (!*user) {
-               pstrcpy(user,lp_guestaccount(-1));
-               guest = True;
-       }
-       
-       pstrcpy(current_user_info.smb_name,user);
-       
-       reload_services(True);
-       
-       /*
-        * Save the username before mapping. We will use
-        * the original username sent to us for security=server
-        * and security=domain checking.
-        */
-       
-       pstrcpy( orig_user, user);
-       
-       /*
-        * Always try the "DOMAIN\user" lookup first, as this is the most
-        * specific case. If this fails then try the simple "user" lookup.
-        * But don't do this for guests, as this is always a local user.
-        */
        
        if (!guest) {
-               pstring dom_user;
-               
-               /* Work out who's who */
-               
-               slprintf(dom_user, sizeof(dom_user) - 1,"%s%s%s",
-                        domain, lp_winbind_separator(), user);
-               
-               if (sys_getpwnam(dom_user) != NULL) {
-                       pstrcpy(user, dom_user);
-                       DEBUG(3,("Using unix username %s\n", dom_user));
+               NTSTATUS nt_status;
+               if (!make_user_info_for_reply(&user_info, 
+                                             user, domain, 
+                                             lm_resp, nt_resp,
+                                             plaintext_password, doencrypt)) {
+                       return ERROR_NT(NT_STATUS_NO_MEMORY);
                }
                
-               /*
-                * Pass the user through the NT -> unix user mapping
-                * function.
-                */
+               nt_status = check_password(user_info, &server_info); 
                
-               (void)map_username(user);
+               free_user_info(&user_info);
                
-               /*
-                * Do any UNIX username case mangling.
-                */
-               smb_getpwnam(user, True);
-       }
-       
-       add_session_user(user);
-       
-       if (!guest) {
-               NTSTATUS nt_status;
-               nt_status = pass_check_smb(orig_user, user, 
-                                          domain, remote_machine,
-                                          (unsigned char *)smb_apasswd, 
-                                          smb_apasslen, 
-                                          (unsigned char *)smb_ntpasswd,
-                                          smb_ntpasslen);
-         
-               if NT_STATUS_IS_OK(nt_status) {
-
-               } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
-                       if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || 
-                           (lp_map_to_guest() ==  MAP_TO_GUEST_ON_BAD_PASSWORD)) {
-                               DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain));
-                               pstrcpy(user,lp_guestaccount(-1));
-                               guest = True;
-                       } else {
-                               /* Match WinXP and don't give the game away */
-                               return ERROR_NT(NT_STATUS_LOGON_FAILURE);
-                       }
-               } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
-                       if (lp_map_to_guest() ==  MAP_TO_GUEST_ON_BAD_PASSWORD) {
-                               pstrcpy(user,lp_guestaccount(-1));
-                               DEBUG(3,("Registered username %s for guest access\n",user));
-                               guest = True;
-                       } else {
+               data_blob_free(&lm_resp);
+               data_blob_free(&nt_resp);
+               data_blob_free(&plaintext_password);
+               
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
+                               if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || 
+                                   (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
+                                       DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain));
+                                       pstrcpy(user,lp_guestaccount(-1));
+                                       guest = True;
+                                       
+                               }
+                       } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
+                               if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
+                                       pstrcpy(user,lp_guestaccount(-1));
+                                       DEBUG(3,("Registered username %s for guest access\n",user));
+                                       guest = True;
+                               }
                                /* Match WinXP and don't give the game away */
                                return ERROR_NT(NT_STATUS_LOGON_FAILURE);
                        }
-               } else {
-                       return ERROR_NT(nt_status);
+                       
+                       if (!guest) {
+                               free_server_info(&server_info);
+                               return ERROR_NT(nt_status_squash(nt_status));
+                       }  
                }
        }
        
-       if (!strequal(user,lp_guestaccount(-1)) &&
-           lp_servicenumber(user) < 0) {
-               add_home_service(user,get_user_home_dir(user));
-       }
-
-
        /* it's ok - setup a reply */
        if (Protocol < PROTOCOL_NT1) {
                set_message(outbuf,3,0,True);
@@ -763,30 +729,26 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                /* perhaps grab OS version here?? */
        }
        
-       /* Set the correct uid in the outgoing and incoming packets
-          We will use this on future requests to determine which
-          user we should become.
-       */
-       {
-               const struct passwd *pw = smb_getpwnam(user,False);
-               if (!pw) {
-                       DEBUG(1,("Username %s is invalid on this system\n",user));
-                       END_PROFILE(SMBsesssetupX);
-                       return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+       if (guest) {
+               SSVAL(outbuf,smb_vwv2,1);
+               free_server_info(&server_info);
+               make_server_info_guest(&server_info);
+       } else {
+               const char *home_dir = pdb_get_homedir(server_info->sam_account);
+               const char *username = pdb_get_username(server_info->sam_account);
+               if ((home_dir && *home_dir)
+                   && (lp_servicenumber(username) < 0)) {
+                       add_home_service(username, home_dir);     
                }
-               gid = pw->pw_gid;
-               uid = pw->pw_uid;
-               full_name = pw->pw_gecos;
        }
-       
-       if (guest)
-               SSVAL(outbuf,smb_vwv2,1);
-       
+
        /* register the name and uid as being validated, so further connections
           to a uid can get through without a password, on the same VC */
-       
-       sess_vuid = register_vuid(uid,gid,user,orig_user,domain,guest, full_name);
-       
+
+       sess_vuid = register_vuid(server_info, user, guest);
+
+       free_server_info(&server_info);
+  
        if (sess_vuid == -1) {
                return ERROR_NT(NT_STATUS_LOGON_FAILURE);
        }