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-2008
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 "lib/util_unixsids.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"
34 #include "../librpc/gen_ndr/ndr_auth.h"
35 #include "../auth/auth_sam_reply.h"
36 #include "../librpc/gen_ndr/idmap.h"
37 #include "lib/param/loadparm.h"
38 #include "../lib/tsocket/tsocket.h"
39 #include "rpc_client/util_netlogon.h"
42 #define DBGC_CLASS DBGC_AUTH
44 /****************************************************************************
45 Create a UNIX user on demand.
46 ****************************************************************************/
48 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
50 TALLOC_CTX *ctx = talloc_tos();
54 add_script = lp_add_user_script(ctx);
55 if (!add_script || !*add_script) {
58 add_script = talloc_all_string_sub(ctx,
66 add_script = talloc_all_string_sub(ctx,
75 add_script = talloc_all_string_sub(ctx,
83 ret = smbrun(add_script, NULL, NULL);
86 ("smb_create_user: Running the command `%s' gave %d\n",
91 /****************************************************************************
92 Create an auth_usersupplied_data structure after appropriate mapping.
93 ****************************************************************************/
95 NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
96 struct auth_usersupplied_info **user_info,
98 const char *client_domain,
99 const char *workstation_name,
100 const struct tsocket_address *remote_address,
101 const struct tsocket_address *local_address,
102 const char *service_description,
103 const DATA_BLOB *lm_pwd,
104 const DATA_BLOB *nt_pwd,
105 const struct samr_Password *lm_interactive_pwd,
106 const struct samr_Password *nt_interactive_pwd,
107 const char *plaintext,
108 enum auth_password_state password_state)
113 char *internal_username = NULL;
115 was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
116 if (!internal_username) {
117 return NT_STATUS_NO_MEMORY;
120 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
121 client_domain, smb_name, workstation_name));
124 * We let the auth stack canonicalize, username
127 domain = client_domain;
129 result = make_user_info(mem_ctx, user_info, smb_name, internal_username,
130 client_domain, domain, workstation_name,
131 remote_address, local_address,
132 service_description, lm_pwd, nt_pwd,
133 lm_interactive_pwd, nt_interactive_pwd,
134 plaintext, password_state);
135 if (NT_STATUS_IS_OK(result)) {
136 /* We have tried mapping */
137 (*user_info)->mapped_state = true;
138 /* did we actually map the user to a different name? */
139 (*user_info)->was_mapped = was_mapped;
144 /****************************************************************************
145 Create an auth_usersupplied_data, making the DATA_BLOBs here.
146 Decrypt and encrypt the passwords.
147 ****************************************************************************/
149 bool make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
150 struct auth_usersupplied_info **user_info,
151 const char *smb_name,
152 const char *client_domain,
153 const char *workstation_name,
154 const struct tsocket_address *remote_address,
155 const struct tsocket_address *local_address,
156 uint32_t logon_parameters,
157 const uchar *lm_network_pwd,
159 const uchar *nt_network_pwd,
164 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
165 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
167 status = make_user_info_map(mem_ctx, user_info,
168 smb_name, client_domain,
173 lm_pwd_len ? &lm_blob : NULL,
174 nt_pwd_len ? &nt_blob : NULL,
176 AUTH_PASSWORD_RESPONSE);
178 if (NT_STATUS_IS_OK(status)) {
179 (*user_info)->logon_parameters = logon_parameters;
181 ret = NT_STATUS_IS_OK(status) ? true : false;
183 data_blob_free(&lm_blob);
184 data_blob_free(&nt_blob);
188 /****************************************************************************
189 Create an auth_usersupplied_data, making the DATA_BLOBs here.
190 Decrypt and encrypt the passwords.
191 ****************************************************************************/
193 bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
194 struct auth_usersupplied_info **user_info,
195 const char *smb_name,
196 const char *client_domain,
197 const char *workstation_name,
198 const struct tsocket_address *remote_address,
199 const struct tsocket_address *local_address,
200 uint32_t logon_parameters,
202 const uchar lm_interactive_pwd[16],
203 const uchar nt_interactive_pwd[16])
205 struct samr_Password lm_pwd;
206 struct samr_Password nt_pwd;
207 unsigned char local_lm_response[24];
208 unsigned char local_nt_response[24];
210 if (lm_interactive_pwd)
211 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
213 if (nt_interactive_pwd)
214 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
216 if (lm_interactive_pwd)
217 SMBOWFencrypt(lm_pwd.hash, chal,
220 if (nt_interactive_pwd)
221 SMBOWFencrypt(nt_pwd.hash, chal,
227 DATA_BLOB local_lm_blob = data_blob_null;
228 DATA_BLOB local_nt_blob = data_blob_null;
230 if (lm_interactive_pwd) {
231 local_lm_blob = data_blob(local_lm_response,
232 sizeof(local_lm_response));
235 if (nt_interactive_pwd) {
236 local_nt_blob = data_blob(local_nt_response,
237 sizeof(local_nt_response));
240 nt_status = make_user_info_map(
243 smb_name, client_domain, workstation_name,
247 lm_interactive_pwd ? &local_lm_blob : NULL,
248 nt_interactive_pwd ? &local_nt_blob : NULL,
249 lm_interactive_pwd ? &lm_pwd : NULL,
250 nt_interactive_pwd ? &nt_pwd : NULL,
251 NULL, AUTH_PASSWORD_HASH);
253 if (NT_STATUS_IS_OK(nt_status)) {
254 (*user_info)->logon_parameters = logon_parameters;
257 ret = NT_STATUS_IS_OK(nt_status) ? true : false;
258 data_blob_free(&local_lm_blob);
259 data_blob_free(&local_nt_blob);
265 /****************************************************************************
266 Create an auth_usersupplied_data structure
267 ****************************************************************************/
269 bool make_user_info_for_reply(TALLOC_CTX *mem_ctx,
270 struct auth_usersupplied_info **user_info,
271 const char *smb_name,
272 const char *client_domain,
273 const struct tsocket_address *remote_address,
274 const struct tsocket_address *local_address,
275 const char *service_description,
276 const uint8_t chal[8],
277 DATA_BLOB plaintext_password)
280 DATA_BLOB local_lm_blob;
281 DATA_BLOB local_nt_blob;
282 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
283 char *plaintext_password_string;
285 * Not encrypted - do so.
288 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
290 if (plaintext_password.data && plaintext_password.length) {
291 unsigned char local_lm_response[24];
293 #ifdef DEBUG_PASSWORD
294 DEBUG(10,("Unencrypted password (len %d):\n",
295 (int)plaintext_password.length));
296 dump_data(100, plaintext_password.data,
297 plaintext_password.length);
300 SMBencrypt( (const char *)plaintext_password.data,
301 (const uchar*)chal, local_lm_response);
302 local_lm_blob = data_blob(local_lm_response, 24);
304 /* We can't do an NT hash here, as the password needs to be
306 local_nt_blob = data_blob_null;
308 local_lm_blob = data_blob_null;
309 local_nt_blob = data_blob_null;
312 plaintext_password_string = talloc_strndup(talloc_tos(),
313 (const char *)plaintext_password.data,
314 plaintext_password.length);
315 if (!plaintext_password_string) {
319 ret = make_user_info(mem_ctx,
320 user_info, smb_name, smb_name, client_domain, client_domain,
321 get_remote_machine_name(),
325 local_lm_blob.data ? &local_lm_blob : NULL,
326 local_nt_blob.data ? &local_nt_blob : NULL,
328 plaintext_password_string,
329 AUTH_PASSWORD_PLAIN);
331 if (plaintext_password_string) {
332 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
333 talloc_free(plaintext_password_string);
336 data_blob_free(&local_lm_blob);
337 return NT_STATUS_IS_OK(ret) ? true : false;
340 /****************************************************************************
341 Create an auth_usersupplied_data structure
342 ****************************************************************************/
344 NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
345 struct auth_usersupplied_info **user_info,
346 const char *smb_name,
347 const char *client_domain,
348 const struct tsocket_address *remote_address,
349 const struct tsocket_address *local_address,
350 const char *service_description,
351 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
353 bool allow_raw = lp_raw_ntlmv2_auth();
355 if (!allow_raw && nt_resp.length >= 48) {
357 * NTLMv2_RESPONSE has at least 48 bytes
358 * and should only be supported via NTLMSSP.
360 DEBUG(2,("Rejecting raw NTLMv2 authentication with "
361 "user [%s\\%s] from[%s]\n",
362 client_domain, smb_name,
363 tsocket_address_string(remote_address, mem_ctx)));
364 return NT_STATUS_INVALID_PARAMETER;
367 return make_user_info(mem_ctx,
368 user_info, smb_name, smb_name,
369 client_domain, client_domain,
370 get_remote_machine_name(),
374 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
375 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
377 AUTH_PASSWORD_RESPONSE);
380 /****************************************************************************
381 Create a guest user_info blob, for anonymous authentication.
382 ****************************************************************************/
384 bool make_user_info_guest(TALLOC_CTX *mem_ctx,
385 const struct tsocket_address *remote_address,
386 const struct tsocket_address *local_address,
387 const char *service_description,
388 struct auth_usersupplied_info **user_info)
392 nt_status = make_user_info(mem_ctx,
403 AUTH_PASSWORD_RESPONSE);
405 return NT_STATUS_IS_OK(nt_status) ? true : false;
408 static NTSTATUS log_nt_token(struct security_token *token)
410 TALLOC_CTX *frame = talloc_stackframe();
415 if ((lp_log_nt_token_command(frame) == NULL) ||
416 (strlen(lp_log_nt_token_command(frame)) == 0)) {
421 group_sidstr = talloc_strdup(frame, "");
422 for (i=1; i<token->num_sids; i++) {
423 group_sidstr = talloc_asprintf(
424 frame, "%s %s", group_sidstr,
425 sid_string_talloc(frame, &token->sids[i]));
428 command = talloc_string_sub(
429 frame, lp_log_nt_token_command(frame),
430 "%s", sid_string_talloc(frame, &token->sids[0]));
431 command = talloc_string_sub(frame, command, "%t", group_sidstr);
433 if (command == NULL) {
435 return NT_STATUS_NO_MEMORY;
438 DEBUG(8, ("running command: [%s]\n", command));
439 if (smbrun(command, NULL, NULL) != 0) {
440 DEBUG(0, ("Could not log NT token\n"));
442 return NT_STATUS_ACCESS_DENIED;
450 * Create the token to use from server_info->info3 and
451 * server_info->sids (the info3/sam groups). Find the unix gids.
454 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
455 const struct auth_serversupplied_info *server_info,
456 DATA_BLOB *session_key,
457 const char *smb_username, /* for ->sanitized_username, for %U subs */
458 struct auth_session_info **session_info_out)
460 struct security_token *t;
463 struct dom_sid tmp_sid;
464 struct auth_session_info *session_info;
468 /* Ensure we can't possible take a code path leading to a
471 return NT_STATUS_LOGON_FAILURE;
474 session_info = talloc_zero(mem_ctx, struct auth_session_info);
476 return NT_STATUS_NO_MEMORY;
479 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
480 if (!session_info->unix_token) {
481 TALLOC_FREE(session_info);
482 return NT_STATUS_NO_MEMORY;
485 session_info->unix_token->uid = server_info->utok.uid;
486 session_info->unix_token->gid = server_info->utok.gid;
488 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
489 if (!session_info->unix_info) {
490 TALLOC_FREE(session_info);
491 return NT_STATUS_NO_MEMORY;
494 session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
495 if (!session_info->unix_info->unix_name) {
496 TALLOC_FREE(session_info);
497 return NT_STATUS_NO_MEMORY;
500 /* This is a potentially untrusted username for use in %U */
501 alpha_strcpy(tmp, smb_username, ". _-$", sizeof(tmp));
502 session_info->unix_info->sanitized_username =
503 talloc_strdup(session_info->unix_info, tmp);
506 data_blob_free(&session_info->session_key);
507 session_info->session_key = data_blob_talloc(session_info,
509 session_key->length);
510 if (!session_info->session_key.data && session_key->length) {
511 return NT_STATUS_NO_MEMORY;
514 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
515 server_info->session_key.length);
518 /* We need to populate session_info->info with the information found in server_info->info3 */
519 status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
520 server_info->guest == false,
521 &session_info->info);
522 if (!NT_STATUS_IS_OK(status)) {
523 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
524 TALLOC_FREE(session_info);
528 if (server_info->security_token) {
529 /* Just copy the token, it has already been finalised
530 * (nasty hack to support a cached guest/system session_info
533 session_info->security_token = dup_nt_token(session_info, server_info->security_token);
534 if (!session_info->security_token) {
535 TALLOC_FREE(session_info);
536 return NT_STATUS_NO_MEMORY;
539 session_info->unix_token->ngroups = server_info->utok.ngroups;
540 if (server_info->utok.ngroups != 0) {
541 session_info->unix_token->groups = (gid_t *)talloc_memdup(
542 session_info->unix_token, server_info->utok.groups,
543 sizeof(gid_t)*session_info->unix_token->ngroups);
545 session_info->unix_token->groups = NULL;
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 char *found_username = NULL;
561 status = create_token_from_username(session_info,
562 server_info->unix_name,
564 &session_info->unix_token->uid,
565 &session_info->unix_token->gid,
567 &session_info->security_token);
568 if (NT_STATUS_IS_OK(status)) {
569 session_info->unix_info->unix_name = found_username;
572 status = create_local_nt_token_from_info3(session_info,
576 &session_info->security_token);
579 if (!NT_STATUS_IS_OK(status)) {
583 /* Convert the SIDs to gids. */
585 session_info->unix_token->ngroups = 0;
586 session_info->unix_token->groups = NULL;
588 t = session_info->security_token;
590 ids = talloc_array(talloc_tos(), struct unixid,
593 return NT_STATUS_NO_MEMORY;
596 if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
598 return NT_STATUS_NO_MEMORY;
601 for (i=0; i<t->num_sids; i++) {
603 if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
607 if (ids[i].type != ID_TYPE_GID &&
608 ids[i].type != ID_TYPE_BOTH) {
609 DEBUG(10, ("Could not convert SID %s to gid, "
611 sid_string_dbg(&t->sids[i])));
614 if (!add_gid_to_array_unique(session_info->unix_token,
616 &session_info->unix_token->groups,
617 &session_info->unix_token->ngroups)) {
618 return NT_STATUS_NO_MEMORY;
623 * Add the "Unix Group" SID for each gid to catch mapped groups
624 * and their Unix equivalent. This is to solve the backwards
625 * compatibility problem of 'valid users = +ntadmin' where
626 * ntadmin has been paired with "Domain Admins" in the group
627 * mapping table. Otherwise smb.conf would need to be changed
628 * to 'valid user = "Domain Admins"'. --jerry
630 * For consistency we also add the "Unix User" SID,
631 * so that the complete unix token is represented within
635 uid_to_unix_users_sid(session_info->unix_token->uid, &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);
640 gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
641 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
642 &session_info->security_token->sids,
643 &session_info->security_token->num_sids);
645 for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
646 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
647 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
648 &session_info->security_token->sids,
649 &session_info->security_token->num_sids);
652 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
653 debug_unix_user_token(DBGC_AUTH, 10,
654 session_info->unix_token->uid,
655 session_info->unix_token->gid,
656 session_info->unix_token->ngroups,
657 session_info->unix_token->groups);
659 status = log_nt_token(session_info->security_token);
660 if (!NT_STATUS_IS_OK(status)) {
664 *session_info_out = session_info;
668 /***************************************************************************
669 Make (and fill) a server_info struct from a 'struct passwd' by conversion
671 ***************************************************************************/
673 NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
674 const char *unix_username,
675 const struct passwd *pwd,
676 struct auth_serversupplied_info **server_info)
679 TALLOC_CTX *tmp_ctx = NULL;
680 struct auth_serversupplied_info *result;
682 tmp_ctx = talloc_stackframe();
683 if (tmp_ctx == NULL) {
684 return NT_STATUS_NO_MEMORY;
687 result = make_server_info(tmp_ctx);
688 if (result == NULL) {
689 status = NT_STATUS_NO_MEMORY;
693 status = passwd_to_SamInfo3(result,
698 if (!NT_STATUS_IS_OK(status)) {
702 result->unix_name = talloc_strdup(result, unix_username);
703 if (result->unix_name == NULL) {
704 status = NT_STATUS_NO_MEMORY;
708 result->utok.uid = pwd->pw_uid;
709 result->utok.gid = pwd->pw_gid;
711 *server_info = talloc_steal(mem_ctx, result);
712 status = NT_STATUS_OK;
714 talloc_free(tmp_ctx);
719 static NTSTATUS get_system_info3(TALLOC_CTX *mem_ctx,
720 struct netr_SamInfo3 *info3)
724 /* Set account name */
725 init_lsa_String(&info3->base.account_name, "SYSTEM");
727 /* Set domain name */
728 init_lsa_StringLarge(&info3->base.logon_domain, "NT AUTHORITY");
731 status = dom_sid_split_rid(mem_ctx, &global_sid_System,
732 &info3->base.domain_sid,
734 if (!NT_STATUS_IS_OK(status)) {
738 /* Primary gid is the same */
739 info3->base.primary_gid = info3->base.rid;
744 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
745 struct netr_SamInfo3 *info3)
747 const char *guest_account = lp_guest_account();
748 struct dom_sid domain_sid;
752 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
754 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
755 "account [%s]!\n", guest_account));
756 return NT_STATUS_NO_SUCH_USER;
759 /* Set account name */
760 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
762 return NT_STATUS_NO_MEMORY;
764 init_lsa_String(&info3->base.account_name, tmp);
766 /* Set domain name */
767 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
769 return NT_STATUS_NO_MEMORY;
771 init_lsa_StringLarge(&info3->base.logon_domain, tmp);
774 sid_copy(&domain_sid, get_global_sam_sid());
776 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
777 if (info3->base.domain_sid == NULL) {
778 return NT_STATUS_NO_MEMORY;
782 info3->base.rid = DOMAIN_RID_GUEST;
785 info3->base.primary_gid = DOMAIN_RID_GUESTS;
788 info3->base.user_flags = NETLOGON_GUEST;
794 /***************************************************************************
795 Make (and fill) a user_info struct for a guest login.
796 This *must* succeed for smbd to start. If there is no mapping entry for
797 the guest gid, then create one.
799 The resulting structure is a 'session_info' because
800 create_local_token() has already been called on it. This is quite
801 nasty, as the auth subsystem isn't expect this, but the behavior is
803 ***************************************************************************/
805 static NTSTATUS make_new_session_info_guest(TALLOC_CTX *mem_ctx,
806 struct auth_session_info **_session_info,
807 struct auth_serversupplied_info **_server_info)
809 struct auth_session_info *session_info = NULL;
810 struct auth_serversupplied_info *server_info = NULL;
811 const char *guest_account = lp_guest_account();
812 const char *domain = lp_netbios_name();
813 struct netr_SamInfo3 info3;
817 tmp_ctx = talloc_stackframe();
818 if (tmp_ctx == NULL) {
819 return NT_STATUS_NO_MEMORY;
824 status = get_guest_info3(tmp_ctx, &info3);
825 if (!NT_STATUS_IS_OK(status)) {
826 DEBUG(0, ("get_guest_info3 failed with %s\n",
831 status = make_server_info_info3(tmp_ctx,
836 if (!NT_STATUS_IS_OK(status)) {
837 DEBUG(0, ("make_server_info_info3 failed with %s\n",
842 server_info->guest = true;
844 /* This should not be done here (we should produce a server
845 * info, and later construct a session info from it), but for
846 * now this does not change the previous behavior */
847 status = create_local_token(tmp_ctx, server_info, NULL,
848 server_info->info3->base.account_name.string,
850 if (!NT_STATUS_IS_OK(status)) {
851 DEBUG(0, ("create_local_token failed: %s\n",
856 /* annoying, but the Guest really does have a session key, and it is
858 session_info->session_key = data_blob_talloc_zero(session_info, 16);
860 *_session_info = talloc_move(mem_ctx, &session_info);
861 *_server_info = talloc_move(mem_ctx, &server_info);
863 status = NT_STATUS_OK;
865 TALLOC_FREE(tmp_ctx);
869 /***************************************************************************
870 Make (and fill) a auth_session_info struct for a system user login.
871 This *must* succeed for smbd to start.
872 ***************************************************************************/
874 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
875 struct auth_session_info **session_info)
878 struct auth_serversupplied_info *server_info;
881 tmp_ctx = talloc_stackframe();
882 if (tmp_ctx == NULL) {
883 return NT_STATUS_NO_MEMORY;
886 server_info = make_server_info(tmp_ctx);
888 status = NT_STATUS_NO_MEMORY;
889 DEBUG(0, ("failed making server_info\n"));
893 server_info->info3 = talloc_zero(server_info, struct netr_SamInfo3);
894 if (!server_info->info3) {
895 status = NT_STATUS_NO_MEMORY;
896 DEBUG(0, ("talloc failed setting info3\n"));
900 status = get_system_info3(server_info, server_info->info3);
901 if (!NT_STATUS_IS_OK(status)) {
902 DEBUG(0, ("Failed creating system info3 with %s\n",
907 server_info->utok.uid = sec_initial_uid();
908 server_info->utok.gid = sec_initial_gid();
909 server_info->unix_name = talloc_asprintf(server_info,
910 "NT AUTHORITY%cSYSTEM",
911 *lp_winbind_separator());
913 if (!server_info->unix_name) {
914 status = NT_STATUS_NO_MEMORY;
915 DEBUG(0, ("talloc_asprintf failed setting unix_name\n"));
919 server_info->security_token = talloc_zero(server_info, struct security_token);
920 if (!server_info->security_token) {
921 status = NT_STATUS_NO_MEMORY;
922 DEBUG(0, ("talloc failed setting security token\n"));
926 status = add_sid_to_array_unique(server_info->security_token->sids,
928 &server_info->security_token->sids,
929 &server_info->security_token->num_sids);
930 if (!NT_STATUS_IS_OK(status)) {
934 /* SYSTEM has all privilages */
935 server_info->security_token->privilege_mask = ~0;
937 /* Now turn the server_info into a session_info with the full token etc */
938 status = create_local_token(mem_ctx, server_info, NULL, "SYSTEM", session_info);
939 talloc_free(server_info);
941 if (!NT_STATUS_IS_OK(status)) {
942 DEBUG(0, ("create_local_token failed: %s\n",
947 talloc_steal(mem_ctx, *session_info);
950 TALLOC_FREE(tmp_ctx);
954 /****************************************************************************
955 Fake a auth_session_info just from a username (as a
956 session_info structure, with create_local_token() already called on
958 ****************************************************************************/
960 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
961 const char *username,
963 struct auth_session_info **session_info)
967 struct auth_serversupplied_info *result;
970 tmp_ctx = talloc_stackframe();
971 if (tmp_ctx == NULL) {
972 return NT_STATUS_NO_MEMORY;
975 pwd = Get_Pwnam_alloc(tmp_ctx, username);
977 status = NT_STATUS_NO_SUCH_USER;
981 status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
982 if (!NT_STATUS_IS_OK(status)) {
986 result->nss_token = true;
987 result->guest = is_guest;
989 /* Now turn the server_info into a session_info with the full token etc */
990 status = create_local_token(mem_ctx,
997 talloc_free(tmp_ctx);
1002 /* This function MUST only used to create the cached server_info for
1005 * This is a lossy conversion. Variables known to be lost so far
1008 * - nss_token (not needed because the only read doesn't happen
1009 * for the GUEST user, as this routine populates ->security_token
1011 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1013 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1015 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1016 const struct auth_session_info *src,
1017 struct auth_serversupplied_info *server_info)
1019 struct auth_serversupplied_info *dst;
1022 dst = make_server_info(mem_ctx);
1027 /* This element must be provided to convert back to an auth_serversupplied_info */
1028 SMB_ASSERT(src->unix_info);
1032 /* This element must be provided to convert back to an
1033 * auth_serversupplied_info. This needs to be from the
1034 * auth_session_info because the group values in particular
1035 * may change during create_local_token() processing */
1036 SMB_ASSERT(src->unix_token);
1037 dst->utok.uid = src->unix_token->uid;
1038 dst->utok.gid = src->unix_token->gid;
1039 dst->utok.ngroups = src->unix_token->ngroups;
1040 if (src->unix_token->ngroups != 0) {
1041 dst->utok.groups = (gid_t *)talloc_memdup(
1042 dst, src->unix_token->groups,
1043 sizeof(gid_t)*dst->utok.ngroups);
1045 dst->utok.groups = NULL;
1048 /* We must have a security_token as otherwise the lossy
1049 * conversion without nss_token would cause create_local_token
1050 * to take the wrong path */
1051 SMB_ASSERT(src->security_token);
1053 dst->security_token = dup_nt_token(dst, src->security_token);
1054 if (!dst->security_token) {
1059 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1060 src->session_key.length);
1062 /* This is OK because this functions is only used for the
1063 * GUEST account, which has all-zero keys for both values */
1064 dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1065 src->session_key.length);
1067 status = copy_netr_SamInfo3(dst,
1070 if (!NT_STATUS_IS_OK(status)) {
1075 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1076 if (!dst->unix_name) {
1084 struct auth_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
1085 const struct auth_session_info *src)
1087 struct auth_session_info *dst;
1089 enum ndr_err_code ndr_err;
1091 ndr_err = ndr_push_struct_blob(
1092 &blob, talloc_tos(), src,
1093 (ndr_push_flags_fn_t)ndr_push_auth_session_info);
1094 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1095 DEBUG(0, ("copy_session_info(): ndr_push_auth_session_info failed: "
1096 "%s\n", ndr_errstr(ndr_err)));
1100 dst = talloc(mem_ctx, struct auth_session_info);
1102 DEBUG(0, ("talloc failed\n"));
1103 TALLOC_FREE(blob.data);
1107 ndr_err = ndr_pull_struct_blob(
1109 (ndr_pull_flags_fn_t)ndr_pull_auth_session_info);
1110 TALLOC_FREE(blob.data);
1112 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1113 DEBUG(0, ("copy_session_info(): ndr_pull_auth_session_info failed: "
1114 "%s\n", ndr_errstr(ndr_err)));
1123 * Set a new session key. Used in the rpc server where we have to override the
1124 * SMB level session key with SystemLibraryDTC
1127 bool session_info_set_session_key(struct auth_session_info *info,
1128 DATA_BLOB session_key)
1130 TALLOC_FREE(info->session_key.data);
1132 info->session_key = data_blob_talloc(
1133 info, session_key.data, session_key.length);
1135 return (info->session_key.data != NULL);
1138 static struct auth_session_info *guest_info = NULL;
1140 static struct auth_serversupplied_info *guest_server_info = NULL;
1142 bool init_guest_session_info(TALLOC_CTX *mem_ctx)
1146 if (guest_info != NULL)
1149 status = make_new_session_info_guest(mem_ctx,
1151 &guest_server_info);
1152 return NT_STATUS_IS_OK(status);
1155 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1156 struct auth_serversupplied_info **server_info)
1158 /* This is trickier than it would appear to need to be because
1159 * we are trying to avoid certain costly operations when the
1160 * structure is converted to a 'auth_session_info' again in
1161 * create_local_token() */
1162 *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1163 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1166 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1167 struct auth_session_info **session_info)
1169 *session_info = copy_session_info(mem_ctx, guest_info);
1170 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1173 static struct auth_session_info *system_info = NULL;
1175 NTSTATUS init_system_session_info(TALLOC_CTX *mem_ctx)
1177 if (system_info != NULL)
1178 return NT_STATUS_OK;
1180 return make_new_session_info_system(mem_ctx, &system_info);
1183 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1184 struct auth_session_info **session_info)
1186 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1187 *session_info = copy_session_info(mem_ctx, system_info);
1188 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1191 const struct auth_session_info *get_session_info_system(void)
1196 /***************************************************************************
1197 Purely internal function for make_server_info_info3
1198 ***************************************************************************/
1200 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1201 const char *username, char **found_username,
1202 struct passwd **pwd,
1203 bool *username_was_mapped)
1205 char *orig_dom_user = NULL;
1206 char *dom_user = NULL;
1207 char *lower_username = NULL;
1208 char *real_username = NULL;
1209 struct passwd *passwd;
1211 lower_username = talloc_strdup(mem_ctx, username);
1212 if (!lower_username) {
1213 return NT_STATUS_NO_MEMORY;
1215 if (!strlower_m( lower_username )) {
1216 return NT_STATUS_INVALID_PARAMETER;
1219 orig_dom_user = talloc_asprintf(mem_ctx,
1222 *lp_winbind_separator(),
1224 if (!orig_dom_user) {
1225 return NT_STATUS_NO_MEMORY;
1228 /* Get the passwd struct. Try to create the account if necessary. */
1230 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1232 return NT_STATUS_NO_MEMORY;
1235 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
1237 DEBUG(3, ("Failed to find authenticated user %s via "
1238 "getpwnam(), denying access.\n", dom_user));
1239 return NT_STATUS_NO_SUCH_USER;
1242 if (!real_username) {
1243 return NT_STATUS_NO_MEMORY;
1248 /* This is pointless -- there is no support for differing
1249 unix and windows names. Make sure to always store the
1250 one we actually looked up and succeeded. Have I mentioned
1251 why I hate the 'winbind use default domain' parameter?
1254 *found_username = talloc_strdup( mem_ctx, real_username );
1256 return NT_STATUS_OK;
1259 /****************************************************************************
1260 Wrapper to allow the getpwnam() call to strip the domain name and
1261 try again in case a local UNIX user is already there. Also run through
1262 the username if we fallback to the username only.
1263 ****************************************************************************/
1265 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1266 char **p_save_username, bool create )
1268 struct passwd *pw = NULL;
1270 char *username = NULL;
1272 /* we only save a copy of the username it has been mangled
1273 by winbindd use default domain */
1274 *p_save_username = NULL;
1276 /* don't call map_username() here since it has to be done higher
1277 up the stack so we don't call it multiple times */
1279 username = talloc_strdup(mem_ctx, domuser);
1284 p = strchr_m( username, *lp_winbind_separator() );
1286 /* code for a DOMAIN\user string */
1289 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1291 /* make sure we get the case of the username correct */
1292 /* work around 'winbind use default domain = yes' */
1294 if ( lp_winbind_use_default_domain() &&
1295 !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1298 /* split the domain and username into 2 strings */
1302 *p_save_username = talloc_asprintf(mem_ctx,
1305 *lp_winbind_separator(),
1307 if (!*p_save_username) {
1312 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1319 /* setup for lookup of just the username */
1320 /* remember that p and username are overlapping memory */
1323 username = talloc_strdup(mem_ctx, p);
1329 /* just lookup a plain username */
1331 pw = Get_Pwnam_alloc(mem_ctx, username);
1333 /* Create local user if requested but only if winbindd
1334 is not running. We need to protect against cases
1335 where winbindd is failing and then prematurely
1336 creating users in /etc/passwd */
1338 if ( !pw && create && !winbind_ping() ) {
1339 /* Don't add a machine account. */
1340 if (username[strlen(username)-1] == '$')
1343 _smb_create_user(NULL, username, NULL);
1344 pw = Get_Pwnam_alloc(mem_ctx, username);
1347 /* one last check for a valid passwd struct */
1350 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1355 /***************************************************************************
1356 Make a server_info struct from the info3 returned by a domain logon
1357 ***************************************************************************/
1359 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1360 const char *sent_nt_username,
1362 struct auth_serversupplied_info **server_info,
1363 const struct netr_SamInfo3 *info3)
1365 NTSTATUS nt_status = NT_STATUS_OK;
1366 char *found_username = NULL;
1367 const char *nt_domain;
1368 const char *nt_username;
1369 struct dom_sid user_sid;
1370 struct dom_sid group_sid;
1371 bool username_was_mapped;
1373 struct auth_serversupplied_info *result;
1374 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1377 Here is where we should check the list of
1378 trusted domains, and verify that the SID
1382 if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
1383 nt_status = NT_STATUS_INVALID_PARAMETER;
1387 if (!sid_compose(&group_sid, info3->base.domain_sid,
1388 info3->base.primary_gid)) {
1389 nt_status = NT_STATUS_INVALID_PARAMETER;
1393 nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
1395 /* If the server didn't give us one, just use the one we sent
1397 nt_username = sent_nt_username;
1400 nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
1402 /* If the server didn't give us one, just use the one we sent
1407 /* If getpwnam() fails try the add user script (2.2.x behavior).
1409 We use the _unmapped_ username here in an attempt to provide
1410 consistent username mapping behavior between kerberos and NTLM[SSP]
1411 authentication in domain mode security. I.E. Username mapping
1412 should be applied to the fully qualified username
1413 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1414 called map_username() unnecessarily in make_user_info_map() but
1415 that is how the current code is designed. Making the change here
1416 is the least disruptive place. -- jerry */
1418 /* this call will try to create the user if necessary */
1420 nt_status = check_account(tmp_ctx,
1425 &username_was_mapped);
1427 if (!NT_STATUS_IS_OK(nt_status)) {
1428 /* Handle 'map to guest = Bad Uid */
1429 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
1430 (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
1431 lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
1432 DBG_NOTICE("Try to map %s to guest account",
1434 nt_status = make_server_info_guest(tmp_ctx, &result);
1435 if (NT_STATUS_IS_OK(nt_status)) {
1436 *server_info = talloc_move(mem_ctx, &result);
1442 result = make_server_info(tmp_ctx);
1443 if (result == NULL) {
1444 DEBUG(4, ("make_server_info failed!\n"));
1445 nt_status = NT_STATUS_NO_MEMORY;
1449 result->unix_name = talloc_strdup(result, found_username);
1451 /* copy in the info3 */
1452 nt_status = copy_netr_SamInfo3(result,
1455 if (!NT_STATUS_IS_OK(nt_status)) {
1459 /* Fill in the unix info we found on the way */
1461 result->utok.uid = pwd->pw_uid;
1462 result->utok.gid = pwd->pw_gid;
1464 /* ensure we are never given NULL session keys */
1466 if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
1467 result->session_key = data_blob_null;
1469 result->session_key = data_blob_talloc(
1470 result, info3->base.key.key,
1471 sizeof(info3->base.key.key));
1474 if (all_zero(info3->base.LMSessKey.key,
1475 sizeof(info3->base.LMSessKey.key))) {
1476 result->lm_session_key = data_blob_null;
1478 result->lm_session_key = data_blob_talloc(
1479 result, info3->base.LMSessKey.key,
1480 sizeof(info3->base.LMSessKey.key));
1483 result->nss_token |= username_was_mapped;
1485 result->guest = (info3->base.user_flags & NETLOGON_GUEST);
1487 *server_info = talloc_move(mem_ctx, &result);
1489 nt_status = NT_STATUS_OK;
1491 talloc_free(tmp_ctx);
1496 /*****************************************************************************
1497 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1498 ******************************************************************************/
1500 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1501 const char *sent_nt_username,
1503 const struct wbcAuthUserInfo *info,
1504 struct auth_serversupplied_info **server_info)
1506 struct netr_SamInfo3 info3;
1507 struct netr_SamInfo6 *info6;
1509 info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
1511 return NT_STATUS_NO_MEMORY;
1514 info3.base = info6->base;
1515 info3.sidcount = info6->sidcount;
1516 info3.sids = info6->sids;
1518 return make_server_info_info3(mem_ctx,
1519 sent_nt_username, domain,
1520 server_info, &info3);
1524 * Verify whether or not given domain is trusted.
1526 * This should only be used on a DC.
1528 * @param domain_name name of the domain to be verified
1529 * @return true if domain is one of the trusted ones or
1530 * false if otherwise
1533 bool is_trusted_domain(const char* dom_name)
1541 if (dom_name == NULL || dom_name[0] == '\0') {
1545 if (strequal(dom_name, get_global_sam_name())) {
1550 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1551 "[%s]\n", dom_name ));
1552 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1561 on a logon error possibly map the error to success if "map to guest"
1564 NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
1568 struct auth_serversupplied_info **server_info)
1570 user = user ? user : "";
1571 domain = domain ? domain : "";
1573 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1574 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
1575 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
1576 DEBUG(3,("No such user %s [%s] - using guest account\n",
1578 return make_server_info_guest(mem_ctx, server_info);
1580 } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1581 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
1582 DEBUG(3,("Registered username %s for guest access\n",
1584 return make_server_info_guest(mem_ctx, server_info);
1592 Extract session key from a session info and return it in a blob
1593 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
1595 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
1596 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
1598 Note that returned session_key is referencing the original key, it is supposed to be
1599 short-lived. If original session_info->session_key is gone, the reference will be broken.
1601 NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
1604 if (session_key == NULL || session_info == NULL) {
1605 return NT_STATUS_INVALID_PARAMETER;
1608 if (session_info->session_key.length == 0) {
1609 return NT_STATUS_NO_USER_SESSION_KEY;
1612 *session_key = session_info->session_key;
1613 if (intent == KEY_USE_16BYTES) {
1614 session_key->length = MIN(session_info->session_key.length, 16);
1616 return NT_STATUS_OK;