me stupid.
[Samba.git] / source / smbd / auth.c
blob4bfbfe65fee4ec0361a931c339cc9379b351a87a
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Password and authentication handling
5 Copyright (C) Andrew Tridgell 1992-2000
6 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
7 Copyright (C) Andrew Bartlett 2001
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "includes.h"
26 extern int DEBUGLEVEL;
28 extern pstring global_myname;
31 /****************************************************************************
32 update the encrypted smbpasswd file from the plaintext username and password
34 this ugly hack needs to die, but not quite yet...
35 *****************************************************************************/
36 static BOOL update_smbpassword_file(char *user, char *password)
38 SAM_ACCOUNT *sampass = NULL;
39 BOOL ret;
41 pdb_init_sam(&sampass);
43 become_root();
44 ret = pdb_getsampwnam(sampass, user);
45 unbecome_root();
47 if(ret == False) {
48 DEBUG(0,("pdb_getsampwnam returned NULL\n"));
49 pdb_free_sam(sampass);
50 return False;
54 * Remove the account disabled flag - we are updating the
55 * users password from a login.
57 pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED);
59 /* Here, the flag is one, because we want to ignore the
60 XXXXXXX'd out password */
61 ret = change_oem_password( sampass, password, True);
62 if (ret == False) {
63 DEBUG(3,("change_oem_password returned False\n"));
66 pdb_free_sam(sampass);
67 return ret;
70 /****************************************************************************
71 Check user is in correct domain if required
72 ****************************************************************************/
74 static BOOL check_domain_match(char *user, char *domain)
77 * If we aren't serving to trusted domains, we must make sure that
78 * the validation request comes from an account in the same domain
79 * as the Samba server
82 if (!lp_allow_trusted_domains() &&
83 !strequal(lp_workgroup(), domain) ) {
84 DEBUG(1, ("check_domain_match: Attempt to connect as user %s from domain %s denied.\n", user, domain));
85 return False;
86 } else {
87 return True;
92 uint32 check_password(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info)
95 uint32 nt_status = NT_STATUS_LOGON_FAILURE;
97 DEBUG(3, ("check_password: Checking password for user %s with the new password interface\n", user_info->smb_username.str));
98 if (check_hosts_equiv(user_info->smb_username.str)) {
99 nt_status = NT_STATUS_NOPROBLEMO;
102 if (!check_domain_match(user_info->smb_username.str, user_info->domain.str)) {
103 return NT_STATUS_LOGON_FAILURE;
106 if ((lp_security() == SEC_DOMAIN) && (nt_status != NT_STATUS_NOPROBLEMO)) {
107 nt_status = check_domain_security(user_info, server_info);
110 if ((lp_security() == SEC_SERVER) && (nt_status != NT_STATUS_NOPROBLEMO)) {
111 nt_status = check_server_security(user_info, server_info);
114 if (lp_security() >= SEC_SERVER) {
115 smb_user_control(user_info->smb_username.str, nt_status);
118 if ((nt_status != NT_STATUS_NOPROBLEMO)
119 && (user_info->plaintext_password.len > 0)
120 && (!lp_plaintext_to_smbpasswd())) {
121 return (pass_check(user_info->smb_username.str,
122 user_info->plaintext_password.str,
123 user_info->plaintext_password.len,
124 lp_update_encrypted() ?
125 update_smbpassword_file : NULL)
126 ? NT_STATUS_NOPROBLEMO : NT_STATUS_LOGON_FAILURE);
129 if (nt_status != NT_STATUS_NOPROBLEMO) {
130 nt_status = check_smbpasswd_security(user_info, server_info);
133 if (nt_status == NT_STATUS_NOPROBLEMO) {
134 /* We might not be root if we are an RPC call */
135 become_root();
136 nt_status = smb_pam_accountcheck(user_info->smb_username.str);
137 unbecome_root();
140 if (nt_status == NT_STATUS_NOPROBLEMO) {
141 DEBUG(5, ("check_password: Password for user %s suceeded\n", user_info->smb_username.str));
142 } else {
143 DEBUG(3, ("check_password: Password for user %s FAILED with error %d\n", user_info->smb_username.str, nt_status));
145 return nt_status;
149 /****************************************************************************
150 COMPATABILITY INTERFACES:
151 ***************************************************************************/
153 /****************************************************************************
154 check if a username/password is OK assuming the password is a 24 byte
155 SMB hash
156 return True if the password is correct, False otherwise
157 ****************************************************************************/
159 uint32 pass_check_smb_with_chal(char *user, char *domain, uchar chal[8],
160 uchar *lm_pwd, int lm_pwd_len,
161 uchar *nt_pwd, int nt_pwd_len)
164 auth_usersupplied_info user_info;
165 auth_serversupplied_info server_info;
166 AUTH_STR ourdomain, theirdomain, smb_username, wksta_name;
168 ZERO_STRUCT(user_info);
169 ZERO_STRUCT(ourdomain);
170 ZERO_STRUCT(theirdomain);
171 ZERO_STRUCT(smb_username);
172 ZERO_STRUCT(wksta_name);
174 ourdomain.str = lp_workgroup();
175 ourdomain.len = strlen(ourdomain.str);
177 theirdomain.str = domain;
178 theirdomain.len = strlen(theirdomain.str);
180 user_info.requested_domain = theirdomain;
181 user_info.domain = ourdomain;
183 smb_username.str = user;
184 smb_username.len = strlen(smb_username.str);
186 user_info.requested_username = smb_username; /* For the time-being */
187 user_info.smb_username = smb_username;
189 user_info.wksta_name.str = client_name();
190 user_info.wksta_name.len = strlen(client_name());
192 user_info.wksta_name = wksta_name;
194 memcpy(user_info.chal, chal, 8);
196 if (lm_pwd_len >= 24 || (lp_encrypted_passwords() && (lm_pwd_len == 0) && lp_null_passwords())) {
197 /* if 24 bytes long assume it is an encrypted password */
199 user_info.lm_resp.buffer = (uint8 *)lm_pwd;
200 user_info.lm_resp.len = lm_pwd_len;
201 user_info.nt_resp.buffer = (uint8 *)nt_pwd;
202 user_info.nt_resp.len = nt_pwd_len;
204 } else {
205 unsigned char local_lm_response[24];
206 unsigned char local_nt_response[24];
209 * Not encrypted - do so.
212 DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
214 if (lm_pwd_len > 0) {
215 SMBencrypt( (uchar *)lm_pwd, user_info.chal, local_lm_response);
216 user_info.lm_resp.buffer = (uint8 *)local_lm_response;
217 user_info.lm_resp.len = 24;
219 /* This encrypts the lm_pwd feild, which actualy contains the password
220 rather than the nt_pwd field becouse that contains nothing */
221 SMBNTencrypt((uchar *)lm_pwd, user_info.chal, local_nt_response);
222 user_info.nt_resp.buffer = (uint8 *)local_nt_response;
223 user_info.nt_resp.len = 24;
226 user_info.plaintext_password.str = lm_pwd;
227 user_info.plaintext_password.len = lm_pwd_len;
231 return check_password(&user_info, &server_info);
234 uint32 pass_check_smb(char *user, char *domain,
235 uchar *lm_pwd, int lm_pwd_len,
236 uchar *nt_pwd, int nt_pwd_len)
238 uchar chal[8];
240 if (!last_challenge(chal)) {
241 generate_random_buffer( chal, 8, False);
244 return pass_check_smb_with_chal(user, domain, chal,
245 lm_pwd, lm_pwd_len,
246 nt_pwd, nt_pwd_len);
250 /****************************************************************************
251 check if a username/password pair is OK either via the system password
252 database or the encrypted SMB password database
253 return True if the password is correct, False otherwise
254 ****************************************************************************/
255 BOOL password_ok(char *user, char *password, int pwlen)
259 * This hack must die! But until I rewrite the rest of samba
260 * it must stay - abartlet 2001-08-03
263 if ((pwlen == 0) && !lp_null_passwords()) {
264 DEBUG(4,("Null passwords not allowed.\n"));
265 return False;
268 if (pass_check_smb(user, lp_workgroup(), NULL, 0, password, pwlen) == NT_STATUS_NOPROBLEMO) {
269 return True;
272 if (pass_check_smb(user, lp_workgroup(), password, pwlen, NULL, 0) == NT_STATUS_NOPROBLEMO) {
273 return True;
276 return False;