Removed version number from file header.
[samba.git] / source3 / auth / auth_util.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Authentication utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Andrew Bartlett 2001
6    Copyright (C) Jeremy Allison 2000-2001
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 extern fstring remote_machine;
26 extern pstring global_myname;
27
28 /****************************************************************************
29  Create a UNIX user on demand.
30 ****************************************************************************/
31
32 static int smb_create_user(const char *unix_user, const char *homedir)
33 {
34         pstring add_script;
35         int ret;
36
37         pstrcpy(add_script, lp_adduser_script());
38         if (! *add_script)
39                 return -1;
40         all_string_sub(add_script, "%u", unix_user, sizeof(pstring));
41         if (homedir)
42                 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
43         ret = smbrun(add_script,NULL);
44         DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
45         return ret;
46 }
47
48 /****************************************************************************
49  Delete a UNIX user on demand.
50 ****************************************************************************/
51
52 int smb_delete_user(const char *unix_user)
53 {
54         pstring del_script;
55         int ret;
56
57         pstrcpy(del_script, lp_deluser_script());
58         if (! *del_script)
59                 return -1;
60         all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
61         ret = smbrun(del_script,NULL);
62         DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
63         return ret;
64 }
65
66 /****************************************************************************
67  Add and Delete UNIX users on demand, based on NTSTATUS codes.
68 ****************************************************************************/
69
70 void smb_user_control(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, NTSTATUS nt_status) 
71 {
72         struct passwd *pwd=NULL;
73
74         if (NT_STATUS_IS_OK(nt_status)) {
75
76                 if (!(server_info->sam_fill_level & SAM_FILL_UNIX)) {
77                         
78                         /*
79                          * User validated ok against Domain controller.
80                          * If the admin wants us to try and create a UNIX
81                          * user on the fly, do so.
82                          */
83                         
84                         if(lp_adduser_script() && !(pwd = Get_Pwnam(user_info->internal_username.str))) {
85                                 smb_create_user(user_info->internal_username.str, NULL);
86                         }
87                 }
88         } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
89                 /*
90                  * User failed to validate ok against Domain controller.
91                  * If the failure was "user doesn't exist" and admin 
92                  * wants us to try and delete that UNIX user on the fly,
93                  * do so.
94                  */
95                 if (lp_deluser_script()) {
96                         smb_delete_user(user_info->internal_username.str);
97                 }
98         }
99 }
100
101 /****************************************************************************
102  Create an auth_usersupplied_data structure
103 ****************************************************************************/
104
105 static BOOL make_user_info(auth_usersupplied_info **user_info, 
106                            const char *smb_name, 
107                            const char *internal_username,
108                            const char *client_domain, 
109                            const char *domain,
110                            const char *wksta_name, 
111                            DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
112                            DATA_BLOB plaintext, 
113                            uint32 auth_flags, BOOL encrypted)
114 {
115
116         DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
117
118         *user_info = malloc(sizeof(**user_info));
119         if (!user_info) {
120                 DEBUG(0,("malloc failed for user_info (size %d)\n", sizeof(*user_info)));
121                 return False;
122         }
123
124         ZERO_STRUCTP(*user_info);
125
126         DEBUG(5,("makeing strings for %s's user_info struct\n", internal_username));
127
128         (*user_info)->smb_name.str = strdup(smb_name);
129         if ((*user_info)->smb_name.str) { 
130                 (*user_info)->smb_name.len = strlen(smb_name);
131         } else {
132                 free_user_info(user_info);
133                 return False;
134         }
135         
136         (*user_info)->internal_username.str = strdup(internal_username);
137         if ((*user_info)->internal_username.str) { 
138                 (*user_info)->internal_username.len = strlen(internal_username);
139         } else {
140                 free_user_info(user_info);
141                 return False;
142         }
143
144         (*user_info)->domain.str = strdup(domain);
145         if ((*user_info)->domain.str) { 
146                 (*user_info)->domain.len = strlen(domain);
147         } else {
148                 free_user_info(user_info);
149                 return False;
150         }
151
152         (*user_info)->client_domain.str = strdup(client_domain);
153         if ((*user_info)->client_domain.str) { 
154                 (*user_info)->client_domain.len = strlen(client_domain);
155         } else {
156                 free_user_info(user_info);
157                 return False;
158         }
159
160         (*user_info)->wksta_name.str = strdup(wksta_name);
161         if ((*user_info)->wksta_name.str) { 
162                 (*user_info)->wksta_name.len = strlen(wksta_name);
163         } else {
164                 free_user_info(user_info);
165                 return False;
166         }
167
168         DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username));
169
170         (*user_info)->lm_resp = data_blob(lm_pwd.data, lm_pwd.length);
171         (*user_info)->nt_resp = data_blob(nt_pwd.data, nt_pwd.length);
172         (*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length);
173
174         (*user_info)->encrypted = encrypted;
175         (*user_info)->auth_flags = auth_flags;
176
177         DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
178
179         return True;
180 }
181
182 /****************************************************************************
183  Create an auth_usersupplied_data structure after appropriate mapping.
184 ****************************************************************************/
185
186 BOOL make_user_info_map(auth_usersupplied_info **user_info, 
187                         const char *smb_name, 
188                         const char *client_domain, 
189                         const char *wksta_name, 
190                         DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
191                         DATA_BLOB plaintext, 
192                         uint32 ntlmssp_flags, BOOL encrypted)
193 {
194         const char *domain;
195         fstring internal_username;
196         fstrcpy(internal_username, smb_name);
197         map_username(internal_username); 
198         
199         if (lp_allow_trusted_domains()) {
200                 /* the client could have given us a workstation name
201                    or other crap for the workgroup - we really need a
202                    way of telling if this domain name is one of our
203                    trusted domain names 
204
205                    The way I do it here is by checking if the fully
206                    qualified username exists. This is rather reliant
207                    on winbind, but until we have a better method this
208                    will have to do 
209                 */
210
211                 domain = client_domain;
212
213                 if ((smb_name) && (*smb_name)) { /* Don't do this for guests */
214                         char *user;
215                         asprintf(&user, "%s%s%s", 
216                                  client_domain, lp_winbind_separator(), 
217                                  smb_name);
218                         if (Get_Pwnam(user) == NULL) {
219                                 domain = lp_workgroup();
220                         }
221                         free(user);
222                 }
223         } else {
224                 domain = lp_workgroup();
225         }
226         
227         return make_user_info(user_info, 
228                               smb_name, internal_username,
229                               client_domain, domain,
230                               wksta_name, 
231                               lm_pwd, nt_pwd,
232                               plaintext, 
233                               ntlmssp_flags, encrypted);
234         
235 }
236
237 /****************************************************************************
238  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
239  Decrypt and encrypt the passwords.
240 ****************************************************************************/
241
242 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
243                                      const char *smb_name, 
244                                      const char *client_domain, 
245                                      const char *wksta_name, 
246                                      const uchar *lm_network_pwd, int lm_pwd_len,
247                                      const uchar *nt_network_pwd, int nt_pwd_len)
248 {
249         BOOL ret;
250         DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
251         DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
252         DATA_BLOB plaintext_blob = data_blob(NULL, 0);
253         uint32 auth_flags = AUTH_FLAG_NONE;
254
255         if (lm_pwd_len)
256                 auth_flags |= AUTH_FLAG_LM_RESP;
257         if (nt_pwd_len == 24) {
258                 auth_flags |= AUTH_FLAG_NTLM_RESP; 
259         } else if (nt_pwd_len != 0) {
260                 auth_flags |= AUTH_FLAG_NTLMv2_RESP; 
261         }
262
263         ret = make_user_info_map(user_info, 
264                                  smb_name, client_domain, 
265                                  wksta_name, 
266                                  lm_blob, nt_blob,
267                                  plaintext_blob, 
268                                  auth_flags, True);
269                 
270         data_blob_free(&lm_blob);
271         data_blob_free(&nt_blob);
272         return ret;
273 }
274
275 /****************************************************************************
276  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
277  Decrypt and encrypt the passwords.
278 ****************************************************************************/
279
280 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
281                                          const char *smb_name, 
282                                          const char *client_domain, 
283                                          const char *wksta_name, 
284                                          const uchar chal[8], 
285                                          const uchar lm_interactive_pwd[16], 
286                                          const uchar nt_interactive_pwd[16], 
287                                          const uchar *dc_sess_key)
288 {
289         char lm_pwd[16];
290         char nt_pwd[16];
291         unsigned char local_lm_response[24];
292         unsigned char local_nt_response[24];
293         unsigned char key[16];
294         uint32 auth_flags = AUTH_FLAG_NONE;
295         
296         ZERO_STRUCT(key);
297         memcpy(key, dc_sess_key, 8);
298         
299         if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
300         if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
301         
302 #ifdef DEBUG_PASSWORD
303         DEBUG(100,("key:"));
304         dump_data(100, (char *)key, sizeof(key));
305         
306         DEBUG(100,("lm owf password:"));
307         dump_data(100, lm_pwd, sizeof(lm_pwd));
308         
309         DEBUG(100,("nt owf password:"));
310         dump_data(100, nt_pwd, sizeof(nt_pwd));
311 #endif
312         
313         SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
314         SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
315         
316 #ifdef DEBUG_PASSWORD
317         DEBUG(100,("decrypt of lm owf password:"));
318         dump_data(100, lm_pwd, sizeof(lm_pwd));
319         
320         DEBUG(100,("decrypt of nt owf password:"));
321         dump_data(100, nt_pwd, sizeof(nt_pwd));
322 #endif
323         
324         SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
325         SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
326         
327         /* Password info parinoia */
328         ZERO_STRUCT(lm_pwd);
329         ZERO_STRUCT(nt_pwd);
330         ZERO_STRUCT(key);
331
332         {
333                 BOOL ret;
334                 DATA_BLOB local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
335                 DATA_BLOB local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
336                 DATA_BLOB plaintext_blob = data_blob(NULL, 0);
337
338                 if (lm_interactive_pwd)
339                         auth_flags |= AUTH_FLAG_LM_RESP;
340                 if (nt_interactive_pwd)
341                         auth_flags |= AUTH_FLAG_NTLM_RESP; 
342
343                 ret = make_user_info_map(user_info, 
344                                          smb_name, client_domain, 
345                                          wksta_name, 
346                                          local_lm_blob,
347                                          local_nt_blob,
348                                          plaintext_blob, 
349                                          auth_flags, True);
350                 
351                 data_blob_free(&local_lm_blob);
352                 data_blob_free(&local_nt_blob);
353                 return ret;
354         }
355 }
356
357
358 /****************************************************************************
359  Create an auth_usersupplied_data structure
360 ****************************************************************************/
361
362 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
363                               const char *smb_name, 
364                               const char *client_domain,
365                               const uint8 chal[8],
366                               DATA_BLOB plaintext_password)
367 {
368
369         DATA_BLOB local_lm_blob;
370         DATA_BLOB local_nt_blob;
371         BOOL ret = False;
372         uint32 auth_flags = AUTH_FLAG_NONE;
373                         
374         /*
375          * Not encrypted - do so.
376          */
377         
378         DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
379         
380         if (plaintext_password.data) {
381                 unsigned char local_lm_response[24];
382                 
383 #ifdef DEBUG_PASSWORD
384                 DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
385                 dump_data(100, plaintext_password.data, plaintext_password.length);
386 #endif
387
388                 SMBencrypt( (const uchar *)plaintext_password.data, (const uchar*)chal, local_lm_response);
389                 local_lm_blob = data_blob(local_lm_response, 24);
390                 
391                 /* We can't do an NT hash here, as the password needs to be
392                    case insensitive */
393                 local_nt_blob = data_blob(NULL, 0); 
394                 
395                 auth_flags = (AUTH_FLAG_PLAINTEXT | AUTH_FLAG_LM_RESP);
396         } else {
397                 local_lm_blob = data_blob(NULL, 0); 
398                 local_nt_blob = data_blob(NULL, 0); 
399         }
400         
401         ret = make_user_info_map(user_info, smb_name,
402                                  client_domain, 
403                                  remote_machine,
404                                  local_lm_blob,
405                                  local_nt_blob,
406                                  plaintext_password, 
407                                  auth_flags, False);
408         
409         data_blob_free(&local_lm_blob);
410         return ret;
411 }
412
413 /****************************************************************************
414  Create an auth_usersupplied_data structure
415 ****************************************************************************/
416
417 BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
418                                   const char *smb_name,
419                                   const char *client_domain, 
420                                   DATA_BLOB lm_resp, DATA_BLOB nt_resp)
421 {
422         uint32 auth_flags = AUTH_FLAG_NONE;
423
424         DATA_BLOB no_plaintext_blob = data_blob(NULL, 0); 
425         
426         if (lm_resp.length == 24) {
427                 auth_flags |= AUTH_FLAG_LM_RESP;
428         }
429         if (nt_resp.length == 0) {
430         } else if (nt_resp.length == 24) {
431                 auth_flags |= AUTH_FLAG_NTLM_RESP;
432         } else {
433                 auth_flags |= AUTH_FLAG_NTLMv2_RESP;
434         }
435
436         return make_user_info_map(user_info, smb_name, 
437                                  client_domain, 
438                                  remote_machine, 
439                                  lm_resp, 
440                                  nt_resp, 
441                                  no_plaintext_blob, 
442                                  auth_flags, True);
443 }
444
445 /****************************************************************************
446  Create a guest user_info blob, for anonymous authenticaion.
447 ****************************************************************************/
448
449 BOOL make_user_info_guest(auth_usersupplied_info **user_info) 
450 {
451         DATA_BLOB lm_blob = data_blob(NULL, 0);
452         DATA_BLOB nt_blob = data_blob(NULL, 0);
453         DATA_BLOB plaintext_blob = data_blob(NULL, 0);
454         uint32 auth_flags = AUTH_FLAG_NONE;
455
456         return make_user_info(user_info, 
457                               "","", 
458                               "","", 
459                               "", 
460                               nt_blob, lm_blob,
461                               plaintext_blob, 
462                               auth_flags, True);
463 }
464
465 /***************************************************************************
466  Make a user_info struct
467 ***************************************************************************/
468
469 BOOL make_server_info(auth_serversupplied_info **server_info) 
470 {
471         *server_info = malloc(sizeof(**server_info));
472         if (!*server_info) {
473                 DEBUG(0,("make_server_info: malloc failed!\n"));
474                 return False;
475         }
476         ZERO_STRUCTP(*server_info);
477         return True;
478 }
479
480 /***************************************************************************
481  Make (and fill) a user_info struct from a SAM_ACCOUNT
482 ***************************************************************************/
483
484 BOOL make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass) 
485 {
486         if (!make_server_info(server_info)) {
487                 return False;
488         }
489
490         (*server_info)->sam_fill_level = SAM_FILL_ALL;
491         (*server_info)->sam_account = sampass;
492
493         DEBUG(5,("make_server_info_sam: made server info for user %s\n",
494                  pdb_get_username((*server_info)->sam_account)));
495         return True;
496 }
497
498 /***************************************************************************
499  Make (and fill) a user_info struct from a 'struct passwd' by conversion 
500  to a SAM_ACCOUNT
501 ***************************************************************************/
502
503 BOOL make_server_info_pw(auth_serversupplied_info **server_info, const struct passwd *pwd)
504 {
505         SAM_ACCOUNT *sampass = NULL;
506         if (!NT_STATUS_IS_OK(pdb_init_sam_pw(&sampass, pwd))) {         
507                 return False;
508         }
509         return make_server_info_sam(server_info, sampass);
510 }
511
512 /***************************************************************************
513  Free a user_info struct
514 ***************************************************************************/
515
516 void free_user_info(auth_usersupplied_info **user_info)
517 {
518         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
519         if (*user_info != NULL) {
520                 if ((*user_info)->smb_name.str) {
521                         DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
522                 }
523                 SAFE_FREE((*user_info)->smb_name.str);
524                 SAFE_FREE((*user_info)->internal_username.str);
525                 SAFE_FREE((*user_info)->client_domain.str);
526                 SAFE_FREE((*user_info)->domain.str);
527                 SAFE_FREE((*user_info)->wksta_name.str);
528                 data_blob_free(&(*user_info)->lm_resp);
529                 data_blob_free(&(*user_info)->nt_resp);
530                 SAFE_FREE((*user_info)->interactive_password);
531                 data_blob_clear_free(&(*user_info)->plaintext_password);
532                 ZERO_STRUCT(**user_info);
533         }
534         SAFE_FREE(*user_info);
535 }
536
537 /***************************************************************************
538  Clear out a server_info struct that has been allocated
539 ***************************************************************************/
540
541 void free_server_info(auth_serversupplied_info **server_info)
542 {
543         if (*server_info != NULL) {
544                 pdb_free_sam(&(*server_info)->sam_account);
545                 
546                 /* call pam_end here, unless we know we are keeping it */
547                 delete_nt_token( &(*server_info)->ptok );
548                 ZERO_STRUCT(**server_info);
549         }
550         SAFE_FREE(*server_info);
551 }
552
553 /***************************************************************************
554  Make a server_info struct for a guest user 
555 ***************************************************************************/
556
557 BOOL make_server_info_guest(auth_serversupplied_info **server_info) 
558 {
559         struct passwd *pass = getpwnam_alloc(lp_guestaccount());
560         
561         if (pass) {
562                 if (!make_server_info_pw(server_info, pass)) {
563                         passwd_free(&pass);
564                         return False;
565                 }
566                 (*server_info)->guest = True;
567                 passwd_free(&pass);
568                 return True;
569         }
570         DEBUG(0,("make_server_info_guest: getpwnam_alloc() failed on guest account!\n")); 
571         return False;
572 }
573
574 /***************************************************************************
575  Make an auth_methods struct
576 ***************************************************************************/
577
578 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
579 {
580         if (!auth_context) {
581                 smb_panic("no auth_context supplied to make_auth_methods()!\n");
582         }
583
584         if (!auth_method) {
585                 smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
586         }
587
588         *auth_method = talloc(auth_context->mem_ctx, sizeof(**auth_method));
589         if (!*auth_method) {
590                 DEBUG(0,("make_auth_method: malloc failed!\n"));
591                 return False;
592         }
593         ZERO_STRUCTP(*auth_method);
594         
595         return True;
596 }
597
598 /****************************************************************************
599  Delete a SID token.
600 ****************************************************************************/
601
602 void delete_nt_token(NT_USER_TOKEN **pptoken)
603 {
604     if (*pptoken) {
605                 NT_USER_TOKEN *ptoken = *pptoken;
606         SAFE_FREE( ptoken->user_sids );
607         ZERO_STRUCTP(ptoken);
608     }
609     SAFE_FREE(*pptoken);
610 }
611
612 /****************************************************************************
613  Duplicate a SID token.
614 ****************************************************************************/
615
616 NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
617 {
618         NT_USER_TOKEN *token;
619
620         if (!ptoken)
621                 return NULL;
622
623     if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
624         return NULL;
625
626     ZERO_STRUCTP(token);
627
628     if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
629         SAFE_FREE(token);
630         return NULL;
631     }
632
633     token->num_sids = ptoken->num_sids;
634
635         return token;
636 }
637
638 /**
639  * Squash an NT_STATUS in line with security requirements.
640  * In an attempt to avoid giving the whole game away when users
641  * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and 
642  * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations 
643  * (session setups in particular).
644  *
645  * @param nt_status NTSTATUS input for squashing.
646  * @return the 'squashed' nt_status
647  **/
648
649 NTSTATUS nt_status_squash(NTSTATUS nt_status)
650 {
651         if NT_STATUS_IS_OK(nt_status) {
652                 return nt_status;               
653         } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
654                 /* Match WinXP and don't give the game away */
655                 return NT_STATUS_LOGON_FAILURE;
656                 
657         } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
658                 /* Match WinXP and don't give the game away */
659                 return NT_STATUS_LOGON_FAILURE;
660         } else {
661                 return nt_status;
662         }  
663 }
664
665
666