r2798: get rid of a unnecessary static
[ira/wip.git] / source / 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    Copyright (C) Rafal Szczesniak 2002
8
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.
13    
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.
18    
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.
22 */
23
24 #include "includes.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_AUTH
28
29 /****************************************************************************
30  Create an auth_usersupplied_data structure
31 ****************************************************************************/
32 static NTSTATUS make_user_info(TALLOC_CTX *mem_ctx,
33                                struct auth_usersupplied_info **user_info, 
34                                const char *smb_name, 
35                                const char *internal_username,
36                                const char *client_domain, 
37                                const char *domain,
38                                const char *wksta_name, 
39                                DATA_BLOB *lm_password, DATA_BLOB *nt_password,
40                                DATA_BLOB *lm_interactive_password, DATA_BLOB *nt_interactive_password,
41                                DATA_BLOB *plaintext, 
42                                BOOL encrypted)
43 {
44
45         DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
46
47         *user_info = talloc_p(mem_ctx, struct auth_usersupplied_info);
48         if (!user_info) {
49                 return NT_STATUS_NO_MEMORY;
50         }
51
52         ZERO_STRUCTP(*user_info);
53
54         DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
55
56         (*user_info)->smb_name.str = talloc_strdup(*user_info, smb_name);
57         if ((*user_info)->smb_name.str) { 
58                 (*user_info)->smb_name.len = strlen(smb_name);
59         } else {
60                 free_user_info(user_info);
61                 return NT_STATUS_NO_MEMORY;
62         }
63         
64         (*user_info)->internal_username.str = talloc_strdup(*user_info, internal_username);
65         if ((*user_info)->internal_username.str) { 
66                 (*user_info)->internal_username.len = strlen(internal_username);
67         } else {
68                 free_user_info(user_info);
69                 return NT_STATUS_NO_MEMORY;
70         }
71
72         (*user_info)->domain.str = talloc_strdup(*user_info, domain);
73         if ((*user_info)->domain.str) { 
74                 (*user_info)->domain.len = strlen(domain);
75         } else {
76                 free_user_info(user_info);
77                 return NT_STATUS_NO_MEMORY;
78         }
79
80         (*user_info)->client_domain.str = talloc_strdup(*user_info, client_domain);
81         if ((*user_info)->client_domain.str) { 
82                 (*user_info)->client_domain.len = strlen(client_domain);
83         } else {
84                 free_user_info(user_info);
85                 return NT_STATUS_NO_MEMORY;
86         }
87
88         (*user_info)->wksta_name.str = talloc_strdup(*user_info, wksta_name);
89         if ((*user_info)->wksta_name.str) { 
90                 (*user_info)->wksta_name.len = strlen(wksta_name);
91         } else {
92                 free_user_info(user_info);
93                 return NT_STATUS_NO_MEMORY;
94         }
95
96         DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
97
98         if (lm_password)
99                 (*user_info)->lm_resp = data_blob_talloc(*user_info, 
100                                                          lm_password->data, 
101                                                          lm_password->length);
102         if (nt_password)
103                 (*user_info)->nt_resp = data_blob_talloc(*user_info,
104                                                          nt_password->data, 
105                                                          nt_password->length);
106         if (lm_interactive_password)
107                 (*user_info)->lm_interactive_password = 
108                         data_blob_talloc(*user_info,
109                                          lm_interactive_password->data, 
110                                          lm_interactive_password->length);
111         if (nt_interactive_password)
112                 (*user_info)->nt_interactive_password = 
113                         data_blob_talloc(*user_info, 
114                                          nt_interactive_password->data, 
115                                          nt_interactive_password->length);
116
117         if (plaintext)
118                 (*user_info)->plaintext_password = 
119                         data_blob_talloc(*user_info, 
120                                          plaintext->data, 
121                                          plaintext->length);
122
123         (*user_info)->encrypted = encrypted;
124
125         DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
126
127         return NT_STATUS_OK;
128 }
129
130 /****************************************************************************
131  Create an auth_usersupplied_data structure after appropriate mapping.
132 ****************************************************************************/
133
134 NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
135                             struct auth_usersupplied_info **user_info, 
136                             const char *smb_name, 
137                             const char *client_domain, 
138                             const char *wksta_name, 
139                             DATA_BLOB *lm_password, DATA_BLOB *nt_password,
140                             DATA_BLOB *lm_interactive_password, DATA_BLOB *nt_interactive_password,
141                             DATA_BLOB *plaintext, 
142                             BOOL encrypted)
143 {
144         const char *domain;
145         
146         DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
147               client_domain, smb_name, wksta_name));
148         
149         /* don't allow "" as a domain, fixes a Win9X bug 
150            where it doens't supply a domain for logon script
151            'net use' commands.                                 */
152
153         if ( *client_domain )
154                 domain = client_domain;
155         else
156                 domain = lp_workgroup();
157
158         /* we know that it is a trusted domain (and we are allowing
159            them) or it is our domain */
160         
161         return make_user_info(mem_ctx, 
162                               user_info, smb_name, smb_name, 
163                               client_domain, domain, wksta_name, 
164                               lm_password, nt_password,
165                               lm_interactive_password, nt_interactive_password,
166                               plaintext, encrypted);
167 }
168
169 /****************************************************************************
170  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
171  Decrypt and encrypt the passwords.
172 ****************************************************************************/
173
174 NTSTATUS make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
175                                          struct auth_usersupplied_info **user_info, 
176                                          const char *smb_name, 
177                                          const char *client_domain, 
178                                          const char *wksta_name, 
179                                          const uint8_t *lm_network_password, int lm_password_len,
180                                          const uint8_t *nt_network_password, int nt_password_len)
181 {
182         NTSTATUS nt_status;
183         DATA_BLOB lm_blob = data_blob(lm_network_password, lm_password_len);
184         DATA_BLOB nt_blob = data_blob(nt_network_password, nt_password_len);
185
186         nt_status = make_user_info_map(mem_ctx,
187                                        user_info,
188                                        smb_name, client_domain, 
189                                        wksta_name, 
190                                        lm_password_len ? &lm_blob : NULL, 
191                                        nt_password_len ? &nt_blob : NULL,
192                                        NULL, NULL, NULL,
193                                        True);
194         
195         data_blob_free(&lm_blob);
196         data_blob_free(&nt_blob);
197         return nt_status;
198 }
199
200 /****************************************************************************
201  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
202  Decrypt and encrypt the passwords.
203 ****************************************************************************/
204
205 NTSTATUS make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
206                                              struct auth_usersupplied_info **user_info, 
207                                              const char *smb_name, 
208                                              const char *client_domain, 
209                                              const char *wksta_name, 
210                                              const uint8_t chal[8], 
211                                              const struct samr_Password *lm_interactive_password, 
212                                              const struct samr_Password *nt_interactive_password)
213 {
214         NTSTATUS nt_status;
215         DATA_BLOB local_lm_blob;
216         DATA_BLOB local_nt_blob;
217         
218         DATA_BLOB lm_interactive_blob;
219         DATA_BLOB nt_interactive_blob;
220         uint8_t local_lm_response[24];
221         uint8_t local_nt_response[24];
222         
223         SMBOWFencrypt(lm_interactive_password->hash, chal, local_lm_response);
224         SMBOWFencrypt(nt_interactive_password->hash, chal, local_nt_response);
225         
226         local_lm_blob = data_blob(local_lm_response, 
227                                   sizeof(local_lm_response));
228         lm_interactive_blob = data_blob(lm_interactive_password->hash, 
229                                         sizeof(lm_interactive_password->hash));
230         
231         local_nt_blob = data_blob(local_nt_response, 
232                                   sizeof(local_nt_response));
233         nt_interactive_blob = data_blob(nt_interactive_password->hash, 
234                                         sizeof(nt_interactive_password->hash));
235         
236         nt_status = make_user_info_map(mem_ctx,
237                                        user_info, 
238                                        smb_name, client_domain, 
239                                        wksta_name, 
240                                        &local_lm_blob,
241                                        &local_nt_blob,
242                                        &lm_interactive_blob,
243                                        &nt_interactive_blob,
244                                        NULL,
245                                        True);
246         
247         data_blob_free(&local_lm_blob);
248         data_blob_free(&local_nt_blob);
249         data_blob_free(&lm_interactive_blob);
250         data_blob_free(&nt_interactive_blob);
251         return nt_status;
252 }
253 /****************************************************************************
254  Create an auth_usersupplied_data structure
255 ****************************************************************************/
256
257 NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
258                                       struct auth_usersupplied_info **user_info, 
259                                       const char *smb_name,
260                                       const char *client_domain, 
261                                       const char *remote_machine,
262                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp)
263 {
264         return make_user_info_map(mem_ctx,
265                                   user_info, smb_name, 
266                                   client_domain, 
267                                   remote_machine,
268                                   lm_resp.data ? &lm_resp : NULL, 
269                                   nt_resp.data ? &nt_resp : NULL, 
270                                   NULL, NULL, NULL,
271                                   True);
272 }
273
274 /****************************************************************************
275  Create a guest user_info blob, for anonymous authenticaion.
276 ****************************************************************************/
277
278 BOOL make_user_info_guest(TALLOC_CTX *mem_ctx,
279                           struct auth_usersupplied_info **user_info) 
280 {
281         NTSTATUS nt_status;
282
283         nt_status = make_user_info(mem_ctx,
284                                    user_info, 
285                                    "","", 
286                                    "","", 
287                                    "", 
288                                    NULL, NULL, 
289                                    NULL, NULL, 
290                                    NULL,
291                                    True);
292                               
293         return NT_STATUS_IS_OK(nt_status) ? True : False;
294 }
295
296 /****************************************************************************
297  prints a NT_USER_TOKEN to debug output.
298 ****************************************************************************/
299
300 void debug_nt_user_token(int dbg_class, int dbg_lev, const NT_USER_TOKEN *token)
301 {
302         TALLOC_CTX *mem_ctx;
303
304         size_t     i;
305         
306         if (!token) {
307                 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
308                 return;
309         }
310         
311         mem_ctx = talloc_init("debug_nt_user_token()");
312         if (!mem_ctx) {
313                 return;
314         }
315
316         DEBUGC(dbg_class, dbg_lev, ("NT user token of user %s\n",
317                                     dom_sid_string(mem_ctx, token->user_sids[0]) ));
318         DEBUGADDC(dbg_class, dbg_lev, ("contains %lu SIDs\n", (unsigned long)token->num_sids));
319         for (i = 0; i < token->num_sids; i++)
320                 DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i, 
321                                                dom_sid_string(mem_ctx, token->user_sids[i])));
322
323         talloc_destroy(mem_ctx);
324 }
325
326 /****************************************************************************
327  prints a NT_USER_TOKEN to debug output.
328 ****************************************************************************/
329
330 void debug_session_info(int dbg_class, int dbg_lev, const struct auth_session_info *session_info)
331 {
332         if (!session_info) {
333                 DEBUGC(dbg_class, dbg_lev, ("Session Info: (NULL)\n"));
334                 return; 
335         }
336
337         debug_nt_user_token(dbg_class, dbg_lev, session_info->nt_user_token);
338 }
339
340 /****************************************************************************
341  Create the SID list for this user.
342 ****************************************************************************/
343
344 NTSTATUS create_nt_user_token(TALLOC_CTX *mem_ctx, 
345                               struct dom_sid *user_sid, struct dom_sid *group_sid, 
346                               int n_groupSIDs, struct dom_sid **groupSIDs, 
347                               BOOL is_guest, struct nt_user_token **token)
348 {
349         NTSTATUS       nt_status = NT_STATUS_OK;
350         struct nt_user_token *ptoken;
351         int i;
352         int sid_ndx;
353         
354         if (!(ptoken = talloc_p(mem_ctx, struct nt_user_token))) {
355                 DEBUG(0, ("create_nt_token: Out of memory allocating token\n"));
356                 nt_status = NT_STATUS_NO_MEMORY;
357                 return nt_status;
358         }
359
360         ptoken->num_sids = 0;
361
362         if (!(ptoken->user_sids = talloc_array_p(mem_ctx, struct dom_sid*, n_groupSIDs + 5))) {
363                 DEBUG(0, ("create_nt_token: Out of memory allocating SIDs\n"));
364                 nt_status = NT_STATUS_NO_MEMORY;
365                 return nt_status;
366         }
367         
368         /*
369          * Note - user SID *MUST* be first in token !
370          * se_access_check depends on this.
371          *
372          * Primary group SID is second in token. Convention.
373          */
374
375         ptoken->user_sids[PRIMARY_USER_SID_INDEX] = user_sid;
376         ptoken->num_sids++;
377         ptoken->user_sids[PRIMARY_GROUP_SID_INDEX] = group_sid;
378         ptoken->num_sids++;
379
380         /*
381          * Finally add the "standard" SIDs.
382          * The only difference between guest and "anonymous" (which we
383          * don't really support) is the addition of Authenticated_Users.
384          */
385         ptoken->user_sids[2] = dom_sid_parse_talloc(mem_ctx, SID_WORLD);
386         ptoken->user_sids[3] = dom_sid_parse_talloc(mem_ctx, SID_NETWORK);
387
388         if (is_guest) {
389                 ptoken->user_sids[4] = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN_GUESTS);
390                 ptoken->num_sids++;
391         } else {
392                 ptoken->user_sids[4] = dom_sid_parse_talloc(mem_ctx, SID_AUTHENTICATED_USERS);
393                 ptoken->num_sids++;
394         }
395
396         sid_ndx = 5; /* next available spot */
397
398         for (i = 0; i < n_groupSIDs; i++) {
399                 size_t check_sid_idx;
400                 for (check_sid_idx = 1; check_sid_idx < ptoken->num_sids; check_sid_idx++) {
401                         if (sid_equal(ptoken->user_sids[check_sid_idx], 
402                                       groupSIDs[i])) {
403                                 break;
404                         }
405                 }
406                 
407                 if (check_sid_idx >= ptoken->num_sids) /* Not found already */ {
408                         ptoken->user_sids[sid_ndx++] = groupSIDs[i];
409                         ptoken->num_sids++;
410                 }
411         }
412         
413         debug_nt_user_token(DBGC_AUTH, 10, ptoken);
414         
415         *token = ptoken;
416
417         return nt_status;
418 }
419
420 /***************************************************************************
421  Make a user_info struct
422 ***************************************************************************/
423
424 NTSTATUS make_server_info(const TALLOC_CTX *mem_ctx,
425                           struct auth_serversupplied_info **server_info, 
426                           const char *username)
427 {
428         *server_info = talloc_p(mem_ctx, struct auth_serversupplied_info);
429         if (!*server_info) {
430                 return NT_STATUS_NO_MEMORY;
431         }
432         ZERO_STRUCTP(*server_info);
433         
434         return NT_STATUS_OK;
435 }
436
437 /***************************************************************************
438  Make (and fill) a user_info struct for a guest login.
439 ***************************************************************************/
440 NTSTATUS make_server_info_guest(const TALLOC_CTX *mem_ctx, struct auth_serversupplied_info **server_info)
441 {
442         NTSTATUS nt_status;
443
444         nt_status = make_server_info(mem_ctx, server_info, "");
445
446         if (!NT_STATUS_IS_OK(nt_status)) {
447                 return nt_status;
448         }
449         
450         (*server_info)->guest = True;
451
452         (*server_info)->user_sid = dom_sid_parse_talloc((*server_info), SID_ANONYMOUS);
453         (*server_info)->primary_group_sid = dom_sid_parse_talloc((*server_info), SID_BUILTIN_GUESTS);
454         (*server_info)->n_domain_groups = 0;
455         (*server_info)->domain_groups = NULL;
456         
457         /* annoying, but the Guest really does have a session key, 
458            and it is all zeros! */
459         (*server_info)->user_session_key = data_blob_talloc(*server_info, NULL, 16);
460         (*server_info)->lm_session_key = data_blob_talloc(*server_info, NULL, 16);
461
462         data_blob_clear(&(*server_info)->user_session_key);
463         data_blob_clear(&(*server_info)->lm_session_key);
464
465         (*server_info)->account_name = "";
466         (*server_info)->domain = "";
467         (*server_info)->full_name = "Anonymous";
468         (*server_info)->logon_script = "";
469         (*server_info)->profile_path = "";
470         (*server_info)->home_directory = "";
471         (*server_info)->home_drive = "";
472
473         (*server_info)->last_logon = 0;
474         (*server_info)->last_logoff = 0;
475         (*server_info)->acct_expiry = 0;
476         (*server_info)->last_password_change = 0;
477         (*server_info)->allow_password_change = 0;
478         (*server_info)->force_password_change = 0;
479
480         (*server_info)->logon_count = 0;
481         (*server_info)->bad_password_count = 0;
482
483         (*server_info)->acct_flags = ACB_NORMAL;
484
485         return nt_status;
486 }
487
488 /***************************************************************************
489  Free a user_info struct
490 ***************************************************************************/
491
492 void free_user_info(struct auth_usersupplied_info **user_info)
493 {
494         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
495         if (*user_info) {
496                 data_blob_clear(&(*user_info)->plaintext_password);
497         }
498
499         talloc_free(*user_info);
500         *user_info = NULL;
501 }
502
503 /***************************************************************************
504  Clear out a server_info struct that has been allocated
505 ***************************************************************************/
506
507 void free_server_info(struct auth_serversupplied_info **server_info)
508 {
509         DEBUG(5,("attempting to free a server_info structure\n"));
510         talloc_free(*server_info);
511         *server_info = NULL;
512 }
513
514 /***************************************************************************
515  Make an auth_methods struct
516 ***************************************************************************/
517
518 BOOL make_auth_methods(struct auth_context *auth_context, struct auth_methods **auth_method) 
519 {
520         if (!auth_context) {
521                 smb_panic("no auth_context supplied to make_auth_methods()!\n");
522         }
523
524         if (!auth_method) {
525                 smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
526         }
527
528         *auth_method = talloc_p(auth_context, struct auth_methods);
529         if (!*auth_method) {
530                 return False;
531         }
532         ZERO_STRUCTP(*auth_method);
533         
534         return True;
535 }
536
537 NTSTATUS make_session_info(struct auth_serversupplied_info *server_info, 
538                            struct auth_session_info **session_info) 
539 {
540         NTSTATUS nt_status;
541
542         *session_info = talloc_p(server_info, struct auth_session_info);
543         if (!*session_info) {
544                 return NT_STATUS_NO_MEMORY;
545         }
546         
547         (*session_info)->refcount = 1;
548         (*session_info)->server_info = server_info;
549
550         /* unless set otherwise, the session key is the user session
551          * key from the auth subsystem */
552  
553         (*session_info)->session_key = server_info->user_session_key;
554         
555         nt_status = create_nt_user_token((*session_info), 
556                                          server_info->user_sid, 
557                                          server_info->primary_group_sid, 
558                                          server_info->n_domain_groups, 
559                                          server_info->domain_groups,
560                                          False, 
561                                          &(*session_info)->nt_user_token);
562         
563         return nt_status;
564 }
565
566 /***************************************************************************
567  Clear out a server_info struct that has been allocated
568 ***************************************************************************/
569
570 void free_session_info(struct auth_session_info **session_info)
571 {
572         DEBUG(5,("attempting to free a session_info structure\n"));
573         if (*session_info) {
574                 (*session_info)->refcount--;
575                 if ((*session_info)->refcount <= 0) {
576                         talloc_free((*session_info));
577                 }
578         }
579         *session_info = NULL;
580 }
581
582 /**
583  * Squash an NT_STATUS in line with security requirements.
584  * In an attempt to avoid giving the whole game away when users
585  * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and 
586  * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations 
587  * (session setups in particular).
588  *
589  * @param nt_status NTSTATUS input for squashing.
590  * @return the 'squashed' nt_status
591  **/
592
593 NTSTATUS nt_status_squash(NTSTATUS nt_status)
594 {
595         if NT_STATUS_IS_OK(nt_status) {
596                 return nt_status;               
597         } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
598                 /* Match WinXP and don't give the game away */
599                 return NT_STATUS_LOGON_FAILURE;
600                 
601         } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
602                 /* Match WinXP and don't give the game away */
603                 return NT_STATUS_LOGON_FAILURE;
604         } else {
605                 return nt_status;
606         }  
607 }
608
609
610