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"
40 #include "source4/auth/auth.h"
41 #include "auth/auth_util.h"
44 #define DBGC_CLASS DBGC_AUTH
46 /****************************************************************************
47 Create a UNIX user on demand.
48 ****************************************************************************/
50 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
52 TALLOC_CTX *ctx = talloc_tos();
56 add_script = lp_add_user_script(ctx);
57 if (!add_script || !*add_script) {
60 add_script = talloc_all_string_sub(ctx,
68 add_script = talloc_all_string_sub(ctx,
77 add_script = talloc_all_string_sub(ctx,
85 ret = smbrun(add_script, NULL, NULL);
88 ("smb_create_user: Running the command `%s' gave %d\n",
93 /****************************************************************************
94 Create an auth_usersupplied_data structure after appropriate mapping.
95 ****************************************************************************/
97 NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
98 struct auth_usersupplied_info **user_info,
100 const char *client_domain,
101 const char *workstation_name,
102 const struct tsocket_address *remote_address,
103 const struct tsocket_address *local_address,
104 const char *service_description,
105 const DATA_BLOB *lm_pwd,
106 const DATA_BLOB *nt_pwd,
107 const struct samr_Password *lm_interactive_pwd,
108 const struct samr_Password *nt_interactive_pwd,
109 const char *plaintext,
110 enum auth_password_state password_state)
115 char *internal_username = NULL;
117 was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
118 if (!internal_username) {
119 return NT_STATUS_NO_MEMORY;
122 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
123 client_domain, smb_name, workstation_name));
126 * We let the auth stack canonicalize, username
129 domain = client_domain;
131 result = make_user_info(mem_ctx, user_info, smb_name, internal_username,
132 client_domain, domain, workstation_name,
133 remote_address, local_address,
134 service_description, lm_pwd, nt_pwd,
135 lm_interactive_pwd, nt_interactive_pwd,
136 plaintext, password_state);
137 if (NT_STATUS_IS_OK(result)) {
138 /* We have tried mapping */
139 (*user_info)->mapped_state = true;
140 /* did we actually map the user to a different name? */
141 (*user_info)->was_mapped = was_mapped;
146 /****************************************************************************
147 Create an auth_usersupplied_data, making the DATA_BLOBs here.
148 Decrypt and encrypt the passwords.
149 ****************************************************************************/
151 bool make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
152 struct auth_usersupplied_info **user_info,
153 const char *smb_name,
154 const char *client_domain,
155 const char *workstation_name,
156 const struct tsocket_address *remote_address,
157 const struct tsocket_address *local_address,
158 uint32_t logon_parameters,
159 const uchar *lm_network_pwd,
161 const uchar *nt_network_pwd,
166 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
167 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
169 status = make_user_info_map(mem_ctx, user_info,
170 smb_name, client_domain,
175 lm_pwd_len ? &lm_blob : NULL,
176 nt_pwd_len ? &nt_blob : NULL,
178 AUTH_PASSWORD_RESPONSE);
180 if (NT_STATUS_IS_OK(status)) {
181 (*user_info)->logon_parameters = logon_parameters;
183 ret = NT_STATUS_IS_OK(status) ? true : false;
185 data_blob_free(&lm_blob);
186 data_blob_free(&nt_blob);
190 /****************************************************************************
191 Create an auth_usersupplied_data, making the DATA_BLOBs here.
192 Decrypt and encrypt the passwords.
193 ****************************************************************************/
195 bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
196 struct auth_usersupplied_info **user_info,
197 const char *smb_name,
198 const char *client_domain,
199 const char *workstation_name,
200 const struct tsocket_address *remote_address,
201 const struct tsocket_address *local_address,
202 uint32_t logon_parameters,
204 const uchar lm_interactive_pwd[16],
205 const uchar nt_interactive_pwd[16])
207 struct samr_Password lm_pwd;
208 struct samr_Password nt_pwd;
209 unsigned char local_lm_response[24];
210 unsigned char local_nt_response[24];
212 if (lm_interactive_pwd)
213 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
215 if (nt_interactive_pwd)
216 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
218 if (lm_interactive_pwd)
219 SMBOWFencrypt(lm_pwd.hash, chal,
222 if (nt_interactive_pwd)
223 SMBOWFencrypt(nt_pwd.hash, chal,
229 DATA_BLOB local_lm_blob = data_blob_null;
230 DATA_BLOB local_nt_blob = data_blob_null;
232 if (lm_interactive_pwd) {
233 local_lm_blob = data_blob(local_lm_response,
234 sizeof(local_lm_response));
237 if (nt_interactive_pwd) {
238 local_nt_blob = data_blob(local_nt_response,
239 sizeof(local_nt_response));
242 nt_status = make_user_info_map(
245 smb_name, client_domain, workstation_name,
249 lm_interactive_pwd ? &local_lm_blob : NULL,
250 nt_interactive_pwd ? &local_nt_blob : NULL,
251 lm_interactive_pwd ? &lm_pwd : NULL,
252 nt_interactive_pwd ? &nt_pwd : NULL,
253 NULL, AUTH_PASSWORD_HASH);
255 if (NT_STATUS_IS_OK(nt_status)) {
256 (*user_info)->logon_parameters = logon_parameters;
259 ret = NT_STATUS_IS_OK(nt_status) ? true : false;
260 data_blob_free(&local_lm_blob);
261 data_blob_free(&local_nt_blob);
267 /****************************************************************************
268 Create an auth_usersupplied_data structure
269 ****************************************************************************/
271 bool make_user_info_for_reply(TALLOC_CTX *mem_ctx,
272 struct auth_usersupplied_info **user_info,
273 const char *smb_name,
274 const char *client_domain,
275 const struct tsocket_address *remote_address,
276 const struct tsocket_address *local_address,
277 const char *service_description,
278 const uint8_t chal[8],
279 DATA_BLOB plaintext_password)
282 DATA_BLOB local_lm_blob;
283 DATA_BLOB local_nt_blob;
284 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
285 char *plaintext_password_string;
287 * Not encrypted - do so.
290 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
292 if (plaintext_password.data && plaintext_password.length) {
293 unsigned char local_lm_response[24];
295 #ifdef DEBUG_PASSWORD
296 DEBUG(10,("Unencrypted password (len %d):\n",
297 (int)plaintext_password.length));
298 dump_data(100, plaintext_password.data,
299 plaintext_password.length);
302 SMBencrypt( (const char *)plaintext_password.data,
303 (const uchar*)chal, local_lm_response);
304 local_lm_blob = data_blob(local_lm_response, 24);
306 /* We can't do an NT hash here, as the password needs to be
308 local_nt_blob = data_blob_null;
310 local_lm_blob = data_blob_null;
311 local_nt_blob = data_blob_null;
314 plaintext_password_string = talloc_strndup(talloc_tos(),
315 (const char *)plaintext_password.data,
316 plaintext_password.length);
317 if (!plaintext_password_string) {
321 ret = make_user_info(mem_ctx,
322 user_info, smb_name, smb_name, client_domain, client_domain,
323 get_remote_machine_name(),
327 local_lm_blob.data ? &local_lm_blob : NULL,
328 local_nt_blob.data ? &local_nt_blob : NULL,
330 plaintext_password_string,
331 AUTH_PASSWORD_PLAIN);
333 if (plaintext_password_string) {
334 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
335 talloc_free(plaintext_password_string);
338 data_blob_free(&local_lm_blob);
339 return NT_STATUS_IS_OK(ret) ? true : false;
342 /****************************************************************************
343 Create an auth_usersupplied_data structure
344 ****************************************************************************/
346 NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
347 struct auth_usersupplied_info **user_info,
348 const char *smb_name,
349 const char *client_domain,
350 const struct tsocket_address *remote_address,
351 const struct tsocket_address *local_address,
352 const char *service_description,
353 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
355 bool allow_raw = lp_raw_ntlmv2_auth();
357 if (!allow_raw && nt_resp.length >= 48) {
359 * NTLMv2_RESPONSE has at least 48 bytes
360 * and should only be supported via NTLMSSP.
362 DEBUG(2,("Rejecting raw NTLMv2 authentication with "
363 "user [%s\\%s] from[%s]\n",
364 client_domain, smb_name,
365 tsocket_address_string(remote_address, mem_ctx)));
366 return NT_STATUS_INVALID_PARAMETER;
369 return make_user_info(mem_ctx,
370 user_info, smb_name, smb_name,
371 client_domain, client_domain,
372 get_remote_machine_name(),
376 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
377 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
379 AUTH_PASSWORD_RESPONSE);
382 /****************************************************************************
383 Create a guest user_info blob, for anonymous authentication.
384 ****************************************************************************/
386 bool make_user_info_guest(TALLOC_CTX *mem_ctx,
387 const struct tsocket_address *remote_address,
388 const struct tsocket_address *local_address,
389 const char *service_description,
390 struct auth_usersupplied_info **user_info)
394 nt_status = make_user_info(mem_ctx,
405 AUTH_PASSWORD_RESPONSE);
407 return NT_STATUS_IS_OK(nt_status) ? true : false;
410 static NTSTATUS log_nt_token(struct security_token *token)
412 TALLOC_CTX *frame = talloc_stackframe();
415 struct dom_sid_buf buf;
418 if ((lp_log_nt_token_command(frame) == NULL) ||
419 (strlen(lp_log_nt_token_command(frame)) == 0)) {
424 group_sidstr = talloc_strdup(frame, "");
425 for (i=1; i<token->num_sids; i++) {
426 group_sidstr = talloc_asprintf(
427 frame, "%s %s", group_sidstr,
428 dom_sid_str_buf(&token->sids[i], &buf));
431 command = talloc_string_sub(
432 frame, lp_log_nt_token_command(frame),
433 "%s", dom_sid_str_buf(&token->sids[0], &buf));
434 command = talloc_string_sub(frame, command, "%t", group_sidstr);
436 if (command == NULL) {
438 return NT_STATUS_NO_MEMORY;
441 DEBUG(8, ("running command: [%s]\n", command));
442 if (smbrun(command, NULL, NULL) != 0) {
443 DEBUG(0, ("Could not log NT token\n"));
445 return NT_STATUS_ACCESS_DENIED;
453 * Create the token to use from server_info->info3 and
454 * server_info->sids (the info3/sam groups). Find the unix gids.
457 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
458 const struct auth_serversupplied_info *server_info,
459 DATA_BLOB *session_key,
460 const char *smb_username, /* for ->sanitized_username, for %U subs */
461 struct auth_session_info **session_info_out)
463 struct security_token *t;
466 struct dom_sid tmp_sid;
467 struct auth_session_info *session_info;
471 /* Ensure we can't possible take a code path leading to a
474 return NT_STATUS_LOGON_FAILURE;
477 if (server_info->cached_session_info != NULL) {
478 session_info = copy_session_info(mem_ctx,
479 server_info->cached_session_info);
480 if (session_info == NULL) {
481 return NT_STATUS_NO_MEMORY;
484 /* This is a potentially untrusted username for use in %U */
485 alpha_strcpy(tmp, smb_username, ". _-$", sizeof(tmp));
486 session_info->unix_info->sanitized_username =
487 talloc_strdup(session_info->unix_info, tmp);
488 if (session_info->unix_info->sanitized_username == NULL) {
489 TALLOC_FREE(session_info);
490 return NT_STATUS_NO_MEMORY;
493 session_info->unique_session_token = GUID_random();
495 *session_info_out = session_info;
499 session_info = talloc_zero(mem_ctx, struct auth_session_info);
501 return NT_STATUS_NO_MEMORY;
504 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
505 if (!session_info->unix_token) {
506 TALLOC_FREE(session_info);
507 return NT_STATUS_NO_MEMORY;
510 session_info->unix_token->uid = server_info->utok.uid;
511 session_info->unix_token->gid = server_info->utok.gid;
513 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
514 if (!session_info->unix_info) {
515 TALLOC_FREE(session_info);
516 return NT_STATUS_NO_MEMORY;
519 session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
520 if (!session_info->unix_info->unix_name) {
521 TALLOC_FREE(session_info);
522 return NT_STATUS_NO_MEMORY;
525 /* This is a potentially untrusted username for use in %U */
526 alpha_strcpy(tmp, smb_username, ". _-$", sizeof(tmp));
527 session_info->unix_info->sanitized_username =
528 talloc_strdup(session_info->unix_info, tmp);
531 data_blob_free(&session_info->session_key);
532 session_info->session_key = data_blob_talloc(session_info,
534 session_key->length);
535 if (!session_info->session_key.data && session_key->length) {
536 return NT_STATUS_NO_MEMORY;
539 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
540 server_info->session_key.length);
543 /* We need to populate session_info->info with the information found in server_info->info3 */
544 status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
545 server_info->guest == false,
546 &session_info->info);
547 if (!NT_STATUS_IS_OK(status)) {
548 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
549 TALLOC_FREE(session_info);
554 * If winbind is not around, we can not make much use of the SIDs the
555 * domain controller provided us with. Likewise if the user name was
556 * mapped to some local unix user.
559 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
560 (server_info->nss_token)) {
561 char *found_username = NULL;
562 status = create_token_from_username(session_info,
563 server_info->unix_name,
565 &session_info->unix_token->uid,
566 &session_info->unix_token->gid,
568 &session_info->security_token);
569 if (NT_STATUS_IS_OK(status)) {
570 session_info->unix_info->unix_name = found_username;
573 status = create_local_nt_token_from_info3(session_info,
577 &session_info->security_token);
580 if (!NT_STATUS_IS_OK(status)) {
584 /* Convert the SIDs to gids. */
586 session_info->unix_token->ngroups = 0;
587 session_info->unix_token->groups = NULL;
589 t = session_info->security_token;
591 ids = talloc_array(talloc_tos(), struct unixid,
594 return NT_STATUS_NO_MEMORY;
597 if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
599 return NT_STATUS_NO_MEMORY;
602 for (i=0; i<t->num_sids; i++) {
604 if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
608 if (ids[i].type != ID_TYPE_GID &&
609 ids[i].type != ID_TYPE_BOTH) {
610 DEBUG(10, ("Could not convert SID %s to gid, "
612 sid_string_dbg(&t->sids[i])));
615 if (!add_gid_to_array_unique(session_info->unix_token,
617 &session_info->unix_token->groups,
618 &session_info->unix_token->ngroups)) {
619 return NT_STATUS_NO_MEMORY;
624 * Add the "Unix Group" SID for each gid to catch mapped groups
625 * and their Unix equivalent. This is to solve the backwards
626 * compatibility problem of 'valid users = +ntadmin' where
627 * ntadmin has been paired with "Domain Admins" in the group
628 * mapping table. Otherwise smb.conf would need to be changed
629 * to 'valid user = "Domain Admins"'. --jerry
631 * For consistency we also add the "Unix User" SID,
632 * so that the complete unix token is represented within
636 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
637 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
638 &session_info->security_token->sids,
639 &session_info->security_token->num_sids);
641 gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
642 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
643 &session_info->security_token->sids,
644 &session_info->security_token->num_sids);
646 for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
647 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
648 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
649 &session_info->security_token->sids,
650 &session_info->security_token->num_sids);
653 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
654 debug_unix_user_token(DBGC_AUTH, 10,
655 session_info->unix_token->uid,
656 session_info->unix_token->gid,
657 session_info->unix_token->ngroups,
658 session_info->unix_token->groups);
660 status = log_nt_token(session_info->security_token);
661 if (!NT_STATUS_IS_OK(status)) {
665 session_info->unique_session_token = GUID_random();
667 *session_info_out = session_info;
671 NTSTATUS auth3_user_info_dc_add_hints(struct auth_user_info_dc *user_info_dc,
676 uint32_t orig_num_sids = user_info_dc->num_sids;
677 struct dom_sid tmp_sid = { 0, };
681 * We add S-5-88-1-X in order to pass the uid
682 * for the unix token.
684 sid_compose(&tmp_sid,
685 &global_sid_Unix_NFS_Users,
687 status = add_sid_to_array_unique(user_info_dc->sids,
690 &user_info_dc->num_sids);
691 if (!NT_STATUS_IS_OK(status)) {
692 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
698 * We add S-5-88-2-X in order to pass the gid
699 * for the unix token.
701 sid_compose(&tmp_sid,
702 &global_sid_Unix_NFS_Groups,
704 status = add_sid_to_array_unique(user_info_dc->sids,
707 &user_info_dc->num_sids);
708 if (!NT_STATUS_IS_OK(status)) {
709 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
715 * We add S-5-88-3-X in order to pass some flags
716 * (AUTH3_UNIX_HINT_*) to auth3_create_session_info().
718 sid_compose(&tmp_sid,
719 &global_sid_Unix_NFS_Mode,
721 status = add_sid_to_array_unique(user_info_dc->sids,
724 &user_info_dc->num_sids);
725 if (!NT_STATUS_IS_OK(status)) {
726 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
734 user_info_dc->num_sids = orig_num_sids;
738 NTSTATUS auth3_session_info_create(TALLOC_CTX *mem_ctx,
739 const struct auth_user_info_dc *user_info_dc,
740 const char *original_user_name,
741 uint32_t session_info_flags,
742 struct auth_session_info **session_info_out)
744 TALLOC_CTX *frame = talloc_stackframe();
745 struct auth_session_info *session_info = NULL;
747 bool found_hint_uid = false;
749 bool found_hint_gid = false;
750 uint32_t hint_flags = 0;
751 bool found_hint_flags = false;
752 bool need_getpwuid = false;
753 struct unixid *ids = NULL;
754 uint32_t num_gids = 0;
756 struct dom_sid tmp_sid = { 0, };
757 fstring tmp = { 0, };
762 *session_info_out = NULL;
764 if (user_info_dc->num_sids == 0) {
766 return NT_STATUS_INVALID_TOKEN;
769 if (user_info_dc->info == NULL) {
771 return NT_STATUS_INVALID_TOKEN;
774 if (user_info_dc->info->account_name == NULL) {
776 return NT_STATUS_INVALID_TOKEN;
779 session_info = talloc_zero(mem_ctx, struct auth_session_info);
780 if (session_info == NULL) {
782 return NT_STATUS_NO_MEMORY;
784 /* keep this under frame for easier cleanup */
785 talloc_reparent(mem_ctx, frame, session_info);
787 session_info->info = auth_user_info_copy(session_info,
789 if (session_info->info == NULL) {
791 return NT_STATUS_NO_MEMORY;
794 session_info->security_token = talloc_zero(session_info,
795 struct security_token);
796 if (session_info->security_token == NULL) {
798 return NT_STATUS_NO_MEMORY;
802 * Avoid a lot of reallocations and allocate what we'll
805 session_info->security_token->sids = talloc_zero_array(
806 session_info->security_token,
808 user_info_dc->num_sids);
809 if (session_info->security_token->sids == NULL) {
811 return NT_STATUS_NO_MEMORY;
814 for (i = PRIMARY_USER_SID_INDEX; i < user_info_dc->num_sids; i++) {
815 struct security_token *nt_token = session_info->security_token;
819 * S-1-5-88-X-Y sids are only used to give hints
820 * to the unix token construction.
822 * S-1-5-88-1-Y gives the uid=Y
823 * S-1-5-88-2-Y gives the gid=Y
824 * S-1-5-88-3-Y gives flags=Y: AUTH3_UNIX_HINT_*
826 cmp = dom_sid_compare_domain(&global_sid_Unix_NFS,
827 &user_info_dc->sids[i]);
832 match = sid_peek_rid(&user_info_dc->sids[i], &hint);
837 match = dom_sid_in_domain(&global_sid_Unix_NFS_Users,
838 &user_info_dc->sids[i]);
840 if (found_hint_uid) {
842 return NT_STATUS_INVALID_TOKEN;
844 found_hint_uid = true;
845 hint_uid = (uid_t)hint;
849 match = dom_sid_in_domain(&global_sid_Unix_NFS_Groups,
850 &user_info_dc->sids[i]);
852 if (found_hint_gid) {
854 return NT_STATUS_INVALID_TOKEN;
856 found_hint_gid = true;
857 hint_gid = (gid_t)hint;
861 match = dom_sid_in_domain(&global_sid_Unix_NFS_Mode,
862 &user_info_dc->sids[i]);
864 if (found_hint_flags) {
866 return NT_STATUS_INVALID_TOKEN;
868 found_hint_flags = true;
876 status = add_sid_to_array_unique(nt_token->sids,
877 &user_info_dc->sids[i],
879 &nt_token->num_sids);
880 if (!NT_STATUS_IS_OK(status)) {
887 * We need at least one usable SID
889 if (session_info->security_token->num_sids == 0) {
891 return NT_STATUS_INVALID_TOKEN;
895 * We need all tree hints: uid, gid, flags
898 if (found_hint_uid || found_hint_gid || found_hint_flags) {
899 if (!found_hint_uid) {
901 return NT_STATUS_INVALID_TOKEN;
904 if (!found_hint_gid) {
906 return NT_STATUS_INVALID_TOKEN;
909 if (!found_hint_flags) {
911 return NT_STATUS_INVALID_TOKEN;
915 if (session_info->info->authenticated) {
916 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
919 status = finalize_local_nt_token(session_info->security_token,
921 if (!NT_STATUS_IS_OK(status)) {
927 * unless set otherwise, the session key is the user session
928 * key from the auth subsystem
930 if (user_info_dc->user_session_key.length != 0) {
931 session_info->session_key = data_blob_dup_talloc(session_info,
932 user_info_dc->user_session_key);
933 if (session_info->session_key.data == NULL) {
935 return NT_STATUS_NO_MEMORY;
939 if (!(session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)) {
943 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
944 if (session_info->unix_token == NULL) {
946 return NT_STATUS_NO_MEMORY;
948 session_info->unix_token->uid = -1;
949 session_info->unix_token->gid = -1;
951 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
952 if (session_info->unix_info == NULL) {
954 return NT_STATUS_NO_MEMORY;
957 /* Convert the SIDs to uid/gids. */
959 ids = talloc_zero_array(frame, struct unixid,
960 session_info->security_token->num_sids);
963 return NT_STATUS_NO_MEMORY;
966 if (!(hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS)) {
967 ok = sids_to_unixids(session_info->security_token->sids,
968 session_info->security_token->num_sids,
972 return NT_STATUS_NO_MEMORY;
976 if (found_hint_uid) {
977 session_info->unix_token->uid = hint_uid;
978 } else if (ids[0].type == ID_TYPE_UID) {
980 * The primary SID resolves to a UID only.
982 session_info->unix_token->uid = ids[0].id;
983 } else if (ids[0].type == ID_TYPE_BOTH) {
985 * The primary SID resolves to a UID and GID,
986 * use it as uid and add it as first element
987 * to the groups array.
989 session_info->unix_token->uid = ids[0].id;
991 ok = add_gid_to_array_unique(session_info->unix_token,
992 session_info->unix_token->uid,
993 &session_info->unix_token->groups,
994 &session_info->unix_token->ngroups);
997 return NT_STATUS_NO_MEMORY;
1001 * It we can't get a uid, we can't imporsonate
1005 return NT_STATUS_INVALID_TOKEN;
1008 if (found_hint_gid) {
1009 session_info->unix_token->gid = hint_gid;
1011 need_getpwuid = true;
1014 if (hint_flags & AUTH3_UNIX_HINT_QUALIFIED_NAME) {
1015 session_info->unix_info->unix_name =
1016 talloc_asprintf(session_info->unix_info,
1018 session_info->info->domain_name,
1019 *lp_winbind_separator(),
1020 session_info->info->account_name);
1021 if (session_info->unix_info->unix_name == NULL) {
1023 return NT_STATUS_NO_MEMORY;
1025 } else if (hint_flags & AUTH3_UNIX_HINT_ISLOLATED_NAME) {
1026 session_info->unix_info->unix_name =
1027 talloc_strdup(session_info->unix_info,
1028 session_info->info->account_name);
1029 if (session_info->unix_info->unix_name == NULL) {
1031 return NT_STATUS_NO_MEMORY;
1034 need_getpwuid = true;
1037 if (need_getpwuid) {
1038 struct passwd *pwd = NULL;
1041 * Ask the system for the primary gid
1042 * and the real unix name.
1044 pwd = getpwuid_alloc(frame, session_info->unix_token->uid);
1047 return NT_STATUS_INVALID_TOKEN;
1049 if (!found_hint_gid) {
1050 session_info->unix_token->gid = pwd->pw_gid;
1053 session_info->unix_info->unix_name =
1054 talloc_strdup(session_info->unix_info, pwd->pw_name);
1055 if (session_info->unix_info->unix_name == NULL) {
1057 return NT_STATUS_NO_MEMORY;
1063 ok = add_gid_to_array_unique(session_info->unix_token,
1064 session_info->unix_token->gid,
1065 &session_info->unix_token->groups,
1066 &session_info->unix_token->ngroups);
1069 return NT_STATUS_NO_MEMORY;
1072 /* This is a potentially untrusted username for use in %U */
1073 alpha_strcpy(tmp, original_user_name, ". _-$", sizeof(tmp));
1074 session_info->unix_info->sanitized_username =
1075 talloc_strdup(session_info->unix_info, tmp);
1076 if (session_info->unix_info->sanitized_username == NULL) {
1078 return NT_STATUS_NO_MEMORY;
1081 for (i=0; i < session_info->security_token->num_sids; i++) {
1083 if (ids[i].type != ID_TYPE_GID &&
1084 ids[i].type != ID_TYPE_BOTH) {
1085 struct security_token *nt_token =
1086 session_info->security_token;
1088 DEBUG(10, ("Could not convert SID %s to gid, "
1090 sid_string_dbg(&nt_token->sids[i])));
1094 ok = add_gid_to_array_unique(session_info->unix_token,
1096 &session_info->unix_token->groups,
1097 &session_info->unix_token->ngroups);
1100 return NT_STATUS_NO_MEMORY;
1106 * Now we must get any groups this user has been
1107 * added to in /etc/group and merge them in.
1108 * This has to be done in every code path
1109 * that creates an NT token, as remote users
1110 * may have been added to the local /etc/group
1111 * database. Tokens created merely from the
1112 * info3 structs (via the DC or via the krb5 PAC)
1113 * won't have these local groups. Note the
1114 * groups added here will only be UNIX groups
1115 * (S-1-22-2-XXXX groups) as getgroups_unix_user()
1116 * turns off winbindd before calling getgroups().
1118 * NB. This is duplicating work already
1119 * done in the 'unix_user:' case of
1120 * create_token_from_sid() but won't
1121 * do anything other than be inefficient
1124 if (!(hint_flags & AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS)) {
1125 ok = getgroups_unix_user(frame,
1126 session_info->unix_info->unix_name,
1127 session_info->unix_token->gid,
1131 return NT_STATUS_INVALID_TOKEN;
1135 for (i=0; i < num_gids; i++) {
1137 ok = add_gid_to_array_unique(session_info->unix_token,
1139 &session_info->unix_token->groups,
1140 &session_info->unix_token->ngroups);
1143 return NT_STATUS_NO_MEMORY;
1148 if (hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS) {
1150 * We should not translate the unix token uid/gids
1151 * to S-1-22-X-Y SIDs.
1157 * Add the "Unix Group" SID for each gid to catch mapped groups
1158 * and their Unix equivalent. This is to solve the backwards
1159 * compatibility problem of 'valid users = +ntadmin' where
1160 * ntadmin has been paired with "Domain Admins" in the group
1161 * mapping table. Otherwise smb.conf would need to be changed
1162 * to 'valid user = "Domain Admins"'. --jerry
1164 * For consistency we also add the "Unix User" SID,
1165 * so that the complete unix token is represented within
1169 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
1170 status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1171 &session_info->security_token->sids,
1172 &session_info->security_token->num_sids);
1173 if (!NT_STATUS_IS_OK(status)) {
1178 gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
1179 status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1180 &session_info->security_token->sids,
1181 &session_info->security_token->num_sids);
1182 if (!NT_STATUS_IS_OK(status)) {
1187 for (i=0; i < session_info->unix_token->ngroups; i++ ) {
1188 struct security_token *nt_token = session_info->security_token;
1190 gid_to_unix_groups_sid(session_info->unix_token->groups[i],
1192 status = add_sid_to_array_unique(nt_token->sids,
1195 &nt_token->num_sids);
1196 if (!NT_STATUS_IS_OK(status)) {
1203 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
1204 if (session_info->unix_token != NULL) {
1205 debug_unix_user_token(DBGC_AUTH, 10,
1206 session_info->unix_token->uid,
1207 session_info->unix_token->gid,
1208 session_info->unix_token->ngroups,
1209 session_info->unix_token->groups);
1212 status = log_nt_token(session_info->security_token);
1213 if (!NT_STATUS_IS_OK(status)) {
1218 session_info->unique_session_token = GUID_random();
1220 *session_info_out = talloc_move(mem_ctx, &session_info);
1222 return NT_STATUS_OK;
1225 /***************************************************************************
1226 Make (and fill) a server_info struct from a 'struct passwd' by conversion
1228 ***************************************************************************/
1230 NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
1231 const char *unix_username,
1232 const struct passwd *pwd,
1233 struct auth_serversupplied_info **server_info)
1236 TALLOC_CTX *tmp_ctx = NULL;
1237 struct auth_serversupplied_info *result;
1239 tmp_ctx = talloc_stackframe();
1240 if (tmp_ctx == NULL) {
1241 return NT_STATUS_NO_MEMORY;
1244 result = make_server_info(tmp_ctx);
1245 if (result == NULL) {
1246 status = NT_STATUS_NO_MEMORY;
1250 status = passwd_to_SamInfo3(result,
1255 if (!NT_STATUS_IS_OK(status)) {
1259 result->unix_name = talloc_strdup(result, unix_username);
1260 if (result->unix_name == NULL) {
1261 status = NT_STATUS_NO_MEMORY;
1265 result->utok.uid = pwd->pw_uid;
1266 result->utok.gid = pwd->pw_gid;
1268 *server_info = talloc_steal(mem_ctx, result);
1269 status = NT_STATUS_OK;
1271 talloc_free(tmp_ctx);
1276 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
1277 struct netr_SamInfo3 *info3)
1279 const char *guest_account = lp_guest_account();
1280 struct dom_sid domain_sid;
1284 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
1286 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
1287 "account [%s]!\n", guest_account));
1288 return NT_STATUS_NO_SUCH_USER;
1291 /* Set account name */
1292 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
1294 return NT_STATUS_NO_MEMORY;
1296 init_lsa_String(&info3->base.account_name, tmp);
1298 /* Set domain name */
1299 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
1301 return NT_STATUS_NO_MEMORY;
1303 init_lsa_StringLarge(&info3->base.logon_domain, tmp);
1306 sid_copy(&domain_sid, get_global_sam_sid());
1308 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
1309 if (info3->base.domain_sid == NULL) {
1310 return NT_STATUS_NO_MEMORY;
1314 info3->base.rid = DOMAIN_RID_GUEST;
1317 info3->base.primary_gid = DOMAIN_RID_GUESTS;
1320 info3->base.user_flags = NETLOGON_GUEST;
1323 return NT_STATUS_OK;
1326 /***************************************************************************
1327 Make (and fill) a user_info struct for a guest login.
1328 This *must* succeed for smbd to start. If there is no mapping entry for
1329 the guest gid, then create one.
1331 The resulting structure is a 'session_info' because
1332 create_local_token() has already been called on it. This is quite
1333 nasty, as the auth subsystem isn't expect this, but the behavior is
1335 ***************************************************************************/
1337 static NTSTATUS make_new_session_info_guest(TALLOC_CTX *mem_ctx,
1338 struct auth_session_info **_session_info,
1339 struct auth_serversupplied_info **_server_info)
1341 struct auth_session_info *session_info = NULL;
1342 struct auth_serversupplied_info *server_info = NULL;
1343 const char *guest_account = lp_guest_account();
1344 const char *domain = lp_netbios_name();
1345 struct netr_SamInfo3 info3;
1346 TALLOC_CTX *tmp_ctx;
1349 tmp_ctx = talloc_stackframe();
1350 if (tmp_ctx == NULL) {
1351 return NT_STATUS_NO_MEMORY;
1356 status = get_guest_info3(tmp_ctx, &info3);
1357 if (!NT_STATUS_IS_OK(status)) {
1358 DEBUG(0, ("get_guest_info3 failed with %s\n",
1359 nt_errstr(status)));
1363 status = make_server_info_info3(tmp_ctx,
1368 if (!NT_STATUS_IS_OK(status)) {
1369 DEBUG(0, ("make_server_info_info3 failed with %s\n",
1370 nt_errstr(status)));
1374 server_info->guest = true;
1376 /* This should not be done here (we should produce a server
1377 * info, and later construct a session info from it), but for
1378 * now this does not change the previous behavior */
1379 status = create_local_token(tmp_ctx, server_info, NULL,
1380 server_info->info3->base.account_name.string,
1382 if (!NT_STATUS_IS_OK(status)) {
1383 DEBUG(0, ("create_local_token failed: %s\n",
1384 nt_errstr(status)));
1388 /* annoying, but the Guest really does have a session key, and it is
1390 session_info->session_key = data_blob_talloc_zero(session_info, 16);
1392 *_session_info = talloc_move(mem_ctx, &session_info);
1393 *_server_info = talloc_move(mem_ctx, &server_info);
1395 status = NT_STATUS_OK;
1397 TALLOC_FREE(tmp_ctx);
1401 /***************************************************************************
1402 Make (and fill) a auth_session_info struct for a system user login.
1403 This *must* succeed for smbd to start.
1404 ***************************************************************************/
1406 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
1407 struct auth_session_info **session_info)
1409 TALLOC_CTX *frame = talloc_stackframe();
1410 struct auth_user_info_dc *user_info_dc = NULL;
1413 uint32_t hint_flags = 0;
1414 uint32_t session_info_flags = 0;
1417 status = auth_system_user_info_dc(frame, lp_netbios_name(),
1419 if (!NT_STATUS_IS_OK(status)) {
1420 DEBUG(0, ("auth_system_user_info_dc failed: %s\n",
1421 nt_errstr(status)));
1426 * Just get the initial uid/gid
1427 * and don't expand the unix groups.
1429 uid = sec_initial_uid();
1430 gid = sec_initial_gid();
1431 hint_flags |= AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS;
1434 * Also avoid sid mapping to gids,
1435 * as well as adding the unix_token uid/gids as
1436 * S-1-22-X-Y SIDs to the nt token.
1438 hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS;
1439 hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS;
1442 * The unix name will be "NT AUTHORITY+SYSTEM",
1443 * where '+' is the "winbind separator" character.
1445 hint_flags |= AUTH3_UNIX_HINT_QUALIFIED_NAME;
1446 status = auth3_user_info_dc_add_hints(user_info_dc,
1450 if (!NT_STATUS_IS_OK(status)) {
1451 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1452 nt_errstr(status)));
1456 session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1457 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1458 status = auth3_session_info_create(mem_ctx, user_info_dc,
1459 user_info_dc->info->account_name,
1462 if (!NT_STATUS_IS_OK(status)) {
1463 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1464 nt_errstr(status)));
1473 static NTSTATUS make_new_session_info_anonymous(TALLOC_CTX *mem_ctx,
1474 struct auth_session_info **session_info)
1476 TALLOC_CTX *frame = talloc_stackframe();
1477 const char *guest_account = lp_guest_account();
1478 struct auth_user_info_dc *user_info_dc = NULL;
1479 struct passwd *pwd = NULL;
1480 uint32_t hint_flags = 0;
1481 uint32_t session_info_flags = 0;
1485 * We use the guest account for the unix token
1486 * while we use a true anonymous nt token.
1488 * It's very important to have a separate
1489 * nt token for anonymous.
1492 pwd = Get_Pwnam_alloc(frame, guest_account);
1494 DBG_ERR("Unable to locate guest account [%s]!\n",
1496 status = NT_STATUS_NO_SUCH_USER;
1500 status = auth_anonymous_user_info_dc(frame, lp_netbios_name(),
1502 if (!NT_STATUS_IS_OK(status)) {
1503 DEBUG(0, ("auth_anonymous_user_info_dc failed: %s\n",
1504 nt_errstr(status)));
1509 * Note we don't pass AUTH3_UNIX_HINT_QUALIFIED_NAME
1510 * nor AUTH3_UNIX_HINT_ISOLATED_NAME here
1511 * as we want the unix name be found by getpwuid_alloc().
1514 status = auth3_user_info_dc_add_hints(user_info_dc,
1518 if (!NT_STATUS_IS_OK(status)) {
1519 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1520 nt_errstr(status)));
1525 * In future we may want to remove
1526 * AUTH_SESSION_INFO_DEFAULT_GROUPS.
1528 * Similar to Windows with EveryoneIncludesAnonymous
1529 * and RestrictAnonymous.
1531 * We may introduce AUTH_SESSION_INFO_ANON_WORLD...
1533 * But for this is required to keep the existing tests
1536 session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
1537 session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1538 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1539 status = auth3_session_info_create(mem_ctx, user_info_dc,
1543 if (!NT_STATUS_IS_OK(status)) {
1544 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1545 nt_errstr(status)));
1554 /****************************************************************************
1555 Fake a auth_session_info just from a username (as a
1556 session_info structure, with create_local_token() already called on
1558 ****************************************************************************/
1560 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
1561 const char *username,
1563 struct auth_session_info **session_info)
1567 struct auth_serversupplied_info *result;
1568 TALLOC_CTX *tmp_ctx;
1570 tmp_ctx = talloc_stackframe();
1571 if (tmp_ctx == NULL) {
1572 return NT_STATUS_NO_MEMORY;
1575 pwd = Get_Pwnam_alloc(tmp_ctx, username);
1577 status = NT_STATUS_NO_SUCH_USER;
1581 status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
1582 if (!NT_STATUS_IS_OK(status)) {
1586 result->nss_token = true;
1587 result->guest = is_guest;
1589 /* Now turn the server_info into a session_info with the full token etc */
1590 status = create_local_token(mem_ctx,
1597 talloc_free(tmp_ctx);
1602 /* This function MUST only used to create the cached server_info for
1605 * This is a lossy conversion. Variables known to be lost so far
1608 * - nss_token (not needed because the only read doesn't happen
1609 * for the GUEST user, as this routine populates ->security_token
1611 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1613 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1615 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1616 const struct auth_session_info *src,
1617 struct auth_serversupplied_info *server_info)
1619 struct auth_serversupplied_info *dst;
1622 dst = make_server_info(mem_ctx);
1627 /* This element must be provided to convert back to an auth_serversupplied_info */
1628 SMB_ASSERT(src->unix_info);
1632 /* This element must be provided to convert back to an
1633 * auth_serversupplied_info. This needs to be from the
1634 * auth_session_info because the group values in particular
1635 * may change during create_local_token() processing */
1636 SMB_ASSERT(src->unix_token);
1637 dst->utok.uid = src->unix_token->uid;
1638 dst->utok.gid = src->unix_token->gid;
1639 dst->utok.ngroups = src->unix_token->ngroups;
1640 if (src->unix_token->ngroups != 0) {
1641 dst->utok.groups = (gid_t *)talloc_memdup(
1642 dst, src->unix_token->groups,
1643 sizeof(gid_t)*dst->utok.ngroups);
1645 dst->utok.groups = NULL;
1648 /* We must have a security_token as otherwise the lossy
1649 * conversion without nss_token would cause create_local_token
1650 * to take the wrong path */
1651 SMB_ASSERT(src->security_token);
1653 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1654 src->session_key.length);
1656 /* This is OK because this functions is only used for the
1657 * GUEST account, which has all-zero keys for both values */
1658 dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1659 src->session_key.length);
1661 status = copy_netr_SamInfo3(dst,
1664 if (!NT_STATUS_IS_OK(status)) {
1669 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1670 if (!dst->unix_name) {
1675 dst->cached_session_info = src;
1680 * Set a new session key. Used in the rpc server where we have to override the
1681 * SMB level session key with SystemLibraryDTC
1684 bool session_info_set_session_key(struct auth_session_info *info,
1685 DATA_BLOB session_key)
1687 TALLOC_FREE(info->session_key.data);
1689 info->session_key = data_blob_talloc(
1690 info, session_key.data, session_key.length);
1692 return (info->session_key.data != NULL);
1695 static struct auth_session_info *guest_info = NULL;
1696 static struct auth_session_info *anonymous_info = NULL;
1698 static struct auth_serversupplied_info *guest_server_info = NULL;
1700 bool init_guest_session_info(TALLOC_CTX *mem_ctx)
1704 if (guest_info != NULL)
1707 status = make_new_session_info_guest(mem_ctx,
1709 &guest_server_info);
1710 if (!NT_STATUS_IS_OK(status)) {
1714 status = make_new_session_info_anonymous(mem_ctx,
1716 if (!NT_STATUS_IS_OK(status)) {
1723 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1724 struct auth_serversupplied_info **server_info)
1726 /* This is trickier than it would appear to need to be because
1727 * we are trying to avoid certain costly operations when the
1728 * structure is converted to a 'auth_session_info' again in
1729 * create_local_token() */
1730 *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1731 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1734 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1735 struct auth_session_info **session_info)
1737 *session_info = copy_session_info(mem_ctx, guest_info);
1738 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1741 NTSTATUS make_server_info_anonymous(TALLOC_CTX *mem_ctx,
1742 struct auth_serversupplied_info **server_info)
1744 if (anonymous_info == NULL) {
1745 return NT_STATUS_UNSUCCESSFUL;
1749 * This is trickier than it would appear to need to be because
1750 * we are trying to avoid certain costly operations when the
1751 * structure is converted to a 'auth_session_info' again in
1752 * create_local_token()
1754 * We use a guest server_info, but with the anonymous session info,
1755 * which means create_local_token() will return a copy
1756 * of the anonymous token.
1758 * The server info is just used as legacy in order to
1759 * keep existing code working. Maybe some debug messages
1760 * will still refer to guest instead of anonymous.
1762 *server_info = copy_session_info_serverinfo_guest(mem_ctx, anonymous_info,
1764 if (*server_info == NULL) {
1765 return NT_STATUS_NO_MEMORY;
1768 return NT_STATUS_OK;
1771 NTSTATUS make_session_info_anonymous(TALLOC_CTX *mem_ctx,
1772 struct auth_session_info **session_info)
1774 if (anonymous_info == NULL) {
1775 return NT_STATUS_UNSUCCESSFUL;
1778 *session_info = copy_session_info(mem_ctx, anonymous_info);
1779 if (*session_info == NULL) {
1780 return NT_STATUS_NO_MEMORY;
1783 return NT_STATUS_OK;
1786 static struct auth_session_info *system_info = NULL;
1788 NTSTATUS init_system_session_info(TALLOC_CTX *mem_ctx)
1790 if (system_info != NULL)
1791 return NT_STATUS_OK;
1793 return make_new_session_info_system(mem_ctx, &system_info);
1796 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1797 struct auth_session_info **session_info)
1799 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1800 *session_info = copy_session_info(mem_ctx, system_info);
1801 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1804 const struct auth_session_info *get_session_info_system(void)
1809 /***************************************************************************
1810 Purely internal function for make_server_info_info3
1811 ***************************************************************************/
1813 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1814 const char *username, char **found_username,
1815 struct passwd **pwd,
1816 bool *username_was_mapped)
1818 char *orig_dom_user = NULL;
1819 char *dom_user = NULL;
1820 char *lower_username = NULL;
1821 char *real_username = NULL;
1822 struct passwd *passwd;
1824 lower_username = talloc_strdup(mem_ctx, username);
1825 if (!lower_username) {
1826 return NT_STATUS_NO_MEMORY;
1828 if (!strlower_m( lower_username )) {
1829 return NT_STATUS_INVALID_PARAMETER;
1832 orig_dom_user = talloc_asprintf(mem_ctx,
1835 *lp_winbind_separator(),
1837 if (!orig_dom_user) {
1838 return NT_STATUS_NO_MEMORY;
1841 /* Get the passwd struct. Try to create the account if necessary. */
1843 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1845 return NT_STATUS_NO_MEMORY;
1848 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
1850 DEBUG(3, ("Failed to find authenticated user %s via "
1851 "getpwnam(), denying access.\n", dom_user));
1852 return NT_STATUS_NO_SUCH_USER;
1855 if (!real_username) {
1856 return NT_STATUS_NO_MEMORY;
1861 /* This is pointless -- there is no support for differing
1862 unix and windows names. Make sure to always store the
1863 one we actually looked up and succeeded. Have I mentioned
1864 why I hate the 'winbind use default domain' parameter?
1867 *found_username = talloc_strdup( mem_ctx, real_username );
1869 return NT_STATUS_OK;
1872 /****************************************************************************
1873 Wrapper to allow the getpwnam() call to strip the domain name and
1874 try again in case a local UNIX user is already there. Also run through
1875 the username if we fallback to the username only.
1876 ****************************************************************************/
1878 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1879 char **p_save_username, bool create )
1881 struct passwd *pw = NULL;
1883 char *username = NULL;
1885 /* we only save a copy of the username it has been mangled
1886 by winbindd use default domain */
1887 *p_save_username = NULL;
1889 /* don't call map_username() here since it has to be done higher
1890 up the stack so we don't call it multiple times */
1892 username = talloc_strdup(mem_ctx, domuser);
1897 p = strchr_m( username, *lp_winbind_separator() );
1899 /* code for a DOMAIN\user string */
1902 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1904 /* make sure we get the case of the username correct */
1905 /* work around 'winbind use default domain = yes' */
1907 if ( lp_winbind_use_default_domain() &&
1908 !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1911 /* split the domain and username into 2 strings */
1915 *p_save_username = talloc_asprintf(mem_ctx,
1918 *lp_winbind_separator(),
1920 if (!*p_save_username) {
1925 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1932 /* setup for lookup of just the username */
1933 /* remember that p and username are overlapping memory */
1936 username = talloc_strdup(mem_ctx, p);
1942 /* just lookup a plain username */
1944 pw = Get_Pwnam_alloc(mem_ctx, username);
1946 /* Create local user if requested but only if winbindd
1947 is not running. We need to protect against cases
1948 where winbindd is failing and then prematurely
1949 creating users in /etc/passwd */
1951 if ( !pw && create && !winbind_ping() ) {
1952 /* Don't add a machine account. */
1953 if (username[strlen(username)-1] == '$')
1956 _smb_create_user(NULL, username, NULL);
1957 pw = Get_Pwnam_alloc(mem_ctx, username);
1960 /* one last check for a valid passwd struct */
1963 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1968 /***************************************************************************
1969 Make a server_info struct from the info3 returned by a domain logon
1970 ***************************************************************************/
1972 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1973 const char *sent_nt_username,
1975 struct auth_serversupplied_info **server_info,
1976 const struct netr_SamInfo3 *info3)
1978 NTSTATUS nt_status = NT_STATUS_OK;
1979 char *found_username = NULL;
1980 const char *nt_domain;
1981 const char *nt_username;
1982 struct dom_sid user_sid;
1983 struct dom_sid group_sid;
1984 bool username_was_mapped;
1986 struct auth_serversupplied_info *result;
1987 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1990 Here is where we should check the list of
1991 trusted domains, and verify that the SID
1995 if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
1996 nt_status = NT_STATUS_INVALID_PARAMETER;
2000 if (!sid_compose(&group_sid, info3->base.domain_sid,
2001 info3->base.primary_gid)) {
2002 nt_status = NT_STATUS_INVALID_PARAMETER;
2006 nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
2008 /* If the server didn't give us one, just use the one we sent
2010 nt_username = sent_nt_username;
2013 nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
2015 /* If the server didn't give us one, just use the one we sent
2020 /* If getpwnam() fails try the add user script (2.2.x behavior).
2022 We use the _unmapped_ username here in an attempt to provide
2023 consistent username mapping behavior between kerberos and NTLM[SSP]
2024 authentication in domain mode security. I.E. Username mapping
2025 should be applied to the fully qualified username
2026 (e.g. DOMAIN\user) and not just the login name. Yes this means we
2027 called map_username() unnecessarily in make_user_info_map() but
2028 that is how the current code is designed. Making the change here
2029 is the least disruptive place. -- jerry */
2031 /* this call will try to create the user if necessary */
2033 nt_status = check_account(tmp_ctx,
2038 &username_was_mapped);
2040 if (!NT_STATUS_IS_OK(nt_status)) {
2041 /* Handle 'map to guest = Bad Uid */
2042 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
2043 (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
2044 lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
2045 DBG_NOTICE("Try to map %s to guest account",
2047 nt_status = make_server_info_guest(tmp_ctx, &result);
2048 if (NT_STATUS_IS_OK(nt_status)) {
2049 *server_info = talloc_move(mem_ctx, &result);
2055 result = make_server_info(tmp_ctx);
2056 if (result == NULL) {
2057 DEBUG(4, ("make_server_info failed!\n"));
2058 nt_status = NT_STATUS_NO_MEMORY;
2062 result->unix_name = talloc_strdup(result, found_username);
2064 /* copy in the info3 */
2065 nt_status = copy_netr_SamInfo3(result,
2068 if (!NT_STATUS_IS_OK(nt_status)) {
2072 /* Fill in the unix info we found on the way */
2074 result->utok.uid = pwd->pw_uid;
2075 result->utok.gid = pwd->pw_gid;
2077 /* ensure we are never given NULL session keys */
2079 if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
2080 result->session_key = data_blob_null;
2082 result->session_key = data_blob_talloc(
2083 result, info3->base.key.key,
2084 sizeof(info3->base.key.key));
2087 if (all_zero(info3->base.LMSessKey.key,
2088 sizeof(info3->base.LMSessKey.key))) {
2089 result->lm_session_key = data_blob_null;
2091 result->lm_session_key = data_blob_talloc(
2092 result, info3->base.LMSessKey.key,
2093 sizeof(info3->base.LMSessKey.key));
2096 result->nss_token |= username_was_mapped;
2098 result->guest = (info3->base.user_flags & NETLOGON_GUEST);
2100 *server_info = talloc_move(mem_ctx, &result);
2102 nt_status = NT_STATUS_OK;
2104 talloc_free(tmp_ctx);
2109 /*****************************************************************************
2110 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
2111 ******************************************************************************/
2113 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
2114 const char *sent_nt_username,
2116 const struct wbcAuthUserInfo *info,
2117 struct auth_serversupplied_info **server_info)
2119 struct netr_SamInfo3 info3;
2120 struct netr_SamInfo6 *info6;
2122 info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
2124 return NT_STATUS_NO_MEMORY;
2127 info3.base = info6->base;
2128 info3.sidcount = info6->sidcount;
2129 info3.sids = info6->sids;
2131 return make_server_info_info3(mem_ctx,
2132 sent_nt_username, domain,
2133 server_info, &info3);
2137 * Verify whether or not given domain is trusted.
2139 * This should only be used on a DC.
2141 * @param domain_name name of the domain to be verified
2142 * @return true if domain is one of the trusted ones or
2143 * false if otherwise
2146 bool is_trusted_domain(const char* dom_name)
2154 if (dom_name == NULL || dom_name[0] == '\0') {
2158 if (strequal(dom_name, get_global_sam_name())) {
2163 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2164 "[%s]\n", dom_name ));
2165 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2174 on a logon error possibly map the error to success if "map to guest"
2177 NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
2181 struct auth_serversupplied_info **server_info)
2183 user = user ? user : "";
2184 domain = domain ? domain : "";
2186 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2187 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
2188 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
2189 DEBUG(3,("No such user %s [%s] - using guest account\n",
2191 return make_server_info_guest(mem_ctx, server_info);
2193 } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2194 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
2195 DEBUG(3,("Registered username %s for guest access\n",
2197 return make_server_info_guest(mem_ctx, server_info);
2205 Extract session key from a session info and return it in a blob
2206 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
2208 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
2209 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
2211 Note that returned session_key is referencing the original key, it is supposed to be
2212 short-lived. If original session_info->session_key is gone, the reference will be broken.
2214 NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
2217 if (session_key == NULL || session_info == NULL) {
2218 return NT_STATUS_INVALID_PARAMETER;
2221 if (session_info->session_key.length == 0) {
2222 return NT_STATUS_NO_USER_SESSION_KEY;
2225 *session_key = session_info->session_key;
2226 if (intent == KEY_USE_16BYTES) {
2227 session_key->length = MIN(session_info->session_key.length, 16);
2229 return NT_STATUS_OK;