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 BOOL make_user_info(auth_usersupplied_info **user_info,
162 char *smb_name, char *internal_username,
163 char *client_domain, char *domain,
164 char *wksta_name, DATA_BLOB sec_blob,
165 DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
167 uint32 ntlmssp_flags, BOOL encrypted)
170 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
172 *user_info = malloc(sizeof(**user_info));
174 DEBUG(0,("malloc failed for user_info (size %d)\n", sizeof(*user_info)));
178 ZERO_STRUCTP(*user_info);
180 DEBUG(5,("makeing strings for %s's user_info struct\n", internal_username));
182 (*user_info)->smb_name.str = strdup(smb_name);
183 if ((*user_info)->smb_name.str) {
184 (*user_info)->smb_name.len = strlen(smb_name);
186 free_user_info(user_info);
190 (*user_info)->internal_username.str = strdup(internal_username);
191 if ((*user_info)->internal_username.str) {
192 (*user_info)->internal_username.len = strlen(internal_username);
194 free_user_info(user_info);
198 (*user_info)->domain.str = strdup(domain);
199 if ((*user_info)->domain.str) {
200 (*user_info)->domain.len = strlen(domain);
202 free_user_info(user_info);
206 (*user_info)->client_domain.str = strdup(client_domain);
207 if ((*user_info)->client_domain.str) {
208 (*user_info)->client_domain.len = strlen(client_domain);
210 free_user_info(user_info);
214 (*user_info)->wksta_name.str = strdup(wksta_name);
215 if ((*user_info)->wksta_name.str) {
216 (*user_info)->wksta_name.len = strlen(wksta_name);
218 free_user_info(user_info);
222 DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username));
224 (*user_info)->sec_blob = data_blob(sec_blob.data, sec_blob.length);
225 (*user_info)->lm_resp = data_blob(lm_pwd.data, lm_pwd.length);
226 (*user_info)->nt_resp = data_blob(nt_pwd.data, nt_pwd.length);
227 (*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length);
229 (*user_info)->encrypted = encrypted;
230 (*user_info)->ntlmssp_flags = ntlmssp_flags;
232 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
237 /****************************************************************************
238 Create an auth_usersupplied_data structure after appropriate mapping.
239 ****************************************************************************/
241 BOOL make_user_info_map(auth_usersupplied_info **user_info,
244 char *wksta_name, DATA_BLOB sec_blob,
245 DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
247 uint32 ntlmssp_flags, BOOL encrypted)
250 fstring internal_username;
251 fstrcpy(internal_username, smb_name);
252 map_username(internal_username);
254 if (lp_allow_trusted_domains()) {
255 domain = client_domain;
257 domain = lp_workgroup();
260 return make_user_info(user_info,
261 smb_name, internal_username,
262 client_domain, domain,
263 wksta_name, sec_blob,
266 ntlmssp_flags, encrypted);
270 /****************************************************************************
271 Create an auth_usersupplied_data, making the DATA_BLOBs here.
272 Decrupt and encrypt the passwords.
273 ****************************************************************************/
275 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
278 char *wksta_name, uchar chal[8],
279 uchar *lm_network_pwd, int lm_pwd_len,
280 uchar *nt_network_pwd, int nt_pwd_len)
283 DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
284 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
285 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
286 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
287 uint32 ntlmssp_flags = 0;
290 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
291 if (nt_pwd_len == 24) {
292 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
293 } else if (nt_pwd_len != 0) {
294 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
297 ret = make_user_info_map(user_info,
298 smb_name, client_domain,
299 wksta_name, sec_blob,
302 ntlmssp_flags, True);
304 data_blob_free(&lm_blob);
305 data_blob_free(&nt_blob);
309 /****************************************************************************
310 Create an auth_usersupplied_data, making the DATA_BLOBs here.
311 Decrupt and encrypt the passwords.
312 ****************************************************************************/
314 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
318 uchar lm_interactive_pwd[16],
319 uchar nt_interactive_pwd[16],
324 unsigned char local_lm_response[24];
325 unsigned char local_nt_response[24];
326 unsigned char key[16];
328 uint32 ntlmssp_flags = 0;
330 generate_random_buffer(chal, 8, False);
333 memcpy(key, dc_sess_key, 8);
335 if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
336 if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
338 #ifdef DEBUG_PASSWORD
340 dump_data(100, (char *)key, sizeof(key));
342 DEBUG(100,("lm owf password:"));
343 dump_data(100, lm_pwd, sizeof(lm_pwd));
345 DEBUG(100,("nt owf password:"));
346 dump_data(100, nt_pwd, sizeof(nt_pwd));
349 SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
350 SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
352 #ifdef DEBUG_PASSWORD
353 DEBUG(100,("decrypt of lm owf password:"));
354 dump_data(100, lm_pwd, sizeof(lm_pwd));
356 DEBUG(100,("decrypt of nt owf password:"));
357 dump_data(100, nt_pwd, sizeof(nt_pwd));
360 generate_random_buffer(chal, 8, False);
361 SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
362 SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
364 /* Password info parinoia */
371 DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
372 DATA_BLOB local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
373 DATA_BLOB local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
374 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
376 if (lm_interactive_pwd)
377 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
378 if (nt_interactive_pwd)
379 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
381 ret = make_user_info_map(user_info,
382 smb_name, client_domain,
383 wksta_name, sec_blob,
387 ntlmssp_flags, True);
389 data_blob_free(&local_lm_blob);
390 data_blob_free(&local_nt_blob);
395 /****************************************************************************
396 Create an auth_usersupplied_data structure
397 ****************************************************************************/
399 BOOL make_user_info_winbind(auth_usersupplied_info **user_info,
404 unsigned char local_lm_response[24];
405 unsigned char local_nt_response[24];
407 DATA_BLOB local_lm_blob;
408 DATA_BLOB local_nt_blob;
409 DATA_BLOB plaintext_blob;
410 uint32 ntlmssp_flags = 0;
413 * Not encrypted - do so.
416 DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
418 generate_random_buffer(chal, 8, False);
421 SMBencrypt( (uchar *)password, chal, local_lm_response);
423 /* This encrypts the lm_pwd feild, which actualy contains the password
424 rather than the nt_pwd field becouse that contains nothing */
426 /* WATCH OUT. This doesn't work if the incoming password is incorrectly cased.
427 We might want to add a check here and only do an LM in that case */
429 SMBNTencrypt((uchar *)password, chal, local_nt_response);
431 local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
432 local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
433 plaintext_blob = data_blob(password, strlen(password)+1);
434 if ((!local_lm_blob.data) || (!local_nt_blob.data)|| (!plaintext_blob.data)) {
435 data_blob_free(&local_lm_blob);
436 data_blob_free(&local_nt_blob);
437 data_blob_clear_free(&plaintext_blob);
440 ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM;
442 local_lm_blob = data_blob(NULL, 0);
443 local_nt_blob = data_blob(NULL, 0);
444 plaintext_blob = data_blob(NULL, 0);
449 DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
451 if (!sec_blob.data) {
455 ret = make_user_info(user_info,
458 global_myname, sec_blob,
462 ntlmssp_flags, False);
464 data_blob_free(&local_lm_blob);
465 data_blob_free(&local_nt_blob);
466 data_blob_clear_free(&plaintext_blob);
471 /****************************************************************************
472 Create an auth_usersupplied_data, making the DATA_BLOBs here.
473 Decrupt and encrypt the passwords.
474 ****************************************************************************/
476 BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info,
480 uchar *lm_network_pwd, int lm_pwd_len,
481 uchar *nt_network_pwd, int nt_pwd_len)
484 DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
485 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
486 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
487 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
488 uint32 ntlmssp_flags = 0;
491 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
493 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
495 ret = make_user_info(user_info,
497 client_domain, client_domain,
498 global_myname, sec_blob,
501 ntlmssp_flags, True);
503 data_blob_free(&lm_blob);
504 data_blob_free(&nt_blob);
508 /****************************************************************************
509 Create an auth_usersupplied_data structure
510 ****************************************************************************/
512 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
515 DATA_BLOB lm_resp, DATA_BLOB nt_resp,
516 DATA_BLOB plaintext_password,
521 DATA_BLOB local_lm_blob;
522 DATA_BLOB local_nt_blob;
525 uint32 ntlmssp_flags = 0;
528 DATA_BLOB no_plaintext_blob = data_blob(NULL, 0);
529 if (!last_challenge(chal)) {
530 DEBUG(0,("Encrypted login but no challange set!\n"));
533 sec_blob = data_blob(chal, 8);
535 if (lm_resp.length == 24) {
536 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
538 if (nt_resp.length == 0) {
539 } else if (nt_resp.length == 24) {
540 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
542 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
545 return make_user_info_map(user_info, smb_name,
547 remote_machine, sec_blob,
551 ntlmssp_flags, encrypted);
554 generate_random_buffer(chal, 8, False);
556 sec_blob = data_blob(chal, 8);
559 * Not encrypted - do so.
562 DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
564 if (plaintext_password.data) {
565 unsigned char local_lm_response[24];
567 SMBencrypt( (uchar *)plaintext_password.data, chal, local_lm_response);
568 local_lm_blob = data_blob(local_lm_response, 24);
570 /* We can't do an NT hash here, as the password needs to be case insensitive */
571 local_nt_blob = data_blob(NULL, 0);
573 ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM;
575 local_lm_blob = data_blob(NULL, 0);
576 local_nt_blob = data_blob(NULL, 0);
579 ret = make_user_info_map(user_info, smb_name,
586 ntlmssp_flags, encrypted);
588 data_blob_free(&local_lm_blob);
592 /****************************************************************************
593 Create a guest user_info blob, for anonymous authenticaion.
594 ****************************************************************************/
596 BOOL make_user_info_guest(auth_usersupplied_info **user_info)
598 DATA_BLOB sec_blob = data_blob(NULL, 0);
599 DATA_BLOB lm_blob = data_blob(NULL, 0);
600 DATA_BLOB nt_blob = data_blob(NULL, 0);
601 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
602 uint32 ntlmssp_flags = 0;
604 return make_user_info(user_info,
610 ntlmssp_flags, True);
613 BOOL make_server_info(auth_serversupplied_info **server_info)
615 *server_info = malloc(sizeof(**server_info));
617 DEBUG(0,("make_server_info_sam: malloc failed!\n"));
620 ZERO_STRUCTP(*server_info);
624 BOOL make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass)
626 if (!make_server_info(server_info)) {
630 (*server_info)->sam_fill_level = SAM_FILL_ALL;
631 (*server_info)->sam_account = sampass;
633 DEBUG(5,("make_server_info_sam: made sever info for user %s\n",
634 pdb_get_username((*server_info)->sam_account)));
638 BOOL make_server_info_pw(auth_serversupplied_info **server_info, struct passwd *pwd)
640 SAM_ACCOUNT *sampass = NULL;
641 if (!pdb_init_sam_pw(&sampass, pwd)) {
644 return make_server_info_sam(server_info, sampass);
647 void free_user_info(auth_usersupplied_info **user_info)
649 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
650 if (*user_info != NULL) {
651 if ((*user_info)->smb_name.str) {
652 DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
654 SAFE_FREE((*user_info)->smb_name.str);
655 SAFE_FREE((*user_info)->internal_username.str);
656 SAFE_FREE((*user_info)->client_domain.str);
657 SAFE_FREE((*user_info)->domain.str);
658 data_blob_free(&(*user_info)->sec_blob);
659 data_blob_free(&(*user_info)->lm_resp);
660 data_blob_free(&(*user_info)->nt_resp);
661 SAFE_FREE((*user_info)->interactive_password);
662 data_blob_clear_free(&(*user_info)->plaintext_password);
663 ZERO_STRUCT(**user_info);
665 SAFE_FREE(*user_info);
668 /***************************************************************************
669 Clear out a server_info struct that has been allocated
670 ***************************************************************************/
672 void free_server_info(auth_serversupplied_info **server_info)
674 if (*server_info != NULL) {
675 pdb_free_sam(&(*server_info)->sam_account);
677 /* call pam_end here, unless we know we are keeping it */
678 delete_nt_token( &(*server_info)->ptok );
679 ZERO_STRUCT(**server_info);
681 SAFE_FREE(*server_info);
684 /***************************************************************************
685 Make a server_info struct for a guest user
686 ***************************************************************************/
688 BOOL make_server_info_guest(auth_serversupplied_info **server_info)
690 struct passwd *pass = sys_getpwnam(lp_guestaccount(-1));
693 if (!make_server_info_pw(server_info, pass)) {
696 (*server_info)->guest = True;
699 DEBUG(0,("make_server_info_guest: sys_getpwnam() failed on guest account!\n"));
703 /****************************************************************************
705 ****************************************************************************/
707 void delete_nt_token(NT_USER_TOKEN **pptoken)
710 NT_USER_TOKEN *ptoken = *pptoken;
711 SAFE_FREE( ptoken->user_sids );
712 ZERO_STRUCTP(ptoken);
717 /****************************************************************************
718 Duplicate a SID token.
719 ****************************************************************************/
721 NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
723 NT_USER_TOKEN *token;
728 if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
733 if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
738 token->num_sids = ptoken->num_sids;
743 /****************************************************************************
744 Check for a guest logon (username = "") and if so create the required
746 ****************************************************************************/
748 NTSTATUS check_guest_security(const auth_usersupplied_info *user_info,
749 auth_serversupplied_info **server_info)
751 NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
753 if (!(user_info->internal_username.str
754 && *user_info->internal_username.str)) {
755 if (make_server_info_guest(server_info)) {
756 nt_status = NT_STATUS_OK;
758 nt_status = NT_STATUS_NO_SUCH_USER;