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