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
29 extern DOM_SID global_sid_World
;
30 extern DOM_SID global_sid_Network
;
31 extern DOM_SID global_sid_Builtin_Guests
;
32 extern DOM_SID global_sid_Authenticated_Users
;
35 /****************************************************************************
36 Create a UNIX user on demand.
37 ****************************************************************************/
39 static int smb_create_user(const char *domain
, const char *unix_username
, const char *homedir
)
44 pstrcpy(add_script
, lp_adduser_script());
47 all_string_sub(add_script
, "%u", unix_username
, sizeof(pstring
));
49 all_string_sub(add_script
, "%D", domain
, sizeof(pstring
));
51 all_string_sub(add_script
, "%H", homedir
, sizeof(pstring
));
52 ret
= smbrun(add_script
,NULL
);
54 DEBUG(ret
? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script
,ret
));
58 /****************************************************************************
59 Add and Delete UNIX users on demand, based on NTSTATUS codes.
60 We don't care about RID's here so ignore.
61 ****************************************************************************/
63 void auth_add_user_script(const char *domain
, const char *username
)
66 * User validated ok against Domain controller.
67 * If the admin wants us to try and create a UNIX
68 * user on the fly, do so.
71 if ( *lp_adduser_script() )
72 smb_create_user(domain
, username
, NULL
);
74 DEBUG(10,("auth_add_user_script: no 'add user script'. Asking winbindd\n"));
76 /* should never get here is we a re a domain member running winbindd
77 However, a host set for 'security = server' might run winbindd for
80 if ( !winbind_create_user(username
, NULL
) ) {
81 DEBUG(5,("auth_add_user_script: winbindd_create_user() failed\n"));
86 /****************************************************************************
87 Create a SAM_ACCOUNT - either by looking in the pdb, or by faking it up from
89 ****************************************************************************/
91 NTSTATUS
auth_get_sam_account(const char *user
, SAM_ACCOUNT
**account
)
95 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_sam(account
))) {
100 pdb_ret
= pdb_getsampwnam(*account
, user
);
105 struct passwd
*pass
= Get_Pwnam(user
);
107 return NT_STATUS_NO_SUCH_USER
;
109 if (!NT_STATUS_IS_OK(nt_status
= pdb_fill_sam_pw(*account
, pass
))) {
116 /****************************************************************************
117 Create an auth_usersupplied_data structure
118 ****************************************************************************/
120 static NTSTATUS
make_user_info(auth_usersupplied_info
**user_info
,
121 const char *smb_name
,
122 const char *internal_username
,
123 const char *client_domain
,
125 const char *wksta_name
,
126 DATA_BLOB
*lm_pwd
, DATA_BLOB
*nt_pwd
,
127 DATA_BLOB
*lm_interactive_pwd
, DATA_BLOB
*nt_interactive_pwd
,
128 DATA_BLOB
*plaintext
,
132 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username
, smb_name
));
134 *user_info
= SMB_MALLOC_P(auth_usersupplied_info
);
136 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info
)));
137 return NT_STATUS_NO_MEMORY
;
140 ZERO_STRUCTP(*user_info
);
142 DEBUG(5,("making strings for %s's user_info struct\n", internal_username
));
144 (*user_info
)->smb_name
.str
= SMB_STRDUP(smb_name
);
145 if ((*user_info
)->smb_name
.str
) {
146 (*user_info
)->smb_name
.len
= strlen(smb_name
);
148 free_user_info(user_info
);
149 return NT_STATUS_NO_MEMORY
;
152 (*user_info
)->internal_username
.str
= SMB_STRDUP(internal_username
);
153 if ((*user_info
)->internal_username
.str
) {
154 (*user_info
)->internal_username
.len
= strlen(internal_username
);
156 free_user_info(user_info
);
157 return NT_STATUS_NO_MEMORY
;
160 (*user_info
)->domain
.str
= SMB_STRDUP(domain
);
161 if ((*user_info
)->domain
.str
) {
162 (*user_info
)->domain
.len
= strlen(domain
);
164 free_user_info(user_info
);
165 return NT_STATUS_NO_MEMORY
;
168 (*user_info
)->client_domain
.str
= SMB_STRDUP(client_domain
);
169 if ((*user_info
)->client_domain
.str
) {
170 (*user_info
)->client_domain
.len
= strlen(client_domain
);
172 free_user_info(user_info
);
173 return NT_STATUS_NO_MEMORY
;
176 (*user_info
)->wksta_name
.str
= SMB_STRDUP(wksta_name
);
177 if ((*user_info
)->wksta_name
.str
) {
178 (*user_info
)->wksta_name
.len
= strlen(wksta_name
);
180 free_user_info(user_info
);
181 return NT_STATUS_NO_MEMORY
;
184 DEBUG(5,("making blobs for %s's user_info struct\n", internal_username
));
187 (*user_info
)->lm_resp
= data_blob(lm_pwd
->data
, lm_pwd
->length
);
189 (*user_info
)->nt_resp
= data_blob(nt_pwd
->data
, nt_pwd
->length
);
190 if (lm_interactive_pwd
)
191 (*user_info
)->lm_interactive_pwd
= data_blob(lm_interactive_pwd
->data
, lm_interactive_pwd
->length
);
192 if (nt_interactive_pwd
)
193 (*user_info
)->nt_interactive_pwd
= data_blob(nt_interactive_pwd
->data
, nt_interactive_pwd
->length
);
196 (*user_info
)->plaintext_password
= data_blob(plaintext
->data
, plaintext
->length
);
198 (*user_info
)->encrypted
= encrypted
;
200 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted
? "":"un" , internal_username
, smb_name
));
205 /****************************************************************************
206 Create an auth_usersupplied_data structure after appropriate mapping.
207 ****************************************************************************/
209 NTSTATUS
make_user_info_map(auth_usersupplied_info
**user_info
,
210 const char *smb_name
,
211 const char *client_domain
,
212 const char *wksta_name
,
213 DATA_BLOB
*lm_pwd
, DATA_BLOB
*nt_pwd
,
214 DATA_BLOB
*lm_interactive_pwd
, DATA_BLOB
*nt_interactive_pwd
,
215 DATA_BLOB
*plaintext
,
219 fstring internal_username
;
220 fstrcpy(internal_username
, smb_name
);
221 map_username(internal_username
);
223 DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
224 client_domain
, smb_name
, wksta_name
));
226 /* don't allow "" as a domain, fixes a Win9X bug
227 where it doens't supply a domain for logon script
228 'net use' commands. */
230 if ( *client_domain
)
231 domain
= client_domain
;
233 domain
= lp_workgroup();
235 /* do what win2k does. Always map unknown domains to our own
236 and let the "passdb backend" handle unknown users. */
238 if ( !is_trusted_domain(domain
) && !strequal(domain
, get_global_sam_name()) )
239 domain
= get_default_sam_name();
241 /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
243 return make_user_info(user_info
, smb_name
, internal_username
,
244 client_domain
, domain
, wksta_name
,
246 lm_interactive_pwd
, nt_interactive_pwd
,
247 plaintext
, encrypted
);
250 /****************************************************************************
251 Create an auth_usersupplied_data, making the DATA_BLOBs here.
252 Decrypt and encrypt the passwords.
253 ****************************************************************************/
255 BOOL
make_user_info_netlogon_network(auth_usersupplied_info
**user_info
,
256 const char *smb_name
,
257 const char *client_domain
,
258 const char *wksta_name
,
259 const uchar
*lm_network_pwd
, int lm_pwd_len
,
260 const uchar
*nt_network_pwd
, int nt_pwd_len
)
264 DATA_BLOB lm_blob
= data_blob(lm_network_pwd
, lm_pwd_len
);
265 DATA_BLOB nt_blob
= data_blob(nt_network_pwd
, nt_pwd_len
);
267 nt_status
= make_user_info_map(user_info
,
268 smb_name
, client_domain
,
270 lm_pwd_len
? &lm_blob
: NULL
,
271 nt_pwd_len
? &nt_blob
: NULL
,
275 ret
= NT_STATUS_IS_OK(nt_status
) ? True
: False
;
277 data_blob_free(&lm_blob
);
278 data_blob_free(&nt_blob
);
282 /****************************************************************************
283 Create an auth_usersupplied_data, making the DATA_BLOBs here.
284 Decrypt and encrypt the passwords.
285 ****************************************************************************/
287 BOOL
make_user_info_netlogon_interactive(auth_usersupplied_info
**user_info
,
288 const char *smb_name
,
289 const char *client_domain
,
290 const char *wksta_name
,
292 const uchar lm_interactive_pwd
[16],
293 const uchar nt_interactive_pwd
[16],
294 const uchar
*dc_sess_key
)
298 unsigned char local_lm_response
[24];
299 unsigned char local_nt_response
[24];
300 unsigned char key
[16];
303 memcpy(key
, dc_sess_key
, 8);
305 if (lm_interactive_pwd
) memcpy(lm_pwd
, lm_interactive_pwd
, sizeof(lm_pwd
));
306 if (nt_interactive_pwd
) memcpy(nt_pwd
, nt_interactive_pwd
, sizeof(nt_pwd
));
308 #ifdef DEBUG_PASSWORD
310 dump_data(100, (char *)key
, sizeof(key
));
312 DEBUG(100,("lm owf password:"));
313 dump_data(100, lm_pwd
, sizeof(lm_pwd
));
315 DEBUG(100,("nt owf password:"));
316 dump_data(100, nt_pwd
, sizeof(nt_pwd
));
319 if (lm_interactive_pwd
)
320 SamOEMhash((uchar
*)lm_pwd
, key
, sizeof(lm_pwd
));
322 if (nt_interactive_pwd
)
323 SamOEMhash((uchar
*)nt_pwd
, key
, sizeof(nt_pwd
));
325 #ifdef DEBUG_PASSWORD
326 DEBUG(100,("decrypt of lm owf password:"));
327 dump_data(100, lm_pwd
, sizeof(lm_pwd
));
329 DEBUG(100,("decrypt of nt owf password:"));
330 dump_data(100, nt_pwd
, sizeof(nt_pwd
));
333 if (lm_interactive_pwd
)
334 SMBOWFencrypt((const unsigned char *)lm_pwd
, chal
, local_lm_response
);
336 if (nt_interactive_pwd
)
337 SMBOWFencrypt((const unsigned char *)nt_pwd
, chal
, local_nt_response
);
339 /* Password info paranoia */
345 DATA_BLOB local_lm_blob
;
346 DATA_BLOB local_nt_blob
;
348 DATA_BLOB lm_interactive_blob
;
349 DATA_BLOB nt_interactive_blob
;
351 if (lm_interactive_pwd
) {
352 local_lm_blob
= data_blob(local_lm_response
, sizeof(local_lm_response
));
353 lm_interactive_blob
= data_blob(lm_pwd
, sizeof(lm_pwd
));
357 if (nt_interactive_pwd
) {
358 local_nt_blob
= data_blob(local_nt_response
, sizeof(local_nt_response
));
359 nt_interactive_blob
= data_blob(nt_pwd
, sizeof(nt_pwd
));
363 nt_status
= make_user_info_map(user_info
,
364 smb_name
, client_domain
,
366 lm_interactive_pwd
? &local_lm_blob
: NULL
,
367 nt_interactive_pwd
? &local_nt_blob
: NULL
,
368 lm_interactive_pwd
? &lm_interactive_blob
: NULL
,
369 nt_interactive_pwd
? &nt_interactive_blob
: NULL
,
373 ret
= NT_STATUS_IS_OK(nt_status
) ? True
: False
;
374 data_blob_free(&local_lm_blob
);
375 data_blob_free(&local_nt_blob
);
376 data_blob_free(&lm_interactive_blob
);
377 data_blob_free(&nt_interactive_blob
);
383 /****************************************************************************
384 Create an auth_usersupplied_data structure
385 ****************************************************************************/
387 BOOL
make_user_info_for_reply(auth_usersupplied_info
**user_info
,
388 const char *smb_name
,
389 const char *client_domain
,
391 DATA_BLOB plaintext_password
)
394 DATA_BLOB local_lm_blob
;
395 DATA_BLOB local_nt_blob
;
396 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
399 * Not encrypted - do so.
402 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
404 if (plaintext_password
.data
) {
405 unsigned char local_lm_response
[24];
407 #ifdef DEBUG_PASSWORD
408 DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password
.length
));
409 dump_data(100, plaintext_password
.data
, plaintext_password
.length
);
412 SMBencrypt( (const char *)plaintext_password
.data
, (const uchar
*)chal
, local_lm_response
);
413 local_lm_blob
= data_blob(local_lm_response
, 24);
415 /* We can't do an NT hash here, as the password needs to be
417 local_nt_blob
= data_blob(NULL
, 0);
420 local_lm_blob
= data_blob(NULL
, 0);
421 local_nt_blob
= data_blob(NULL
, 0);
424 ret
= make_user_info_map(user_info
, smb_name
,
426 get_remote_machine_name(),
427 local_lm_blob
.data
? &local_lm_blob
: NULL
,
428 local_nt_blob
.data
? &local_nt_blob
: NULL
,
430 plaintext_password
.data
? &plaintext_password
: NULL
,
433 data_blob_free(&local_lm_blob
);
434 return NT_STATUS_IS_OK(ret
) ? True
: False
;
437 /****************************************************************************
438 Create an auth_usersupplied_data structure
439 ****************************************************************************/
441 NTSTATUS
make_user_info_for_reply_enc(auth_usersupplied_info
**user_info
,
442 const char *smb_name
,
443 const char *client_domain
,
444 DATA_BLOB lm_resp
, DATA_BLOB nt_resp
)
446 return make_user_info_map(user_info
, smb_name
,
448 get_remote_machine_name(),
449 lm_resp
.data
? &lm_resp
: NULL
,
450 nt_resp
.data
? &nt_resp
: NULL
,
455 /****************************************************************************
456 Create a guest user_info blob, for anonymous authenticaion.
457 ****************************************************************************/
459 BOOL
make_user_info_guest(auth_usersupplied_info
**user_info
)
463 nt_status
= make_user_info(user_info
,
472 return NT_STATUS_IS_OK(nt_status
) ? True
: False
;
475 /****************************************************************************
476 prints a NT_USER_TOKEN to debug output.
477 ****************************************************************************/
479 void debug_nt_user_token(int dbg_class
, int dbg_lev
, NT_USER_TOKEN
*token
)
485 DEBUGC(dbg_class
, dbg_lev
, ("NT user token: (NULL)\n"));
489 DEBUGC(dbg_class
, dbg_lev
, ("NT user token of user %s\n",
490 sid_to_string(sid_str
, &token
->user_sids
[0]) ));
491 DEBUGADDC(dbg_class
, dbg_lev
, ("contains %lu SIDs\n", (unsigned long)token
->num_sids
));
492 for (i
= 0; i
< token
->num_sids
; i
++)
493 DEBUGADDC(dbg_class
, dbg_lev
, ("SID[%3lu]: %s\n", (unsigned long)i
,
494 sid_to_string(sid_str
, &token
->user_sids
[i
])));
496 dump_se_priv( dbg_class
, dbg_lev
, &token
->privileges
);
499 /****************************************************************************
500 prints a UNIX 'token' to debug output.
501 ****************************************************************************/
503 void debug_unix_user_token(int dbg_class
, int dbg_lev
, uid_t uid
, gid_t gid
, int n_groups
, gid_t
*groups
)
506 DEBUGC(dbg_class
, dbg_lev
, ("UNIX token of user %ld\n", (long int)uid
));
508 DEBUGADDC(dbg_class
, dbg_lev
, ("Primary group is %ld and contains %i supplementary groups\n", (long int)gid
, n_groups
));
509 for (i
= 0; i
< n_groups
; i
++)
510 DEBUGADDC(dbg_class
, dbg_lev
, ("Group[%3i]: %ld\n", i
,
511 (long int)groups
[i
]));
514 /****************************************************************************
515 Create the SID list for this user.
516 ****************************************************************************/
518 static NTSTATUS
create_nt_user_token(const DOM_SID
*user_sid
, const DOM_SID
*group_sid
,
519 int n_groupSIDs
, DOM_SID
*groupSIDs
,
520 BOOL is_guest
, NT_USER_TOKEN
**token
)
522 NTSTATUS nt_status
= NT_STATUS_OK
;
523 NT_USER_TOKEN
*ptoken
;
527 if ((ptoken
= SMB_MALLOC_P(NT_USER_TOKEN
)) == NULL
) {
528 DEBUG(0, ("create_nt_token: Out of memory allocating token\n"));
529 nt_status
= NT_STATUS_NO_MEMORY
;
533 ZERO_STRUCTP(ptoken
);
535 ptoken
->num_sids
= n_groupSIDs
+ 5;
537 if ((ptoken
->user_sids
= SMB_MALLOC_ARRAY( DOM_SID
, ptoken
->num_sids
)) == NULL
) {
538 DEBUG(0, ("create_nt_token: Out of memory allocating SIDs\n"));
539 nt_status
= NT_STATUS_NO_MEMORY
;
543 memset((char*)ptoken
->user_sids
,0,sizeof(DOM_SID
) * ptoken
->num_sids
);
546 * Note - user SID *MUST* be first in token !
547 * se_access_check depends on this.
549 * Primary group SID is second in token. Convention.
552 sid_copy(&ptoken
->user_sids
[PRIMARY_USER_SID_INDEX
], user_sid
);
554 sid_copy(&ptoken
->user_sids
[PRIMARY_GROUP_SID_INDEX
], group_sid
);
557 * Finally add the "standard" SIDs.
558 * The only difference between guest and "anonymous" (which we
559 * don't really support) is the addition of Authenticated_Users.
562 sid_copy(&ptoken
->user_sids
[2], &global_sid_World
);
563 sid_copy(&ptoken
->user_sids
[3], &global_sid_Network
);
566 sid_copy(&ptoken
->user_sids
[4], &global_sid_Builtin_Guests
);
568 sid_copy(&ptoken
->user_sids
[4], &global_sid_Authenticated_Users
);
570 sid_ndx
= 5; /* next available spot */
572 for (i
= 0; i
< n_groupSIDs
; i
++) {
573 size_t check_sid_idx
;
574 for (check_sid_idx
= 1; check_sid_idx
< ptoken
->num_sids
; check_sid_idx
++) {
575 if (sid_equal(&ptoken
->user_sids
[check_sid_idx
],
581 if (check_sid_idx
>= ptoken
->num_sids
) /* Not found already */ {
582 sid_copy(&ptoken
->user_sids
[sid_ndx
++], &groupSIDs
[i
]);
588 /* add privileges assigned to this user */
590 get_privileges_for_sids( &ptoken
->privileges
, ptoken
->user_sids
, ptoken
->num_sids
);
592 debug_nt_user_token(DBGC_AUTH
, 10, ptoken
);
594 if ((lp_log_nt_token_command() != NULL
) &&
595 (strlen(lp_log_nt_token_command()) > 0)) {
599 char *user_sidstr
, *group_sidstr
;
601 mem_ctx
= talloc_init("setnttoken");
603 return NT_STATUS_NO_MEMORY
;
605 sid_to_string(sidstr
, &ptoken
->user_sids
[0]);
606 user_sidstr
= talloc_strdup(mem_ctx
, sidstr
);
608 group_sidstr
= talloc_strdup(mem_ctx
, "");
609 for (i
=1; i
<ptoken
->num_sids
; i
++) {
610 sid_to_string(sidstr
, &ptoken
->user_sids
[i
]);
611 group_sidstr
= talloc_asprintf(mem_ctx
, "%s %s",
612 group_sidstr
, sidstr
);
615 command
= strdup(lp_log_nt_token_command());
616 command
= realloc_string_sub(command
, "%s", user_sidstr
);
617 command
= realloc_string_sub(command
, "%t", group_sidstr
);
618 DEBUG(8, ("running command: [%s]\n", command
));
619 if (smbrun(command
, NULL
) != 0) {
620 DEBUG(0, ("Could not log NT token\n"));
621 nt_status
= NT_STATUS_ACCESS_DENIED
;
623 talloc_destroy(mem_ctx
);
632 /****************************************************************************
633 Create the SID list for this user.
634 ****************************************************************************/
636 NT_USER_TOKEN
*create_nt_token(uid_t uid
, gid_t gid
, int ngroups
, gid_t
*groups
, BOOL is_guest
)
641 NT_USER_TOKEN
*token
;
644 if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid
, uid
))) {
647 if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid
, gid
))) {
651 group_sids
= SMB_MALLOC_ARRAY(DOM_SID
, ngroups
);
653 DEBUG(0, ("create_nt_token: malloc() failed for DOM_SID list!\n"));
657 for (i
= 0; i
< ngroups
; i
++) {
658 if (!NT_STATUS_IS_OK(gid_to_sid(&(group_sids
)[i
], (groups
)[i
]))) {
659 DEBUG(1, ("create_nt_token: failed to convert gid %ld to a sid!\n", (long int)groups
[i
]));
660 SAFE_FREE(group_sids
);
665 if (!NT_STATUS_IS_OK(create_nt_user_token(&user_sid
, &group_sid
,
666 ngroups
, group_sids
, is_guest
, &token
))) {
667 SAFE_FREE(group_sids
);
671 SAFE_FREE(group_sids
);
676 /******************************************************************************
677 * this function returns the groups (SIDs) of the local SAM the user is in.
678 * If this samba server is a DC of the domain the user belongs to, it returns
679 * both domain groups and local / builtin groups. If the user is in a trusted
680 * domain, or samba is a member server of a domain, then this function returns
681 * local and builtin groups the user is a member of.
683 * currently this is a hack, as there is no sam implementation that is capable
686 * NOTE!! This function will fail if you pass in a winbind user without
688 ******************************************************************************/
690 static NTSTATUS
get_user_groups(const char *username
, uid_t uid
, gid_t gid
,
691 int *n_groups
, DOM_SID
**groups
, gid_t
**unix_groups
)
699 if (strchr(username
, *lp_winbind_separator()) == NULL
) {
703 result
= pdb_enum_group_memberships(username
, gid
, groups
,
704 unix_groups
, n_groups
);
709 /* We have the separator, this must be winbind */
711 n_unix_groups
= winbind_getgroups( username
, unix_groups
);
713 DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n",
714 username
, n_unix_groups
== -1 ? "FAIL" : "SUCCESS"));
716 if ( n_unix_groups
== -1 )
717 return NT_STATUS_NO_SUCH_USER
; /* what should this return
720 debug_unix_user_token(DBGC_CLASS
, 5, uid
, gid
, n_unix_groups
, *unix_groups
);
722 /* now setup the space for storing the SIDS */
724 if (n_unix_groups
> 0) {
726 *groups
= SMB_MALLOC_ARRAY(DOM_SID
, n_unix_groups
);
729 DEBUG(0, ("get_user_group: malloc() failed for DOM_SID list!\n"));
730 SAFE_FREE(*unix_groups
);
731 return NT_STATUS_NO_MEMORY
;
735 *n_groups
= n_unix_groups
;
737 for (i
= 0; i
< *n_groups
; i
++) {
738 if (!NT_STATUS_IS_OK(gid_to_sid(&(*groups
)[i
], (*unix_groups
)[i
]))) {
739 DEBUG(1, ("get_user_groups: failed to convert gid %ld to a sid!\n",
740 (long int)(*unix_groups
)[i
+1]));
742 SAFE_FREE(*unix_groups
);
743 return NT_STATUS_NO_SUCH_USER
;
750 /***************************************************************************
751 Make a user_info struct
752 ***************************************************************************/
754 static NTSTATUS
make_server_info(auth_serversupplied_info
**server_info
)
756 *server_info
= SMB_MALLOC_P(auth_serversupplied_info
);
758 DEBUG(0,("make_server_info: malloc failed!\n"));
759 return NT_STATUS_NO_MEMORY
;
761 ZERO_STRUCTP(*server_info
);
763 /* Initialise the uid and gid values to something non-zero
764 which may save us from giving away root access if there
765 is a bug in allocating these fields. */
767 (*server_info
)->uid
= -1;
768 (*server_info
)->gid
= -1;
773 /***************************************************************************
774 Fill a server_info struct from a SAM_ACCOUNT with their groups
775 ***************************************************************************/
777 static NTSTATUS
add_user_groups(auth_serversupplied_info
**server_info
,
778 const char * unix_username
,
779 SAM_ACCOUNT
*sampass
,
780 uid_t uid
, gid_t gid
)
783 const DOM_SID
*user_sid
= pdb_get_user_sid(sampass
);
784 const DOM_SID
*group_sid
= pdb_get_group_sid(sampass
);
786 DOM_SID
*groupSIDs
= NULL
;
787 gid_t
*unix_groups
= NULL
;
788 NT_USER_TOKEN
*token
;
792 nt_status
= get_user_groups(unix_username
, uid
, gid
,
793 &n_groupSIDs
, &groupSIDs
, &unix_groups
);
795 if (!NT_STATUS_IS_OK(nt_status
)) {
796 DEBUG(4,("get_user_groups_from_local_sam failed\n"));
797 free_server_info(server_info
);
801 is_guest
= (sid_peek_rid(user_sid
, &rid
) && rid
== DOMAIN_USER_RID_GUEST
);
803 if (!NT_STATUS_IS_OK(nt_status
= create_nt_user_token(user_sid
, group_sid
,
804 n_groupSIDs
, groupSIDs
, is_guest
,
807 DEBUG(4,("create_nt_user_token failed\n"));
808 SAFE_FREE(groupSIDs
);
809 SAFE_FREE(unix_groups
);
810 free_server_info(server_info
);
814 SAFE_FREE(groupSIDs
);
816 (*server_info
)->n_groups
= n_groupSIDs
;
817 (*server_info
)->groups
= unix_groups
;
818 (*server_info
)->ptok
= token
;
823 /***************************************************************************
824 Make (and fill) a user_info struct from a SAM_ACCOUNT
825 ***************************************************************************/
827 NTSTATUS
make_server_info_sam(auth_serversupplied_info
**server_info
,
828 SAM_ACCOUNT
*sampass
)
833 if (!NT_STATUS_IS_OK(nt_status
= make_server_info(server_info
)))
836 (*server_info
)->sam_account
= sampass
;
838 if ( !(pwd
= getpwnam_alloc(pdb_get_username(sampass
))) ) {
839 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
840 pdb_get_username(sampass
)));
841 free_server_info(server_info
);
842 return NT_STATUS_NO_SUCH_USER
;
844 (*server_info
)->unix_name
= smb_xstrdup(pwd
->pw_name
);
845 (*server_info
)->gid
= pwd
->pw_gid
;
846 (*server_info
)->uid
= pwd
->pw_uid
;
850 if (!NT_STATUS_IS_OK(nt_status
= add_user_groups(server_info
, pdb_get_username(sampass
),
853 (*server_info
)->gid
)))
855 free_server_info(server_info
);
859 (*server_info
)->sam_fill_level
= SAM_FILL_ALL
;
860 DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
861 pdb_get_username(sampass
),
862 (*server_info
)->unix_name
));
867 /***************************************************************************
868 Make (and fill) a user_info struct from a 'struct passwd' by conversion
870 ***************************************************************************/
872 NTSTATUS
make_server_info_pw(auth_serversupplied_info
**server_info
,
877 SAM_ACCOUNT
*sampass
= NULL
;
878 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_sam_pw(&sampass
, pwd
))) {
881 if (!NT_STATUS_IS_OK(nt_status
= make_server_info(server_info
))) {
885 (*server_info
)->sam_account
= sampass
;
887 if (!NT_STATUS_IS_OK(nt_status
= add_user_groups(server_info
, unix_username
,
888 sampass
, pwd
->pw_uid
, pwd
->pw_gid
)))
893 (*server_info
)->unix_name
= smb_xstrdup(unix_username
);
895 (*server_info
)->sam_fill_level
= SAM_FILL_ALL
;
896 (*server_info
)->uid
= pwd
->pw_uid
;
897 (*server_info
)->gid
= pwd
->pw_gid
;
901 /***************************************************************************
902 Make (and fill) a user_info struct for a guest login.
903 ***************************************************************************/
905 static NTSTATUS
make_new_server_info_guest(auth_serversupplied_info
**server_info
)
908 SAM_ACCOUNT
*sampass
= NULL
;
911 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_sam(&sampass
))) {
915 sid_copy(&guest_sid
, get_global_sam_sid());
916 sid_append_rid(&guest_sid
, DOMAIN_USER_RID_GUEST
);
919 if (!pdb_getsampwsid(sampass
, &guest_sid
)) {
921 return NT_STATUS_NO_SUCH_USER
;
925 nt_status
= make_server_info_sam(server_info
, sampass
);
927 if (NT_STATUS_IS_OK(nt_status
)) {
928 static const char zeros
[16];
929 (*server_info
)->guest
= True
;
931 /* annoying, but the Guest really does have a session key,
932 and it is all zeros! */
933 (*server_info
)->user_session_key
= data_blob(zeros
, sizeof(zeros
));
934 (*server_info
)->lm_session_key
= data_blob(zeros
, sizeof(zeros
));
940 static auth_serversupplied_info
*copy_serverinfo(auth_serversupplied_info
*src
)
942 auth_serversupplied_info
*dst
;
944 if (!NT_STATUS_IS_OK(make_server_info(&dst
)))
947 dst
->guest
= src
->guest
;
950 dst
->n_groups
= src
->n_groups
;
951 if (src
->n_groups
!= 0)
952 dst
->groups
= memdup(src
->groups
, sizeof(gid_t
)*dst
->n_groups
);
955 dst
->ptok
= dup_nt_token(src
->ptok
);
956 dst
->user_session_key
= data_blob(src
->user_session_key
.data
,
957 src
->user_session_key
.length
);
958 dst
->lm_session_key
= data_blob(src
->lm_session_key
.data
,
959 src
->lm_session_key
.length
);
960 pdb_copy_sam_account(src
->sam_account
, &dst
->sam_account
);
961 dst
->pam_handle
= NULL
;
962 dst
->unix_name
= smb_xstrdup(src
->unix_name
);
967 static auth_serversupplied_info
*guest_info
= NULL
;
969 BOOL
init_guest_info(void)
971 if (guest_info
!= NULL
)
974 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info
));
977 NTSTATUS
make_server_info_guest(auth_serversupplied_info
**server_info
)
979 *server_info
= copy_serverinfo(guest_info
);
980 return (*server_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
983 /***************************************************************************
984 Purely internal function for make_server_info_info3
985 Fill the sam account from getpwnam
986 ***************************************************************************/
987 static NTSTATUS
fill_sam_account(TALLOC_CTX
*mem_ctx
,
989 const char *username
,
990 char **found_username
,
991 uid_t
*uid
, gid_t
*gid
,
992 SAM_ACCOUNT
**sam_account
)
994 fstring dom_user
, lower_username
;
995 fstring real_username
;
996 struct passwd
*passwd
;
998 fstrcpy( lower_username
, username
);
999 strlower_m( lower_username
);
1001 fstr_sprintf(dom_user
, "%s%c%s", domain
, *lp_winbind_separator(),
1004 /* get the passwd struct but don't create the user if he/she
1005 does not exist. We were explicitly called from a following
1006 a winbindd authentication request so we should assume that
1007 nss_winbindd is working */
1009 map_username( dom_user
);
1011 if ( !(passwd
= smb_getpwnam( dom_user
, real_username
, True
)) )
1012 return NT_STATUS_NO_SUCH_USER
;
1014 *uid
= passwd
->pw_uid
;
1015 *gid
= passwd
->pw_gid
;
1017 /* This is pointless -- there is no suport for differing
1018 unix and windows names. Make sure to always store the
1019 one we actually looked up and succeeded. Have I mentioned
1020 why I hate the 'winbind use default domain' parameter?
1023 *found_username
= talloc_strdup( mem_ctx
, real_username
);
1025 DEBUG(5,("fill_sam_account: located username was [%s]\n",
1028 return pdb_init_sam_pw(sam_account
, passwd
);
1031 /****************************************************************************
1032 Wrapper to allow the getpwnam() call to strip the domain name and
1033 try again in case a local UNIX user is already there. Also run through
1034 the username if we fallback to the username only.
1035 ****************************************************************************/
1037 struct passwd
*smb_getpwnam( char *domuser
, fstring save_username
, BOOL create
)
1039 struct passwd
*pw
= NULL
;
1043 /* we only save a copy of the username it has been mangled
1044 by winbindd use default domain */
1046 save_username
[0] = '\0';
1048 /* don't call map_username() here since it has to be done higher
1049 up the stack so we don't call it mutliple times */
1051 fstrcpy( username
, domuser
);
1053 p
= strchr_m( username
, *lp_winbind_separator() );
1055 /* code for a DOMAIN\user string */
1058 fstring strip_username
;
1060 pw
= Get_Pwnam( domuser
);
1062 /* make sure we get the case of the username correct */
1063 /* work around 'winbind use default domain = yes' */
1065 if ( !strchr_m( pw
->pw_name
, *lp_winbind_separator() ) ) {
1068 /* split the domain and username into 2 strings */
1072 fstr_sprintf(save_username
, "%s%c%s", domain
, *lp_winbind_separator(), pw
->pw_name
);
1075 fstrcpy( save_username
, pw
->pw_name
);
1081 /* setup for lookup of just the username */
1082 /* remember that p and username are overlapping memory */
1085 fstrcpy( strip_username
, p
);
1086 fstrcpy( username
, strip_username
);
1089 /* just lookup a plain username */
1091 pw
= Get_Pwnam(username
);
1093 /* Create local user if requested. */
1095 if ( !pw
&& create
) {
1096 /* Don't add a machine account. */
1097 if (username
[strlen(username
)-1] == '$')
1100 auth_add_user_script(NULL
, username
);
1101 pw
= Get_Pwnam(username
);
1104 /* one last check for a valid passwd struct */
1107 fstrcpy( save_username
, pw
->pw_name
);
1112 /***************************************************************************
1113 Make a server_info struct from the info3 returned by a domain logon
1114 ***************************************************************************/
1116 NTSTATUS
make_server_info_info3(TALLOC_CTX
*mem_ctx
,
1117 const char *internal_username
,
1118 const char *sent_nt_username
,
1120 auth_serversupplied_info
**server_info
,
1121 NET_USER_INFO_3
*info3
)
1123 static const char zeros
[16];
1125 NTSTATUS nt_status
= NT_STATUS_OK
;
1126 char *found_username
;
1127 const char *nt_domain
;
1128 const char *nt_username
;
1130 SAM_ACCOUNT
*sam_account
= NULL
;
1138 DOM_SID
*lgroupSIDs
= NULL
;
1140 gid_t
*unix_groups
= NULL
;
1141 NT_USER_TOKEN
*token
;
1143 DOM_SID
*all_group_SIDs
;
1147 Here is where we should check the list of
1148 trusted domains, and verify that the SID
1152 sid_copy(&user_sid
, &info3
->dom_sid
.sid
);
1153 if (!sid_append_rid(&user_sid
, info3
->user_rid
)) {
1154 return NT_STATUS_INVALID_PARAMETER
;
1157 sid_copy(&group_sid
, &info3
->dom_sid
.sid
);
1158 if (!sid_append_rid(&group_sid
, info3
->group_rid
)) {
1159 return NT_STATUS_INVALID_PARAMETER
;
1162 if (!(nt_username
= unistr2_tdup(mem_ctx
, &(info3
->uni_user_name
)))) {
1163 /* If the server didn't give us one, just use the one we sent them */
1164 nt_username
= sent_nt_username
;
1167 if (!(nt_domain
= unistr2_tdup(mem_ctx
, &(info3
->uni_logon_dom
)))) {
1168 /* If the server didn't give us one, just use the one we sent them */
1172 /* try to fill the SAM account.. If getpwnam() fails, then try the
1173 add user script (2.2.x behavior).
1175 We use the _unmapped_ username here in an attempt to provide
1176 consistent username mapping behavior between kerberos and NTLM[SSP]
1177 authentication in domain mode security. I.E. Username mapping should
1178 be applied to the fully qualified username (e.g. DOMAIN\user) and
1179 no just the login name. Yes this mean swe called map_username()
1180 unnecessarily in make_user_info_map() but that is how the current
1181 code is designed. Making the change here is the least disruptive
1184 nt_status
= fill_sam_account(mem_ctx
, nt_domain
, sent_nt_username
,
1185 &found_username
, &uid
, &gid
, &sam_account
);
1187 if (NT_STATUS_EQUAL(nt_status
, NT_STATUS_NO_SUCH_USER
)) {
1188 DEBUG(3,("User %s does not exist, trying to add it\n", internal_username
));
1189 auth_add_user_script( nt_domain
, sent_nt_username
);
1190 nt_status
= fill_sam_account( mem_ctx
, nt_domain
, sent_nt_username
,
1191 &found_username
, &uid
, &gid
, &sam_account
);
1194 if (!NT_STATUS_IS_OK(nt_status
)) {
1195 DEBUG(0, ("make_server_info_info3: pdb_init_sam failed!\n"));
1199 if (!pdb_set_nt_username(sam_account
, nt_username
, PDB_CHANGED
)) {
1200 pdb_free_sam(&sam_account
);
1201 return NT_STATUS_NO_MEMORY
;
1204 if (!pdb_set_username(sam_account
, nt_username
, PDB_CHANGED
)) {
1205 pdb_free_sam(&sam_account
);
1206 return NT_STATUS_NO_MEMORY
;
1209 if (!pdb_set_domain(sam_account
, nt_domain
, PDB_CHANGED
)) {
1210 pdb_free_sam(&sam_account
);
1211 return NT_STATUS_NO_MEMORY
;
1214 if (!pdb_set_user_sid(sam_account
, &user_sid
, PDB_CHANGED
)) {
1215 pdb_free_sam(&sam_account
);
1216 return NT_STATUS_UNSUCCESSFUL
;
1219 if (!pdb_set_group_sid(sam_account
, &group_sid
, PDB_CHANGED
)) {
1220 pdb_free_sam(&sam_account
);
1221 return NT_STATUS_UNSUCCESSFUL
;
1224 if (!pdb_set_fullname(sam_account
, unistr2_static(&(info3
->uni_full_name
)),
1226 pdb_free_sam(&sam_account
);
1227 return NT_STATUS_NO_MEMORY
;
1230 if (!pdb_set_logon_script(sam_account
, unistr2_static(&(info3
->uni_logon_script
)), PDB_CHANGED
)) {
1231 pdb_free_sam(&sam_account
);
1232 return NT_STATUS_NO_MEMORY
;
1235 if (!pdb_set_profile_path(sam_account
, unistr2_static(&(info3
->uni_profile_path
)), PDB_CHANGED
)) {
1236 pdb_free_sam(&sam_account
);
1237 return NT_STATUS_NO_MEMORY
;
1240 if (!pdb_set_homedir(sam_account
, unistr2_static(&(info3
->uni_home_dir
)), PDB_CHANGED
)) {
1241 pdb_free_sam(&sam_account
);
1242 return NT_STATUS_NO_MEMORY
;
1245 if (!pdb_set_dir_drive(sam_account
, unistr2_static(&(info3
->uni_dir_drive
)), PDB_CHANGED
)) {
1246 pdb_free_sam(&sam_account
);
1247 return NT_STATUS_NO_MEMORY
;
1250 if (!NT_STATUS_IS_OK(nt_status
= make_server_info(server_info
))) {
1251 DEBUG(4, ("make_server_info failed!\n"));
1252 pdb_free_sam(&sam_account
);
1256 /* save this here to _net_sam_logon() doesn't fail (it assumes a
1257 valid SAM_ACCOUNT) */
1259 (*server_info
)->sam_account
= sam_account
;
1261 (*server_info
)->unix_name
= smb_xstrdup(found_username
);
1263 /* Fill in the unix info we found on the way */
1265 (*server_info
)->sam_fill_level
= SAM_FILL_ALL
;
1266 (*server_info
)->uid
= uid
;
1267 (*server_info
)->gid
= gid
;
1269 /* Store the user group information in the server_info
1270 returned to the caller. */
1272 nt_status
= get_user_groups((*server_info
)->unix_name
,
1273 uid
, gid
, &n_lgroupSIDs
, &lgroupSIDs
, &unix_groups
);
1275 if ( !NT_STATUS_IS_OK(nt_status
) ) {
1276 DEBUG(4,("get_user_groups failed\n"));
1280 (*server_info
)->groups
= unix_groups
;
1281 (*server_info
)->n_groups
= n_lgroupSIDs
;
1283 /* Create a 'combined' list of all SIDs we might want in the SD */
1285 all_group_SIDs
= SMB_MALLOC_ARRAY(DOM_SID
,info3
->num_groups2
+ info3
->num_other_sids
+ n_lgroupSIDs
);
1287 if (!all_group_SIDs
) {
1288 DEBUG(0, ("malloc() failed for DOM_SID list!\n"));
1289 SAFE_FREE(lgroupSIDs
);
1290 free_server_info(server_info
);
1291 return NT_STATUS_NO_MEMORY
;
1294 /* and create (by appending rids) the 'domain' sids */
1296 for (i
= 0; i
< info3
->num_groups2
; i
++) {
1298 sid_copy(&all_group_SIDs
[i
], &(info3
->dom_sid
.sid
));
1300 if (!sid_append_rid(&all_group_SIDs
[i
], info3
->gids
[i
].g_rid
)) {
1302 nt_status
= NT_STATUS_INVALID_PARAMETER
;
1304 DEBUG(3,("could not append additional group rid 0x%x\n",
1305 info3
->gids
[i
].g_rid
));
1307 SAFE_FREE(lgroupSIDs
);
1308 SAFE_FREE(all_group_SIDs
);
1309 free_server_info(server_info
);
1316 /* Copy 'other' sids. We need to do sid filtering here to
1317 prevent possible elevation of privileges. See:
1319 http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
1322 for (i
= 0; i
< info3
->num_other_sids
; i
++) {
1323 sid_copy(&all_group_SIDs
[info3
->num_groups2
+ i
],
1324 &info3
->other_sids
[i
].sid
);
1328 /* add local alias sids */
1330 for (i
= 0; i
< n_lgroupSIDs
; i
++) {
1331 sid_copy(&all_group_SIDs
[info3
->num_groups2
+
1332 info3
->num_other_sids
+ i
],
1336 /* Where are the 'global' sids... */
1338 /* can the user be guest? if yes, where is it stored? */
1340 nt_status
= create_nt_user_token(&user_sid
, &group_sid
,
1341 info3
->num_groups2
+ info3
->num_other_sids
+ n_lgroupSIDs
,
1342 all_group_SIDs
, False
, &token
);
1344 if ( !NT_STATUS_IS_OK(nt_status
) ) {
1345 DEBUG(4,("create_nt_user_token failed\n"));
1346 SAFE_FREE(lgroupSIDs
);
1347 SAFE_FREE(all_group_SIDs
);
1348 free_server_info(server_info
);
1352 (*server_info
)->ptok
= token
;
1354 SAFE_FREE(lgroupSIDs
);
1355 SAFE_FREE(all_group_SIDs
);
1357 /* ensure we are never given NULL session keys */
1359 if (memcmp(info3
->user_sess_key
, zeros
, sizeof(zeros
)) == 0) {
1360 (*server_info
)->user_session_key
= data_blob(NULL
, 0);
1362 (*server_info
)->user_session_key
= data_blob(info3
->user_sess_key
, sizeof(info3
->user_sess_key
));
1365 if (memcmp(info3
->lm_sess_key
, zeros
, 8) == 0) {
1366 (*server_info
)->lm_session_key
= data_blob(NULL
, 0);
1368 (*server_info
)->lm_session_key
= data_blob(info3
->lm_sess_key
, sizeof(info3
->lm_sess_key
));
1371 return NT_STATUS_OK
;
1374 /***************************************************************************
1375 Free a user_info struct
1376 ***************************************************************************/
1378 void free_user_info(auth_usersupplied_info
**user_info
)
1380 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1381 if (*user_info
!= NULL
) {
1382 if ((*user_info
)->smb_name
.str
) {
1383 DEBUG(10,("structure was created for %s\n", (*user_info
)->smb_name
.str
));
1385 SAFE_FREE((*user_info
)->smb_name
.str
);
1386 SAFE_FREE((*user_info
)->internal_username
.str
);
1387 SAFE_FREE((*user_info
)->client_domain
.str
);
1388 SAFE_FREE((*user_info
)->domain
.str
);
1389 SAFE_FREE((*user_info
)->wksta_name
.str
);
1390 data_blob_free(&(*user_info
)->lm_resp
);
1391 data_blob_free(&(*user_info
)->nt_resp
);
1392 data_blob_clear_free(&(*user_info
)->lm_interactive_pwd
);
1393 data_blob_clear_free(&(*user_info
)->nt_interactive_pwd
);
1394 data_blob_clear_free(&(*user_info
)->plaintext_password
);
1395 ZERO_STRUCT(**user_info
);
1397 SAFE_FREE(*user_info
);
1400 /***************************************************************************
1401 Clear out a server_info struct that has been allocated
1402 ***************************************************************************/
1404 void free_server_info(auth_serversupplied_info
**server_info
)
1406 DEBUG(5,("attempting to free (and zero) a server_info structure\n"));
1407 if (*server_info
!= NULL
) {
1408 pdb_free_sam(&(*server_info
)->sam_account
);
1410 /* call pam_end here, unless we know we are keeping it */
1411 delete_nt_token( &(*server_info
)->ptok
);
1412 SAFE_FREE((*server_info
)->groups
);
1413 SAFE_FREE((*server_info
)->unix_name
);
1414 data_blob_free(&(*server_info
)->lm_session_key
);
1415 data_blob_free(&(*server_info
)->user_session_key
);
1416 ZERO_STRUCT(**server_info
);
1418 SAFE_FREE(*server_info
);
1421 /***************************************************************************
1422 Make an auth_methods struct
1423 ***************************************************************************/
1425 BOOL
make_auth_methods(struct auth_context
*auth_context
, auth_methods
**auth_method
)
1427 if (!auth_context
) {
1428 smb_panic("no auth_context supplied to make_auth_methods()!\n");
1432 smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
1435 *auth_method
= TALLOC_P(auth_context
->mem_ctx
, auth_methods
);
1436 if (!*auth_method
) {
1437 DEBUG(0,("make_auth_method: malloc failed!\n"));
1440 ZERO_STRUCTP(*auth_method
);
1445 /****************************************************************************
1447 ****************************************************************************/
1449 void delete_nt_token(NT_USER_TOKEN
**pptoken
)
1452 NT_USER_TOKEN
*ptoken
= *pptoken
;
1454 SAFE_FREE( ptoken
->user_sids
);
1455 ZERO_STRUCTP(ptoken
);
1457 SAFE_FREE(*pptoken
);
1460 /****************************************************************************
1461 Duplicate a SID token.
1462 ****************************************************************************/
1464 NT_USER_TOKEN
*dup_nt_token(NT_USER_TOKEN
*ptoken
)
1466 NT_USER_TOKEN
*token
;
1471 if ((token
= SMB_MALLOC_P(NT_USER_TOKEN
)) == NULL
)
1474 ZERO_STRUCTP(token
);
1476 token
->user_sids
= (DOM_SID
*)memdup( ptoken
->user_sids
, sizeof(DOM_SID
) * ptoken
->num_sids
);
1483 token
->num_sids
= ptoken
->num_sids
;
1485 /* copy the privileges; don't consider failure to be critical here */
1487 if ( !se_priv_copy( &token
->privileges
, &ptoken
->privileges
) ) {
1488 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. Continuing with 0 privileges assigned.\n"));
1494 /****************************************************************************
1495 Check for a SID in an NT_USER_TOKEN
1496 ****************************************************************************/
1498 BOOL
nt_token_check_sid ( DOM_SID
*sid
, NT_USER_TOKEN
*token
)
1502 if ( !sid
|| !token
)
1505 for ( i
=0; i
<token
->num_sids
; i
++ ) {
1506 if ( sid_equal( sid
, &token
->user_sids
[i
] ) )
1513 BOOL
nt_token_check_domain_rid( NT_USER_TOKEN
*token
, uint32 rid
)
1517 /* if we are a domain member, the get the domain SID, else for
1518 a DC or standalone server, use our own SID */
1520 if ( lp_server_role() == ROLE_DOMAIN_MEMBER
) {
1521 if ( !secrets_fetch_domain_sid( lp_workgroup(), &domain_sid
) ) {
1522 DEBUG(1,("nt_token_check_domain_rid: Cannot lookup SID for domain [%s]\n",
1528 sid_copy( &domain_sid
, get_global_sam_sid() );
1530 sid_append_rid( &domain_sid
, rid
);
1532 return nt_token_check_sid( &domain_sid
, token
);\
1536 * Verify whether or not given domain is trusted.
1538 * @param domain_name name of the domain to be verified
1539 * @return true if domain is one of the trusted once or
1540 * false if otherwise
1543 BOOL
is_trusted_domain(const char* dom_name
)
1545 DOM_SID trustdom_sid
;
1550 /* no trusted domains for a standalone server */
1552 if ( lp_server_role() == ROLE_STANDALONE
)
1555 /* if we are a DC, then check for a direct trust relationships */
1559 DEBUG (5,("is_trusted_domain: Checking for domain trust with [%s]\n",
1561 ret
= secrets_fetch_trusted_domain_password(dom_name
, &pass
, &trustdom_sid
, &lct
);
1568 /* if winbindd is not up and we are a domain member) then we need to update the
1569 trustdom_cache ourselves */
1571 if ( !winbind_ping() )
1572 update_trustdom_cache();
1575 /* now the trustdom cache should be available a DC could still
1576 * have a transitive trust so fall back to the cache of trusted
1577 * domains (like a domain member would use */
1579 if ( trustdom_cache_fetch(dom_name
, &trustdom_sid
) ) {