r6369: update release notes
[Samba.git] / source / auth / auth_util.c
bloba50a449815c1314940a16f9f3db1f90d8d533041
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
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.
24 #include "includes.h"
26 #undef DBGC_CLASS
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)
36 pstring add_script;
37 int ret;
39 pstrcpy(add_script, lp_adduser_script());
40 if (! *add_script)
41 return -1;
42 all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
43 if (domain)
44 all_string_sub(add_script, "%D", domain, sizeof(pstring));
45 if (homedir)
46 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
47 ret = smbrun(add_script,NULL);
48 flush_pwnam_cache();
49 DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
50 return ret;
53 /****************************************************************************
54 Add and Delete UNIX users on demand, based on NTSTATUS codes.
55 We don't care about RID's here so ignore.
56 ****************************************************************************/
58 void auth_add_user_script(const char *domain, const char *username)
61 * User validated ok against Domain controller.
62 * If the admin wants us to try and create a UNIX
63 * user on the fly, do so.
66 if ( *lp_adduser_script() )
67 smb_create_user(domain, username, NULL);
68 else {
69 DEBUG(10,("auth_add_user_script: no 'add user script'. Asking winbindd\n"));
71 /* should never get here is we a re a domain member running winbindd
72 However, a host set for 'security = server' might run winbindd for
73 account allocation */
75 if ( !winbind_create_user(username, NULL) ) {
76 DEBUG(5,("auth_add_user_script: winbindd_create_user() failed\n"));
81 /****************************************************************************
82 Create a SAM_ACCOUNT - either by looking in the pdb, or by faking it up from
83 unix info.
84 ****************************************************************************/
86 NTSTATUS auth_get_sam_account(const char *user, SAM_ACCOUNT **account)
88 BOOL pdb_ret;
89 NTSTATUS nt_status;
90 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(account))) {
91 return nt_status;
94 become_root();
95 pdb_ret = pdb_getsampwnam(*account, user);
96 unbecome_root();
98 if (!pdb_ret) {
100 struct passwd *pass = Get_Pwnam(user);
101 if (!pass)
102 return NT_STATUS_NO_SUCH_USER;
104 if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*account, pass))) {
105 return nt_status;
108 return NT_STATUS_OK;
111 /****************************************************************************
112 Create an auth_usersupplied_data structure
113 ****************************************************************************/
115 static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
116 const char *smb_name,
117 const char *internal_username,
118 const char *client_domain,
119 const char *domain,
120 const char *wksta_name,
121 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
122 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
123 DATA_BLOB *plaintext,
124 BOOL encrypted)
127 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
129 *user_info = SMB_MALLOC_P(auth_usersupplied_info);
130 if (!user_info) {
131 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
132 return NT_STATUS_NO_MEMORY;
135 ZERO_STRUCTP(*user_info);
137 DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
139 (*user_info)->smb_name.str = SMB_STRDUP(smb_name);
140 if ((*user_info)->smb_name.str) {
141 (*user_info)->smb_name.len = strlen(smb_name);
142 } else {
143 free_user_info(user_info);
144 return NT_STATUS_NO_MEMORY;
147 (*user_info)->internal_username.str = SMB_STRDUP(internal_username);
148 if ((*user_info)->internal_username.str) {
149 (*user_info)->internal_username.len = strlen(internal_username);
150 } else {
151 free_user_info(user_info);
152 return NT_STATUS_NO_MEMORY;
155 (*user_info)->domain.str = SMB_STRDUP(domain);
156 if ((*user_info)->domain.str) {
157 (*user_info)->domain.len = strlen(domain);
158 } else {
159 free_user_info(user_info);
160 return NT_STATUS_NO_MEMORY;
163 (*user_info)->client_domain.str = SMB_STRDUP(client_domain);
164 if ((*user_info)->client_domain.str) {
165 (*user_info)->client_domain.len = strlen(client_domain);
166 } else {
167 free_user_info(user_info);
168 return NT_STATUS_NO_MEMORY;
171 (*user_info)->wksta_name.str = SMB_STRDUP(wksta_name);
172 if ((*user_info)->wksta_name.str) {
173 (*user_info)->wksta_name.len = strlen(wksta_name);
174 } else {
175 free_user_info(user_info);
176 return NT_STATUS_NO_MEMORY;
179 DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
181 if (lm_pwd)
182 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
183 if (nt_pwd)
184 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
185 if (lm_interactive_pwd)
186 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
187 if (nt_interactive_pwd)
188 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
190 if (plaintext)
191 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
193 (*user_info)->encrypted = encrypted;
195 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
197 return NT_STATUS_OK;
200 /****************************************************************************
201 Create an auth_usersupplied_data structure after appropriate mapping.
202 ****************************************************************************/
204 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
205 const char *smb_name,
206 const char *client_domain,
207 const char *wksta_name,
208 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
209 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
210 DATA_BLOB *plaintext,
211 BOOL encrypted)
213 const char *domain;
214 fstring internal_username;
215 fstrcpy(internal_username, smb_name);
216 map_username(internal_username);
218 DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
219 client_domain, smb_name, wksta_name));
221 /* don't allow "" as a domain, fixes a Win9X bug
222 where it doens't supply a domain for logon script
223 'net use' commands. */
225 if ( *client_domain )
226 domain = client_domain;
227 else
228 domain = lp_workgroup();
230 /* do what win2k does. Always map unknown domains to our own
231 and let the "passdb backend" handle unknown users. */
233 if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) )
234 domain = get_default_sam_name();
236 /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
238 return make_user_info(user_info, smb_name, internal_username,
239 client_domain, domain, wksta_name,
240 lm_pwd, nt_pwd,
241 lm_interactive_pwd, nt_interactive_pwd,
242 plaintext, encrypted);
245 /****************************************************************************
246 Create an auth_usersupplied_data, making the DATA_BLOBs here.
247 Decrypt and encrypt the passwords.
248 ****************************************************************************/
250 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
251 const char *smb_name,
252 const char *client_domain,
253 const char *wksta_name,
254 const uchar *lm_network_pwd, int lm_pwd_len,
255 const uchar *nt_network_pwd, int nt_pwd_len)
257 BOOL ret;
258 NTSTATUS nt_status;
259 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
260 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
262 nt_status = make_user_info_map(user_info,
263 smb_name, client_domain,
264 wksta_name,
265 lm_pwd_len ? &lm_blob : NULL,
266 nt_pwd_len ? &nt_blob : NULL,
267 NULL, NULL, NULL,
268 True);
270 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
272 data_blob_free(&lm_blob);
273 data_blob_free(&nt_blob);
274 return ret;
277 /****************************************************************************
278 Create an auth_usersupplied_data, making the DATA_BLOBs here.
279 Decrypt and encrypt the passwords.
280 ****************************************************************************/
282 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
283 const char *smb_name,
284 const char *client_domain,
285 const char *wksta_name,
286 const uchar chal[8],
287 const uchar lm_interactive_pwd[16],
288 const uchar nt_interactive_pwd[16],
289 const uchar *dc_sess_key)
291 char lm_pwd[16];
292 char nt_pwd[16];
293 unsigned char local_lm_response[24];
294 unsigned char local_nt_response[24];
295 unsigned char key[16];
297 ZERO_STRUCT(key);
298 memcpy(key, dc_sess_key, 8);
300 if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
301 if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
303 #ifdef DEBUG_PASSWORD
304 DEBUG(100,("key:"));
305 dump_data(100, (char *)key, sizeof(key));
307 DEBUG(100,("lm owf password:"));
308 dump_data(100, lm_pwd, sizeof(lm_pwd));
310 DEBUG(100,("nt owf password:"));
311 dump_data(100, nt_pwd, sizeof(nt_pwd));
312 #endif
314 if (lm_interactive_pwd)
315 SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
317 if (nt_interactive_pwd)
318 SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
320 #ifdef DEBUG_PASSWORD
321 DEBUG(100,("decrypt of lm owf password:"));
322 dump_data(100, lm_pwd, sizeof(lm_pwd));
324 DEBUG(100,("decrypt of nt owf password:"));
325 dump_data(100, nt_pwd, sizeof(nt_pwd));
326 #endif
328 if (lm_interactive_pwd)
329 SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
331 if (nt_interactive_pwd)
332 SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
334 /* Password info paranoia */
335 ZERO_STRUCT(key);
338 BOOL ret;
339 NTSTATUS nt_status;
340 DATA_BLOB local_lm_blob;
341 DATA_BLOB local_nt_blob;
343 DATA_BLOB lm_interactive_blob;
344 DATA_BLOB nt_interactive_blob;
346 if (lm_interactive_pwd) {
347 local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
348 lm_interactive_blob = data_blob(lm_pwd, sizeof(lm_pwd));
349 ZERO_STRUCT(lm_pwd);
352 if (nt_interactive_pwd) {
353 local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
354 nt_interactive_blob = data_blob(nt_pwd, sizeof(nt_pwd));
355 ZERO_STRUCT(nt_pwd);
358 nt_status = make_user_info_map(user_info,
359 smb_name, client_domain,
360 wksta_name,
361 lm_interactive_pwd ? &local_lm_blob : NULL,
362 nt_interactive_pwd ? &local_nt_blob : NULL,
363 lm_interactive_pwd ? &lm_interactive_blob : NULL,
364 nt_interactive_pwd ? &nt_interactive_blob : NULL,
365 NULL,
366 True);
368 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
369 data_blob_free(&local_lm_blob);
370 data_blob_free(&local_nt_blob);
371 data_blob_free(&lm_interactive_blob);
372 data_blob_free(&nt_interactive_blob);
373 return ret;
378 /****************************************************************************
379 Create an auth_usersupplied_data structure
380 ****************************************************************************/
382 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
383 const char *smb_name,
384 const char *client_domain,
385 const uint8 chal[8],
386 DATA_BLOB plaintext_password)
389 DATA_BLOB local_lm_blob;
390 DATA_BLOB local_nt_blob;
391 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
394 * Not encrypted - do so.
397 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
399 if (plaintext_password.data) {
400 unsigned char local_lm_response[24];
402 #ifdef DEBUG_PASSWORD
403 DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
404 dump_data(100, plaintext_password.data, plaintext_password.length);
405 #endif
407 SMBencrypt( (const char *)plaintext_password.data, (const uchar*)chal, local_lm_response);
408 local_lm_blob = data_blob(local_lm_response, 24);
410 /* We can't do an NT hash here, as the password needs to be
411 case insensitive */
412 local_nt_blob = data_blob(NULL, 0);
414 } else {
415 local_lm_blob = data_blob(NULL, 0);
416 local_nt_blob = data_blob(NULL, 0);
419 ret = make_user_info_map(user_info, smb_name,
420 client_domain,
421 get_remote_machine_name(),
422 local_lm_blob.data ? &local_lm_blob : NULL,
423 local_nt_blob.data ? &local_nt_blob : NULL,
424 NULL, NULL,
425 plaintext_password.data ? &plaintext_password : NULL,
426 False);
428 data_blob_free(&local_lm_blob);
429 return NT_STATUS_IS_OK(ret) ? True : False;
432 /****************************************************************************
433 Create an auth_usersupplied_data structure
434 ****************************************************************************/
436 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
437 const char *smb_name,
438 const char *client_domain,
439 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
441 return make_user_info_map(user_info, smb_name,
442 client_domain,
443 get_remote_machine_name(),
444 lm_resp.data ? &lm_resp : NULL,
445 nt_resp.data ? &nt_resp : NULL,
446 NULL, NULL, NULL,
447 True);
450 /****************************************************************************
451 Create a guest user_info blob, for anonymous authenticaion.
452 ****************************************************************************/
454 BOOL make_user_info_guest(auth_usersupplied_info **user_info)
456 NTSTATUS nt_status;
458 nt_status = make_user_info(user_info,
459 "","",
460 "","",
461 "",
462 NULL, NULL,
463 NULL, NULL,
464 NULL,
465 True);
467 return NT_STATUS_IS_OK(nt_status) ? True : False;
470 /****************************************************************************
471 prints a NT_USER_TOKEN to debug output.
472 ****************************************************************************/
474 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
476 fstring sid_str;
477 size_t i;
479 if (!token) {
480 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
481 return;
484 DEBUGC(dbg_class, dbg_lev, ("NT user token of user %s\n",
485 sid_to_string(sid_str, &token->user_sids[0]) ));
486 DEBUGADDC(dbg_class, dbg_lev, ("contains %lu SIDs\n", (unsigned long)token->num_sids));
487 for (i = 0; i < token->num_sids; i++)
488 DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i,
489 sid_to_string(sid_str, &token->user_sids[i])));
491 dump_se_priv( dbg_class, dbg_lev, &token->privileges );
494 /****************************************************************************
495 prints a UNIX 'token' to debug output.
496 ****************************************************************************/
498 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid, int n_groups, gid_t *groups)
500 int i;
501 DEBUGC(dbg_class, dbg_lev, ("UNIX token of user %ld\n", (long int)uid));
503 DEBUGADDC(dbg_class, dbg_lev, ("Primary group is %ld and contains %i supplementary groups\n", (long int)gid, n_groups));
504 for (i = 0; i < n_groups; i++)
505 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i,
506 (long int)groups[i]));
509 /****************************************************************************
510 Create the SID list for this user.
511 ****************************************************************************/
513 static NTSTATUS create_nt_user_token(const DOM_SID *user_sid, const DOM_SID *group_sid,
514 int n_groupSIDs, DOM_SID *groupSIDs,
515 BOOL is_guest, NT_USER_TOKEN **token)
517 NTSTATUS nt_status = NT_STATUS_OK;
518 NT_USER_TOKEN *ptoken;
519 int i;
520 int sid_ndx;
522 if ((ptoken = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL) {
523 DEBUG(0, ("create_nt_token: Out of memory allocating token\n"));
524 nt_status = NT_STATUS_NO_MEMORY;
525 return nt_status;
528 ZERO_STRUCTP(ptoken);
530 ptoken->num_sids = n_groupSIDs + 5;
532 if ((ptoken->user_sids = SMB_MALLOC_ARRAY( DOM_SID, ptoken->num_sids )) == NULL) {
533 DEBUG(0, ("create_nt_token: Out of memory allocating SIDs\n"));
534 nt_status = NT_STATUS_NO_MEMORY;
535 return nt_status;
538 memset((char*)ptoken->user_sids,0,sizeof(DOM_SID) * ptoken->num_sids);
541 * Note - user SID *MUST* be first in token !
542 * se_access_check depends on this.
544 * Primary group SID is second in token. Convention.
547 sid_copy(&ptoken->user_sids[PRIMARY_USER_SID_INDEX], user_sid);
548 if (group_sid)
549 sid_copy(&ptoken->user_sids[PRIMARY_GROUP_SID_INDEX], group_sid);
552 * Finally add the "standard" SIDs.
553 * The only difference between guest and "anonymous" (which we
554 * don't really support) is the addition of Authenticated_Users.
557 sid_copy(&ptoken->user_sids[2], &global_sid_World);
558 sid_copy(&ptoken->user_sids[3], &global_sid_Network);
560 if (is_guest)
561 sid_copy(&ptoken->user_sids[4], &global_sid_Builtin_Guests);
562 else
563 sid_copy(&ptoken->user_sids[4], &global_sid_Authenticated_Users);
565 sid_ndx = 5; /* next available spot */
567 for (i = 0; i < n_groupSIDs; i++) {
568 size_t check_sid_idx;
569 for (check_sid_idx = 1; check_sid_idx < ptoken->num_sids; check_sid_idx++) {
570 if (sid_equal(&ptoken->user_sids[check_sid_idx],
571 &groupSIDs[i])) {
572 break;
576 if (check_sid_idx >= ptoken->num_sids) /* Not found already */ {
577 sid_copy(&ptoken->user_sids[sid_ndx++], &groupSIDs[i]);
578 } else {
579 ptoken->num_sids--;
583 /* add privileges assigned to this user */
585 get_privileges_for_sids( &ptoken->privileges, ptoken->user_sids, ptoken->num_sids );
587 debug_nt_user_token(DBGC_AUTH, 10, ptoken);
589 if ((lp_log_nt_token_command() != NULL) &&
590 (strlen(lp_log_nt_token_command()) > 0)) {
591 TALLOC_CTX *mem_ctx;
592 char *command;
593 fstring sidstr;
594 char *user_sidstr, *group_sidstr;
596 mem_ctx = talloc_init("setnttoken");
597 if (mem_ctx == NULL)
598 return NT_STATUS_NO_MEMORY;
600 sid_to_string(sidstr, &ptoken->user_sids[0]);
601 user_sidstr = talloc_strdup(mem_ctx, sidstr);
603 group_sidstr = talloc_strdup(mem_ctx, "");
604 for (i=1; i<ptoken->num_sids; i++) {
605 sid_to_string(sidstr, &ptoken->user_sids[i]);
606 group_sidstr = talloc_asprintf(mem_ctx, "%s %s",
607 group_sidstr, sidstr);
610 command = strdup(lp_log_nt_token_command());
611 command = realloc_string_sub(command, "%s", user_sidstr);
612 command = realloc_string_sub(command, "%t", group_sidstr);
613 DEBUG(8, ("running command: [%s]\n", command));
614 if (smbrun(command, NULL) != 0) {
615 DEBUG(0, ("Could not log NT token\n"));
616 nt_status = NT_STATUS_ACCESS_DENIED;
618 talloc_destroy(mem_ctx);
619 SAFE_FREE(command);
622 *token = ptoken;
624 return nt_status;
627 /****************************************************************************
628 Create the SID list for this user.
629 ****************************************************************************/
631 NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest)
633 DOM_SID user_sid;
634 DOM_SID group_sid;
635 DOM_SID *group_sids;
636 NT_USER_TOKEN *token;
637 int i;
639 if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, uid))) {
640 return NULL;
642 if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, gid))) {
643 return NULL;
646 group_sids = SMB_MALLOC_ARRAY(DOM_SID, ngroups);
647 if (!group_sids) {
648 DEBUG(0, ("create_nt_token: malloc() failed for DOM_SID list!\n"));
649 return NULL;
652 for (i = 0; i < ngroups; i++) {
653 if (!NT_STATUS_IS_OK(gid_to_sid(&(group_sids)[i], (groups)[i]))) {
654 DEBUG(1, ("create_nt_token: failed to convert gid %ld to a sid!\n", (long int)groups[i]));
655 SAFE_FREE(group_sids);
656 return NULL;
660 if (!NT_STATUS_IS_OK(create_nt_user_token(&user_sid, &group_sid,
661 ngroups, group_sids, is_guest, &token))) {
662 SAFE_FREE(group_sids);
663 return NULL;
666 SAFE_FREE(group_sids);
668 return token;
671 /******************************************************************************
672 * this function returns the groups (SIDs) of the local SAM the user is in.
673 * If this samba server is a DC of the domain the user belongs to, it returns
674 * both domain groups and local / builtin groups. If the user is in a trusted
675 * domain, or samba is a member server of a domain, then this function returns
676 * local and builtin groups the user is a member of.
678 * currently this is a hack, as there is no sam implementation that is capable
679 * of groups.
681 * NOTE!! This function will fail if you pass in a winbind user without
682 * the domain --jerry
683 ******************************************************************************/
685 static NTSTATUS get_user_groups(const char *username, uid_t uid, gid_t gid,
686 int *n_groups, DOM_SID **groups, gid_t **unix_groups)
688 int n_unix_groups;
689 int i;
691 *n_groups = 0;
692 *groups = NULL;
694 if (strchr(username, *lp_winbind_separator()) == NULL) {
695 NTSTATUS result;
697 become_root();
698 result = pdb_enum_group_memberships(username, gid, groups,
699 unix_groups, n_groups);
700 unbecome_root();
701 return result;
704 /* We have the separator, this must be winbind */
706 n_unix_groups = winbind_getgroups( username, unix_groups );
708 DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n",
709 username, n_unix_groups == -1 ? "FAIL" : "SUCCESS"));
711 if ( n_unix_groups == -1 )
712 return NT_STATUS_NO_SUCH_USER; /* what should this return
713 * value be? */
715 debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups);
717 /* now setup the space for storing the SIDS */
719 if (n_unix_groups > 0) {
721 *groups = SMB_MALLOC_ARRAY(DOM_SID, n_unix_groups);
723 if (!*groups) {
724 DEBUG(0, ("get_user_group: malloc() failed for DOM_SID list!\n"));
725 SAFE_FREE(*unix_groups);
726 return NT_STATUS_NO_MEMORY;
730 *n_groups = n_unix_groups;
732 for (i = 0; i < *n_groups; i++) {
733 if (!NT_STATUS_IS_OK(gid_to_sid(&(*groups)[i], (*unix_groups)[i]))) {
734 DEBUG(1, ("get_user_groups: failed to convert gid %ld to a sid!\n",
735 (long int)(*unix_groups)[i+1]));
736 SAFE_FREE(*groups);
737 SAFE_FREE(*unix_groups);
738 return NT_STATUS_NO_SUCH_USER;
742 return NT_STATUS_OK;
745 /***************************************************************************
746 Make a user_info struct
747 ***************************************************************************/
749 static NTSTATUS make_server_info(auth_serversupplied_info **server_info)
751 *server_info = SMB_MALLOC_P(auth_serversupplied_info);
752 if (!*server_info) {
753 DEBUG(0,("make_server_info: malloc failed!\n"));
754 return NT_STATUS_NO_MEMORY;
756 ZERO_STRUCTP(*server_info);
758 /* Initialise the uid and gid values to something non-zero
759 which may save us from giving away root access if there
760 is a bug in allocating these fields. */
762 (*server_info)->uid = -1;
763 (*server_info)->gid = -1;
765 return NT_STATUS_OK;
768 /***************************************************************************
769 Fill a server_info struct from a SAM_ACCOUNT with their groups
770 ***************************************************************************/
772 static NTSTATUS add_user_groups(auth_serversupplied_info **server_info,
773 const char * unix_username,
774 SAM_ACCOUNT *sampass,
775 uid_t uid, gid_t gid)
777 NTSTATUS nt_status;
778 const DOM_SID *user_sid = pdb_get_user_sid(sampass);
779 const DOM_SID *group_sid = pdb_get_group_sid(sampass);
780 int n_groupSIDs = 0;
781 DOM_SID *groupSIDs = NULL;
782 gid_t *unix_groups = NULL;
783 NT_USER_TOKEN *token;
784 BOOL is_guest;
785 uint32 rid;
787 nt_status = get_user_groups(unix_username, uid, gid,
788 &n_groupSIDs, &groupSIDs, &unix_groups);
790 if (!NT_STATUS_IS_OK(nt_status)) {
791 DEBUG(4,("get_user_groups_from_local_sam failed\n"));
792 free_server_info(server_info);
793 return nt_status;
796 is_guest = (sid_peek_rid(user_sid, &rid) && rid == DOMAIN_USER_RID_GUEST);
798 if (!NT_STATUS_IS_OK(nt_status = create_nt_user_token(user_sid, group_sid,
799 n_groupSIDs, groupSIDs, is_guest,
800 &token)))
802 DEBUG(4,("create_nt_user_token failed\n"));
803 SAFE_FREE(groupSIDs);
804 SAFE_FREE(unix_groups);
805 free_server_info(server_info);
806 return nt_status;
809 SAFE_FREE(groupSIDs);
811 (*server_info)->n_groups = n_groupSIDs;
812 (*server_info)->groups = unix_groups;
813 (*server_info)->ptok = token;
815 return nt_status;
818 /***************************************************************************
819 Make (and fill) a user_info struct from a SAM_ACCOUNT
820 ***************************************************************************/
822 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
823 SAM_ACCOUNT *sampass)
825 NTSTATUS nt_status;
826 struct passwd *pwd;
828 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info)))
829 return nt_status;
831 (*server_info)->sam_account = sampass;
833 if ( !(pwd = getpwnam_alloc(pdb_get_username(sampass))) ) {
834 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
835 pdb_get_username(sampass)));
836 free_server_info(server_info);
837 return NT_STATUS_NO_SUCH_USER;
839 (*server_info)->unix_name = smb_xstrdup(pwd->pw_name);
840 (*server_info)->gid = pwd->pw_gid;
841 (*server_info)->uid = pwd->pw_uid;
843 passwd_free(&pwd);
845 if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, pdb_get_username(sampass),
846 sampass,
847 (*server_info)->uid,
848 (*server_info)->gid)))
850 free_server_info(server_info);
851 return nt_status;
854 (*server_info)->sam_fill_level = SAM_FILL_ALL;
855 DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
856 pdb_get_username(sampass),
857 (*server_info)->unix_name));
859 return nt_status;
862 /***************************************************************************
863 Make (and fill) a user_info struct from a 'struct passwd' by conversion
864 to a SAM_ACCOUNT
865 ***************************************************************************/
867 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
868 char *unix_username,
869 struct passwd *pwd)
871 NTSTATUS nt_status;
872 SAM_ACCOUNT *sampass = NULL;
873 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {
874 return nt_status;
876 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
877 return nt_status;
880 (*server_info)->sam_account = sampass;
882 if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username,
883 sampass, pwd->pw_uid, pwd->pw_gid)))
885 return nt_status;
888 (*server_info)->unix_name = smb_xstrdup(unix_username);
890 (*server_info)->sam_fill_level = SAM_FILL_ALL;
891 (*server_info)->uid = pwd->pw_uid;
892 (*server_info)->gid = pwd->pw_gid;
893 return nt_status;
896 /***************************************************************************
897 Make (and fill) a user_info struct for a guest login.
898 ***************************************************************************/
900 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
902 NTSTATUS nt_status;
903 SAM_ACCOUNT *sampass = NULL;
904 DOM_SID guest_sid;
906 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) {
907 return nt_status;
910 sid_copy(&guest_sid, get_global_sam_sid());
911 sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
913 become_root();
914 if (!pdb_getsampwsid(sampass, &guest_sid)) {
915 unbecome_root();
916 return NT_STATUS_NO_SUCH_USER;
918 unbecome_root();
920 nt_status = make_server_info_sam(server_info, sampass);
922 if (NT_STATUS_IS_OK(nt_status)) {
923 static const char zeros[16];
924 (*server_info)->guest = True;
926 /* annoying, but the Guest really does have a session key,
927 and it is all zeros! */
928 (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
929 (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
932 return nt_status;
935 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
937 auth_serversupplied_info *dst;
939 if (!NT_STATUS_IS_OK(make_server_info(&dst)))
940 return NULL;
942 dst->guest = src->guest;
943 dst->uid = src->uid;
944 dst->gid = src->gid;
945 dst->n_groups = src->n_groups;
946 if (src->n_groups != 0)
947 dst->groups = memdup(src->groups, sizeof(gid_t)*dst->n_groups);
948 else
949 dst->groups = NULL;
950 dst->ptok = dup_nt_token(src->ptok);
951 dst->user_session_key = data_blob(src->user_session_key.data,
952 src->user_session_key.length);
953 dst->lm_session_key = data_blob(src->lm_session_key.data,
954 src->lm_session_key.length);
955 pdb_copy_sam_account(src->sam_account, &dst->sam_account);
956 dst->pam_handle = NULL;
957 dst->unix_name = smb_xstrdup(src->unix_name);
959 return dst;
962 static auth_serversupplied_info *guest_info = NULL;
964 BOOL init_guest_info(void)
966 if (guest_info != NULL)
967 return True;
969 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
972 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
974 *server_info = copy_serverinfo(guest_info);
975 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
978 /***************************************************************************
979 Purely internal function for make_server_info_info3
980 Fill the sam account from getpwnam
981 ***************************************************************************/
982 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
983 const char *domain,
984 const char *username,
985 char **found_username,
986 uid_t *uid, gid_t *gid,
987 SAM_ACCOUNT **sam_account)
989 fstring dom_user, lower_username;
990 fstring real_username;
991 struct passwd *passwd;
993 fstrcpy( lower_username, username );
994 strlower_m( lower_username );
996 fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(),
997 lower_username);
999 /* get the passwd struct but don't create the user if he/she
1000 does not exist. We were explicitly called from a following
1001 a winbindd authentication request so we should assume that
1002 nss_winbindd is working */
1004 map_username( dom_user );
1006 if ( !(passwd = smb_getpwnam( dom_user, real_username, True )) )
1007 return NT_STATUS_NO_SUCH_USER;
1009 *uid = passwd->pw_uid;
1010 *gid = passwd->pw_gid;
1012 /* This is pointless -- there is no suport for differing
1013 unix and windows names. Make sure to always store the
1014 one we actually looked up and succeeded. Have I mentioned
1015 why I hate the 'winbind use default domain' parameter?
1016 --jerry */
1018 *found_username = talloc_strdup( mem_ctx, real_username );
1020 DEBUG(5,("fill_sam_account: located username was [%s]\n",
1021 *found_username));
1023 return pdb_init_sam_pw(sam_account, passwd);
1026 /****************************************************************************
1027 Wrapper to allow the getpwnam() call to strip the domain name and
1028 try again in case a local UNIX user is already there. Also run through
1029 the username if we fallback to the username only.
1030 ****************************************************************************/
1032 struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create )
1034 struct passwd *pw = NULL;
1035 char *p;
1036 fstring username;
1038 /* we only save a copy of the username it has been mangled
1039 by winbindd use default domain */
1041 save_username[0] = '\0';
1043 /* don't call map_username() here since it has to be done higher
1044 up the stack so we don't call it mutliple times */
1046 fstrcpy( username, domuser );
1048 p = strchr_m( username, *lp_winbind_separator() );
1050 /* code for a DOMAIN\user string */
1052 if ( p ) {
1053 fstring strip_username;
1055 pw = Get_Pwnam( domuser );
1056 if ( pw ) {
1057 /* make sure we get the case of the username correct */
1058 /* work around 'winbind use default domain = yes' */
1060 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1061 char *domain;
1063 /* split the domain and username into 2 strings */
1064 *p = '\0';
1065 domain = username;
1067 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1069 else
1070 fstrcpy( save_username, pw->pw_name );
1072 /* whew -- done! */
1073 return pw;
1076 /* setup for lookup of just the username */
1077 /* remember that p and username are overlapping memory */
1079 p++;
1080 fstrcpy( strip_username, p );
1081 fstrcpy( username, strip_username );
1084 /* just lookup a plain username */
1086 pw = Get_Pwnam(username);
1088 /* Create local user if requested. */
1090 if ( !pw && create ) {
1091 /* Don't add a machine account. */
1092 if (username[strlen(username)-1] == '$')
1093 return NULL;
1095 auth_add_user_script(NULL, username);
1096 pw = Get_Pwnam(username);
1099 /* one last check for a valid passwd struct */
1101 if ( pw )
1102 fstrcpy( save_username, pw->pw_name );
1104 return pw;
1107 /***************************************************************************
1108 Make a server_info struct from the info3 returned by a domain logon
1109 ***************************************************************************/
1111 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1112 const char *internal_username,
1113 const char *sent_nt_username,
1114 const char *domain,
1115 auth_serversupplied_info **server_info,
1116 NET_USER_INFO_3 *info3)
1118 static const char zeros[16];
1120 NTSTATUS nt_status = NT_STATUS_OK;
1121 char *found_username;
1122 const char *nt_domain;
1123 const char *nt_username;
1125 SAM_ACCOUNT *sam_account = NULL;
1126 DOM_SID user_sid;
1127 DOM_SID group_sid;
1129 uid_t uid;
1130 gid_t gid;
1132 int n_lgroupSIDs;
1133 DOM_SID *lgroupSIDs = NULL;
1135 gid_t *unix_groups = NULL;
1136 NT_USER_TOKEN *token;
1138 DOM_SID *all_group_SIDs;
1139 size_t i;
1142 Here is where we should check the list of
1143 trusted domains, and verify that the SID
1144 matches.
1147 sid_copy(&user_sid, &info3->dom_sid.sid);
1148 if (!sid_append_rid(&user_sid, info3->user_rid)) {
1149 return NT_STATUS_INVALID_PARAMETER;
1152 sid_copy(&group_sid, &info3->dom_sid.sid);
1153 if (!sid_append_rid(&group_sid, info3->group_rid)) {
1154 return NT_STATUS_INVALID_PARAMETER;
1157 if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1158 /* If the server didn't give us one, just use the one we sent them */
1159 nt_username = sent_nt_username;
1162 if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1163 /* If the server didn't give us one, just use the one we sent them */
1164 nt_domain = domain;
1167 /* try to fill the SAM account.. If getpwnam() fails, then try the
1168 add user script (2.2.x behavior).
1170 We use the _unmapped_ username here in an attempt to provide
1171 consistent username mapping behavior between kerberos and NTLM[SSP]
1172 authentication in domain mode security. I.E. Username mapping should
1173 be applied to the fully qualified username (e.g. DOMAIN\user) and
1174 no just the login name. Yes this mean swe called map_username()
1175 unnecessarily in make_user_info_map() but that is how the current
1176 code is designed. Making the change here is the least disruptive
1177 place. -- jerry */
1179 nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1180 &found_username, &uid, &gid, &sam_account);
1182 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
1183 DEBUG(3,("User %s does not exist, trying to add it\n", internal_username));
1184 auth_add_user_script( nt_domain, sent_nt_username );
1185 nt_status = fill_sam_account( mem_ctx, nt_domain, sent_nt_username,
1186 &found_username, &uid, &gid, &sam_account );
1189 if (!NT_STATUS_IS_OK(nt_status)) {
1190 DEBUG(0, ("make_server_info_info3: pdb_init_sam failed!\n"));
1191 return nt_status;
1194 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1195 pdb_free_sam(&sam_account);
1196 return NT_STATUS_NO_MEMORY;
1199 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1200 pdb_free_sam(&sam_account);
1201 return NT_STATUS_NO_MEMORY;
1204 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1205 pdb_free_sam(&sam_account);
1206 return NT_STATUS_NO_MEMORY;
1209 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1210 pdb_free_sam(&sam_account);
1211 return NT_STATUS_UNSUCCESSFUL;
1214 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1215 pdb_free_sam(&sam_account);
1216 return NT_STATUS_UNSUCCESSFUL;
1219 if (!pdb_set_fullname(sam_account, unistr2_static(&(info3->uni_full_name)),
1220 PDB_CHANGED)) {
1221 pdb_free_sam(&sam_account);
1222 return NT_STATUS_NO_MEMORY;
1225 if (!pdb_set_logon_script(sam_account, unistr2_static(&(info3->uni_logon_script)), PDB_CHANGED)) {
1226 pdb_free_sam(&sam_account);
1227 return NT_STATUS_NO_MEMORY;
1230 if (!pdb_set_profile_path(sam_account, unistr2_static(&(info3->uni_profile_path)), PDB_CHANGED)) {
1231 pdb_free_sam(&sam_account);
1232 return NT_STATUS_NO_MEMORY;
1235 if (!pdb_set_homedir(sam_account, unistr2_static(&(info3->uni_home_dir)), PDB_CHANGED)) {
1236 pdb_free_sam(&sam_account);
1237 return NT_STATUS_NO_MEMORY;
1240 if (!pdb_set_dir_drive(sam_account, unistr2_static(&(info3->uni_dir_drive)), PDB_CHANGED)) {
1241 pdb_free_sam(&sam_account);
1242 return NT_STATUS_NO_MEMORY;
1245 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
1246 DEBUG(4, ("make_server_info failed!\n"));
1247 pdb_free_sam(&sam_account);
1248 return nt_status;
1251 /* save this here to _net_sam_logon() doesn't fail (it assumes a
1252 valid SAM_ACCOUNT) */
1254 (*server_info)->sam_account = sam_account;
1256 (*server_info)->unix_name = smb_xstrdup(found_username);
1258 /* Fill in the unix info we found on the way */
1260 (*server_info)->sam_fill_level = SAM_FILL_ALL;
1261 (*server_info)->uid = uid;
1262 (*server_info)->gid = gid;
1264 /* Store the user group information in the server_info
1265 returned to the caller. */
1267 nt_status = get_user_groups((*server_info)->unix_name,
1268 uid, gid, &n_lgroupSIDs, &lgroupSIDs, &unix_groups);
1270 if ( !NT_STATUS_IS_OK(nt_status) ) {
1271 DEBUG(4,("get_user_groups failed\n"));
1272 return nt_status;
1275 (*server_info)->groups = unix_groups;
1276 (*server_info)->n_groups = n_lgroupSIDs;
1278 /* Create a 'combined' list of all SIDs we might want in the SD */
1280 all_group_SIDs = SMB_MALLOC_ARRAY(DOM_SID,info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs);
1282 if (!all_group_SIDs) {
1283 DEBUG(0, ("malloc() failed for DOM_SID list!\n"));
1284 SAFE_FREE(lgroupSIDs);
1285 free_server_info(server_info);
1286 return NT_STATUS_NO_MEMORY;
1289 /* and create (by appending rids) the 'domain' sids */
1291 for (i = 0; i < info3->num_groups2; i++) {
1293 sid_copy(&all_group_SIDs[i], &(info3->dom_sid.sid));
1295 if (!sid_append_rid(&all_group_SIDs[i], info3->gids[i].g_rid)) {
1297 nt_status = NT_STATUS_INVALID_PARAMETER;
1299 DEBUG(3,("could not append additional group rid 0x%x\n",
1300 info3->gids[i].g_rid));
1302 SAFE_FREE(lgroupSIDs);
1303 SAFE_FREE(all_group_SIDs);
1304 free_server_info(server_info);
1306 return nt_status;
1311 /* Copy 'other' sids. We need to do sid filtering here to
1312 prevent possible elevation of privileges. See:
1314 http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
1317 for (i = 0; i < info3->num_other_sids; i++) {
1318 sid_copy(&all_group_SIDs[info3->num_groups2 + i],
1319 &info3->other_sids[i].sid);
1323 /* add local alias sids */
1325 for (i = 0; i < n_lgroupSIDs; i++) {
1326 sid_copy(&all_group_SIDs[info3->num_groups2 +
1327 info3->num_other_sids + i],
1328 &lgroupSIDs[i]);
1331 /* Where are the 'global' sids... */
1333 /* can the user be guest? if yes, where is it stored? */
1335 nt_status = create_nt_user_token(&user_sid, &group_sid,
1336 info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs,
1337 all_group_SIDs, False, &token);
1339 if ( !NT_STATUS_IS_OK(nt_status) ) {
1340 DEBUG(4,("create_nt_user_token failed\n"));
1341 SAFE_FREE(lgroupSIDs);
1342 SAFE_FREE(all_group_SIDs);
1343 free_server_info(server_info);
1344 return nt_status;
1347 (*server_info)->ptok = token;
1349 SAFE_FREE(lgroupSIDs);
1350 SAFE_FREE(all_group_SIDs);
1352 /* ensure we are never given NULL session keys */
1354 if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
1355 (*server_info)->user_session_key = data_blob(NULL, 0);
1356 } else {
1357 (*server_info)->user_session_key = data_blob(info3->user_sess_key, sizeof(info3->user_sess_key));
1360 if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
1361 (*server_info)->lm_session_key = data_blob(NULL, 0);
1362 } else {
1363 (*server_info)->lm_session_key = data_blob(info3->lm_sess_key, sizeof(info3->lm_sess_key));
1366 return NT_STATUS_OK;
1369 /***************************************************************************
1370 Free a user_info struct
1371 ***************************************************************************/
1373 void free_user_info(auth_usersupplied_info **user_info)
1375 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1376 if (*user_info != NULL) {
1377 if ((*user_info)->smb_name.str) {
1378 DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
1380 SAFE_FREE((*user_info)->smb_name.str);
1381 SAFE_FREE((*user_info)->internal_username.str);
1382 SAFE_FREE((*user_info)->client_domain.str);
1383 SAFE_FREE((*user_info)->domain.str);
1384 SAFE_FREE((*user_info)->wksta_name.str);
1385 data_blob_free(&(*user_info)->lm_resp);
1386 data_blob_free(&(*user_info)->nt_resp);
1387 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1388 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1389 data_blob_clear_free(&(*user_info)->plaintext_password);
1390 ZERO_STRUCT(**user_info);
1392 SAFE_FREE(*user_info);
1395 /***************************************************************************
1396 Clear out a server_info struct that has been allocated
1397 ***************************************************************************/
1399 void free_server_info(auth_serversupplied_info **server_info)
1401 DEBUG(5,("attempting to free (and zero) a server_info structure\n"));
1402 if (*server_info != NULL) {
1403 pdb_free_sam(&(*server_info)->sam_account);
1405 /* call pam_end here, unless we know we are keeping it */
1406 delete_nt_token( &(*server_info)->ptok );
1407 SAFE_FREE((*server_info)->groups);
1408 SAFE_FREE((*server_info)->unix_name);
1409 data_blob_free(&(*server_info)->lm_session_key);
1410 data_blob_free(&(*server_info)->user_session_key);
1411 ZERO_STRUCT(**server_info);
1413 SAFE_FREE(*server_info);
1416 /***************************************************************************
1417 Make an auth_methods struct
1418 ***************************************************************************/
1420 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method)
1422 if (!auth_context) {
1423 smb_panic("no auth_context supplied to make_auth_methods()!\n");
1426 if (!auth_method) {
1427 smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
1430 *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1431 if (!*auth_method) {
1432 DEBUG(0,("make_auth_method: malloc failed!\n"));
1433 return False;
1435 ZERO_STRUCTP(*auth_method);
1437 return True;
1440 /****************************************************************************
1441 Delete a SID token.
1442 ****************************************************************************/
1444 void delete_nt_token(NT_USER_TOKEN **pptoken)
1446 if (*pptoken) {
1447 NT_USER_TOKEN *ptoken = *pptoken;
1449 SAFE_FREE( ptoken->user_sids );
1450 ZERO_STRUCTP(ptoken);
1452 SAFE_FREE(*pptoken);
1455 /****************************************************************************
1456 Duplicate a SID token.
1457 ****************************************************************************/
1459 NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
1461 NT_USER_TOKEN *token;
1463 if (!ptoken)
1464 return NULL;
1466 if ((token = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL)
1467 return NULL;
1469 ZERO_STRUCTP(token);
1471 token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
1473 if ( !token ) {
1474 SAFE_FREE(token);
1475 return NULL;
1478 token->num_sids = ptoken->num_sids;
1480 /* copy the privileges; don't consider failure to be critical here */
1482 if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
1483 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. Continuing with 0 privileges assigned.\n"));
1486 return token;
1489 /****************************************************************************
1490 Check for a SID in an NT_USER_TOKEN
1491 ****************************************************************************/
1493 BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token )
1495 int i;
1497 if ( !sid || !token )
1498 return False;
1500 for ( i=0; i<token->num_sids; i++ ) {
1501 if ( sid_equal( sid, &token->user_sids[i] ) )
1502 return True;
1505 return False;
1508 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
1510 DOM_SID domain_sid;
1512 /* if we are a domain member, the get the domain SID, else for
1513 a DC or standalone server, use our own SID */
1515 if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
1516 if ( !secrets_fetch_domain_sid( lp_workgroup(), &domain_sid ) ) {
1517 DEBUG(1,("nt_token_check_domain_rid: Cannot lookup SID for domain [%s]\n",
1518 lp_workgroup()));
1519 return False;
1522 else
1523 sid_copy( &domain_sid, get_global_sam_sid() );
1525 sid_append_rid( &domain_sid, rid );
1527 return nt_token_check_sid( &domain_sid, token );\
1531 * Verify whether or not given domain is trusted.
1533 * @param domain_name name of the domain to be verified
1534 * @return true if domain is one of the trusted once or
1535 * false if otherwise
1538 BOOL is_trusted_domain(const char* dom_name)
1540 DOM_SID trustdom_sid;
1541 char *pass = NULL;
1542 time_t lct;
1543 BOOL ret;
1545 /* no trusted domains for a standalone server */
1547 if ( lp_server_role() == ROLE_STANDALONE )
1548 return False;
1550 /* if we are a DC, then check for a direct trust relationships */
1552 if ( IS_DC ) {
1553 become_root();
1554 DEBUG (5,("is_trusted_domain: Checking for domain trust with [%s]\n",
1555 dom_name ));
1556 ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
1557 unbecome_root();
1558 SAFE_FREE(pass);
1559 if (ret)
1560 return True;
1562 else {
1563 /* if winbindd is not up and we are a domain member) then we need to update the
1564 trustdom_cache ourselves */
1566 if ( !winbind_ping() )
1567 update_trustdom_cache();
1570 /* now the trustdom cache should be available a DC could still
1571 * have a transitive trust so fall back to the cache of trusted
1572 * domains (like a domain member would use */
1574 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1575 return True;
1578 return False;