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
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #define DBGC_CLASS DBGC_AUTH
30 /****************************************************************************
31 Create a UNIX user on demand.
32 ****************************************************************************/
34 static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
39 pstrcpy(add_script, lp_adduser_script());
42 all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
44 all_string_sub(add_script, "%D", domain, sizeof(pstring));
46 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
47 ret = smbrun(add_script,NULL);
49 DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
53 /****************************************************************************
54 Create a SAM_ACCOUNT - either by looking in the pdb, or by faking it up from
56 ****************************************************************************/
58 NTSTATUS auth_get_sam_account(const char *user, SAM_ACCOUNT **account)
62 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(account))) {
67 pdb_ret = pdb_getsampwnam(*account, user);
72 struct passwd *pass = Get_Pwnam(user);
74 return NT_STATUS_NO_SUCH_USER;
76 if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*account, pass))) {
83 /****************************************************************************
84 Create an auth_usersupplied_data structure
85 ****************************************************************************/
87 static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
89 const char *internal_username,
90 const char *client_domain,
92 const char *wksta_name,
93 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
94 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
99 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
101 *user_info = SMB_MALLOC_P(auth_usersupplied_info);
103 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
104 return NT_STATUS_NO_MEMORY;
107 ZERO_STRUCTP(*user_info);
109 DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
111 (*user_info)->smb_name.str = SMB_STRDUP(smb_name);
112 if ((*user_info)->smb_name.str) {
113 (*user_info)->smb_name.len = strlen(smb_name);
115 free_user_info(user_info);
116 return NT_STATUS_NO_MEMORY;
119 (*user_info)->internal_username.str = SMB_STRDUP(internal_username);
120 if ((*user_info)->internal_username.str) {
121 (*user_info)->internal_username.len = strlen(internal_username);
123 free_user_info(user_info);
124 return NT_STATUS_NO_MEMORY;
127 (*user_info)->domain.str = SMB_STRDUP(domain);
128 if ((*user_info)->domain.str) {
129 (*user_info)->domain.len = strlen(domain);
131 free_user_info(user_info);
132 return NT_STATUS_NO_MEMORY;
135 (*user_info)->client_domain.str = SMB_STRDUP(client_domain);
136 if ((*user_info)->client_domain.str) {
137 (*user_info)->client_domain.len = strlen(client_domain);
139 free_user_info(user_info);
140 return NT_STATUS_NO_MEMORY;
143 (*user_info)->wksta_name.str = SMB_STRDUP(wksta_name);
144 if ((*user_info)->wksta_name.str) {
145 (*user_info)->wksta_name.len = strlen(wksta_name);
147 free_user_info(user_info);
148 return NT_STATUS_NO_MEMORY;
151 DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
154 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
156 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
157 if (lm_interactive_pwd)
158 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
159 if (nt_interactive_pwd)
160 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
163 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
165 (*user_info)->encrypted = encrypted;
167 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
172 /****************************************************************************
173 Create an auth_usersupplied_data structure after appropriate mapping.
174 ****************************************************************************/
176 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
177 const char *smb_name,
178 const char *client_domain,
179 const char *wksta_name,
180 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
181 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
182 DATA_BLOB *plaintext,
186 fstring internal_username;
187 fstrcpy(internal_username, smb_name);
188 map_username(internal_username);
190 DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
191 client_domain, smb_name, wksta_name));
193 /* don't allow "" as a domain, fixes a Win9X bug
194 where it doens't supply a domain for logon script
195 'net use' commands. */
197 if ( *client_domain )
198 domain = client_domain;
200 domain = lp_workgroup();
202 /* do what win2k does. Always map unknown domains to our own
203 and let the "passdb backend" handle unknown users. */
205 if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) )
206 domain = get_default_sam_name();
208 /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
210 return make_user_info(user_info, smb_name, internal_username,
211 client_domain, domain, wksta_name,
213 lm_interactive_pwd, nt_interactive_pwd,
214 plaintext, encrypted);
217 /****************************************************************************
218 Create an auth_usersupplied_data, making the DATA_BLOBs here.
219 Decrypt and encrypt the passwords.
220 ****************************************************************************/
222 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
223 const char *smb_name,
224 const char *client_domain,
225 const char *wksta_name,
226 const uchar *lm_network_pwd, int lm_pwd_len,
227 const uchar *nt_network_pwd, int nt_pwd_len)
231 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
232 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
234 nt_status = make_user_info_map(user_info,
235 smb_name, client_domain,
237 lm_pwd_len ? &lm_blob : NULL,
238 nt_pwd_len ? &nt_blob : NULL,
242 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
244 data_blob_free(&lm_blob);
245 data_blob_free(&nt_blob);
249 /****************************************************************************
250 Create an auth_usersupplied_data, making the DATA_BLOBs here.
251 Decrypt and encrypt the passwords.
252 ****************************************************************************/
254 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
255 const char *smb_name,
256 const char *client_domain,
257 const char *wksta_name,
259 const uchar lm_interactive_pwd[16],
260 const uchar nt_interactive_pwd[16],
261 const uchar *dc_sess_key)
265 unsigned char local_lm_response[24];
266 unsigned char local_nt_response[24];
267 unsigned char key[16];
270 memcpy(key, dc_sess_key, 8);
272 if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
273 if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
275 #ifdef DEBUG_PASSWORD
277 dump_data(100, (char *)key, sizeof(key));
279 DEBUG(100,("lm owf password:"));
280 dump_data(100, lm_pwd, sizeof(lm_pwd));
282 DEBUG(100,("nt owf password:"));
283 dump_data(100, nt_pwd, sizeof(nt_pwd));
286 if (lm_interactive_pwd)
287 SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
289 if (nt_interactive_pwd)
290 SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
292 #ifdef DEBUG_PASSWORD
293 DEBUG(100,("decrypt of lm owf password:"));
294 dump_data(100, lm_pwd, sizeof(lm_pwd));
296 DEBUG(100,("decrypt of nt owf password:"));
297 dump_data(100, nt_pwd, sizeof(nt_pwd));
300 if (lm_interactive_pwd)
301 SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
303 if (nt_interactive_pwd)
304 SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
306 /* Password info paranoia */
312 DATA_BLOB local_lm_blob;
313 DATA_BLOB local_nt_blob;
315 DATA_BLOB lm_interactive_blob;
316 DATA_BLOB nt_interactive_blob;
318 if (lm_interactive_pwd) {
319 local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
320 lm_interactive_blob = data_blob(lm_pwd, sizeof(lm_pwd));
324 if (nt_interactive_pwd) {
325 local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
326 nt_interactive_blob = data_blob(nt_pwd, sizeof(nt_pwd));
330 nt_status = make_user_info_map(user_info,
331 smb_name, client_domain,
333 lm_interactive_pwd ? &local_lm_blob : NULL,
334 nt_interactive_pwd ? &local_nt_blob : NULL,
335 lm_interactive_pwd ? &lm_interactive_blob : NULL,
336 nt_interactive_pwd ? &nt_interactive_blob : NULL,
340 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
341 data_blob_free(&local_lm_blob);
342 data_blob_free(&local_nt_blob);
343 data_blob_free(&lm_interactive_blob);
344 data_blob_free(&nt_interactive_blob);
350 /****************************************************************************
351 Create an auth_usersupplied_data structure
352 ****************************************************************************/
354 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
355 const char *smb_name,
356 const char *client_domain,
358 DATA_BLOB plaintext_password)
361 DATA_BLOB local_lm_blob;
362 DATA_BLOB local_nt_blob;
363 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
366 * Not encrypted - do so.
369 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
371 if (plaintext_password.data) {
372 unsigned char local_lm_response[24];
374 #ifdef DEBUG_PASSWORD
375 DEBUG(10,("Unencrypted password (len %d):\n",(int)plaintext_password.length));
376 dump_data(100, plaintext_password.data, plaintext_password.length);
379 SMBencrypt( (const char *)plaintext_password.data, (const uchar*)chal, local_lm_response);
380 local_lm_blob = data_blob(local_lm_response, 24);
382 /* We can't do an NT hash here, as the password needs to be
384 local_nt_blob = data_blob(NULL, 0);
387 local_lm_blob = data_blob(NULL, 0);
388 local_nt_blob = data_blob(NULL, 0);
391 ret = make_user_info_map(user_info, smb_name,
393 get_remote_machine_name(),
394 local_lm_blob.data ? &local_lm_blob : NULL,
395 local_nt_blob.data ? &local_nt_blob : NULL,
397 plaintext_password.data ? &plaintext_password : NULL,
400 data_blob_free(&local_lm_blob);
401 return NT_STATUS_IS_OK(ret) ? True : False;
404 /****************************************************************************
405 Create an auth_usersupplied_data structure
406 ****************************************************************************/
408 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
409 const char *smb_name,
410 const char *client_domain,
411 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
413 return make_user_info_map(user_info, smb_name,
415 get_remote_machine_name(),
416 lm_resp.data ? &lm_resp : NULL,
417 nt_resp.data ? &nt_resp : NULL,
422 /****************************************************************************
423 Create a guest user_info blob, for anonymous authenticaion.
424 ****************************************************************************/
426 BOOL make_user_info_guest(auth_usersupplied_info **user_info)
430 nt_status = make_user_info(user_info,
439 return NT_STATUS_IS_OK(nt_status) ? True : False;
442 /****************************************************************************
443 prints a NT_USER_TOKEN to debug output.
444 ****************************************************************************/
446 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
452 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
456 DEBUGC(dbg_class, dbg_lev, ("NT user token of user %s\n",
457 sid_to_string(sid_str, &token->user_sids[0]) ));
458 DEBUGADDC(dbg_class, dbg_lev, ("contains %lu SIDs\n", (unsigned long)token->num_sids));
459 for (i = 0; i < token->num_sids; i++)
460 DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i,
461 sid_to_string(sid_str, &token->user_sids[i])));
463 dump_se_priv( dbg_class, dbg_lev, &token->privileges );
466 /****************************************************************************
467 prints a UNIX 'token' to debug output.
468 ****************************************************************************/
470 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid, int n_groups, gid_t *groups)
473 DEBUGC(dbg_class, dbg_lev, ("UNIX token of user %ld\n", (long int)uid));
475 DEBUGADDC(dbg_class, dbg_lev, ("Primary group is %ld and contains %i supplementary groups\n", (long int)gid, n_groups));
476 for (i = 0; i < n_groups; i++)
477 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i,
478 (long int)groups[i]));
481 /****************************************************************************
482 Create the SID list for this user.
483 ****************************************************************************/
485 static NTSTATUS create_nt_user_token(const DOM_SID *user_sid, const DOM_SID *group_sid,
486 int n_groupSIDs, DOM_SID *groupSIDs,
487 BOOL is_guest, NT_USER_TOKEN **token)
489 NTSTATUS nt_status = NT_STATUS_OK;
490 NT_USER_TOKEN *ptoken;
494 if ((ptoken = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL) {
495 DEBUG(0, ("create_nt_token: Out of memory allocating token\n"));
496 nt_status = NT_STATUS_NO_MEMORY;
500 ZERO_STRUCTP(ptoken);
502 ptoken->num_sids = n_groupSIDs + 5;
504 if ((ptoken->user_sids = SMB_MALLOC_ARRAY( DOM_SID, ptoken->num_sids )) == NULL) {
505 DEBUG(0, ("create_nt_token: Out of memory allocating SIDs\n"));
506 nt_status = NT_STATUS_NO_MEMORY;
510 memset((char*)ptoken->user_sids,0,sizeof(DOM_SID) * ptoken->num_sids);
513 * Note - user SID *MUST* be first in token !
514 * se_access_check depends on this.
516 * Primary group SID is second in token. Convention.
519 sid_copy(&ptoken->user_sids[PRIMARY_USER_SID_INDEX], user_sid);
521 sid_copy(&ptoken->user_sids[PRIMARY_GROUP_SID_INDEX], group_sid);
524 * Finally add the "standard" SIDs.
525 * The only difference between guest and "anonymous" (which we
526 * don't really support) is the addition of Authenticated_Users.
529 sid_copy(&ptoken->user_sids[2], &global_sid_World);
530 sid_copy(&ptoken->user_sids[3], &global_sid_Network);
533 sid_copy(&ptoken->user_sids[4], &global_sid_Builtin_Guests);
535 sid_copy(&ptoken->user_sids[4], &global_sid_Authenticated_Users);
537 sid_ndx = 5; /* next available spot */
539 for (i = 0; i < n_groupSIDs; i++) {
540 size_t check_sid_idx;
541 for (check_sid_idx = 1; check_sid_idx < ptoken->num_sids; check_sid_idx++) {
542 if (sid_equal(&ptoken->user_sids[check_sid_idx],
548 if (check_sid_idx >= ptoken->num_sids) /* Not found already */ {
549 sid_copy(&ptoken->user_sids[sid_ndx++], &groupSIDs[i]);
555 /* add privileges assigned to this user */
557 get_privileges_for_sids( &ptoken->privileges, ptoken->user_sids, ptoken->num_sids );
559 debug_nt_user_token(DBGC_AUTH, 10, ptoken);
561 if ((lp_log_nt_token_command() != NULL) &&
562 (strlen(lp_log_nt_token_command()) > 0)) {
566 char *user_sidstr, *group_sidstr;
568 mem_ctx = talloc_init("setnttoken");
570 return NT_STATUS_NO_MEMORY;
572 sid_to_string(sidstr, &ptoken->user_sids[0]);
573 user_sidstr = talloc_strdup(mem_ctx, sidstr);
575 group_sidstr = talloc_strdup(mem_ctx, "");
576 for (i=1; i<ptoken->num_sids; i++) {
577 sid_to_string(sidstr, &ptoken->user_sids[i]);
578 group_sidstr = talloc_asprintf(mem_ctx, "%s %s",
579 group_sidstr, sidstr);
582 command = SMB_STRDUP(lp_log_nt_token_command());
583 command = realloc_string_sub(command, "%s", user_sidstr);
584 command = realloc_string_sub(command, "%t", group_sidstr);
585 DEBUG(8, ("running command: [%s]\n", command));
586 if (smbrun(command, NULL) != 0) {
587 DEBUG(0, ("Could not log NT token\n"));
588 nt_status = NT_STATUS_ACCESS_DENIED;
590 talloc_destroy(mem_ctx);
599 /****************************************************************************
600 Create the SID list for this user.
601 ****************************************************************************/
603 NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest)
608 NT_USER_TOKEN *token;
611 if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, uid))) {
614 if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, gid))) {
618 group_sids = SMB_MALLOC_ARRAY(DOM_SID, ngroups);
620 DEBUG(0, ("create_nt_token: malloc() failed for DOM_SID list!\n"));
624 for (i = 0; i < ngroups; i++) {
625 if (!NT_STATUS_IS_OK(gid_to_sid(&(group_sids)[i], (groups)[i]))) {
626 DEBUG(1, ("create_nt_token: failed to convert gid %ld to a sid!\n", (long int)groups[i]));
627 SAFE_FREE(group_sids);
632 if (!NT_STATUS_IS_OK(create_nt_user_token(&user_sid, &group_sid,
633 ngroups, group_sids, is_guest, &token))) {
634 SAFE_FREE(group_sids);
638 SAFE_FREE(group_sids);
643 /******************************************************************************
644 Create a token for the root user to be used internally by smbd.
645 This is similar to running under the context of the LOCAL_SYSTEM account
646 in Windows. This is a read-only token. Do not modify it or free() it.
647 Create a copy if your need to change it.
648 ******************************************************************************/
650 NT_USER_TOKEN *get_root_nt_token( void )
652 static NT_USER_TOKEN *token = NULL;
653 DOM_SID u_sid, g_sid;
661 if ( !(pw = getpwnam( "root" )) ) {
662 DEBUG(0,("create_root_nt_token: getpwnam\"root\") failed!\n"));
666 /* get the user and primary group SIDs; although the
667 BUILTIN\Administrators SId is really the one that matters here */
669 if ( !NT_STATUS_IS_OK(uid_to_sid(&u_sid, pw->pw_uid)) )
671 if ( !NT_STATUS_IS_OK(gid_to_sid(&g_sid, pw->pw_gid)) )
674 sid_copy( &g_sids[0], &global_sid_Builtin_Administrators );
676 result = create_nt_user_token( &u_sid, &g_sid, 1, g_sids, False, &token);
678 return NT_STATUS_IS_OK(result) ? token : NULL;
681 /******************************************************************************
682 * this function returns the groups (SIDs) of the local SAM the user is in.
683 * If this samba server is a DC of the domain the user belongs to, it returns
684 * both domain groups and local / builtin groups. If the user is in a trusted
685 * domain, or samba is a member server of a domain, then this function returns
686 * local and builtin groups the user is a member of.
688 * currently this is a hack, as there is no sam implementation that is capable
691 * NOTE!! This function will fail if you pass in a winbind user without
693 ******************************************************************************/
695 static NTSTATUS get_user_groups(const char *username, uid_t uid, gid_t gid,
696 int *n_groups, DOM_SID **groups, gid_t **unix_groups)
704 if (strchr(username, *lp_winbind_separator()) == NULL) {
708 result = pdb_enum_group_memberships(username, gid, groups,
709 unix_groups, n_groups);
714 /* We have the separator, this must be winbind */
716 n_unix_groups = winbind_getgroups( username, unix_groups );
718 DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n",
719 username, n_unix_groups == -1 ? "FAIL" : "SUCCESS"));
721 if ( n_unix_groups == -1 )
722 return NT_STATUS_NO_SUCH_USER; /* what should this return
725 debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups);
727 /* now setup the space for storing the SIDS */
729 if (n_unix_groups > 0) {
731 *groups = SMB_MALLOC_ARRAY(DOM_SID, n_unix_groups);
734 DEBUG(0, ("get_user_group: malloc() failed for DOM_SID list!\n"));
735 SAFE_FREE(*unix_groups);
736 return NT_STATUS_NO_MEMORY;
740 *n_groups = n_unix_groups;
742 for (i = 0; i < *n_groups; i++) {
743 if (!NT_STATUS_IS_OK(gid_to_sid(&(*groups)[i], (*unix_groups)[i]))) {
744 DEBUG(1, ("get_user_groups: failed to convert gid %ld to a sid!\n",
745 (long int)(*unix_groups)[i+1]));
747 SAFE_FREE(*unix_groups);
748 return NT_STATUS_NO_SUCH_USER;
755 /***************************************************************************
756 Make a user_info struct
757 ***************************************************************************/
759 static NTSTATUS make_server_info(auth_serversupplied_info **server_info)
761 *server_info = SMB_MALLOC_P(auth_serversupplied_info);
763 DEBUG(0,("make_server_info: malloc failed!\n"));
764 return NT_STATUS_NO_MEMORY;
766 ZERO_STRUCTP(*server_info);
768 /* Initialise the uid and gid values to something non-zero
769 which may save us from giving away root access if there
770 is a bug in allocating these fields. */
772 (*server_info)->uid = -1;
773 (*server_info)->gid = -1;
778 /***************************************************************************
779 Fill a server_info struct from a SAM_ACCOUNT with their groups
780 ***************************************************************************/
782 static NTSTATUS add_user_groups(auth_serversupplied_info **server_info,
783 const char * unix_username,
784 SAM_ACCOUNT *sampass,
785 uid_t uid, gid_t gid)
788 const DOM_SID *user_sid = pdb_get_user_sid(sampass);
789 const DOM_SID *group_sid = pdb_get_group_sid(sampass);
791 DOM_SID *groupSIDs = NULL;
792 gid_t *unix_groups = NULL;
793 NT_USER_TOKEN *token;
797 nt_status = get_user_groups(unix_username, uid, gid,
798 &n_groupSIDs, &groupSIDs, &unix_groups);
800 if (!NT_STATUS_IS_OK(nt_status)) {
801 DEBUG(4,("get_user_groups_from_local_sam failed\n"));
802 free_server_info(server_info);
806 is_guest = (sid_peek_rid(user_sid, &rid) && rid == DOMAIN_USER_RID_GUEST);
808 if (!NT_STATUS_IS_OK(nt_status = create_nt_user_token(user_sid, group_sid,
809 n_groupSIDs, groupSIDs, is_guest,
812 DEBUG(4,("create_nt_user_token failed\n"));
813 SAFE_FREE(groupSIDs);
814 SAFE_FREE(unix_groups);
815 free_server_info(server_info);
819 SAFE_FREE(groupSIDs);
821 (*server_info)->n_groups = n_groupSIDs;
822 (*server_info)->groups = unix_groups;
823 (*server_info)->ptok = token;
828 /***************************************************************************
829 Make (and fill) a user_info struct from a SAM_ACCOUNT
830 ***************************************************************************/
832 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
833 SAM_ACCOUNT *sampass)
838 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info)))
841 (*server_info)->sam_account = sampass;
843 if ( !(pwd = getpwnam_alloc(pdb_get_username(sampass))) ) {
844 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
845 pdb_get_username(sampass)));
846 free_server_info(server_info);
847 return NT_STATUS_NO_SUCH_USER;
849 (*server_info)->unix_name = smb_xstrdup(pwd->pw_name);
850 (*server_info)->gid = pwd->pw_gid;
851 (*server_info)->uid = pwd->pw_uid;
855 if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, pdb_get_username(sampass),
858 (*server_info)->gid)))
860 free_server_info(server_info);
864 (*server_info)->sam_fill_level = SAM_FILL_ALL;
865 DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
866 pdb_get_username(sampass),
867 (*server_info)->unix_name));
872 /***************************************************************************
873 Make (and fill) a user_info struct from a Kerberos PAC logon_info by conversion
875 ***************************************************************************/
877 NTSTATUS make_server_info_pac(auth_serversupplied_info **server_info,
880 PAC_LOGON_INFO *logon_info)
883 SAM_ACCOUNT *sampass = NULL;
884 DOM_SID user_sid, group_sid;
887 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {
890 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
894 /* only copy user_sid, group_sid and domain name out of the PAC for
895 * now, we will benefit from more later - Guenther */
897 sid_copy(&user_sid, &logon_info->info3.dom_sid.sid);
898 sid_append_rid(&user_sid, logon_info->info3.user_rid);
899 pdb_set_user_sid(sampass, &user_sid, PDB_SET);
901 sid_copy(&group_sid, &logon_info->info3.dom_sid.sid);
902 sid_append_rid(&group_sid, logon_info->info3.group_rid);
903 pdb_set_group_sid(sampass, &group_sid, PDB_SET);
905 unistr2_to_ascii(dom_name, &logon_info->info3.uni_logon_dom, -1);
906 pdb_set_domain(sampass, dom_name, PDB_SET);
908 pdb_set_logon_count(sampass, logon_info->info3.logon_count, PDB_SET);
910 (*server_info)->sam_account = sampass;
912 if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username,
913 sampass, pwd->pw_uid, pwd->pw_gid)))
918 (*server_info)->unix_name = smb_xstrdup(unix_username);
920 (*server_info)->sam_fill_level = SAM_FILL_ALL;
921 (*server_info)->uid = pwd->pw_uid;
922 (*server_info)->gid = pwd->pw_gid;
927 /***************************************************************************
928 Make (and fill) a user_info struct from a 'struct passwd' by conversion
930 ***************************************************************************/
932 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
937 SAM_ACCOUNT *sampass = NULL;
938 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {
941 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
945 (*server_info)->sam_account = sampass;
947 if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username,
948 sampass, pwd->pw_uid, pwd->pw_gid)))
953 (*server_info)->unix_name = smb_xstrdup(unix_username);
955 (*server_info)->sam_fill_level = SAM_FILL_ALL;
956 (*server_info)->uid = pwd->pw_uid;
957 (*server_info)->gid = pwd->pw_gid;
961 /***************************************************************************
962 Make (and fill) a user_info struct for a guest login.
963 ***************************************************************************/
965 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
968 SAM_ACCOUNT *sampass = NULL;
971 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) {
975 sid_copy(&guest_sid, get_global_sam_sid());
976 sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
979 if (!pdb_getsampwsid(sampass, &guest_sid)) {
981 return NT_STATUS_NO_SUCH_USER;
985 nt_status = make_server_info_sam(server_info, sampass);
987 if (NT_STATUS_IS_OK(nt_status)) {
988 static const char zeros[16];
989 (*server_info)->guest = True;
991 /* annoying, but the Guest really does have a session key,
992 and it is all zeros! */
993 (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
994 (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1000 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
1002 auth_serversupplied_info *dst;
1004 if (!NT_STATUS_IS_OK(make_server_info(&dst)))
1007 dst->guest = src->guest;
1008 dst->uid = src->uid;
1009 dst->gid = src->gid;
1010 dst->n_groups = src->n_groups;
1011 if (src->n_groups != 0)
1012 dst->groups = memdup(src->groups, sizeof(gid_t)*dst->n_groups);
1015 dst->ptok = dup_nt_token(src->ptok);
1016 dst->user_session_key = data_blob(src->user_session_key.data,
1017 src->user_session_key.length);
1018 dst->lm_session_key = data_blob(src->lm_session_key.data,
1019 src->lm_session_key.length);
1020 pdb_copy_sam_account(src->sam_account, &dst->sam_account);
1021 dst->pam_handle = NULL;
1022 dst->unix_name = smb_xstrdup(src->unix_name);
1027 static auth_serversupplied_info *guest_info = NULL;
1029 BOOL init_guest_info(void)
1031 if (guest_info != NULL)
1034 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1037 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
1039 *server_info = copy_serverinfo(guest_info);
1040 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1043 /***************************************************************************
1044 Purely internal function for make_server_info_info3
1045 Fill the sam account from getpwnam
1046 ***************************************************************************/
1047 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
1049 const char *username,
1050 char **found_username,
1051 uid_t *uid, gid_t *gid,
1052 SAM_ACCOUNT **sam_account)
1055 fstring dom_user, lower_username;
1056 fstring real_username;
1057 struct passwd *passwd;
1059 fstrcpy( lower_username, username );
1060 strlower_m( lower_username );
1062 fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(),
1065 /* get the passwd struct but don't create the user if he/she
1066 does not exist. We were explicitly called from a following
1067 a winbindd authentication request so we should assume that
1068 nss_winbindd is working */
1070 map_username( dom_user );
1072 if ( !(passwd = smb_getpwnam( dom_user, real_username, True )) )
1073 return NT_STATUS_NO_SUCH_USER;
1075 *uid = passwd->pw_uid;
1076 *gid = passwd->pw_gid;
1078 /* This is pointless -- there is no suport for differing
1079 unix and windows names. Make sure to always store the
1080 one we actually looked up and succeeded. Have I mentioned
1081 why I hate the 'winbind use default domain' parameter?
1084 *found_username = talloc_strdup( mem_ctx, real_username );
1086 DEBUG(5,("fill_sam_account: located username was [%s]\n",
1089 nt_status = pdb_init_sam_pw(sam_account, passwd);
1090 passwd_free(&passwd);
1094 /****************************************************************************
1095 Wrapper to allow the getpwnam() call to strip the domain name and
1096 try again in case a local UNIX user is already there. Also run through
1097 the username if we fallback to the username only.
1098 ****************************************************************************/
1100 struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create )
1102 struct passwd *pw = NULL;
1106 /* we only save a copy of the username it has been mangled
1107 by winbindd use default domain */
1109 save_username[0] = '\0';
1111 /* don't call map_username() here since it has to be done higher
1112 up the stack so we don't call it mutliple times */
1114 fstrcpy( username, domuser );
1116 p = strchr_m( username, *lp_winbind_separator() );
1118 /* code for a DOMAIN\user string */
1121 fstring strip_username;
1123 pw = Get_Pwnam_alloc( domuser );
1125 /* make sure we get the case of the username correct */
1126 /* work around 'winbind use default domain = yes' */
1128 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1131 /* split the domain and username into 2 strings */
1135 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1138 fstrcpy( save_username, pw->pw_name );
1144 /* setup for lookup of just the username */
1145 /* remember that p and username are overlapping memory */
1148 fstrcpy( strip_username, p );
1149 fstrcpy( username, strip_username );
1152 /* just lookup a plain username */
1154 pw = Get_Pwnam_alloc(username);
1156 /* Create local user if requested. */
1158 if ( !pw && create ) {
1159 /* Don't add a machine account. */
1160 if (username[strlen(username)-1] == '$')
1163 smb_create_user(NULL, username, NULL);
1164 pw = Get_Pwnam_alloc(username);
1167 /* one last check for a valid passwd struct */
1170 fstrcpy( save_username, pw->pw_name );
1175 /***************************************************************************
1176 Make a server_info struct from the info3 returned by a domain logon
1177 ***************************************************************************/
1179 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1180 const char *internal_username,
1181 const char *sent_nt_username,
1183 auth_serversupplied_info **server_info,
1184 NET_USER_INFO_3 *info3)
1186 static const char zeros[16];
1188 NTSTATUS nt_status = NT_STATUS_OK;
1189 char *found_username;
1190 const char *nt_domain;
1191 const char *nt_username;
1193 SAM_ACCOUNT *sam_account = NULL;
1201 DOM_SID *lgroupSIDs = NULL;
1203 gid_t *unix_groups = NULL;
1204 NT_USER_TOKEN *token;
1206 DOM_SID *all_group_SIDs;
1210 Here is where we should check the list of
1211 trusted domains, and verify that the SID
1215 sid_copy(&user_sid, &info3->dom_sid.sid);
1216 if (!sid_append_rid(&user_sid, info3->user_rid)) {
1217 return NT_STATUS_INVALID_PARAMETER;
1220 sid_copy(&group_sid, &info3->dom_sid.sid);
1221 if (!sid_append_rid(&group_sid, info3->group_rid)) {
1222 return NT_STATUS_INVALID_PARAMETER;
1225 if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1226 /* If the server didn't give us one, just use the one we sent them */
1227 nt_username = sent_nt_username;
1230 if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1231 /* If the server didn't give us one, just use the one we sent them */
1235 /* try to fill the SAM account.. If getpwnam() fails, then try the
1236 add user script (2.2.x behavior).
1238 We use the _unmapped_ username here in an attempt to provide
1239 consistent username mapping behavior between kerberos and NTLM[SSP]
1240 authentication in domain mode security. I.E. Username mapping should
1241 be applied to the fully qualified username (e.g. DOMAIN\user) and
1242 no just the login name. Yes this mean swe called map_username()
1243 unnecessarily in make_user_info_map() but that is how the current
1244 code is designed. Making the change here is the least disruptive
1247 nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1248 &found_username, &uid, &gid, &sam_account);
1250 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
1251 DEBUG(3,("User %s does not exist, trying to add it\n", internal_username));
1252 smb_create_user( nt_domain, sent_nt_username, NULL);
1253 nt_status = fill_sam_account( mem_ctx, nt_domain, sent_nt_username,
1254 &found_username, &uid, &gid, &sam_account );
1257 /* if we still don't have a valid unix account check for
1258 'map to gues = bad uid' */
1260 if (!NT_STATUS_IS_OK(nt_status)) {
1261 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1262 make_server_info_guest(server_info);
1263 return NT_STATUS_OK;
1266 DEBUG(0, ("make_server_info_info3: pdb_init_sam failed!\n"));
1270 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1271 pdb_free_sam(&sam_account);
1272 return NT_STATUS_NO_MEMORY;
1275 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1276 pdb_free_sam(&sam_account);
1277 return NT_STATUS_NO_MEMORY;
1280 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1281 pdb_free_sam(&sam_account);
1282 return NT_STATUS_NO_MEMORY;
1285 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1286 pdb_free_sam(&sam_account);
1287 return NT_STATUS_UNSUCCESSFUL;
1290 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1291 pdb_free_sam(&sam_account);
1292 return NT_STATUS_UNSUCCESSFUL;
1295 if (!pdb_set_fullname(sam_account, unistr2_static(&(info3->uni_full_name)),
1297 pdb_free_sam(&sam_account);
1298 return NT_STATUS_NO_MEMORY;
1301 if (!pdb_set_logon_script(sam_account, unistr2_static(&(info3->uni_logon_script)), PDB_CHANGED)) {
1302 pdb_free_sam(&sam_account);
1303 return NT_STATUS_NO_MEMORY;
1306 if (!pdb_set_profile_path(sam_account, unistr2_static(&(info3->uni_profile_path)), PDB_CHANGED)) {
1307 pdb_free_sam(&sam_account);
1308 return NT_STATUS_NO_MEMORY;
1311 if (!pdb_set_homedir(sam_account, unistr2_static(&(info3->uni_home_dir)), PDB_CHANGED)) {
1312 pdb_free_sam(&sam_account);
1313 return NT_STATUS_NO_MEMORY;
1316 if (!pdb_set_dir_drive(sam_account, unistr2_static(&(info3->uni_dir_drive)), PDB_CHANGED)) {
1317 pdb_free_sam(&sam_account);
1318 return NT_STATUS_NO_MEMORY;
1321 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
1322 DEBUG(4, ("make_server_info failed!\n"));
1323 pdb_free_sam(&sam_account);
1327 /* save this here to _net_sam_logon() doesn't fail (it assumes a
1328 valid SAM_ACCOUNT) */
1330 (*server_info)->sam_account = sam_account;
1332 (*server_info)->unix_name = smb_xstrdup(found_username);
1334 /* Fill in the unix info we found on the way */
1336 (*server_info)->sam_fill_level = SAM_FILL_ALL;
1337 (*server_info)->uid = uid;
1338 (*server_info)->gid = gid;
1340 /* Store the user group information in the server_info
1341 returned to the caller. */
1343 nt_status = get_user_groups((*server_info)->unix_name,
1344 uid, gid, &n_lgroupSIDs, &lgroupSIDs, &unix_groups);
1346 if ( !NT_STATUS_IS_OK(nt_status) ) {
1347 DEBUG(4,("get_user_groups failed\n"));
1351 (*server_info)->groups = unix_groups;
1352 (*server_info)->n_groups = n_lgroupSIDs;
1354 /* Create a 'combined' list of all SIDs we might want in the SD */
1356 all_group_SIDs = SMB_MALLOC_ARRAY(DOM_SID,info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs);
1358 if (!all_group_SIDs) {
1359 DEBUG(0, ("malloc() failed for DOM_SID list!\n"));
1360 SAFE_FREE(lgroupSIDs);
1361 free_server_info(server_info);
1362 return NT_STATUS_NO_MEMORY;
1365 /* and create (by appending rids) the 'domain' sids */
1367 for (i = 0; i < info3->num_groups2; i++) {
1369 sid_copy(&all_group_SIDs[i], &(info3->dom_sid.sid));
1371 if (!sid_append_rid(&all_group_SIDs[i], info3->gids[i].g_rid)) {
1373 nt_status = NT_STATUS_INVALID_PARAMETER;
1375 DEBUG(3,("could not append additional group rid 0x%x\n",
1376 info3->gids[i].g_rid));
1378 SAFE_FREE(lgroupSIDs);
1379 SAFE_FREE(all_group_SIDs);
1380 free_server_info(server_info);
1387 /* Copy 'other' sids. We need to do sid filtering here to
1388 prevent possible elevation of privileges. See:
1390 http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
1393 for (i = 0; i < info3->num_other_sids; i++) {
1394 sid_copy(&all_group_SIDs[info3->num_groups2 + i],
1395 &info3->other_sids[i].sid);
1399 /* add local alias sids */
1401 for (i = 0; i < n_lgroupSIDs; i++) {
1402 sid_copy(&all_group_SIDs[info3->num_groups2 +
1403 info3->num_other_sids + i],
1407 /* Where are the 'global' sids... */
1409 /* can the user be guest? if yes, where is it stored? */
1411 nt_status = create_nt_user_token(&user_sid, &group_sid,
1412 info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs,
1413 all_group_SIDs, False, &token);
1415 if ( !NT_STATUS_IS_OK(nt_status) ) {
1416 DEBUG(4,("create_nt_user_token failed\n"));
1417 SAFE_FREE(lgroupSIDs);
1418 SAFE_FREE(all_group_SIDs);
1419 free_server_info(server_info);
1423 (*server_info)->login_server = unistr2_tdup(mem_ctx,
1424 &(info3->uni_logon_srv));
1426 (*server_info)->ptok = token;
1428 SAFE_FREE(lgroupSIDs);
1429 SAFE_FREE(all_group_SIDs);
1431 /* ensure we are never given NULL session keys */
1433 if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
1434 (*server_info)->user_session_key = data_blob(NULL, 0);
1436 (*server_info)->user_session_key = data_blob(info3->user_sess_key, sizeof(info3->user_sess_key));
1439 if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
1440 (*server_info)->lm_session_key = data_blob(NULL, 0);
1442 (*server_info)->lm_session_key = data_blob(info3->lm_sess_key, sizeof(info3->lm_sess_key));
1445 return NT_STATUS_OK;
1448 /***************************************************************************
1449 Free a user_info struct
1450 ***************************************************************************/
1452 void free_user_info(auth_usersupplied_info **user_info)
1454 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1455 if (*user_info != NULL) {
1456 if ((*user_info)->smb_name.str) {
1457 DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
1459 SAFE_FREE((*user_info)->smb_name.str);
1460 SAFE_FREE((*user_info)->internal_username.str);
1461 SAFE_FREE((*user_info)->client_domain.str);
1462 SAFE_FREE((*user_info)->domain.str);
1463 SAFE_FREE((*user_info)->wksta_name.str);
1464 data_blob_free(&(*user_info)->lm_resp);
1465 data_blob_free(&(*user_info)->nt_resp);
1466 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1467 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1468 data_blob_clear_free(&(*user_info)->plaintext_password);
1469 ZERO_STRUCT(**user_info);
1471 SAFE_FREE(*user_info);
1474 /***************************************************************************
1475 Clear out a server_info struct that has been allocated
1476 ***************************************************************************/
1478 void free_server_info(auth_serversupplied_info **server_info)
1480 DEBUG(5,("attempting to free (and zero) a server_info structure\n"));
1481 if (*server_info != NULL) {
1482 pdb_free_sam(&(*server_info)->sam_account);
1484 /* call pam_end here, unless we know we are keeping it */
1485 delete_nt_token( &(*server_info)->ptok );
1486 SAFE_FREE((*server_info)->groups);
1487 SAFE_FREE((*server_info)->unix_name);
1488 data_blob_free(&(*server_info)->lm_session_key);
1489 data_blob_free(&(*server_info)->user_session_key);
1490 ZERO_STRUCT(**server_info);
1492 SAFE_FREE(*server_info);
1495 /***************************************************************************
1496 Make an auth_methods struct
1497 ***************************************************************************/
1499 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method)
1501 if (!auth_context) {
1502 smb_panic("no auth_context supplied to make_auth_methods()!\n");
1506 smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
1509 *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1510 if (!*auth_method) {
1511 DEBUG(0,("make_auth_method: malloc failed!\n"));
1514 ZERO_STRUCTP(*auth_method);
1519 /****************************************************************************
1521 ****************************************************************************/
1523 void delete_nt_token(NT_USER_TOKEN **pptoken)
1526 NT_USER_TOKEN *ptoken = *pptoken;
1528 SAFE_FREE( ptoken->user_sids );
1529 ZERO_STRUCTP(ptoken);
1531 SAFE_FREE(*pptoken);
1534 /****************************************************************************
1535 Duplicate a SID token.
1536 ****************************************************************************/
1538 NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
1540 NT_USER_TOKEN *token;
1545 if ((token = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL)
1548 ZERO_STRUCTP(token);
1550 token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
1557 token->num_sids = ptoken->num_sids;
1559 /* copy the privileges; don't consider failure to be critical here */
1561 if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
1562 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. Continuing with 0 privileges assigned.\n"));
1568 /****************************************************************************
1569 Check for a SID in an NT_USER_TOKEN
1570 ****************************************************************************/
1572 BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token )
1576 if ( !sid || !token )
1579 for ( i=0; i<token->num_sids; i++ ) {
1580 if ( sid_equal( sid, &token->user_sids[i] ) )
1587 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
1591 /* if we are a domain member, the get the domain SID, else for
1592 a DC or standalone server, use our own SID */
1594 if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
1595 if ( !secrets_fetch_domain_sid( lp_workgroup(), &domain_sid ) ) {
1596 DEBUG(1,("nt_token_check_domain_rid: Cannot lookup SID for domain [%s]\n",
1602 sid_copy( &domain_sid, get_global_sam_sid() );
1604 sid_append_rid( &domain_sid, rid );
1606 return nt_token_check_sid( &domain_sid, token );\
1610 * Verify whether or not given domain is trusted.
1612 * @param domain_name name of the domain to be verified
1613 * @return true if domain is one of the trusted once or
1614 * false if otherwise
1617 BOOL is_trusted_domain(const char* dom_name)
1619 DOM_SID trustdom_sid;
1624 /* no trusted domains for a standalone server */
1626 if ( lp_server_role() == ROLE_STANDALONE )
1629 /* if we are a DC, then check for a direct trust relationships */
1633 DEBUG (5,("is_trusted_domain: Checking for domain trust with [%s]\n",
1635 ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
1644 /* If winbind is around, ask it */
1646 result = wb_is_trusted_domain(dom_name);
1648 if (result == NSS_STATUS_SUCCESS) {
1652 if (result == NSS_STATUS_NOTFOUND) {
1653 /* winbind could not find the domain */
1657 /* The only other possible result is that winbind is not up
1658 and running. We need to update the trustdom_cache
1661 update_trustdom_cache();
1664 /* now the trustdom cache should be available a DC could still
1665 * have a transitive trust so fall back to the cache of trusted
1666 * domains (like a domain member would use */
1668 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {