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