2 Unix SMB/CIFS implementation.
3 Authentication utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001
6 Copyright (C) Jeremy Allison 2000-2001
7 Copyright (C) Rafal Szczesniak 2002
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #define DBGC_CLASS DBGC_AUTH
29 extern DOM_SID global_sid_World;
30 extern DOM_SID global_sid_Network;
31 extern DOM_SID global_sid_Builtin_Guests;
32 extern DOM_SID global_sid_Authenticated_Users;
35 /****************************************************************************
36 Create a UNIX user on demand.
37 ****************************************************************************/
39 static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
44 pstrcpy(add_script, lp_adduser_script());
47 all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
49 all_string_sub(add_script, "%D", domain, sizeof(pstring));
51 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
52 ret = smbrun(add_script,NULL);
53 DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
57 /****************************************************************************
58 Add and Delete UNIX users on demand, based on NTSTATUS codes.
59 We don't care about RID's here so ignore.
60 ****************************************************************************/
62 void auth_add_user_script(const char *domain, const char *username)
65 * User validated ok against Domain controller.
66 * If the admin wants us to try and create a UNIX
67 * user on the fly, do so.
70 if ( *lp_adduser_script() )
71 smb_create_user(domain, username, NULL);
73 DEBUG(10,("auth_add_user_script: no 'add user script'. Asking winbindd\n"));
75 /* should never get here is we a re a domain member running winbindd
76 However, a host set for 'security = server' might run winbindd for
79 if ( !winbind_create_user(username, NULL) ) {
80 DEBUG(5,("auth_add_user_script: winbindd_create_user() failed\n"));
85 /****************************************************************************
86 Create a SAM_ACCOUNT - either by looking in the pdb, or by faking it up from
88 ****************************************************************************/
90 NTSTATUS auth_get_sam_account(const char *user, SAM_ACCOUNT **account)
94 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(account))) {
99 pdb_ret = pdb_getsampwnam(*account, user);
104 struct passwd *pass = Get_Pwnam(user);
106 return NT_STATUS_NO_SUCH_USER;
108 if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*account, pass))) {
115 /****************************************************************************
116 Create an auth_usersupplied_data structure
117 ****************************************************************************/
119 static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
120 const char *smb_name,
121 const char *internal_username,
122 const char *client_domain,
124 const char *wksta_name,
125 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
126 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
127 DATA_BLOB *plaintext,
131 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
133 *user_info = SMB_MALLOC_P(auth_usersupplied_info);
135 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
136 return NT_STATUS_NO_MEMORY;
139 ZERO_STRUCTP(*user_info);
141 DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
143 (*user_info)->smb_name.str = SMB_STRDUP(smb_name);
144 if ((*user_info)->smb_name.str) {
145 (*user_info)->smb_name.len = strlen(smb_name);
147 free_user_info(user_info);
148 return NT_STATUS_NO_MEMORY;
151 (*user_info)->internal_username.str = SMB_STRDUP(internal_username);
152 if ((*user_info)->internal_username.str) {
153 (*user_info)->internal_username.len = strlen(internal_username);
155 free_user_info(user_info);
156 return NT_STATUS_NO_MEMORY;
159 (*user_info)->domain.str = SMB_STRDUP(domain);
160 if ((*user_info)->domain.str) {
161 (*user_info)->domain.len = strlen(domain);
163 free_user_info(user_info);
164 return NT_STATUS_NO_MEMORY;
167 (*user_info)->client_domain.str = SMB_STRDUP(client_domain);
168 if ((*user_info)->client_domain.str) {
169 (*user_info)->client_domain.len = strlen(client_domain);
171 free_user_info(user_info);
172 return NT_STATUS_NO_MEMORY;
175 (*user_info)->wksta_name.str = SMB_STRDUP(wksta_name);
176 if ((*user_info)->wksta_name.str) {
177 (*user_info)->wksta_name.len = strlen(wksta_name);
179 free_user_info(user_info);
180 return NT_STATUS_NO_MEMORY;
183 DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
186 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
188 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
189 if (lm_interactive_pwd)
190 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
191 if (nt_interactive_pwd)
192 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
195 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
197 (*user_info)->encrypted = encrypted;
199 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
204 /****************************************************************************
205 Create an auth_usersupplied_data structure after appropriate mapping.
206 ****************************************************************************/
208 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
209 const char *smb_name,
210 const char *client_domain,
211 const char *wksta_name,
212 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
213 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
214 DATA_BLOB *plaintext,
218 fstring internal_username;
219 fstrcpy(internal_username, smb_name);
220 map_username(internal_username);
222 DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
223 client_domain, smb_name, wksta_name));
225 /* don't allow "" as a domain, fixes a Win9X bug
226 where it doens't supply a domain for logon script
227 'net use' commands. */
229 if ( *client_domain )
230 domain = client_domain;
232 domain = lp_workgroup();
234 /* do what win2k does. Always map unknown domains to our own
235 and let the "passdb backend" handle unknown users. */
237 if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) )
238 domain = get_default_sam_name();
240 /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
242 return make_user_info(user_info, smb_name, internal_username,
243 client_domain, domain, wksta_name,
245 lm_interactive_pwd, nt_interactive_pwd,
246 plaintext, encrypted);
249 /****************************************************************************
250 Create an auth_usersupplied_data, making the DATA_BLOBs here.
251 Decrypt and encrypt the passwords.
252 ****************************************************************************/
254 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
255 const char *smb_name,
256 const char *client_domain,
257 const char *wksta_name,
258 const uchar *lm_network_pwd, int lm_pwd_len,
259 const uchar *nt_network_pwd, int nt_pwd_len)
263 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
264 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
266 nt_status = make_user_info_map(user_info,
267 smb_name, client_domain,
269 lm_pwd_len ? &lm_blob : NULL,
270 nt_pwd_len ? &nt_blob : NULL,
274 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
276 data_blob_free(&lm_blob);
277 data_blob_free(&nt_blob);
281 /****************************************************************************
282 Create an auth_usersupplied_data, making the DATA_BLOBs here.
283 Decrypt and encrypt the passwords.
284 ****************************************************************************/
286 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
287 const char *smb_name,
288 const char *client_domain,
289 const char *wksta_name,
291 const uchar lm_interactive_pwd[16],
292 const uchar nt_interactive_pwd[16],
293 const uchar *dc_sess_key)
297 unsigned char local_lm_response[24];
298 unsigned char local_nt_response[24];
299 unsigned char key[16];
302 memcpy(key, dc_sess_key, 8);
304 if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
305 if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
307 #ifdef DEBUG_PASSWORD
309 dump_data(100, (char *)key, sizeof(key));
311 DEBUG(100,("lm owf password:"));
312 dump_data(100, lm_pwd, sizeof(lm_pwd));
314 DEBUG(100,("nt owf password:"));
315 dump_data(100, nt_pwd, sizeof(nt_pwd));
318 if (lm_interactive_pwd)
319 SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
321 if (nt_interactive_pwd)
322 SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
324 #ifdef DEBUG_PASSWORD
325 DEBUG(100,("decrypt of lm owf password:"));
326 dump_data(100, lm_pwd, sizeof(lm_pwd));
328 DEBUG(100,("decrypt of nt owf password:"));
329 dump_data(100, nt_pwd, sizeof(nt_pwd));
332 if (lm_interactive_pwd)
333 SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
335 if (nt_interactive_pwd)
336 SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
338 /* Password info paranoia */
344 DATA_BLOB local_lm_blob;
345 DATA_BLOB local_nt_blob;
347 DATA_BLOB lm_interactive_blob;
348 DATA_BLOB nt_interactive_blob;
350 if (lm_interactive_pwd) {
351 local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
352 lm_interactive_blob = data_blob(lm_pwd, sizeof(lm_pwd));
356 if (nt_interactive_pwd) {
357 local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
358 nt_interactive_blob = data_blob(nt_pwd, sizeof(nt_pwd));
362 nt_status = make_user_info_map(user_info,
363 smb_name, client_domain,
365 lm_interactive_pwd ? &local_lm_blob : NULL,
366 nt_interactive_pwd ? &local_nt_blob : NULL,
367 lm_interactive_pwd ? &lm_interactive_blob : NULL,
368 nt_interactive_pwd ? &nt_interactive_blob : NULL,
372 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
373 data_blob_free(&local_lm_blob);
374 data_blob_free(&local_nt_blob);
375 data_blob_free(&lm_interactive_blob);
376 data_blob_free(&nt_interactive_blob);
382 /****************************************************************************
383 Create an auth_usersupplied_data structure
384 ****************************************************************************/
386 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
387 const char *smb_name,
388 const char *client_domain,
390 DATA_BLOB plaintext_password)
393 DATA_BLOB local_lm_blob;
394 DATA_BLOB local_nt_blob;
395 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
398 * Not encrypted - do so.
401 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
403 if (plaintext_password.data) {
404 unsigned char local_lm_response[24];
406 #ifdef DEBUG_PASSWORD
407 DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
408 dump_data(100, plaintext_password.data, plaintext_password.length);
411 SMBencrypt( (const char *)plaintext_password.data, (const uchar*)chal, local_lm_response);
412 local_lm_blob = data_blob(local_lm_response, 24);
414 /* We can't do an NT hash here, as the password needs to be
416 local_nt_blob = data_blob(NULL, 0);
419 local_lm_blob = data_blob(NULL, 0);
420 local_nt_blob = data_blob(NULL, 0);
423 ret = make_user_info_map(user_info, smb_name,
425 get_remote_machine_name(),
426 local_lm_blob.data ? &local_lm_blob : NULL,
427 local_nt_blob.data ? &local_nt_blob : NULL,
429 plaintext_password.data ? &plaintext_password : NULL,
432 data_blob_free(&local_lm_blob);
433 return NT_STATUS_IS_OK(ret) ? True : False;
436 /****************************************************************************
437 Create an auth_usersupplied_data structure
438 ****************************************************************************/
440 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
441 const char *smb_name,
442 const char *client_domain,
443 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
445 return make_user_info_map(user_info, smb_name,
447 get_remote_machine_name(),
448 lm_resp.data ? &lm_resp : NULL,
449 nt_resp.data ? &nt_resp : NULL,
454 /****************************************************************************
455 Create a guest user_info blob, for anonymous authenticaion.
456 ****************************************************************************/
458 BOOL make_user_info_guest(auth_usersupplied_info **user_info)
462 nt_status = make_user_info(user_info,
471 return NT_STATUS_IS_OK(nt_status) ? True : False;
474 /****************************************************************************
475 prints a NT_USER_TOKEN to debug output.
476 ****************************************************************************/
478 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
484 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
488 DEBUGC(dbg_class, dbg_lev, ("NT user token of user %s\n",
489 sid_to_string(sid_str, &token->user_sids[0]) ));
490 DEBUGADDC(dbg_class, dbg_lev, ("contains %lu SIDs\n", (unsigned long)token->num_sids));
491 for (i = 0; i < token->num_sids; i++)
492 DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i,
493 sid_to_string(sid_str, &token->user_sids[i])));
495 dump_se_priv( dbg_class, dbg_lev, &token->privileges );
498 /****************************************************************************
499 prints a UNIX 'token' to debug output.
500 ****************************************************************************/
502 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid, int n_groups, gid_t *groups)
505 DEBUGC(dbg_class, dbg_lev, ("UNIX token of user %ld\n", (long int)uid));
507 DEBUGADDC(dbg_class, dbg_lev, ("Primary group is %ld and contains %i supplementary groups\n", (long int)gid, n_groups));
508 for (i = 0; i < n_groups; i++)
509 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i,
510 (long int)groups[i]));
513 /****************************************************************************
514 Create the SID list for this user.
515 ****************************************************************************/
517 static NTSTATUS create_nt_user_token(const DOM_SID *user_sid, const DOM_SID *group_sid,
518 int n_groupSIDs, DOM_SID *groupSIDs,
519 BOOL is_guest, NT_USER_TOKEN **token)
521 NTSTATUS nt_status = NT_STATUS_OK;
522 NT_USER_TOKEN *ptoken;
526 if ((ptoken = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL) {
527 DEBUG(0, ("create_nt_token: Out of memory allocating token\n"));
528 nt_status = NT_STATUS_NO_MEMORY;
532 ZERO_STRUCTP(ptoken);
534 ptoken->num_sids = n_groupSIDs + 5;
536 if ((ptoken->user_sids = SMB_MALLOC_ARRAY( DOM_SID, ptoken->num_sids )) == NULL) {
537 DEBUG(0, ("create_nt_token: Out of memory allocating SIDs\n"));
538 nt_status = NT_STATUS_NO_MEMORY;
542 memset((char*)ptoken->user_sids,0,sizeof(DOM_SID) * ptoken->num_sids);
545 * Note - user SID *MUST* be first in token !
546 * se_access_check depends on this.
548 * Primary group SID is second in token. Convention.
551 sid_copy(&ptoken->user_sids[PRIMARY_USER_SID_INDEX], user_sid);
553 sid_copy(&ptoken->user_sids[PRIMARY_GROUP_SID_INDEX], group_sid);
556 * Finally add the "standard" SIDs.
557 * The only difference between guest and "anonymous" (which we
558 * don't really support) is the addition of Authenticated_Users.
561 sid_copy(&ptoken->user_sids[2], &global_sid_World);
562 sid_copy(&ptoken->user_sids[3], &global_sid_Network);
565 sid_copy(&ptoken->user_sids[4], &global_sid_Builtin_Guests);
567 sid_copy(&ptoken->user_sids[4], &global_sid_Authenticated_Users);
569 sid_ndx = 5; /* next available spot */
571 for (i = 0; i < n_groupSIDs; i++) {
572 size_t check_sid_idx;
573 for (check_sid_idx = 1; check_sid_idx < ptoken->num_sids; check_sid_idx++) {
574 if (sid_equal(&ptoken->user_sids[check_sid_idx],
580 if (check_sid_idx >= ptoken->num_sids) /* Not found already */ {
581 sid_copy(&ptoken->user_sids[sid_ndx++], &groupSIDs[i]);
587 /* add privileges assigned to this user */
589 get_privileges_for_sids( &ptoken->privileges, ptoken->user_sids, ptoken->num_sids );
591 debug_nt_user_token(DBGC_AUTH, 10, ptoken);
593 if ((lp_log_nt_token_command() != NULL) &&
594 (strlen(lp_log_nt_token_command()) > 0)) {
598 char *user_sidstr, *group_sidstr;
600 mem_ctx = talloc_init("setnttoken");
602 return NT_STATUS_NO_MEMORY;
604 sid_to_string(sidstr, &ptoken->user_sids[0]);
605 user_sidstr = talloc_strdup(mem_ctx, sidstr);
607 group_sidstr = talloc_strdup(mem_ctx, "");
608 for (i=1; i<ptoken->num_sids; i++) {
609 sid_to_string(sidstr, &ptoken->user_sids[i]);
610 group_sidstr = talloc_asprintf(mem_ctx, "%s %s",
611 group_sidstr, sidstr);
614 command = strdup(lp_log_nt_token_command());
615 command = realloc_string_sub(command, "%s", user_sidstr);
616 command = realloc_string_sub(command, "%t", group_sidstr);
617 DEBUG(8, ("running command: [%s]\n", command));
618 if (smbrun(command, NULL) != 0) {
619 DEBUG(0, ("Could not log NT token\n"));
620 nt_status = NT_STATUS_ACCESS_DENIED;
622 talloc_destroy(mem_ctx);
631 /****************************************************************************
632 Create the SID list for this user.
633 ****************************************************************************/
635 NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest)
640 NT_USER_TOKEN *token;
643 if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, uid))) {
646 if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, gid))) {
650 group_sids = SMB_MALLOC_ARRAY(DOM_SID, ngroups);
652 DEBUG(0, ("create_nt_token: malloc() failed for DOM_SID list!\n"));
656 for (i = 0; i < ngroups; i++) {
657 if (!NT_STATUS_IS_OK(gid_to_sid(&(group_sids)[i], (groups)[i]))) {
658 DEBUG(1, ("create_nt_token: failed to convert gid %ld to a sid!\n", (long int)groups[i]));
659 SAFE_FREE(group_sids);
664 if (!NT_STATUS_IS_OK(create_nt_user_token(&user_sid, &group_sid,
665 ngroups, group_sids, is_guest, &token))) {
666 SAFE_FREE(group_sids);
670 SAFE_FREE(group_sids);
675 /******************************************************************************
676 * this function returns the groups (SIDs) of the local SAM the user is in.
677 * If this samba server is a DC of the domain the user belongs to, it returns
678 * both domain groups and local / builtin groups. If the user is in a trusted
679 * domain, or samba is a member server of a domain, then this function returns
680 * local and builtin groups the user is a member of.
682 * currently this is a hack, as there is no sam implementation that is capable
685 * NOTE!! This function will fail if you pass in a winbind user without
687 ******************************************************************************/
689 static NTSTATUS get_user_groups(const char *username, uid_t uid, gid_t gid,
690 int *n_groups, DOM_SID **groups, gid_t **unix_groups)
698 if (strchr(username, *lp_winbind_separator()) == NULL) {
702 result = pdb_enum_group_memberships(username, gid, groups,
703 unix_groups, n_groups);
708 /* We have the separator, this must be winbind */
710 n_unix_groups = winbind_getgroups( username, unix_groups );
712 DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n",
713 username, n_unix_groups == -1 ? "FAIL" : "SUCCESS"));
715 if ( n_unix_groups == -1 )
716 return NT_STATUS_NO_SUCH_USER; /* what should this return
719 debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups);
721 /* now setup the space for storing the SIDS */
723 if (n_unix_groups > 0) {
725 *groups = SMB_MALLOC_ARRAY(DOM_SID, n_unix_groups);
728 DEBUG(0, ("get_user_group: malloc() failed for DOM_SID list!\n"));
729 SAFE_FREE(*unix_groups);
730 return NT_STATUS_NO_MEMORY;
734 *n_groups = n_unix_groups;
736 for (i = 0; i < *n_groups; i++) {
737 if (!NT_STATUS_IS_OK(gid_to_sid(&(*groups)[i], (*unix_groups)[i]))) {
738 DEBUG(1, ("get_user_groups: failed to convert gid %ld to a sid!\n",
739 (long int)(*unix_groups)[i+1]));
741 SAFE_FREE(*unix_groups);
742 return NT_STATUS_NO_SUCH_USER;
749 /***************************************************************************
750 Make a user_info struct
751 ***************************************************************************/
753 static NTSTATUS make_server_info(auth_serversupplied_info **server_info)
755 *server_info = SMB_MALLOC_P(auth_serversupplied_info);
757 DEBUG(0,("make_server_info: malloc failed!\n"));
758 return NT_STATUS_NO_MEMORY;
760 ZERO_STRUCTP(*server_info);
762 /* Initialise the uid and gid values to something non-zero
763 which may save us from giving away root access if there
764 is a bug in allocating these fields. */
766 (*server_info)->uid = -1;
767 (*server_info)->gid = -1;
772 /***************************************************************************
773 Fill a server_info struct from a SAM_ACCOUNT with their groups
774 ***************************************************************************/
776 static NTSTATUS add_user_groups(auth_serversupplied_info **server_info,
777 const char * unix_username,
778 SAM_ACCOUNT *sampass,
779 uid_t uid, gid_t gid)
782 const DOM_SID *user_sid = pdb_get_user_sid(sampass);
783 const DOM_SID *group_sid = pdb_get_group_sid(sampass);
785 DOM_SID *groupSIDs = NULL;
786 gid_t *unix_groups = NULL;
787 NT_USER_TOKEN *token;
791 nt_status = get_user_groups(unix_username, uid, gid,
792 &n_groupSIDs, &groupSIDs, &unix_groups);
794 if (!NT_STATUS_IS_OK(nt_status)) {
795 DEBUG(4,("get_user_groups_from_local_sam failed\n"));
796 free_server_info(server_info);
800 is_guest = (sid_peek_rid(user_sid, &rid) && rid == DOMAIN_USER_RID_GUEST);
802 if (!NT_STATUS_IS_OK(nt_status = create_nt_user_token(user_sid, group_sid,
803 n_groupSIDs, groupSIDs, is_guest,
806 DEBUG(4,("create_nt_user_token failed\n"));
807 SAFE_FREE(groupSIDs);
808 SAFE_FREE(unix_groups);
809 free_server_info(server_info);
813 SAFE_FREE(groupSIDs);
815 (*server_info)->n_groups = n_groupSIDs;
816 (*server_info)->groups = unix_groups;
817 (*server_info)->ptok = token;
822 /***************************************************************************
823 Make (and fill) a user_info struct from a SAM_ACCOUNT
824 ***************************************************************************/
826 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
827 SAM_ACCOUNT *sampass)
832 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info)))
835 (*server_info)->sam_account = sampass;
837 if ( !(pwd = getpwnam_alloc(pdb_get_username(sampass))) ) {
838 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
839 pdb_get_username(sampass)));
840 free_server_info(server_info);
841 return NT_STATUS_NO_SUCH_USER;
843 (*server_info)->unix_name = smb_xstrdup(pwd->pw_name);
844 (*server_info)->gid = pwd->pw_gid;
845 (*server_info)->uid = pwd->pw_uid;
849 if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, pdb_get_username(sampass),
852 (*server_info)->gid)))
854 free_server_info(server_info);
858 (*server_info)->sam_fill_level = SAM_FILL_ALL;
859 DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
860 pdb_get_username(sampass),
861 (*server_info)->unix_name));
866 /***************************************************************************
867 Make (and fill) a user_info struct from a 'struct passwd' by conversion
869 ***************************************************************************/
871 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
876 SAM_ACCOUNT *sampass = NULL;
877 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {
880 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
884 (*server_info)->sam_account = sampass;
886 if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username,
887 sampass, pwd->pw_uid, pwd->pw_gid)))
892 (*server_info)->unix_name = smb_xstrdup(unix_username);
894 (*server_info)->sam_fill_level = SAM_FILL_ALL;
895 (*server_info)->uid = pwd->pw_uid;
896 (*server_info)->gid = pwd->pw_gid;
900 /***************************************************************************
901 Make (and fill) a user_info struct for a guest login.
902 ***************************************************************************/
904 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
907 SAM_ACCOUNT *sampass = NULL;
910 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) {
914 sid_copy(&guest_sid, get_global_sam_sid());
915 sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
918 if (!pdb_getsampwsid(sampass, &guest_sid)) {
920 return NT_STATUS_NO_SUCH_USER;
924 nt_status = make_server_info_sam(server_info, sampass);
926 if (NT_STATUS_IS_OK(nt_status)) {
927 static const char zeros[16];
928 (*server_info)->guest = True;
930 /* annoying, but the Guest really does have a session key,
931 and it is all zeros! */
932 (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
933 (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
939 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
941 auth_serversupplied_info *dst;
943 if (!NT_STATUS_IS_OK(make_server_info(&dst)))
946 dst->guest = src->guest;
949 dst->n_groups = src->n_groups;
950 if (src->n_groups != 0)
951 dst->groups = memdup(src->groups, sizeof(gid_t)*dst->n_groups);
954 dst->ptok = dup_nt_token(src->ptok);
955 dst->user_session_key = data_blob(src->user_session_key.data,
956 src->user_session_key.length);
957 dst->lm_session_key = data_blob(src->lm_session_key.data,
958 src->lm_session_key.length);
959 pdb_copy_sam_account(src->sam_account, &dst->sam_account);
960 dst->pam_handle = NULL;
961 dst->unix_name = smb_xstrdup(src->unix_name);
966 static auth_serversupplied_info *guest_info = NULL;
968 BOOL init_guest_info(void)
970 if (guest_info != NULL)
973 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
976 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
978 *server_info = copy_serverinfo(guest_info);
979 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
982 /***************************************************************************
983 Purely internal function for make_server_info_info3
984 Fill the sam account from getpwnam
985 ***************************************************************************/
986 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
988 const char *username,
989 char **found_username,
990 uid_t *uid, gid_t *gid,
991 SAM_ACCOUNT **sam_account)
993 fstring dom_user, lower_username;
994 fstring real_username;
995 struct passwd *passwd;
997 fstrcpy( lower_username, username );
998 strlower_m( lower_username );
1000 fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(),
1003 /* get the passwd struct but don't create the user if he/she
1004 does not exist. We were explicitly called from a following
1005 a winbindd authentication request so we should assume that
1006 nss_winbindd is working */
1008 map_username( dom_user );
1010 if ( !(passwd = smb_getpwnam( dom_user, real_username, True )) )
1011 return NT_STATUS_NO_SUCH_USER;
1013 *uid = passwd->pw_uid;
1014 *gid = passwd->pw_gid;
1016 /* This is pointless -- there is no suport for differing
1017 unix and windows names. Make sure to always store the
1018 one we actually looked up and succeeded. Have I mentioned
1019 why I hate the 'winbind use default domain' parameter?
1022 *found_username = talloc_strdup( mem_ctx, real_username );
1024 DEBUG(5,("fill_sam_account: located username was [%s]\n",
1027 return pdb_init_sam_pw(sam_account, passwd);
1030 /****************************************************************************
1031 Wrapper to allow the getpwnam() call to strip the domain name and
1032 try again in case a local UNIX user is already there. Also run through
1033 the username if we fallback to the username only.
1034 ****************************************************************************/
1036 struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create )
1038 struct passwd *pw = NULL;
1042 /* we only save a copy of the username it has been mangled
1043 by winbindd use default domain */
1045 save_username[0] = '\0';
1047 /* don't call map_username() here since it has to be done higher
1048 up the stack so we don't call it mutliple times */
1050 fstrcpy( username, domuser );
1052 p = strchr_m( username, *lp_winbind_separator() );
1054 /* code for a DOMAIN\user string */
1057 fstring strip_username;
1059 pw = Get_Pwnam( domuser );
1061 /* make sure we get the case of the username correct */
1062 /* work around 'winbind use default domain = yes' */
1064 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1067 /* split the domain and username into 2 strings */
1071 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1074 fstrcpy( save_username, pw->pw_name );
1080 /* setup for lookup of just the username */
1081 /* remember that p and username are overlapping memory */
1084 fstrcpy( strip_username, p );
1085 fstrcpy( username, strip_username );
1088 /* just lookup a plain username */
1090 pw = Get_Pwnam(username);
1092 /* Create local user if requested. */
1094 if ( !pw && create ) {
1095 /* Don't add a machine account. */
1096 if (username[strlen(username)-1] == '$')
1099 auth_add_user_script(NULL, username);
1100 pw = Get_Pwnam(username);
1103 /* one last check for a valid passwd struct */
1106 fstrcpy( save_username, pw->pw_name );
1111 /***************************************************************************
1112 Make a server_info struct from the info3 returned by a domain logon
1113 ***************************************************************************/
1115 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1116 const char *internal_username,
1117 const char *sent_nt_username,
1119 auth_serversupplied_info **server_info,
1120 NET_USER_INFO_3 *info3)
1122 static const char zeros[16];
1124 NTSTATUS nt_status = NT_STATUS_OK;
1125 char *found_username;
1126 const char *nt_domain;
1127 const char *nt_username;
1129 SAM_ACCOUNT *sam_account = NULL;
1137 DOM_SID *lgroupSIDs = NULL;
1139 gid_t *unix_groups = NULL;
1140 NT_USER_TOKEN *token;
1142 DOM_SID *all_group_SIDs;
1146 Here is where we should check the list of
1147 trusted domains, and verify that the SID
1151 sid_copy(&user_sid, &info3->dom_sid.sid);
1152 if (!sid_append_rid(&user_sid, info3->user_rid)) {
1153 return NT_STATUS_INVALID_PARAMETER;
1156 sid_copy(&group_sid, &info3->dom_sid.sid);
1157 if (!sid_append_rid(&group_sid, info3->group_rid)) {
1158 return NT_STATUS_INVALID_PARAMETER;
1161 if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1162 /* If the server didn't give us one, just use the one we sent them */
1163 nt_username = sent_nt_username;
1166 if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1167 /* If the server didn't give us one, just use the one we sent them */
1171 /* try to fill the SAM account.. If getpwnam() fails, then try the
1172 add user script (2.2.x behavior).
1174 We use the _unmapped_ username here in an attempt to provide
1175 consistent username mapping behavior between kerberos and NTLM[SSP]
1176 authentication in domain mode security. I.E. Username mapping should
1177 be applied to the fully qualified username (e.g. DOMAIN\user) and
1178 no just the login name. Yes this mean swe called map_username()
1179 unnecessarily in make_user_info_map() but that is how the current
1180 code is designed. Making the change here is the least disruptive
1183 nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1184 &found_username, &uid, &gid, &sam_account);
1186 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
1187 DEBUG(3,("User %s does not exist, trying to add it\n", internal_username));
1188 auth_add_user_script( nt_domain, sent_nt_username );
1189 nt_status = fill_sam_account( mem_ctx, nt_domain, sent_nt_username,
1190 &found_username, &uid, &gid, &sam_account );
1193 if (!NT_STATUS_IS_OK(nt_status)) {
1194 DEBUG(0, ("make_server_info_info3: pdb_init_sam failed!\n"));
1198 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1199 pdb_free_sam(&sam_account);
1200 return NT_STATUS_NO_MEMORY;
1203 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1204 pdb_free_sam(&sam_account);
1205 return NT_STATUS_NO_MEMORY;
1208 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1209 pdb_free_sam(&sam_account);
1210 return NT_STATUS_NO_MEMORY;
1213 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1214 pdb_free_sam(&sam_account);
1215 return NT_STATUS_UNSUCCESSFUL;
1218 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1219 pdb_free_sam(&sam_account);
1220 return NT_STATUS_UNSUCCESSFUL;
1223 if (!pdb_set_fullname(sam_account, unistr2_static(&(info3->uni_full_name)),
1225 pdb_free_sam(&sam_account);
1226 return NT_STATUS_NO_MEMORY;
1229 if (!pdb_set_logon_script(sam_account, unistr2_static(&(info3->uni_logon_script)), PDB_CHANGED)) {
1230 pdb_free_sam(&sam_account);
1231 return NT_STATUS_NO_MEMORY;
1234 if (!pdb_set_profile_path(sam_account, unistr2_static(&(info3->uni_profile_path)), PDB_CHANGED)) {
1235 pdb_free_sam(&sam_account);
1236 return NT_STATUS_NO_MEMORY;
1239 if (!pdb_set_homedir(sam_account, unistr2_static(&(info3->uni_home_dir)), PDB_CHANGED)) {
1240 pdb_free_sam(&sam_account);
1241 return NT_STATUS_NO_MEMORY;
1244 if (!pdb_set_dir_drive(sam_account, unistr2_static(&(info3->uni_dir_drive)), PDB_CHANGED)) {
1245 pdb_free_sam(&sam_account);
1246 return NT_STATUS_NO_MEMORY;
1249 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
1250 DEBUG(4, ("make_server_info failed!\n"));
1251 pdb_free_sam(&sam_account);
1255 /* save this here to _net_sam_logon() doesn't fail (it assumes a
1256 valid SAM_ACCOUNT) */
1258 (*server_info)->sam_account = sam_account;
1260 (*server_info)->unix_name = smb_xstrdup(found_username);
1262 /* Fill in the unix info we found on the way */
1264 (*server_info)->sam_fill_level = SAM_FILL_ALL;
1265 (*server_info)->uid = uid;
1266 (*server_info)->gid = gid;
1268 /* Store the user group information in the server_info
1269 returned to the caller. */
1271 nt_status = get_user_groups((*server_info)->unix_name,
1272 uid, gid, &n_lgroupSIDs, &lgroupSIDs, &unix_groups);
1274 if ( !NT_STATUS_IS_OK(nt_status) ) {
1275 DEBUG(4,("get_user_groups failed\n"));
1279 (*server_info)->groups = unix_groups;
1280 (*server_info)->n_groups = n_lgroupSIDs;
1282 /* Create a 'combined' list of all SIDs we might want in the SD */
1284 all_group_SIDs = SMB_MALLOC_ARRAY(DOM_SID,info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs);
1286 if (!all_group_SIDs) {
1287 DEBUG(0, ("malloc() failed for DOM_SID list!\n"));
1288 SAFE_FREE(lgroupSIDs);
1289 free_server_info(server_info);
1290 return NT_STATUS_NO_MEMORY;
1293 /* and create (by appending rids) the 'domain' sids */
1295 for (i = 0; i < info3->num_groups2; i++) {
1297 sid_copy(&all_group_SIDs[i], &(info3->dom_sid.sid));
1299 if (!sid_append_rid(&all_group_SIDs[i], info3->gids[i].g_rid)) {
1301 nt_status = NT_STATUS_INVALID_PARAMETER;
1303 DEBUG(3,("could not append additional group rid 0x%x\n",
1304 info3->gids[i].g_rid));
1306 SAFE_FREE(lgroupSIDs);
1307 SAFE_FREE(all_group_SIDs);
1308 free_server_info(server_info);
1315 /* Copy 'other' sids. We need to do sid filtering here to
1316 prevent possible elevation of privileges. See:
1318 http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
1321 for (i = 0; i < info3->num_other_sids; i++) {
1322 sid_copy(&all_group_SIDs[info3->num_groups2 + i],
1323 &info3->other_sids[i].sid);
1327 /* add local alias sids */
1329 for (i = 0; i < n_lgroupSIDs; i++) {
1330 sid_copy(&all_group_SIDs[info3->num_groups2 +
1331 info3->num_other_sids + i],
1335 /* Where are the 'global' sids... */
1337 /* can the user be guest? if yes, where is it stored? */
1339 nt_status = create_nt_user_token(&user_sid, &group_sid,
1340 info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs,
1341 all_group_SIDs, False, &token);
1343 if ( !NT_STATUS_IS_OK(nt_status) ) {
1344 DEBUG(4,("create_nt_user_token failed\n"));
1345 SAFE_FREE(lgroupSIDs);
1346 SAFE_FREE(all_group_SIDs);
1347 free_server_info(server_info);
1351 (*server_info)->ptok = token;
1353 SAFE_FREE(lgroupSIDs);
1354 SAFE_FREE(all_group_SIDs);
1356 /* ensure we are never given NULL session keys */
1358 if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
1359 (*server_info)->user_session_key = data_blob(NULL, 0);
1361 (*server_info)->user_session_key = data_blob(info3->user_sess_key, sizeof(info3->user_sess_key));
1364 if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
1365 (*server_info)->lm_session_key = data_blob(NULL, 0);
1367 (*server_info)->lm_session_key = data_blob(info3->lm_sess_key, sizeof(info3->lm_sess_key));
1370 return NT_STATUS_OK;
1373 /***************************************************************************
1374 Free a user_info struct
1375 ***************************************************************************/
1377 void free_user_info(auth_usersupplied_info **user_info)
1379 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1380 if (*user_info != NULL) {
1381 if ((*user_info)->smb_name.str) {
1382 DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
1384 SAFE_FREE((*user_info)->smb_name.str);
1385 SAFE_FREE((*user_info)->internal_username.str);
1386 SAFE_FREE((*user_info)->client_domain.str);
1387 SAFE_FREE((*user_info)->domain.str);
1388 SAFE_FREE((*user_info)->wksta_name.str);
1389 data_blob_free(&(*user_info)->lm_resp);
1390 data_blob_free(&(*user_info)->nt_resp);
1391 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1392 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1393 data_blob_clear_free(&(*user_info)->plaintext_password);
1394 ZERO_STRUCT(**user_info);
1396 SAFE_FREE(*user_info);
1399 /***************************************************************************
1400 Clear out a server_info struct that has been allocated
1401 ***************************************************************************/
1403 void free_server_info(auth_serversupplied_info **server_info)
1405 DEBUG(5,("attempting to free (and zero) a server_info structure\n"));
1406 if (*server_info != NULL) {
1407 pdb_free_sam(&(*server_info)->sam_account);
1409 /* call pam_end here, unless we know we are keeping it */
1410 delete_nt_token( &(*server_info)->ptok );
1411 SAFE_FREE((*server_info)->groups);
1412 SAFE_FREE((*server_info)->unix_name);
1413 data_blob_free(&(*server_info)->lm_session_key);
1414 data_blob_free(&(*server_info)->user_session_key);
1415 ZERO_STRUCT(**server_info);
1417 SAFE_FREE(*server_info);
1420 /***************************************************************************
1421 Make an auth_methods struct
1422 ***************************************************************************/
1424 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method)
1426 if (!auth_context) {
1427 smb_panic("no auth_context supplied to make_auth_methods()!\n");
1431 smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
1434 *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1435 if (!*auth_method) {
1436 DEBUG(0,("make_auth_method: malloc failed!\n"));
1439 ZERO_STRUCTP(*auth_method);
1444 /****************************************************************************
1446 ****************************************************************************/
1448 void delete_nt_token(NT_USER_TOKEN **pptoken)
1451 NT_USER_TOKEN *ptoken = *pptoken;
1453 SAFE_FREE( ptoken->user_sids );
1454 ZERO_STRUCTP(ptoken);
1456 SAFE_FREE(*pptoken);
1459 /****************************************************************************
1460 Duplicate a SID token.
1461 ****************************************************************************/
1463 NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
1465 NT_USER_TOKEN *token;
1470 if ((token = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL)
1473 ZERO_STRUCTP(token);
1475 token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
1482 token->num_sids = ptoken->num_sids;
1484 /* copy the privileges; don't consider failure to be critical here */
1486 if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
1487 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. Continuing with 0 privileges assigned.\n"));
1493 /****************************************************************************
1494 Check for a SID in an NT_USER_TOKEN
1495 ****************************************************************************/
1497 BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token )
1501 if ( !sid || !token )
1504 for ( i=0; i<token->num_sids; i++ ) {
1505 if ( sid_equal( sid, &token->user_sids[i] ) )
1512 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
1516 /* if we are a domain member, the get the domain SID, else for
1517 a DC or standalone server, use our own SID */
1519 if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
1520 if ( !secrets_fetch_domain_sid( lp_workgroup(), &domain_sid ) ) {
1521 DEBUG(1,("nt_token_check_domain_rid: Cannot lookup SID for domain [%s]\n",
1527 sid_copy( &domain_sid, get_global_sam_sid() );
1529 sid_append_rid( &domain_sid, rid );
1531 return nt_token_check_sid( &domain_sid, token );\
1535 * Verify whether or not given domain is trusted.
1537 * @param domain_name name of the domain to be verified
1538 * @return true if domain is one of the trusted once or
1539 * false if otherwise
1542 BOOL is_trusted_domain(const char* dom_name)
1544 DOM_SID trustdom_sid;
1549 /* no trusted domains for a standalone server */
1551 if ( lp_server_role() == ROLE_STANDALONE )
1554 /* if we are a DC, then check for a direct trust relationships */
1558 DEBUG (5,("is_trusted_domain: Checking for domain trust with [%s]\n",
1560 ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
1567 /* if winbindd is not up and we are a domain member) then we need to update the
1568 trustdom_cache ourselves */
1570 if ( !winbind_ping() )
1571 update_trustdom_cache();
1574 /* now the trustdom cache should be available a DC could still
1575 * have a transitive trust so fall back to the cache of trusted
1576 * domains (like a domain member would use */
1578 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {