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 : NULL,
362 nt_resp.data ? &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 if (!NT_STATUS_IS_OK(status)) {
613 DEBUG(10, ("Failed to convert samu to info3: %s\n",
615 TALLOC_FREE(sampass);
620 TALLOC_FREE(sampass);
622 result->unix_name = talloc_strdup(result, unix_username);
623 result->sanitized_username = sanitize_username(result, unix_username);
625 if ((result->unix_name == NULL)
626 || (result->sanitized_username == NULL)) {
628 return NT_STATUS_NO_MEMORY;
631 result->utok.uid = pwd->pw_uid;
632 result->utok.gid = pwd->pw_gid;
634 *server_info = result;
639 /***************************************************************************
640 Make (and fill) a user_info struct for a guest login.
641 This *must* succeed for smbd to start. If there is no mapping entry for
642 the guest gid, then create one.
643 ***************************************************************************/
645 static NTSTATUS make_new_server_info_guest(struct auth_serversupplied_info **server_info)
648 struct samu *sampass = NULL;
649 struct dom_sid guest_sid;
651 static const char zeros[16] = {0, };
654 if ( !(sampass = samu_new( NULL )) ) {
655 return NT_STATUS_NO_MEMORY;
658 sid_compose(&guest_sid, get_global_sam_sid(), DOMAIN_RID_GUEST);
661 ret = pdb_getsampwsid(sampass, &guest_sid);
665 TALLOC_FREE(sampass);
666 return NT_STATUS_NO_SUCH_USER;
669 status = make_server_info_sam(server_info, sampass);
670 if (!NT_STATUS_IS_OK(status)) {
671 TALLOC_FREE(sampass);
675 TALLOC_FREE(sampass);
677 (*server_info)->guest = True;
679 status = create_local_token(*server_info);
680 if (!NT_STATUS_IS_OK(status)) {
681 DEBUG(10, ("create_local_token failed: %s\n",
686 /* annoying, but the Guest really does have a session key, and it is
688 (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
689 (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
691 alpha_strcpy(tmp, (*server_info)->info3->base.account_name.string,
692 ". _-$", sizeof(tmp));
693 (*server_info)->sanitized_username = talloc_strdup(*server_info, tmp);
698 /***************************************************************************
699 Make (and fill) a user_info struct for a system user login.
700 This *must* succeed for smbd to start.
701 ***************************************************************************/
703 static NTSTATUS make_new_server_info_system(TALLOC_CTX *mem_ctx,
704 struct auth_serversupplied_info **server_info)
709 pwd = getpwuid_alloc(mem_ctx, sec_initial_uid());
711 return NT_STATUS_NO_MEMORY;
714 status = make_serverinfo_from_username(mem_ctx,
718 if (!NT_STATUS_IS_OK(status)) {
722 (*server_info)->system = true;
727 /****************************************************************************
728 Fake a auth_serversupplied_info just from a username
729 ****************************************************************************/
731 NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
732 const char *username,
734 struct auth_serversupplied_info **presult)
736 struct auth_serversupplied_info *result;
740 pwd = getpwnam_alloc(talloc_tos(), username);
742 return NT_STATUS_NO_SUCH_USER;
745 status = make_server_info_pw(&result, pwd->pw_name, pwd);
749 if (!NT_STATUS_IS_OK(status)) {
753 result->nss_token = true;
754 result->guest = is_guest;
756 status = create_local_token(result);
758 if (!NT_STATUS_IS_OK(status)) {
768 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
769 const struct auth_serversupplied_info *src)
771 struct auth_serversupplied_info *dst;
773 dst = make_server_info(mem_ctx);
778 dst->guest = src->guest;
779 dst->system = src->system;
780 dst->utok.uid = src->utok.uid;
781 dst->utok.gid = src->utok.gid;
782 dst->utok.ngroups = src->utok.ngroups;
783 if (src->utok.ngroups != 0) {
784 dst->utok.groups = (gid_t *)TALLOC_MEMDUP(
785 dst, src->utok.groups,
786 sizeof(gid_t)*dst->utok.ngroups);
788 dst->utok.groups = NULL;
792 dst->ptok = dup_nt_token(dst, src->ptok);
799 dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
800 src->user_session_key.length);
802 dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
803 src->lm_session_key.length);
805 dst->info3 = copy_netr_SamInfo3(dst, src->info3);
810 dst->extra = src->extra;
812 dst->pam_handle = NULL;
813 dst->unix_name = talloc_strdup(dst, src->unix_name);
814 if (!dst->unix_name) {
819 dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
820 if (!dst->sanitized_username) {
829 * Set a new session key. Used in the rpc server where we have to override the
830 * SMB level session key with SystemLibraryDTC
833 bool server_info_set_session_key(struct auth_serversupplied_info *info,
834 DATA_BLOB session_key)
836 TALLOC_FREE(info->user_session_key.data);
838 info->user_session_key = data_blob_talloc(
839 info, session_key.data, session_key.length);
841 return (info->user_session_key.data != NULL);
844 static struct auth_serversupplied_info *guest_info = NULL;
846 bool init_guest_info(void)
848 if (guest_info != NULL)
851 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
854 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
855 struct auth_serversupplied_info **server_info)
857 *server_info = copy_serverinfo(mem_ctx, guest_info);
858 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
861 static struct auth_serversupplied_info *system_info = NULL;
863 bool init_system_info(void)
865 if (system_info != NULL)
868 return NT_STATUS_IS_OK(make_new_server_info_system(talloc_autofree_context(), &system_info));
871 NTSTATUS make_server_info_system(TALLOC_CTX *mem_ctx,
872 struct auth_serversupplied_info **server_info)
874 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
875 *server_info = copy_serverinfo(mem_ctx, system_info);
876 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
879 bool copy_current_user(struct current_user *dst, struct current_user *src)
882 NT_USER_TOKEN *nt_token;
884 groups = (gid_t *)memdup(src->ut.groups,
885 sizeof(gid_t) * src->ut.ngroups);
886 if ((src->ut.ngroups != 0) && (groups == NULL)) {
890 nt_token = dup_nt_token(NULL, src->nt_user_token);
891 if (nt_token == NULL) {
896 dst->conn = src->conn;
897 dst->vuid = src->vuid;
898 dst->ut.uid = src->ut.uid;
899 dst->ut.gid = src->ut.gid;
900 dst->ut.ngroups = src->ut.ngroups;
901 dst->ut.groups = groups;
902 dst->nt_user_token = nt_token;
906 /***************************************************************************
907 Purely internal function for make_server_info_info3
908 ***************************************************************************/
910 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
911 const char *username, char **found_username,
912 uid_t *uid, gid_t *gid,
913 bool *username_was_mapped)
915 fstring dom_user, lower_username;
916 fstring real_username;
917 struct passwd *passwd;
919 fstrcpy( lower_username, username );
920 strlower_m( lower_username );
922 fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(),
925 /* Get the passwd struct. Try to create the account if necessary. */
927 *username_was_mapped = map_username(dom_user);
929 passwd = smb_getpwnam( NULL, dom_user, real_username, True );
931 DEBUG(3, ("Failed to find authenticated user %s via "
932 "getpwnam(), denying access.\n", dom_user));
933 return NT_STATUS_NO_SUCH_USER;
936 *uid = passwd->pw_uid;
937 *gid = passwd->pw_gid;
939 /* This is pointless -- there is no suport for differing
940 unix and windows names. Make sure to always store the
941 one we actually looked up and succeeded. Have I mentioned
942 why I hate the 'winbind use default domain' parameter?
945 *found_username = talloc_strdup( mem_ctx, real_username );
952 /****************************************************************************
953 Wrapper to allow the getpwnam() call to strip the domain name and
954 try again in case a local UNIX user is already there. Also run through
955 the username if we fallback to the username only.
956 ****************************************************************************/
958 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
959 fstring save_username, bool create )
961 struct passwd *pw = NULL;
965 /* we only save a copy of the username it has been mangled
966 by winbindd use default domain */
968 save_username[0] = '\0';
970 /* don't call map_username() here since it has to be done higher
971 up the stack so we don't call it multiple times */
973 fstrcpy( username, domuser );
975 p = strchr_m( username, *lp_winbind_separator() );
977 /* code for a DOMAIN\user string */
980 fstring strip_username;
982 pw = Get_Pwnam_alloc( mem_ctx, domuser );
984 /* make sure we get the case of the username correct */
985 /* work around 'winbind use default domain = yes' */
987 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
990 /* split the domain and username into 2 strings */
994 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
997 fstrcpy( save_username, pw->pw_name );
1003 /* setup for lookup of just the username */
1004 /* remember that p and username are overlapping memory */
1007 fstrcpy( strip_username, p );
1008 fstrcpy( username, strip_username );
1011 /* just lookup a plain username */
1013 pw = Get_Pwnam_alloc(mem_ctx, username);
1015 /* Create local user if requested but only if winbindd
1016 is not running. We need to protect against cases
1017 where winbindd is failing and then prematurely
1018 creating users in /etc/passwd */
1020 if ( !pw && create && !winbind_ping() ) {
1021 /* Don't add a machine account. */
1022 if (username[strlen(username)-1] == '$')
1025 _smb_create_user(NULL, username, NULL);
1026 pw = Get_Pwnam_alloc(mem_ctx, username);
1029 /* one last check for a valid passwd struct */
1032 fstrcpy( save_username, pw->pw_name );
1037 /***************************************************************************
1038 Make a server_info struct from the info3 returned by a domain logon
1039 ***************************************************************************/
1041 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1042 const char *sent_nt_username,
1044 struct auth_serversupplied_info **server_info,
1045 struct netr_SamInfo3 *info3)
1047 static const char zeros[16] = {0, };
1049 NTSTATUS nt_status = NT_STATUS_OK;
1050 char *found_username = NULL;
1051 const char *nt_domain;
1052 const char *nt_username;
1053 struct dom_sid user_sid;
1054 struct dom_sid group_sid;
1055 bool username_was_mapped;
1057 uid_t uid = (uid_t)-1;
1058 gid_t gid = (gid_t)-1;
1060 struct auth_serversupplied_info *result;
1063 Here is where we should check the list of
1064 trusted domains, and verify that the SID
1068 if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
1069 return NT_STATUS_INVALID_PARAMETER;
1072 if (!sid_compose(&group_sid, info3->base.domain_sid,
1073 info3->base.primary_gid)) {
1074 return NT_STATUS_INVALID_PARAMETER;
1077 nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1079 /* If the server didn't give us one, just use the one we sent
1081 nt_username = sent_nt_username;
1084 nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1086 /* If the server didn't give us one, just use the one we sent
1091 /* If getpwnam() fails try the add user script (2.2.x behavior).
1093 We use the _unmapped_ username here in an attempt to provide
1094 consistent username mapping behavior between kerberos and NTLM[SSP]
1095 authentication in domain mode security. I.E. Username mapping
1096 should be applied to the fully qualified username
1097 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1098 called map_username() unnecessarily in make_user_info_map() but
1099 that is how the current code is designed. Making the change here
1100 is the least disruptive place. -- jerry */
1102 /* this call will try to create the user if necessary */
1104 nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
1105 &found_username, &uid, &gid,
1106 &username_was_mapped);
1108 if (!NT_STATUS_IS_OK(nt_status)) {
1112 result = make_server_info(NULL);
1113 if (result == NULL) {
1114 DEBUG(4, ("make_server_info failed!\n"));
1115 return NT_STATUS_NO_MEMORY;
1118 result->unix_name = talloc_strdup(result, found_username);
1120 result->sanitized_username = sanitize_username(result,
1122 if (result->sanitized_username == NULL) {
1123 TALLOC_FREE(result);
1124 return NT_STATUS_NO_MEMORY;
1127 /* copy in the info3 */
1128 result->info3 = copy_netr_SamInfo3(result, info3);
1130 /* Fill in the unix info we found on the way */
1132 result->utok.uid = uid;
1133 result->utok.gid = gid;
1135 /* ensure we are never given NULL session keys */
1137 if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1138 result->user_session_key = data_blob_null;
1140 result->user_session_key = data_blob_talloc(
1141 result, info3->base.key.key,
1142 sizeof(info3->base.key.key));
1145 if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1146 result->lm_session_key = data_blob_null;
1148 result->lm_session_key = data_blob_talloc(
1149 result, info3->base.LMSessKey.key,
1150 sizeof(info3->base.LMSessKey.key));
1153 result->nss_token |= username_was_mapped;
1155 *server_info = result;
1157 return NT_STATUS_OK;
1160 /*****************************************************************************
1161 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1162 ******************************************************************************/
1164 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1165 const char *sent_nt_username,
1167 const struct wbcAuthUserInfo *info,
1168 struct auth_serversupplied_info **server_info)
1170 struct netr_SamInfo3 *info3;
1172 info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
1174 return NT_STATUS_NO_MEMORY;
1177 return make_server_info_info3(mem_ctx,
1178 sent_nt_username, domain,
1179 server_info, info3);
1183 * Verify whether or not given domain is trusted.
1185 * @param domain_name name of the domain to be verified
1186 * @return true if domain is one of the trusted ones or
1187 * false if otherwise
1190 bool is_trusted_domain(const char* dom_name)
1192 struct dom_sid trustdom_sid;
1195 /* no trusted domains for a standalone server */
1197 if ( lp_server_role() == ROLE_STANDALONE )
1200 if (dom_name == NULL || dom_name[0] == '\0') {
1204 if (strequal(dom_name, get_global_sam_name())) {
1208 /* if we are a DC, then check for a direct trust relationships */
1212 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1213 "[%s]\n", dom_name ));
1214 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1222 /* If winbind is around, ask it */
1224 result = wb_is_trusted_domain(dom_name);
1226 if (result == WBC_ERR_SUCCESS) {
1230 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1231 /* winbind could not find the domain */
1235 /* The only other possible result is that winbind is not up
1236 and running. We need to update the trustdom_cache
1239 update_trustdom_cache();
1242 /* now the trustdom cache should be available a DC could still
1243 * have a transitive trust so fall back to the cache of trusted
1244 * domains (like a domain member would use */
1246 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {