493d7393d072eb0ab046f94c77cc79b67d3e943f
[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    Copyright (C) Rafal Szczesniak 2002
8    Copyright (C) Volker Lendecke 2006
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include "includes.h"
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_AUTH
29
30 static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
31                                                    const DOM_SID *user_sid,
32                                                    const DOM_SID *group_sid,
33                                                    BOOL is_guest,
34                                                    int num_groupsids,
35                                                    const DOM_SID *groupsids);
36
37 /****************************************************************************
38  Create a UNIX user on demand.
39 ****************************************************************************/
40
41 static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
42 {
43         pstring add_script;
44         int ret;
45
46         pstrcpy(add_script, lp_adduser_script());
47         if (! *add_script)
48                 return -1;
49         all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
50         if (domain)
51                 all_string_sub(add_script, "%D", domain, sizeof(pstring));
52         if (homedir)
53                 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
54         ret = smbrun(add_script,NULL);
55         flush_pwnam_cache();
56         DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
57         return ret;
58 }
59
60 /****************************************************************************
61  Create an auth_usersupplied_data structure
62 ****************************************************************************/
63
64 static NTSTATUS make_user_info(auth_usersupplied_info **user_info, 
65                                const char *smb_name, 
66                                const char *internal_username,
67                                const char *client_domain, 
68                                const char *domain,
69                                const char *wksta_name, 
70                                DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
71                                DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
72                                DATA_BLOB *plaintext, 
73                                BOOL encrypted)
74 {
75
76         DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
77
78         *user_info = SMB_MALLOC_P(auth_usersupplied_info);
79         if (*user_info == NULL) {
80                 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
81                 return NT_STATUS_NO_MEMORY;
82         }
83
84         ZERO_STRUCTP(*user_info);
85
86         DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
87
88         (*user_info)->smb_name = SMB_STRDUP(smb_name);
89         if ((*user_info)->smb_name == NULL) { 
90                 free_user_info(user_info);
91                 return NT_STATUS_NO_MEMORY;
92         }
93         
94         (*user_info)->internal_username = SMB_STRDUP(internal_username);
95         if ((*user_info)->internal_username == NULL) { 
96                 free_user_info(user_info);
97                 return NT_STATUS_NO_MEMORY;
98         }
99
100         (*user_info)->domain = SMB_STRDUP(domain);
101         if ((*user_info)->domain == NULL) { 
102                 free_user_info(user_info);
103                 return NT_STATUS_NO_MEMORY;
104         }
105
106         (*user_info)->client_domain = SMB_STRDUP(client_domain);
107         if ((*user_info)->client_domain == NULL) { 
108                 free_user_info(user_info);
109                 return NT_STATUS_NO_MEMORY;
110         }
111
112         (*user_info)->wksta_name = SMB_STRDUP(wksta_name);
113         if ((*user_info)->wksta_name == NULL) { 
114                 free_user_info(user_info);
115                 return NT_STATUS_NO_MEMORY;
116         }
117
118         DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
119
120         if (lm_pwd)
121                 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
122         if (nt_pwd)
123                 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
124         if (lm_interactive_pwd)
125                 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
126         if (nt_interactive_pwd)
127                 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
128
129         if (plaintext)
130                 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
131
132         (*user_info)->encrypted = encrypted;
133
134         (*user_info)->logon_parameters = 0;
135
136         DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
137
138         return NT_STATUS_OK;
139 }
140
141 /****************************************************************************
142  Create an auth_usersupplied_data structure after appropriate mapping.
143 ****************************************************************************/
144
145 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, 
146                             const char *smb_name, 
147                             const char *client_domain, 
148                             const char *wksta_name, 
149                             DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
150                             DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
151                             DATA_BLOB *plaintext, 
152                             BOOL encrypted)
153 {
154         const char *domain;
155         NTSTATUS result;
156         BOOL was_mapped;
157         fstring internal_username;
158         fstrcpy(internal_username, smb_name);
159         was_mapped = map_username(internal_username); 
160         
161         DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
162               client_domain, smb_name, wksta_name));
163         
164         /* don't allow "" as a domain, fixes a Win9X bug 
165            where it doens't supply a domain for logon script
166            'net use' commands.                                 */
167
168         if ( *client_domain )
169                 domain = client_domain;
170         else
171                 domain = lp_workgroup();
172
173         /* do what win2k does.  Always map unknown domains to our own
174            and let the "passdb backend" handle unknown users. */
175
176         if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) ) 
177                 domain = my_sam_name();
178         
179         /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
180         
181         result = make_user_info(user_info, smb_name, internal_username, 
182                               client_domain, domain, wksta_name, 
183                               lm_pwd, nt_pwd,
184                               lm_interactive_pwd, nt_interactive_pwd,
185                               plaintext, encrypted);
186         if (NT_STATUS_IS_OK(result)) {
187                 (*user_info)->was_mapped = was_mapped;
188         }
189         return result;
190 }
191
192 /****************************************************************************
193  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
194  Decrypt and encrypt the passwords.
195 ****************************************************************************/
196
197 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
198                                      const char *smb_name, 
199                                      const char *client_domain, 
200                                      const char *wksta_name, 
201                                      uint32 logon_parameters,
202                                      const uchar *lm_network_pwd,
203                                      int lm_pwd_len,
204                                      const uchar *nt_network_pwd,
205                                      int nt_pwd_len)
206 {
207         BOOL ret;
208         NTSTATUS status;
209         DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
210         DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
211
212         status = make_user_info_map(user_info,
213                                     smb_name, client_domain, 
214                                     wksta_name, 
215                                     lm_pwd_len ? &lm_blob : NULL, 
216                                     nt_pwd_len ? &nt_blob : NULL,
217                                     NULL, NULL, NULL,
218                                     True);
219
220         if (NT_STATUS_IS_OK(status)) {
221                 (*user_info)->logon_parameters = logon_parameters;
222         }
223         ret = NT_STATUS_IS_OK(status) ? True : False;
224
225         data_blob_free(&lm_blob);
226         data_blob_free(&nt_blob);
227         return ret;
228 }
229
230 /****************************************************************************
231  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
232  Decrypt and encrypt the passwords.
233 ****************************************************************************/
234
235 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
236                                          const char *smb_name, 
237                                          const char *client_domain, 
238                                          const char *wksta_name, 
239                                          uint32 logon_parameters,
240                                          const uchar chal[8], 
241                                          const uchar lm_interactive_pwd[16], 
242                                          const uchar nt_interactive_pwd[16], 
243                                          const uchar *dc_sess_key)
244 {
245         char lm_pwd[16];
246         char nt_pwd[16];
247         unsigned char local_lm_response[24];
248         unsigned char local_nt_response[24];
249         unsigned char key[16];
250         
251         ZERO_STRUCT(key);
252         memcpy(key, dc_sess_key, 8);
253         
254         if (lm_interactive_pwd)
255                 memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
256
257         if (nt_interactive_pwd)
258                 memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
259         
260 #ifdef DEBUG_PASSWORD
261         DEBUG(100,("key:"));
262         dump_data(100, (char *)key, sizeof(key));
263         
264         DEBUG(100,("lm owf password:"));
265         dump_data(100, lm_pwd, sizeof(lm_pwd));
266         
267         DEBUG(100,("nt owf password:"));
268         dump_data(100, nt_pwd, sizeof(nt_pwd));
269 #endif
270         
271         if (lm_interactive_pwd)
272                 SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
273         
274         if (nt_interactive_pwd)
275                 SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
276         
277 #ifdef DEBUG_PASSWORD
278         DEBUG(100,("decrypt of lm owf password:"));
279         dump_data(100, lm_pwd, sizeof(lm_pwd));
280         
281         DEBUG(100,("decrypt of nt owf password:"));
282         dump_data(100, nt_pwd, sizeof(nt_pwd));
283 #endif
284         
285         if (lm_interactive_pwd)
286                 SMBOWFencrypt((const unsigned char *)lm_pwd, chal,
287                               local_lm_response);
288
289         if (nt_interactive_pwd)
290                 SMBOWFencrypt((const unsigned char *)nt_pwd, chal,
291                               local_nt_response);
292         
293         /* Password info paranoia */
294         ZERO_STRUCT(key);
295
296         {
297                 BOOL ret;
298                 NTSTATUS nt_status;
299                 DATA_BLOB local_lm_blob;
300                 DATA_BLOB local_nt_blob;
301
302                 DATA_BLOB lm_interactive_blob;
303                 DATA_BLOB nt_interactive_blob;
304                 
305                 if (lm_interactive_pwd) {
306                         local_lm_blob = data_blob(local_lm_response,
307                                                   sizeof(local_lm_response));
308                         lm_interactive_blob = data_blob(lm_pwd,
309                                                         sizeof(lm_pwd));
310                         ZERO_STRUCT(lm_pwd);
311                 }
312                 
313                 if (nt_interactive_pwd) {
314                         local_nt_blob = data_blob(local_nt_response,
315                                                   sizeof(local_nt_response));
316                         nt_interactive_blob = data_blob(nt_pwd,
317                                                         sizeof(nt_pwd));
318                         ZERO_STRUCT(nt_pwd);
319                 }
320
321                 nt_status = make_user_info_map(
322                         user_info, 
323                         smb_name, client_domain, wksta_name, 
324                         lm_interactive_pwd ? &local_lm_blob : NULL,
325                         nt_interactive_pwd ? &local_nt_blob : NULL,
326                         lm_interactive_pwd ? &lm_interactive_blob : NULL,
327                         nt_interactive_pwd ? &nt_interactive_blob : NULL,
328                         NULL, True);
329
330                 if (NT_STATUS_IS_OK(nt_status)) {
331                         (*user_info)->logon_parameters = logon_parameters;
332                 }
333
334                 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
335                 data_blob_free(&local_lm_blob);
336                 data_blob_free(&local_nt_blob);
337                 data_blob_free(&lm_interactive_blob);
338                 data_blob_free(&nt_interactive_blob);
339                 return ret;
340         }
341 }
342
343
344 /****************************************************************************
345  Create an auth_usersupplied_data structure
346 ****************************************************************************/
347
348 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
349                               const char *smb_name, 
350                               const char *client_domain,
351                               const uint8 chal[8],
352                               DATA_BLOB plaintext_password)
353 {
354
355         DATA_BLOB local_lm_blob;
356         DATA_BLOB local_nt_blob;
357         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
358                         
359         /*
360          * Not encrypted - do so.
361          */
362         
363         DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
364                  "format.\n"));
365         
366         if (plaintext_password.data) {
367                 unsigned char local_lm_response[24];
368                 
369 #ifdef DEBUG_PASSWORD
370                 DEBUG(10,("Unencrypted password (len %d):\n",
371                           (int)plaintext_password.length));
372                 dump_data(100, (const char *)plaintext_password.data,
373                           plaintext_password.length);
374 #endif
375
376                 SMBencrypt( (const char *)plaintext_password.data,
377                             (const uchar*)chal, local_lm_response);
378                 local_lm_blob = data_blob(local_lm_response, 24);
379                 
380                 /* We can't do an NT hash here, as the password needs to be
381                    case insensitive */
382                 local_nt_blob = data_blob(NULL, 0); 
383                 
384         } else {
385                 local_lm_blob = data_blob(NULL, 0); 
386                 local_nt_blob = data_blob(NULL, 0); 
387         }
388         
389         ret = make_user_info_map(
390                 user_info, smb_name, client_domain, 
391                 get_remote_machine_name(),
392                 local_lm_blob.data ? &local_lm_blob : NULL,
393                 local_nt_blob.data ? &local_nt_blob : NULL,
394                 NULL, NULL,
395                 plaintext_password.data ? &plaintext_password : NULL, 
396                 False);
397         
398         data_blob_free(&local_lm_blob);
399         return NT_STATUS_IS_OK(ret) ? True : False;
400 }
401
402 /****************************************************************************
403  Create an auth_usersupplied_data structure
404 ****************************************************************************/
405
406 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
407                                       const char *smb_name,
408                                       const char *client_domain, 
409                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp)
410 {
411         return make_user_info_map(user_info, smb_name, 
412                                   client_domain, 
413                                   get_remote_machine_name(), 
414                                   lm_resp.data ? &lm_resp : NULL, 
415                                   nt_resp.data ? &nt_resp : NULL, 
416                                   NULL, NULL, NULL,
417                                   True);
418 }
419
420 /****************************************************************************
421  Create a guest user_info blob, for anonymous authenticaion.
422 ****************************************************************************/
423
424 BOOL make_user_info_guest(auth_usersupplied_info **user_info) 
425 {
426         NTSTATUS nt_status;
427
428         nt_status = make_user_info(user_info, 
429                                    "","", 
430                                    "","", 
431                                    "", 
432                                    NULL, NULL, 
433                                    NULL, NULL, 
434                                    NULL,
435                                    True);
436                               
437         return NT_STATUS_IS_OK(nt_status) ? True : False;
438 }
439
440 /****************************************************************************
441  prints a NT_USER_TOKEN to debug output.
442 ****************************************************************************/
443
444 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
445 {
446         size_t     i;
447         
448         if (!token) {
449                 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
450                 return;
451         }
452         
453         DEBUGC(dbg_class, dbg_lev,
454                ("NT user token of user %s\n",
455                 sid_string_static(&token->user_sids[0]) ));
456         DEBUGADDC(dbg_class, dbg_lev,
457                   ("contains %lu SIDs\n", (unsigned long)token->num_sids));
458         for (i = 0; i < token->num_sids; i++)
459                 DEBUGADDC(dbg_class, dbg_lev,
460                           ("SID[%3lu]: %s\n", (unsigned long)i, 
461                            sid_string_static(&token->user_sids[i])));
462
463         dump_se_priv( dbg_class, dbg_lev, &token->privileges );
464 }
465
466 /****************************************************************************
467  prints a UNIX 'token' to debug output.
468 ****************************************************************************/
469
470 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
471                            int n_groups, gid_t *groups)
472 {
473         int     i;
474         DEBUGC(dbg_class, dbg_lev,
475                ("UNIX token of user %ld\n", (long int)uid));
476
477         DEBUGADDC(dbg_class, dbg_lev,
478                   ("Primary group is %ld and contains %i supplementary "
479                    "groups\n", (long int)gid, n_groups));
480         for (i = 0; i < n_groups; i++)
481                 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i, 
482                         (long int)groups[i]));
483 }
484
485 /******************************************************************************
486  Create a token for the root user to be used internally by smbd.
487  This is similar to running under the context of the LOCAL_SYSTEM account
488  in Windows.  This is a read-only token.  Do not modify it or free() it.
489  Create a copy if your need to change it.
490 ******************************************************************************/
491
492 NT_USER_TOKEN *get_root_nt_token( void )
493 {
494         static NT_USER_TOKEN *token = NULL;
495         DOM_SID u_sid, g_sid;
496         struct passwd *pw;
497         
498         if ( token )
499                 return token;
500                 
501         if ( !(pw = sys_getpwnam( "root" )) ) {
502                 DEBUG(0,("get_root_nt_token: getpwnam\"root\") failed!\n"));
503                 return NULL;
504         }
505         
506         /* get the user and primary group SIDs; although the 
507            BUILTIN\Administrators SId is really the one that matters here */
508            
509         uid_to_sid(&u_sid, pw->pw_uid);
510         gid_to_sid(&g_sid, pw->pw_gid);
511
512         token = create_local_nt_token(NULL, &u_sid, &g_sid, False,
513                                       1, &global_sid_Builtin_Administrators);
514         return token;
515 }
516
517 static int server_info_dtor(void *p)
518 {
519         auth_serversupplied_info *server_info =
520                 talloc_get_type_abort(p, auth_serversupplied_info);
521
522         if (server_info->sam_account != NULL) {
523                 TALLOC_FREE(server_info->sam_account);
524         }
525
526         ZERO_STRUCTP(server_info);
527         return 0;
528 }
529
530 /***************************************************************************
531  Make a server_info struct. Free with TALLOC_FREE().
532 ***************************************************************************/
533
534 static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
535 {
536         struct auth_serversupplied_info *result;
537
538         result = TALLOC_ZERO_P(mem_ctx, auth_serversupplied_info);
539         if (result == NULL) {
540                 DEBUG(0, ("talloc failed\n"));
541                 return NULL;
542         }
543
544         talloc_set_destructor(result, server_info_dtor);
545
546         /* Initialise the uid and gid values to something non-zero
547            which may save us from giving away root access if there
548            is a bug in allocating these fields. */
549
550         result->uid = -1;
551         result->gid = -1;
552         return result;
553 }
554
555 /***************************************************************************
556  Make (and fill) a user_info struct from a struct samu
557 ***************************************************************************/
558
559 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, 
560                               struct samu *sampass)
561 {
562         NTSTATUS status;
563         struct passwd *pwd;
564         gid_t *gids;
565         auth_serversupplied_info *result;
566
567         if ( !(pwd = getpwnam_alloc(NULL, pdb_get_username(sampass))) ) {
568                 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
569                           pdb_get_username(sampass)));
570                 return NT_STATUS_NO_SUCH_USER;
571         }
572
573         if ( !(result = make_server_info(NULL)) ) {
574                 TALLOC_FREE(pwd);
575                 return NT_STATUS_NO_MEMORY;
576         }
577
578         result->sam_account = sampass;
579         result->unix_name = talloc_strdup(result, pwd->pw_name);
580         result->gid = pwd->pw_gid;
581         result->uid = pwd->pw_uid;
582         
583         TALLOC_FREE(pwd);
584
585         status = pdb_enum_group_memberships(result, sampass,
586                                             &result->sids, &gids,
587                                             &result->num_sids);
588
589         if (!NT_STATUS_IS_OK(status)) {
590                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
591                            nt_errstr(status)));
592                 result->sam_account = NULL; /* Don't free on error exit. */
593                 TALLOC_FREE(result);
594                 return status;
595         }
596
597         /* For now we throw away the gids and convert via sid_to_gid
598          * later. This needs fixing, but I'd like to get the code straight and
599          * simple first. */
600         TALLOC_FREE(gids);
601
602         DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
603                  pdb_get_username(sampass), result->unix_name));
604
605         *server_info = result;
606
607         return NT_STATUS_OK;
608 }
609
610 /*
611  * Add alias SIDs from memberships within the partially created token SID list
612  */
613
614 static NTSTATUS add_aliases(TALLOC_CTX *tmp_ctx, const DOM_SID *domain_sid,
615                             struct nt_user_token *token)
616 {
617         uint32 *aliases;
618         size_t i, num_aliases;
619         NTSTATUS status;
620
621         aliases = NULL;
622         num_aliases = 0;
623
624         status = pdb_enum_alias_memberships(tmp_ctx, domain_sid,
625                                             token->user_sids,
626                                             token->num_sids,
627                                             &aliases, &num_aliases);
628
629         if (!NT_STATUS_IS_OK(status)) {
630                 DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n",
631                            nt_errstr(status)));
632                 return status;
633         }
634
635         for (i=0; i<num_aliases; i++) {
636                 DOM_SID alias_sid;
637                 sid_compose(&alias_sid, domain_sid, aliases[i]);
638                 add_sid_to_array_unique(token, &alias_sid,
639                                         &token->user_sids,
640                                         &token->num_sids);
641                 if (token->user_sids == NULL) {
642                         DEBUG(0, ("add_sid_to_array failed\n"));
643                         return NT_STATUS_NO_MEMORY;
644                 }
645         }
646
647         return NT_STATUS_OK;
648 }
649
650 static NTSTATUS log_nt_token(TALLOC_CTX *tmp_ctx, NT_USER_TOKEN *token)
651 {
652         char *command;
653         char *group_sidstr;
654         size_t i;
655
656         if ((lp_log_nt_token_command() == NULL) ||
657             (strlen(lp_log_nt_token_command()) == 0)) {
658                 return NT_STATUS_OK;
659         }
660
661         group_sidstr = talloc_strdup(tmp_ctx, "");
662         for (i=1; i<token->num_sids; i++) {
663                 group_sidstr = talloc_asprintf(
664                         tmp_ctx, "%s %s", group_sidstr,
665                         sid_string_static(&token->user_sids[i]));
666         }
667
668         command = talloc_string_sub(
669                 tmp_ctx, lp_log_nt_token_command(),
670                 "%s", sid_string_static(&token->user_sids[0]));
671         command = talloc_string_sub(tmp_ctx, command, "%t", group_sidstr);
672
673         if (command == NULL) {
674                 return NT_STATUS_NO_MEMORY;
675         }
676
677         DEBUG(8, ("running command: [%s]\n", command));
678         if (smbrun(command, NULL) != 0) {
679                 DEBUG(0, ("Could not log NT token\n"));
680                 return NT_STATUS_ACCESS_DENIED;
681         }
682
683         return NT_STATUS_OK;
684 }
685
686 /*******************************************************************
687 *******************************************************************/
688
689 static NTSTATUS add_builtin_administrators( TALLOC_CTX *ctx, struct nt_user_token *token )
690 {
691         DOM_SID domadm;
692
693         /* nothing to do if we aren't in a domain */
694         
695         if ( !(IS_DC || lp_server_role()==ROLE_DOMAIN_MEMBER) ) {
696                 return NT_STATUS_OK;
697         }
698         
699         /* Find the Domain Admins SID */
700         
701         if ( IS_DC ) {
702                 sid_copy( &domadm, get_global_sam_sid() );
703         } else {
704                 if ( !secrets_fetch_domain_sid( lp_workgroup(), &domadm ) )
705                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
706         }
707         sid_append_rid( &domadm, DOMAIN_GROUP_RID_ADMINS );
708         
709         /* Add Administrators if the user beloongs to Domain Admins */
710         
711         if ( nt_token_check_sid( &domadm, token ) ) {
712                 add_sid_to_array(token, &global_sid_Builtin_Administrators,
713                                  &token->user_sids, &token->num_sids);
714         }
715         
716         return NT_STATUS_OK;
717 }
718
719 /*******************************************************************
720 *******************************************************************/
721
722 static NTSTATUS create_builtin_users( void )
723 {
724         NTSTATUS status;
725         DOM_SID dom_users;
726
727         status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_USERS );
728         if ( !NT_STATUS_IS_OK(status) ) {
729                 DEBUG(0,("create_builtin_users: Failed to create Users\n"));
730                 return status;
731         }
732         
733         /* add domain users */
734         if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER)) 
735                 && secrets_fetch_domain_sid(lp_workgroup(), &dom_users))
736         {
737                 sid_append_rid(&dom_users, DOMAIN_GROUP_RID_USERS );
738                 status = pdb_add_aliasmem( &global_sid_Builtin_Users, &dom_users);
739                 if ( !NT_STATUS_IS_OK(status) ) {
740                         DEBUG(0,("create_builtin_administrators: Failed to add Domain Users to"
741                                 " Users\n"));
742                         return status;
743                 }
744         }
745                         
746         return NT_STATUS_OK;
747 }               
748
749 /*******************************************************************
750 *******************************************************************/
751
752 static NTSTATUS create_builtin_administrators( void )
753 {
754         NTSTATUS status;
755         DOM_SID dom_admins, root_sid;
756         fstring root_name;
757         enum SID_NAME_USE type;         
758         TALLOC_CTX *ctx;
759         BOOL ret;
760
761         status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_ADMINS );
762         if ( !NT_STATUS_IS_OK(status) ) {
763                 DEBUG(0,("create_builtin_administrators: Failed to create Administrators\n"));
764                 return status;
765         }
766         
767         /* add domain admins */
768         if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER)) 
769                 && secrets_fetch_domain_sid(lp_workgroup(), &dom_admins))
770         {
771                 sid_append_rid(&dom_admins, DOMAIN_GROUP_RID_ADMINS);
772                 status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &dom_admins );
773                 if ( !NT_STATUS_IS_OK(status) ) {
774                         DEBUG(0,("create_builtin_administrators: Failed to add Domain Admins"
775                                 " Administrators\n"));
776                         return status;
777                 }
778         }
779                         
780         /* add root */
781         if ( (ctx = talloc_init("create_builtin_administrators")) == NULL ) {
782                 return NT_STATUS_NO_MEMORY;
783         }
784         fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
785         ret = lookup_name( ctx, root_name, 0, NULL, NULL, &root_sid, &type );
786         TALLOC_FREE( ctx );
787
788         if ( ret ) {
789                 status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &root_sid );
790                 if ( !NT_STATUS_IS_OK(status) ) {
791                         DEBUG(0,("create_builtin_administrators: Failed to add root"
792                                 " Administrators\n"));
793                         return status;
794                 }
795         }
796         
797         return NT_STATUS_OK;
798 }               
799
800 /*******************************************************************
801  Create a NT token for the user, expanding local aliases
802 *******************************************************************/
803
804 static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
805                                                    const DOM_SID *user_sid,
806                                                    const DOM_SID *group_sid,
807                                                    BOOL is_guest,
808                                                    int num_groupsids,
809                                                    const DOM_SID *groupsids)
810 {
811         TALLOC_CTX *tmp_ctx;
812         struct nt_user_token *result = NULL;
813         int i;
814         NTSTATUS status;
815         gid_t gid;
816
817         tmp_ctx = talloc_new(mem_ctx);
818         if (tmp_ctx == NULL) {
819                 DEBUG(0, ("talloc_new failed\n"));
820                 return NULL;
821         }
822
823         result = TALLOC_ZERO_P(tmp_ctx, NT_USER_TOKEN);
824         if (result == NULL) {
825                 DEBUG(0, ("talloc failed\n"));
826                 goto done;
827         }
828
829         /* Add the user and primary group sid */
830
831         add_sid_to_array(result, user_sid,
832                          &result->user_sids, &result->num_sids);
833         add_sid_to_array(result, group_sid,
834                          &result->user_sids, &result->num_sids);
835                          
836         /* Add in BUILTIN sids */
837         
838         add_sid_to_array(result, &global_sid_World,
839                          &result->user_sids, &result->num_sids);
840         add_sid_to_array(result, &global_sid_Network,
841                          &result->user_sids, &result->num_sids);
842
843         if (is_guest) {
844                 add_sid_to_array(result, &global_sid_Builtin_Guests,
845                                  &result->user_sids, &result->num_sids);
846         } else {
847                 add_sid_to_array(result, &global_sid_Authenticated_Users,
848                                  &result->user_sids, &result->num_sids);
849         }
850         
851         /* Now the SIDs we got from authentication. These are the ones from
852          * the info3 struct or from the pdb_enum_group_memberships, depending
853          * on who authenticated the user. */
854
855         for (i=0; i<num_groupsids; i++) {
856                 add_sid_to_array_unique(result, &groupsids[i],
857                                         &result->user_sids, &result->num_sids);
858         }
859         
860         /* Deal with the BUILTIN\Administrators group.  If the SID can
861            be resolved then assume that the add_aliasmem( S-1-5-32 ) 
862            handled it. */
863
864         if ( !sid_to_gid( &global_sid_Builtin_Administrators, &gid ) ) {
865                 /* We can only create a mapping if winbind is running 
866                    and the nested group functionality has been enabled */
867                    
868                 if ( lp_winbind_nested_groups() && winbind_ping() ) {
869                         become_root();
870                         status = create_builtin_administrators( );
871                         if ( !NT_STATUS_IS_OK(status) ) {
872                                 DEBUG(0,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
873                                 /* don't fail, just log the message */
874                         }
875                         unbecome_root();
876                 }
877                 else {
878                         status = add_builtin_administrators( tmp_ctx, result ); 
879                         if ( !NT_STATUS_IS_OK(status) ) {
880                                 /* just log a complaint but do not fail */
881                                 DEBUG(3,("create_local_nt_token: failed to check for local Administrators"
882                                         " membership (%s)\n", nt_errstr(status)));
883                         }                       
884                 }               
885         }
886
887         /* Deal with the BUILTIN\Users group.  If the SID can
888            be resolved then assume that the add_aliasmem( S-1-5-32 ) 
889            handled it. */
890
891         if ( !sid_to_gid( &global_sid_Builtin_Users, &gid ) ) {
892                 /* We can only create a mapping if winbind is running 
893                    and the nested group functionality has been enabled */
894                    
895                 if ( lp_winbind_nested_groups() && winbind_ping() ) {
896                         become_root();
897                         status = create_builtin_users( );
898                         if ( !NT_STATUS_IS_OK(status) ) {
899                                 DEBUG(0,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
900                                 /* don't fail, just log the message */
901                         }
902                         unbecome_root();
903                 }
904         }
905
906         /* Deal with local groups */
907         
908         if (lp_winbind_nested_groups()) {
909
910                 /* Now add the aliases. First the one from our local SAM */
911
912                 status = add_aliases(tmp_ctx, get_global_sam_sid(), result);
913
914                 if (!NT_STATUS_IS_OK(status)) {
915                         result = NULL;
916                         goto done;
917                 }
918
919                 /* Finally the builtin ones */
920
921                 status = add_aliases(tmp_ctx, &global_sid_Builtin, result);
922
923                 if (!NT_STATUS_IS_OK(status)) {
924                         result = NULL;
925                         goto done;
926                 }
927         } 
928
929
930         get_privileges_for_sids(&result->privileges, result->user_sids,
931                                 result->num_sids);
932
933         talloc_steal(mem_ctx, result);
934
935  done:
936         TALLOC_FREE(tmp_ctx);
937         return result;
938 }
939
940 /*
941  * Create the token to use from server_info->sam_account and
942  * server_info->sids (the info3/sam groups). Find the unix gids.
943  */
944
945 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
946 {
947         TALLOC_CTX *mem_ctx;
948         NTSTATUS status;
949         size_t i;
950         
951
952         mem_ctx = talloc_new(NULL);
953         if (mem_ctx == NULL) {
954                 DEBUG(0, ("talloc_new failed\n"));
955                 return NT_STATUS_NO_MEMORY;
956         }
957
958         if (server_info->was_mapped) {
959                 status = create_token_from_username(server_info,
960                                                     server_info->unix_name,
961                                                     server_info->guest,
962                                                     &server_info->uid,
963                                                     &server_info->gid,
964                                                     &server_info->unix_name,
965                                                     &server_info->ptok);
966                 
967         } else {
968                 server_info->ptok = create_local_nt_token(
969                         server_info,
970                         pdb_get_user_sid(server_info->sam_account),
971                         pdb_get_group_sid(server_info->sam_account),
972                         server_info->guest,
973                         server_info->num_sids, server_info->sids);
974                 status = server_info->ptok ?
975                         NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
976         }
977
978         if (!NT_STATUS_IS_OK(status)) {
979                 TALLOC_FREE(mem_ctx);
980                 return status;
981         }
982         
983         /* Convert the SIDs to gids. */
984
985         server_info->n_groups = 0;
986         server_info->groups = NULL;
987
988         /* Start at index 1, where the groups start. */
989
990         for (i=1; i<server_info->ptok->num_sids; i++) {
991                 gid_t gid;
992                 DOM_SID *sid = &server_info->ptok->user_sids[i];
993
994                 if (!sid_to_gid(sid, &gid)) {
995                         DEBUG(10, ("Could not convert SID %s to gid, "
996                                    "ignoring it\n", sid_string_static(sid)));
997                         continue;
998                 }
999                 add_gid_to_array_unique(server_info, gid, &server_info->groups,
1000                                         &server_info->n_groups);
1001         }
1002         
1003         debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
1004
1005         status = log_nt_token(mem_ctx, server_info->ptok);
1006
1007         TALLOC_FREE(mem_ctx);
1008         return status;
1009 }
1010
1011 /*
1012  * Create an artificial NT token given just a username. (Initially indended
1013  * for force user)
1014  *
1015  * We go through lookup_name() to avoid problems we had with 'winbind use
1016  * default domain'.
1017  *
1018  * We have 3 cases:
1019  *
1020  * unmapped unix users: Go directly to nss to find the user's group.
1021  *
1022  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
1023  *
1024  * If the user is provided by winbind, the primary gid is set to "domain
1025  * users" of the user's domain. For an explanation why this is necessary, see
1026  * the thread starting at
1027  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
1028  */
1029
1030 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
1031                                     BOOL is_guest,
1032                                     uid_t *uid, gid_t *gid,
1033                                     char **found_username,
1034                                     struct nt_user_token **token)
1035 {
1036         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
1037         TALLOC_CTX *tmp_ctx;
1038         DOM_SID user_sid;
1039         enum SID_NAME_USE type;
1040         gid_t *gids;
1041         DOM_SID primary_group_sid;
1042         DOM_SID *group_sids;
1043         size_t num_group_sids;
1044
1045         tmp_ctx = talloc_new(NULL);
1046         if (tmp_ctx == NULL) {
1047                 DEBUG(0, ("talloc_new failed\n"));
1048                 return NT_STATUS_NO_MEMORY;
1049         }
1050
1051         if (!lookup_name(tmp_ctx, username, LOOKUP_NAME_ALL,
1052                          NULL, NULL, &user_sid, &type)) {
1053                 DEBUG(1, ("lookup_name for %s failed\n", username));
1054                 goto done;
1055         }
1056
1057         if (type != SID_NAME_USER) {
1058                 DEBUG(1, ("%s is a %s, not a user\n", username,
1059                           sid_type_lookup(type)));
1060                 goto done;
1061         }
1062
1063         if (!sid_to_uid(&user_sid, uid)) {
1064                 DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
1065                           username, sid_string_static(&user_sid)));
1066                 goto done;
1067         }
1068
1069         if (sid_check_is_in_our_domain(&user_sid)) {
1070
1071                 /* This is a passdb user, so ask passdb */
1072
1073                 struct samu *sam_acct = NULL;
1074                 const DOM_SID *gr_sid = NULL;
1075
1076                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
1077                         result = NT_STATUS_NO_MEMORY;
1078                         goto done;
1079                 }
1080
1081                 if (!pdb_getsampwsid(sam_acct, &user_sid)) {
1082                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
1083                                   sid_string_static(&user_sid), username));
1084                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
1085                         goto unix_user;
1086                 }
1087
1088                 gr_sid = pdb_get_group_sid(sam_acct);
1089                 if (!gr_sid) {
1090                         goto unix_user;
1091                 }
1092
1093                 sid_copy(&primary_group_sid, gr_sid);
1094
1095                 if (!sid_to_gid(&primary_group_sid, gid)) {
1096                         DEBUG(1, ("sid_to_gid(%s) failed\n",
1097                                   sid_string_static(&primary_group_sid)));
1098                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
1099                         goto unix_user;
1100                 }
1101
1102                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
1103                                                     &group_sids, &gids,
1104                                                     &num_group_sids);
1105                 if (!NT_STATUS_IS_OK(result)) {
1106                         DEBUG(10, ("enum_group_memberships failed for %s\n",
1107                                    username));
1108                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
1109                         goto unix_user;
1110                 }
1111
1112                 *found_username = talloc_strdup(mem_ctx,
1113                                                 pdb_get_username(sam_acct));
1114
1115         } else  if (sid_check_is_in_unix_users(&user_sid)) {
1116
1117                 /* This is a unix user not in passdb. We need to ask nss
1118                  * directly, without consulting passdb */
1119
1120                 struct passwd *pass;
1121                 size_t i;
1122
1123                 /*
1124                  * This goto target is used as a fallback for the passdb
1125                  * case. The concrete bug report is when passdb gave us an
1126                  * unmapped gid.
1127                  */
1128
1129         unix_user:
1130
1131                 uid_to_unix_users_sid(*uid, &user_sid);
1132
1133                 pass = getpwuid_alloc(tmp_ctx, *uid);
1134                 if (pass == NULL) {
1135                         DEBUG(1, ("getpwuid(%d) for user %s failed\n",
1136                                   *uid, username));
1137                         goto done;
1138                 }
1139
1140                 *gid = pass->pw_gid;
1141                 gid_to_sid(&primary_group_sid, pass->pw_gid);
1142
1143                 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
1144                                          &gids, &num_group_sids)) {
1145                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
1146                                   username));
1147                         goto done;
1148                 }
1149
1150                 group_sids = talloc_array(tmp_ctx, DOM_SID, num_group_sids);
1151                 if (group_sids == NULL) {
1152                         DEBUG(1, ("talloc_array failed\n"));
1153                         result = NT_STATUS_NO_MEMORY;
1154                         goto done;
1155                 }
1156
1157                 for (i=0; i<num_group_sids; i++) {
1158                         gid_to_sid(&group_sids[i], gids[i]);
1159                 }
1160                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
1161
1162         } else {
1163
1164                 /* This user is from winbind, force the primary gid to the
1165                  * user's "domain users" group. Under certain circumstances
1166                  * (user comes from NT4), this might be a loss of
1167                  * information. But we can not rely on winbind getting the
1168                  * correct info. AD might prohibit winbind looking up that
1169                  * information. */
1170
1171                 uint32 dummy;
1172
1173                 sid_copy(&primary_group_sid, &user_sid);
1174                 sid_split_rid(&primary_group_sid, &dummy);
1175                 sid_append_rid(&primary_group_sid, DOMAIN_GROUP_RID_USERS);
1176
1177                 if (!sid_to_gid(&primary_group_sid, gid)) {
1178                         DEBUG(1, ("sid_to_gid(%s) failed\n",
1179                                   sid_string_static(&primary_group_sid)));
1180                         goto done;
1181                 }
1182
1183                 num_group_sids = 0;
1184                 group_sids = NULL;
1185
1186                 *found_username = talloc_strdup(mem_ctx, username);
1187         }
1188
1189         *token = create_local_nt_token(mem_ctx, &user_sid, &primary_group_sid,
1190                                        is_guest, num_group_sids, group_sids);
1191
1192         if ((*token == NULL) || (*found_username == NULL)) {
1193                 result = NT_STATUS_NO_MEMORY;
1194                 goto done;
1195         }
1196
1197         result = NT_STATUS_OK;
1198  done:
1199         TALLOC_FREE(tmp_ctx);
1200         return result;
1201 }
1202
1203 /***************************************************************************
1204  Build upon create_token_from_username:
1205
1206  Expensive helper function to figure out whether a user given its name is
1207  member of a particular group.
1208 ***************************************************************************/
1209 BOOL user_in_group_sid(const char *username, const DOM_SID *group_sid)
1210 {
1211         NTSTATUS status;
1212         uid_t uid;
1213         gid_t gid;
1214         char *found_username;
1215         struct nt_user_token *token;
1216         BOOL result;
1217
1218         TALLOC_CTX *mem_ctx;
1219
1220         mem_ctx = talloc_new(NULL);
1221         if (mem_ctx == NULL) {
1222                 DEBUG(0, ("talloc_new failed\n"));
1223                 return False;
1224         }
1225
1226         status = create_token_from_username(mem_ctx, username, False,
1227                                             &uid, &gid, &found_username,
1228                                             &token);
1229
1230         if (!NT_STATUS_IS_OK(status)) {
1231                 DEBUG(10, ("could not create token for %s\n", username));
1232                 return False;
1233         }
1234
1235         result = nt_token_check_sid(group_sid, token);
1236
1237         TALLOC_FREE(mem_ctx);
1238         return result;
1239         
1240 }
1241
1242 BOOL user_in_group(const char *username, const char *groupname)
1243 {
1244         TALLOC_CTX *mem_ctx;
1245         DOM_SID group_sid;
1246         BOOL ret;
1247
1248         mem_ctx = talloc_new(NULL);
1249         if (mem_ctx == NULL) {
1250                 DEBUG(0, ("talloc_new failed\n"));
1251                 return False;
1252         }
1253
1254         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1255                           NULL, NULL, &group_sid, NULL);
1256         TALLOC_FREE(mem_ctx);
1257
1258         if (!ret) {
1259                 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1260                 return False;
1261         }
1262
1263         return user_in_group_sid(username, &group_sid);
1264 }
1265
1266
1267 /***************************************************************************
1268  Make (and fill) a user_info struct from a 'struct passwd' by conversion 
1269  to a struct samu
1270 ***************************************************************************/
1271
1272 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 
1273                              char *unix_username,
1274                              struct passwd *pwd)
1275 {
1276         NTSTATUS status;
1277         struct samu *sampass = NULL;
1278         gid_t *gids;
1279         auth_serversupplied_info *result;
1280         
1281         if ( !(sampass = samu_new( NULL )) ) {
1282                 return NT_STATUS_NO_MEMORY;
1283         }
1284         
1285         status = samu_set_unix( sampass, pwd );
1286         if (!NT_STATUS_IS_OK(status)) {
1287                 return status;
1288         }
1289
1290         result = make_server_info(NULL);
1291         if (result == NULL) {
1292                 TALLOC_FREE(sampass);
1293                 return NT_STATUS_NO_MEMORY;
1294         }
1295
1296         result->sam_account = sampass;
1297         result->unix_name = talloc_strdup(result, unix_username);
1298         result->uid = pwd->pw_uid;
1299         result->gid = pwd->pw_gid;
1300
1301         status = pdb_enum_group_memberships(result, sampass,
1302                                             &result->sids, &gids,
1303                                             &result->num_sids);
1304
1305         if (!NT_STATUS_IS_OK(status)) {
1306                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1307                            nt_errstr(status)));
1308                 TALLOC_FREE(result);
1309                 return status;
1310         }
1311
1312         /* For now we throw away the gids and convert via sid_to_gid
1313          * later. This needs fixing, but I'd like to get the code straight and
1314          * simple first. */
1315         TALLOC_FREE(gids);
1316
1317         *server_info = result;
1318
1319         return NT_STATUS_OK;
1320 }
1321
1322 /***************************************************************************
1323  Make (and fill) a user_info struct for a guest login.
1324  This *must* succeed for smbd to start. If there is no mapping entry for
1325  the guest gid, then create one.
1326 ***************************************************************************/
1327
1328 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1329 {
1330         NTSTATUS status;
1331         struct samu *sampass = NULL;
1332         DOM_SID guest_sid;
1333         BOOL ret;
1334         static const char zeros[16];
1335
1336         if ( !(sampass = samu_new( NULL )) ) {
1337                 return NT_STATUS_NO_MEMORY;
1338         }
1339
1340         sid_copy(&guest_sid, get_global_sam_sid());
1341         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1342
1343         become_root();
1344         ret = pdb_getsampwsid(sampass, &guest_sid);
1345         unbecome_root();
1346
1347         if (!ret) {
1348                 TALLOC_FREE(sampass);
1349                 return NT_STATUS_NO_SUCH_USER;
1350         }
1351
1352         status = make_server_info_sam(server_info, sampass);
1353         if (!NT_STATUS_IS_OK(status)) {
1354                 TALLOC_FREE(sampass);
1355                 return status;
1356         }
1357         
1358         (*server_info)->guest = True;
1359
1360         status = create_local_token(*server_info);
1361         if (!NT_STATUS_IS_OK(status)) {
1362                 DEBUG(10, ("create_local_token failed: %s\n",
1363                            nt_errstr(status)));
1364                 return status;
1365         }
1366
1367         /* annoying, but the Guest really does have a session key, and it is
1368            all zeros! */
1369         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1370         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1371
1372         return NT_STATUS_OK;
1373 }
1374
1375 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
1376 {
1377         auth_serversupplied_info *dst;
1378
1379         dst = make_server_info(NULL);
1380         if (dst == NULL) {
1381                 return NULL;
1382         }
1383
1384         dst->guest = src->guest;
1385         dst->uid = src->uid;
1386         dst->gid = src->gid;
1387         dst->n_groups = src->n_groups;
1388         if (src->n_groups != 0) {
1389                 dst->groups = talloc_memdup(dst, src->groups,
1390                                             sizeof(gid_t)*dst->n_groups);
1391         } else {
1392                 dst->groups = NULL;
1393         }
1394
1395         if (src->ptok) {
1396                 dst->ptok = dup_nt_token(dst, src->ptok);
1397                 if (!dst->ptok) {
1398                         TALLOC_FREE(dst);
1399                         return NULL;
1400                 }
1401         }
1402         
1403         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1404                                                 src->user_session_key.length);
1405
1406         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1407                                                 src->lm_session_key.length);
1408
1409         dst->sam_account = samu_new(NULL);
1410         if (!dst->sam_account) {
1411                 TALLOC_FREE(dst);
1412                 return NULL;
1413         }
1414
1415         if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1416                 TALLOC_FREE(dst);
1417                 return NULL;
1418         }
1419         
1420         dst->pam_handle = NULL;
1421         dst->unix_name = talloc_strdup(dst, src->unix_name);
1422         if (!dst->unix_name) {
1423                 TALLOC_FREE(dst);
1424                 return NULL;
1425         }
1426
1427         return dst;
1428 }
1429
1430 static auth_serversupplied_info *guest_info = NULL;
1431
1432 BOOL init_guest_info(void)
1433 {
1434         if (guest_info != NULL)
1435                 return True;
1436
1437         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1438 }
1439
1440 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
1441 {
1442         *server_info = copy_serverinfo(guest_info);
1443         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1444 }
1445
1446 /***************************************************************************
1447  Purely internal function for make_server_info_info3
1448  Fill the sam account from getpwnam
1449 ***************************************************************************/
1450 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
1451                                  const char *domain,
1452                                  const char *username,
1453                                  char **found_username,
1454                                  uid_t *uid, gid_t *gid,
1455                                  struct samu *account,
1456                                  BOOL *username_was_mapped)
1457 {
1458         NTSTATUS nt_status;
1459         fstring dom_user, lower_username;
1460         fstring real_username;
1461         struct passwd *passwd;
1462
1463         fstrcpy( lower_username, username );
1464         strlower_m( lower_username );
1465
1466         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1467                 lower_username);
1468
1469         /* Get the passwd struct.  Try to create the account is necessary. */
1470
1471         *username_was_mapped = map_username( dom_user );
1472
1473         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1474                 return NT_STATUS_NO_SUCH_USER;
1475
1476         *uid = passwd->pw_uid;
1477         *gid = passwd->pw_gid;
1478
1479         /* This is pointless -- there is no suport for differing 
1480            unix and windows names.  Make sure to always store the 
1481            one we actually looked up and succeeded. Have I mentioned
1482            why I hate the 'winbind use default domain' parameter?   
1483                                          --jerry              */
1484            
1485         *found_username = talloc_strdup( mem_ctx, real_username );
1486         
1487         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1488
1489         nt_status = samu_set_unix( account, passwd );
1490         
1491         TALLOC_FREE(passwd);
1492         
1493         return nt_status;
1494 }
1495
1496 /****************************************************************************
1497  Wrapper to allow the getpwnam() call to strip the domain name and 
1498  try again in case a local UNIX user is already there.  Also run through 
1499  the username if we fallback to the username only.
1500  ****************************************************************************/
1501  
1502 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1503                              fstring save_username, BOOL create )
1504 {
1505         struct passwd *pw = NULL;
1506         char *p;
1507         fstring username;
1508         
1509         /* we only save a copy of the username it has been mangled 
1510            by winbindd use default domain */
1511            
1512         save_username[0] = '\0';
1513            
1514         /* don't call map_username() here since it has to be done higher 
1515            up the stack so we don't call it mutliple times */
1516
1517         fstrcpy( username, domuser );
1518         
1519         p = strchr_m( username, *lp_winbind_separator() );
1520         
1521         /* code for a DOMAIN\user string */
1522         
1523         if ( p ) {
1524                 fstring strip_username;
1525
1526                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1527                 if ( pw ) {     
1528                         /* make sure we get the case of the username correct */
1529                         /* work around 'winbind use default domain = yes' */
1530
1531                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1532                                 char *domain;
1533                                 
1534                                 /* split the domain and username into 2 strings */
1535                                 *p = '\0';
1536                                 domain = username;
1537
1538                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1539                         }
1540                         else
1541                                 fstrcpy( save_username, pw->pw_name );
1542
1543                         /* whew -- done! */             
1544                         return pw;
1545                 }
1546
1547                 /* setup for lookup of just the username */
1548                 /* remember that p and username are overlapping memory */
1549
1550                 p++;
1551                 fstrcpy( strip_username, p );
1552                 fstrcpy( username, strip_username );
1553         }
1554         
1555         /* just lookup a plain username */
1556         
1557         pw = Get_Pwnam_alloc(mem_ctx, username);
1558                 
1559         /* Create local user if requested but only if winbindd
1560            is not running.  We need to protect against cases
1561            where winbindd is failing and then prematurely
1562            creating users in /etc/passwd */
1563         
1564         if ( !pw && create && !winbind_ping() ) {
1565                 /* Don't add a machine account. */
1566                 if (username[strlen(username)-1] == '$')
1567                         return NULL;
1568
1569                 smb_create_user(NULL, username, NULL);
1570                 pw = Get_Pwnam_alloc(mem_ctx, username);
1571         }
1572         
1573         /* one last check for a valid passwd struct */
1574         
1575         if ( pw )
1576                 fstrcpy( save_username, pw->pw_name );
1577
1578         return pw;
1579 }
1580
1581 /***************************************************************************
1582  Make a server_info struct from the info3 returned by a domain logon 
1583 ***************************************************************************/
1584
1585 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1586                                 const char *sent_nt_username,
1587                                 const char *domain,
1588                                 auth_serversupplied_info **server_info, 
1589                                 NET_USER_INFO_3 *info3) 
1590 {
1591         static const char zeros[16];
1592
1593         NTSTATUS nt_status = NT_STATUS_OK;
1594         char *found_username;
1595         const char *nt_domain;
1596         const char *nt_username;
1597         struct samu *sam_account = NULL;
1598         DOM_SID user_sid;
1599         DOM_SID group_sid;
1600         BOOL username_was_mapped;
1601
1602         uid_t uid;
1603         gid_t gid;
1604
1605         size_t i;
1606
1607         auth_serversupplied_info *result;
1608
1609         /* 
1610            Here is where we should check the list of
1611            trusted domains, and verify that the SID 
1612            matches.
1613         */
1614
1615         sid_copy(&user_sid, &info3->dom_sid.sid);
1616         if (!sid_append_rid(&user_sid, info3->user_rid)) {
1617                 return NT_STATUS_INVALID_PARAMETER;
1618         }
1619         
1620         sid_copy(&group_sid, &info3->dom_sid.sid);
1621         if (!sid_append_rid(&group_sid, info3->group_rid)) {
1622                 return NT_STATUS_INVALID_PARAMETER;
1623         }
1624
1625         if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1626                 /* If the server didn't give us one, just use the one we sent
1627                  * them */
1628                 nt_username = sent_nt_username;
1629         }
1630
1631         if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1632                 /* If the server didn't give us one, just use the one we sent
1633                  * them */
1634                 nt_domain = domain;
1635         }
1636         
1637         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1638            add user script (2.2.x behavior).
1639
1640            We use the _unmapped_ username here in an attempt to provide
1641            consistent username mapping behavior between kerberos and NTLM[SSP]
1642            authentication in domain mode security.  I.E. Username mapping
1643            should be applied to the fully qualified username
1644            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1645            called map_username() unnecessarily in make_user_info_map() but
1646            that is how the current code is designed.  Making the change here
1647            is the least disruptive place.  -- jerry */
1648            
1649         if ( !(sam_account = samu_new( NULL )) ) {
1650                 return NT_STATUS_NO_MEMORY;
1651         }
1652
1653         /* this call will try to create the user if necessary */
1654
1655         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1656                                      &found_username, &uid, &gid, sam_account,
1657                                      &username_was_mapped);
1658
1659         
1660         /* if we still don't have a valid unix account check for 
1661           'map to guest = bad uid' */
1662           
1663         if (!NT_STATUS_IS_OK(nt_status)) {
1664                 TALLOC_FREE( sam_account );
1665                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1666                         make_server_info_guest(server_info); 
1667                         return NT_STATUS_OK;
1668                 }
1669                 return nt_status;
1670         }
1671                 
1672         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1673                 TALLOC_FREE(sam_account);
1674                 return NT_STATUS_NO_MEMORY;
1675         }
1676
1677         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1678                 TALLOC_FREE(sam_account);
1679                 return NT_STATUS_NO_MEMORY;
1680         }
1681
1682         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1683                 TALLOC_FREE(sam_account);
1684                 return NT_STATUS_NO_MEMORY;
1685         }
1686
1687         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1688                 TALLOC_FREE(sam_account);
1689                 return NT_STATUS_UNSUCCESSFUL;
1690         }
1691
1692         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1693                 TALLOC_FREE(sam_account);
1694                 return NT_STATUS_UNSUCCESSFUL;
1695         }
1696                 
1697         if (!pdb_set_fullname(sam_account,
1698                               unistr2_static(&(info3->uni_full_name)), 
1699                               PDB_CHANGED)) {
1700                 TALLOC_FREE(sam_account);
1701                 return NT_STATUS_NO_MEMORY;
1702         }
1703
1704         if (!pdb_set_logon_script(sam_account,
1705                                   unistr2_static(&(info3->uni_logon_script)),
1706                                   PDB_CHANGED)) {
1707                 TALLOC_FREE(sam_account);
1708                 return NT_STATUS_NO_MEMORY;
1709         }
1710
1711         if (!pdb_set_profile_path(sam_account,
1712                                   unistr2_static(&(info3->uni_profile_path)),
1713                                   PDB_CHANGED)) {
1714                 TALLOC_FREE(sam_account);
1715                 return NT_STATUS_NO_MEMORY;
1716         }
1717
1718         if (!pdb_set_homedir(sam_account,
1719                              unistr2_static(&(info3->uni_home_dir)),
1720                              PDB_CHANGED)) {
1721                 TALLOC_FREE(sam_account);
1722                 return NT_STATUS_NO_MEMORY;
1723         }
1724
1725         if (!pdb_set_dir_drive(sam_account,
1726                                unistr2_static(&(info3->uni_dir_drive)),
1727                                PDB_CHANGED)) {
1728                 TALLOC_FREE(sam_account);
1729                 return NT_STATUS_NO_MEMORY;
1730         }
1731
1732         if (!pdb_set_acct_ctrl(sam_account, info3->acct_flags, PDB_CHANGED)) {
1733                 TALLOC_FREE(sam_account);
1734                 return NT_STATUS_NO_MEMORY;
1735         }
1736
1737         result = make_server_info(NULL);
1738         if (result == NULL) {
1739                 DEBUG(4, ("make_server_info failed!\n"));
1740                 TALLOC_FREE(sam_account);
1741                 return NT_STATUS_NO_MEMORY;
1742         }
1743
1744         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1745            valid struct samu) */
1746                    
1747         result->sam_account = sam_account;
1748         result->unix_name = talloc_strdup(result, found_username);
1749
1750         /* Fill in the unix info we found on the way */
1751
1752         result->uid = uid;
1753         result->gid = gid;
1754
1755         /* Create a 'combined' list of all SIDs we might want in the SD */
1756
1757         result->num_sids = 0;
1758         result->sids = NULL;
1759
1760         /* and create (by appending rids) the 'domain' sids */
1761         
1762         for (i = 0; i < info3->num_groups2; i++) {
1763                 DOM_SID sid;
1764                 if (!sid_compose(&sid, &info3->dom_sid.sid,
1765                                  info3->gids[i].g_rid)) {
1766                         DEBUG(3,("could not append additional group rid "
1767                                  "0x%x\n", info3->gids[i].g_rid));
1768                         TALLOC_FREE(result);
1769                         return NT_STATUS_INVALID_PARAMETER;
1770                 }
1771                 add_sid_to_array(result, &sid, &result->sids,
1772                                  &result->num_sids);
1773         }
1774
1775         /* Copy 'other' sids.  We need to do sid filtering here to
1776            prevent possible elevation of privileges.  See:
1777
1778            http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
1779          */
1780
1781         for (i = 0; i < info3->num_other_sids; i++) {
1782                 add_sid_to_array(result, &info3->other_sids[i].sid,
1783                                  &result->sids,
1784                                  &result->num_sids);
1785         }
1786
1787         result->login_server = unistr2_tdup(result, 
1788                                             &(info3->uni_logon_srv));
1789
1790         /* ensure we are never given NULL session keys */
1791         
1792         if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
1793                 result->user_session_key = data_blob(NULL, 0);
1794         } else {
1795                 result->user_session_key = data_blob_talloc(
1796                         result, info3->user_sess_key,
1797                         sizeof(info3->user_sess_key));
1798         }
1799
1800         if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
1801                 result->lm_session_key = data_blob(NULL, 0);
1802         } else {
1803                 result->lm_session_key = data_blob_talloc(
1804                         result, info3->lm_sess_key,
1805                         sizeof(info3->lm_sess_key));
1806         }
1807
1808         result->was_mapped = username_was_mapped;
1809
1810         *server_info = result;
1811
1812         return NT_STATUS_OK;
1813 }
1814
1815 /***************************************************************************
1816  Free a user_info struct
1817 ***************************************************************************/
1818
1819 void free_user_info(auth_usersupplied_info **user_info)
1820 {
1821         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1822         if (*user_info != NULL) {
1823                 if ((*user_info)->smb_name) {
1824                         DEBUG(10,("structure was created for %s\n",
1825                                   (*user_info)->smb_name));
1826                 }
1827                 SAFE_FREE((*user_info)->smb_name);
1828                 SAFE_FREE((*user_info)->internal_username);
1829                 SAFE_FREE((*user_info)->client_domain);
1830                 SAFE_FREE((*user_info)->domain);
1831                 SAFE_FREE((*user_info)->wksta_name);
1832                 data_blob_free(&(*user_info)->lm_resp);
1833                 data_blob_free(&(*user_info)->nt_resp);
1834                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1835                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1836                 data_blob_clear_free(&(*user_info)->plaintext_password);
1837                 ZERO_STRUCT(**user_info);
1838         }
1839         SAFE_FREE(*user_info);
1840 }
1841
1842 /***************************************************************************
1843  Make an auth_methods struct
1844 ***************************************************************************/
1845
1846 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
1847 {
1848         if (!auth_context) {
1849                 smb_panic("no auth_context supplied to "
1850                           "make_auth_methods()!\n");
1851         }
1852
1853         if (!auth_method) {
1854                 smb_panic("make_auth_methods: pointer to auth_method pointer "
1855                           "is NULL!\n");
1856         }
1857
1858         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1859         if (!*auth_method) {
1860                 DEBUG(0,("make_auth_method: malloc failed!\n"));
1861                 return False;
1862         }
1863         ZERO_STRUCTP(*auth_method);
1864         
1865         return True;
1866 }
1867
1868 /****************************************************************************
1869  Duplicate a SID token.
1870 ****************************************************************************/
1871
1872 NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, NT_USER_TOKEN *ptoken)
1873 {
1874         NT_USER_TOKEN *token;
1875
1876         if (!ptoken)
1877                 return NULL;
1878
1879         token = TALLOC_P(mem_ctx, NT_USER_TOKEN);
1880         if (token == NULL) {
1881                 DEBUG(0, ("talloc failed\n"));
1882                 return NULL;
1883         }
1884
1885         token->user_sids = talloc_memdup(token, ptoken->user_sids,
1886                                          sizeof(DOM_SID) * ptoken->num_sids );
1887
1888         if ((ptoken->user_sids != NULL) && (token->user_sids == NULL)) {
1889                 DEBUG(0, ("talloc_memdup failed\n"));
1890                 TALLOC_FREE(token);
1891                 return NULL;
1892         }
1893
1894         token->num_sids = ptoken->num_sids;
1895         
1896         /* copy the privileges; don't consider failure to be critical here */
1897         
1898         if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
1899                 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!.  "
1900                          "Continuing with 0 privileges assigned.\n"));
1901         }
1902
1903         return token;
1904 }
1905
1906 /****************************************************************************
1907  Check for a SID in an NT_USER_TOKEN
1908 ****************************************************************************/
1909
1910 BOOL nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
1911 {
1912         int i;
1913         
1914         if ( !sid || !token )
1915                 return False;
1916         
1917         for ( i=0; i<token->num_sids; i++ ) {
1918                 if ( sid_equal( sid, &token->user_sids[i] ) )
1919                         return True;
1920         }
1921
1922         return False;
1923 }
1924
1925 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid ) 
1926 {
1927         DOM_SID domain_sid;
1928
1929         /* if we are a domain member, the get the domain SID, else for 
1930            a DC or standalone server, use our own SID */
1931
1932         if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
1933                 if ( !secrets_fetch_domain_sid( lp_workgroup(),
1934                                                 &domain_sid ) ) {
1935                         DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
1936                                  "SID for domain [%s]\n", lp_workgroup()));
1937                         return False;
1938                 }
1939         } 
1940         else
1941                 sid_copy( &domain_sid, get_global_sam_sid() );
1942
1943         sid_append_rid( &domain_sid, rid );
1944         
1945         return nt_token_check_sid( &domain_sid, token );\
1946 }
1947
1948 /**
1949  * Verify whether or not given domain is trusted.
1950  *
1951  * @param domain_name name of the domain to be verified
1952  * @return true if domain is one of the trusted once or
1953  *         false if otherwise
1954  **/
1955
1956 BOOL is_trusted_domain(const char* dom_name)
1957 {
1958         DOM_SID trustdom_sid;
1959         BOOL ret;
1960
1961         /* no trusted domains for a standalone server */
1962
1963         if ( lp_server_role() == ROLE_STANDALONE )
1964                 return False;
1965
1966         /* if we are a DC, then check for a direct trust relationships */
1967
1968         if ( IS_DC ) {
1969                 become_root();
1970                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1971                           "[%s]\n", dom_name ));
1972                 ret = secrets_fetch_trusted_domain_password(dom_name, NULL,
1973                                                             NULL, NULL);
1974                 unbecome_root();
1975                 if (ret)
1976                         return True;
1977         }
1978         else {
1979                 NSS_STATUS result;
1980
1981                 /* If winbind is around, ask it */
1982
1983                 result = wb_is_trusted_domain(dom_name);
1984
1985                 if (result == NSS_STATUS_SUCCESS) {
1986                         return True;
1987                 }
1988
1989                 if (result == NSS_STATUS_NOTFOUND) {
1990                         /* winbind could not find the domain */
1991                         return False;
1992                 }
1993
1994                 /* The only other possible result is that winbind is not up
1995                    and running. We need to update the trustdom_cache
1996                    ourselves */
1997                 
1998                 update_trustdom_cache();
1999         }
2000
2001         /* now the trustdom cache should be available a DC could still
2002          * have a transitive trust so fall back to the cache of trusted
2003          * domains (like a domain member would use  */
2004
2005         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
2006                 return True;
2007         }
2008
2009         return False;
2010 }
2011