b401409f6c7804898aa0f0dfbf4e8b6ef9fc5125
[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 #include "auth.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../lib/crypto/arcfour.h"
28 #include "rpc_client/init_lsa.h"
29 #include "../libcli/security/security.h"
30 #include "../lib/util/util_pw.h"
31 #include "lib/winbind_util.h"
32 #include "passdb.h"
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_AUTH
36
37 /****************************************************************************
38  Create a UNIX user on demand.
39 ****************************************************************************/
40
41 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
42 {
43         TALLOC_CTX *ctx = talloc_tos();
44         char *add_script;
45         int ret;
46
47         add_script = talloc_strdup(ctx, lp_adduser_script());
48         if (!add_script || !*add_script) {
49                 return -1;
50         }
51         add_script = talloc_all_string_sub(ctx,
52                                 add_script,
53                                 "%u",
54                                 unix_username);
55         if (!add_script) {
56                 return -1;
57         }
58         if (domain) {
59                 add_script = talloc_all_string_sub(ctx,
60                                         add_script,
61                                         "%D",
62                                         domain);
63                 if (!add_script) {
64                         return -1;
65                 }
66         }
67         if (homedir) {
68                 add_script = talloc_all_string_sub(ctx,
69                                 add_script,
70                                 "%H",
71                                 homedir);
72                 if (!add_script) {
73                         return -1;
74                 }
75         }
76         ret = smbrun(add_script,NULL);
77         flush_pwnam_cache();
78         DEBUG(ret ? 0 : 3,
79                 ("smb_create_user: Running the command `%s' gave %d\n",
80                  add_script,ret));
81         return ret;
82 }
83
84 /****************************************************************************
85  Create an auth_usersupplied_data structure after appropriate mapping.
86 ****************************************************************************/
87
88 NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info,
89                             const char *smb_name,
90                             const char *client_domain,
91                             const char *workstation_name,
92                             DATA_BLOB *lm_pwd,
93                             DATA_BLOB *nt_pwd,
94                             const struct samr_Password *lm_interactive_pwd,
95                             const struct samr_Password *nt_interactive_pwd,
96                             const char *plaintext,
97                             enum auth_password_state password_state)
98 {
99         const char *domain;
100         NTSTATUS result;
101         bool was_mapped;
102         char *internal_username = NULL;
103
104         was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
105         if (!internal_username) {
106                 return NT_STATUS_NO_MEMORY;
107         }
108
109         DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
110                  client_domain, smb_name, workstation_name));
111
112         domain = client_domain;
113
114         /* If you connect to a Windows domain member using a bogus domain name,
115          * the Windows box will map the BOGUS\user to SAMNAME\user.  Thus, if
116          * the Windows box is a DC the name will become DOMAIN\user and be
117          * authenticated against AD, if the Windows box is a member server but
118          * not a DC the name will become WORKSTATION\user.  A standalone
119          * non-domain member box will also map to WORKSTATION\user.
120          * This also deals with the client passing in a "" domain */
121
122         if (!is_trusted_domain(domain) &&
123             !strequal(domain, my_sam_name()))
124         {
125                 if (lp_map_untrusted_to_domain())
126                         domain = my_sam_name();
127                 else
128                         domain = get_global_sam_name();
129                 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
130                           "workstation [%s]\n",
131                           client_domain, domain, smb_name, workstation_name));
132         }
133
134         /* We know that the given domain is trusted (and we are allowing them),
135          * it is our global SAM name, or for legacy behavior it is our
136          * primary domain name */
137
138         result = make_user_info(user_info, smb_name, internal_username,
139                               client_domain, domain, workstation_name,
140                               lm_pwd, nt_pwd,
141                               lm_interactive_pwd, nt_interactive_pwd,
142                               plaintext, password_state);
143         if (NT_STATUS_IS_OK(result)) {
144                 /* We have tried mapping */
145                 (*user_info)->mapped_state = True;
146                 /* did we actually map the user to a different name? */
147                 (*user_info)->was_mapped = was_mapped;
148         }
149         return result;
150 }
151
152 /****************************************************************************
153  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
154  Decrypt and encrypt the passwords.
155 ****************************************************************************/
156
157 bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info,
158                                      const char *smb_name, 
159                                      const char *client_domain, 
160                                      const char *workstation_name,
161                                      uint32 logon_parameters,
162                                      const uchar *lm_network_pwd,
163                                      int lm_pwd_len,
164                                      const uchar *nt_network_pwd,
165                                      int nt_pwd_len)
166 {
167         bool ret;
168         NTSTATUS status;
169         DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
170         DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
171
172         status = make_user_info_map(user_info,
173                                     smb_name, client_domain, 
174                                     workstation_name,
175                                     lm_pwd_len ? &lm_blob : NULL, 
176                                     nt_pwd_len ? &nt_blob : NULL,
177                                     NULL, NULL, NULL,
178                                     AUTH_PASSWORD_RESPONSE);
179
180         if (NT_STATUS_IS_OK(status)) {
181                 (*user_info)->logon_parameters = logon_parameters;
182         }
183         ret = NT_STATUS_IS_OK(status) ? True : False;
184
185         data_blob_free(&lm_blob);
186         data_blob_free(&nt_blob);
187         return ret;
188 }
189
190 /****************************************************************************
191  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
192  Decrypt and encrypt the passwords.
193 ****************************************************************************/
194
195 bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
196                                          const char *smb_name, 
197                                          const char *client_domain, 
198                                          const char *workstation_name,
199                                          uint32 logon_parameters,
200                                          const uchar chal[8], 
201                                          const uchar lm_interactive_pwd[16], 
202                                          const uchar nt_interactive_pwd[16], 
203                                          const uchar *dc_sess_key)
204 {
205         struct samr_Password lm_pwd;
206         struct samr_Password nt_pwd;
207         unsigned char local_lm_response[24];
208         unsigned char local_nt_response[24];
209         unsigned char key[16];
210
211         memcpy(key, dc_sess_key, 16);
212
213         if (lm_interactive_pwd)
214                 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
215
216         if (nt_interactive_pwd)
217                 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
218
219 #ifdef DEBUG_PASSWORD
220         DEBUG(100,("key:"));
221         dump_data(100, key, sizeof(key));
222
223         DEBUG(100,("lm owf password:"));
224         dump_data(100, lm_pwd.hash, sizeof(lm_pwd.hash));
225
226         DEBUG(100,("nt owf password:"));
227         dump_data(100, nt_pwd.hash, sizeof(nt_pwd.hash));
228 #endif
229
230         if (lm_interactive_pwd)
231                 arcfour_crypt(lm_pwd.hash, key, sizeof(lm_pwd.hash));
232
233         if (nt_interactive_pwd)
234                 arcfour_crypt(nt_pwd.hash, key, sizeof(nt_pwd.hash));
235
236 #ifdef DEBUG_PASSWORD
237         DEBUG(100,("decrypt of lm owf password:"));
238         dump_data(100, lm_pwd.hash, sizeof(lm_pwd));
239
240         DEBUG(100,("decrypt of nt owf password:"));
241         dump_data(100, nt_pwd.hash, sizeof(nt_pwd));
242 #endif
243
244         if (lm_interactive_pwd)
245                 SMBOWFencrypt(lm_pwd.hash, chal,
246                               local_lm_response);
247
248         if (nt_interactive_pwd)
249                 SMBOWFencrypt(nt_pwd.hash, chal,
250                               local_nt_response);
251
252         /* Password info paranoia */
253         ZERO_STRUCT(key);
254
255         {
256                 bool ret;
257                 NTSTATUS nt_status;
258                 DATA_BLOB local_lm_blob;
259                 DATA_BLOB local_nt_blob;
260
261                 if (lm_interactive_pwd) {
262                         local_lm_blob = data_blob(local_lm_response,
263                                                   sizeof(local_lm_response));
264                 }
265
266                 if (nt_interactive_pwd) {
267                         local_nt_blob = data_blob(local_nt_response,
268                                                   sizeof(local_nt_response));
269                 }
270
271                 nt_status = make_user_info_map(
272                         user_info, 
273                         smb_name, client_domain, workstation_name,
274                         lm_interactive_pwd ? &local_lm_blob : NULL,
275                         nt_interactive_pwd ? &local_nt_blob : NULL,
276                         lm_interactive_pwd ? &lm_pwd : NULL,
277                         nt_interactive_pwd ? &nt_pwd : NULL,
278                         NULL, AUTH_PASSWORD_HASH);
279
280                 if (NT_STATUS_IS_OK(nt_status)) {
281                         (*user_info)->logon_parameters = logon_parameters;
282                 }
283
284                 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
285                 data_blob_free(&local_lm_blob);
286                 data_blob_free(&local_nt_blob);
287                 return ret;
288         }
289 }
290
291
292 /****************************************************************************
293  Create an auth_usersupplied_data structure
294 ****************************************************************************/
295
296 bool make_user_info_for_reply(struct auth_usersupplied_info **user_info,
297                               const char *smb_name, 
298                               const char *client_domain,
299                               const uint8 chal[8],
300                               DATA_BLOB plaintext_password)
301 {
302
303         DATA_BLOB local_lm_blob;
304         DATA_BLOB local_nt_blob;
305         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
306         char *plaintext_password_string;
307         /*
308          * Not encrypted - do so.
309          */
310
311         DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
312                  "format.\n"));
313         if (plaintext_password.data && plaintext_password.length) {
314                 unsigned char local_lm_response[24];
315
316 #ifdef DEBUG_PASSWORD
317                 DEBUG(10,("Unencrypted password (len %d):\n",
318                           (int)plaintext_password.length));
319                 dump_data(100, plaintext_password.data,
320                           plaintext_password.length);
321 #endif
322
323                 SMBencrypt( (const char *)plaintext_password.data,
324                             (const uchar*)chal, local_lm_response);
325                 local_lm_blob = data_blob(local_lm_response, 24);
326
327                 /* We can't do an NT hash here, as the password needs to be
328                    case insensitive */
329                 local_nt_blob = data_blob_null; 
330         } else {
331                 local_lm_blob = data_blob_null; 
332                 local_nt_blob = data_blob_null; 
333         }
334
335         plaintext_password_string = talloc_strndup(talloc_tos(),
336                                                    (const char *)plaintext_password.data,
337                                                    plaintext_password.length);
338         if (!plaintext_password_string) {
339                 return False;
340         }
341
342         ret = make_user_info_map(
343                 user_info, smb_name, client_domain, 
344                 get_remote_machine_name(),
345                 local_lm_blob.data ? &local_lm_blob : NULL,
346                 local_nt_blob.data ? &local_nt_blob : NULL,
347                 NULL, NULL,
348                 plaintext_password_string,
349                 AUTH_PASSWORD_PLAIN);
350
351         if (plaintext_password_string) {
352                 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
353                 talloc_free(plaintext_password_string);
354         }
355
356         data_blob_free(&local_lm_blob);
357         return NT_STATUS_IS_OK(ret) ? True : False;
358 }
359
360 /****************************************************************************
361  Create an auth_usersupplied_data structure
362 ****************************************************************************/
363
364 NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info,
365                                       const char *smb_name,
366                                       const char *client_domain, 
367                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp)
368 {
369         return make_user_info_map(user_info, smb_name, 
370                                   client_domain, 
371                                   get_remote_machine_name(), 
372                                   lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
373                                   nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
374                                   NULL, NULL, NULL,
375                                   AUTH_PASSWORD_RESPONSE);
376 }
377
378 /****************************************************************************
379  Create a guest user_info blob, for anonymous authenticaion.
380 ****************************************************************************/
381
382 bool make_user_info_guest(struct auth_usersupplied_info **user_info)
383 {
384         NTSTATUS nt_status;
385
386         nt_status = make_user_info(user_info, 
387                                    "","", 
388                                    "","", 
389                                    "", 
390                                    NULL, NULL, 
391                                    NULL, NULL, 
392                                    NULL,
393                                    AUTH_PASSWORD_RESPONSE);
394
395         return NT_STATUS_IS_OK(nt_status) ? True : False;
396 }
397
398 static NTSTATUS log_nt_token(struct security_token *token)
399 {
400         TALLOC_CTX *frame = talloc_stackframe();
401         char *command;
402         char *group_sidstr;
403         size_t i;
404
405         if ((lp_log_nt_token_command() == NULL) ||
406             (strlen(lp_log_nt_token_command()) == 0)) {
407                 TALLOC_FREE(frame);
408                 return NT_STATUS_OK;
409         }
410
411         group_sidstr = talloc_strdup(frame, "");
412         for (i=1; i<token->num_sids; i++) {
413                 group_sidstr = talloc_asprintf(
414                         frame, "%s %s", group_sidstr,
415                         sid_string_talloc(frame, &token->sids[i]));
416         }
417
418         command = talloc_string_sub(
419                 frame, lp_log_nt_token_command(),
420                 "%s", sid_string_talloc(frame, &token->sids[0]));
421         command = talloc_string_sub(frame, command, "%t", group_sidstr);
422
423         if (command == NULL) {
424                 TALLOC_FREE(frame);
425                 return NT_STATUS_NO_MEMORY;
426         }
427
428         DEBUG(8, ("running command: [%s]\n", command));
429         if (smbrun(command, NULL) != 0) {
430                 DEBUG(0, ("Could not log NT token\n"));
431                 TALLOC_FREE(frame);
432                 return NT_STATUS_ACCESS_DENIED;
433         }
434
435         TALLOC_FREE(frame);
436         return NT_STATUS_OK;
437 }
438
439 /*
440  * Create the token to use from server_info->info3 and
441  * server_info->sids (the info3/sam groups). Find the unix gids.
442  */
443
444 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
445                             const struct auth_serversupplied_info *server_info,
446                             DATA_BLOB *session_key,
447                             struct auth_serversupplied_info **session_info_out)
448 {
449         struct security_token *t;
450         NTSTATUS status;
451         size_t i;
452         struct dom_sid tmp_sid;
453         struct auth_serversupplied_info *session_info;
454         struct wbcUnixId *ids;
455
456         /* Ensure we can't possible take a code path leading to a
457          * null defref. */
458         if (!server_info) {
459                 return NT_STATUS_LOGON_FAILURE;
460         }
461
462         session_info = copy_serverinfo(mem_ctx, server_info);
463
464         if (!session_info) {
465                 return NT_STATUS_NO_MEMORY;
466         }
467
468         if (session_key) {
469                 data_blob_free(&session_info->session_key);
470                 session_info->session_key = data_blob_talloc(session_info,
471                                                                   session_key->data,
472                                                                   session_key->length);
473                 if (!session_info->session_key.data && session_key->length) {
474                         return NT_STATUS_NO_MEMORY;
475                 }
476         }
477
478         if (session_info->security_token) {
479                 /* Just copy the token, it has already been finalised
480                  * (nasty hack to support a cached guest session_info,
481                  * and a possible strategy for auth_samba4 to pass in
482                  * a finalised session) */
483                 *session_info_out = session_info;
484                 return NT_STATUS_OK;
485         }
486
487         /*
488          * If winbind is not around, we can not make much use of the SIDs the
489          * domain controller provided us with. Likewise if the user name was
490          * mapped to some local unix user.
491          */
492
493         if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
494             (session_info->nss_token)) {
495                 status = create_token_from_username(session_info,
496                                                     session_info->unix_name,
497                                                     session_info->guest,
498                                                     &session_info->utok.uid,
499                                                     &session_info->utok.gid,
500                                                     &session_info->unix_name,
501                                                     &session_info->security_token);
502
503         } else {
504                 status = create_local_nt_token_from_info3(session_info,
505                                                           session_info->guest,
506                                                           session_info->info3,
507                                                           &session_info->extra,
508                                                           &session_info->security_token);
509         }
510
511         if (!NT_STATUS_IS_OK(status)) {
512                 return status;
513         }
514
515         /* Convert the SIDs to gids. */
516
517         session_info->utok.ngroups = 0;
518         session_info->utok.groups = NULL;
519
520         t = session_info->security_token;
521
522         ids = talloc_array(talloc_tos(), struct wbcUnixId,
523                            t->num_sids);
524         if (ids == NULL) {
525                 return NT_STATUS_NO_MEMORY;
526         }
527
528         if (!sids_to_unix_ids(t->sids, t->num_sids, ids)) {
529                 TALLOC_FREE(ids);
530                 return NT_STATUS_NO_MEMORY;
531         }
532
533         /* Start at index 1, where the groups start. */
534
535         for (i=1; i<t->num_sids; i++) {
536
537                 if (ids[i].type != WBC_ID_TYPE_GID) {
538                         DEBUG(10, ("Could not convert SID %s to gid, "
539                                    "ignoring it\n",
540                                    sid_string_dbg(&t->sids[i])));
541                         continue;
542                 }
543                 if (!add_gid_to_array_unique(session_info, ids[i].id.gid,
544                                              &session_info->utok.groups,
545                                              &session_info->utok.ngroups)) {
546                         return NT_STATUS_NO_MEMORY;
547                 }
548         }
549
550         /*
551          * Add the "Unix Group" SID for each gid to catch mapped groups
552          * and their Unix equivalent.  This is to solve the backwards
553          * compatibility problem of 'valid users = +ntadmin' where
554          * ntadmin has been paired with "Domain Admins" in the group
555          * mapping table.  Otherwise smb.conf would need to be changed
556          * to 'valid user = "Domain Admins"'.  --jerry
557          *
558          * For consistency we also add the "Unix User" SID,
559          * so that the complete unix token is represented within
560          * the nt token.
561          */
562
563         uid_to_unix_users_sid(session_info->utok.uid, &tmp_sid);
564
565         add_sid_to_array_unique(session_info->security_token, &tmp_sid,
566                                 &session_info->security_token->sids,
567                                 &session_info->security_token->num_sids);
568
569         for ( i=0; i<session_info->utok.ngroups; i++ ) {
570                 gid_to_unix_groups_sid(session_info->utok.groups[i], &tmp_sid);
571                 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
572                                         &session_info->security_token->sids,
573                                         &session_info->security_token->num_sids);
574         }
575
576         security_token_debug(DBGC_AUTH, 10, session_info->security_token);
577         debug_unix_user_token(DBGC_AUTH, 10,
578                               session_info->utok.uid,
579                               session_info->utok.gid,
580                               session_info->utok.ngroups,
581                               session_info->utok.groups);
582
583         status = log_nt_token(session_info->security_token);
584         if (!NT_STATUS_IS_OK(status)) {
585                 return status;
586         }
587
588         *session_info_out = session_info;
589         return NT_STATUS_OK;
590 }
591
592 /***************************************************************************
593  Make (and fill) a server_info struct from a 'struct passwd' by conversion
594  to a struct samu
595 ***************************************************************************/
596
597 NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
598                              char *unix_username,
599                              struct passwd *pwd)
600 {
601         NTSTATUS status;
602         struct samu *sampass = NULL;
603         char *qualified_name = NULL;
604         TALLOC_CTX *mem_ctx = NULL;
605         struct dom_sid u_sid;
606         enum lsa_SidType type;
607         struct auth_serversupplied_info *result;
608
609         /*
610          * The SID returned in server_info->sam_account is based
611          * on our SAM sid even though for a pure UNIX account this should
612          * not be the case as it doesn't really exist in the SAM db.
613          * This causes lookups on "[in]valid users" to fail as they
614          * will lookup this name as a "Unix User" SID to check against
615          * the user token. Fix this by adding the "Unix User"\unix_username
616          * SID to the sid array. The correct fix should probably be
617          * changing the server_info->sam_account user SID to be a
618          * S-1-22 Unix SID, but this might break old configs where
619          * plaintext passwords were used with no SAM backend.
620          */
621
622         mem_ctx = talloc_init("make_server_info_pw_tmp");
623         if (!mem_ctx) {
624                 return NT_STATUS_NO_MEMORY;
625         }
626
627         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
628                                         unix_users_domain_name(),
629                                         unix_username );
630         if (!qualified_name) {
631                 TALLOC_FREE(mem_ctx);
632                 return NT_STATUS_NO_MEMORY;
633         }
634
635         if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
636                                                 NULL, NULL,
637                                                 &u_sid, &type)) {
638                 TALLOC_FREE(mem_ctx);
639                 return NT_STATUS_NO_SUCH_USER;
640         }
641
642         TALLOC_FREE(mem_ctx);
643
644         if (type != SID_NAME_USER) {
645                 return NT_STATUS_NO_SUCH_USER;
646         }
647
648         if ( !(sampass = samu_new( NULL )) ) {
649                 return NT_STATUS_NO_MEMORY;
650         }
651
652         status = samu_set_unix( sampass, pwd );
653         if (!NT_STATUS_IS_OK(status)) {
654                 return status;
655         }
656
657         /* In pathological cases the above call can set the account
658          * name to the DOMAIN\username form. Reset the account name
659          * using unix_username */
660         pdb_set_username(sampass, unix_username, PDB_SET);
661
662         /* set the user sid to be the calculated u_sid */
663         pdb_set_user_sid(sampass, &u_sid, PDB_SET);
664
665         result = make_server_info(NULL);
666         if (result == NULL) {
667                 TALLOC_FREE(sampass);
668                 return NT_STATUS_NO_MEMORY;
669         }
670
671         status = samu_to_SamInfo3(result, sampass, global_myname(),
672                                   &result->info3, &result->extra);
673         TALLOC_FREE(sampass);
674         if (!NT_STATUS_IS_OK(status)) {
675                 DEBUG(10, ("Failed to convert samu to info3: %s\n",
676                            nt_errstr(status)));
677                 TALLOC_FREE(result);
678                 return status;
679         }
680
681         result->unix_name = talloc_strdup(result, unix_username);
682         result->sanitized_username = sanitize_username(result, unix_username);
683
684         if ((result->unix_name == NULL)
685             || (result->sanitized_username == NULL)) {
686                 TALLOC_FREE(result);
687                 return NT_STATUS_NO_MEMORY;
688         }
689
690         result->utok.uid = pwd->pw_uid;
691         result->utok.gid = pwd->pw_gid;
692
693         *server_info = result;
694
695         return NT_STATUS_OK;
696 }
697
698 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
699                                 struct netr_SamInfo3 *info3)
700 {
701         const char *guest_account = lp_guestaccount();
702         struct dom_sid domain_sid;
703         struct passwd *pwd;
704         const char *tmp;
705
706         pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
707         if (pwd == NULL) {
708                 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
709                          "account [%s]!\n", guest_account));
710                 return NT_STATUS_NO_SUCH_USER;
711         }
712
713         /* Set acount name */
714         tmp = talloc_strdup(mem_ctx, pwd->pw_name);
715         if (tmp == NULL) {
716                 return NT_STATUS_NO_MEMORY;
717         }
718         init_lsa_String(&info3->base.account_name, tmp);
719
720         /* Set domain name */
721         tmp = talloc_strdup(mem_ctx, get_global_sam_name());
722         if (tmp == NULL) {
723                 return NT_STATUS_NO_MEMORY;
724         }
725         init_lsa_StringLarge(&info3->base.domain, tmp);
726
727         /* Domain sid */
728         sid_copy(&domain_sid, get_global_sam_sid());
729
730         info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
731         if (info3->base.domain_sid == NULL) {
732                 return NT_STATUS_NO_MEMORY;
733         }
734
735         /* Guest rid */
736         info3->base.rid = DOMAIN_RID_GUEST;
737
738         /* Primary gid */
739         info3->base.primary_gid = BUILTIN_RID_GUESTS;
740
741         TALLOC_FREE(pwd);
742         return NT_STATUS_OK;
743 }
744
745 /***************************************************************************
746  Make (and fill) a user_info struct for a guest login.
747  This *must* succeed for smbd to start. If there is no mapping entry for
748  the guest gid, then create one.
749
750  The resulting structure is a 'session_info' because
751  create_local_token() has already been called on it.  This is quite
752  nasty, as the auth subsystem isn't expect this, but the behaviour is
753  left as-is for now.
754 ***************************************************************************/
755
756 static NTSTATUS make_new_server_info_guest(struct auth_serversupplied_info **session_info)
757 {
758         struct auth_serversupplied_info *server_info;
759         static const char zeros[16] = {0};
760         const char *guest_account = lp_guestaccount();
761         const char *domain = global_myname();
762         struct netr_SamInfo3 info3;
763         TALLOC_CTX *tmp_ctx;
764         NTSTATUS status;
765         fstring tmp;
766
767         tmp_ctx = talloc_stackframe();
768         if (tmp_ctx == NULL) {
769                 return NT_STATUS_NO_MEMORY;
770         }
771
772         ZERO_STRUCT(info3);
773
774         status = get_guest_info3(tmp_ctx, &info3);
775         if (!NT_STATUS_IS_OK(status)) {
776                 goto done;
777         }
778
779         status = make_server_info_info3(tmp_ctx,
780                                         guest_account,
781                                         domain,
782                                         &server_info,
783                                         &info3);
784         if (!NT_STATUS_IS_OK(status)) {
785                 goto done;
786         }
787
788         server_info->guest = True;
789
790         /* This should not be done here (we should produce a server
791          * info, and later construct a session info from it), but for
792          * now this does not change the previous behaviours */
793         status = create_local_token(tmp_ctx, server_info, NULL, session_info);
794         TALLOC_FREE(server_info);
795         if (!NT_STATUS_IS_OK(status)) {
796                 DEBUG(10, ("create_local_token failed: %s\n",
797                            nt_errstr(status)));
798                 goto done;
799         }
800         talloc_steal(NULL, *session_info);
801
802         /* annoying, but the Guest really does have a session key, and it is
803            all zeros! */
804         (*session_info)->session_key = data_blob(zeros, sizeof(zeros));
805         (*session_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
806
807         alpha_strcpy(tmp, (*session_info)->info3->base.account_name.string,
808                      ". _-$", sizeof(tmp));
809         (*session_info)->sanitized_username = talloc_strdup(*session_info, tmp);
810
811         status = NT_STATUS_OK;
812 done:
813         TALLOC_FREE(tmp_ctx);
814         return NT_STATUS_OK;
815 }
816
817 /***************************************************************************
818  Make (and fill) a auth_session_info struct for a system user login.
819  This *must* succeed for smbd to start.
820 ***************************************************************************/
821
822 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
823                                             struct auth_serversupplied_info **session_info)
824 {
825         struct passwd *pwd;
826         NTSTATUS status;
827
828         pwd = getpwuid_alloc(mem_ctx, sec_initial_uid());
829         if (pwd == NULL) {
830                 return NT_STATUS_NO_SUCH_USER;
831         }
832
833         status = make_session_info_from_username(mem_ctx,
834                                                  pwd->pw_name,
835                                                  false,
836                                                  session_info);
837         TALLOC_FREE(pwd);
838         if (!NT_STATUS_IS_OK(status)) {
839                 return status;
840         }
841
842         (*session_info)->system = true;
843
844         status = add_sid_to_array_unique((*session_info)->security_token->sids,
845                                          &global_sid_System,
846                                          &(*session_info)->security_token->sids,
847                                          &(*session_info)->security_token->num_sids);
848         if (!NT_STATUS_IS_OK(status)) {
849                 TALLOC_FREE((*session_info));
850                 return status;
851         }
852
853         return NT_STATUS_OK;
854 }
855
856 /****************************************************************************
857   Fake a auth_serversupplied_info just from a username (as a
858   session_info structure, with create_local_token() already called on
859   it.
860 ****************************************************************************/
861
862 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
863                                          const char *username,
864                                          bool is_guest,
865                                          struct auth_serversupplied_info **session_info)
866 {
867         struct auth_serversupplied_info *result;
868         struct passwd *pwd;
869         NTSTATUS status;
870
871         pwd = Get_Pwnam_alloc(talloc_tos(), username);
872         if (pwd == NULL) {
873                 return NT_STATUS_NO_SUCH_USER;
874         }
875
876         status = make_server_info_pw(&result, pwd->pw_name, pwd);
877
878         TALLOC_FREE(pwd);
879
880         if (!NT_STATUS_IS_OK(status)) {
881                 return status;
882         }
883
884         result->nss_token = true;
885         result->guest = is_guest;
886
887         /* Now turn the server_info into a session_info with the full token etc */
888         status = create_local_token(mem_ctx, result, NULL, session_info);
889         talloc_free(result);
890         return status;
891 }
892
893
894 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
895                                                  const struct auth_serversupplied_info *src)
896 {
897         struct auth_serversupplied_info *dst;
898
899         dst = make_server_info(mem_ctx);
900         if (dst == NULL) {
901                 return NULL;
902         }
903
904         dst->guest = src->guest;
905         dst->system = src->system;
906         dst->utok.uid = src->utok.uid;
907         dst->utok.gid = src->utok.gid;
908         dst->utok.ngroups = src->utok.ngroups;
909         if (src->utok.ngroups != 0) {
910                 dst->utok.groups = (gid_t *)talloc_memdup(
911                         dst, src->utok.groups,
912                         sizeof(gid_t)*dst->utok.ngroups);
913         } else {
914                 dst->utok.groups = NULL;
915         }
916
917         if (src->security_token) {
918                 dst->security_token = dup_nt_token(dst, src->security_token);
919                 if (!dst->security_token) {
920                         TALLOC_FREE(dst);
921                         return NULL;
922                 }
923         }
924
925         dst->session_key = data_blob_talloc( dst, src->session_key.data,
926                                                 src->session_key.length);
927
928         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
929                                                 src->lm_session_key.length);
930
931         dst->info3 = copy_netr_SamInfo3(dst, src->info3);
932         if (!dst->info3) {
933                 TALLOC_FREE(dst);
934                 return NULL;
935         }
936         dst->extra = src->extra;
937
938         dst->unix_name = talloc_strdup(dst, src->unix_name);
939         if (!dst->unix_name) {
940                 TALLOC_FREE(dst);
941                 return NULL;
942         }
943
944         dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
945         if (!dst->sanitized_username) {
946                 TALLOC_FREE(dst);
947                 return NULL;
948         }
949
950         return dst;
951 }
952
953 /*
954  * Set a new session key. Used in the rpc server where we have to override the
955  * SMB level session key with SystemLibraryDTC
956  */
957
958 bool session_info_set_session_key(struct auth_serversupplied_info *info,
959                                  DATA_BLOB session_key)
960 {
961         TALLOC_FREE(info->session_key.data);
962
963         info->session_key = data_blob_talloc(
964                 info, session_key.data, session_key.length);
965
966         return (info->session_key.data != NULL);
967 }
968
969 static struct auth_serversupplied_info *guest_info = NULL;
970
971 bool init_guest_info(void)
972 {
973         if (guest_info != NULL)
974                 return True;
975
976         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
977 }
978
979 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
980                                 struct auth_serversupplied_info **server_info)
981 {
982         *server_info = copy_serverinfo(mem_ctx, guest_info);
983         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
984 }
985
986 static struct auth_serversupplied_info *system_info = NULL;
987
988 NTSTATUS init_system_info(void)
989 {
990         if (system_info != NULL)
991                 return NT_STATUS_OK;
992
993         return make_new_session_info_system(NULL, &system_info);
994 }
995
996 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
997                                 struct auth_serversupplied_info **session_info)
998 {
999         if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1000         *session_info = copy_serverinfo(mem_ctx, system_info);
1001         return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1002 }
1003
1004 const struct auth_serversupplied_info *get_session_info_system(void)
1005 {
1006     return system_info;
1007 }
1008
1009 bool copy_current_user(struct current_user *dst, struct current_user *src)
1010 {
1011         gid_t *groups;
1012         struct security_token *nt_token;
1013
1014         groups = (gid_t *)memdup(src->ut.groups,
1015                                  sizeof(gid_t) * src->ut.ngroups);
1016         if ((src->ut.ngroups != 0) && (groups == NULL)) {
1017                 return False;
1018         }
1019
1020         nt_token = dup_nt_token(NULL, src->nt_user_token);
1021         if (nt_token == NULL) {
1022                 SAFE_FREE(groups);
1023                 return False;
1024         }
1025
1026         dst->conn = src->conn;
1027         dst->vuid = src->vuid;
1028         dst->ut.uid = src->ut.uid;
1029         dst->ut.gid = src->ut.gid;
1030         dst->ut.ngroups = src->ut.ngroups;
1031         dst->ut.groups = groups;
1032         dst->nt_user_token = nt_token;
1033         return True;
1034 }
1035
1036 /***************************************************************************
1037  Purely internal function for make_server_info_info3
1038 ***************************************************************************/
1039
1040 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1041                               const char *username, char **found_username,
1042                               struct passwd **pwd,
1043                               bool *username_was_mapped)
1044 {
1045         char *orig_dom_user = NULL;
1046         char *dom_user = NULL;
1047         char *lower_username = NULL;
1048         char *real_username = NULL;
1049         struct passwd *passwd;
1050
1051         lower_username = talloc_strdup(mem_ctx, username);
1052         if (!lower_username) {
1053                 return NT_STATUS_NO_MEMORY;
1054         }
1055         strlower_m( lower_username );
1056
1057         orig_dom_user = talloc_asprintf(mem_ctx,
1058                                 "%s%c%s",
1059                                 domain,
1060                                 *lp_winbind_separator(),
1061                                 lower_username);
1062         if (!orig_dom_user) {
1063                 return NT_STATUS_NO_MEMORY;
1064         }
1065
1066         /* Get the passwd struct.  Try to create the account if necessary. */
1067
1068         *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1069         if (!dom_user) {
1070                 return NT_STATUS_NO_MEMORY;
1071         }
1072
1073         passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, True );
1074         if (!passwd) {
1075                 DEBUG(3, ("Failed to find authenticated user %s via "
1076                           "getpwnam(), denying access.\n", dom_user));
1077                 return NT_STATUS_NO_SUCH_USER;
1078         }
1079
1080         if (!real_username) {
1081                 return NT_STATUS_NO_MEMORY;
1082         }
1083
1084         *pwd = passwd;
1085
1086         /* This is pointless -- there is no suport for differing 
1087            unix and windows names.  Make sure to always store the 
1088            one we actually looked up and succeeded. Have I mentioned
1089            why I hate the 'winbind use default domain' parameter?   
1090                                          --jerry              */
1091
1092         *found_username = talloc_strdup( mem_ctx, real_username );
1093
1094         return NT_STATUS_OK;
1095 }
1096
1097 /****************************************************************************
1098  Wrapper to allow the getpwnam() call to strip the domain name and 
1099  try again in case a local UNIX user is already there.  Also run through 
1100  the username if we fallback to the username only.
1101  ****************************************************************************/
1102
1103 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1104                              char **p_save_username, bool create )
1105 {
1106         struct passwd *pw = NULL;
1107         char *p = NULL;
1108         char *username = NULL;
1109
1110         /* we only save a copy of the username it has been mangled 
1111            by winbindd use default domain */
1112         *p_save_username = NULL;
1113
1114         /* don't call map_username() here since it has to be done higher 
1115            up the stack so we don't call it multiple times */
1116
1117         username = talloc_strdup(mem_ctx, domuser);
1118         if (!username) {
1119                 return NULL;
1120         }
1121
1122         p = strchr_m( username, *lp_winbind_separator() );
1123
1124         /* code for a DOMAIN\user string */
1125
1126         if ( p ) {
1127                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1128                 if ( pw ) {
1129                         /* make sure we get the case of the username correct */
1130                         /* work around 'winbind use default domain = yes' */
1131
1132                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1133                                 char *domain;
1134
1135                                 /* split the domain and username into 2 strings */
1136                                 *p = '\0';
1137                                 domain = username;
1138
1139                                 *p_save_username = talloc_asprintf(mem_ctx,
1140                                                                 "%s%c%s",
1141                                                                 domain,
1142                                                                 *lp_winbind_separator(),
1143                                                                 pw->pw_name);
1144                                 if (!*p_save_username) {
1145                                         TALLOC_FREE(pw);
1146                                         return NULL;
1147                                 }
1148                         } else {
1149                                 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1150                         }
1151
1152                         /* whew -- done! */
1153                         return pw;
1154                 }
1155
1156                 /* setup for lookup of just the username */
1157                 /* remember that p and username are overlapping memory */
1158
1159                 p++;
1160                 username = talloc_strdup(mem_ctx, p);
1161                 if (!username) {
1162                         return NULL;
1163                 }
1164         }
1165
1166         /* just lookup a plain username */
1167
1168         pw = Get_Pwnam_alloc(mem_ctx, username);
1169
1170         /* Create local user if requested but only if winbindd
1171            is not running.  We need to protect against cases
1172            where winbindd is failing and then prematurely
1173            creating users in /etc/passwd */
1174
1175         if ( !pw && create && !winbind_ping() ) {
1176                 /* Don't add a machine account. */
1177                 if (username[strlen(username)-1] == '$')
1178                         return NULL;
1179
1180                 _smb_create_user(NULL, username, NULL);
1181                 pw = Get_Pwnam_alloc(mem_ctx, username);
1182         }
1183
1184         /* one last check for a valid passwd struct */
1185
1186         if (pw) {
1187                 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1188         }
1189         return pw;
1190 }
1191
1192 /***************************************************************************
1193  Make a server_info struct from the info3 returned by a domain logon 
1194 ***************************************************************************/
1195
1196 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1197                                 const char *sent_nt_username,
1198                                 const char *domain,
1199                                 struct auth_serversupplied_info **server_info,
1200                                 struct netr_SamInfo3 *info3)
1201 {
1202         static const char zeros[16] = {0, };
1203
1204         NTSTATUS nt_status = NT_STATUS_OK;
1205         char *found_username = NULL;
1206         const char *nt_domain;
1207         const char *nt_username;
1208         bool username_was_mapped;
1209         struct passwd *pwd;
1210         struct auth_serversupplied_info *result;
1211         struct dom_sid *group_sid;
1212         struct netr_SamInfo3 *i3;
1213
1214         /* 
1215            Here is where we should check the list of
1216            trusted domains, and verify that the SID 
1217            matches.
1218         */
1219
1220         nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1221         if (!nt_username) {
1222                 /* If the server didn't give us one, just use the one we sent
1223                  * them */
1224                 nt_username = sent_nt_username;
1225         }
1226
1227         nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1228         if (!nt_domain) {
1229                 /* If the server didn't give us one, just use the one we sent
1230                  * them */
1231                 nt_domain = domain;
1232         }
1233
1234         /* If getpwnam() fails try the add user script (2.2.x behavior).
1235
1236            We use the _unmapped_ username here in an attempt to provide
1237            consistent username mapping behavior between kerberos and NTLM[SSP]
1238            authentication in domain mode security.  I.E. Username mapping
1239            should be applied to the fully qualified username
1240            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1241            called map_username() unnecessarily in make_user_info_map() but
1242            that is how the current code is designed.  Making the change here
1243            is the least disruptive place.  -- jerry */
1244
1245         /* this call will try to create the user if necessary */
1246
1247         nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
1248                                      &found_username, &pwd,
1249                                      &username_was_mapped);
1250
1251         if (!NT_STATUS_IS_OK(nt_status)) {
1252                 return nt_status;
1253         }
1254
1255         result = make_server_info(NULL);
1256         if (result == NULL) {
1257                 DEBUG(4, ("make_server_info failed!\n"));
1258                 return NT_STATUS_NO_MEMORY;
1259         }
1260
1261         result->unix_name = talloc_strdup(result, found_username);
1262
1263         result->sanitized_username = sanitize_username(result,
1264                                                        result->unix_name);
1265         if (result->sanitized_username == NULL) {
1266                 TALLOC_FREE(result);
1267                 return NT_STATUS_NO_MEMORY;
1268         }
1269
1270         /* copy in the info3 */
1271         result->info3 = i3 = copy_netr_SamInfo3(result, info3);
1272         if (result->info3 == NULL) {
1273                 TALLOC_FREE(result);
1274                 return NT_STATUS_NO_MEMORY;
1275         }
1276
1277         /* Fill in the unix info we found on the way */
1278         result->utok.uid = pwd->pw_uid;
1279         result->utok.gid = pwd->pw_gid;
1280
1281         /* We can't just trust that the primary group sid sent us is something
1282          * we can really use. Obtain the useable sid, and store the original
1283          * one as an additional group if it had to be replaced */
1284         nt_status = get_primary_group_sid(mem_ctx, found_username,
1285                                           &pwd, &group_sid);
1286         if (!NT_STATUS_IS_OK(nt_status)) {
1287                 TALLOC_FREE(result);
1288                 return nt_status;
1289         }
1290
1291         /* store and check if it is the same we got originally */
1292         sid_peek_rid(group_sid, &i3->base.primary_gid);
1293         if (i3->base.primary_gid != info3->base.primary_gid) {
1294                 uint32_t n = i3->base.groups.count;
1295                 /* not the same, store the original as an additional group */
1296                 i3->base.groups.rids =
1297                         talloc_realloc(i3, i3->base.groups.rids,
1298                                         struct samr_RidWithAttribute, n + 1);
1299                 if (i3->base.groups.rids == NULL) {
1300                         TALLOC_FREE(result);
1301                         return NT_STATUS_NO_MEMORY;
1302                 }
1303                 i3->base.groups.rids[n].rid = info3->base.primary_gid;
1304                 i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED;
1305                 i3->base.groups.count = n + 1;
1306         }
1307
1308         /* ensure we are never given NULL session keys */
1309
1310         if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1311                 result->session_key = data_blob_null;
1312         } else {
1313                 result->session_key = data_blob_talloc(
1314                         result, info3->base.key.key,
1315                         sizeof(info3->base.key.key));
1316         }
1317
1318         if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1319                 result->lm_session_key = data_blob_null;
1320         } else {
1321                 result->lm_session_key = data_blob_talloc(
1322                         result, info3->base.LMSessKey.key,
1323                         sizeof(info3->base.LMSessKey.key));
1324         }
1325
1326         result->nss_token |= username_was_mapped;
1327
1328         *server_info = result;
1329
1330         return NT_STATUS_OK;
1331 }
1332
1333 /*****************************************************************************
1334  Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1335 ******************************************************************************/
1336
1337 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1338                                           const char *sent_nt_username,
1339                                           const char *domain,
1340                                           const struct wbcAuthUserInfo *info,
1341                                           struct auth_serversupplied_info **server_info)
1342 {
1343         struct netr_SamInfo3 *info3;
1344
1345         info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
1346         if (!info3) {
1347                 return NT_STATUS_NO_MEMORY;
1348         }
1349
1350         return make_server_info_info3(mem_ctx,
1351                                       sent_nt_username, domain,
1352                                       server_info, info3);
1353 }
1354
1355 /**
1356  * Verify whether or not given domain is trusted.
1357  *
1358  * @param domain_name name of the domain to be verified
1359  * @return true if domain is one of the trusted ones or
1360  *         false if otherwise
1361  **/
1362
1363 bool is_trusted_domain(const char* dom_name)
1364 {
1365         struct dom_sid trustdom_sid;
1366         bool ret;
1367
1368         /* no trusted domains for a standalone server */
1369
1370         if ( lp_server_role() == ROLE_STANDALONE )
1371                 return False;
1372
1373         if (dom_name == NULL || dom_name[0] == '\0') {
1374                 return false;
1375         }
1376
1377         if (strequal(dom_name, get_global_sam_name())) {
1378                 return false;
1379         }
1380
1381         /* if we are a DC, then check for a direct trust relationships */
1382
1383         if ( IS_DC ) {
1384                 become_root();
1385                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1386                           "[%s]\n", dom_name ));
1387                 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1388                 unbecome_root();
1389                 if (ret)
1390                         return True;
1391         }
1392         else {
1393                 wbcErr result;
1394
1395                 /* If winbind is around, ask it */
1396
1397                 result = wb_is_trusted_domain(dom_name);
1398
1399                 if (result == WBC_ERR_SUCCESS) {
1400                         return True;
1401                 }
1402
1403                 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1404                         /* winbind could not find the domain */
1405                         return False;
1406                 }
1407
1408                 /* The only other possible result is that winbind is not up
1409                    and running. We need to update the trustdom_cache
1410                    ourselves */
1411
1412                 update_trustdom_cache();
1413         }
1414
1415         /* now the trustdom cache should be available a DC could still
1416          * have a transitive trust so fall back to the cache of trusted
1417          * domains (like a domain member would use  */
1418
1419         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1420                 return True;
1421         }
1422
1423         return False;
1424 }
1425