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/>.
26 #include "smbd/globals.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../lib/crypto/arcfour.h"
29 #include "rpc_client/init_lsa.h"
30 #include "../libcli/security/security.h"
31 #include "../lib/util/util_pw.h"
32 #include "lib/winbind_util.h"
36 #define DBGC_CLASS DBGC_AUTH
38 /****************************************************************************
39 Create a UNIX user on demand.
40 ****************************************************************************/
42 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
44 TALLOC_CTX *ctx = talloc_tos();
48 add_script = talloc_strdup(ctx, lp_adduser_script());
49 if (!add_script || !*add_script) {
52 add_script = talloc_all_string_sub(ctx,
60 add_script = talloc_all_string_sub(ctx,
69 add_script = talloc_all_string_sub(ctx,
77 ret = smbrun(add_script,NULL);
80 ("smb_create_user: Running the command `%s' gave %d\n",
85 /****************************************************************************
86 Create an auth_usersupplied_data structure after appropriate mapping.
87 ****************************************************************************/
89 NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info,
91 const char *client_domain,
92 const char *workstation_name,
95 const struct samr_Password *lm_interactive_pwd,
96 const struct samr_Password *nt_interactive_pwd,
97 const char *plaintext,
98 enum auth_password_state password_state)
103 char *internal_username = NULL;
105 was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
106 if (!internal_username) {
107 return NT_STATUS_NO_MEMORY;
110 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
111 client_domain, smb_name, workstation_name));
113 domain = client_domain;
115 /* If you connect to a Windows domain member using a bogus domain name,
116 * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if
117 * the Windows box is a DC the name will become DOMAIN\user and be
118 * authenticated against AD, if the Windows box is a member server but
119 * not a DC the name will become WORKSTATION\user. A standalone
120 * non-domain member box will also map to WORKSTATION\user.
121 * This also deals with the client passing in a "" domain */
123 if (!is_trusted_domain(domain) &&
124 !strequal(domain, my_sam_name()))
126 if (lp_map_untrusted_to_domain())
127 domain = my_sam_name();
129 domain = get_global_sam_name();
130 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
131 "workstation [%s]\n",
132 client_domain, domain, smb_name, workstation_name));
135 /* We know that the given domain is trusted (and we are allowing them),
136 * it is our global SAM name, or for legacy behavior it is our
137 * primary domain name */
139 result = make_user_info(user_info, smb_name, internal_username,
140 client_domain, domain, workstation_name,
142 lm_interactive_pwd, nt_interactive_pwd,
143 plaintext, password_state);
144 if (NT_STATUS_IS_OK(result)) {
145 /* We have tried mapping */
146 (*user_info)->mapped_state = True;
147 /* did we actually map the user to a different name? */
148 (*user_info)->was_mapped = was_mapped;
153 /****************************************************************************
154 Create an auth_usersupplied_data, making the DATA_BLOBs here.
155 Decrypt and encrypt the passwords.
156 ****************************************************************************/
158 bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info,
159 const char *smb_name,
160 const char *client_domain,
161 const char *workstation_name,
162 uint32 logon_parameters,
163 const uchar *lm_network_pwd,
165 const uchar *nt_network_pwd,
170 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
171 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
173 status = make_user_info_map(user_info,
174 smb_name, client_domain,
176 lm_pwd_len ? &lm_blob : NULL,
177 nt_pwd_len ? &nt_blob : NULL,
179 AUTH_PASSWORD_RESPONSE);
181 if (NT_STATUS_IS_OK(status)) {
182 (*user_info)->logon_parameters = logon_parameters;
184 ret = NT_STATUS_IS_OK(status) ? True : False;
186 data_blob_free(&lm_blob);
187 data_blob_free(&nt_blob);
191 /****************************************************************************
192 Create an auth_usersupplied_data, making the DATA_BLOBs here.
193 Decrypt and encrypt the passwords.
194 ****************************************************************************/
196 bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
197 const char *smb_name,
198 const char *client_domain,
199 const char *workstation_name,
200 uint32 logon_parameters,
202 const uchar lm_interactive_pwd[16],
203 const uchar nt_interactive_pwd[16],
204 const uchar *dc_sess_key)
206 struct samr_Password lm_pwd;
207 struct samr_Password nt_pwd;
208 unsigned char local_lm_response[24];
209 unsigned char local_nt_response[24];
210 unsigned char key[16];
212 memcpy(key, dc_sess_key, 16);
214 if (lm_interactive_pwd)
215 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
217 if (nt_interactive_pwd)
218 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
220 #ifdef DEBUG_PASSWORD
222 dump_data(100, key, sizeof(key));
224 DEBUG(100,("lm owf password:"));
225 dump_data(100, lm_pwd.hash, sizeof(lm_pwd.hash));
227 DEBUG(100,("nt owf password:"));
228 dump_data(100, nt_pwd.hash, sizeof(nt_pwd.hash));
231 if (lm_interactive_pwd)
232 arcfour_crypt(lm_pwd.hash, key, sizeof(lm_pwd.hash));
234 if (nt_interactive_pwd)
235 arcfour_crypt(nt_pwd.hash, key, sizeof(nt_pwd.hash));
237 #ifdef DEBUG_PASSWORD
238 DEBUG(100,("decrypt of lm owf password:"));
239 dump_data(100, lm_pwd.hash, sizeof(lm_pwd));
241 DEBUG(100,("decrypt of nt owf password:"));
242 dump_data(100, nt_pwd.hash, sizeof(nt_pwd));
245 if (lm_interactive_pwd)
246 SMBOWFencrypt(lm_pwd.hash, chal,
249 if (nt_interactive_pwd)
250 SMBOWFencrypt(nt_pwd.hash, chal,
253 /* Password info paranoia */
259 DATA_BLOB local_lm_blob;
260 DATA_BLOB local_nt_blob;
262 if (lm_interactive_pwd) {
263 local_lm_blob = data_blob(local_lm_response,
264 sizeof(local_lm_response));
267 if (nt_interactive_pwd) {
268 local_nt_blob = data_blob(local_nt_response,
269 sizeof(local_nt_response));
272 nt_status = make_user_info_map(
274 smb_name, client_domain, workstation_name,
275 lm_interactive_pwd ? &local_lm_blob : NULL,
276 nt_interactive_pwd ? &local_nt_blob : NULL,
277 lm_interactive_pwd ? &lm_pwd : NULL,
278 nt_interactive_pwd ? &nt_pwd : NULL,
279 NULL, AUTH_PASSWORD_HASH);
281 if (NT_STATUS_IS_OK(nt_status)) {
282 (*user_info)->logon_parameters = logon_parameters;
285 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
286 data_blob_free(&local_lm_blob);
287 data_blob_free(&local_nt_blob);
293 /****************************************************************************
294 Create an auth_usersupplied_data structure
295 ****************************************************************************/
297 bool make_user_info_for_reply(struct auth_usersupplied_info **user_info,
298 const char *smb_name,
299 const char *client_domain,
301 DATA_BLOB plaintext_password)
304 DATA_BLOB local_lm_blob;
305 DATA_BLOB local_nt_blob;
306 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
307 char *plaintext_password_string;
309 * Not encrypted - do so.
312 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 plaintext_password_string = talloc_strndup(talloc_tos(),
337 (const char *)plaintext_password.data,
338 plaintext_password.length);
339 if (!plaintext_password_string) {
343 ret = make_user_info_map(
344 user_info, smb_name, client_domain,
345 get_remote_machine_name(),
346 local_lm_blob.data ? &local_lm_blob : NULL,
347 local_nt_blob.data ? &local_nt_blob : NULL,
349 plaintext_password_string,
350 AUTH_PASSWORD_PLAIN);
352 if (plaintext_password_string) {
353 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
354 talloc_free(plaintext_password_string);
357 data_blob_free(&local_lm_blob);
358 return NT_STATUS_IS_OK(ret) ? True : False;
361 /****************************************************************************
362 Create an auth_usersupplied_data structure
363 ****************************************************************************/
365 NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info,
366 const char *smb_name,
367 const char *client_domain,
368 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
370 return make_user_info_map(user_info, smb_name,
372 get_remote_machine_name(),
373 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
374 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
376 AUTH_PASSWORD_RESPONSE);
379 /****************************************************************************
380 Create a guest user_info blob, for anonymous authenticaion.
381 ****************************************************************************/
383 bool make_user_info_guest(struct auth_usersupplied_info **user_info)
387 nt_status = make_user_info(user_info,
394 AUTH_PASSWORD_RESPONSE);
396 return NT_STATUS_IS_OK(nt_status) ? True : False;
399 static NTSTATUS log_nt_token(struct security_token *token)
401 TALLOC_CTX *frame = talloc_stackframe();
406 if ((lp_log_nt_token_command() == NULL) ||
407 (strlen(lp_log_nt_token_command()) == 0)) {
412 group_sidstr = talloc_strdup(frame, "");
413 for (i=1; i<token->num_sids; i++) {
414 group_sidstr = talloc_asprintf(
415 frame, "%s %s", group_sidstr,
416 sid_string_talloc(frame, &token->sids[i]));
419 command = talloc_string_sub(
420 frame, lp_log_nt_token_command(),
421 "%s", sid_string_talloc(frame, &token->sids[0]));
422 command = talloc_string_sub(frame, command, "%t", group_sidstr);
424 if (command == NULL) {
426 return NT_STATUS_NO_MEMORY;
429 DEBUG(8, ("running command: [%s]\n", command));
430 if (smbrun(command, NULL) != 0) {
431 DEBUG(0, ("Could not log NT token\n"));
433 return NT_STATUS_ACCESS_DENIED;
441 * Create the token to use from server_info->info3 and
442 * server_info->sids (the info3/sam groups). Find the unix gids.
445 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
446 const struct auth_serversupplied_info *server_info,
447 DATA_BLOB *session_key,
448 struct auth_serversupplied_info **session_info_out)
452 struct dom_sid tmp_sid;
453 struct auth_serversupplied_info *session_info;
455 /* Ensure we can't possible take a code path leading to a
458 return NT_STATUS_LOGON_FAILURE;
461 session_info = copy_serverinfo(mem_ctx, server_info);
464 return NT_STATUS_NO_MEMORY;
468 data_blob_free(&session_info->session_key);
469 session_info->session_key = data_blob_talloc(session_info,
471 session_key->length);
472 if (!session_info->session_key.data && session_key->length) {
473 return NT_STATUS_NO_MEMORY;
477 if (session_info->security_token) {
478 /* Just copy the token, it has already been finalised
479 * (nasty hack to support a cached guest session_info,
480 * and a possible strategy for auth_samba4 to pass in
481 * a finalised session) */
482 *session_info_out = session_info;
487 * If winbind is not around, we can not make much use of the SIDs the
488 * domain controller provided us with. Likewise if the user name was
489 * mapped to some local unix user.
492 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
493 (session_info->nss_token)) {
494 status = create_token_from_username(session_info,
495 session_info->unix_name,
497 &session_info->utok.uid,
498 &session_info->utok.gid,
499 &session_info->unix_name,
500 &session_info->security_token);
503 status = create_local_nt_token_from_info3(session_info,
506 &session_info->extra,
507 &session_info->security_token);
510 if (!NT_STATUS_IS_OK(status)) {
514 /* Convert the SIDs to gids. */
516 session_info->utok.ngroups = 0;
517 session_info->utok.groups = NULL;
519 /* Start at index 1, where the groups start. */
521 for (i=1; i<session_info->security_token->num_sids; i++) {
523 struct dom_sid *sid = &session_info->security_token->sids[i];
525 if (!sid_to_gid(sid, &gid)) {
526 DEBUG(10, ("Could not convert SID %s to gid, "
527 "ignoring it\n", sid_string_dbg(sid)));
530 if (!add_gid_to_array_unique(session_info, gid,
531 &session_info->utok.groups,
532 &session_info->utok.ngroups)) {
533 return NT_STATUS_NO_MEMORY;
538 * Add the "Unix Group" SID for each gid to catch mapped groups
539 * and their Unix equivalent. This is to solve the backwards
540 * compatibility problem of 'valid users = +ntadmin' where
541 * ntadmin has been paired with "Domain Admins" in the group
542 * mapping table. Otherwise smb.conf would need to be changed
543 * to 'valid user = "Domain Admins"'. --jerry
545 * For consistency we also add the "Unix User" SID,
546 * so that the complete unix token is represented within
550 uid_to_unix_users_sid(session_info->utok.uid, &tmp_sid);
552 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
553 &session_info->security_token->sids,
554 &session_info->security_token->num_sids);
556 for ( i=0; i<session_info->utok.ngroups; i++ ) {
557 gid_to_unix_groups_sid(session_info->utok.groups[i], &tmp_sid);
558 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
559 &session_info->security_token->sids,
560 &session_info->security_token->num_sids);
563 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
564 debug_unix_user_token(DBGC_AUTH, 10,
565 session_info->utok.uid,
566 session_info->utok.gid,
567 session_info->utok.ngroups,
568 session_info->utok.groups);
570 status = log_nt_token(session_info->security_token);
571 if (!NT_STATUS_IS_OK(status)) {
575 *session_info_out = session_info;
579 /***************************************************************************
580 Make (and fill) a server_info struct from a 'struct passwd' by conversion
582 ***************************************************************************/
584 NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
589 struct samu *sampass = NULL;
590 char *qualified_name = NULL;
591 TALLOC_CTX *mem_ctx = NULL;
592 struct dom_sid u_sid;
593 enum lsa_SidType type;
594 struct auth_serversupplied_info *result;
597 * The SID returned in server_info->sam_account is based
598 * on our SAM sid even though for a pure UNIX account this should
599 * not be the case as it doesn't really exist in the SAM db.
600 * This causes lookups on "[in]valid users" to fail as they
601 * will lookup this name as a "Unix User" SID to check against
602 * the user token. Fix this by adding the "Unix User"\unix_username
603 * SID to the sid array. The correct fix should probably be
604 * changing the server_info->sam_account user SID to be a
605 * S-1-22 Unix SID, but this might break old configs where
606 * plaintext passwords were used with no SAM backend.
609 mem_ctx = talloc_init("make_server_info_pw_tmp");
611 return NT_STATUS_NO_MEMORY;
614 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
615 unix_users_domain_name(),
617 if (!qualified_name) {
618 TALLOC_FREE(mem_ctx);
619 return NT_STATUS_NO_MEMORY;
622 if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
625 TALLOC_FREE(mem_ctx);
626 return NT_STATUS_NO_SUCH_USER;
629 TALLOC_FREE(mem_ctx);
631 if (type != SID_NAME_USER) {
632 return NT_STATUS_NO_SUCH_USER;
635 if ( !(sampass = samu_new( NULL )) ) {
636 return NT_STATUS_NO_MEMORY;
639 status = samu_set_unix( sampass, pwd );
640 if (!NT_STATUS_IS_OK(status)) {
644 /* In pathological cases the above call can set the account
645 * name to the DOMAIN\username form. Reset the account name
646 * using unix_username */
647 pdb_set_username(sampass, unix_username, PDB_SET);
649 /* set the user sid to be the calculated u_sid */
650 pdb_set_user_sid(sampass, &u_sid, PDB_SET);
652 result = make_server_info(NULL);
653 if (result == NULL) {
654 TALLOC_FREE(sampass);
655 return NT_STATUS_NO_MEMORY;
658 status = samu_to_SamInfo3(result, sampass, global_myname(),
659 &result->info3, &result->extra);
660 TALLOC_FREE(sampass);
661 if (!NT_STATUS_IS_OK(status)) {
662 DEBUG(10, ("Failed to convert samu to info3: %s\n",
668 result->unix_name = talloc_strdup(result, unix_username);
669 result->sanitized_username = sanitize_username(result, unix_username);
671 if ((result->unix_name == NULL)
672 || (result->sanitized_username == NULL)) {
674 return NT_STATUS_NO_MEMORY;
677 result->utok.uid = pwd->pw_uid;
678 result->utok.gid = pwd->pw_gid;
680 *server_info = result;
685 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
686 struct netr_SamInfo3 *info3)
688 const char *guest_account = lp_guestaccount();
689 struct dom_sid domain_sid;
693 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
695 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
696 "account [%s]!\n", guest_account));
697 return NT_STATUS_NO_SUCH_USER;
700 /* Set acount name */
701 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
703 return NT_STATUS_NO_MEMORY;
705 init_lsa_String(&info3->base.account_name, tmp);
707 /* Set domain name */
708 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
710 return NT_STATUS_NO_MEMORY;
712 init_lsa_StringLarge(&info3->base.domain, tmp);
715 sid_copy(&domain_sid, get_global_sam_sid());
717 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
718 if (info3->base.domain_sid == NULL) {
719 return NT_STATUS_NO_MEMORY;
723 info3->base.rid = DOMAIN_RID_GUEST;
726 info3->base.primary_gid = BUILTIN_RID_GUESTS;
732 /***************************************************************************
733 Make (and fill) a user_info struct for a guest login.
734 This *must* succeed for smbd to start. If there is no mapping entry for
735 the guest gid, then create one.
737 The resulting structure is a 'session_info' because
738 create_local_token() has already been called on it. This is quite
739 nasty, as the auth subsystem isn't expect this, but the behaviour is
741 ***************************************************************************/
743 static NTSTATUS make_new_server_info_guest(struct auth_serversupplied_info **session_info)
745 struct auth_serversupplied_info *server_info;
746 static const char zeros[16] = {0};
747 const char *guest_account = lp_guestaccount();
748 const char *domain = global_myname();
749 struct netr_SamInfo3 info3;
754 tmp_ctx = talloc_stackframe();
755 if (tmp_ctx == NULL) {
756 return NT_STATUS_NO_MEMORY;
761 status = get_guest_info3(tmp_ctx, &info3);
762 if (!NT_STATUS_IS_OK(status)) {
766 status = make_server_info_info3(tmp_ctx,
771 if (!NT_STATUS_IS_OK(status)) {
775 server_info->guest = True;
777 /* This should not be done here (we should produce a server
778 * info, and later construct a session info from it), but for
779 * now this does not change the previous behaviours */
780 status = create_local_token(tmp_ctx, server_info, NULL, session_info);
781 TALLOC_FREE(server_info);
782 if (!NT_STATUS_IS_OK(status)) {
783 DEBUG(10, ("create_local_token failed: %s\n",
787 talloc_steal(NULL, *session_info);
789 /* annoying, but the Guest really does have a session key, and it is
791 (*session_info)->session_key = data_blob(zeros, sizeof(zeros));
792 (*session_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
794 alpha_strcpy(tmp, (*session_info)->info3->base.account_name.string,
795 ". _-$", sizeof(tmp));
796 (*session_info)->sanitized_username = talloc_strdup(*session_info, tmp);
798 status = NT_STATUS_OK;
800 TALLOC_FREE(tmp_ctx);
804 /***************************************************************************
805 Make (and fill) a auth_session_info struct for a system user login.
806 This *must* succeed for smbd to start.
807 ***************************************************************************/
809 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
810 struct auth_serversupplied_info **session_info)
815 pwd = getpwuid_alloc(mem_ctx, sec_initial_uid());
817 return NT_STATUS_NO_SUCH_USER;
820 status = make_session_info_from_username(mem_ctx,
825 if (!NT_STATUS_IS_OK(status)) {
829 (*session_info)->system = true;
831 status = add_sid_to_array_unique((*session_info)->security_token->sids,
833 &(*session_info)->security_token->sids,
834 &(*session_info)->security_token->num_sids);
835 if (!NT_STATUS_IS_OK(status)) {
836 TALLOC_FREE((*session_info));
843 /****************************************************************************
844 Fake a auth_serversupplied_info just from a username (as a
845 session_info structure, with create_local_token() already called on
847 ****************************************************************************/
849 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
850 const char *username,
852 struct auth_serversupplied_info **session_info)
854 struct auth_serversupplied_info *result;
858 pwd = Get_Pwnam_alloc(talloc_tos(), username);
860 return NT_STATUS_NO_SUCH_USER;
863 status = make_server_info_pw(&result, pwd->pw_name, pwd);
867 if (!NT_STATUS_IS_OK(status)) {
871 result->nss_token = true;
872 result->guest = is_guest;
874 /* Now turn the server_info into a session_info with the full token etc */
875 status = create_local_token(mem_ctx, result, NULL, session_info);
881 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
882 const struct auth_serversupplied_info *src)
884 struct auth_serversupplied_info *dst;
886 dst = make_server_info(mem_ctx);
891 dst->guest = src->guest;
892 dst->system = src->system;
893 dst->utok.uid = src->utok.uid;
894 dst->utok.gid = src->utok.gid;
895 dst->utok.ngroups = src->utok.ngroups;
896 if (src->utok.ngroups != 0) {
897 dst->utok.groups = (gid_t *)TALLOC_MEMDUP(
898 dst, src->utok.groups,
899 sizeof(gid_t)*dst->utok.ngroups);
901 dst->utok.groups = NULL;
904 if (src->security_token) {
905 dst->security_token = dup_nt_token(dst, src->security_token);
906 if (!dst->security_token) {
912 dst->session_key = data_blob_talloc( dst, src->session_key.data,
913 src->session_key.length);
915 dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
916 src->lm_session_key.length);
918 dst->info3 = copy_netr_SamInfo3(dst, src->info3);
923 dst->extra = src->extra;
925 dst->unix_name = talloc_strdup(dst, src->unix_name);
926 if (!dst->unix_name) {
931 dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
932 if (!dst->sanitized_username) {
941 * Set a new session key. Used in the rpc server where we have to override the
942 * SMB level session key with SystemLibraryDTC
945 bool session_info_set_session_key(struct auth_serversupplied_info *info,
946 DATA_BLOB session_key)
948 TALLOC_FREE(info->session_key.data);
950 info->session_key = data_blob_talloc(
951 info, session_key.data, session_key.length);
953 return (info->session_key.data != NULL);
956 static struct auth_serversupplied_info *guest_info = NULL;
958 bool init_guest_info(void)
960 if (guest_info != NULL)
963 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
966 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
967 struct auth_serversupplied_info **server_info)
969 *server_info = copy_serverinfo(mem_ctx, guest_info);
970 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
973 static struct auth_serversupplied_info *system_info = NULL;
975 NTSTATUS init_system_info(void)
977 if (system_info != NULL)
980 return make_new_session_info_system(NULL, &system_info);
983 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
984 struct auth_serversupplied_info **session_info)
986 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
987 *session_info = copy_serverinfo(mem_ctx, system_info);
988 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
991 const struct auth_serversupplied_info *get_session_info_system(void)
996 bool copy_current_user(struct current_user *dst, struct current_user *src)
999 struct security_token *nt_token;
1001 groups = (gid_t *)memdup(src->ut.groups,
1002 sizeof(gid_t) * src->ut.ngroups);
1003 if ((src->ut.ngroups != 0) && (groups == NULL)) {
1007 nt_token = dup_nt_token(NULL, src->nt_user_token);
1008 if (nt_token == NULL) {
1013 dst->conn = src->conn;
1014 dst->vuid = src->vuid;
1015 dst->ut.uid = src->ut.uid;
1016 dst->ut.gid = src->ut.gid;
1017 dst->ut.ngroups = src->ut.ngroups;
1018 dst->ut.groups = groups;
1019 dst->nt_user_token = nt_token;
1023 /***************************************************************************
1024 Purely internal function for make_server_info_info3
1025 ***************************************************************************/
1027 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1028 const char *username, char **found_username,
1029 struct passwd **pwd,
1030 bool *username_was_mapped)
1032 char *orig_dom_user = NULL;
1033 char *dom_user = NULL;
1034 char *lower_username = NULL;
1035 char *real_username = NULL;
1036 struct passwd *passwd;
1038 lower_username = talloc_strdup(mem_ctx, username);
1039 if (!lower_username) {
1040 return NT_STATUS_NO_MEMORY;
1042 strlower_m( lower_username );
1044 orig_dom_user = talloc_asprintf(mem_ctx,
1047 *lp_winbind_separator(),
1049 if (!orig_dom_user) {
1050 return NT_STATUS_NO_MEMORY;
1053 /* Get the passwd struct. Try to create the account if necessary. */
1055 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1057 return NT_STATUS_NO_MEMORY;
1060 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, True );
1062 DEBUG(3, ("Failed to find authenticated user %s via "
1063 "getpwnam(), denying access.\n", dom_user));
1064 return NT_STATUS_NO_SUCH_USER;
1067 if (!real_username) {
1068 return NT_STATUS_NO_MEMORY;
1073 /* This is pointless -- there is no suport for differing
1074 unix and windows names. Make sure to always store the
1075 one we actually looked up and succeeded. Have I mentioned
1076 why I hate the 'winbind use default domain' parameter?
1079 *found_username = talloc_strdup( mem_ctx, real_username );
1081 return NT_STATUS_OK;
1084 /****************************************************************************
1085 Wrapper to allow the getpwnam() call to strip the domain name and
1086 try again in case a local UNIX user is already there. Also run through
1087 the username if we fallback to the username only.
1088 ****************************************************************************/
1090 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1091 char **p_save_username, bool create )
1093 struct passwd *pw = NULL;
1095 char *username = NULL;
1097 /* we only save a copy of the username it has been mangled
1098 by winbindd use default domain */
1099 *p_save_username = NULL;
1101 /* don't call map_username() here since it has to be done higher
1102 up the stack so we don't call it multiple times */
1104 username = talloc_strdup(mem_ctx, domuser);
1109 p = strchr_m( username, *lp_winbind_separator() );
1111 /* code for a DOMAIN\user string */
1114 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1116 /* make sure we get the case of the username correct */
1117 /* work around 'winbind use default domain = yes' */
1119 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1122 /* split the domain and username into 2 strings */
1126 *p_save_username = talloc_asprintf(mem_ctx,
1129 *lp_winbind_separator(),
1131 if (!*p_save_username) {
1136 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1143 /* setup for lookup of just the username */
1144 /* remember that p and username are overlapping memory */
1147 username = talloc_strdup(mem_ctx, p);
1153 /* just lookup a plain username */
1155 pw = Get_Pwnam_alloc(mem_ctx, username);
1157 /* Create local user if requested but only if winbindd
1158 is not running. We need to protect against cases
1159 where winbindd is failing and then prematurely
1160 creating users in /etc/passwd */
1162 if ( !pw && create && !winbind_ping() ) {
1163 /* Don't add a machine account. */
1164 if (username[strlen(username)-1] == '$')
1167 _smb_create_user(NULL, username, NULL);
1168 pw = Get_Pwnam_alloc(mem_ctx, username);
1171 /* one last check for a valid passwd struct */
1174 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1179 /***************************************************************************
1180 Make a server_info struct from the info3 returned by a domain logon
1181 ***************************************************************************/
1183 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1184 const char *sent_nt_username,
1186 struct auth_serversupplied_info **server_info,
1187 struct netr_SamInfo3 *info3)
1189 static const char zeros[16] = {0, };
1191 NTSTATUS nt_status = NT_STATUS_OK;
1192 char *found_username = NULL;
1193 const char *nt_domain;
1194 const char *nt_username;
1195 bool username_was_mapped;
1197 struct auth_serversupplied_info *result;
1198 struct dom_sid *group_sid;
1199 struct netr_SamInfo3 *i3;
1202 Here is where we should check the list of
1203 trusted domains, and verify that the SID
1207 nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1209 /* If the server didn't give us one, just use the one we sent
1211 nt_username = sent_nt_username;
1214 nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1216 /* If the server didn't give us one, just use the one we sent
1221 /* If getpwnam() fails try the add user script (2.2.x behavior).
1223 We use the _unmapped_ username here in an attempt to provide
1224 consistent username mapping behavior between kerberos and NTLM[SSP]
1225 authentication in domain mode security. I.E. Username mapping
1226 should be applied to the fully qualified username
1227 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1228 called map_username() unnecessarily in make_user_info_map() but
1229 that is how the current code is designed. Making the change here
1230 is the least disruptive place. -- jerry */
1232 /* this call will try to create the user if necessary */
1234 nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
1235 &found_username, &pwd,
1236 &username_was_mapped);
1238 if (!NT_STATUS_IS_OK(nt_status)) {
1242 result = make_server_info(NULL);
1243 if (result == NULL) {
1244 DEBUG(4, ("make_server_info failed!\n"));
1245 return NT_STATUS_NO_MEMORY;
1248 result->unix_name = talloc_strdup(result, found_username);
1250 result->sanitized_username = sanitize_username(result,
1252 if (result->sanitized_username == NULL) {
1253 TALLOC_FREE(result);
1254 return NT_STATUS_NO_MEMORY;
1257 /* copy in the info3 */
1258 result->info3 = i3 = copy_netr_SamInfo3(result, info3);
1259 if (result->info3 == NULL) {
1260 TALLOC_FREE(result);
1261 return NT_STATUS_NO_MEMORY;
1264 /* Fill in the unix info we found on the way */
1265 result->utok.uid = pwd->pw_uid;
1266 result->utok.gid = pwd->pw_gid;
1268 /* We can't just trust that the primary group sid sent us is something
1269 * we can really use. Obtain the useable sid, and store the original
1270 * one as an additional group if it had to be replaced */
1271 nt_status = get_primary_group_sid(mem_ctx, found_username,
1273 if (!NT_STATUS_IS_OK(nt_status)) {
1274 TALLOC_FREE(result);
1278 /* store and check if it is the same we got originally */
1279 sid_peek_rid(group_sid, &i3->base.primary_gid);
1280 if (i3->base.primary_gid != info3->base.primary_gid) {
1281 uint32_t n = i3->base.groups.count;
1282 /* not the same, store the original as an additional group */
1283 i3->base.groups.rids =
1284 talloc_realloc(i3, i3->base.groups.rids,
1285 struct samr_RidWithAttribute, n + 1);
1286 if (i3->base.groups.rids == NULL) {
1287 TALLOC_FREE(result);
1288 return NT_STATUS_NO_MEMORY;
1290 i3->base.groups.rids[n].rid = info3->base.primary_gid;
1291 i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED;
1292 i3->base.groups.count = n + 1;
1295 /* ensure we are never given NULL session keys */
1297 if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1298 result->session_key = data_blob_null;
1300 result->session_key = data_blob_talloc(
1301 result, info3->base.key.key,
1302 sizeof(info3->base.key.key));
1305 if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1306 result->lm_session_key = data_blob_null;
1308 result->lm_session_key = data_blob_talloc(
1309 result, info3->base.LMSessKey.key,
1310 sizeof(info3->base.LMSessKey.key));
1313 result->nss_token |= username_was_mapped;
1315 *server_info = result;
1317 return NT_STATUS_OK;
1320 /*****************************************************************************
1321 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1322 ******************************************************************************/
1324 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1325 const char *sent_nt_username,
1327 const struct wbcAuthUserInfo *info,
1328 struct auth_serversupplied_info **server_info)
1330 struct netr_SamInfo3 *info3;
1332 info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
1334 return NT_STATUS_NO_MEMORY;
1337 return make_server_info_info3(mem_ctx,
1338 sent_nt_username, domain,
1339 server_info, info3);
1343 * Verify whether or not given domain is trusted.
1345 * @param domain_name name of the domain to be verified
1346 * @return true if domain is one of the trusted ones or
1347 * false if otherwise
1350 bool is_trusted_domain(const char* dom_name)
1352 struct dom_sid trustdom_sid;
1355 /* no trusted domains for a standalone server */
1357 if ( lp_server_role() == ROLE_STANDALONE )
1360 if (dom_name == NULL || dom_name[0] == '\0') {
1364 if (strequal(dom_name, get_global_sam_name())) {
1368 /* if we are a DC, then check for a direct trust relationships */
1372 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1373 "[%s]\n", dom_name ));
1374 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1382 /* If winbind is around, ask it */
1384 result = wb_is_trusted_domain(dom_name);
1386 if (result == WBC_ERR_SUCCESS) {
1390 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1391 /* winbind could not find the domain */
1395 /* The only other possible result is that winbind is not up
1396 and running. We need to update the trustdom_cache
1399 update_trustdom_cache();
1402 /* now the trustdom cache should be available a DC could still
1403 * have a transitive trust so fall back to the cache of trusted
1404 * domains (like a domain member would use */
1406 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {