mount.cifs: check access of credential files before opening
[Samba.git] / source / auth / auth_util.c
blob7897a921efdee8002027d1b871cf4017cdcdbd2d
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
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
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.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "includes.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_AUTH
30 static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
31 const DOM_SID *user_sid,
32 BOOL is_guest,
33 int num_groupsids,
34 const DOM_SID *groupsids);
36 /****************************************************************************
37 Create a UNIX user on demand.
38 ****************************************************************************/
40 static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
42 pstring add_script;
43 int ret;
45 pstrcpy(add_script, lp_adduser_script());
46 if (! *add_script)
47 return -1;
48 all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
49 if (domain)
50 all_string_sub(add_script, "%D", domain, sizeof(pstring));
51 if (homedir)
52 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
53 ret = smbrun(add_script,NULL);
54 flush_pwnam_cache();
55 DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
56 return ret;
59 /****************************************************************************
60 Create an auth_usersupplied_data structure
61 ****************************************************************************/
63 static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
64 const char *smb_name,
65 const char *internal_username,
66 const char *client_domain,
67 const char *domain,
68 const char *wksta_name,
69 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
70 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
71 DATA_BLOB *plaintext,
72 BOOL encrypted)
75 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
77 *user_info = SMB_MALLOC_P(auth_usersupplied_info);
78 if (*user_info == NULL) {
79 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
80 return NT_STATUS_NO_MEMORY;
83 ZERO_STRUCTP(*user_info);
85 DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
87 (*user_info)->smb_name = SMB_STRDUP(smb_name);
88 if ((*user_info)->smb_name == NULL) {
89 free_user_info(user_info);
90 return NT_STATUS_NO_MEMORY;
93 (*user_info)->internal_username = SMB_STRDUP(internal_username);
94 if ((*user_info)->internal_username == NULL) {
95 free_user_info(user_info);
96 return NT_STATUS_NO_MEMORY;
99 (*user_info)->domain = SMB_STRDUP(domain);
100 if ((*user_info)->domain == NULL) {
101 free_user_info(user_info);
102 return NT_STATUS_NO_MEMORY;
105 (*user_info)->client_domain = SMB_STRDUP(client_domain);
106 if ((*user_info)->client_domain == NULL) {
107 free_user_info(user_info);
108 return NT_STATUS_NO_MEMORY;
111 (*user_info)->wksta_name = SMB_STRDUP(wksta_name);
112 if ((*user_info)->wksta_name == NULL) {
113 free_user_info(user_info);
114 return NT_STATUS_NO_MEMORY;
117 DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
119 if (lm_pwd)
120 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
121 if (nt_pwd)
122 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
123 if (lm_interactive_pwd)
124 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
125 if (nt_interactive_pwd)
126 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
128 if (plaintext)
129 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
131 (*user_info)->encrypted = encrypted;
133 (*user_info)->logon_parameters = 0;
135 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
137 return NT_STATUS_OK;
140 /****************************************************************************
141 Create an auth_usersupplied_data structure after appropriate mapping.
142 ****************************************************************************/
144 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
145 const char *smb_name,
146 const char *client_domain,
147 const char *wksta_name,
148 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
149 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
150 DATA_BLOB *plaintext,
151 BOOL encrypted)
153 const char *domain;
154 NTSTATUS result;
155 BOOL was_mapped;
156 fstring internal_username;
157 fstrcpy(internal_username, smb_name);
158 was_mapped = map_username(internal_username);
160 DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
161 client_domain, smb_name, wksta_name));
163 /* don't allow "" as a domain, fixes a Win9X bug
164 where it doens't supply a domain for logon script
165 'net use' commands. */
167 if ( *client_domain )
168 domain = client_domain;
169 else
170 domain = lp_workgroup();
172 /* do what win2k does. Always map unknown domains to our own
173 and let the "passdb backend" handle unknown users. */
175 if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) )
176 domain = my_sam_name();
178 /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
180 result = make_user_info(user_info, smb_name, internal_username,
181 client_domain, domain, wksta_name,
182 lm_pwd, nt_pwd,
183 lm_interactive_pwd, nt_interactive_pwd,
184 plaintext, encrypted);
185 if (NT_STATUS_IS_OK(result)) {
186 (*user_info)->was_mapped = was_mapped;
188 return result;
191 /****************************************************************************
192 Create an auth_usersupplied_data, making the DATA_BLOBs here.
193 Decrypt and encrypt the passwords.
194 ****************************************************************************/
196 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
197 const char *smb_name,
198 const char *client_domain,
199 const char *wksta_name,
200 uint32 logon_parameters,
201 const uchar *lm_network_pwd,
202 int lm_pwd_len,
203 const uchar *nt_network_pwd,
204 int nt_pwd_len)
206 BOOL ret;
207 NTSTATUS status;
208 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
209 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
211 status = make_user_info_map(user_info,
212 smb_name, client_domain,
213 wksta_name,
214 lm_pwd_len ? &lm_blob : NULL,
215 nt_pwd_len ? &nt_blob : NULL,
216 NULL, NULL, NULL,
217 True);
219 if (NT_STATUS_IS_OK(status)) {
220 (*user_info)->logon_parameters = logon_parameters;
222 ret = NT_STATUS_IS_OK(status) ? True : False;
224 data_blob_free(&lm_blob);
225 data_blob_free(&nt_blob);
226 return ret;
229 /****************************************************************************
230 Create an auth_usersupplied_data, making the DATA_BLOBs here.
231 Decrypt and encrypt the passwords.
232 ****************************************************************************/
234 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
235 const char *smb_name,
236 const char *client_domain,
237 const char *wksta_name,
238 uint32 logon_parameters,
239 const uchar chal[8],
240 const uchar lm_interactive_pwd[16],
241 const uchar nt_interactive_pwd[16],
242 const uchar *dc_sess_key)
244 char lm_pwd[16];
245 char nt_pwd[16];
246 unsigned char local_lm_response[24];
247 unsigned char local_nt_response[24];
248 unsigned char key[16];
250 ZERO_STRUCT(key);
251 memcpy(key, dc_sess_key, 8);
253 if (lm_interactive_pwd)
254 memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
256 if (nt_interactive_pwd)
257 memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
259 #ifdef DEBUG_PASSWORD
260 DEBUG(100,("key:"));
261 dump_data(100, (char *)key, sizeof(key));
263 DEBUG(100,("lm owf password:"));
264 dump_data(100, lm_pwd, sizeof(lm_pwd));
266 DEBUG(100,("nt owf password:"));
267 dump_data(100, nt_pwd, sizeof(nt_pwd));
268 #endif
270 if (lm_interactive_pwd)
271 SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
273 if (nt_interactive_pwd)
274 SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
276 #ifdef DEBUG_PASSWORD
277 DEBUG(100,("decrypt of lm owf password:"));
278 dump_data(100, lm_pwd, sizeof(lm_pwd));
280 DEBUG(100,("decrypt of nt owf password:"));
281 dump_data(100, nt_pwd, sizeof(nt_pwd));
282 #endif
284 if (lm_interactive_pwd)
285 SMBOWFencrypt((const unsigned char *)lm_pwd, chal,
286 local_lm_response);
288 if (nt_interactive_pwd)
289 SMBOWFencrypt((const unsigned char *)nt_pwd, chal,
290 local_nt_response);
292 /* Password info paranoia */
293 ZERO_STRUCT(key);
296 BOOL ret;
297 NTSTATUS nt_status;
298 DATA_BLOB local_lm_blob;
299 DATA_BLOB local_nt_blob;
301 DATA_BLOB lm_interactive_blob;
302 DATA_BLOB nt_interactive_blob;
304 if (lm_interactive_pwd) {
305 local_lm_blob = data_blob(local_lm_response,
306 sizeof(local_lm_response));
307 lm_interactive_blob = data_blob(lm_pwd,
308 sizeof(lm_pwd));
309 ZERO_STRUCT(lm_pwd);
312 if (nt_interactive_pwd) {
313 local_nt_blob = data_blob(local_nt_response,
314 sizeof(local_nt_response));
315 nt_interactive_blob = data_blob(nt_pwd,
316 sizeof(nt_pwd));
317 ZERO_STRUCT(nt_pwd);
320 nt_status = make_user_info_map(
321 user_info,
322 smb_name, client_domain, wksta_name,
323 lm_interactive_pwd ? &local_lm_blob : NULL,
324 nt_interactive_pwd ? &local_nt_blob : NULL,
325 lm_interactive_pwd ? &lm_interactive_blob : NULL,
326 nt_interactive_pwd ? &nt_interactive_blob : NULL,
327 NULL, True);
329 if (NT_STATUS_IS_OK(nt_status)) {
330 (*user_info)->logon_parameters = logon_parameters;
333 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
334 data_blob_free(&local_lm_blob);
335 data_blob_free(&local_nt_blob);
336 data_blob_free(&lm_interactive_blob);
337 data_blob_free(&nt_interactive_blob);
338 return ret;
343 /****************************************************************************
344 Create an auth_usersupplied_data structure
345 ****************************************************************************/
347 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
348 const char *smb_name,
349 const char *client_domain,
350 const uint8 chal[8],
351 DATA_BLOB plaintext_password)
354 DATA_BLOB local_lm_blob;
355 DATA_BLOB local_nt_blob;
356 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
359 * Not encrypted - do so.
362 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
363 "format.\n"));
365 if (plaintext_password.data) {
366 unsigned char local_lm_response[24];
368 #ifdef DEBUG_PASSWORD
369 DEBUG(10,("Unencrypted password (len %d):\n",
370 (int)plaintext_password.length));
371 dump_data(100, (const char *)plaintext_password.data,
372 plaintext_password.length);
373 #endif
375 SMBencrypt( (const char *)plaintext_password.data,
376 (const uchar*)chal, local_lm_response);
377 local_lm_blob = data_blob(local_lm_response, 24);
379 /* We can't do an NT hash here, as the password needs to be
380 case insensitive */
381 local_nt_blob = data_blob(NULL, 0);
383 } else {
384 local_lm_blob = data_blob(NULL, 0);
385 local_nt_blob = data_blob(NULL, 0);
388 ret = make_user_info_map(
389 user_info, smb_name, client_domain,
390 get_remote_machine_name(),
391 local_lm_blob.data ? &local_lm_blob : NULL,
392 local_nt_blob.data ? &local_nt_blob : NULL,
393 NULL, NULL,
394 plaintext_password.data ? &plaintext_password : NULL,
395 False);
397 data_blob_free(&local_lm_blob);
398 return NT_STATUS_IS_OK(ret) ? True : False;
401 /****************************************************************************
402 Create an auth_usersupplied_data structure
403 ****************************************************************************/
405 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
406 const char *smb_name,
407 const char *client_domain,
408 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
410 return make_user_info_map(user_info, smb_name,
411 client_domain,
412 get_remote_machine_name(),
413 lm_resp.data ? &lm_resp : NULL,
414 nt_resp.data ? &nt_resp : NULL,
415 NULL, NULL, NULL,
416 True);
419 /****************************************************************************
420 Create a guest user_info blob, for anonymous authenticaion.
421 ****************************************************************************/
423 BOOL make_user_info_guest(auth_usersupplied_info **user_info)
425 NTSTATUS nt_status;
427 nt_status = make_user_info(user_info,
428 "","",
429 "","",
430 "",
431 NULL, NULL,
432 NULL, NULL,
433 NULL,
434 True);
436 return NT_STATUS_IS_OK(nt_status) ? True : False;
439 /****************************************************************************
440 prints a NT_USER_TOKEN to debug output.
441 ****************************************************************************/
443 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
445 size_t i;
447 if (!token) {
448 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
449 return;
452 DEBUGC(dbg_class, dbg_lev,
453 ("NT user token of user %s\n",
454 sid_string_static(&token->user_sids[0]) ));
455 DEBUGADDC(dbg_class, dbg_lev,
456 ("contains %lu SIDs\n", (unsigned long)token->num_sids));
457 for (i = 0; i < token->num_sids; i++)
458 DEBUGADDC(dbg_class, dbg_lev,
459 ("SID[%3lu]: %s\n", (unsigned long)i,
460 sid_string_static(&token->user_sids[i])));
462 dump_se_priv( dbg_class, dbg_lev, &token->privileges );
465 /****************************************************************************
466 prints a UNIX 'token' to debug output.
467 ****************************************************************************/
469 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
470 int n_groups, gid_t *groups)
472 int i;
473 DEBUGC(dbg_class, dbg_lev,
474 ("UNIX token of user %ld\n", (long int)uid));
476 DEBUGADDC(dbg_class, dbg_lev,
477 ("Primary group is %ld and contains %i supplementary "
478 "groups\n", (long int)gid, n_groups));
479 for (i = 0; i < n_groups; i++)
480 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i,
481 (long int)groups[i]));
484 /******************************************************************************
485 Create a token for the root user to be used internally by smbd.
486 This is similar to running under the context of the LOCAL_SYSTEM account
487 in Windows. This is a read-only token. Do not modify it or free() it.
488 Create a copy if your need to change it.
489 ******************************************************************************/
491 NT_USER_TOKEN *get_root_nt_token( void )
493 static NT_USER_TOKEN *token = NULL;
494 DOM_SID u_sid, g_sid;
495 struct passwd *pw;
497 if ( token )
498 return token;
500 if ( !(pw = sys_getpwnam( "root" )) ) {
501 DEBUG(0,("get_root_nt_token: getpwnam\"root\") failed!\n"));
502 return NULL;
505 /* get the user and primary group SIDs; although the
506 BUILTIN\Administrators SId is really the one that matters here */
508 uid_to_sid(&u_sid, pw->pw_uid);
509 gid_to_sid(&g_sid, pw->pw_gid);
511 token = create_local_nt_token(NULL, &u_sid, False,
512 1, &global_sid_Builtin_Administrators);
513 return token;
516 static int server_info_dtor(auth_serversupplied_info *server_info)
518 TALLOC_FREE(server_info->sam_account);
519 ZERO_STRUCTP(server_info);
520 return 0;
523 /***************************************************************************
524 Make a server_info struct. Free with TALLOC_FREE().
525 ***************************************************************************/
527 static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
529 struct auth_serversupplied_info *result;
531 result = TALLOC_ZERO_P(mem_ctx, auth_serversupplied_info);
532 if (result == NULL) {
533 DEBUG(0, ("talloc failed\n"));
534 return NULL;
537 talloc_set_destructor(result, server_info_dtor);
539 /* Initialise the uid and gid values to something non-zero
540 which may save us from giving away root access if there
541 is a bug in allocating these fields. */
543 result->uid = -1;
544 result->gid = -1;
545 return result;
548 /***************************************************************************
549 Is the incoming username our own machine account ?
550 If so, the connection is almost certainly from winbindd.
551 ***************************************************************************/
553 static BOOL is_our_machine_account(const char *username)
555 BOOL ret;
556 char *truncname = NULL;
557 size_t ulen = strlen(username);
559 if (ulen == 0 || username[ulen-1] != '$') {
560 return False;
562 truncname = SMB_STRDUP(username);
563 if (!truncname) {
564 return False;
566 truncname[ulen-1] = '\0';
567 ret = strequal(truncname, global_myname());
568 SAFE_FREE(truncname);
569 return ret;
572 /***************************************************************************
573 Make (and fill) a user_info struct from a struct samu
574 ***************************************************************************/
576 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
577 struct samu *sampass)
579 struct passwd *pwd;
580 gid_t *gids;
581 auth_serversupplied_info *result;
582 int i;
583 size_t num_gids;
584 DOM_SID unix_group_sid;
585 const char *username = pdb_get_username(sampass);
587 if ( !(pwd = getpwnam_alloc(NULL, username)) ) {
588 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
589 username));
590 return NT_STATUS_NO_SUCH_USER;
593 if ( !(result = make_server_info(NULL)) ) {
594 TALLOC_FREE(pwd);
595 return NT_STATUS_NO_MEMORY;
598 result->sam_account = sampass;
599 result->unix_name = talloc_strdup(result, pwd->pw_name);
600 result->gid = pwd->pw_gid;
601 result->uid = pwd->pw_uid;
603 TALLOC_FREE(pwd);
605 if (IS_DC && is_our_machine_account(username)) {
607 * Ensure for a connection from our own
608 * machine account (from winbindd on a DC)
609 * there are no supplementary groups.
610 * Prevents loops in calling gid_to_sid().
612 result->sids = NULL;
613 gids = NULL;
614 result->num_sids = 0;
617 * This is a hack of monstrous proportions.
618 * If we know it's winbindd talking to us,
619 * we know we must never recurse into it,
620 * so turn off contacting winbindd for this
621 * entire process. This will get fixed when
622 * winbindd doesn't need to talk to smbd on
623 * a PDC. JRA.
626 winbind_off();
628 DEBUG(10, ("make_server_info_sam: our machine account %s "
629 "setting supplementary group list empty and "
630 "turning off winbindd requests.\n",
631 username));
632 } else {
633 NTSTATUS status = pdb_enum_group_memberships(result, sampass,
634 &result->sids, &gids,
635 &result->num_sids);
637 if (!NT_STATUS_IS_OK(status)) {
638 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
639 nt_errstr(status)));
640 result->sam_account = NULL; /* Don't free on error exit. */
641 TALLOC_FREE(result);
642 return status;
646 /* Add the "Unix Group" SID for each gid to catch mapped groups
647 and their Unix equivalent. This is to solve the backwards
648 compatibility problem of 'valid users = +ntadmin' where
649 ntadmin has been paired with "Domain Admins" in the group
650 mapping table. Otherwise smb.conf would need to be changed
651 to 'valid user = "Domain Admins"'. --jerry */
653 num_gids = result->num_sids;
654 for ( i=0; i<num_gids; i++ ) {
655 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
656 DEBUG(1,("make_server_info_sam: Failed to create SID "
657 "for gid %d!\n", gids[i]));
658 continue;
660 if (!add_sid_to_array_unique( result, &unix_group_sid,
661 &result->sids, &result->num_sids )) {
662 result->sam_account = NULL; /* Don't free on error exit. */
663 TALLOC_FREE(result);
664 return NT_STATUS_NO_MEMORY;
668 /* For now we throw away the gids and convert via sid_to_gid
669 * later. This needs fixing, but I'd like to get the code straight and
670 * simple first. */
672 TALLOC_FREE(gids);
674 DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
675 pdb_get_username(sampass), result->unix_name));
677 *server_info = result;
679 return NT_STATUS_OK;
683 * Add alias SIDs from memberships within the partially created token SID list
686 static NTSTATUS add_aliases(const DOM_SID *domain_sid,
687 struct nt_user_token *token)
689 uint32 *aliases;
690 size_t i, num_aliases;
691 NTSTATUS status;
692 TALLOC_CTX *tmp_ctx;
694 if (!(tmp_ctx = talloc_init("add_aliases"))) {
695 return NT_STATUS_NO_MEMORY;
698 aliases = NULL;
699 num_aliases = 0;
701 status = pdb_enum_alias_memberships(tmp_ctx, domain_sid,
702 token->user_sids,
703 token->num_sids,
704 &aliases, &num_aliases);
706 if (!NT_STATUS_IS_OK(status)) {
707 DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n",
708 nt_errstr(status)));
709 TALLOC_FREE(tmp_ctx);
710 return status;
713 for (i=0; i<num_aliases; i++) {
714 DOM_SID alias_sid;
715 sid_compose(&alias_sid, domain_sid, aliases[i]);
716 if (!add_sid_to_array_unique(token, &alias_sid,
717 &token->user_sids,
718 &token->num_sids)) {
719 DEBUG(0, ("add_sid_to_array failed\n"));
720 TALLOC_FREE(tmp_ctx);
721 return NT_STATUS_NO_MEMORY;
725 TALLOC_FREE(tmp_ctx);
726 return NT_STATUS_OK;
729 static NTSTATUS log_nt_token(TALLOC_CTX *tmp_ctx, NT_USER_TOKEN *token)
731 char *command;
732 char *group_sidstr;
733 size_t i;
735 if ((lp_log_nt_token_command() == NULL) ||
736 (strlen(lp_log_nt_token_command()) == 0)) {
737 return NT_STATUS_OK;
740 group_sidstr = talloc_strdup(tmp_ctx, "");
741 for (i=1; i<token->num_sids; i++) {
742 group_sidstr = talloc_asprintf(
743 tmp_ctx, "%s %s", group_sidstr,
744 sid_string_static(&token->user_sids[i]));
747 command = talloc_string_sub(
748 tmp_ctx, lp_log_nt_token_command(),
749 "%s", sid_string_static(&token->user_sids[0]));
750 command = talloc_string_sub(tmp_ctx, command, "%t", group_sidstr);
752 if (command == NULL) {
753 return NT_STATUS_NO_MEMORY;
756 DEBUG(8, ("running command: [%s]\n", command));
757 if (smbrun(command, NULL) != 0) {
758 DEBUG(0, ("Could not log NT token\n"));
759 return NT_STATUS_ACCESS_DENIED;
762 return NT_STATUS_OK;
765 /*******************************************************************
766 *******************************************************************/
768 static NTSTATUS add_builtin_administrators( struct nt_user_token *token )
770 DOM_SID domadm;
772 /* nothing to do if we aren't in a domain */
774 if ( !(IS_DC || lp_server_role()==ROLE_DOMAIN_MEMBER) ) {
775 return NT_STATUS_OK;
778 /* Find the Domain Admins SID */
780 if ( IS_DC ) {
781 sid_copy( &domadm, get_global_sam_sid() );
782 } else {
783 if ( !secrets_fetch_domain_sid( lp_workgroup(), &domadm ) )
784 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
786 sid_append_rid( &domadm, DOMAIN_GROUP_RID_ADMINS );
788 /* Add Administrators if the user beloongs to Domain Admins */
790 if ( nt_token_check_sid( &domadm, token ) ) {
791 if (!add_sid_to_array(token, &global_sid_Builtin_Administrators,
792 &token->user_sids, &token->num_sids)) {
793 return NT_STATUS_NO_MEMORY;
797 return NT_STATUS_OK;
800 /*******************************************************************
801 *******************************************************************/
803 static NTSTATUS create_builtin_users( void )
805 NTSTATUS status;
806 DOM_SID dom_users;
808 status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_USERS );
809 if ( !NT_STATUS_IS_OK(status) ) {
810 DEBUG(0,("create_builtin_users: Failed to create Users\n"));
811 return status;
814 /* add domain users */
815 if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
816 && secrets_fetch_domain_sid(lp_workgroup(), &dom_users))
818 sid_append_rid(&dom_users, DOMAIN_GROUP_RID_USERS );
819 status = pdb_add_aliasmem( &global_sid_Builtin_Users, &dom_users);
820 if ( !NT_STATUS_IS_OK(status) ) {
821 DEBUG(0,("create_builtin_users: Failed to add Domain Users to"
822 " Users\n"));
823 return status;
827 return NT_STATUS_OK;
830 /*******************************************************************
831 *******************************************************************/
833 static NTSTATUS create_builtin_administrators( void )
835 NTSTATUS status;
836 DOM_SID dom_admins, root_sid;
837 fstring root_name;
838 enum lsa_SidType type;
839 TALLOC_CTX *ctx;
840 BOOL ret;
842 status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_ADMINS );
843 if ( !NT_STATUS_IS_OK(status) ) {
844 DEBUG(0,("create_builtin_administrators: Failed to create Administrators\n"));
845 return status;
848 /* add domain admins */
849 if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
850 && secrets_fetch_domain_sid(lp_workgroup(), &dom_admins))
852 sid_append_rid(&dom_admins, DOMAIN_GROUP_RID_ADMINS);
853 status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &dom_admins );
854 if ( !NT_STATUS_IS_OK(status) ) {
855 DEBUG(0,("create_builtin_administrators: Failed to add Domain Admins"
856 " Administrators\n"));
857 return status;
861 /* add root */
862 if ( (ctx = talloc_init("create_builtin_administrators")) == NULL ) {
863 return NT_STATUS_NO_MEMORY;
865 fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
866 ret = lookup_name( ctx, root_name, LOOKUP_NAME_DOMAIN, NULL, NULL, &root_sid, &type );
867 TALLOC_FREE( ctx );
869 if ( ret ) {
870 status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &root_sid );
871 if ( !NT_STATUS_IS_OK(status) ) {
872 DEBUG(0,("create_builtin_administrators: Failed to add root"
873 " Administrators\n"));
874 return status;
878 return NT_STATUS_OK;
881 /*******************************************************************
882 Create a NT token for the user, expanding local aliases
883 *******************************************************************/
885 static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
886 const DOM_SID *user_sid,
887 BOOL is_guest,
888 int num_groupsids,
889 const DOM_SID *groupsids)
891 struct nt_user_token *result = NULL;
892 int i;
893 NTSTATUS status;
894 gid_t gid;
896 DEBUG(10, ("Create local NT token for %s\n", sid_string_static(user_sid)));
898 if (!(result = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN))) {
899 DEBUG(0, ("talloc failed\n"));
900 return NULL;
903 /* Add the user and primary group sid */
905 if (!add_sid_to_array(result, user_sid,
906 &result->user_sids, &result->num_sids)) {
907 return NULL;
910 /* For guest, num_groupsids may be zero. */
911 if (num_groupsids) {
912 if (!add_sid_to_array(result, &groupsids[0],
913 &result->user_sids, &result->num_sids)) {
914 return NULL;
918 /* Add in BUILTIN sids */
920 if (!add_sid_to_array(result, &global_sid_World,
921 &result->user_sids, &result->num_sids)) {
922 return NULL;
924 if (!add_sid_to_array(result, &global_sid_Network,
925 &result->user_sids, &result->num_sids)) {
926 return NULL;
929 if (is_guest) {
930 if (!add_sid_to_array(result, &global_sid_Builtin_Guests,
931 &result->user_sids, &result->num_sids)) {
932 return NULL;
934 } else {
935 if (!add_sid_to_array(result, &global_sid_Authenticated_Users,
936 &result->user_sids, &result->num_sids)) {
937 return NULL;
941 /* Now the SIDs we got from authentication. These are the ones from
942 * the info3 struct or from the pdb_enum_group_memberships, depending
943 * on who authenticated the user.
944 * Note that we start the for loop at "1" here, we already added the
945 * first group sid as primary above. */
947 for (i=1; i<num_groupsids; i++) {
948 if (!add_sid_to_array_unique(result, &groupsids[i],
949 &result->user_sids, &result->num_sids)) {
950 return NULL;
954 /* Deal with the BUILTIN\Administrators group. If the SID can
955 be resolved then assume that the add_aliasmem( S-1-5-32 )
956 handled it. */
958 if ( !sid_to_gid( &global_sid_Builtin_Administrators, &gid ) ) {
959 /* We can only create a mapping if winbind is running
960 and the nested group functionality has been enabled */
962 if ( lp_winbind_nested_groups() && winbind_ping() ) {
963 become_root();
964 status = create_builtin_administrators( );
965 if ( !NT_STATUS_IS_OK(status) ) {
966 DEBUG(2,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
967 /* don't fail, just log the message */
969 unbecome_root();
971 else {
972 status = add_builtin_administrators( result );
973 if ( !NT_STATUS_IS_OK(status) ) {
974 /* just log a complaint but do not fail */
975 DEBUG(3,("create_local_nt_token: failed to check for local Administrators"
976 " membership (%s)\n", nt_errstr(status)));
981 /* Deal with the BUILTIN\Users group. If the SID can
982 be resolved then assume that the add_aliasmem( S-1-5-32 )
983 handled it. */
985 if ( !sid_to_gid( &global_sid_Builtin_Users, &gid ) ) {
986 /* We can only create a mapping if winbind is running
987 and the nested group functionality has been enabled */
989 if ( lp_winbind_nested_groups() && winbind_ping() ) {
990 become_root();
991 status = create_builtin_users( );
992 if ( !NT_STATUS_IS_OK(status) ) {
993 DEBUG(2,("create_local_nt_token: Failed to create BUILTIN\\Users group!\n"));
994 /* don't fail, just log the message */
996 unbecome_root();
1000 /* Deal with local groups */
1002 if (lp_winbind_nested_groups()) {
1004 become_root();
1006 /* Now add the aliases. First the one from our local SAM */
1008 status = add_aliases(get_global_sam_sid(), result);
1010 if (!NT_STATUS_IS_OK(status)) {
1011 unbecome_root();
1012 TALLOC_FREE(result);
1013 return NULL;
1016 /* Finally the builtin ones */
1018 status = add_aliases(&global_sid_Builtin, result);
1020 if (!NT_STATUS_IS_OK(status)) {
1021 unbecome_root();
1022 TALLOC_FREE(result);
1023 return NULL;
1026 unbecome_root();
1030 get_privileges_for_sids(&result->privileges, result->user_sids,
1031 result->num_sids);
1032 return result;
1036 * Create the token to use from server_info->sam_account and
1037 * server_info->sids (the info3/sam groups). Find the unix gids.
1040 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
1042 TALLOC_CTX *mem_ctx;
1043 NTSTATUS status;
1044 size_t i;
1047 mem_ctx = talloc_new(NULL);
1048 if (mem_ctx == NULL) {
1049 DEBUG(0, ("talloc_new failed\n"));
1050 return NT_STATUS_NO_MEMORY;
1054 * If winbind is not around, we can not make much use of the SIDs the
1055 * domain controller provided us with. Likewise if the user name was
1056 * mapped to some local unix user.
1059 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
1060 (server_info->was_mapped)) {
1061 status = create_token_from_username(server_info,
1062 server_info->unix_name,
1063 server_info->guest,
1064 &server_info->uid,
1065 &server_info->gid,
1066 &server_info->unix_name,
1067 &server_info->ptok);
1069 } else {
1070 server_info->ptok = create_local_nt_token(
1071 server_info,
1072 pdb_get_user_sid(server_info->sam_account),
1073 server_info->guest,
1074 server_info->num_sids, server_info->sids);
1075 status = server_info->ptok ?
1076 NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
1079 if (!NT_STATUS_IS_OK(status)) {
1080 TALLOC_FREE(mem_ctx);
1081 return status;
1084 /* Convert the SIDs to gids. */
1086 server_info->n_groups = 0;
1087 server_info->groups = NULL;
1089 /* Start at index 1, where the groups start. */
1091 for (i=1; i<server_info->ptok->num_sids; i++) {
1092 gid_t gid;
1093 DOM_SID *sid = &server_info->ptok->user_sids[i];
1095 if (!sid_to_gid(sid, &gid)) {
1096 DEBUG(10, ("Could not convert SID %s to gid, "
1097 "ignoring it\n", sid_string_static(sid)));
1098 continue;
1100 add_gid_to_array_unique(server_info, gid, &server_info->groups,
1101 &server_info->n_groups);
1104 debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
1106 status = log_nt_token(mem_ctx, server_info->ptok);
1108 TALLOC_FREE(mem_ctx);
1109 return status;
1113 * Create an artificial NT token given just a username. (Initially indended
1114 * for force user)
1116 * We go through lookup_name() to avoid problems we had with 'winbind use
1117 * default domain'.
1119 * We have 3 cases:
1121 * unmapped unix users: Go directly to nss to find the user's group.
1123 * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
1125 * If the user is provided by winbind, the primary gid is set to "domain
1126 * users" of the user's domain. For an explanation why this is necessary, see
1127 * the thread starting at
1128 * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
1131 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
1132 BOOL is_guest,
1133 uid_t *uid, gid_t *gid,
1134 char **found_username,
1135 struct nt_user_token **token)
1137 NTSTATUS result = NT_STATUS_NO_SUCH_USER;
1138 TALLOC_CTX *tmp_ctx;
1139 DOM_SID user_sid;
1140 enum lsa_SidType type;
1141 gid_t *gids;
1142 DOM_SID *group_sids;
1143 DOM_SID unix_group_sid;
1144 size_t num_group_sids;
1145 size_t num_gids;
1146 size_t i;
1148 tmp_ctx = talloc_new(NULL);
1149 if (tmp_ctx == NULL) {
1150 DEBUG(0, ("talloc_new failed\n"));
1151 return NT_STATUS_NO_MEMORY;
1154 if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
1155 NULL, NULL, &user_sid, &type)) {
1156 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
1157 goto done;
1160 if (type != SID_NAME_USER) {
1161 DEBUG(1, ("%s is a %s, not a user\n", username,
1162 sid_type_lookup(type)));
1163 goto done;
1166 if (!sid_to_uid(&user_sid, uid)) {
1167 DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
1168 username, sid_string_static(&user_sid)));
1169 goto done;
1172 if (sid_check_is_in_our_domain(&user_sid)) {
1173 BOOL ret;
1175 /* This is a passdb user, so ask passdb */
1177 struct samu *sam_acct = NULL;
1179 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
1180 result = NT_STATUS_NO_MEMORY;
1181 goto done;
1184 become_root();
1185 ret = pdb_getsampwsid(sam_acct, &user_sid);
1186 unbecome_root();
1188 if (!ret) {
1189 DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
1190 sid_string_static(&user_sid), username));
1191 DEBUGADD(1, ("Fall back to unix user %s\n", username));
1192 goto unix_user;
1195 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
1196 &group_sids, &gids,
1197 &num_group_sids);
1198 if (!NT_STATUS_IS_OK(result)) {
1199 DEBUG(10, ("enum_group_memberships failed for %s\n",
1200 username));
1201 DEBUGADD(1, ("Fall back to unix user %s\n", username));
1202 goto unix_user;
1205 /* see the smb_panic() in pdb_default_enum_group_memberships */
1206 SMB_ASSERT(num_group_sids > 0);
1208 *gid = gids[0];
1210 /* Ensure we're returning the found_username on the right context. */
1211 *found_username = talloc_strdup(mem_ctx,
1212 pdb_get_username(sam_acct));
1214 } else if (sid_check_is_in_unix_users(&user_sid)) {
1216 /* This is a unix user not in passdb. We need to ask nss
1217 * directly, without consulting passdb */
1219 struct passwd *pass;
1222 * This goto target is used as a fallback for the passdb
1223 * case. The concrete bug report is when passdb gave us an
1224 * unmapped gid.
1227 unix_user:
1229 uid_to_unix_users_sid(*uid, &user_sid);
1231 pass = getpwuid_alloc(tmp_ctx, *uid);
1232 if (pass == NULL) {
1233 DEBUG(1, ("getpwuid(%d) for user %s failed\n",
1234 *uid, username));
1235 goto done;
1238 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
1239 &gids, &num_group_sids)) {
1240 DEBUG(1, ("getgroups_unix_user for user %s failed\n",
1241 username));
1242 goto done;
1245 if (num_group_sids) {
1246 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
1247 if (group_sids == NULL) {
1248 DEBUG(1, ("TALLOC_ARRAY failed\n"));
1249 result = NT_STATUS_NO_MEMORY;
1250 goto done;
1252 } else {
1253 group_sids = NULL;
1256 for (i=0; i<num_group_sids; i++) {
1257 gid_to_sid(&group_sids[i], gids[i]);
1260 /* In getgroups_unix_user we always set the primary gid */
1261 SMB_ASSERT(num_group_sids > 0);
1263 *gid = gids[0];
1265 /* Ensure we're returning the found_username on the right context. */
1266 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
1267 } else {
1269 /* This user is from winbind, force the primary gid to the
1270 * user's "domain users" group. Under certain circumstances
1271 * (user comes from NT4), this might be a loss of
1272 * information. But we can not rely on winbind getting the
1273 * correct info. AD might prohibit winbind looking up that
1274 * information. */
1276 uint32 dummy;
1278 num_group_sids = 1;
1279 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
1280 if (group_sids == NULL) {
1281 DEBUG(1, ("TALLOC_ARRAY failed\n"));
1282 result = NT_STATUS_NO_MEMORY;
1283 goto done;
1286 sid_copy(&group_sids[0], &user_sid);
1287 sid_split_rid(&group_sids[0], &dummy);
1288 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
1290 if (!sid_to_gid(&group_sids[0], gid)) {
1291 DEBUG(1, ("sid_to_gid(%s) failed\n",
1292 sid_string_static(&group_sids[0])));
1293 goto done;
1296 gids = gid;
1298 /* Ensure we're returning the found_username on the right context. */
1299 *found_username = talloc_strdup(mem_ctx, username);
1302 /* Add the "Unix Group" SID for each gid to catch mapped groups
1303 and their Unix equivalent. This is to solve the backwards
1304 compatibility problem of 'valid users = +ntadmin' where
1305 ntadmin has been paired with "Domain Admins" in the group
1306 mapping table. Otherwise smb.conf would need to be changed
1307 to 'valid user = "Domain Admins"'. --jerry */
1309 num_gids = num_group_sids;
1310 for ( i=0; i<num_gids; i++ ) {
1311 gid_t high, low;
1313 /* don't pickup anything managed by Winbind */
1315 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
1316 continue;
1318 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
1319 DEBUG(1,("create_token_from_username: Failed to create SID "
1320 "for gid %d!\n", gids[i]));
1321 continue;
1323 if (!add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
1324 &group_sids, &num_group_sids )) {
1325 result = NT_STATUS_NO_MEMORY;
1326 goto done;
1330 /* Ensure we're creating the nt_token on the right context. */
1331 *token = create_local_nt_token(mem_ctx, &user_sid,
1332 is_guest, num_group_sids, group_sids);
1334 if ((*token == NULL) || (*found_username == NULL)) {
1335 result = NT_STATUS_NO_MEMORY;
1336 goto done;
1339 result = NT_STATUS_OK;
1340 done:
1341 TALLOC_FREE(tmp_ctx);
1342 return result;
1345 /***************************************************************************
1346 Build upon create_token_from_username:
1348 Expensive helper function to figure out whether a user given its name is
1349 member of a particular group.
1350 ***************************************************************************/
1352 BOOL user_in_group_sid(const char *username, const DOM_SID *group_sid)
1354 NTSTATUS status;
1355 uid_t uid;
1356 gid_t gid;
1357 char *found_username;
1358 struct nt_user_token *token;
1359 BOOL result;
1361 TALLOC_CTX *mem_ctx;
1363 mem_ctx = talloc_new(NULL);
1364 if (mem_ctx == NULL) {
1365 DEBUG(0, ("talloc_new failed\n"));
1366 return False;
1369 status = create_token_from_username(mem_ctx, username, False,
1370 &uid, &gid, &found_username,
1371 &token);
1373 if (!NT_STATUS_IS_OK(status)) {
1374 DEBUG(10, ("could not create token for %s\n", username));
1375 return False;
1378 result = nt_token_check_sid(group_sid, token);
1380 TALLOC_FREE(mem_ctx);
1381 return result;
1385 BOOL user_in_group(const char *username, const char *groupname)
1387 TALLOC_CTX *mem_ctx;
1388 DOM_SID group_sid;
1389 BOOL ret;
1391 mem_ctx = talloc_new(NULL);
1392 if (mem_ctx == NULL) {
1393 DEBUG(0, ("talloc_new failed\n"));
1394 return False;
1397 ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1398 NULL, NULL, &group_sid, NULL);
1399 TALLOC_FREE(mem_ctx);
1401 if (!ret) {
1402 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1403 return False;
1406 return user_in_group_sid(username, &group_sid);
1410 /***************************************************************************
1411 Make (and fill) a user_info struct from a 'struct passwd' by conversion
1412 to a struct samu
1413 ***************************************************************************/
1415 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
1416 char *unix_username,
1417 struct passwd *pwd)
1419 NTSTATUS status;
1420 struct samu *sampass = NULL;
1421 gid_t *gids;
1422 char *qualified_name = NULL;
1423 TALLOC_CTX *mem_ctx = NULL;
1424 DOM_SID u_sid;
1425 enum lsa_SidType type;
1426 auth_serversupplied_info *result;
1428 if ( !(sampass = samu_new( NULL )) ) {
1429 return NT_STATUS_NO_MEMORY;
1432 status = samu_set_unix( sampass, pwd );
1433 if (!NT_STATUS_IS_OK(status)) {
1434 return status;
1437 result = make_server_info(NULL);
1438 if (result == NULL) {
1439 TALLOC_FREE(sampass);
1440 return NT_STATUS_NO_MEMORY;
1443 result->sam_account = sampass;
1444 result->unix_name = talloc_strdup(result, unix_username);
1445 result->uid = pwd->pw_uid;
1446 result->gid = pwd->pw_gid;
1448 status = pdb_enum_group_memberships(result, sampass,
1449 &result->sids, &gids,
1450 &result->num_sids);
1452 if (!NT_STATUS_IS_OK(status)) {
1453 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1454 nt_errstr(status)));
1455 TALLOC_FREE(result);
1456 return status;
1460 * The SID returned in server_info->sam_account is based
1461 * on our SAM sid even though for a pure UNIX account this should
1462 * not be the case as it doesn't really exist in the SAM db.
1463 * This causes lookups on "[in]valid users" to fail as they
1464 * will lookup this name as a "Unix User" SID to check against
1465 * the user token. Fix this by adding the "Unix User"\unix_username
1466 * SID to the sid array. The correct fix should probably be
1467 * changing the server_info->sam_account user SID to be a
1468 * S-1-22 Unix SID, but this might break old configs where
1469 * plaintext passwords were used with no SAM backend.
1472 mem_ctx = talloc_init("make_server_info_pw_tmp");
1473 if (!mem_ctx) {
1474 TALLOC_FREE(result);
1475 return NT_STATUS_NO_MEMORY;
1478 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
1479 unix_users_domain_name(),
1480 unix_username );
1481 if (!qualified_name) {
1482 TALLOC_FREE(result);
1483 TALLOC_FREE(mem_ctx);
1484 return NT_STATUS_NO_MEMORY;
1487 if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
1488 NULL, NULL,
1489 &u_sid, &type)) {
1490 TALLOC_FREE(result);
1491 TALLOC_FREE(mem_ctx);
1492 return NT_STATUS_NO_SUCH_USER;
1495 TALLOC_FREE(mem_ctx);
1497 if (type != SID_NAME_USER) {
1498 TALLOC_FREE(result);
1499 return NT_STATUS_NO_SUCH_USER;
1502 if (!add_sid_to_array_unique(result, &u_sid,
1503 &result->sids,
1504 &result->num_sids)) {
1505 TALLOC_FREE(result);
1506 return NT_STATUS_NO_MEMORY;
1509 /* For now we throw away the gids and convert via sid_to_gid
1510 * later. This needs fixing, but I'd like to get the code straight and
1511 * simple first. */
1512 TALLOC_FREE(gids);
1514 *server_info = result;
1516 return NT_STATUS_OK;
1519 /***************************************************************************
1520 Make (and fill) a user_info struct for a guest login.
1521 This *must* succeed for smbd to start. If there is no mapping entry for
1522 the guest gid, then create one.
1523 ***************************************************************************/
1525 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1527 NTSTATUS status;
1528 struct samu *sampass = NULL;
1529 DOM_SID guest_sid;
1530 BOOL ret;
1531 static const char zeros[16] = { 0, };
1533 if ( !(sampass = samu_new( NULL )) ) {
1534 return NT_STATUS_NO_MEMORY;
1537 sid_copy(&guest_sid, get_global_sam_sid());
1538 sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1540 become_root();
1541 ret = pdb_getsampwsid(sampass, &guest_sid);
1542 unbecome_root();
1544 if (!ret) {
1545 TALLOC_FREE(sampass);
1546 return NT_STATUS_NO_SUCH_USER;
1549 status = make_server_info_sam(server_info, sampass);
1550 if (!NT_STATUS_IS_OK(status)) {
1551 TALLOC_FREE(sampass);
1552 return status;
1555 (*server_info)->guest = True;
1557 status = create_local_token(*server_info);
1558 if (!NT_STATUS_IS_OK(status)) {
1559 DEBUG(10, ("create_local_token failed: %s\n",
1560 nt_errstr(status)));
1561 return status;
1564 /* annoying, but the Guest really does have a session key, and it is
1565 all zeros! */
1566 (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1567 (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1569 return NT_STATUS_OK;
1572 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
1574 auth_serversupplied_info *dst;
1576 dst = make_server_info(NULL);
1577 if (dst == NULL) {
1578 return NULL;
1581 dst->guest = src->guest;
1582 dst->uid = src->uid;
1583 dst->gid = src->gid;
1584 dst->n_groups = src->n_groups;
1585 if (src->n_groups != 0) {
1586 dst->groups = (gid_t *)TALLOC_MEMDUP(
1587 dst, src->groups, sizeof(gid_t)*dst->n_groups);
1588 } else {
1589 dst->groups = NULL;
1592 if (src->ptok) {
1593 dst->ptok = dup_nt_token(dst, src->ptok);
1594 if (!dst->ptok) {
1595 TALLOC_FREE(dst);
1596 return NULL;
1600 dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1601 src->user_session_key.length);
1603 dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1604 src->lm_session_key.length);
1606 dst->sam_account = samu_new(NULL);
1607 if (!dst->sam_account) {
1608 TALLOC_FREE(dst);
1609 return NULL;
1612 if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1613 TALLOC_FREE(dst);
1614 return NULL;
1617 dst->pam_handle = NULL;
1618 dst->unix_name = talloc_strdup(dst, src->unix_name);
1619 if (!dst->unix_name) {
1620 TALLOC_FREE(dst);
1621 return NULL;
1624 return dst;
1627 static auth_serversupplied_info *guest_info = NULL;
1629 BOOL init_guest_info(void)
1631 if (guest_info != NULL)
1632 return True;
1634 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1637 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
1639 *server_info = copy_serverinfo(guest_info);
1640 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1643 BOOL copy_current_user(struct current_user *dst, struct current_user *src)
1645 gid_t *groups;
1646 NT_USER_TOKEN *nt_token;
1648 groups = (gid_t *)memdup(src->ut.groups,
1649 sizeof(gid_t) * src->ut.ngroups);
1650 if ((src->ut.ngroups != 0) && (groups == NULL)) {
1651 return False;
1654 nt_token = dup_nt_token(NULL, src->nt_user_token);
1655 if (nt_token == NULL) {
1656 SAFE_FREE(groups);
1657 return False;
1660 dst->conn = src->conn;
1661 dst->vuid = src->vuid;
1662 dst->ut.uid = src->ut.uid;
1663 dst->ut.gid = src->ut.gid;
1664 dst->ut.ngroups = src->ut.ngroups;
1665 dst->ut.groups = groups;
1666 dst->nt_user_token = nt_token;
1667 return True;
1670 BOOL set_current_user_guest(struct current_user *dst)
1672 gid_t *groups;
1673 NT_USER_TOKEN *nt_token;
1675 groups = (gid_t *)memdup(guest_info->groups,
1676 sizeof(gid_t) * guest_info->n_groups);
1677 if (groups == NULL) {
1678 return False;
1681 nt_token = dup_nt_token(NULL, guest_info->ptok);
1682 if (nt_token == NULL) {
1683 SAFE_FREE(groups);
1684 return False;
1687 TALLOC_FREE(dst->nt_user_token);
1688 SAFE_FREE(dst->ut.groups);
1690 /* dst->conn is never really dereferenced, it's only tested for
1691 * equality in uid.c */
1692 dst->conn = NULL;
1694 dst->vuid = UID_FIELD_INVALID;
1695 dst->ut.uid = guest_info->uid;
1696 dst->ut.gid = guest_info->gid;
1697 dst->ut.ngroups = guest_info->n_groups;
1698 dst->ut.groups = groups;
1699 dst->nt_user_token = nt_token;
1700 return True;
1703 /***************************************************************************
1704 Purely internal function for make_server_info_info3
1705 Fill the sam account from getpwnam
1706 ***************************************************************************/
1707 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
1708 const char *domain,
1709 const char *username,
1710 char **found_username,
1711 uid_t *uid, gid_t *gid,
1712 struct samu *account,
1713 BOOL *username_was_mapped)
1715 NTSTATUS nt_status;
1716 fstring dom_user, lower_username;
1717 fstring real_username;
1718 struct passwd *passwd;
1720 fstrcpy( lower_username, username );
1721 strlower_m( lower_username );
1723 fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(),
1724 lower_username);
1726 /* Get the passwd struct. Try to create the account is necessary. */
1728 *username_was_mapped = map_username( dom_user );
1730 if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1731 return NT_STATUS_NO_SUCH_USER;
1733 *uid = passwd->pw_uid;
1734 *gid = passwd->pw_gid;
1736 /* This is pointless -- there is no suport for differing
1737 unix and windows names. Make sure to always store the
1738 one we actually looked up and succeeded. Have I mentioned
1739 why I hate the 'winbind use default domain' parameter?
1740 --jerry */
1742 *found_username = talloc_strdup( mem_ctx, real_username );
1744 DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1746 nt_status = samu_set_unix( account, passwd );
1748 TALLOC_FREE(passwd);
1750 return nt_status;
1753 /****************************************************************************
1754 Wrapper to allow the getpwnam() call to strip the domain name and
1755 try again in case a local UNIX user is already there. Also run through
1756 the username if we fallback to the username only.
1757 ****************************************************************************/
1759 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1760 fstring save_username, BOOL create )
1762 struct passwd *pw = NULL;
1763 char *p;
1764 fstring username;
1766 /* we only save a copy of the username it has been mangled
1767 by winbindd use default domain */
1769 save_username[0] = '\0';
1771 /* don't call map_username() here since it has to be done higher
1772 up the stack so we don't call it mutliple times */
1774 fstrcpy( username, domuser );
1776 p = strchr_m( username, *lp_winbind_separator() );
1778 /* code for a DOMAIN\user string */
1780 if ( p ) {
1781 fstring strip_username;
1783 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1784 if ( pw ) {
1785 /* make sure we get the case of the username correct */
1786 /* work around 'winbind use default domain = yes' */
1788 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1789 char *domain;
1791 /* split the domain and username into 2 strings */
1792 *p = '\0';
1793 domain = username;
1795 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1797 else
1798 fstrcpy( save_username, pw->pw_name );
1800 /* whew -- done! */
1801 return pw;
1804 /* setup for lookup of just the username */
1805 /* remember that p and username are overlapping memory */
1807 p++;
1808 fstrcpy( strip_username, p );
1809 fstrcpy( username, strip_username );
1812 /* just lookup a plain username */
1814 pw = Get_Pwnam_alloc(mem_ctx, username);
1816 /* Create local user if requested but only if winbindd
1817 is not running. We need to protect against cases
1818 where winbindd is failing and then prematurely
1819 creating users in /etc/passwd */
1821 if ( !pw && create && !winbind_ping() ) {
1822 /* Don't add a machine account. */
1823 if (username[strlen(username)-1] == '$')
1824 return NULL;
1826 smb_create_user(NULL, username, NULL);
1827 pw = Get_Pwnam_alloc(mem_ctx, username);
1830 /* one last check for a valid passwd struct */
1832 if ( pw )
1833 fstrcpy( save_username, pw->pw_name );
1835 return pw;
1838 /***************************************************************************
1839 Make a server_info struct from the info3 returned by a domain logon
1840 ***************************************************************************/
1842 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1843 const char *sent_nt_username,
1844 const char *domain,
1845 auth_serversupplied_info **server_info,
1846 NET_USER_INFO_3 *info3)
1848 static const char zeros[16] = { 0, };
1850 NTSTATUS nt_status = NT_STATUS_OK;
1851 char *found_username;
1852 const char *nt_domain;
1853 const char *nt_username;
1854 struct samu *sam_account = NULL;
1855 DOM_SID user_sid;
1856 DOM_SID group_sid;
1857 BOOL username_was_mapped;
1859 uid_t uid;
1860 gid_t gid;
1862 size_t i;
1864 auth_serversupplied_info *result;
1867 Here is where we should check the list of
1868 trusted domains, and verify that the SID
1869 matches.
1872 sid_copy(&user_sid, &info3->dom_sid.sid);
1873 if (!sid_append_rid(&user_sid, info3->user_rid)) {
1874 return NT_STATUS_INVALID_PARAMETER;
1877 sid_copy(&group_sid, &info3->dom_sid.sid);
1878 if (!sid_append_rid(&group_sid, info3->group_rid)) {
1879 return NT_STATUS_INVALID_PARAMETER;
1882 if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1883 /* If the server didn't give us one, just use the one we sent
1884 * them */
1885 nt_username = sent_nt_username;
1888 if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1889 /* If the server didn't give us one, just use the one we sent
1890 * them */
1891 nt_domain = domain;
1894 /* try to fill the SAM account.. If getpwnam() fails, then try the
1895 add user script (2.2.x behavior).
1897 We use the _unmapped_ username here in an attempt to provide
1898 consistent username mapping behavior between kerberos and NTLM[SSP]
1899 authentication in domain mode security. I.E. Username mapping
1900 should be applied to the fully qualified username
1901 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1902 called map_username() unnecessarily in make_user_info_map() but
1903 that is how the current code is designed. Making the change here
1904 is the least disruptive place. -- jerry */
1906 if ( !(sam_account = samu_new( NULL )) ) {
1907 return NT_STATUS_NO_MEMORY;
1910 /* this call will try to create the user if necessary */
1912 nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1913 &found_username, &uid, &gid, sam_account,
1914 &username_was_mapped);
1917 /* if we still don't have a valid unix account check for
1918 'map to guest = bad uid' */
1920 if (!NT_STATUS_IS_OK(nt_status)) {
1921 TALLOC_FREE( sam_account );
1922 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1923 make_server_info_guest(server_info);
1924 return NT_STATUS_OK;
1926 return nt_status;
1929 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1930 TALLOC_FREE(sam_account);
1931 return NT_STATUS_NO_MEMORY;
1934 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1935 TALLOC_FREE(sam_account);
1936 return NT_STATUS_NO_MEMORY;
1939 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1940 TALLOC_FREE(sam_account);
1941 return NT_STATUS_NO_MEMORY;
1944 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1945 TALLOC_FREE(sam_account);
1946 return NT_STATUS_UNSUCCESSFUL;
1949 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1950 TALLOC_FREE(sam_account);
1951 return NT_STATUS_UNSUCCESSFUL;
1954 if (!pdb_set_fullname(sam_account,
1955 unistr2_static(&(info3->uni_full_name)),
1956 PDB_CHANGED)) {
1957 TALLOC_FREE(sam_account);
1958 return NT_STATUS_NO_MEMORY;
1961 if (!pdb_set_logon_script(sam_account,
1962 unistr2_static(&(info3->uni_logon_script)),
1963 PDB_CHANGED)) {
1964 TALLOC_FREE(sam_account);
1965 return NT_STATUS_NO_MEMORY;
1968 if (!pdb_set_profile_path(sam_account,
1969 unistr2_static(&(info3->uni_profile_path)),
1970 PDB_CHANGED)) {
1971 TALLOC_FREE(sam_account);
1972 return NT_STATUS_NO_MEMORY;
1975 if (!pdb_set_homedir(sam_account,
1976 unistr2_static(&(info3->uni_home_dir)),
1977 PDB_CHANGED)) {
1978 TALLOC_FREE(sam_account);
1979 return NT_STATUS_NO_MEMORY;
1982 if (!pdb_set_dir_drive(sam_account,
1983 unistr2_static(&(info3->uni_dir_drive)),
1984 PDB_CHANGED)) {
1985 TALLOC_FREE(sam_account);
1986 return NT_STATUS_NO_MEMORY;
1989 if (!pdb_set_acct_ctrl(sam_account, info3->acct_flags, PDB_CHANGED)) {
1990 TALLOC_FREE(sam_account);
1991 return NT_STATUS_NO_MEMORY;
1994 if (!pdb_set_pass_last_set_time(
1995 sam_account,
1996 nt_time_to_unix(info3->pass_last_set_time),
1997 PDB_CHANGED)) {
1998 TALLOC_FREE(sam_account);
1999 return NT_STATUS_NO_MEMORY;
2002 if (!pdb_set_pass_can_change_time(
2003 sam_account,
2004 nt_time_to_unix(info3->pass_can_change_time),
2005 PDB_CHANGED)) {
2006 TALLOC_FREE(sam_account);
2007 return NT_STATUS_NO_MEMORY;
2010 if (!pdb_set_pass_must_change_time(
2011 sam_account,
2012 nt_time_to_unix(info3->pass_must_change_time),
2013 PDB_CHANGED)) {
2014 TALLOC_FREE(sam_account);
2015 return NT_STATUS_NO_MEMORY;
2018 result = make_server_info(NULL);
2019 if (result == NULL) {
2020 DEBUG(4, ("make_server_info failed!\n"));
2021 TALLOC_FREE(sam_account);
2022 return NT_STATUS_NO_MEMORY;
2025 /* save this here to _net_sam_logon() doesn't fail (it assumes a
2026 valid struct samu) */
2028 result->sam_account = sam_account;
2029 result->unix_name = talloc_strdup(result, found_username);
2031 /* Fill in the unix info we found on the way */
2033 result->uid = uid;
2034 result->gid = gid;
2036 /* Create a 'combined' list of all SIDs we might want in the SD */
2038 result->num_sids = 0;
2039 result->sids = NULL;
2041 /* and create (by appending rids) the 'domain' sids */
2043 for (i = 0; i < info3->num_groups2; i++) {
2044 DOM_SID sid;
2045 if (!sid_compose(&sid, &info3->dom_sid.sid,
2046 info3->gids[i].g_rid)) {
2047 DEBUG(3,("could not append additional group rid "
2048 "0x%x\n", info3->gids[i].g_rid));
2049 TALLOC_FREE(result);
2050 return NT_STATUS_INVALID_PARAMETER;
2052 if (!add_sid_to_array(result, &sid, &result->sids,
2053 &result->num_sids)) {
2054 TALLOC_FREE(result);
2055 return NT_STATUS_NO_MEMORY;
2059 /* Copy 'other' sids. We need to do sid filtering here to
2060 prevent possible elevation of privileges. See:
2062 http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
2065 for (i = 0; i < info3->num_other_sids; i++) {
2066 if (!add_sid_to_array(result, &info3->other_sids[i].sid,
2067 &result->sids,
2068 &result->num_sids)) {
2069 TALLOC_FREE(result);
2070 return NT_STATUS_NO_MEMORY;
2074 result->login_server = unistr2_tdup(result,
2075 &(info3->uni_logon_srv));
2077 /* ensure we are never given NULL session keys */
2079 if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
2080 result->user_session_key = data_blob(NULL, 0);
2081 } else {
2082 result->user_session_key = data_blob_talloc(
2083 result, info3->user_sess_key,
2084 sizeof(info3->user_sess_key));
2087 if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
2088 result->lm_session_key = data_blob(NULL, 0);
2089 } else {
2090 result->lm_session_key = data_blob_talloc(
2091 result, info3->lm_sess_key,
2092 sizeof(info3->lm_sess_key));
2095 result->was_mapped = username_was_mapped;
2097 *server_info = result;
2099 return NT_STATUS_OK;
2102 /***************************************************************************
2103 Free a user_info struct
2104 ***************************************************************************/
2106 void free_user_info(auth_usersupplied_info **user_info)
2108 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
2109 if (*user_info != NULL) {
2110 if ((*user_info)->smb_name) {
2111 DEBUG(10,("structure was created for %s\n",
2112 (*user_info)->smb_name));
2114 SAFE_FREE((*user_info)->smb_name);
2115 SAFE_FREE((*user_info)->internal_username);
2116 SAFE_FREE((*user_info)->client_domain);
2117 SAFE_FREE((*user_info)->domain);
2118 SAFE_FREE((*user_info)->wksta_name);
2119 data_blob_free(&(*user_info)->lm_resp);
2120 data_blob_free(&(*user_info)->nt_resp);
2121 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
2122 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
2123 data_blob_clear_free(&(*user_info)->plaintext_password);
2124 ZERO_STRUCT(**user_info);
2126 SAFE_FREE(*user_info);
2129 /***************************************************************************
2130 Make an auth_methods struct
2131 ***************************************************************************/
2133 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method)
2135 if (!auth_context) {
2136 smb_panic("no auth_context supplied to "
2137 "make_auth_methods()!\n");
2140 if (!auth_method) {
2141 smb_panic("make_auth_methods: pointer to auth_method pointer "
2142 "is NULL!\n");
2145 *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
2146 if (!*auth_method) {
2147 DEBUG(0,("make_auth_method: malloc failed!\n"));
2148 return False;
2150 ZERO_STRUCTP(*auth_method);
2152 return True;
2155 /****************************************************************************
2156 Duplicate a SID token.
2157 ****************************************************************************/
2159 NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, const NT_USER_TOKEN *ptoken)
2161 NT_USER_TOKEN *token;
2163 if (!ptoken)
2164 return NULL;
2166 token = TALLOC_P(mem_ctx, NT_USER_TOKEN);
2167 if (token == NULL) {
2168 DEBUG(0, ("talloc failed\n"));
2169 return NULL;
2172 ZERO_STRUCTP(token);
2174 if (ptoken->user_sids && ptoken->num_sids) {
2175 token->user_sids = (DOM_SID *)TALLOC_MEMDUP(
2176 token, ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
2178 if (token->user_sids == NULL) {
2179 DEBUG(0, ("TALLOC_MEMDUP failed\n"));
2180 TALLOC_FREE(token);
2181 return NULL;
2183 token->num_sids = ptoken->num_sids;
2186 /* copy the privileges; don't consider failure to be critical here */
2188 if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
2189 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. "
2190 "Continuing with 0 privileges assigned.\n"));
2193 return token;
2196 /****************************************************************************
2197 Check for a SID in an NT_USER_TOKEN
2198 ****************************************************************************/
2200 BOOL nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
2202 int i;
2204 if ( !sid || !token )
2205 return False;
2207 for ( i=0; i<token->num_sids; i++ ) {
2208 if ( sid_equal( sid, &token->user_sids[i] ) )
2209 return True;
2212 return False;
2215 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
2217 DOM_SID domain_sid;
2219 /* if we are a domain member, the get the domain SID, else for
2220 a DC or standalone server, use our own SID */
2222 if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
2223 if ( !secrets_fetch_domain_sid( lp_workgroup(),
2224 &domain_sid ) ) {
2225 DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
2226 "SID for domain [%s]\n", lp_workgroup()));
2227 return False;
2230 else
2231 sid_copy( &domain_sid, get_global_sam_sid() );
2233 sid_append_rid( &domain_sid, rid );
2235 return nt_token_check_sid( &domain_sid, token );\
2239 * Verify whether or not given domain is trusted.
2241 * @param domain_name name of the domain to be verified
2242 * @return true if domain is one of the trusted once or
2243 * false if otherwise
2246 BOOL is_trusted_domain(const char* dom_name)
2248 DOM_SID trustdom_sid;
2249 BOOL ret;
2251 /* no trusted domains for a standalone server */
2253 if ( lp_server_role() == ROLE_STANDALONE )
2254 return False;
2256 /* if we are a DC, then check for a direct trust relationships */
2258 if ( IS_DC ) {
2259 become_root();
2260 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2261 "[%s]\n", dom_name ));
2262 ret = secrets_fetch_trusted_domain_password(dom_name, NULL,
2263 NULL, NULL);
2264 unbecome_root();
2265 if (ret)
2266 return True;
2268 else {
2269 NSS_STATUS result;
2271 /* If winbind is around, ask it */
2273 result = wb_is_trusted_domain(dom_name);
2275 if (result == NSS_STATUS_SUCCESS) {
2276 return True;
2279 if (result == NSS_STATUS_NOTFOUND) {
2280 /* winbind could not find the domain */
2281 return False;
2284 /* The only other possible result is that winbind is not up
2285 and running. We need to update the trustdom_cache
2286 ourselves */
2288 update_trustdom_cache();
2291 /* now the trustdom cache should be available a DC could still
2292 * have a transitive trust so fall back to the cache of trusted
2293 * domains (like a domain member would use */
2295 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
2296 return True;
2299 return False;