2 Unix SMB/CIFS implementation.
3 Authentication utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001-2011
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 "../libcli/auth/libcli_auth.h"
27 #include "../lib/crypto/arcfour.h"
28 #include "rpc_client/init_lsa.h"
29 #include "../libcli/security/security.h"
30 #include "../lib/util/util_pw.h"
31 #include "lib/winbind_util.h"
35 #define DBGC_CLASS DBGC_AUTH
37 /****************************************************************************
38 Create a UNIX user on demand.
39 ****************************************************************************/
41 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
43 TALLOC_CTX *ctx = talloc_tos();
47 add_script = talloc_strdup(ctx, lp_adduser_script());
48 if (!add_script || !*add_script) {
51 add_script = talloc_all_string_sub(ctx,
59 add_script = talloc_all_string_sub(ctx,
68 add_script = talloc_all_string_sub(ctx,
76 ret = smbrun(add_script,NULL);
79 ("smb_create_user: Running the command `%s' gave %d\n",
84 /****************************************************************************
85 Create an auth_usersupplied_data structure after appropriate mapping.
86 ****************************************************************************/
88 NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info,
90 const char *client_domain,
91 const char *workstation_name,
92 const struct tsocket_address *remote_address,
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,
141 remote_address, lm_pwd, nt_pwd,
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 const struct tsocket_address *remote_address,
163 uint32 logon_parameters,
164 const uchar *lm_network_pwd,
166 const uchar *nt_network_pwd,
171 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
172 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
174 status = make_user_info_map(user_info,
175 smb_name, client_domain,
178 lm_pwd_len ? &lm_blob : NULL,
179 nt_pwd_len ? &nt_blob : NULL,
181 AUTH_PASSWORD_RESPONSE);
183 if (NT_STATUS_IS_OK(status)) {
184 (*user_info)->logon_parameters = logon_parameters;
186 ret = NT_STATUS_IS_OK(status) ? True : False;
188 data_blob_free(&lm_blob);
189 data_blob_free(&nt_blob);
193 /****************************************************************************
194 Create an auth_usersupplied_data, making the DATA_BLOBs here.
195 Decrypt and encrypt the passwords.
196 ****************************************************************************/
198 bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
199 const char *smb_name,
200 const char *client_domain,
201 const char *workstation_name,
202 const struct tsocket_address *remote_address,
203 uint32 logon_parameters,
205 const uchar lm_interactive_pwd[16],
206 const uchar nt_interactive_pwd[16],
207 const uchar *dc_sess_key)
209 struct samr_Password lm_pwd;
210 struct samr_Password nt_pwd;
211 unsigned char local_lm_response[24];
212 unsigned char local_nt_response[24];
213 unsigned char key[16];
215 memcpy(key, dc_sess_key, 16);
217 if (lm_interactive_pwd)
218 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
220 if (nt_interactive_pwd)
221 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
223 #ifdef DEBUG_PASSWORD
225 dump_data(100, key, sizeof(key));
227 DEBUG(100,("lm owf password:"));
228 dump_data(100, lm_pwd.hash, sizeof(lm_pwd.hash));
230 DEBUG(100,("nt owf password:"));
231 dump_data(100, nt_pwd.hash, sizeof(nt_pwd.hash));
234 if (lm_interactive_pwd)
235 arcfour_crypt(lm_pwd.hash, key, sizeof(lm_pwd.hash));
237 if (nt_interactive_pwd)
238 arcfour_crypt(nt_pwd.hash, key, sizeof(nt_pwd.hash));
240 #ifdef DEBUG_PASSWORD
241 DEBUG(100,("decrypt of lm owf password:"));
242 dump_data(100, lm_pwd.hash, sizeof(lm_pwd));
244 DEBUG(100,("decrypt of nt owf password:"));
245 dump_data(100, nt_pwd.hash, sizeof(nt_pwd));
248 if (lm_interactive_pwd)
249 SMBOWFencrypt(lm_pwd.hash, chal,
252 if (nt_interactive_pwd)
253 SMBOWFencrypt(nt_pwd.hash, chal,
256 /* Password info paranoia */
262 DATA_BLOB local_lm_blob;
263 DATA_BLOB local_nt_blob;
265 if (lm_interactive_pwd) {
266 local_lm_blob = data_blob(local_lm_response,
267 sizeof(local_lm_response));
270 if (nt_interactive_pwd) {
271 local_nt_blob = data_blob(local_nt_response,
272 sizeof(local_nt_response));
275 nt_status = make_user_info_map(
277 smb_name, client_domain, workstation_name,
279 lm_interactive_pwd ? &local_lm_blob : NULL,
280 nt_interactive_pwd ? &local_nt_blob : NULL,
281 lm_interactive_pwd ? &lm_pwd : NULL,
282 nt_interactive_pwd ? &nt_pwd : NULL,
283 NULL, AUTH_PASSWORD_HASH);
285 if (NT_STATUS_IS_OK(nt_status)) {
286 (*user_info)->logon_parameters = logon_parameters;
289 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
290 data_blob_free(&local_lm_blob);
291 data_blob_free(&local_nt_blob);
297 /****************************************************************************
298 Create an auth_usersupplied_data structure
299 ****************************************************************************/
301 bool make_user_info_for_reply(struct auth_usersupplied_info **user_info,
302 const char *smb_name,
303 const char *client_domain,
304 const struct tsocket_address *remote_address,
306 DATA_BLOB plaintext_password)
309 DATA_BLOB local_lm_blob;
310 DATA_BLOB local_nt_blob;
311 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
312 char *plaintext_password_string;
314 * Not encrypted - do so.
317 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
319 if (plaintext_password.data && plaintext_password.length) {
320 unsigned char local_lm_response[24];
322 #ifdef DEBUG_PASSWORD
323 DEBUG(10,("Unencrypted password (len %d):\n",
324 (int)plaintext_password.length));
325 dump_data(100, plaintext_password.data,
326 plaintext_password.length);
329 SMBencrypt( (const char *)plaintext_password.data,
330 (const uchar*)chal, local_lm_response);
331 local_lm_blob = data_blob(local_lm_response, 24);
333 /* We can't do an NT hash here, as the password needs to be
335 local_nt_blob = data_blob_null;
337 local_lm_blob = data_blob_null;
338 local_nt_blob = data_blob_null;
341 plaintext_password_string = talloc_strndup(talloc_tos(),
342 (const char *)plaintext_password.data,
343 plaintext_password.length);
344 if (!plaintext_password_string) {
348 ret = make_user_info_map(
349 user_info, smb_name, client_domain,
350 get_remote_machine_name(),
352 local_lm_blob.data ? &local_lm_blob : NULL,
353 local_nt_blob.data ? &local_nt_blob : NULL,
355 plaintext_password_string,
356 AUTH_PASSWORD_PLAIN);
358 if (plaintext_password_string) {
359 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
360 talloc_free(plaintext_password_string);
363 data_blob_free(&local_lm_blob);
364 return NT_STATUS_IS_OK(ret) ? True : False;
367 /****************************************************************************
368 Create an auth_usersupplied_data structure
369 ****************************************************************************/
371 NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info,
372 const char *smb_name,
373 const char *client_domain,
374 const struct tsocket_address *remote_address,
375 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
377 return make_user_info_map(user_info, smb_name,
379 get_remote_machine_name(),
381 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
382 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
384 AUTH_PASSWORD_RESPONSE);
387 /****************************************************************************
388 Create a guest user_info blob, for anonymous authenticaion.
389 ****************************************************************************/
391 bool make_user_info_guest(const struct tsocket_address *remote_address,
392 struct auth_usersupplied_info **user_info)
396 nt_status = make_user_info(user_info,
404 AUTH_PASSWORD_RESPONSE);
406 return NT_STATUS_IS_OK(nt_status) ? True : False;
409 static NTSTATUS log_nt_token(struct security_token *token)
411 TALLOC_CTX *frame = talloc_stackframe();
416 if ((lp_log_nt_token_command() == NULL) ||
417 (strlen(lp_log_nt_token_command()) == 0)) {
422 group_sidstr = talloc_strdup(frame, "");
423 for (i=1; i<token->num_sids; i++) {
424 group_sidstr = talloc_asprintf(
425 frame, "%s %s", group_sidstr,
426 sid_string_talloc(frame, &token->sids[i]));
429 command = talloc_string_sub(
430 frame, lp_log_nt_token_command(),
431 "%s", sid_string_talloc(frame, &token->sids[0]));
432 command = talloc_string_sub(frame, command, "%t", group_sidstr);
434 if (command == NULL) {
436 return NT_STATUS_NO_MEMORY;
439 DEBUG(8, ("running command: [%s]\n", command));
440 if (smbrun(command, NULL) != 0) {
441 DEBUG(0, ("Could not log NT token\n"));
443 return NT_STATUS_ACCESS_DENIED;
451 * Create the token to use from server_info->info3 and
452 * server_info->sids (the info3/sam groups). Find the unix gids.
455 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
456 const struct auth_serversupplied_info *server_info,
457 DATA_BLOB *session_key,
458 struct auth3_session_info **session_info_out)
460 struct security_token *t;
463 struct dom_sid tmp_sid;
464 struct auth3_session_info *session_info;
465 struct wbcUnixId *ids;
467 /* Ensure we can't possible take a code path leading to a
470 return NT_STATUS_LOGON_FAILURE;
473 session_info = make_auth3_session_info(mem_ctx);
475 return NT_STATUS_NO_MEMORY;
478 session_info->unix_token = talloc(session_info, struct security_unix_token);
479 if (!session_info->unix_token) {
480 TALLOC_FREE(session_info);
481 return NT_STATUS_NO_MEMORY;
484 session_info->unix_token->uid = server_info->utok.uid;
485 session_info->unix_token->gid = server_info->utok.gid;
486 session_info->unix_token->ngroups = server_info->utok.ngroups;
487 if (server_info->utok.ngroups != 0) {
488 session_info->unix_token->groups = (gid_t *)talloc_memdup(
489 session_info->unix_token, server_info->utok.groups,
490 sizeof(gid_t)*session_info->unix_token->ngroups);
492 session_info->unix_token->groups = NULL;
495 if (server_info->security_token) {
496 session_info->security_token = dup_nt_token(session_info, server_info->security_token);
497 if (!session_info->security_token) {
498 TALLOC_FREE(session_info);
499 return NT_STATUS_NO_MEMORY;
503 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
504 server_info->session_key.length);
506 session_info->info3 = copy_netr_SamInfo3(session_info, server_info->info3);
507 if (!session_info->info3) {
508 TALLOC_FREE(session_info);
509 return NT_STATUS_NO_MEMORY;
512 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
513 if (!session_info->unix_info) {
514 TALLOC_FREE(session_info);
515 return NT_STATUS_NO_MEMORY;
518 session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
519 if (!session_info->unix_info->unix_name) {
520 TALLOC_FREE(session_info);
521 return NT_STATUS_NO_MEMORY;
524 session_info->unix_info->sanitized_username = talloc_strdup(session_info, server_info->sanitized_username);
525 if (!session_info->unix_info->sanitized_username) {
526 TALLOC_FREE(session_info);
527 return NT_STATUS_NO_MEMORY;
530 session_info->unix_info->guest = server_info->guest;
531 session_info->unix_info->system = server_info->system;
534 data_blob_free(&session_info->session_key);
535 session_info->session_key = data_blob_talloc(session_info,
537 session_key->length);
538 if (!session_info->session_key.data && session_key->length) {
539 return NT_STATUS_NO_MEMORY;
543 if (session_info->security_token) {
544 /* Just copy the token, it has already been finalised
545 * (nasty hack to support a cached guest session_info,
546 * and a possible strategy for auth_samba4 to pass in
547 * a finalised session) */
548 *session_info_out = session_info;
553 * If winbind is not around, we can not make much use of the SIDs the
554 * domain controller provided us with. Likewise if the user name was
555 * mapped to some local unix user.
558 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
559 (server_info->nss_token)) {
560 status = create_token_from_username(session_info,
561 server_info->unix_name,
563 &session_info->unix_token->uid,
564 &session_info->unix_token->gid,
565 &session_info->unix_info->unix_name,
566 &session_info->security_token);
569 status = create_local_nt_token_from_info3(session_info,
573 &session_info->security_token);
576 if (!NT_STATUS_IS_OK(status)) {
580 /* Convert the SIDs to gids. */
582 session_info->unix_token->ngroups = 0;
583 session_info->unix_token->groups = NULL;
585 t = session_info->security_token;
587 ids = talloc_array(talloc_tos(), struct wbcUnixId,
590 return NT_STATUS_NO_MEMORY;
593 if (!sids_to_unix_ids(t->sids, t->num_sids, ids)) {
595 return NT_STATUS_NO_MEMORY;
598 /* Start at index 1, where the groups start. */
600 for (i=1; i<t->num_sids; i++) {
602 if (ids[i].type != WBC_ID_TYPE_GID) {
603 DEBUG(10, ("Could not convert SID %s to gid, "
605 sid_string_dbg(&t->sids[i])));
608 if (!add_gid_to_array_unique(session_info, ids[i].id.gid,
609 &session_info->unix_token->groups,
610 &session_info->unix_token->ngroups)) {
611 return NT_STATUS_NO_MEMORY;
616 * Add the "Unix Group" SID for each gid to catch mapped groups
617 * and their Unix equivalent. This is to solve the backwards
618 * compatibility problem of 'valid users = +ntadmin' where
619 * ntadmin has been paired with "Domain Admins" in the group
620 * mapping table. Otherwise smb.conf would need to be changed
621 * to 'valid user = "Domain Admins"'. --jerry
623 * For consistency we also add the "Unix User" SID,
624 * so that the complete unix token is represented within
628 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
630 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
631 &session_info->security_token->sids,
632 &session_info->security_token->num_sids);
634 for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
635 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
636 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
637 &session_info->security_token->sids,
638 &session_info->security_token->num_sids);
641 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
642 debug_unix_user_token(DBGC_AUTH, 10,
643 session_info->unix_token->uid,
644 session_info->unix_token->gid,
645 session_info->unix_token->ngroups,
646 session_info->unix_token->groups);
648 status = log_nt_token(session_info->security_token);
649 if (!NT_STATUS_IS_OK(status)) {
653 *session_info_out = session_info;
657 /***************************************************************************
658 Make (and fill) a server_info struct from a 'struct passwd' by conversion
660 ***************************************************************************/
662 NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
667 struct samu *sampass = NULL;
668 char *qualified_name = NULL;
669 TALLOC_CTX *mem_ctx = NULL;
670 struct dom_sid u_sid;
671 enum lsa_SidType type;
672 struct auth_serversupplied_info *result;
675 * The SID returned in server_info->sam_account is based
676 * on our SAM sid even though for a pure UNIX account this should
677 * not be the case as it doesn't really exist in the SAM db.
678 * This causes lookups on "[in]valid users" to fail as they
679 * will lookup this name as a "Unix User" SID to check against
680 * the user token. Fix this by adding the "Unix User"\unix_username
681 * SID to the sid array. The correct fix should probably be
682 * changing the server_info->sam_account user SID to be a
683 * S-1-22 Unix SID, but this might break old configs where
684 * plaintext passwords were used with no SAM backend.
687 mem_ctx = talloc_init("make_server_info_pw_tmp");
689 return NT_STATUS_NO_MEMORY;
692 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
693 unix_users_domain_name(),
695 if (!qualified_name) {
696 TALLOC_FREE(mem_ctx);
697 return NT_STATUS_NO_MEMORY;
700 if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
703 TALLOC_FREE(mem_ctx);
704 return NT_STATUS_NO_SUCH_USER;
707 TALLOC_FREE(mem_ctx);
709 if (type != SID_NAME_USER) {
710 return NT_STATUS_NO_SUCH_USER;
713 if ( !(sampass = samu_new( NULL )) ) {
714 return NT_STATUS_NO_MEMORY;
717 status = samu_set_unix( sampass, pwd );
718 if (!NT_STATUS_IS_OK(status)) {
722 /* In pathological cases the above call can set the account
723 * name to the DOMAIN\username form. Reset the account name
724 * using unix_username */
725 pdb_set_username(sampass, unix_username, PDB_SET);
727 /* set the user sid to be the calculated u_sid */
728 pdb_set_user_sid(sampass, &u_sid, PDB_SET);
730 result = make_server_info(NULL);
731 if (result == NULL) {
732 TALLOC_FREE(sampass);
733 return NT_STATUS_NO_MEMORY;
736 status = samu_to_SamInfo3(result, sampass, lp_netbios_name(),
737 &result->info3, &result->extra);
738 TALLOC_FREE(sampass);
739 if (!NT_STATUS_IS_OK(status)) {
740 DEBUG(10, ("Failed to convert samu to info3: %s\n",
746 result->unix_name = talloc_strdup(result, unix_username);
747 result->sanitized_username = sanitize_username(result, unix_username);
749 if ((result->unix_name == NULL)
750 || (result->sanitized_username == NULL)) {
752 return NT_STATUS_NO_MEMORY;
755 result->utok.uid = pwd->pw_uid;
756 result->utok.gid = pwd->pw_gid;
758 *server_info = result;
763 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
764 struct netr_SamInfo3 *info3)
766 const char *guest_account = lp_guestaccount();
767 struct dom_sid domain_sid;
771 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
773 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
774 "account [%s]!\n", guest_account));
775 return NT_STATUS_NO_SUCH_USER;
778 /* Set acount name */
779 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
781 return NT_STATUS_NO_MEMORY;
783 init_lsa_String(&info3->base.account_name, tmp);
785 /* Set domain name */
786 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
788 return NT_STATUS_NO_MEMORY;
790 init_lsa_StringLarge(&info3->base.domain, tmp);
793 sid_copy(&domain_sid, get_global_sam_sid());
795 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
796 if (info3->base.domain_sid == NULL) {
797 return NT_STATUS_NO_MEMORY;
801 info3->base.rid = DOMAIN_RID_GUEST;
804 info3->base.primary_gid = BUILTIN_RID_GUESTS;
810 /***************************************************************************
811 Make (and fill) a user_info struct for a guest login.
812 This *must* succeed for smbd to start. If there is no mapping entry for
813 the guest gid, then create one.
815 The resulting structure is a 'session_info' because
816 create_local_token() has already been called on it. This is quite
817 nasty, as the auth subsystem isn't expect this, but the behaviour is
819 ***************************************************************************/
821 static NTSTATUS make_new_session_info_guest(struct auth3_session_info **session_info, struct auth_serversupplied_info **server_info)
823 static const char zeros[16] = {0};
824 const char *guest_account = lp_guestaccount();
825 const char *domain = lp_netbios_name();
826 struct netr_SamInfo3 info3;
831 tmp_ctx = talloc_stackframe();
832 if (tmp_ctx == NULL) {
833 return NT_STATUS_NO_MEMORY;
838 status = get_guest_info3(tmp_ctx, &info3);
839 if (!NT_STATUS_IS_OK(status)) {
840 DEBUG(0, ("get_guest_info3 failed with %s\n",
845 status = make_server_info_info3(tmp_ctx,
850 if (!NT_STATUS_IS_OK(status)) {
851 DEBUG(0, ("make_server_info_info3 failed with %s\n",
856 (*server_info)->guest = True;
858 /* This should not be done here (we should produce a server
859 * info, and later construct a session info from it), but for
860 * now this does not change the previous behaviours */
861 status = create_local_token(tmp_ctx, *server_info, NULL, session_info);
862 if (!NT_STATUS_IS_OK(status)) {
863 DEBUG(0, ("create_local_token failed: %s\n",
867 talloc_steal(NULL, *session_info);
868 talloc_steal(NULL, *server_info);
870 /* annoying, but the Guest really does have a session key, and it is
872 (*session_info)->session_key = data_blob(zeros, sizeof(zeros));
874 alpha_strcpy(tmp, (*session_info)->info3->base.account_name.string,
875 ". _-$", sizeof(tmp));
876 (*session_info)->unix_info->sanitized_username = talloc_strdup(*session_info, tmp);
878 status = NT_STATUS_OK;
880 TALLOC_FREE(tmp_ctx);
884 /***************************************************************************
885 Make (and fill) a auth_session_info struct for a system user login.
886 This *must* succeed for smbd to start.
887 ***************************************************************************/
889 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
890 struct auth3_session_info **session_info)
895 pwd = getpwuid_alloc(mem_ctx, sec_initial_uid());
897 return NT_STATUS_NO_SUCH_USER;
900 status = make_session_info_from_username(mem_ctx,
905 if (!NT_STATUS_IS_OK(status)) {
909 (*session_info)->unix_info->system = true;
911 status = add_sid_to_array_unique((*session_info)->security_token->sids,
913 &(*session_info)->security_token->sids,
914 &(*session_info)->security_token->num_sids);
915 if (!NT_STATUS_IS_OK(status)) {
916 TALLOC_FREE((*session_info));
923 /****************************************************************************
924 Fake a auth3_session_info just from a username (as a
925 session_info structure, with create_local_token() already called on
927 ****************************************************************************/
929 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
930 const char *username,
932 struct auth3_session_info **session_info)
934 struct auth_serversupplied_info *result;
938 pwd = Get_Pwnam_alloc(talloc_tos(), username);
940 return NT_STATUS_NO_SUCH_USER;
943 status = make_server_info_pw(&result, pwd->pw_name, pwd);
947 if (!NT_STATUS_IS_OK(status)) {
951 result->nss_token = true;
952 result->guest = is_guest;
954 /* Now turn the server_info into a session_info with the full token etc */
955 status = create_local_token(mem_ctx, result, NULL, session_info);
960 /* This function MUST only used to create the cached server_info for
963 * This is a lossy conversion. Variables known to be lost so far
966 * - nss_token (not needed because the only read doesn't happen
967 * for the GUEST user, as this routine populates ->security_token
969 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
971 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
973 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
974 const struct auth3_session_info *src,
975 struct auth_serversupplied_info *server_info)
977 struct auth_serversupplied_info *dst;
979 dst = make_server_info(mem_ctx);
984 /* This element must be provided to convert back to an auth_serversupplied_info */
985 SMB_ASSERT(src->unix_info);
987 dst->guest = src->unix_info->guest;
988 dst->system = src->unix_info->system;
990 /* This element must be provided to convert back to an
991 * auth_serversupplied_info. This needs to be from hte
992 * auth3_session_info because the group values in particular
993 * may change during create_local_token() processing */
994 SMB_ASSERT(src->unix_token);
995 dst->utok.uid = src->unix_token->uid;
996 dst->utok.gid = src->unix_token->gid;
997 dst->utok.ngroups = src->unix_token->ngroups;
998 if (src->unix_token->ngroups != 0) {
999 dst->utok.groups = (gid_t *)talloc_memdup(
1000 dst, src->unix_token->groups,
1001 sizeof(gid_t)*dst->utok.ngroups);
1003 dst->utok.groups = NULL;
1006 /* We must have a security_token as otherwise the lossy
1007 * conversion without nss_token would cause create_local_token
1008 * to take the wrong path */
1009 SMB_ASSERT(src->security_token);
1011 dst->security_token = dup_nt_token(dst, src->security_token);
1012 if (!dst->security_token) {
1017 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1018 src->session_key.length);
1020 /* This is OK because this functions is only used for the
1021 * GUEST account, which has all-zero keys for both values */
1022 dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1023 src->session_key.length);
1025 dst->info3 = copy_netr_SamInfo3(dst, server_info->info3);
1031 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1032 if (!dst->unix_name) {
1037 dst->sanitized_username = talloc_strdup(dst, src->unix_info->sanitized_username);
1038 if (!dst->sanitized_username) {
1046 struct auth3_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
1047 const struct auth3_session_info *src)
1049 struct auth3_session_info *dst;
1051 dst = make_auth3_session_info(mem_ctx);
1056 if (src->unix_token) {
1057 dst->unix_token = talloc(dst, struct security_unix_token);
1058 if (!dst->unix_token) {
1062 dst->unix_token->uid = src->unix_token->uid;
1063 dst->unix_token->gid = src->unix_token->gid;
1064 dst->unix_token->ngroups = src->unix_token->ngroups;
1065 if (src->unix_token->ngroups != 0) {
1066 dst->unix_token->groups = (gid_t *)talloc_memdup(
1067 dst->unix_token, src->unix_token->groups,
1068 sizeof(gid_t)*dst->unix_token->ngroups);
1070 dst->unix_token->groups = NULL;
1073 dst->unix_token = NULL;
1076 if (src->security_token) {
1077 dst->security_token = dup_nt_token(dst, src->security_token);
1078 if (!dst->security_token) {
1084 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1085 src->session_key.length);
1087 dst->info3 = copy_netr_SamInfo3(dst, src->info3);
1093 if (src->unix_info) {
1094 dst->unix_info = talloc_zero(dst, struct auth_user_info_unix);
1095 if (!dst->unix_info) {
1100 dst->unix_info->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1101 if (!dst->unix_info->unix_name) {
1106 dst->unix_info->sanitized_username = talloc_strdup(dst, src->unix_info->sanitized_username);
1107 if (!dst->unix_info->sanitized_username) {
1112 dst->unix_info->guest = src->unix_info->guest;
1113 dst->unix_info->system = src->unix_info->system;
1120 * Set a new session key. Used in the rpc server where we have to override the
1121 * SMB level session key with SystemLibraryDTC
1124 bool session_info_set_session_key(struct auth3_session_info *info,
1125 DATA_BLOB session_key)
1127 TALLOC_FREE(info->session_key.data);
1129 info->session_key = data_blob_talloc(
1130 info, session_key.data, session_key.length);
1132 return (info->session_key.data != NULL);
1135 static struct auth3_session_info *guest_info = NULL;
1137 static struct auth_serversupplied_info *guest_server_info = NULL;
1139 bool init_guest_info(void)
1141 if (guest_info != NULL)
1144 return NT_STATUS_IS_OK(make_new_session_info_guest(&guest_info, &guest_server_info));
1147 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1148 struct auth_serversupplied_info **server_info)
1150 /* This is trickier than it would appear to need to be because
1151 * we are trying to avoid certain costly operations when the
1152 * structure is converted to a 'auth3_session_info' again in
1153 * create_local_token() */
1154 *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1155 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1158 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1159 struct auth3_session_info **session_info)
1161 *session_info = copy_session_info(mem_ctx, guest_info);
1162 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1165 static struct auth3_session_info *system_info = NULL;
1167 NTSTATUS init_system_info(void)
1169 if (system_info != NULL)
1170 return NT_STATUS_OK;
1172 return make_new_session_info_system(NULL, &system_info);
1175 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1176 struct auth3_session_info **session_info)
1178 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1179 *session_info = copy_session_info(mem_ctx, system_info);
1180 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1183 const struct auth3_session_info *get_session_info_system(void)
1188 bool copy_current_user(struct current_user *dst, struct current_user *src)
1191 struct security_token *nt_token;
1193 groups = (gid_t *)memdup(src->ut.groups,
1194 sizeof(gid_t) * src->ut.ngroups);
1195 if ((src->ut.ngroups != 0) && (groups == NULL)) {
1199 nt_token = dup_nt_token(NULL, src->nt_user_token);
1200 if (nt_token == NULL) {
1205 dst->conn = src->conn;
1206 dst->vuid = src->vuid;
1207 dst->ut.uid = src->ut.uid;
1208 dst->ut.gid = src->ut.gid;
1209 dst->ut.ngroups = src->ut.ngroups;
1210 dst->ut.groups = groups;
1211 dst->nt_user_token = nt_token;
1215 /***************************************************************************
1216 Purely internal function for make_server_info_info3
1217 ***************************************************************************/
1219 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1220 const char *username, char **found_username,
1221 struct passwd **pwd,
1222 bool *username_was_mapped)
1224 char *orig_dom_user = NULL;
1225 char *dom_user = NULL;
1226 char *lower_username = NULL;
1227 char *real_username = NULL;
1228 struct passwd *passwd;
1230 lower_username = talloc_strdup(mem_ctx, username);
1231 if (!lower_username) {
1232 return NT_STATUS_NO_MEMORY;
1234 strlower_m( lower_username );
1236 orig_dom_user = talloc_asprintf(mem_ctx,
1239 *lp_winbind_separator(),
1241 if (!orig_dom_user) {
1242 return NT_STATUS_NO_MEMORY;
1245 /* Get the passwd struct. Try to create the account if necessary. */
1247 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1249 return NT_STATUS_NO_MEMORY;
1252 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, True );
1254 DEBUG(3, ("Failed to find authenticated user %s via "
1255 "getpwnam(), denying access.\n", dom_user));
1256 return NT_STATUS_NO_SUCH_USER;
1259 if (!real_username) {
1260 return NT_STATUS_NO_MEMORY;
1265 /* This is pointless -- there is no suport for differing
1266 unix and windows names. Make sure to always store the
1267 one we actually looked up and succeeded. Have I mentioned
1268 why I hate the 'winbind use default domain' parameter?
1271 *found_username = talloc_strdup( mem_ctx, real_username );
1273 return NT_STATUS_OK;
1276 /****************************************************************************
1277 Wrapper to allow the getpwnam() call to strip the domain name and
1278 try again in case a local UNIX user is already there. Also run through
1279 the username if we fallback to the username only.
1280 ****************************************************************************/
1282 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1283 char **p_save_username, bool create )
1285 struct passwd *pw = NULL;
1287 char *username = NULL;
1289 /* we only save a copy of the username it has been mangled
1290 by winbindd use default domain */
1291 *p_save_username = NULL;
1293 /* don't call map_username() here since it has to be done higher
1294 up the stack so we don't call it multiple times */
1296 username = talloc_strdup(mem_ctx, domuser);
1301 p = strchr_m( username, *lp_winbind_separator() );
1303 /* code for a DOMAIN\user string */
1306 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1308 /* make sure we get the case of the username correct */
1309 /* work around 'winbind use default domain = yes' */
1311 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1314 /* split the domain and username into 2 strings */
1318 *p_save_username = talloc_asprintf(mem_ctx,
1321 *lp_winbind_separator(),
1323 if (!*p_save_username) {
1328 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1335 /* setup for lookup of just the username */
1336 /* remember that p and username are overlapping memory */
1339 username = talloc_strdup(mem_ctx, p);
1345 /* just lookup a plain username */
1347 pw = Get_Pwnam_alloc(mem_ctx, username);
1349 /* Create local user if requested but only if winbindd
1350 is not running. We need to protect against cases
1351 where winbindd is failing and then prematurely
1352 creating users in /etc/passwd */
1354 if ( !pw && create && !winbind_ping() ) {
1355 /* Don't add a machine account. */
1356 if (username[strlen(username)-1] == '$')
1359 _smb_create_user(NULL, username, NULL);
1360 pw = Get_Pwnam_alloc(mem_ctx, username);
1363 /* one last check for a valid passwd struct */
1366 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1371 /***************************************************************************
1372 Make a server_info struct from the info3 returned by a domain logon
1373 ***************************************************************************/
1375 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1376 const char *sent_nt_username,
1378 struct auth_serversupplied_info **server_info,
1379 struct netr_SamInfo3 *info3)
1381 static const char zeros[16] = {0, };
1383 NTSTATUS nt_status = NT_STATUS_OK;
1384 char *found_username = NULL;
1385 const char *nt_domain;
1386 const char *nt_username;
1387 bool username_was_mapped;
1389 struct auth_serversupplied_info *result;
1390 struct dom_sid *group_sid;
1391 struct netr_SamInfo3 *i3;
1394 Here is where we should check the list of
1395 trusted domains, and verify that the SID
1399 nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1401 /* If the server didn't give us one, just use the one we sent
1403 nt_username = sent_nt_username;
1406 nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1408 /* If the server didn't give us one, just use the one we sent
1413 /* If getpwnam() fails try the add user script (2.2.x behavior).
1415 We use the _unmapped_ username here in an attempt to provide
1416 consistent username mapping behavior between kerberos and NTLM[SSP]
1417 authentication in domain mode security. I.E. Username mapping
1418 should be applied to the fully qualified username
1419 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1420 called map_username() unnecessarily in make_user_info_map() but
1421 that is how the current code is designed. Making the change here
1422 is the least disruptive place. -- jerry */
1424 /* this call will try to create the user if necessary */
1426 nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
1427 &found_username, &pwd,
1428 &username_was_mapped);
1430 if (!NT_STATUS_IS_OK(nt_status)) {
1434 result = make_server_info(NULL);
1435 if (result == NULL) {
1436 DEBUG(4, ("make_server_info failed!\n"));
1437 return NT_STATUS_NO_MEMORY;
1440 result->unix_name = talloc_strdup(result, found_username);
1442 result->sanitized_username = sanitize_username(result,
1444 if (result->sanitized_username == NULL) {
1445 TALLOC_FREE(result);
1446 return NT_STATUS_NO_MEMORY;
1449 /* copy in the info3 */
1450 result->info3 = i3 = copy_netr_SamInfo3(result, info3);
1451 if (result->info3 == NULL) {
1452 TALLOC_FREE(result);
1453 return NT_STATUS_NO_MEMORY;
1456 /* Fill in the unix info we found on the way */
1457 result->utok.uid = pwd->pw_uid;
1458 result->utok.gid = pwd->pw_gid;
1460 /* We can't just trust that the primary group sid sent us is something
1461 * we can really use. Obtain the useable sid, and store the original
1462 * one as an additional group if it had to be replaced */
1463 nt_status = get_primary_group_sid(mem_ctx, found_username,
1465 if (!NT_STATUS_IS_OK(nt_status)) {
1466 TALLOC_FREE(result);
1470 /* store and check if it is the same we got originally */
1471 sid_peek_rid(group_sid, &i3->base.primary_gid);
1472 if (i3->base.primary_gid != info3->base.primary_gid) {
1473 uint32_t n = i3->base.groups.count;
1474 /* not the same, store the original as an additional group */
1475 i3->base.groups.rids =
1476 talloc_realloc(i3, i3->base.groups.rids,
1477 struct samr_RidWithAttribute, n + 1);
1478 if (i3->base.groups.rids == NULL) {
1479 TALLOC_FREE(result);
1480 return NT_STATUS_NO_MEMORY;
1482 i3->base.groups.rids[n].rid = info3->base.primary_gid;
1483 i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED;
1484 i3->base.groups.count = n + 1;
1487 /* ensure we are never given NULL session keys */
1489 if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1490 result->session_key = data_blob_null;
1492 result->session_key = data_blob_talloc(
1493 result, info3->base.key.key,
1494 sizeof(info3->base.key.key));
1497 if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1498 result->lm_session_key = data_blob_null;
1500 result->lm_session_key = data_blob_talloc(
1501 result, info3->base.LMSessKey.key,
1502 sizeof(info3->base.LMSessKey.key));
1505 result->nss_token |= username_was_mapped;
1507 result->guest = (info3->base.user_flags & NETLOGON_GUEST);
1509 *server_info = result;
1511 return NT_STATUS_OK;
1514 /*****************************************************************************
1515 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1516 ******************************************************************************/
1518 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1519 const char *sent_nt_username,
1521 const struct wbcAuthUserInfo *info,
1522 struct auth_serversupplied_info **server_info)
1524 struct netr_SamInfo3 *info3;
1526 info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
1528 return NT_STATUS_NO_MEMORY;
1531 return make_server_info_info3(mem_ctx,
1532 sent_nt_username, domain,
1533 server_info, info3);
1537 * Verify whether or not given domain is trusted.
1539 * @param domain_name name of the domain to be verified
1540 * @return true if domain is one of the trusted ones or
1541 * false if otherwise
1544 bool is_trusted_domain(const char* dom_name)
1546 struct dom_sid trustdom_sid;
1549 /* no trusted domains for a standalone server */
1551 if ( lp_server_role() == ROLE_STANDALONE )
1554 if (dom_name == NULL || dom_name[0] == '\0') {
1558 if (strequal(dom_name, get_global_sam_name())) {
1562 /* if we are a DC, then check for a direct trust relationships */
1566 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1567 "[%s]\n", dom_name ));
1568 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1576 /* If winbind is around, ask it */
1578 result = wb_is_trusted_domain(dom_name);
1580 if (result == WBC_ERR_SUCCESS) {
1584 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1585 /* winbind could not find the domain */
1589 /* The only other possible result is that winbind is not up
1590 and running. We need to update the trustdom_cache
1593 update_trustdom_cache();
1596 /* now the trustdom cache should be available a DC could still
1597 * have a transitive trust so fall back to the cache of trusted
1598 * domains (like a domain member would use */
1600 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {