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 extern fstring remote_machine;
27 extern pstring global_myname;
29 /****************************************************************************
30 Create a UNIX user on demand.
31 ****************************************************************************/
33 static int smb_create_user(const char *unix_user, const char *homedir)
38 pstrcpy(add_script, lp_adduser_script());
41 all_string_sub(add_script, "%u", unix_user, sizeof(pstring));
43 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
44 ret = smbrun(add_script,NULL);
45 DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
49 /****************************************************************************
50 Delete a UNIX user on demand.
51 ****************************************************************************/
53 static int smb_delete_user(char *unix_user)
58 pstrcpy(del_script, lp_deluser_script());
61 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
62 ret = smbrun(del_script,NULL);
63 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
67 /****************************************************************************
68 Add and Delete UNIX users on demand, based on NTSTATUS codes.
69 ****************************************************************************/
71 void smb_user_control(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, NTSTATUS nt_status)
73 struct passwd *pwd=NULL;
75 if (NT_STATUS_IS_OK(nt_status)) {
77 if (!(server_info->sam_fill_level & SAM_FILL_UNIX)) {
80 * User validated ok against Domain controller.
81 * If the admin wants us to try and create a UNIX
82 * user on the fly, do so.
85 if(lp_adduser_script() && !(pwd = Get_Pwnam(user_info->internal_username.str))) {
86 smb_create_user(user_info->internal_username.str, NULL);
89 if(lp_adduser_script()) {
91 const char *home_dir = pdb_get_homedir(server_info->sam_account);
93 * Also call smb_create_user if the users
94 * home directory doesn't exist. Used with
95 * winbindd to allow the script to create
96 * the home directory for a user mapped
101 (sys_stat(home_dir, &st) == -1) && (errno == ENOENT)) {
102 smb_create_user(user_info->internal_username.str, home_dir);
106 } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
108 * User failed to validate ok against Domain controller.
109 * If the failure was "user doesn't exist" and admin
110 * wants us to try and delete that UNIX user on the fly,
113 if (lp_deluser_script()) {
114 smb_delete_user(user_info->internal_username.str);
119 /****************************************************************************
120 Create an auth_usersupplied_data structure
121 ****************************************************************************/
123 static BOOL make_user_info(auth_usersupplied_info **user_info,
124 const char *smb_name,
125 const char *internal_username,
126 const char *client_domain,
128 const char *wksta_name,
129 DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
131 uint32 ntlmssp_flags, BOOL encrypted)
134 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
136 *user_info = malloc(sizeof(**user_info));
138 DEBUG(0,("malloc failed for user_info (size %d)\n", sizeof(*user_info)));
142 ZERO_STRUCTP(*user_info);
144 DEBUG(5,("makeing strings for %s's user_info struct\n", internal_username));
146 (*user_info)->smb_name.str = strdup(smb_name);
147 if ((*user_info)->smb_name.str) {
148 (*user_info)->smb_name.len = strlen(smb_name);
150 free_user_info(user_info);
154 (*user_info)->internal_username.str = strdup(internal_username);
155 if ((*user_info)->internal_username.str) {
156 (*user_info)->internal_username.len = strlen(internal_username);
158 free_user_info(user_info);
162 (*user_info)->domain.str = strdup(domain);
163 if ((*user_info)->domain.str) {
164 (*user_info)->domain.len = strlen(domain);
166 free_user_info(user_info);
170 (*user_info)->client_domain.str = strdup(client_domain);
171 if ((*user_info)->client_domain.str) {
172 (*user_info)->client_domain.len = strlen(client_domain);
174 free_user_info(user_info);
178 (*user_info)->wksta_name.str = strdup(wksta_name);
179 if ((*user_info)->wksta_name.str) {
180 (*user_info)->wksta_name.len = strlen(wksta_name);
182 free_user_info(user_info);
186 DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username));
188 (*user_info)->lm_resp = data_blob(lm_pwd.data, lm_pwd.length);
189 (*user_info)->nt_resp = data_blob(nt_pwd.data, nt_pwd.length);
190 (*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length);
192 (*user_info)->encrypted = encrypted;
193 (*user_info)->ntlmssp_flags = ntlmssp_flags;
195 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
200 /****************************************************************************
201 Create an auth_usersupplied_data structure after appropriate mapping.
202 ****************************************************************************/
204 BOOL make_user_info_map(auth_usersupplied_info **user_info,
205 const char *smb_name,
206 const char *client_domain,
207 const char *wksta_name,
208 DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
210 uint32 ntlmssp_flags, BOOL encrypted)
213 fstring internal_username;
214 fstrcpy(internal_username, smb_name);
215 map_username(internal_username);
217 if (lp_allow_trusted_domains()) {
218 domain = client_domain;
220 domain = lp_workgroup();
223 return make_user_info(user_info,
224 smb_name, internal_username,
225 client_domain, domain,
229 ntlmssp_flags, encrypted);
233 /****************************************************************************
234 Create an auth_usersupplied_data, making the DATA_BLOBs here.
235 Decrypt and encrypt the passwords.
236 ****************************************************************************/
238 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
242 uchar *lm_network_pwd, int lm_pwd_len,
243 uchar *nt_network_pwd, int nt_pwd_len)
246 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
247 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
248 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
249 uint32 ntlmssp_flags = 0;
252 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
253 if (nt_pwd_len == 24) {
254 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
255 } else if (nt_pwd_len != 0) {
256 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
259 ret = make_user_info_map(user_info,
260 smb_name, client_domain,
264 ntlmssp_flags, True);
266 data_blob_free(&lm_blob);
267 data_blob_free(&nt_blob);
271 /****************************************************************************
272 Create an auth_usersupplied_data, making the DATA_BLOBs here.
273 Decrypt and encrypt the passwords.
274 ****************************************************************************/
276 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
281 uchar lm_interactive_pwd[16],
282 uchar nt_interactive_pwd[16],
287 unsigned char local_lm_response[24];
288 unsigned char local_nt_response[24];
289 unsigned char key[16];
290 uint32 ntlmssp_flags = 0;
293 memcpy(key, dc_sess_key, 8);
295 if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
296 if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
298 #ifdef DEBUG_PASSWORD
300 dump_data(100, (char *)key, sizeof(key));
302 DEBUG(100,("lm owf password:"));
303 dump_data(100, lm_pwd, sizeof(lm_pwd));
305 DEBUG(100,("nt owf password:"));
306 dump_data(100, nt_pwd, sizeof(nt_pwd));
309 SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
310 SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
312 #ifdef DEBUG_PASSWORD
313 DEBUG(100,("decrypt of lm owf password:"));
314 dump_data(100, lm_pwd, sizeof(lm_pwd));
316 DEBUG(100,("decrypt of nt owf password:"));
317 dump_data(100, nt_pwd, sizeof(nt_pwd));
320 SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
321 SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
323 /* Password info parinoia */
330 DATA_BLOB local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
331 DATA_BLOB local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
332 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
334 if (lm_interactive_pwd)
335 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
336 if (nt_interactive_pwd)
337 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
339 ret = make_user_info_map(user_info,
340 smb_name, client_domain,
345 ntlmssp_flags, True);
347 data_blob_free(&local_lm_blob);
348 data_blob_free(&local_nt_blob);
353 /****************************************************************************
354 Create an auth_usersupplied_data structure
355 ****************************************************************************/
357 BOOL make_user_info_winbind(auth_usersupplied_info **user_info,
358 const char *username,
360 const char *password,
361 char chal[8] /* Give winbind back the challenge we used */
364 unsigned char local_lm_response[24];
365 unsigned char local_nt_response[24];
366 DATA_BLOB local_lm_blob;
367 DATA_BLOB local_nt_blob;
368 DATA_BLOB plaintext_blob;
369 uint32 ntlmssp_flags = 0;
372 * Not encrypted - do so.
375 DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
377 generate_random_buffer(chal, 8, False);
380 SMBencrypt( (const uchar *)password, chal, local_lm_response);
382 /* This encrypts the lm_pwd field, which actually contains
383 the password rather than the nt_pwd field because that
386 /* WATCH OUT. This doesn't work if the incoming password is
387 incorrectly cased. We might want to add a check here
388 and only do an LM in that case */
390 SMBNTencrypt((const uchar *)password, chal, local_nt_response);
392 local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
393 local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
394 plaintext_blob = data_blob(password, strlen(password)+1);
395 if ((!local_lm_blob.data) || (!local_nt_blob.data)|| (!plaintext_blob.data)) {
396 data_blob_free(&local_lm_blob);
397 data_blob_free(&local_nt_blob);
398 data_blob_clear_free(&plaintext_blob);
401 ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM;
403 local_lm_blob = data_blob(NULL, 0);
404 local_nt_blob = data_blob(NULL, 0);
405 plaintext_blob = data_blob(NULL, 0);
411 ret = make_user_info(user_info,
418 ntlmssp_flags, False);
420 data_blob_free(&local_lm_blob);
421 data_blob_free(&local_nt_blob);
422 data_blob_clear_free(&plaintext_blob);
427 /****************************************************************************
428 Create an auth_usersupplied_data, making the DATA_BLOBs here.
429 Decrypt and encrypt the passwords.
430 ****************************************************************************/
432 BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info,
435 uchar *lm_network_pwd, int lm_pwd_len,
436 uchar *nt_network_pwd, int nt_pwd_len)
439 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
440 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
441 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
442 uint32 ntlmssp_flags = 0;
445 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
447 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
449 ret = make_user_info(user_info,
451 client_domain, client_domain,
455 ntlmssp_flags, True);
457 data_blob_free(&lm_blob);
458 data_blob_free(&nt_blob);
462 /****************************************************************************
463 Create an auth_usersupplied_data structure
464 ****************************************************************************/
466 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
470 DATA_BLOB plaintext_password)
473 DATA_BLOB local_lm_blob;
474 DATA_BLOB local_nt_blob;
476 uint32 ntlmssp_flags = 0;
479 * Not encrypted - do so.
482 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
484 if (plaintext_password.data) {
485 unsigned char local_lm_response[24];
487 #ifdef DEBUG_PASSWORD
488 DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
489 dump_data(100, plaintext_password.data, plaintext_password.length);
492 SMBencrypt( (const uchar *)plaintext_password.data, chal, local_lm_response);
493 local_lm_blob = data_blob(local_lm_response, 24);
495 /* We can't do an NT hash here, as the password needs to be
497 local_nt_blob = data_blob(NULL, 0);
499 ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM;
501 local_lm_blob = data_blob(NULL, 0);
502 local_nt_blob = data_blob(NULL, 0);
505 ret = make_user_info_map(user_info, smb_name,
511 ntlmssp_flags, False);
513 data_blob_free(&local_lm_blob);
517 /****************************************************************************
518 Create an auth_usersupplied_data structure
519 ****************************************************************************/
521 BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
524 DATA_BLOB lm_resp, DATA_BLOB nt_resp,
525 DATA_BLOB plaintext_password)
527 uint32 ntlmssp_flags = 0;
529 DATA_BLOB no_plaintext_blob = data_blob(NULL, 0);
531 if (lm_resp.length == 24) {
532 ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
534 if (nt_resp.length == 0) {
535 } else if (nt_resp.length == 24) {
536 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
538 ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
541 return make_user_info_map(user_info, smb_name,
547 ntlmssp_flags, True);
550 /****************************************************************************
551 Create a guest user_info blob, for anonymous authenticaion.
552 ****************************************************************************/
554 BOOL make_user_info_guest(auth_usersupplied_info **user_info)
556 DATA_BLOB lm_blob = data_blob(NULL, 0);
557 DATA_BLOB nt_blob = data_blob(NULL, 0);
558 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
559 uint32 ntlmssp_flags = 0;
561 return make_user_info(user_info,
567 ntlmssp_flags, True);
570 /***************************************************************************
571 Make a user_info struct
572 ***************************************************************************/
574 BOOL make_server_info(auth_serversupplied_info **server_info)
576 *server_info = malloc(sizeof(**server_info));
578 DEBUG(0,("make_server_info: malloc failed!\n"));
581 ZERO_STRUCTP(*server_info);
585 /***************************************************************************
586 Make (and fill) a user_info struct from a SAM_ACCOUNT
587 ***************************************************************************/
589 BOOL make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass)
591 if (!make_server_info(server_info)) {
595 (*server_info)->sam_fill_level = SAM_FILL_ALL;
596 (*server_info)->sam_account = sampass;
598 DEBUG(5,("make_server_info_sam: made server info for user %s\n",
599 pdb_get_username((*server_info)->sam_account)));
603 /***************************************************************************
604 Make (and fill) a user_info struct from a 'struct passwd' by conversion
606 ***************************************************************************/
608 BOOL make_server_info_pw(auth_serversupplied_info **server_info, const struct passwd *pwd)
610 SAM_ACCOUNT *sampass = NULL;
611 if (!pdb_init_sam_pw(&sampass, pwd)) {
614 return make_server_info_sam(server_info, sampass);
617 /***************************************************************************
618 Free a user_info struct
619 ***************************************************************************/
621 void free_user_info(auth_usersupplied_info **user_info)
623 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
624 if (*user_info != NULL) {
625 if ((*user_info)->smb_name.str) {
626 DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
628 SAFE_FREE((*user_info)->smb_name.str);
629 SAFE_FREE((*user_info)->internal_username.str);
630 SAFE_FREE((*user_info)->client_domain.str);
631 SAFE_FREE((*user_info)->domain.str);
632 data_blob_free(&(*user_info)->lm_resp);
633 data_blob_free(&(*user_info)->nt_resp);
634 SAFE_FREE((*user_info)->interactive_password);
635 data_blob_clear_free(&(*user_info)->plaintext_password);
636 ZERO_STRUCT(**user_info);
638 SAFE_FREE(*user_info);
641 /***************************************************************************
642 Clear out a server_info struct that has been allocated
643 ***************************************************************************/
645 void free_server_info(auth_serversupplied_info **server_info)
647 if (*server_info != NULL) {
648 pdb_free_sam(&(*server_info)->sam_account);
650 /* call pam_end here, unless we know we are keeping it */
651 delete_nt_token( &(*server_info)->ptok );
652 ZERO_STRUCT(**server_info);
654 SAFE_FREE(*server_info);
657 /***************************************************************************
658 Make a server_info struct for a guest user
659 ***************************************************************************/
661 BOOL make_server_info_guest(auth_serversupplied_info **server_info)
663 struct passwd *pass = sys_getpwnam(lp_guestaccount());
666 if (!make_server_info_pw(server_info, pass)) {
669 (*server_info)->guest = True;
672 DEBUG(0,("make_server_info_guest: sys_getpwnam() failed on guest account!\n"));
676 /***************************************************************************
677 Make an auth_methods struct
678 ***************************************************************************/
680 BOOL make_auth_methods(auth_methods **auth_method)
682 *auth_method = malloc(sizeof(**auth_method));
684 DEBUG(0,("make_auth_method: malloc failed!\n"));
687 ZERO_STRUCTP(*auth_method);
692 /****************************************************************************
694 ****************************************************************************/
696 void delete_nt_token(NT_USER_TOKEN **pptoken)
699 NT_USER_TOKEN *ptoken = *pptoken;
700 SAFE_FREE( ptoken->user_sids );
701 ZERO_STRUCTP(ptoken);
706 /****************************************************************************
707 Duplicate a SID token.
708 ****************************************************************************/
710 NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
712 NT_USER_TOKEN *token;
717 if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
722 if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
727 token->num_sids = ptoken->num_sids;