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