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