2 Unix SMB/CIFS implementation.
3 Authentication utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001
6 Copyright (C) Jeremy Allison 2000-2001
7 Copyright (C) Rafal Szczesniak 2002
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #define DBGC_CLASS DBGC_AUTH
30 /****************************************************************************
31 Create a UNIX user on demand.
32 ****************************************************************************/
34 static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
39 pstrcpy(add_script, lp_adduser_script());
42 all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
44 all_string_sub(add_script, "%D", domain, sizeof(pstring));
46 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
47 ret = smbrun(add_script,NULL);
49 DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
53 /****************************************************************************
54 Create a SAM_ACCOUNT - either by looking in the pdb, or by faking it up from
56 ****************************************************************************/
58 NTSTATUS auth_get_sam_account(const char *user, SAM_ACCOUNT **account)
62 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(account))) {
67 pdb_ret = pdb_getsampwnam(*account, user);
72 struct passwd *pass = Get_Pwnam(user);
74 return NT_STATUS_NO_SUCH_USER;
76 if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*account, pass))) {
83 /****************************************************************************
84 Create an auth_usersupplied_data structure
85 ****************************************************************************/
87 static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
89 const char *internal_username,
90 const char *client_domain,
92 const char *wksta_name,
93 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
94 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
99 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
101 *user_info = SMB_MALLOC_P(auth_usersupplied_info);
103 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
104 return NT_STATUS_NO_MEMORY;
107 ZERO_STRUCTP(*user_info);
109 DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
111 (*user_info)->smb_name.str = SMB_STRDUP(smb_name);
112 if ((*user_info)->smb_name.str) {
113 (*user_info)->smb_name.len = strlen(smb_name);
115 free_user_info(user_info);
116 return NT_STATUS_NO_MEMORY;
119 (*user_info)->internal_username.str = SMB_STRDUP(internal_username);
120 if ((*user_info)->internal_username.str) {
121 (*user_info)->internal_username.len = strlen(internal_username);
123 free_user_info(user_info);
124 return NT_STATUS_NO_MEMORY;
127 (*user_info)->domain.str = SMB_STRDUP(domain);
128 if ((*user_info)->domain.str) {
129 (*user_info)->domain.len = strlen(domain);
131 free_user_info(user_info);
132 return NT_STATUS_NO_MEMORY;
135 (*user_info)->client_domain.str = SMB_STRDUP(client_domain);
136 if ((*user_info)->client_domain.str) {
137 (*user_info)->client_domain.len = strlen(client_domain);
139 free_user_info(user_info);
140 return NT_STATUS_NO_MEMORY;
143 (*user_info)->wksta_name.str = SMB_STRDUP(wksta_name);
144 if ((*user_info)->wksta_name.str) {
145 (*user_info)->wksta_name.len = strlen(wksta_name);
147 free_user_info(user_info);
148 return NT_STATUS_NO_MEMORY;
151 DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
154 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
156 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
157 if (lm_interactive_pwd)
158 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
159 if (nt_interactive_pwd)
160 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
163 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
165 (*user_info)->encrypted = encrypted;
167 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
172 /****************************************************************************
173 Create an auth_usersupplied_data structure after appropriate mapping.
174 ****************************************************************************/
176 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
177 const char *smb_name,
178 const char *client_domain,
179 const char *wksta_name,
180 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
181 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
182 DATA_BLOB *plaintext,
186 fstring internal_username;
187 fstrcpy(internal_username, smb_name);
188 map_username(internal_username);
190 DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
191 client_domain, smb_name, wksta_name));
193 /* don't allow "" as a domain, fixes a Win9X bug
194 where it doens't supply a domain for logon script
195 'net use' commands. */
197 if ( *client_domain )
198 domain = client_domain;
200 domain = lp_workgroup();
202 /* do what win2k does. Always map unknown domains to our own
203 and let the "passdb backend" handle unknown users. */
205 if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) )
206 domain = get_default_sam_name();
208 /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
210 return make_user_info(user_info, smb_name, internal_username,
211 client_domain, domain, wksta_name,
213 lm_interactive_pwd, nt_interactive_pwd,
214 plaintext, encrypted);
217 /****************************************************************************
218 Create an auth_usersupplied_data, making the DATA_BLOBs here.
219 Decrypt and encrypt the passwords.
220 ****************************************************************************/
222 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
223 const char *smb_name,
224 const char *client_domain,
225 const char *wksta_name,
226 const uchar *lm_network_pwd, int lm_pwd_len,
227 const uchar *nt_network_pwd, int nt_pwd_len)
231 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
232 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
234 nt_status = make_user_info_map(user_info,
235 smb_name, client_domain,
237 lm_pwd_len ? &lm_blob : NULL,
238 nt_pwd_len ? &nt_blob : NULL,
242 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
244 data_blob_free(&lm_blob);
245 data_blob_free(&nt_blob);
249 /****************************************************************************
250 Create an auth_usersupplied_data, making the DATA_BLOBs here.
251 Decrypt and encrypt the passwords.
252 ****************************************************************************/
254 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
255 const char *smb_name,
256 const char *client_domain,
257 const char *wksta_name,
259 const uchar lm_interactive_pwd[16],
260 const uchar nt_interactive_pwd[16],
261 const uchar *dc_sess_key)
265 unsigned char local_lm_response[24];
266 unsigned char local_nt_response[24];
267 unsigned char key[16];
270 memcpy(key, dc_sess_key, 8);
272 if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
273 if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
275 #ifdef DEBUG_PASSWORD
277 dump_data(100, (char *)key, sizeof(key));
279 DEBUG(100,("lm owf password:"));
280 dump_data(100, lm_pwd, sizeof(lm_pwd));
282 DEBUG(100,("nt owf password:"));
283 dump_data(100, nt_pwd, sizeof(nt_pwd));
286 if (lm_interactive_pwd)
287 SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));
289 if (nt_interactive_pwd)
290 SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));
292 #ifdef DEBUG_PASSWORD
293 DEBUG(100,("decrypt of lm owf password:"));
294 dump_data(100, lm_pwd, sizeof(lm_pwd));
296 DEBUG(100,("decrypt of nt owf password:"));
297 dump_data(100, nt_pwd, sizeof(nt_pwd));
300 if (lm_interactive_pwd)
301 SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
303 if (nt_interactive_pwd)
304 SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
306 /* Password info paranoia */
312 DATA_BLOB local_lm_blob;
313 DATA_BLOB local_nt_blob;
315 DATA_BLOB lm_interactive_blob;
316 DATA_BLOB nt_interactive_blob;
318 if (lm_interactive_pwd) {
319 local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
320 lm_interactive_blob = data_blob(lm_pwd, sizeof(lm_pwd));
324 if (nt_interactive_pwd) {
325 local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
326 nt_interactive_blob = data_blob(nt_pwd, sizeof(nt_pwd));
330 nt_status = make_user_info_map(user_info,
331 smb_name, client_domain,
333 lm_interactive_pwd ? &local_lm_blob : NULL,
334 nt_interactive_pwd ? &local_nt_blob : NULL,
335 lm_interactive_pwd ? &lm_interactive_blob : NULL,
336 nt_interactive_pwd ? &nt_interactive_blob : NULL,
340 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
341 data_blob_free(&local_lm_blob);
342 data_blob_free(&local_nt_blob);
343 data_blob_free(&lm_interactive_blob);
344 data_blob_free(&nt_interactive_blob);
350 /****************************************************************************
351 Create an auth_usersupplied_data structure
352 ****************************************************************************/
354 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
355 const char *smb_name,
356 const char *client_domain,
358 DATA_BLOB plaintext_password)
361 DATA_BLOB local_lm_blob;
362 DATA_BLOB local_nt_blob;
363 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
366 * Not encrypted - do so.
369 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
371 if (plaintext_password.data) {
372 unsigned char local_lm_response[24];
374 #ifdef DEBUG_PASSWORD
375 DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
376 dump_data(100, plaintext_password.data, plaintext_password.length);
379 SMBencrypt( (const char *)plaintext_password.data, (const uchar*)chal, local_lm_response);
380 local_lm_blob = data_blob(local_lm_response, 24);
382 /* We can't do an NT hash here, as the password needs to be
384 local_nt_blob = data_blob(NULL, 0);
387 local_lm_blob = data_blob(NULL, 0);
388 local_nt_blob = data_blob(NULL, 0);
391 ret = make_user_info_map(user_info, smb_name,
393 get_remote_machine_name(),
394 local_lm_blob.data ? &local_lm_blob : NULL,
395 local_nt_blob.data ? &local_nt_blob : NULL,
397 plaintext_password.data ? &plaintext_password : NULL,
400 data_blob_free(&local_lm_blob);
401 return NT_STATUS_IS_OK(ret) ? True : False;
404 /****************************************************************************
405 Create an auth_usersupplied_data structure
406 ****************************************************************************/
408 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
409 const char *smb_name,
410 const char *client_domain,
411 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
413 return make_user_info_map(user_info, smb_name,
415 get_remote_machine_name(),
416 lm_resp.data ? &lm_resp : NULL,
417 nt_resp.data ? &nt_resp : NULL,
422 /****************************************************************************
423 Create a guest user_info blob, for anonymous authenticaion.
424 ****************************************************************************/
426 BOOL make_user_info_guest(auth_usersupplied_info **user_info)
430 nt_status = make_user_info(user_info,
439 return NT_STATUS_IS_OK(nt_status) ? True : False;
442 /****************************************************************************
443 prints a NT_USER_TOKEN to debug output.
444 ****************************************************************************/
446 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
452 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
456 DEBUGC(dbg_class, dbg_lev, ("NT user token of user %s\n",
457 sid_to_string(sid_str, &token->user_sids[0]) ));
458 DEBUGADDC(dbg_class, dbg_lev, ("contains %lu SIDs\n", (unsigned long)token->num_sids));
459 for (i = 0; i < token->num_sids; i++)
460 DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i,
461 sid_to_string(sid_str, &token->user_sids[i])));
463 dump_se_priv( dbg_class, dbg_lev, &token->privileges );
466 /****************************************************************************
467 prints a UNIX 'token' to debug output.
468 ****************************************************************************/
470 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid, int n_groups, gid_t *groups)
473 DEBUGC(dbg_class, dbg_lev, ("UNIX token of user %ld\n", (long int)uid));
475 DEBUGADDC(dbg_class, dbg_lev, ("Primary group is %ld and contains %i supplementary groups\n", (long int)gid, n_groups));
476 for (i = 0; i < n_groups; i++)
477 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i,
478 (long int)groups[i]));
481 /****************************************************************************
482 Create the SID list for this user.
483 ****************************************************************************/
485 static NTSTATUS create_nt_user_token(const DOM_SID *user_sid, const DOM_SID *group_sid,
486 int n_groupSIDs, DOM_SID *groupSIDs,
487 BOOL is_guest, NT_USER_TOKEN **token)
489 NTSTATUS nt_status = NT_STATUS_OK;
490 NT_USER_TOKEN *ptoken;
494 if ((ptoken = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL) {
495 DEBUG(0, ("create_nt_token: Out of memory allocating token\n"));
496 nt_status = NT_STATUS_NO_MEMORY;
500 ZERO_STRUCTP(ptoken);
502 ptoken->num_sids = n_groupSIDs + 5;
504 if ((ptoken->user_sids = SMB_MALLOC_ARRAY( DOM_SID, ptoken->num_sids )) == NULL) {
505 DEBUG(0, ("create_nt_token: Out of memory allocating SIDs\n"));
506 nt_status = NT_STATUS_NO_MEMORY;
510 memset((char*)ptoken->user_sids,0,sizeof(DOM_SID) * ptoken->num_sids);
513 * Note - user SID *MUST* be first in token !
514 * se_access_check depends on this.
516 * Primary group SID is second in token. Convention.
519 sid_copy(&ptoken->user_sids[PRIMARY_USER_SID_INDEX], user_sid);
521 sid_copy(&ptoken->user_sids[PRIMARY_GROUP_SID_INDEX], group_sid);
524 * Finally add the "standard" SIDs.
525 * The only difference between guest and "anonymous" (which we
526 * don't really support) is the addition of Authenticated_Users.
529 sid_copy(&ptoken->user_sids[2], &global_sid_World);
530 sid_copy(&ptoken->user_sids[3], &global_sid_Network);
533 sid_copy(&ptoken->user_sids[4], &global_sid_Builtin_Guests);
535 sid_copy(&ptoken->user_sids[4], &global_sid_Authenticated_Users);
537 sid_ndx = 5; /* next available spot */
539 for (i = 0; i < n_groupSIDs; i++) {
540 size_t check_sid_idx;
541 for (check_sid_idx = 1; check_sid_idx < ptoken->num_sids; check_sid_idx++) {
542 if (sid_equal(&ptoken->user_sids[check_sid_idx],
548 if (check_sid_idx >= ptoken->num_sids) /* Not found already */ {
549 sid_copy(&ptoken->user_sids[sid_ndx++], &groupSIDs[i]);
555 /* add privileges assigned to this user */
557 get_privileges_for_sids( &ptoken->privileges, ptoken->user_sids, ptoken->num_sids );
559 debug_nt_user_token(DBGC_AUTH, 10, ptoken);
561 if ((lp_log_nt_token_command() != NULL) &&
562 (strlen(lp_log_nt_token_command()) > 0)) {
566 char *user_sidstr, *group_sidstr;
568 mem_ctx = talloc_init("setnttoken");
570 return NT_STATUS_NO_MEMORY;
572 sid_to_string(sidstr, &ptoken->user_sids[0]);
573 user_sidstr = talloc_strdup(mem_ctx, sidstr);
575 group_sidstr = talloc_strdup(mem_ctx, "");
576 for (i=1; i<ptoken->num_sids; i++) {
577 sid_to_string(sidstr, &ptoken->user_sids[i]);
578 group_sidstr = talloc_asprintf(mem_ctx, "%s %s",
579 group_sidstr, sidstr);
582 command = SMB_STRDUP(lp_log_nt_token_command());
583 command = realloc_string_sub(command, "%s", user_sidstr);
584 command = realloc_string_sub(command, "%t", group_sidstr);
585 DEBUG(8, ("running command: [%s]\n", command));
586 if (smbrun(command, NULL) != 0) {
587 DEBUG(0, ("Could not log NT token\n"));
588 nt_status = NT_STATUS_ACCESS_DENIED;
590 talloc_destroy(mem_ctx);
599 /****************************************************************************
600 Create the SID list for this user.
601 ****************************************************************************/
603 NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest)
608 NT_USER_TOKEN *token;
611 if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, uid))) {
614 if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, gid))) {
618 group_sids = SMB_MALLOC_ARRAY(DOM_SID, ngroups);
620 DEBUG(0, ("create_nt_token: malloc() failed for DOM_SID list!\n"));
624 for (i = 0; i < ngroups; i++) {
625 if (!NT_STATUS_IS_OK(gid_to_sid(&(group_sids)[i], (groups)[i]))) {
626 DEBUG(1, ("create_nt_token: failed to convert gid %ld to a sid!\n", (long int)groups[i]));
627 SAFE_FREE(group_sids);
632 if (!NT_STATUS_IS_OK(create_nt_user_token(&user_sid, &group_sid,
633 ngroups, group_sids, is_guest, &token))) {
634 SAFE_FREE(group_sids);
638 SAFE_FREE(group_sids);
643 /******************************************************************************
644 * this function returns the groups (SIDs) of the local SAM the user is in.
645 * If this samba server is a DC of the domain the user belongs to, it returns
646 * both domain groups and local / builtin groups. If the user is in a trusted
647 * domain, or samba is a member server of a domain, then this function returns
648 * local and builtin groups the user is a member of.
650 * currently this is a hack, as there is no sam implementation that is capable
653 * NOTE!! This function will fail if you pass in a winbind user without
655 ******************************************************************************/
657 static NTSTATUS get_user_groups(const char *username, uid_t uid, gid_t gid,
658 int *n_groups, DOM_SID **groups, gid_t **unix_groups)
666 if (strchr(username, *lp_winbind_separator()) == NULL) {
670 result = pdb_enum_group_memberships(username, gid, groups,
671 unix_groups, n_groups);
676 /* We have the separator, this must be winbind */
678 n_unix_groups = winbind_getgroups( username, unix_groups );
680 DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n",
681 username, n_unix_groups == -1 ? "FAIL" : "SUCCESS"));
683 if ( n_unix_groups == -1 )
684 return NT_STATUS_NO_SUCH_USER; /* what should this return
687 debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups);
689 /* now setup the space for storing the SIDS */
691 if (n_unix_groups > 0) {
693 *groups = SMB_MALLOC_ARRAY(DOM_SID, n_unix_groups);
696 DEBUG(0, ("get_user_group: malloc() failed for DOM_SID list!\n"));
697 SAFE_FREE(*unix_groups);
698 return NT_STATUS_NO_MEMORY;
702 *n_groups = n_unix_groups;
704 for (i = 0; i < *n_groups; i++) {
705 if (!NT_STATUS_IS_OK(gid_to_sid(&(*groups)[i], (*unix_groups)[i]))) {
706 DEBUG(1, ("get_user_groups: failed to convert gid %ld to a sid!\n",
707 (long int)(*unix_groups)[i+1]));
709 SAFE_FREE(*unix_groups);
710 return NT_STATUS_NO_SUCH_USER;
717 /***************************************************************************
718 Make a user_info struct
719 ***************************************************************************/
721 static NTSTATUS make_server_info(auth_serversupplied_info **server_info)
723 *server_info = SMB_MALLOC_P(auth_serversupplied_info);
725 DEBUG(0,("make_server_info: malloc failed!\n"));
726 return NT_STATUS_NO_MEMORY;
728 ZERO_STRUCTP(*server_info);
730 /* Initialise the uid and gid values to something non-zero
731 which may save us from giving away root access if there
732 is a bug in allocating these fields. */
734 (*server_info)->uid = -1;
735 (*server_info)->gid = -1;
740 /***************************************************************************
741 Fill a server_info struct from a SAM_ACCOUNT with their groups
742 ***************************************************************************/
744 static NTSTATUS add_user_groups(auth_serversupplied_info **server_info,
745 const char * unix_username,
746 SAM_ACCOUNT *sampass,
747 uid_t uid, gid_t gid)
750 const DOM_SID *user_sid = pdb_get_user_sid(sampass);
751 const DOM_SID *group_sid = pdb_get_group_sid(sampass);
753 DOM_SID *groupSIDs = NULL;
754 gid_t *unix_groups = NULL;
755 NT_USER_TOKEN *token;
759 nt_status = get_user_groups(unix_username, uid, gid,
760 &n_groupSIDs, &groupSIDs, &unix_groups);
762 if (!NT_STATUS_IS_OK(nt_status)) {
763 DEBUG(4,("get_user_groups_from_local_sam failed\n"));
764 free_server_info(server_info);
768 is_guest = (sid_peek_rid(user_sid, &rid) && rid == DOMAIN_USER_RID_GUEST);
770 if (!NT_STATUS_IS_OK(nt_status = create_nt_user_token(user_sid, group_sid,
771 n_groupSIDs, groupSIDs, is_guest,
774 DEBUG(4,("create_nt_user_token failed\n"));
775 SAFE_FREE(groupSIDs);
776 SAFE_FREE(unix_groups);
777 free_server_info(server_info);
781 SAFE_FREE(groupSIDs);
783 (*server_info)->n_groups = n_groupSIDs;
784 (*server_info)->groups = unix_groups;
785 (*server_info)->ptok = token;
790 /***************************************************************************
791 Make (and fill) a user_info struct from a SAM_ACCOUNT
792 ***************************************************************************/
794 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
795 SAM_ACCOUNT *sampass)
800 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info)))
803 (*server_info)->sam_account = sampass;
805 if ( !(pwd = getpwnam_alloc(pdb_get_username(sampass))) ) {
806 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
807 pdb_get_username(sampass)));
808 free_server_info(server_info);
809 return NT_STATUS_NO_SUCH_USER;
811 (*server_info)->unix_name = smb_xstrdup(pwd->pw_name);
812 (*server_info)->gid = pwd->pw_gid;
813 (*server_info)->uid = pwd->pw_uid;
817 if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, pdb_get_username(sampass),
820 (*server_info)->gid)))
822 free_server_info(server_info);
826 (*server_info)->sam_fill_level = SAM_FILL_ALL;
827 DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
828 pdb_get_username(sampass),
829 (*server_info)->unix_name));
834 /***************************************************************************
835 Make (and fill) a user_info struct from a 'struct passwd' by conversion
837 ***************************************************************************/
839 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
844 SAM_ACCOUNT *sampass = NULL;
845 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {
848 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
852 (*server_info)->sam_account = sampass;
854 if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username,
855 sampass, pwd->pw_uid, pwd->pw_gid)))
860 (*server_info)->unix_name = smb_xstrdup(unix_username);
862 (*server_info)->sam_fill_level = SAM_FILL_ALL;
863 (*server_info)->uid = pwd->pw_uid;
864 (*server_info)->gid = pwd->pw_gid;
868 /***************************************************************************
869 Make (and fill) a user_info struct for a guest login.
870 ***************************************************************************/
872 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
875 SAM_ACCOUNT *sampass = NULL;
878 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) {
882 sid_copy(&guest_sid, get_global_sam_sid());
883 sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
886 if (!pdb_getsampwsid(sampass, &guest_sid)) {
888 return NT_STATUS_NO_SUCH_USER;
892 nt_status = make_server_info_sam(server_info, sampass);
894 if (NT_STATUS_IS_OK(nt_status)) {
895 static const char zeros[16];
896 (*server_info)->guest = True;
898 /* annoying, but the Guest really does have a session key,
899 and it is all zeros! */
900 (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
901 (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
907 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
909 auth_serversupplied_info *dst;
911 if (!NT_STATUS_IS_OK(make_server_info(&dst)))
914 dst->guest = src->guest;
917 dst->n_groups = src->n_groups;
918 if (src->n_groups != 0)
919 dst->groups = memdup(src->groups, sizeof(gid_t)*dst->n_groups);
922 dst->ptok = dup_nt_token(src->ptok);
923 dst->user_session_key = data_blob(src->user_session_key.data,
924 src->user_session_key.length);
925 dst->lm_session_key = data_blob(src->lm_session_key.data,
926 src->lm_session_key.length);
927 pdb_copy_sam_account(src->sam_account, &dst->sam_account);
928 dst->pam_handle = NULL;
929 dst->unix_name = smb_xstrdup(src->unix_name);
934 static auth_serversupplied_info *guest_info = NULL;
936 BOOL init_guest_info(void)
938 if (guest_info != NULL)
941 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
944 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
946 *server_info = copy_serverinfo(guest_info);
947 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
950 /***************************************************************************
951 Purely internal function for make_server_info_info3
952 Fill the sam account from getpwnam
953 ***************************************************************************/
954 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
956 const char *username,
957 char **found_username,
958 uid_t *uid, gid_t *gid,
959 SAM_ACCOUNT **sam_account)
961 fstring dom_user, lower_username;
962 fstring real_username;
963 struct passwd *passwd;
965 fstrcpy( lower_username, username );
966 strlower_m( lower_username );
968 fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(),
971 /* get the passwd struct but don't create the user if he/she
972 does not exist. We were explicitly called from a following
973 a winbindd authentication request so we should assume that
974 nss_winbindd is working */
976 map_username( dom_user );
978 if ( !(passwd = smb_getpwnam( dom_user, real_username, True )) )
979 return NT_STATUS_NO_SUCH_USER;
981 *uid = passwd->pw_uid;
982 *gid = passwd->pw_gid;
984 /* This is pointless -- there is no suport for differing
985 unix and windows names. Make sure to always store the
986 one we actually looked up and succeeded. Have I mentioned
987 why I hate the 'winbind use default domain' parameter?
990 *found_username = talloc_strdup( mem_ctx, real_username );
992 DEBUG(5,("fill_sam_account: located username was [%s]\n",
995 return pdb_init_sam_pw(sam_account, passwd);
998 /****************************************************************************
999 Wrapper to allow the getpwnam() call to strip the domain name and
1000 try again in case a local UNIX user is already there. Also run through
1001 the username if we fallback to the username only.
1002 ****************************************************************************/
1004 struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create )
1006 struct passwd *pw = NULL;
1010 /* we only save a copy of the username it has been mangled
1011 by winbindd use default domain */
1013 save_username[0] = '\0';
1015 /* don't call map_username() here since it has to be done higher
1016 up the stack so we don't call it mutliple times */
1018 fstrcpy( username, domuser );
1020 p = strchr_m( username, *lp_winbind_separator() );
1022 /* code for a DOMAIN\user string */
1025 fstring strip_username;
1027 pw = Get_Pwnam( domuser );
1029 /* make sure we get the case of the username correct */
1030 /* work around 'winbind use default domain = yes' */
1032 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1035 /* split the domain and username into 2 strings */
1039 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1042 fstrcpy( save_username, pw->pw_name );
1048 /* setup for lookup of just the username */
1049 /* remember that p and username are overlapping memory */
1052 fstrcpy( strip_username, p );
1053 fstrcpy( username, strip_username );
1056 /* just lookup a plain username */
1058 pw = Get_Pwnam(username);
1060 /* Create local user if requested. */
1062 if ( !pw && create ) {
1063 /* Don't add a machine account. */
1064 if (username[strlen(username)-1] == '$')
1067 smb_create_user(NULL, username, NULL);
1068 pw = Get_Pwnam(username);
1071 /* one last check for a valid passwd struct */
1074 fstrcpy( save_username, pw->pw_name );
1079 /***************************************************************************
1080 Make a server_info struct from the info3 returned by a domain logon
1081 ***************************************************************************/
1083 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1084 const char *internal_username,
1085 const char *sent_nt_username,
1087 auth_serversupplied_info **server_info,
1088 NET_USER_INFO_3 *info3)
1090 static const char zeros[16];
1092 NTSTATUS nt_status = NT_STATUS_OK;
1093 char *found_username;
1094 const char *nt_domain;
1095 const char *nt_username;
1097 SAM_ACCOUNT *sam_account = NULL;
1105 DOM_SID *lgroupSIDs = NULL;
1107 gid_t *unix_groups = NULL;
1108 NT_USER_TOKEN *token;
1110 DOM_SID *all_group_SIDs;
1114 Here is where we should check the list of
1115 trusted domains, and verify that the SID
1119 sid_copy(&user_sid, &info3->dom_sid.sid);
1120 if (!sid_append_rid(&user_sid, info3->user_rid)) {
1121 return NT_STATUS_INVALID_PARAMETER;
1124 sid_copy(&group_sid, &info3->dom_sid.sid);
1125 if (!sid_append_rid(&group_sid, info3->group_rid)) {
1126 return NT_STATUS_INVALID_PARAMETER;
1129 if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1130 /* If the server didn't give us one, just use the one we sent them */
1131 nt_username = sent_nt_username;
1134 if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1135 /* If the server didn't give us one, just use the one we sent them */
1139 /* try to fill the SAM account.. If getpwnam() fails, then try the
1140 add user script (2.2.x behavior).
1142 We use the _unmapped_ username here in an attempt to provide
1143 consistent username mapping behavior between kerberos and NTLM[SSP]
1144 authentication in domain mode security. I.E. Username mapping should
1145 be applied to the fully qualified username (e.g. DOMAIN\user) and
1146 no just the login name. Yes this mean swe called map_username()
1147 unnecessarily in make_user_info_map() but that is how the current
1148 code is designed. Making the change here is the least disruptive
1151 nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1152 &found_username, &uid, &gid, &sam_account);
1154 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
1155 DEBUG(3,("User %s does not exist, trying to add it\n", internal_username));
1156 smb_create_user( nt_domain, sent_nt_username, NULL);
1157 nt_status = fill_sam_account( mem_ctx, nt_domain, sent_nt_username,
1158 &found_username, &uid, &gid, &sam_account );
1161 if (!NT_STATUS_IS_OK(nt_status)) {
1162 DEBUG(0, ("make_server_info_info3: pdb_init_sam failed!\n"));
1166 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1167 pdb_free_sam(&sam_account);
1168 return NT_STATUS_NO_MEMORY;
1171 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1172 pdb_free_sam(&sam_account);
1173 return NT_STATUS_NO_MEMORY;
1176 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1177 pdb_free_sam(&sam_account);
1178 return NT_STATUS_NO_MEMORY;
1181 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1182 pdb_free_sam(&sam_account);
1183 return NT_STATUS_UNSUCCESSFUL;
1186 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1187 pdb_free_sam(&sam_account);
1188 return NT_STATUS_UNSUCCESSFUL;
1191 if (!pdb_set_fullname(sam_account, unistr2_static(&(info3->uni_full_name)),
1193 pdb_free_sam(&sam_account);
1194 return NT_STATUS_NO_MEMORY;
1197 if (!pdb_set_logon_script(sam_account, unistr2_static(&(info3->uni_logon_script)), PDB_CHANGED)) {
1198 pdb_free_sam(&sam_account);
1199 return NT_STATUS_NO_MEMORY;
1202 if (!pdb_set_profile_path(sam_account, unistr2_static(&(info3->uni_profile_path)), PDB_CHANGED)) {
1203 pdb_free_sam(&sam_account);
1204 return NT_STATUS_NO_MEMORY;
1207 if (!pdb_set_homedir(sam_account, unistr2_static(&(info3->uni_home_dir)), PDB_CHANGED)) {
1208 pdb_free_sam(&sam_account);
1209 return NT_STATUS_NO_MEMORY;
1212 if (!pdb_set_dir_drive(sam_account, unistr2_static(&(info3->uni_dir_drive)), PDB_CHANGED)) {
1213 pdb_free_sam(&sam_account);
1214 return NT_STATUS_NO_MEMORY;
1217 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
1218 DEBUG(4, ("make_server_info failed!\n"));
1219 pdb_free_sam(&sam_account);
1223 /* save this here to _net_sam_logon() doesn't fail (it assumes a
1224 valid SAM_ACCOUNT) */
1226 (*server_info)->sam_account = sam_account;
1228 (*server_info)->unix_name = smb_xstrdup(found_username);
1230 /* Fill in the unix info we found on the way */
1232 (*server_info)->sam_fill_level = SAM_FILL_ALL;
1233 (*server_info)->uid = uid;
1234 (*server_info)->gid = gid;
1236 /* Store the user group information in the server_info
1237 returned to the caller. */
1239 nt_status = get_user_groups((*server_info)->unix_name,
1240 uid, gid, &n_lgroupSIDs, &lgroupSIDs, &unix_groups);
1242 if ( !NT_STATUS_IS_OK(nt_status) ) {
1243 DEBUG(4,("get_user_groups failed\n"));
1247 (*server_info)->groups = unix_groups;
1248 (*server_info)->n_groups = n_lgroupSIDs;
1250 /* Create a 'combined' list of all SIDs we might want in the SD */
1252 all_group_SIDs = SMB_MALLOC_ARRAY(DOM_SID,info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs);
1254 if (!all_group_SIDs) {
1255 DEBUG(0, ("malloc() failed for DOM_SID list!\n"));
1256 SAFE_FREE(lgroupSIDs);
1257 free_server_info(server_info);
1258 return NT_STATUS_NO_MEMORY;
1261 /* and create (by appending rids) the 'domain' sids */
1263 for (i = 0; i < info3->num_groups2; i++) {
1265 sid_copy(&all_group_SIDs[i], &(info3->dom_sid.sid));
1267 if (!sid_append_rid(&all_group_SIDs[i], info3->gids[i].g_rid)) {
1269 nt_status = NT_STATUS_INVALID_PARAMETER;
1271 DEBUG(3,("could not append additional group rid 0x%x\n",
1272 info3->gids[i].g_rid));
1274 SAFE_FREE(lgroupSIDs);
1275 SAFE_FREE(all_group_SIDs);
1276 free_server_info(server_info);
1283 /* Copy 'other' sids. We need to do sid filtering here to
1284 prevent possible elevation of privileges. See:
1286 http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
1289 for (i = 0; i < info3->num_other_sids; i++) {
1290 sid_copy(&all_group_SIDs[info3->num_groups2 + i],
1291 &info3->other_sids[i].sid);
1295 /* add local alias sids */
1297 for (i = 0; i < n_lgroupSIDs; i++) {
1298 sid_copy(&all_group_SIDs[info3->num_groups2 +
1299 info3->num_other_sids + i],
1303 /* Where are the 'global' sids... */
1305 /* can the user be guest? if yes, where is it stored? */
1307 nt_status = create_nt_user_token(&user_sid, &group_sid,
1308 info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs,
1309 all_group_SIDs, False, &token);
1311 if ( !NT_STATUS_IS_OK(nt_status) ) {
1312 DEBUG(4,("create_nt_user_token failed\n"));
1313 SAFE_FREE(lgroupSIDs);
1314 SAFE_FREE(all_group_SIDs);
1315 free_server_info(server_info);
1319 (*server_info)->ptok = token;
1321 SAFE_FREE(lgroupSIDs);
1322 SAFE_FREE(all_group_SIDs);
1324 /* ensure we are never given NULL session keys */
1326 if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
1327 (*server_info)->user_session_key = data_blob(NULL, 0);
1329 (*server_info)->user_session_key = data_blob(info3->user_sess_key, sizeof(info3->user_sess_key));
1332 if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
1333 (*server_info)->lm_session_key = data_blob(NULL, 0);
1335 (*server_info)->lm_session_key = data_blob(info3->lm_sess_key, sizeof(info3->lm_sess_key));
1338 return NT_STATUS_OK;
1341 /***************************************************************************
1342 Free a user_info struct
1343 ***************************************************************************/
1345 void free_user_info(auth_usersupplied_info **user_info)
1347 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1348 if (*user_info != NULL) {
1349 if ((*user_info)->smb_name.str) {
1350 DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));
1352 SAFE_FREE((*user_info)->smb_name.str);
1353 SAFE_FREE((*user_info)->internal_username.str);
1354 SAFE_FREE((*user_info)->client_domain.str);
1355 SAFE_FREE((*user_info)->domain.str);
1356 SAFE_FREE((*user_info)->wksta_name.str);
1357 data_blob_free(&(*user_info)->lm_resp);
1358 data_blob_free(&(*user_info)->nt_resp);
1359 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1360 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1361 data_blob_clear_free(&(*user_info)->plaintext_password);
1362 ZERO_STRUCT(**user_info);
1364 SAFE_FREE(*user_info);
1367 /***************************************************************************
1368 Clear out a server_info struct that has been allocated
1369 ***************************************************************************/
1371 void free_server_info(auth_serversupplied_info **server_info)
1373 DEBUG(5,("attempting to free (and zero) a server_info structure\n"));
1374 if (*server_info != NULL) {
1375 pdb_free_sam(&(*server_info)->sam_account);
1377 /* call pam_end here, unless we know we are keeping it */
1378 delete_nt_token( &(*server_info)->ptok );
1379 SAFE_FREE((*server_info)->groups);
1380 SAFE_FREE((*server_info)->unix_name);
1381 data_blob_free(&(*server_info)->lm_session_key);
1382 data_blob_free(&(*server_info)->user_session_key);
1383 ZERO_STRUCT(**server_info);
1385 SAFE_FREE(*server_info);
1388 /***************************************************************************
1389 Make an auth_methods struct
1390 ***************************************************************************/
1392 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method)
1394 if (!auth_context) {
1395 smb_panic("no auth_context supplied to make_auth_methods()!\n");
1399 smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
1402 *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1403 if (!*auth_method) {
1404 DEBUG(0,("make_auth_method: malloc failed!\n"));
1407 ZERO_STRUCTP(*auth_method);
1412 /****************************************************************************
1414 ****************************************************************************/
1416 void delete_nt_token(NT_USER_TOKEN **pptoken)
1419 NT_USER_TOKEN *ptoken = *pptoken;
1421 SAFE_FREE( ptoken->user_sids );
1422 ZERO_STRUCTP(ptoken);
1424 SAFE_FREE(*pptoken);
1427 /****************************************************************************
1428 Duplicate a SID token.
1429 ****************************************************************************/
1431 NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
1433 NT_USER_TOKEN *token;
1438 if ((token = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL)
1441 ZERO_STRUCTP(token);
1443 token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
1450 token->num_sids = ptoken->num_sids;
1452 /* copy the privileges; don't consider failure to be critical here */
1454 if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
1455 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. Continuing with 0 privileges assigned.\n"));
1461 /****************************************************************************
1462 Check for a SID in an NT_USER_TOKEN
1463 ****************************************************************************/
1465 BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token )
1469 if ( !sid || !token )
1472 for ( i=0; i<token->num_sids; i++ ) {
1473 if ( sid_equal( sid, &token->user_sids[i] ) )
1480 BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
1484 /* if we are a domain member, the get the domain SID, else for
1485 a DC or standalone server, use our own SID */
1487 if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
1488 if ( !secrets_fetch_domain_sid( lp_workgroup(), &domain_sid ) ) {
1489 DEBUG(1,("nt_token_check_domain_rid: Cannot lookup SID for domain [%s]\n",
1495 sid_copy( &domain_sid, get_global_sam_sid() );
1497 sid_append_rid( &domain_sid, rid );
1499 return nt_token_check_sid( &domain_sid, token );\
1503 * Verify whether or not given domain is trusted.
1505 * @param domain_name name of the domain to be verified
1506 * @return true if domain is one of the trusted once or
1507 * false if otherwise
1510 BOOL is_trusted_domain(const char* dom_name)
1512 DOM_SID trustdom_sid;
1517 /* no trusted domains for a standalone server */
1519 if ( lp_server_role() == ROLE_STANDALONE )
1522 /* if we are a DC, then check for a direct trust relationships */
1526 DEBUG (5,("is_trusted_domain: Checking for domain trust with [%s]\n",
1528 ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
1535 /* if winbindd is not up and we are a domain member) then we need to update the
1536 trustdom_cache ourselves */
1538 if ( !winbind_ping() )
1539 update_trustdom_cache();
1542 /* now the trustdom cache should be available a DC could still
1543 * have a transitive trust so fall back to the cache of trusted
1544 * domains (like a domain member would use */
1546 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {