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
8 Copyright (C) Volker Lendecke 2006
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "smbd/globals.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../lib/crypto/arcfour.h"
30 #define DBGC_CLASS DBGC_AUTH
32 /****************************************************************************
33 Create a UNIX user on demand.
34 ****************************************************************************/
36 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
38 TALLOC_CTX *ctx = talloc_tos();
42 add_script = talloc_strdup(ctx, lp_adduser_script());
43 if (!add_script || !*add_script) {
46 add_script = talloc_all_string_sub(ctx,
54 add_script = talloc_all_string_sub(ctx,
63 add_script = talloc_all_string_sub(ctx,
71 ret = smbrun(add_script,NULL);
74 ("smb_create_user: Running the command `%s' gave %d\n",
79 /****************************************************************************
80 Create an auth_usersupplied_data structure after appropriate mapping.
81 ****************************************************************************/
83 NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info,
85 const char *client_domain,
86 const char *workstation_name,
89 DATA_BLOB *lm_interactive_pwd,
90 DATA_BLOB *nt_interactive_pwd,
97 fstring internal_username;
98 fstrcpy(internal_username, smb_name);
99 was_mapped = map_username(internal_username);
101 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
102 client_domain, smb_name, workstation_name));
104 domain = client_domain;
106 /* If you connect to a Windows domain member using a bogus domain name,
107 * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if
108 * the Windows box is a DC the name will become DOMAIN\user and be
109 * authenticated against AD, if the Windows box is a member server but
110 * not a DC the name will become WORKSTATION\user. A standalone
111 * non-domain member box will also map to WORKSTATION\user.
112 * This also deals with the client passing in a "" domain */
114 if (!is_trusted_domain(domain) &&
115 !strequal(domain, my_sam_name()))
117 if (lp_map_untrusted_to_domain())
118 domain = my_sam_name();
120 domain = get_global_sam_name();
121 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
122 "workstation [%s]\n",
123 client_domain, domain, smb_name, workstation_name));
126 /* We know that the given domain is trusted (and we are allowing them),
127 * it is our global SAM name, or for legacy behavior it is our
128 * primary domain name */
130 result = make_user_info(user_info, smb_name, internal_username,
131 client_domain, domain, workstation_name,
133 lm_interactive_pwd, nt_interactive_pwd,
134 plaintext, encrypted);
135 if (NT_STATUS_IS_OK(result)) {
136 (*user_info)->was_mapped = was_mapped;
141 /****************************************************************************
142 Create an auth_usersupplied_data, making the DATA_BLOBs here.
143 Decrypt and encrypt the passwords.
144 ****************************************************************************/
146 bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info,
147 const char *smb_name,
148 const char *client_domain,
149 const char *workstation_name,
150 uint32 logon_parameters,
151 const uchar *lm_network_pwd,
153 const uchar *nt_network_pwd,
158 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
159 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
161 status = make_user_info_map(user_info,
162 smb_name, client_domain,
164 lm_pwd_len ? &lm_blob : NULL,
165 nt_pwd_len ? &nt_blob : NULL,
169 if (NT_STATUS_IS_OK(status)) {
170 (*user_info)->logon_parameters = logon_parameters;
172 ret = NT_STATUS_IS_OK(status) ? True : False;
174 data_blob_free(&lm_blob);
175 data_blob_free(&nt_blob);
179 /****************************************************************************
180 Create an auth_usersupplied_data, making the DATA_BLOBs here.
181 Decrypt and encrypt the passwords.
182 ****************************************************************************/
184 bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
185 const char *smb_name,
186 const char *client_domain,
187 const char *workstation_name,
188 uint32 logon_parameters,
190 const uchar lm_interactive_pwd[16],
191 const uchar nt_interactive_pwd[16],
192 const uchar *dc_sess_key)
194 unsigned char lm_pwd[16];
195 unsigned char nt_pwd[16];
196 unsigned char local_lm_response[24];
197 unsigned char local_nt_response[24];
198 unsigned char key[16];
200 memcpy(key, dc_sess_key, 16);
202 if (lm_interactive_pwd)
203 memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
205 if (nt_interactive_pwd)
206 memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
208 #ifdef DEBUG_PASSWORD
210 dump_data(100, key, sizeof(key));
212 DEBUG(100,("lm owf password:"));
213 dump_data(100, lm_pwd, sizeof(lm_pwd));
215 DEBUG(100,("nt owf password:"));
216 dump_data(100, nt_pwd, sizeof(nt_pwd));
219 if (lm_interactive_pwd)
220 arcfour_crypt(lm_pwd, key, sizeof(lm_pwd));
222 if (nt_interactive_pwd)
223 arcfour_crypt(nt_pwd, key, sizeof(nt_pwd));
225 #ifdef DEBUG_PASSWORD
226 DEBUG(100,("decrypt of lm owf password:"));
227 dump_data(100, lm_pwd, sizeof(lm_pwd));
229 DEBUG(100,("decrypt of nt owf password:"));
230 dump_data(100, nt_pwd, sizeof(nt_pwd));
233 if (lm_interactive_pwd)
234 SMBOWFencrypt(lm_pwd, chal,
237 if (nt_interactive_pwd)
238 SMBOWFencrypt(nt_pwd, chal,
241 /* Password info paranoia */
247 DATA_BLOB local_lm_blob;
248 DATA_BLOB local_nt_blob;
250 DATA_BLOB lm_interactive_blob;
251 DATA_BLOB nt_interactive_blob;
253 if (lm_interactive_pwd) {
254 local_lm_blob = data_blob(local_lm_response,
255 sizeof(local_lm_response));
256 lm_interactive_blob = data_blob(lm_pwd,
261 if (nt_interactive_pwd) {
262 local_nt_blob = data_blob(local_nt_response,
263 sizeof(local_nt_response));
264 nt_interactive_blob = data_blob(nt_pwd,
269 nt_status = make_user_info_map(
271 smb_name, client_domain, workstation_name,
272 lm_interactive_pwd ? &local_lm_blob : NULL,
273 nt_interactive_pwd ? &local_nt_blob : NULL,
274 lm_interactive_pwd ? &lm_interactive_blob : NULL,
275 nt_interactive_pwd ? &nt_interactive_blob : NULL,
278 if (NT_STATUS_IS_OK(nt_status)) {
279 (*user_info)->logon_parameters = logon_parameters;
282 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
283 data_blob_free(&local_lm_blob);
284 data_blob_free(&local_nt_blob);
285 data_blob_free(&lm_interactive_blob);
286 data_blob_free(&nt_interactive_blob);
292 /****************************************************************************
293 Create an auth_usersupplied_data structure
294 ****************************************************************************/
296 bool make_user_info_for_reply(struct auth_usersupplied_info **user_info,
297 const char *smb_name,
298 const char *client_domain,
300 DATA_BLOB plaintext_password)
303 DATA_BLOB local_lm_blob;
304 DATA_BLOB local_nt_blob;
305 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
308 * Not encrypted - do so.
311 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
314 if (plaintext_password.data && plaintext_password.length) {
315 unsigned char local_lm_response[24];
317 #ifdef DEBUG_PASSWORD
318 DEBUG(10,("Unencrypted password (len %d):\n",
319 (int)plaintext_password.length));
320 dump_data(100, plaintext_password.data,
321 plaintext_password.length);
324 SMBencrypt( (const char *)plaintext_password.data,
325 (const uchar*)chal, local_lm_response);
326 local_lm_blob = data_blob(local_lm_response, 24);
328 /* We can't do an NT hash here, as the password needs to be
330 local_nt_blob = data_blob_null;
332 local_lm_blob = data_blob_null;
333 local_nt_blob = data_blob_null;
336 ret = make_user_info_map(
337 user_info, smb_name, client_domain,
338 get_remote_machine_name(),
339 local_lm_blob.data ? &local_lm_blob : NULL,
340 local_nt_blob.data ? &local_nt_blob : NULL,
342 plaintext_password.data && plaintext_password.length ? &plaintext_password : NULL,
345 data_blob_free(&local_lm_blob);
346 return NT_STATUS_IS_OK(ret) ? True : False;
349 /****************************************************************************
350 Create an auth_usersupplied_data structure
351 ****************************************************************************/
353 NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info,
354 const char *smb_name,
355 const char *client_domain,
356 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
358 return make_user_info_map(user_info, smb_name,
360 get_remote_machine_name(),
361 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
362 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
367 /****************************************************************************
368 Create a guest user_info blob, for anonymous authenticaion.
369 ****************************************************************************/
371 bool make_user_info_guest(struct auth_usersupplied_info **user_info)
375 nt_status = make_user_info(user_info,
384 return NT_STATUS_IS_OK(nt_status) ? True : False;
387 static NTSTATUS log_nt_token(NT_USER_TOKEN *token)
389 TALLOC_CTX *frame = talloc_stackframe();
394 if ((lp_log_nt_token_command() == NULL) ||
395 (strlen(lp_log_nt_token_command()) == 0)) {
400 group_sidstr = talloc_strdup(frame, "");
401 for (i=1; i<token->num_sids; i++) {
402 group_sidstr = talloc_asprintf(
403 frame, "%s %s", group_sidstr,
404 sid_string_talloc(frame, &token->user_sids[i]));
407 command = talloc_string_sub(
408 frame, lp_log_nt_token_command(),
409 "%s", sid_string_talloc(frame, &token->user_sids[0]));
410 command = talloc_string_sub(frame, command, "%t", group_sidstr);
412 if (command == NULL) {
414 return NT_STATUS_NO_MEMORY;
417 DEBUG(8, ("running command: [%s]\n", command));
418 if (smbrun(command, NULL) != 0) {
419 DEBUG(0, ("Could not log NT token\n"));
421 return NT_STATUS_ACCESS_DENIED;
429 * Create the token to use from server_info->info3 and
430 * server_info->sids (the info3/sam groups). Find the unix gids.
433 NTSTATUS create_local_token(struct auth_serversupplied_info *server_info)
437 struct dom_sid tmp_sid;
440 * If winbind is not around, we can not make much use of the SIDs the
441 * domain controller provided us with. Likewise if the user name was
442 * mapped to some local unix user.
445 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
446 (server_info->nss_token)) {
447 status = create_token_from_username(server_info,
448 server_info->unix_name,
450 &server_info->utok.uid,
451 &server_info->utok.gid,
452 &server_info->unix_name,
456 status = create_local_nt_token_from_info3(server_info,
463 if (!NT_STATUS_IS_OK(status)) {
467 /* Convert the SIDs to gids. */
469 server_info->utok.ngroups = 0;
470 server_info->utok.groups = NULL;
472 /* Start at index 1, where the groups start. */
474 for (i=1; i<server_info->ptok->num_sids; i++) {
476 struct dom_sid *sid = &server_info->ptok->user_sids[i];
478 if (!sid_to_gid(sid, &gid)) {
479 DEBUG(10, ("Could not convert SID %s to gid, "
480 "ignoring it\n", sid_string_dbg(sid)));
483 add_gid_to_array_unique(server_info, gid,
484 &server_info->utok.groups,
485 &server_info->utok.ngroups);
489 * Add the "Unix Group" SID for each gid to catch mapped groups
490 * and their Unix equivalent. This is to solve the backwards
491 * compatibility problem of 'valid users = +ntadmin' where
492 * ntadmin has been paired with "Domain Admins" in the group
493 * mapping table. Otherwise smb.conf would need to be changed
494 * to 'valid user = "Domain Admins"'. --jerry
496 * For consistency we also add the "Unix User" SID,
497 * so that the complete unix token is represented within
501 if (!uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid)) {
502 DEBUG(1,("create_local_token: Failed to create SID "
503 "for uid %u!\n", (unsigned int)server_info->utok.uid));
505 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
506 &server_info->ptok->user_sids,
507 &server_info->ptok->num_sids);
509 for ( i=0; i<server_info->utok.ngroups; i++ ) {
510 if (!gid_to_unix_groups_sid( server_info->utok.groups[i], &tmp_sid ) ) {
511 DEBUG(1,("create_local_token: Failed to create SID "
512 "for gid %u!\n", (unsigned int)server_info->utok.groups[i]));
515 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
516 &server_info->ptok->user_sids,
517 &server_info->ptok->num_sids);
520 debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
521 debug_unix_user_token(DBGC_AUTH, 10,
522 server_info->utok.uid,
523 server_info->utok.gid,
524 server_info->utok.ngroups,
525 server_info->utok.groups);
527 status = log_nt_token(server_info->ptok);
531 /***************************************************************************
532 Make (and fill) a server_info struct from a 'struct passwd' by conversion
534 ***************************************************************************/
536 NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
541 struct samu *sampass = NULL;
542 char *qualified_name = NULL;
543 TALLOC_CTX *mem_ctx = NULL;
544 struct dom_sid u_sid;
545 enum lsa_SidType type;
546 struct auth_serversupplied_info *result;
549 * The SID returned in server_info->sam_account is based
550 * on our SAM sid even though for a pure UNIX account this should
551 * not be the case as it doesn't really exist in the SAM db.
552 * This causes lookups on "[in]valid users" to fail as they
553 * will lookup this name as a "Unix User" SID to check against
554 * the user token. Fix this by adding the "Unix User"\unix_username
555 * SID to the sid array. The correct fix should probably be
556 * changing the server_info->sam_account user SID to be a
557 * S-1-22 Unix SID, but this might break old configs where
558 * plaintext passwords were used with no SAM backend.
561 mem_ctx = talloc_init("make_server_info_pw_tmp");
563 return NT_STATUS_NO_MEMORY;
566 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
567 unix_users_domain_name(),
569 if (!qualified_name) {
570 TALLOC_FREE(mem_ctx);
571 return NT_STATUS_NO_MEMORY;
574 if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
577 TALLOC_FREE(mem_ctx);
578 return NT_STATUS_NO_SUCH_USER;
581 TALLOC_FREE(mem_ctx);
583 if (type != SID_NAME_USER) {
584 return NT_STATUS_NO_SUCH_USER;
587 if ( !(sampass = samu_new( NULL )) ) {
588 return NT_STATUS_NO_MEMORY;
591 status = samu_set_unix( sampass, pwd );
592 if (!NT_STATUS_IS_OK(status)) {
596 /* In pathological cases the above call can set the account
597 * name to the DOMAIN\username form. Reset the account name
598 * using unix_username */
599 pdb_set_username(sampass, unix_username, PDB_SET);
601 /* set the user sid to be the calculated u_sid */
602 pdb_set_user_sid(sampass, &u_sid, PDB_SET);
604 result = make_server_info(NULL);
605 if (result == NULL) {
606 TALLOC_FREE(sampass);
607 return NT_STATUS_NO_MEMORY;
610 status = samu_to_SamInfo3(result, sampass, global_myname(),
611 &result->info3, &result->extra);
612 TALLOC_FREE(sampass);
613 if (!NT_STATUS_IS_OK(status)) {
614 DEBUG(10, ("Failed to convert samu to info3: %s\n",
620 result->unix_name = talloc_strdup(result, unix_username);
621 result->sanitized_username = sanitize_username(result, unix_username);
623 if ((result->unix_name == NULL)
624 || (result->sanitized_username == NULL)) {
626 return NT_STATUS_NO_MEMORY;
629 result->utok.uid = pwd->pw_uid;
630 result->utok.gid = pwd->pw_gid;
632 *server_info = result;
637 /***************************************************************************
638 Make (and fill) a user_info struct for a guest login.
639 This *must* succeed for smbd to start. If there is no mapping entry for
640 the guest gid, then create one.
641 ***************************************************************************/
643 static NTSTATUS make_new_server_info_guest(struct auth_serversupplied_info **server_info)
646 struct samu *sampass = NULL;
647 struct dom_sid guest_sid;
649 static const char zeros[16] = {0, };
652 if ( !(sampass = samu_new( NULL )) ) {
653 return NT_STATUS_NO_MEMORY;
656 sid_compose(&guest_sid, get_global_sam_sid(), DOMAIN_RID_GUEST);
659 ret = pdb_getsampwsid(sampass, &guest_sid);
663 TALLOC_FREE(sampass);
664 return NT_STATUS_NO_SUCH_USER;
667 status = make_server_info_sam(server_info, sampass);
668 if (!NT_STATUS_IS_OK(status)) {
669 TALLOC_FREE(sampass);
673 TALLOC_FREE(sampass);
675 (*server_info)->guest = True;
677 status = create_local_token(*server_info);
678 if (!NT_STATUS_IS_OK(status)) {
679 DEBUG(10, ("create_local_token failed: %s\n",
684 /* annoying, but the Guest really does have a session key, and it is
686 (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
687 (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
689 alpha_strcpy(tmp, (*server_info)->info3->base.account_name.string,
690 ". _-$", sizeof(tmp));
691 (*server_info)->sanitized_username = talloc_strdup(*server_info, tmp);
696 /***************************************************************************
697 Make (and fill) a user_info struct for a system user login.
698 This *must* succeed for smbd to start.
699 ***************************************************************************/
701 static NTSTATUS make_new_server_info_system(TALLOC_CTX *mem_ctx,
702 struct auth_serversupplied_info **server_info)
707 pwd = getpwuid_alloc(mem_ctx, sec_initial_uid());
709 return NT_STATUS_NO_MEMORY;
712 status = make_serverinfo_from_username(mem_ctx,
716 if (!NT_STATUS_IS_OK(status)) {
720 (*server_info)->system = true;
725 /****************************************************************************
726 Fake a auth_serversupplied_info just from a username
727 ****************************************************************************/
729 NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
730 const char *username,
732 struct auth_serversupplied_info **presult)
734 struct auth_serversupplied_info *result;
738 pwd = getpwnam_alloc(talloc_tos(), username);
740 return NT_STATUS_NO_SUCH_USER;
743 status = make_server_info_pw(&result, pwd->pw_name, pwd);
747 if (!NT_STATUS_IS_OK(status)) {
751 result->nss_token = true;
752 result->guest = is_guest;
754 status = create_local_token(result);
756 if (!NT_STATUS_IS_OK(status)) {
766 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
767 const struct auth_serversupplied_info *src)
769 struct auth_serversupplied_info *dst;
771 dst = make_server_info(mem_ctx);
776 dst->guest = src->guest;
777 dst->system = src->system;
778 dst->utok.uid = src->utok.uid;
779 dst->utok.gid = src->utok.gid;
780 dst->utok.ngroups = src->utok.ngroups;
781 if (src->utok.ngroups != 0) {
782 dst->utok.groups = (gid_t *)TALLOC_MEMDUP(
783 dst, src->utok.groups,
784 sizeof(gid_t)*dst->utok.ngroups);
786 dst->utok.groups = NULL;
790 dst->ptok = dup_nt_token(dst, src->ptok);
797 dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
798 src->user_session_key.length);
800 dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
801 src->lm_session_key.length);
803 dst->info3 = copy_netr_SamInfo3(dst, src->info3);
808 dst->extra = src->extra;
810 dst->pam_handle = NULL;
811 dst->unix_name = talloc_strdup(dst, src->unix_name);
812 if (!dst->unix_name) {
817 dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
818 if (!dst->sanitized_username) {
827 * Set a new session key. Used in the rpc server where we have to override the
828 * SMB level session key with SystemLibraryDTC
831 bool server_info_set_session_key(struct auth_serversupplied_info *info,
832 DATA_BLOB session_key)
834 TALLOC_FREE(info->user_session_key.data);
836 info->user_session_key = data_blob_talloc(
837 info, session_key.data, session_key.length);
839 return (info->user_session_key.data != NULL);
842 static struct auth_serversupplied_info *guest_info = NULL;
844 bool init_guest_info(void)
846 if (guest_info != NULL)
849 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
852 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
853 struct auth_serversupplied_info **server_info)
855 *server_info = copy_serverinfo(mem_ctx, guest_info);
856 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
859 static struct auth_serversupplied_info *system_info = NULL;
861 bool init_system_info(void)
863 if (system_info != NULL)
866 return NT_STATUS_IS_OK(make_new_server_info_system(talloc_autofree_context(), &system_info));
869 NTSTATUS make_server_info_system(TALLOC_CTX *mem_ctx,
870 struct auth_serversupplied_info **server_info)
872 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
873 *server_info = copy_serverinfo(mem_ctx, system_info);
874 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
877 bool copy_current_user(struct current_user *dst, struct current_user *src)
880 NT_USER_TOKEN *nt_token;
882 groups = (gid_t *)memdup(src->ut.groups,
883 sizeof(gid_t) * src->ut.ngroups);
884 if ((src->ut.ngroups != 0) && (groups == NULL)) {
888 nt_token = dup_nt_token(NULL, src->nt_user_token);
889 if (nt_token == NULL) {
894 dst->conn = src->conn;
895 dst->vuid = src->vuid;
896 dst->ut.uid = src->ut.uid;
897 dst->ut.gid = src->ut.gid;
898 dst->ut.ngroups = src->ut.ngroups;
899 dst->ut.groups = groups;
900 dst->nt_user_token = nt_token;
904 /***************************************************************************
905 Purely internal function for make_server_info_info3
906 ***************************************************************************/
908 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
909 const char *username, char **found_username,
911 bool *username_was_mapped)
913 fstring dom_user, lower_username;
914 fstring real_username;
915 struct passwd *passwd;
917 fstrcpy( lower_username, username );
918 strlower_m( lower_username );
920 fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(),
923 /* Get the passwd struct. Try to create the account if necessary. */
925 *username_was_mapped = map_username(dom_user);
927 passwd = smb_getpwnam( NULL, dom_user, real_username, True );
929 DEBUG(3, ("Failed to find authenticated user %s via "
930 "getpwnam(), denying access.\n", dom_user));
931 return NT_STATUS_NO_SUCH_USER;
936 /* This is pointless -- there is no suport for differing
937 unix and windows names. Make sure to always store the
938 one we actually looked up and succeeded. Have I mentioned
939 why I hate the 'winbind use default domain' parameter?
942 *found_username = talloc_strdup( mem_ctx, real_username );
947 /****************************************************************************
948 Wrapper to allow the getpwnam() call to strip the domain name and
949 try again in case a local UNIX user is already there. Also run through
950 the username if we fallback to the username only.
951 ****************************************************************************/
953 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
954 fstring save_username, bool create )
956 struct passwd *pw = NULL;
960 /* we only save a copy of the username it has been mangled
961 by winbindd use default domain */
963 save_username[0] = '\0';
965 /* don't call map_username() here since it has to be done higher
966 up the stack so we don't call it multiple times */
968 fstrcpy( username, domuser );
970 p = strchr_m( username, *lp_winbind_separator() );
972 /* code for a DOMAIN\user string */
975 fstring strip_username;
977 pw = Get_Pwnam_alloc( mem_ctx, domuser );
979 /* make sure we get the case of the username correct */
980 /* work around 'winbind use default domain = yes' */
982 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
985 /* split the domain and username into 2 strings */
989 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
992 fstrcpy( save_username, pw->pw_name );
998 /* setup for lookup of just the username */
999 /* remember that p and username are overlapping memory */
1002 fstrcpy( strip_username, p );
1003 fstrcpy( username, strip_username );
1006 /* just lookup a plain username */
1008 pw = Get_Pwnam_alloc(mem_ctx, username);
1010 /* Create local user if requested but only if winbindd
1011 is not running. We need to protect against cases
1012 where winbindd is failing and then prematurely
1013 creating users in /etc/passwd */
1015 if ( !pw && create && !winbind_ping() ) {
1016 /* Don't add a machine account. */
1017 if (username[strlen(username)-1] == '$')
1020 _smb_create_user(NULL, username, NULL);
1021 pw = Get_Pwnam_alloc(mem_ctx, username);
1024 /* one last check for a valid passwd struct */
1027 fstrcpy( save_username, pw->pw_name );
1032 /***************************************************************************
1033 Make a server_info struct from the info3 returned by a domain logon
1034 ***************************************************************************/
1036 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1037 const char *sent_nt_username,
1039 struct auth_serversupplied_info **server_info,
1040 struct netr_SamInfo3 *info3)
1042 static const char zeros[16] = {0, };
1044 NTSTATUS nt_status = NT_STATUS_OK;
1045 char *found_username = NULL;
1046 const char *nt_domain;
1047 const char *nt_username;
1048 bool username_was_mapped;
1050 struct auth_serversupplied_info *result;
1051 struct dom_sid *group_sid;
1052 struct netr_SamInfo3 *i3;
1055 Here is where we should check the list of
1056 trusted domains, and verify that the SID
1060 nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1062 /* If the server didn't give us one, just use the one we sent
1064 nt_username = sent_nt_username;
1067 nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1069 /* If the server didn't give us one, just use the one we sent
1074 /* If getpwnam() fails try the add user script (2.2.x behavior).
1076 We use the _unmapped_ username here in an attempt to provide
1077 consistent username mapping behavior between kerberos and NTLM[SSP]
1078 authentication in domain mode security. I.E. Username mapping
1079 should be applied to the fully qualified username
1080 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1081 called map_username() unnecessarily in make_user_info_map() but
1082 that is how the current code is designed. Making the change here
1083 is the least disruptive place. -- jerry */
1085 /* this call will try to create the user if necessary */
1087 nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
1088 &found_username, &pwd,
1089 &username_was_mapped);
1091 if (!NT_STATUS_IS_OK(nt_status)) {
1095 result = make_server_info(NULL);
1096 if (result == NULL) {
1097 DEBUG(4, ("make_server_info failed!\n"));
1098 return NT_STATUS_NO_MEMORY;
1101 result->unix_name = talloc_strdup(result, found_username);
1103 result->sanitized_username = sanitize_username(result,
1105 if (result->sanitized_username == NULL) {
1106 TALLOC_FREE(result);
1107 return NT_STATUS_NO_MEMORY;
1110 /* copy in the info3 */
1111 result->info3 = i3 = copy_netr_SamInfo3(result, info3);
1112 if (result->info3 == NULL) {
1113 TALLOC_FREE(result);
1114 return NT_STATUS_NO_MEMORY;
1117 /* Fill in the unix info we found on the way */
1118 result->utok.uid = pwd->pw_uid;
1119 result->utok.gid = pwd->pw_gid;
1121 /* We can't just trust that the primary group sid sent us is something
1122 * we can really use. Obtain the useable sid, and store the original
1123 * one as an additional group if it had to be replaced */
1124 nt_status = get_primary_group_sid(mem_ctx, found_username,
1126 if (!NT_STATUS_IS_OK(nt_status)) {
1127 TALLOC_FREE(result);
1131 /* store and check if it is the same we got originally */
1132 sid_peek_rid(group_sid, &i3->base.primary_gid);
1133 if (i3->base.primary_gid != info3->base.primary_gid) {
1134 uint32_t n = i3->base.groups.count;
1135 /* not the same, store the original as an additional group */
1136 i3->base.groups.rids =
1137 talloc_realloc(i3, i3->base.groups.rids,
1138 struct samr_RidWithAttribute, n + 1);
1139 if (i3->base.groups.rids == NULL) {
1140 TALLOC_FREE(result);
1141 return NT_STATUS_NO_MEMORY;
1143 i3->base.groups.rids[n].rid = info3->base.primary_gid;
1144 i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED;
1145 i3->base.groups.count = n + 1;
1148 /* ensure we are never given NULL session keys */
1150 if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1151 result->user_session_key = data_blob_null;
1153 result->user_session_key = data_blob_talloc(
1154 result, info3->base.key.key,
1155 sizeof(info3->base.key.key));
1158 if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1159 result->lm_session_key = data_blob_null;
1161 result->lm_session_key = data_blob_talloc(
1162 result, info3->base.LMSessKey.key,
1163 sizeof(info3->base.LMSessKey.key));
1166 result->nss_token |= username_was_mapped;
1168 *server_info = result;
1170 return NT_STATUS_OK;
1173 /*****************************************************************************
1174 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1175 ******************************************************************************/
1177 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1178 const char *sent_nt_username,
1180 const struct wbcAuthUserInfo *info,
1181 struct auth_serversupplied_info **server_info)
1183 struct netr_SamInfo3 *info3;
1185 info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
1187 return NT_STATUS_NO_MEMORY;
1190 return make_server_info_info3(mem_ctx,
1191 sent_nt_username, domain,
1192 server_info, info3);
1196 * Verify whether or not given domain is trusted.
1198 * @param domain_name name of the domain to be verified
1199 * @return true if domain is one of the trusted ones or
1200 * false if otherwise
1203 bool is_trusted_domain(const char* dom_name)
1205 struct dom_sid trustdom_sid;
1208 /* no trusted domains for a standalone server */
1210 if ( lp_server_role() == ROLE_STANDALONE )
1213 if (dom_name == NULL || dom_name[0] == '\0') {
1217 if (strequal(dom_name, get_global_sam_name())) {
1221 /* if we are a DC, then check for a direct trust relationships */
1225 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1226 "[%s]\n", dom_name ));
1227 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1235 /* If winbind is around, ask it */
1237 result = wb_is_trusted_domain(dom_name);
1239 if (result == WBC_ERR_SUCCESS) {
1243 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1244 /* winbind could not find the domain */
1248 /* The only other possible result is that winbind is not up
1249 and running. We need to update the trustdom_cache
1252 update_trustdom_cache();
1255 /* now the trustdom cache should be available a DC could still
1256 * have a transitive trust so fall back to the cache of trusted
1257 * domains (like a domain member would use */
1259 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {