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