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