2 Unix SMB/Netbios implementation.
4 Authentication utility functions
5 Copyright (C) Andrew Tridgell 1992-1998
6 Copyright (C) Andrew Bartlett 2001
7 Copyright (C) Jeremy Allison 2000-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.
26 /* Data to do lanman1/2 password challenge. */
27 static unsigned char saved_challenge[8];
28 static BOOL challenge_sent=False;
29 extern fstring remote_machine;
30 extern pstring global_myname;
32 /*******************************************************************
33 Get the next challenge value - no repeats.
34 ********************************************************************/
36 void generate_next_challenge(char *challenge)
40 generate_random_buffer(buf,8,False);
41 memcpy(saved_challenge, buf, 8);
42 memcpy(challenge,buf,8);
43 challenge_sent = True;
46 /*******************************************************************
47 Set the last challenge sent, usually from a password server.
48 ********************************************************************/
50 BOOL set_challenge(unsigned char *challenge)
52 memcpy(saved_challenge,challenge,8);
53 challenge_sent = True;
57 /*******************************************************************
58 Get the last challenge sent.
59 ********************************************************************/
61 BOOL last_challenge(unsigned char *challenge)
65 memcpy(challenge,saved_challenge,8);
69 /****************************************************************************
70 Create a UNIX user on demand.
71 ****************************************************************************/
73 static int smb_create_user(const char *unix_user, const char *homedir)
78 pstrcpy(add_script, lp_adduser_script());
81 all_string_sub(add_script, "%u", unix_user, sizeof(pstring));
83 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
84 ret = smbrun(add_script,NULL);
85 DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
89 /****************************************************************************
90 Delete a UNIX user on demand.
91 ****************************************************************************/
93 static int smb_delete_user(char *unix_user)
98 pstrcpy(del_script, lp_deluser_script());
101 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
102 ret = smbrun(del_script,NULL);
103 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
107 /****************************************************************************
108 Add and Delete UNIX users on demand, based on NTSTATUS codes.
109 ****************************************************************************/
111 void smb_user_control(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, NTSTATUS nt_status)
113 struct passwd *pwd=NULL;
115 if (NT_STATUS_IS_OK(nt_status)) {
117 if (!(server_info->sam_fill_level & SAM_FILL_UNIX)) {
120 * User validated ok against Domain controller.
121 * If the admin wants us to try and create a UNIX
122 * user on the fly, do so.
125 if(lp_adduser_script() && !(pwd = Get_Pwnam(user_info->internal_username.str))) {
126 smb_create_user(user_info->internal_username.str, NULL);
129 if(lp_adduser_script()) {
131 const char *home_dir = pdb_get_homedir(server_info->sam_account);
133 * Also call smb_create_user if the users home directory
134 * doesn't exist. Used with winbindd to allow the script to
135 * create the home directory for a user mapped with winbindd.
139 (sys_stat(home_dir, &st) == -1) && (errno == ENOENT)) {
140 smb_create_user(user_info->internal_username.str, home_dir);
144 } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
146 * User failed to validate ok against Domain controller.
147 * If the failure was "user doesn't exist" and admin
148 * wants us to try and delete that UNIX user on the fly,
151 if (lp_deluser_script()) {
152 smb_delete_user(user_info->internal_username.str);
157 /****************************************************************************
158 Create an auth_usersupplied_data structure
159 ****************************************************************************/
161 static BOOL make_user_info(auth_usersupplied_info **user_info,
162 const char *smb_name,
163 const char *internal_username,
164 const char *client_domain,
166 const char *wksta_name,
168 DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
170 uint32 ntlmssp_flags, BOOL encrypted)
173 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
175 *user_info = malloc(sizeof(**user_info));
177 DEBUG(0,("malloc failed for user_info (size %d)\n", sizeof(*user_info)));
181 ZERO_STRUCTP(*user_info);
183 DEBUG(5,("makeing strings for %s's user_info struct\n", internal_username));
185 (*user_info)->smb_name.str = strdup(smb_name);
186 if ((*user_info)->smb_name.str) {
187 (*user_info)->smb_name.len = strlen(smb_name);
189 free_user_info(user_info);
193 (*user_info)->internal_username.str = strdup(internal_username);
194 if ((*user_info)->internal_username.str) {
195 (*user_info)->internal_username.len = strlen(internal_username);
197 free_user_info(user_info);
201 (*user_info)->domain.str = strdup(domain);
202 if ((*user_info)->domain.str) {
203 (*user_info)->domain.len = strlen(domain);
205 free_user_info(user_info);
209 (*user_info)->client_domain.str = strdup(client_domain);
210 if ((*user_info)->client_domain.str) {
211 (*user_info)->client_domain.len = strlen(client_domain);
213 free_user_info(user_info);
217 (*user_info)->wksta_name.str = strdup(wksta_name);
218 if ((*user_info)->wksta_name.str) {
219 (*user_info)->wksta_name.len = strlen(wksta_name);
221 free_user_info(user_info);
225 DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username));
227 (*user_info)->sec_blob = data_blob(sec_blob.data, sec_blob.length);
228 (*user_info)->lm_resp = data_blob(lm_pwd.data, lm_pwd.length);
229 (*user_info)->nt_resp = data_blob(nt_pwd.data, nt_pwd.length);
230 (*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length);
232 (*user_info)->encrypted = encrypted;
233 (*user_info)->ntlmssp_flags = ntlmssp_flags;
235 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
240 /****************************************************************************
241 Create an auth_usersupplied_data structure after appropriate mapping.
242 ****************************************************************************/
244 BOOL make_user_info_map(auth_usersupplied_info **user_info,
245 const char *smb_name,
246 const char *client_domain,
247 const char *wksta_name, DATA_BLOB sec_blob,
248 DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
250 uint32 ntlmssp_flags, BOOL encrypted)
253 fstring internal_username;
254 fstrcpy(internal_username, smb_name);
255 map_username(internal_username);
257 if (lp_allow_trusted_domains()) {
258 domain = client_domain;
260 domain = lp_workgroup();
263 return make_user_info(user_info,
264 smb_name, internal_username,
265 client_domain, domain,
266 wksta_name, sec_blob,
269 ntlmssp_flags, encrypted);
273 /****************************************************************************
274 Create an auth_usersupplied_data, making the DATA_BLOBs here.
275 Decrupt and encrypt the passwords.
276 ****************************************************************************/
278 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
281 char *wksta_name, uchar chal[8],
282 uchar *lm_network_pwd, int lm_pwd_len,
283 uchar *nt_network_pwd, int nt_pwd_len)
286 DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
287 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
288 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
289 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
290 uint32 ntlmssp_flags = 0;
293 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
294 if (nt_pwd_len == 24) {
295 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
296 } else if (nt_pwd_len != 0) {
297 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
300 ret = make_user_info_map(user_info,
301 smb_name, client_domain,
302 wksta_name, sec_blob,
305 ntlmssp_flags, True);
307 data_blob_free(&lm_blob);
308 data_blob_free(&nt_blob);
312 /****************************************************************************
313 Create an auth_usersupplied_data, making the DATA_BLOBs here.
314 Decrupt and encrypt the passwords.
315 ****************************************************************************/
317 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
321 uchar lm_interactive_pwd[16],
322 uchar nt_interactive_pwd[16],
327 unsigned char local_lm_response[24];
328 unsigned char local_nt_response[24];
329 unsigned char key[16];
331 uint32 ntlmssp_flags = 0;
333 generate_random_buffer(chal, 8, False);
336 memcpy(key, dc_sess_key, 8);
338 if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
339 if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
341 #ifdef DEBUG_PASSWORD
343 dump_data(100, (char *)key, sizeof(key));
345 DEBUG(100,("lm owf password:"));
346 dump_data(100, lm_pwd, sizeof(lm_pwd));
348 DEBUG(100,("nt owf password:"));
349 dump_data(100, nt_pwd, sizeof(nt_pwd));
352 SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
353 SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
355 #ifdef DEBUG_PASSWORD
356 DEBUG(100,("decrypt of lm owf password:"));
357 dump_data(100, lm_pwd, sizeof(lm_pwd));
359 DEBUG(100,("decrypt of nt owf password:"));
360 dump_data(100, nt_pwd, sizeof(nt_pwd));
363 generate_random_buffer(chal, 8, False);
364 SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
365 SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
367 /* Password info parinoia */
374 DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
375 DATA_BLOB local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
376 DATA_BLOB local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
377 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
379 if (lm_interactive_pwd)
380 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
381 if (nt_interactive_pwd)
382 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
384 ret = make_user_info_map(user_info,
385 smb_name, client_domain,
386 wksta_name, sec_blob,
390 ntlmssp_flags, True);
392 data_blob_free(&local_lm_blob);
393 data_blob_free(&local_nt_blob);
398 /****************************************************************************
399 Create an auth_usersupplied_data structure
400 ****************************************************************************/
402 BOOL make_user_info_winbind(auth_usersupplied_info **user_info,
407 unsigned char local_lm_response[24];
408 unsigned char local_nt_response[24];
410 DATA_BLOB local_lm_blob;
411 DATA_BLOB local_nt_blob;
412 DATA_BLOB plaintext_blob;
413 uint32 ntlmssp_flags = 0;
416 * Not encrypted - do so.
419 DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
421 generate_random_buffer(chal, 8, False);
424 SMBencrypt( (const uchar *)password, chal, local_lm_response);
426 /* This encrypts the lm_pwd feild, which actualy contains the password
427 rather than the nt_pwd field becouse that contains nothing */
429 /* WATCH OUT. This doesn't work if the incoming password is incorrectly cased.
430 We might want to add a check here and only do an LM in that case */
432 SMBNTencrypt((const uchar *)password, chal, local_nt_response);
434 local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
435 local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
436 plaintext_blob = data_blob(password, strlen(password)+1);
437 if ((!local_lm_blob.data) || (!local_nt_blob.data)|| (!plaintext_blob.data)) {
438 data_blob_free(&local_lm_blob);
439 data_blob_free(&local_nt_blob);
440 data_blob_clear_free(&plaintext_blob);
443 ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM;
445 local_lm_blob = data_blob(NULL, 0);
446 local_nt_blob = data_blob(NULL, 0);
447 plaintext_blob = data_blob(NULL, 0);
452 DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
454 if (!sec_blob.data) {
458 ret = make_user_info(user_info,
461 global_myname, sec_blob,
465 ntlmssp_flags, False);
467 data_blob_free(&local_lm_blob);
468 data_blob_free(&local_nt_blob);
469 data_blob_clear_free(&plaintext_blob);
474 /****************************************************************************
475 Create an auth_usersupplied_data, making the DATA_BLOBs here.
476 Decrupt and encrypt the passwords.
477 ****************************************************************************/
479 BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info,
483 uchar *lm_network_pwd, int lm_pwd_len,
484 uchar *nt_network_pwd, int nt_pwd_len)
487 DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
488 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
489 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
490 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
491 uint32 ntlmssp_flags = 0;
494 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
496 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
498 ret = make_user_info(user_info,
500 client_domain, client_domain,
501 global_myname, sec_blob,
504 ntlmssp_flags, True);
506 data_blob_free(&lm_blob);
507 data_blob_free(&nt_blob);
511 /****************************************************************************
512 Create an auth_usersupplied_data structure
513 ****************************************************************************/
515 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
518 DATA_BLOB lm_resp, DATA_BLOB nt_resp,
519 DATA_BLOB plaintext_password,
524 DATA_BLOB local_lm_blob;
525 DATA_BLOB local_nt_blob;
528 uint32 ntlmssp_flags = 0;
531 DATA_BLOB no_plaintext_blob = data_blob(NULL, 0);
532 if (!last_challenge(chal)) {
533 DEBUG(0,("Encrypted login but no challange set!\n"));
536 sec_blob = data_blob(chal, 8);
538 if (lm_resp.length == 24) {
539 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
541 if (nt_resp.length == 0) {
542 } else if (nt_resp.length == 24) {
543 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
545 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
548 return make_user_info_map(user_info, smb_name,
550 remote_machine, sec_blob,
554 ntlmssp_flags, encrypted);
557 generate_random_buffer(chal, 8, False);
559 sec_blob = data_blob(chal, 8);
562 * Not encrypted - do so.
565 DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
567 if (plaintext_password.data) {
568 unsigned char local_lm_response[24];
570 SMBencrypt( (const uchar *)plaintext_password.data, chal, local_lm_response);
571 local_lm_blob = data_blob(local_lm_response, 24);
573 /* We can't do an NT hash here, as the password needs to be case insensitive */
574 local_nt_blob = data_blob(NULL, 0);
576 ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM;
578 local_lm_blob = data_blob(NULL, 0);
579 local_nt_blob = data_blob(NULL, 0);
582 ret = make_user_info_map(user_info, smb_name,
589 ntlmssp_flags, encrypted);
591 data_blob_free(&local_lm_blob);
595 /****************************************************************************
596 Create a guest user_info blob, for anonymous authenticaion.
597 ****************************************************************************/
599 BOOL make_user_info_guest(auth_usersupplied_info **user_info)
601 DATA_BLOB sec_blob = data_blob(NULL, 0);
602 DATA_BLOB lm_blob = data_blob(NULL, 0);
603 DATA_BLOB nt_blob = data_blob(NULL, 0);
604 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
605 uint32 ntlmssp_flags = 0;
607 return make_user_info(user_info,
613 ntlmssp_flags, True);
616 /***************************************************************************
617 Make a user_info struct
618 ***************************************************************************/
620 BOOL make_server_info(auth_serversupplied_info **server_info)
622 *server_info = malloc(sizeof(**server_info));
624 DEBUG(0,("make_server_info: malloc failed!\n"));
627 ZERO_STRUCTP(*server_info);
631 /***************************************************************************
632 Make (and fill) a user_info struct from a SAM_ACCOUNT
633 ***************************************************************************/
635 BOOL make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass)
637 if (!make_server_info(server_info)) {
641 (*server_info)->sam_fill_level = SAM_FILL_ALL;
642 (*server_info)->sam_account = sampass;
644 DEBUG(5,("make_server_info_sam: made server info for user %s\n",
645 pdb_get_username((*server_info)->sam_account)));
649 /***************************************************************************
650 Make (and fill) a user_info struct from a 'struct passwd' by conversion
652 ***************************************************************************/
654 BOOL make_server_info_pw(auth_serversupplied_info **server_info, const struct passwd *pwd)
656 SAM_ACCOUNT *sampass = NULL;
657 if (!pdb_init_sam_pw(&sampass, pwd)) {
660 return make_server_info_sam(server_info, sampass);
663 /***************************************************************************
664 Free a user_info struct
665 ***************************************************************************/
667 void free_user_info(auth_usersupplied_info **user_info)
669 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
670 if (*user_info != NULL) {
671 if ((*user_info)->smb_name.str) {
672 DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
674 SAFE_FREE((*user_info)->smb_name.str);
675 SAFE_FREE((*user_info)->internal_username.str);
676 SAFE_FREE((*user_info)->client_domain.str);
677 SAFE_FREE((*user_info)->domain.str);
678 data_blob_free(&(*user_info)->sec_blob);
679 data_blob_free(&(*user_info)->lm_resp);
680 data_blob_free(&(*user_info)->nt_resp);
681 SAFE_FREE((*user_info)->interactive_password);
682 data_blob_clear_free(&(*user_info)->plaintext_password);
683 ZERO_STRUCT(**user_info);
685 SAFE_FREE(*user_info);
688 /***************************************************************************
689 Clear out a server_info struct that has been allocated
690 ***************************************************************************/
692 void free_server_info(auth_serversupplied_info **server_info)
694 if (*server_info != NULL) {
695 pdb_free_sam(&(*server_info)->sam_account);
697 /* call pam_end here, unless we know we are keeping it */
698 delete_nt_token( &(*server_info)->ptok );
699 ZERO_STRUCT(**server_info);
701 SAFE_FREE(*server_info);
704 /***************************************************************************
705 Make a server_info struct for a guest user
706 ***************************************************************************/
708 BOOL make_server_info_guest(auth_serversupplied_info **server_info)
710 struct passwd *pass = sys_getpwnam(lp_guestaccount());
713 if (!make_server_info_pw(server_info, pass)) {
716 (*server_info)->guest = True;
719 DEBUG(0,("make_server_info_guest: sys_getpwnam() failed on guest account!\n"));
723 /****************************************************************************
725 ****************************************************************************/
727 void delete_nt_token(NT_USER_TOKEN **pptoken)
730 NT_USER_TOKEN *ptoken = *pptoken;
731 SAFE_FREE( ptoken->user_sids );
732 ZERO_STRUCTP(ptoken);
737 /****************************************************************************
738 Duplicate a SID token.
739 ****************************************************************************/
741 NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
743 NT_USER_TOKEN *token;
748 if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
753 if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
758 token->num_sids = ptoken->num_sids;
763 /****************************************************************************
764 Check for a guest logon (username = "") and if so create the required
766 ****************************************************************************/
768 NTSTATUS check_guest_security(const auth_usersupplied_info *user_info,
769 auth_serversupplied_info **server_info)
771 NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
773 if (!(user_info->internal_username.str
774 && *user_info->internal_username.str)) {
775 if (make_server_info_guest(server_info)) {
776 nt_status = NT_STATUS_OK;
778 nt_status = NT_STATUS_NO_SUCH_USER;