r15600: Correctly fill in the gid for local users.
[ira/wip.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         return NT_STATUS_OK;
692 }
693
694 /*******************************************************************
695 *******************************************************************/
696
697 static NTSTATUS create_builtin_users( void )
698 {
699         NTSTATUS status;
700         DOM_SID dom_users;
701
702         status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_USERS );
703         if ( !NT_STATUS_IS_OK(status) ) {
704                 DEBUG(0,("create_builtin_users: Failed to create Users\n"));
705                 return status;
706         }
707         
708         /* add domain users */
709         if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER)) 
710                 && secrets_fetch_domain_sid(lp_workgroup(), &dom_users))
711         {
712                 sid_append_rid(&dom_users, DOMAIN_GROUP_RID_USERS );
713                 status = pdb_add_aliasmem( &global_sid_Builtin_Users, &dom_users);
714                 if ( !NT_STATUS_IS_OK(status) ) {
715                         DEBUG(0,("create_builtin_administrators: Failed to add Domain Users to"
716                                 " Users\n"));
717                         return status;
718                 }
719         }
720                         
721         return NT_STATUS_OK;
722 }               
723
724 /*******************************************************************
725 *******************************************************************/
726
727 static NTSTATUS create_builtin_administrators( void )
728 {
729         NTSTATUS status;
730         DOM_SID dom_admins, root_sid;
731         fstring root_name;
732         enum SID_NAME_USE type;         
733         TALLOC_CTX *ctx;
734         BOOL ret;
735
736         status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_ADMINS );
737         if ( !NT_STATUS_IS_OK(status) ) {
738                 DEBUG(0,("create_builtin_administrators: Failed to create Administrators\n"));
739                 return status;
740         }
741         
742         /* add domain admins */
743         if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER)) 
744                 && secrets_fetch_domain_sid(lp_workgroup(), &dom_admins))
745         {
746                 sid_append_rid(&dom_admins, DOMAIN_GROUP_RID_ADMINS);
747                 status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &dom_admins );
748                 if ( !NT_STATUS_IS_OK(status) ) {
749                         DEBUG(0,("create_builtin_administrators: Failed to add Domain Admins"
750                                 " Administrators\n"));
751                         return status;
752                 }
753         }
754                         
755         /* add root */
756         if ( (ctx = talloc_init(NULL)) == NULL ) {
757                 return NT_STATUS_NO_MEMORY;
758         }
759         fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
760         ret = lookup_name( ctx, root_name, 0, NULL, NULL, &root_sid, &type );
761         TALLOC_FREE( ctx );
762
763         if ( ret ) {
764                 status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &root_sid );
765                 if ( !NT_STATUS_IS_OK(status) ) {
766                         DEBUG(0,("create_builtin_administrators: Failed to add root"
767                                 " Administrators\n"));
768                         return status;
769                 }
770         }
771         
772         return NT_STATUS_OK;
773 }               
774
775 /*******************************************************************
776  Create a NT token for the user, expanding local aliases
777 *******************************************************************/
778
779 static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
780                                                    const DOM_SID *user_sid,
781                                                    const DOM_SID *group_sid,
782                                                    BOOL is_guest,
783                                                    int num_groupsids,
784                                                    const DOM_SID *groupsids)
785 {
786         TALLOC_CTX *tmp_ctx;
787         struct nt_user_token *result = NULL;
788         int i;
789         NTSTATUS status;
790         gid_t gid;
791
792         tmp_ctx = talloc_new(mem_ctx);
793         if (tmp_ctx == NULL) {
794                 DEBUG(0, ("talloc_new failed\n"));
795                 return NULL;
796         }
797
798         result = TALLOC_ZERO_P(tmp_ctx, NT_USER_TOKEN);
799         if (result == NULL) {
800                 DEBUG(0, ("talloc failed\n"));
801                 goto done;
802         }
803
804         /* Add the user and primary group sid */
805
806         add_sid_to_array(result, user_sid,
807                          &result->user_sids, &result->num_sids);
808         add_sid_to_array(result, group_sid,
809                          &result->user_sids, &result->num_sids);
810                          
811         /* Add in BUILTIN sids */
812         
813         add_sid_to_array(result, &global_sid_World,
814                          &result->user_sids, &result->num_sids);
815         add_sid_to_array(result, &global_sid_Network,
816                          &result->user_sids, &result->num_sids);
817
818         if (is_guest) {
819                 add_sid_to_array(result, &global_sid_Builtin_Guests,
820                                  &result->user_sids, &result->num_sids);
821         } else {
822                 add_sid_to_array(result, &global_sid_Authenticated_Users,
823                                  &result->user_sids, &result->num_sids);
824         }
825         
826         /* Now the SIDs we got from authentication. These are the ones from
827          * the info3 struct or from the pdb_enum_group_memberships, depending
828          * on who authenticated the user. */
829
830         for (i=0; i<num_groupsids; i++) {
831                 add_sid_to_array_unique(result, &groupsids[i],
832                                         &result->user_sids, &result->num_sids);
833         }
834         
835         /* Deal with the BUILTIN\Administrators group.  If the SID can
836            be resolved then assume that the add_aliasmem( S-1-5-32 ) 
837            handled it. */
838
839         if ( !sid_to_gid( &global_sid_Builtin_Administrators, &gid ) ) {
840                 /* We can only create a mapping if winbind is running 
841                    and the nested group functionality has been enabled */
842                    
843                 if ( lp_winbind_nested_groups() && winbind_ping() ) {
844                         become_root();
845                         status = create_builtin_administrators( );
846                         if ( !NT_STATUS_IS_OK(status) ) {
847                                 DEBUG(0,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
848                                 /* don't fail, just log the message */
849                         }
850                         unbecome_root();
851                 }
852                 else {
853                         status = add_builtin_administrators( tmp_ctx, result ); 
854                         if ( !NT_STATUS_IS_OK(status) ) {                       
855                                 result = NULL;
856                                 goto done;
857                         }                       
858                 }               
859         }
860
861         /* Deal with the BUILTIN\Users group.  If the SID can
862            be resolved then assume that the add_aliasmem( S-1-5-32 ) 
863            handled it. */
864
865         if ( !sid_to_gid( &global_sid_Builtin_Users, &gid ) ) {
866                 /* We can only create a mapping if winbind is running 
867                    and the nested group functionality has been enabled */
868                    
869                 if ( lp_winbind_nested_groups() && winbind_ping() ) {
870                         become_root();
871                         status = create_builtin_users( );
872                         if ( !NT_STATUS_IS_OK(status) ) {
873                                 DEBUG(0,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
874                                 /* don't fail, just log the message */
875                         }
876                         unbecome_root();
877                 }
878         }
879
880         /* Deal with local groups */
881         
882         if (lp_winbind_nested_groups()) {
883
884                 /* Now add the aliases. First the one from our local SAM */
885
886                 status = add_aliases(tmp_ctx, get_global_sam_sid(), result);
887
888                 if (!NT_STATUS_IS_OK(status)) {
889                         result = NULL;
890                         goto done;
891                 }
892
893                 /* Finally the builtin ones */
894
895                 status = add_aliases(tmp_ctx, &global_sid_Builtin, result);
896
897                 if (!NT_STATUS_IS_OK(status)) {
898                         result = NULL;
899                         goto done;
900                 }
901         } 
902
903
904         get_privileges_for_sids(&result->privileges, result->user_sids,
905                                 result->num_sids);
906
907         talloc_steal(mem_ctx, result);
908
909  done:
910         TALLOC_FREE(tmp_ctx);
911         return result;
912 }
913
914 /*
915  * Create the token to use from server_info->sam_account and
916  * server_info->sids (the info3/sam groups). Find the unix gids.
917  */
918
919 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
920 {
921         TALLOC_CTX *mem_ctx;
922         NTSTATUS status;
923         size_t i;
924         
925
926         mem_ctx = talloc_new(NULL);
927         if (mem_ctx == NULL) {
928                 DEBUG(0, ("talloc_new failed\n"));
929                 return NT_STATUS_NO_MEMORY;
930         }
931
932         if (server_info->was_mapped) {
933                 status = create_token_from_username(server_info,
934                                                     server_info->unix_name,
935                                                     server_info->guest,
936                                                     &server_info->uid,
937                                                     &server_info->gid,
938                                                     &server_info->unix_name,
939                                                     &server_info->ptok);
940                 
941         } else {
942                 server_info->ptok = create_local_nt_token(
943                         server_info,
944                         pdb_get_user_sid(server_info->sam_account),
945                         pdb_get_group_sid(server_info->sam_account),
946                         server_info->guest,
947                         server_info->num_sids, server_info->sids);
948                 status = server_info->ptok ?
949                         NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
950         }
951
952         if (!NT_STATUS_IS_OK(status)) {
953                 TALLOC_FREE(mem_ctx);
954                 return status;
955         }
956         
957         /* Convert the SIDs to gids. */
958
959         server_info->n_groups = 0;
960         server_info->groups = NULL;
961
962         /* Start at index 1, where the groups start. */
963
964         for (i=1; i<server_info->ptok->num_sids; i++) {
965                 gid_t gid;
966                 DOM_SID *sid = &server_info->ptok->user_sids[i];
967
968                 if (!sid_to_gid(sid, &gid)) {
969                         DEBUG(10, ("Could not convert SID %s to gid, "
970                                    "ignoring it\n", sid_string_static(sid)));
971                         continue;
972                 }
973                 add_gid_to_array_unique(server_info, gid, &server_info->groups,
974                                         &server_info->n_groups);
975         }
976         
977         debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
978
979         status = log_nt_token(mem_ctx, server_info->ptok);
980
981         TALLOC_FREE(mem_ctx);
982         return status;
983 }
984
985 /*
986  * Create an artificial NT token given just a username. (Initially indended
987  * for force user)
988  *
989  * We go through lookup_name() to avoid problems we had with 'winbind use
990  * default domain'.
991  *
992  * We have 3 cases:
993  *
994  * unmapped unix users: Go directly to nss to find the user's group.
995  *
996  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
997  *
998  * If the user is provided by winbind, the primary gid is set to "domain
999  * users" of the user's domain. For an explanation why this is necessary, see
1000  * the thread starting at
1001  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
1002  */
1003
1004 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
1005                                     BOOL is_guest,
1006                                     uid_t *uid, gid_t *gid,
1007                                     char **found_username,
1008                                     struct nt_user_token **token)
1009 {
1010         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
1011         TALLOC_CTX *tmp_ctx;
1012         DOM_SID user_sid;
1013         enum SID_NAME_USE type;
1014         gid_t *gids;
1015         DOM_SID primary_group_sid;
1016         DOM_SID *group_sids;
1017         size_t num_group_sids;
1018
1019         tmp_ctx = talloc_new(NULL);
1020         if (tmp_ctx == NULL) {
1021                 DEBUG(0, ("talloc_new failed\n"));
1022                 return NT_STATUS_NO_MEMORY;
1023         }
1024
1025         if (!lookup_name(tmp_ctx, username, LOOKUP_NAME_ALL,
1026                          NULL, NULL, &user_sid, &type)) {
1027                 DEBUG(1, ("lookup_name for %s failed\n", username));
1028                 goto done;
1029         }
1030
1031         if (type != SID_NAME_USER) {
1032                 DEBUG(1, ("%s is a %s, not a user\n", username,
1033                           sid_type_lookup(type)));
1034                 goto done;
1035         }
1036
1037         if (!sid_to_uid(&user_sid, uid)) {
1038                 DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
1039                           username, sid_string_static(&user_sid)));
1040                 goto done;
1041         }
1042
1043         if (sid_check_is_in_unix_users(&user_sid)) {
1044
1045                 /* This is a unix user not in passdb. We need to ask nss
1046                  * directly, without consulting passdb */
1047
1048                 struct passwd *pass;
1049                 size_t i;
1050
1051                 pass = getpwuid_alloc(tmp_ctx, *uid);
1052                 if (pass == NULL) {
1053                         DEBUG(1, ("getpwuid(%d) for user %s failed\n",
1054                                   *uid, username));
1055                         goto done;
1056                 }
1057
1058                 *gid = pass->pw_gid;
1059                 gid_to_sid(&primary_group_sid, pass->pw_gid);
1060
1061                 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
1062                                          &gids, &num_group_sids)) {
1063                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
1064                                   username));
1065                         goto done;
1066                 }
1067
1068                 group_sids = talloc_array(tmp_ctx, DOM_SID, num_group_sids);
1069                 if (group_sids == NULL) {
1070                         DEBUG(1, ("talloc_array failed\n"));
1071                         result = NT_STATUS_NO_MEMORY;
1072                         goto done;
1073                 }
1074
1075                 for (i=0; i<num_group_sids; i++) {
1076                         gid_to_sid(&group_sids[i], gids[i]);
1077                 }
1078                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
1079
1080         } else if (sid_check_is_in_our_domain(&user_sid)) {
1081
1082                 /* This is a passdb user, so ask passdb */
1083
1084                 struct samu *sam_acct = NULL;
1085
1086                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
1087                         goto done;
1088                 }
1089
1090                 if (!pdb_getsampwsid(sam_acct, &user_sid)) {
1091                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
1092                                   sid_string_static(&user_sid), username));
1093                         result = NT_STATUS_NO_SUCH_USER;
1094                         goto done;
1095                 }
1096
1097                 sid_copy(&primary_group_sid, pdb_get_group_sid(sam_acct));
1098
1099                 if (!sid_to_gid(&primary_group_sid, gid)) {
1100                         DEBUG(1, ("sid_to_gid(%s) failed\n",
1101                                   sid_string_static(&primary_group_sid)));
1102                         goto done;
1103                 }
1104
1105                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
1106                                                     &group_sids, &gids,
1107                                                     &num_group_sids);
1108                 if (!NT_STATUS_IS_OK(result)) {
1109                         DEBUG(10, ("enum_group_memberships failed for %s\n",
1110                                    username));
1111                         goto done;
1112                 }
1113
1114                 *found_username = talloc_strdup(mem_ctx,
1115                                                 pdb_get_username(sam_acct));
1116
1117         } else {
1118
1119                 /* This user is from winbind, force the primary gid to the
1120                  * user's "domain users" group. Under certain circumstances
1121                  * (user comes from NT4), this might be a loss of
1122                  * information. But we can not rely on winbind getting the
1123                  * correct info. AD might prohibit winbind looking up that
1124                  * information. */
1125
1126                 uint32 dummy;
1127
1128                 sid_copy(&primary_group_sid, &user_sid);
1129                 sid_split_rid(&primary_group_sid, &dummy);
1130                 sid_append_rid(&primary_group_sid, DOMAIN_GROUP_RID_USERS);
1131
1132                 if (!sid_to_gid(&primary_group_sid, gid)) {
1133                         DEBUG(1, ("sid_to_gid(%s) failed\n",
1134                                   sid_string_static(&primary_group_sid)));
1135                         goto done;
1136                 }
1137
1138                 num_group_sids = 0;
1139                 group_sids = NULL;
1140
1141                 *found_username = talloc_strdup(mem_ctx, username);
1142         }
1143
1144         *token = create_local_nt_token(mem_ctx, &user_sid, &primary_group_sid,
1145                                        is_guest, num_group_sids, group_sids);
1146
1147         if ((*token == NULL) || (*found_username == NULL)) {
1148                 result = NT_STATUS_NO_MEMORY;
1149                 goto done;
1150         }
1151
1152         result = NT_STATUS_OK;
1153  done:
1154         TALLOC_FREE(tmp_ctx);
1155         return result;
1156 }
1157
1158 /***************************************************************************
1159  Build upon create_token_from_username:
1160
1161  Expensive helper function to figure out whether a user given its name is
1162  member of a particular group.
1163 ***************************************************************************/
1164 BOOL user_in_group_sid(const char *username, const DOM_SID *group_sid)
1165 {
1166         NTSTATUS status;
1167         uid_t uid;
1168         gid_t gid;
1169         char *found_username;
1170         struct nt_user_token *token;
1171         BOOL result;
1172
1173         TALLOC_CTX *mem_ctx;
1174
1175         mem_ctx = talloc_new(NULL);
1176         if (mem_ctx == NULL) {
1177                 DEBUG(0, ("talloc_new failed\n"));
1178                 return False;
1179         }
1180
1181         status = create_token_from_username(mem_ctx, username, False,
1182                                             &uid, &gid, &found_username,
1183                                             &token);
1184
1185         if (!NT_STATUS_IS_OK(status)) {
1186                 DEBUG(10, ("could not create token for %s\n", username));
1187                 return False;
1188         }
1189
1190         result = nt_token_check_sid(group_sid, token);
1191
1192         TALLOC_FREE(mem_ctx);
1193         return result;
1194         
1195 }
1196
1197 BOOL user_in_group(const char *username, const char *groupname)
1198 {
1199         TALLOC_CTX *mem_ctx;
1200         DOM_SID group_sid;
1201         NTSTATUS status;
1202         BOOL ret;
1203
1204         mem_ctx = talloc_new(NULL);
1205         if (mem_ctx == NULL) {
1206                 DEBUG(0, ("talloc_new failed\n"));
1207                 return False;
1208         }
1209
1210         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1211                           NULL, NULL, &group_sid, NULL);
1212         TALLOC_FREE(mem_ctx);
1213
1214         if (!ret) {
1215                 DEBUG(10, ("lookup_name(%s) failed: %s\n", groupname,
1216                            nt_errstr(status)));
1217                 return False;
1218         }
1219
1220         return user_in_group_sid(username, &group_sid);
1221 }
1222
1223
1224 /***************************************************************************
1225  Make (and fill) a user_info struct from a 'struct passwd' by conversion 
1226  to a struct samu
1227 ***************************************************************************/
1228
1229 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 
1230                              char *unix_username,
1231                              struct passwd *pwd)
1232 {
1233         NTSTATUS status;
1234         struct samu *sampass = NULL;
1235         gid_t *gids;
1236         auth_serversupplied_info *result;
1237         
1238         if ( !(sampass = samu_new( NULL )) ) {
1239                 return NT_STATUS_NO_MEMORY;
1240         }
1241         
1242         status = samu_set_unix( sampass, pwd );
1243         if (!NT_STATUS_IS_OK(status)) {
1244                 return status;
1245         }
1246
1247         result = make_server_info(NULL);
1248
1249         if (!NT_STATUS_IS_OK(status)) {
1250                 TALLOC_FREE(sampass);
1251                 return status;
1252         }
1253
1254         result->sam_account = sampass;
1255         result->unix_name = talloc_strdup(result, unix_username);
1256         result->uid = pwd->pw_uid;
1257         result->gid = pwd->pw_gid;
1258
1259         status = pdb_enum_group_memberships(result, sampass,
1260                                             &result->sids, &gids,
1261                                             &result->num_sids);
1262
1263         if (!NT_STATUS_IS_OK(status)) {
1264                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1265                            nt_errstr(status)));
1266                 TALLOC_FREE(result);
1267                 return status;
1268         }
1269
1270         /* For now we throw away the gids and convert via sid_to_gid
1271          * later. This needs fixing, but I'd like to get the code straight and
1272          * simple first. */
1273         TALLOC_FREE(gids);
1274
1275         *server_info = result;
1276
1277         return NT_STATUS_OK;
1278 }
1279
1280 /***************************************************************************
1281  Make (and fill) a user_info struct for a guest login.
1282  This *must* succeed for smbd to start. If there is no mapping entry for
1283  the guest gid, then create one.
1284 **********************
1285 *****************************************************/
1286
1287 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1288 {
1289         NTSTATUS status;
1290         struct samu *sampass = NULL;
1291         DOM_SID guest_sid;
1292         BOOL ret;
1293         static const char zeros[16];
1294
1295         if ( !(sampass = samu_new( NULL )) ) {
1296                 return NT_STATUS_NO_MEMORY;
1297         }
1298
1299         sid_copy(&guest_sid, get_global_sam_sid());
1300         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1301
1302         become_root();
1303         ret = pdb_getsampwsid(sampass, &guest_sid);
1304         unbecome_root();
1305
1306         if (!ret) {
1307                 TALLOC_FREE(sampass);
1308                 return NT_STATUS_NO_SUCH_USER;
1309         }
1310
1311         status = make_server_info_sam(server_info, sampass);
1312         if (!NT_STATUS_IS_OK(status)) {
1313                 TALLOC_FREE(sampass);
1314                 return status;
1315         }
1316         
1317         (*server_info)->guest = True;
1318
1319         status = create_local_token(*server_info);
1320         if (!NT_STATUS_IS_OK(status)) {
1321                 DEBUG(10, ("create_local_token failed: %s\n",
1322                            nt_errstr(status)));
1323                 return status;
1324         }
1325
1326         /* annoying, but the Guest really does have a session key, and it is
1327            all zeros! */
1328         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1329         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1330
1331         return NT_STATUS_OK;
1332 }
1333
1334 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
1335 {
1336         auth_serversupplied_info *dst;
1337
1338         dst = make_server_info(NULL);
1339         if (dst == NULL) {
1340                 return NULL;
1341         }
1342
1343         dst->guest = src->guest;
1344         dst->uid = src->uid;
1345         dst->gid = src->gid;
1346         dst->n_groups = src->n_groups;
1347         if (src->n_groups != 0)
1348                 dst->groups = talloc_memdup(dst, src->groups,
1349                                             sizeof(gid_t)*dst->n_groups);
1350         else
1351                 dst->groups = NULL;
1352                 
1353         dst->ptok = dup_nt_token(dst, src->ptok);
1354         
1355         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1356                 src->user_session_key.length);
1357                 
1358         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1359                 src->lm_session_key.length);
1360                 
1361         if ( (dst->sam_account = samu_new( NULL )) != NULL )
1362                 pdb_copy_sam_account(dst->sam_account, src->sam_account);
1363         
1364         dst->pam_handle = NULL;
1365         dst->unix_name = talloc_strdup(dst, src->unix_name);
1366
1367         return dst;
1368 }
1369
1370 static auth_serversupplied_info *guest_info = NULL;
1371
1372 BOOL init_guest_info(void)
1373 {
1374         if (guest_info != NULL)
1375                 return True;
1376
1377         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1378 }
1379
1380 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
1381 {
1382         *server_info = copy_serverinfo(guest_info);
1383         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1384 }
1385
1386 /***************************************************************************
1387  Purely internal function for make_server_info_info3
1388  Fill the sam account from getpwnam
1389 ***************************************************************************/
1390 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
1391                                  const char *domain,
1392                                  const char *username,
1393                                  char **found_username,
1394                                  uid_t *uid, gid_t *gid,
1395                                  struct samu *account,
1396                                  BOOL *username_was_mapped)
1397 {
1398         NTSTATUS nt_status;
1399         fstring dom_user, lower_username;
1400         fstring real_username;
1401         struct passwd *passwd;
1402
1403         fstrcpy( lower_username, username );
1404         strlower_m( lower_username );
1405
1406         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1407                 lower_username);
1408
1409         /* Get the passwd struct.  Try to create the account is necessary. */
1410
1411         *username_was_mapped = map_username( dom_user );
1412
1413         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1414                 return NT_STATUS_NO_SUCH_USER;
1415
1416         *uid = passwd->pw_uid;
1417         *gid = passwd->pw_gid;
1418
1419         /* This is pointless -- there is no suport for differing 
1420            unix and windows names.  Make sure to always store the 
1421            one we actually looked up and succeeded. Have I mentioned
1422            why I hate the 'winbind use default domain' parameter?   
1423                                          --jerry              */
1424            
1425         *found_username = talloc_strdup( mem_ctx, real_username );
1426         
1427         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1428
1429         nt_status = samu_set_unix( account, passwd );
1430         
1431         TALLOC_FREE(passwd);
1432         
1433         return nt_status;
1434 }
1435
1436 /****************************************************************************
1437  Wrapper to allow the getpwnam() call to strip the domain name and 
1438  try again in case a local UNIX user is already there.  Also run through 
1439  the username if we fallback to the username only.
1440  ****************************************************************************/
1441  
1442 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1443                              fstring save_username, BOOL create )
1444 {
1445         struct passwd *pw = NULL;
1446         char *p;
1447         fstring username;
1448         
1449         /* we only save a copy of the username it has been mangled 
1450            by winbindd use default domain */
1451            
1452         save_username[0] = '\0';
1453            
1454         /* don't call map_username() here since it has to be done higher 
1455            up the stack so we don't call it mutliple times */
1456
1457         fstrcpy( username, domuser );
1458         
1459         p = strchr_m( username, *lp_winbind_separator() );
1460         
1461         /* code for a DOMAIN\user string */
1462         
1463         if ( p ) {
1464                 fstring strip_username;
1465
1466                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1467                 if ( pw ) {     
1468                         /* make sure we get the case of the username correct */
1469                         /* work around 'winbind use default domain = yes' */
1470
1471                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1472                                 char *domain;
1473                                 
1474                                 /* split the domain and username into 2 strings */
1475                                 *p = '\0';
1476                                 domain = username;
1477
1478                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1479                         }
1480                         else
1481                                 fstrcpy( save_username, pw->pw_name );
1482
1483                         /* whew -- done! */             
1484                         return pw;
1485                 }
1486
1487                 /* setup for lookup of just the username */
1488                 /* remember that p and username are overlapping memory */
1489
1490                 p++;
1491                 fstrcpy( strip_username, p );
1492                 fstrcpy( username, strip_username );
1493         }
1494         
1495         /* just lookup a plain username */
1496         
1497         pw = Get_Pwnam_alloc(mem_ctx, username);
1498                 
1499         /* Create local user if requested but only if winbindd
1500            is not running.  We need to protect against cases
1501            where winbindd is failing and then prematurely
1502            creating users in /etc/passwd */
1503         
1504         if ( !pw && create && !winbind_ping() ) {
1505                 /* Don't add a machine account. */
1506                 if (username[strlen(username)-1] == '$')
1507                         return NULL;
1508
1509                 smb_create_user(NULL, username, NULL);
1510                 pw = Get_Pwnam_alloc(mem_ctx, username);
1511         }
1512         
1513         /* one last check for a valid passwd struct */
1514         
1515         if ( pw )
1516                 fstrcpy( save_username, pw->pw_name );
1517
1518         return pw;
1519 }
1520
1521 /***************************************************************************
1522  Make a server_info struct from the info3 returned by a domain logon 
1523 ***************************************************************************/
1524
1525 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1526                                 const char *sent_nt_username,
1527                                 const char *domain,
1528                                 auth_serversupplied_info **server_info, 
1529                                 NET_USER_INFO_3 *info3) 
1530 {
1531         static const char zeros[16];
1532
1533         NTSTATUS nt_status = NT_STATUS_OK;
1534         char *found_username;
1535         const char *nt_domain;
1536         const char *nt_username;
1537         struct samu *sam_account = NULL;
1538         DOM_SID user_sid;
1539         DOM_SID group_sid;
1540         BOOL username_was_mapped;
1541
1542         uid_t uid;
1543         gid_t gid;
1544
1545         size_t i;
1546
1547         auth_serversupplied_info *result;
1548
1549         /* 
1550            Here is where we should check the list of
1551            trusted domains, and verify that the SID 
1552            matches.
1553         */
1554
1555         sid_copy(&user_sid, &info3->dom_sid.sid);
1556         if (!sid_append_rid(&user_sid, info3->user_rid)) {
1557                 return NT_STATUS_INVALID_PARAMETER;
1558         }
1559         
1560         sid_copy(&group_sid, &info3->dom_sid.sid);
1561         if (!sid_append_rid(&group_sid, info3->group_rid)) {
1562                 return NT_STATUS_INVALID_PARAMETER;
1563         }
1564
1565         if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1566                 /* If the server didn't give us one, just use the one we sent
1567                  * them */
1568                 nt_username = sent_nt_username;
1569         }
1570
1571         if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1572                 /* If the server didn't give us one, just use the one we sent
1573                  * them */
1574                 nt_domain = domain;
1575         }
1576         
1577         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1578            add user script (2.2.x behavior).
1579
1580            We use the _unmapped_ username here in an attempt to provide
1581            consistent username mapping behavior between kerberos and NTLM[SSP]
1582            authentication in domain mode security.  I.E. Username mapping
1583            should be applied to the fully qualified username
1584            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1585            called map_username() unnecessarily in make_user_info_map() but
1586            that is how the current code is designed.  Making the change here
1587            is the least disruptive place.  -- jerry */
1588            
1589         if ( !(sam_account = samu_new( NULL )) ) {
1590                 return NT_STATUS_NO_MEMORY;
1591         }
1592
1593         /* this call will try to create the user if necessary */
1594
1595         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1596                                      &found_username, &uid, &gid, sam_account,
1597                                      &username_was_mapped);
1598
1599         
1600         /* if we still don't have a valid unix account check for 
1601           'map to guest = bad uid' */
1602           
1603         if (!NT_STATUS_IS_OK(nt_status)) {
1604                 TALLOC_FREE( sam_account );
1605                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1606                         make_server_info_guest(server_info); 
1607                         return NT_STATUS_OK;
1608                 }
1609                 return nt_status;
1610         }
1611                 
1612         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1613                 TALLOC_FREE(sam_account);
1614                 return NT_STATUS_NO_MEMORY;
1615         }
1616
1617         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1618                 TALLOC_FREE(sam_account);
1619                 return NT_STATUS_NO_MEMORY;
1620         }
1621
1622         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1623                 TALLOC_FREE(sam_account);
1624                 return NT_STATUS_NO_MEMORY;
1625         }
1626
1627         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1628                 TALLOC_FREE(sam_account);
1629                 return NT_STATUS_UNSUCCESSFUL;
1630         }
1631
1632         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1633                 TALLOC_FREE(sam_account);
1634                 return NT_STATUS_UNSUCCESSFUL;
1635         }
1636                 
1637         if (!pdb_set_fullname(sam_account,
1638                               unistr2_static(&(info3->uni_full_name)), 
1639                               PDB_CHANGED)) {
1640                 TALLOC_FREE(sam_account);
1641                 return NT_STATUS_NO_MEMORY;
1642         }
1643
1644         if (!pdb_set_logon_script(sam_account,
1645                                   unistr2_static(&(info3->uni_logon_script)),
1646                                   PDB_CHANGED)) {
1647                 TALLOC_FREE(sam_account);
1648                 return NT_STATUS_NO_MEMORY;
1649         }
1650
1651         if (!pdb_set_profile_path(sam_account,
1652                                   unistr2_static(&(info3->uni_profile_path)),
1653                                   PDB_CHANGED)) {
1654                 TALLOC_FREE(sam_account);
1655                 return NT_STATUS_NO_MEMORY;
1656         }
1657
1658         if (!pdb_set_homedir(sam_account,
1659                              unistr2_static(&(info3->uni_home_dir)),
1660                              PDB_CHANGED)) {
1661                 TALLOC_FREE(sam_account);
1662                 return NT_STATUS_NO_MEMORY;
1663         }
1664
1665         if (!pdb_set_dir_drive(sam_account,
1666                                unistr2_static(&(info3->uni_dir_drive)),
1667                                PDB_CHANGED)) {
1668                 TALLOC_FREE(sam_account);
1669                 return NT_STATUS_NO_MEMORY;
1670         }
1671
1672         if (!pdb_set_acct_ctrl(sam_account, info3->acct_flags, PDB_CHANGED)) {
1673                 TALLOC_FREE(sam_account);
1674                 return NT_STATUS_NO_MEMORY;
1675         }
1676
1677         result = make_server_info(NULL);
1678         if (result == NULL) {
1679                 DEBUG(4, ("make_server_info failed!\n"));
1680                 TALLOC_FREE(sam_account);
1681                 return NT_STATUS_NO_MEMORY;
1682         }
1683
1684         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1685            valid struct samu) */
1686                    
1687         result->sam_account = sam_account;
1688         result->unix_name = talloc_strdup(result, found_username);
1689
1690         /* Fill in the unix info we found on the way */
1691
1692         result->uid = uid;
1693         result->gid = gid;
1694
1695         /* Create a 'combined' list of all SIDs we might want in the SD */
1696
1697         result->num_sids = 0;
1698         result->sids = NULL;
1699
1700         /* and create (by appending rids) the 'domain' sids */
1701         
1702         for (i = 0; i < info3->num_groups2; i++) {
1703                 DOM_SID sid;
1704                 if (!sid_compose(&sid, &info3->dom_sid.sid,
1705                                  info3->gids[i].g_rid)) {
1706                         DEBUG(3,("could not append additional group rid "
1707                                  "0x%x\n", info3->gids[i].g_rid));
1708                         TALLOC_FREE(result);
1709                         return NT_STATUS_INVALID_PARAMETER;
1710                 }
1711                 add_sid_to_array(result, &sid, &result->sids,
1712                                  &result->num_sids);
1713         }
1714
1715         /* Copy 'other' sids.  We need to do sid filtering here to
1716            prevent possible elevation of privileges.  See:
1717
1718            http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
1719          */
1720
1721         for (i = 0; i < info3->num_other_sids; i++) {
1722                 add_sid_to_array(result, &info3->other_sids[i].sid,
1723                                  &result->sids,
1724                                  &result->num_sids);
1725         }
1726
1727         result->login_server = unistr2_tdup(result, 
1728                                             &(info3->uni_logon_srv));
1729
1730         /* ensure we are never given NULL session keys */
1731         
1732         if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
1733                 result->user_session_key = data_blob(NULL, 0);
1734         } else {
1735                 result->user_session_key = data_blob_talloc(
1736                         result, info3->user_sess_key,
1737                         sizeof(info3->user_sess_key));
1738         }
1739
1740         if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
1741                 result->lm_session_key = data_blob(NULL, 0);
1742         } else {
1743                 result->lm_session_key = data_blob_talloc(
1744                         result, info3->lm_sess_key,
1745                         sizeof(info3->lm_sess_key));
1746         }
1747
1748         result->was_mapped = username_was_mapped;
1749
1750         *server_info = result;
1751
1752         return NT_STATUS_OK;
1753 }
1754
1755 /***************************************************************************
1756  Free a user_info struct
1757 ***************************************************************************/
1758
1759 void free_user_info(auth_usersupplied_info **user_info)
1760 {
1761         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1762         if (*user_info != NULL) {
1763                 if ((*user_info)->smb_name) {
1764                         DEBUG(10,("structure was created for %s\n",
1765                                   (*user_info)->smb_name));
1766                 }
1767                 SAFE_FREE((*user_info)->smb_name);
1768                 SAFE_FREE((*user_info)->internal_username);
1769                 SAFE_FREE((*user_info)->client_domain);
1770                 SAFE_FREE((*user_info)->domain);
1771                 SAFE_FREE((*user_info)->wksta_name);
1772                 data_blob_free(&(*user_info)->lm_resp);
1773                 data_blob_free(&(*user_info)->nt_resp);
1774                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1775                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1776                 data_blob_clear_free(&(*user_info)->plaintext_password);
1777                 ZERO_STRUCT(**user_info);
1778         }
1779         SAFE_FREE(*user_info);
1780 }
1781
1782 /***************************************************************************
1783  Make an auth_methods struct
1784 ***************************************************************************/
1785
1786 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
1787 {
1788         if (!auth_context) {
1789                 smb_panic("no auth_context supplied to "
1790                           "make_auth_methods()!\n");
1791         }
1792
1793         if (!auth_method) {
1794                 smb_panic("make_auth_methods: pointer to auth_method pointer "
1795                           "is NULL!\n");
1796         }
1797
1798         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1799         if (!*auth_method) {
1800                 DEBUG(0,("make_auth_method: malloc failed!\n"));
1801                 return False;
1802         }
1803         ZERO_STRUCTP(*auth_method);
1804         
1805         return True;
1806 }
1807
1808 /****************************************************************************
1809  Duplicate a SID token.
1810 ****************************************************************************/
1811
1812 NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, NT_USER_TOKEN *ptoken)
1813 {
1814         NT_USER_TOKEN *token;
1815
1816         if (!ptoken)
1817                 return NULL;
1818
1819         token = TALLOC_P(mem_ctx, NT_USER_TOKEN);
1820         if (token == NULL) {
1821                 DEBUG(0, ("talloc failed\n"));
1822                 return NULL;
1823         }
1824
1825         token->user_sids = talloc_memdup(token, ptoken->user_sids,
1826                                          sizeof(DOM_SID) * ptoken->num_sids );
1827
1828         if ((ptoken->user_sids != NULL) && (token->user_sids == NULL)) {
1829                 DEBUG(0, ("talloc_memdup failed\n"));
1830                 TALLOC_FREE(token);
1831                 return NULL;
1832         }
1833
1834         token->num_sids = ptoken->num_sids;
1835         
1836         /* copy the privileges; don't consider failure to be critical here */
1837         
1838         if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
1839                 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!.  "
1840                          "Continuing with 0 privileges assigned.\n"));
1841         }
1842
1843         return token;
1844 }
1845
1846 /****************************************************************************
1847  Check for a SID in an NT_USER_TOKEN
1848 ****************************************************************************/
1849
1850 BOOL nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
1851 {
1852         int i;
1853         
1854         if ( !sid || !token )
1855                 return False;
1856         
1857         for ( i=0; i<token->num_sids; i++ ) {
1858                 if ( sid_equal( sid, &token->user_sids[i] ) )
1859                         return True;
1860         }
1861
1862         return False;
1863 }
1864
1865 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid ) 
1866 {
1867         DOM_SID domain_sid;
1868
1869         /* if we are a domain member, the get the domain SID, else for 
1870            a DC or standalone server, use our own SID */
1871
1872         if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
1873                 if ( !secrets_fetch_domain_sid( lp_workgroup(),
1874                                                 &domain_sid ) ) {
1875                         DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
1876                                  "SID for domain [%s]\n", lp_workgroup()));
1877                         return False;
1878                 }
1879         } 
1880         else
1881                 sid_copy( &domain_sid, get_global_sam_sid() );
1882
1883         sid_append_rid( &domain_sid, rid );
1884         
1885         return nt_token_check_sid( &domain_sid, token );\
1886 }
1887
1888 /**
1889  * Verify whether or not given domain is trusted.
1890  *
1891  * @param domain_name name of the domain to be verified
1892  * @return true if domain is one of the trusted once or
1893  *         false if otherwise
1894  **/
1895
1896 BOOL is_trusted_domain(const char* dom_name)
1897 {
1898         DOM_SID trustdom_sid;
1899         BOOL ret;
1900
1901         /* no trusted domains for a standalone server */
1902
1903         if ( lp_server_role() == ROLE_STANDALONE )
1904                 return False;
1905
1906         /* if we are a DC, then check for a direct trust relationships */
1907
1908         if ( IS_DC ) {
1909                 become_root();
1910                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1911                           "[%s]\n", dom_name ));
1912                 ret = secrets_fetch_trusted_domain_password(dom_name, NULL,
1913                                                             NULL, NULL);
1914                 unbecome_root();
1915                 if (ret)
1916                         return True;
1917         }
1918         else {
1919                 NSS_STATUS result;
1920
1921                 /* If winbind is around, ask it */
1922
1923                 result = wb_is_trusted_domain(dom_name);
1924
1925                 if (result == NSS_STATUS_SUCCESS) {
1926                         return True;
1927                 }
1928
1929                 if (result == NSS_STATUS_NOTFOUND) {
1930                         /* winbind could not find the domain */
1931                         return False;
1932                 }
1933
1934                 /* The only other possible result is that winbind is not up
1935                    and running. We need to update the trustdom_cache
1936                    ourselves */
1937                 
1938                 update_trustdom_cache();
1939         }
1940
1941         /* now the trustdom cache should be available a DC could still
1942          * have a transitive trust so fall back to the cache of trusted
1943          * domains (like a domain member would use  */
1944
1945         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1946                 return True;
1947         }
1948
1949         return False;
1950 }
1951