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 field, which actualy contains
427 the password rather than the nt_pwd field becouse that
430 /* WATCH OUT. This doesn't work if the incoming password is
431 incorrectly cased. We might want to add a check here
432 and only do an LM in that case */
434 SMBNTencrypt((const uchar *)password, chal, local_nt_response);
436 local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
437 local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
438 plaintext_blob = data_blob(password, strlen(password)+1);
439 if ((!local_lm_blob.data) || (!local_nt_blob.data)|| (!plaintext_blob.data)) {
440 data_blob_free(&local_lm_blob);
441 data_blob_free(&local_nt_blob);
442 data_blob_clear_free(&plaintext_blob);
445 ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM;
447 local_lm_blob = data_blob(NULL, 0);
448 local_nt_blob = data_blob(NULL, 0);
449 plaintext_blob = data_blob(NULL, 0);
454 DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
456 if (!sec_blob.data) {
460 ret = make_user_info(user_info,
463 global_myname, sec_blob,
467 ntlmssp_flags, False);
469 data_blob_free(&local_lm_blob);
470 data_blob_free(&local_nt_blob);
471 data_blob_clear_free(&plaintext_blob);
476 /****************************************************************************
477 Create an auth_usersupplied_data, making the DATA_BLOBs here.
478 Decrypt and encrypt the passwords.
479 ****************************************************************************/
481 BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info,
485 uchar *lm_network_pwd, int lm_pwd_len,
486 uchar *nt_network_pwd, int nt_pwd_len)
489 DATA_BLOB sec_blob = data_blob(chal, 8);
490 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
491 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
492 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
493 uint32 ntlmssp_flags = 0;
496 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
498 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
500 ret = make_user_info(user_info,
502 client_domain, client_domain,
503 global_myname, sec_blob,
506 ntlmssp_flags, True);
508 data_blob_free(&lm_blob);
509 data_blob_free(&nt_blob);
513 /****************************************************************************
514 Create an auth_usersupplied_data structure
515 ****************************************************************************/
517 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
520 DATA_BLOB lm_resp, DATA_BLOB nt_resp,
521 DATA_BLOB plaintext_password,
526 DATA_BLOB local_lm_blob;
527 DATA_BLOB local_nt_blob;
530 uint32 ntlmssp_flags = 0;
533 DATA_BLOB no_plaintext_blob = data_blob(NULL, 0);
534 if (!last_challenge(chal)) {
535 DEBUG(0,("Encrypted login but no challange set!\n"));
538 sec_blob = data_blob(chal, 8);
540 if (lm_resp.length == 24) {
541 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
543 if (nt_resp.length == 0) {
544 } else if (nt_resp.length == 24) {
545 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
547 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
550 return make_user_info_map(user_info, smb_name,
552 remote_machine, sec_blob,
556 ntlmssp_flags, encrypted);
559 generate_random_buffer(chal, 8, False);
561 sec_blob = data_blob(chal, 8);
564 * Not encrypted - do so.
567 DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
569 if (plaintext_password.data) {
570 unsigned char local_lm_response[24];
572 SMBencrypt( (const uchar *)plaintext_password.data, chal, local_lm_response);
573 local_lm_blob = data_blob(local_lm_response, 24);
575 /* We can't do an NT hash here, as the password needs to be case insensitive */
576 local_nt_blob = data_blob(NULL, 0);
578 ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM;
580 local_lm_blob = data_blob(NULL, 0);
581 local_nt_blob = data_blob(NULL, 0);
584 ret = make_user_info_map(user_info, smb_name,
591 ntlmssp_flags, encrypted);
593 data_blob_free(&local_lm_blob);
597 /****************************************************************************
598 Create a guest user_info blob, for anonymous authenticaion.
599 ****************************************************************************/
601 BOOL make_user_info_guest(auth_usersupplied_info **user_info)
603 DATA_BLOB sec_blob = data_blob(NULL, 0);
604 DATA_BLOB lm_blob = data_blob(NULL, 0);
605 DATA_BLOB nt_blob = data_blob(NULL, 0);
606 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
607 uint32 ntlmssp_flags = 0;
609 return make_user_info(user_info,
615 ntlmssp_flags, True);
618 /***************************************************************************
619 Make a user_info struct
620 ***************************************************************************/
622 BOOL make_server_info(auth_serversupplied_info **server_info)
624 *server_info = malloc(sizeof(**server_info));
626 DEBUG(0,("make_server_info: malloc failed!\n"));
629 ZERO_STRUCTP(*server_info);
633 /***************************************************************************
634 Make (and fill) a user_info struct from a SAM_ACCOUNT
635 ***************************************************************************/
637 BOOL make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass)
639 if (!make_server_info(server_info)) {
643 (*server_info)->sam_fill_level = SAM_FILL_ALL;
644 (*server_info)->sam_account = sampass;
646 DEBUG(5,("make_server_info_sam: made server info for user %s\n",
647 pdb_get_username((*server_info)->sam_account)));
651 /***************************************************************************
652 Make (and fill) a user_info struct from a 'struct passwd' by conversion
654 ***************************************************************************/
656 BOOL make_server_info_pw(auth_serversupplied_info **server_info, const struct passwd *pwd)
658 SAM_ACCOUNT *sampass = NULL;
659 if (!pdb_init_sam_pw(&sampass, pwd)) {
662 return make_server_info_sam(server_info, sampass);
665 /***************************************************************************
666 Free a user_info struct
667 ***************************************************************************/
669 void free_user_info(auth_usersupplied_info **user_info)
671 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
672 if (*user_info != NULL) {
673 if ((*user_info)->smb_name.str) {
674 DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
676 SAFE_FREE((*user_info)->smb_name.str);
677 SAFE_FREE((*user_info)->internal_username.str);
678 SAFE_FREE((*user_info)->client_domain.str);
679 SAFE_FREE((*user_info)->domain.str);
680 data_blob_free(&(*user_info)->sec_blob);
681 data_blob_free(&(*user_info)->lm_resp);
682 data_blob_free(&(*user_info)->nt_resp);
683 SAFE_FREE((*user_info)->interactive_password);
684 data_blob_clear_free(&(*user_info)->plaintext_password);
685 ZERO_STRUCT(**user_info);
687 SAFE_FREE(*user_info);
690 /***************************************************************************
691 Clear out a server_info struct that has been allocated
692 ***************************************************************************/
694 void free_server_info(auth_serversupplied_info **server_info)
696 if (*server_info != NULL) {
697 pdb_free_sam(&(*server_info)->sam_account);
699 /* call pam_end here, unless we know we are keeping it */
700 delete_nt_token( &(*server_info)->ptok );
701 ZERO_STRUCT(**server_info);
703 SAFE_FREE(*server_info);
706 /***************************************************************************
707 Make a server_info struct for a guest user
708 ***************************************************************************/
710 BOOL make_server_info_guest(auth_serversupplied_info **server_info)
712 struct passwd *pass = sys_getpwnam(lp_guestaccount());
715 if (!make_server_info_pw(server_info, pass)) {
718 (*server_info)->guest = True;
721 DEBUG(0,("make_server_info_guest: sys_getpwnam() failed on guest account!\n"));
725 /****************************************************************************
727 ****************************************************************************/
729 void delete_nt_token(NT_USER_TOKEN **pptoken)
732 NT_USER_TOKEN *ptoken = *pptoken;
733 SAFE_FREE( ptoken->user_sids );
734 ZERO_STRUCTP(ptoken);
739 /****************************************************************************
740 Duplicate a SID token.
741 ****************************************************************************/
743 NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
745 NT_USER_TOKEN *token;
750 if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
755 if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
760 token->num_sids = ptoken->num_sids;
765 /****************************************************************************
766 Check for a guest logon (username = "") and if so create the required
768 ****************************************************************************/
770 NTSTATUS check_guest_security(const auth_usersupplied_info *user_info,
771 auth_serversupplied_info **server_info)
773 NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
775 if (!(user_info->internal_username.str
776 && *user_info->internal_username.str)) {
777 if (make_server_info_guest(server_info)) {
778 nt_status = NT_STATUS_OK;
780 nt_status = NT_STATUS_NO_SUCH_USER;