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