r5739: sync for 3.0.12rc1 (current with SAMBA_3_0 r5738)
[Samba.git] / source / auth / auth_util.c
blob7cab3df99e4bd9452e0aac57e9f1b4160139cd36
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
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)
41 pstring add_script;
42 int ret;
44 pstrcpy(add_script, lp_adduser_script());
45 if (! *add_script)
46 return -1;
47 all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
48 if (domain)
49 all_string_sub(add_script, "%D", domain, sizeof(pstring));
50 if (homedir)
51 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
52 ret = smbrun(add_script,NULL);
53 flush_pwnam_cache();
54 DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
55 return 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);
73 else {
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
78 account allocation */
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
88 unix info.
89 ****************************************************************************/
91 NTSTATUS auth_get_sam_account(const char *user, SAM_ACCOUNT **account)
93 BOOL pdb_ret;
94 NTSTATUS nt_status;
95 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(account))) {
96 return nt_status;
99 become_root();
100 pdb_ret = pdb_getsampwnam(*account, user);
101 unbecome_root();
103 if (!pdb_ret) {
105 struct passwd *pass = Get_Pwnam(user);
106 if (!pass)
107 return NT_STATUS_NO_SUCH_USER;
109 if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*account, pass))) {
110 return nt_status;
113 return NT_STATUS_OK;
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,
124 const char *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,
129 BOOL encrypted)
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);
135 if (!user_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);
147 } else {
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);
155 } else {
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);
163 } else {
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);
171 } else {
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);
179 } else {
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));
186 if (lm_pwd)
187 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
188 if (nt_pwd)
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);
195 if (plaintext)
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));
202 return NT_STATUS_OK;
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,
216 BOOL encrypted)
218 const char *domain;
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;
232 else
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,
245 lm_pwd, nt_pwd,
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)
262 BOOL ret;
263 NTSTATUS nt_status;
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,
269 wksta_name,
270 lm_pwd_len ? &lm_blob : NULL,
271 nt_pwd_len ? &nt_blob : NULL,
272 NULL, NULL, NULL,
273 True);
275 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
277 data_blob_free(&lm_blob);
278 data_blob_free(&nt_blob);
279 return ret;
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,
291 const uchar chal[8],
292 const uchar lm_interactive_pwd[16],
293 const uchar nt_interactive_pwd[16],
294 const uchar *dc_sess_key)
296 char lm_pwd[16];
297 char nt_pwd[16];
298 unsigned char local_lm_response[24];
299 unsigned char local_nt_response[24];
300 unsigned char key[16];
302 ZERO_STRUCT(key);
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
309 DEBUG(100,("key:"));
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));
317 #endif
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));
331 #endif
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 */
340 ZERO_STRUCT(key);
343 BOOL ret;
344 NTSTATUS nt_status;
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));
354 ZERO_STRUCT(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));
360 ZERO_STRUCT(nt_pwd);
363 nt_status = make_user_info_map(user_info,
364 smb_name, client_domain,
365 wksta_name,
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,
370 NULL,
371 True);
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);
378 return ret;
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,
390 const uint8 chal[8],
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);
410 #endif
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
416 case insensitive */
417 local_nt_blob = data_blob(NULL, 0);
419 } else {
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,
425 client_domain,
426 get_remote_machine_name(),
427 local_lm_blob.data ? &local_lm_blob : NULL,
428 local_nt_blob.data ? &local_nt_blob : NULL,
429 NULL, NULL,
430 plaintext_password.data ? &plaintext_password : NULL,
431 False);
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,
447 client_domain,
448 get_remote_machine_name(),
449 lm_resp.data ? &lm_resp : NULL,
450 nt_resp.data ? &nt_resp : NULL,
451 NULL, NULL, NULL,
452 True);
455 /****************************************************************************
456 Create a guest user_info blob, for anonymous authenticaion.
457 ****************************************************************************/
459 BOOL make_user_info_guest(auth_usersupplied_info **user_info)
461 NTSTATUS nt_status;
463 nt_status = make_user_info(user_info,
464 "","",
465 "","",
466 "",
467 NULL, NULL,
468 NULL, NULL,
469 NULL,
470 True);
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)
481 fstring sid_str;
482 size_t i;
484 if (!token) {
485 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
486 return;
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)
505 int i;
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;
524 int i;
525 int sid_ndx;
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;
530 return nt_status;
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;
540 return nt_status;
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);
553 if (group_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);
565 if (is_guest)
566 sid_copy(&ptoken->user_sids[4], &global_sid_Builtin_Guests);
567 else
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],
576 &groupSIDs[i])) {
577 break;
581 if (check_sid_idx >= ptoken->num_sids) /* Not found already */ {
582 sid_copy(&ptoken->user_sids[sid_ndx++], &groupSIDs[i]);
583 } else {
584 ptoken->num_sids--;
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)) {
596 TALLOC_CTX *mem_ctx;
597 char *command;
598 fstring sidstr;
599 char *user_sidstr, *group_sidstr;
601 mem_ctx = talloc_init("setnttoken");
602 if (mem_ctx == NULL)
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);
624 SAFE_FREE(command);
627 *token = ptoken;
629 return nt_status;
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)
638 DOM_SID user_sid;
639 DOM_SID group_sid;
640 DOM_SID *group_sids;
641 NT_USER_TOKEN *token;
642 int i;
644 if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, uid))) {
645 return NULL;
647 if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, gid))) {
648 return NULL;
651 group_sids = SMB_MALLOC_ARRAY(DOM_SID, ngroups);
652 if (!group_sids) {
653 DEBUG(0, ("create_nt_token: malloc() failed for DOM_SID list!\n"));
654 return NULL;
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);
661 return NULL;
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);
668 return NULL;
671 SAFE_FREE(group_sids);
673 return token;
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
684 * of groups.
686 * NOTE!! This function will fail if you pass in a winbind user without
687 * the domain --jerry
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)
693 int n_unix_groups;
694 int i;
696 *n_groups = 0;
697 *groups = NULL;
699 if (strchr(username, *lp_winbind_separator()) == NULL) {
700 NTSTATUS result;
702 become_root();
703 result = pdb_enum_group_memberships(username, gid, groups,
704 unix_groups, n_groups);
705 unbecome_root();
706 return result;
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
718 * value be? */
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);
728 if (!*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]));
741 SAFE_FREE(*groups);
742 SAFE_FREE(*unix_groups);
743 return NT_STATUS_NO_SUCH_USER;
747 return NT_STATUS_OK;
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);
757 if (!*server_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;
770 return NT_STATUS_OK;
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)
782 NTSTATUS nt_status;
783 const DOM_SID *user_sid = pdb_get_user_sid(sampass);
784 const DOM_SID *group_sid = pdb_get_group_sid(sampass);
785 int n_groupSIDs = 0;
786 DOM_SID *groupSIDs = NULL;
787 gid_t *unix_groups = NULL;
788 NT_USER_TOKEN *token;
789 BOOL is_guest;
790 uint32 rid;
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);
798 return nt_status;
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,
805 &token)))
807 DEBUG(4,("create_nt_user_token failed\n"));
808 SAFE_FREE(groupSIDs);
809 SAFE_FREE(unix_groups);
810 free_server_info(server_info);
811 return nt_status;
814 SAFE_FREE(groupSIDs);
816 (*server_info)->n_groups = n_groupSIDs;
817 (*server_info)->groups = unix_groups;
818 (*server_info)->ptok = token;
820 return nt_status;
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)
830 NTSTATUS nt_status;
831 struct passwd *pwd;
833 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info)))
834 return nt_status;
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;
848 passwd_free(&pwd);
850 if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, pdb_get_username(sampass),
851 sampass,
852 (*server_info)->uid,
853 (*server_info)->gid)))
855 free_server_info(server_info);
856 return nt_status;
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));
864 return nt_status;
867 /***************************************************************************
868 Make (and fill) a user_info struct from a 'struct passwd' by conversion
869 to a SAM_ACCOUNT
870 ***************************************************************************/
872 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
873 char *unix_username,
874 struct passwd *pwd)
876 NTSTATUS nt_status;
877 SAM_ACCOUNT *sampass = NULL;
878 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {
879 return nt_status;
881 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
882 return nt_status;
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)))
890 return nt_status;
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;
898 return nt_status;
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)
907 NTSTATUS nt_status;
908 SAM_ACCOUNT *sampass = NULL;
909 DOM_SID guest_sid;
911 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) {
912 return nt_status;
915 sid_copy(&guest_sid, get_global_sam_sid());
916 sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
918 become_root();
919 if (!pdb_getsampwsid(sampass, &guest_sid)) {
920 unbecome_root();
921 return NT_STATUS_NO_SUCH_USER;
923 unbecome_root();
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));
937 return nt_status;
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)))
945 return NULL;
947 dst->guest = src->guest;
948 dst->uid = src->uid;
949 dst->gid = src->gid;
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);
953 else
954 dst->groups = NULL;
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);
964 return dst;
967 static auth_serversupplied_info *guest_info = NULL;
969 BOOL init_guest_info(void)
971 if (guest_info != NULL)
972 return True;
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,
988 const char *domain,
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(),
1002 lower_username);
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?
1021 --jerry */
1023 *found_username = talloc_strdup( mem_ctx, real_username );
1025 DEBUG(5,("fill_sam_account: located username was [%s]\n",
1026 *found_username));
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;
1040 char *p;
1041 fstring username;
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 */
1057 if ( p ) {
1058 fstring strip_username;
1060 pw = Get_Pwnam( domuser );
1061 if ( pw ) {
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() ) ) {
1066 char *domain;
1068 /* split the domain and username into 2 strings */
1069 *p = '\0';
1070 domain = username;
1072 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1074 else
1075 fstrcpy( save_username, pw->pw_name );
1077 /* whew -- done! */
1078 return pw;
1081 /* setup for lookup of just the username */
1082 /* remember that p and username are overlapping memory */
1084 p++;
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] == '$')
1098 return NULL;
1100 auth_add_user_script(NULL, username);
1101 pw = Get_Pwnam(username);
1104 /* one last check for a valid passwd struct */
1106 if ( pw )
1107 fstrcpy( save_username, pw->pw_name );
1109 return pw;
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,
1119 const char *domain,
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;
1131 DOM_SID user_sid;
1132 DOM_SID group_sid;
1134 uid_t uid;
1135 gid_t gid;
1137 int n_lgroupSIDs;
1138 DOM_SID *lgroupSIDs = NULL;
1140 gid_t *unix_groups = NULL;
1141 NT_USER_TOKEN *token;
1143 DOM_SID *all_group_SIDs;
1144 size_t i;
1147 Here is where we should check the list of
1148 trusted domains, and verify that the SID
1149 matches.
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 */
1169 nt_domain = domain;
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
1182 place. -- jerry */
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"));
1196 return nt_status;
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)),
1225 PDB_CHANGED)) {
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);
1253 return nt_status;
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"));
1277 return nt_status;
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);
1311 return nt_status;
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],
1333 &lgroupSIDs[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);
1349 return nt_status;
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);
1361 } else {
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);
1367 } else {
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");
1431 if (!auth_method) {
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"));
1438 return False;
1440 ZERO_STRUCTP(*auth_method);
1442 return True;
1445 /****************************************************************************
1446 Delete a SID token.
1447 ****************************************************************************/
1449 void delete_nt_token(NT_USER_TOKEN **pptoken)
1451 if (*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;
1468 if (!ptoken)
1469 return NULL;
1471 if ((token = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL)
1472 return NULL;
1474 ZERO_STRUCTP(token);
1476 token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
1478 if ( !token ) {
1479 SAFE_FREE(token);
1480 return NULL;
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"));
1491 return token;
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 )
1500 int i;
1502 if ( !sid || !token )
1503 return False;
1505 for ( i=0; i<token->num_sids; i++ ) {
1506 if ( sid_equal( sid, &token->user_sids[i] ) )
1507 return True;
1510 return False;
1513 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
1515 DOM_SID domain_sid;
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",
1523 lp_workgroup()));
1524 return False;
1527 else
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;
1546 char *pass = NULL;
1547 time_t lct;
1548 BOOL ret;
1550 /* no trusted domains for a standalone server */
1552 if ( lp_server_role() == ROLE_STANDALONE )
1553 return False;
1555 /* if we are a DC, then check for a direct trust relationships */
1557 if ( IS_DC ) {
1558 become_root();
1559 DEBUG (5,("is_trusted_domain: Checking for domain trust with [%s]\n",
1560 dom_name ));
1561 ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
1562 unbecome_root();
1563 SAFE_FREE(pass);
1564 if (ret)
1565 return True;
1567 else {
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) ) {
1580 return True;
1583 return False;