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"
43 #define DBGC_CLASS DBGC_AUTH
45 /****************************************************************************
46 Create a UNIX user on demand.
47 ****************************************************************************/
49 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
51 TALLOC_CTX *ctx = talloc_tos();
55 add_script = lp_add_user_script(ctx);
56 if (!add_script || !*add_script) {
59 add_script = talloc_all_string_sub(ctx,
67 add_script = talloc_all_string_sub(ctx,
76 add_script = talloc_all_string_sub(ctx,
84 ret = smbrun(add_script, NULL, NULL);
87 ("smb_create_user: Running the command `%s' gave %d\n",
92 /****************************************************************************
93 Create an auth_usersupplied_data structure after appropriate mapping.
94 ****************************************************************************/
96 NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
97 struct auth_usersupplied_info **user_info,
99 const char *client_domain,
100 const char *workstation_name,
101 const struct tsocket_address *remote_address,
102 const struct tsocket_address *local_address,
103 const char *service_description,
104 const DATA_BLOB *lm_pwd,
105 const DATA_BLOB *nt_pwd,
106 const struct samr_Password *lm_interactive_pwd,
107 const struct samr_Password *nt_interactive_pwd,
108 const char *plaintext,
109 enum auth_password_state password_state)
114 char *internal_username = NULL;
116 was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
117 if (!internal_username) {
118 return NT_STATUS_NO_MEMORY;
121 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
122 client_domain, smb_name, workstation_name));
125 * We let the auth stack canonicalize, username
128 domain = client_domain;
130 result = make_user_info(mem_ctx, user_info, smb_name, internal_username,
131 client_domain, domain, workstation_name,
132 remote_address, local_address,
133 service_description, lm_pwd, nt_pwd,
134 lm_interactive_pwd, nt_interactive_pwd,
135 plaintext, password_state);
136 if (NT_STATUS_IS_OK(result)) {
137 /* We have tried mapping */
138 (*user_info)->mapped_state = true;
139 /* did we actually map the user to a different name? */
140 (*user_info)->was_mapped = was_mapped;
145 /****************************************************************************
146 Create an auth_usersupplied_data, making the DATA_BLOBs here.
147 Decrypt and encrypt the passwords.
148 ****************************************************************************/
150 bool make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
151 struct auth_usersupplied_info **user_info,
152 const char *smb_name,
153 const char *client_domain,
154 const char *workstation_name,
155 const struct tsocket_address *remote_address,
156 const struct tsocket_address *local_address,
157 uint32_t logon_parameters,
158 const uchar *lm_network_pwd,
160 const uchar *nt_network_pwd,
165 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
166 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
168 status = make_user_info_map(mem_ctx, user_info,
169 smb_name, client_domain,
174 lm_pwd_len ? &lm_blob : NULL,
175 nt_pwd_len ? &nt_blob : NULL,
177 AUTH_PASSWORD_RESPONSE);
179 if (NT_STATUS_IS_OK(status)) {
180 (*user_info)->logon_parameters = logon_parameters;
182 ret = NT_STATUS_IS_OK(status) ? true : false;
184 data_blob_free(&lm_blob);
185 data_blob_free(&nt_blob);
189 /****************************************************************************
190 Create an auth_usersupplied_data, making the DATA_BLOBs here.
191 Decrypt and encrypt the passwords.
192 ****************************************************************************/
194 bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
195 struct auth_usersupplied_info **user_info,
196 const char *smb_name,
197 const char *client_domain,
198 const char *workstation_name,
199 const struct tsocket_address *remote_address,
200 const struct tsocket_address *local_address,
201 uint32_t logon_parameters,
203 const uchar lm_interactive_pwd[16],
204 const uchar nt_interactive_pwd[16])
206 struct samr_Password lm_pwd;
207 struct samr_Password nt_pwd;
208 unsigned char local_lm_response[24];
209 unsigned char local_nt_response[24];
211 if (lm_interactive_pwd)
212 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
214 if (nt_interactive_pwd)
215 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
217 if (lm_interactive_pwd)
218 SMBOWFencrypt(lm_pwd.hash, chal,
221 if (nt_interactive_pwd)
222 SMBOWFencrypt(nt_pwd.hash, chal,
228 DATA_BLOB local_lm_blob = data_blob_null;
229 DATA_BLOB local_nt_blob = data_blob_null;
231 if (lm_interactive_pwd) {
232 local_lm_blob = data_blob(local_lm_response,
233 sizeof(local_lm_response));
236 if (nt_interactive_pwd) {
237 local_nt_blob = data_blob(local_nt_response,
238 sizeof(local_nt_response));
241 nt_status = make_user_info_map(
244 smb_name, client_domain, workstation_name,
248 lm_interactive_pwd ? &local_lm_blob : NULL,
249 nt_interactive_pwd ? &local_nt_blob : NULL,
250 lm_interactive_pwd ? &lm_pwd : NULL,
251 nt_interactive_pwd ? &nt_pwd : NULL,
252 NULL, AUTH_PASSWORD_HASH);
254 if (NT_STATUS_IS_OK(nt_status)) {
255 (*user_info)->logon_parameters = logon_parameters;
258 ret = NT_STATUS_IS_OK(nt_status) ? true : false;
259 data_blob_free(&local_lm_blob);
260 data_blob_free(&local_nt_blob);
266 /****************************************************************************
267 Create an auth_usersupplied_data structure
268 ****************************************************************************/
270 bool make_user_info_for_reply(TALLOC_CTX *mem_ctx,
271 struct auth_usersupplied_info **user_info,
272 const char *smb_name,
273 const char *client_domain,
274 const struct tsocket_address *remote_address,
275 const struct tsocket_address *local_address,
276 const char *service_description,
277 const uint8_t chal[8],
278 DATA_BLOB plaintext_password)
281 DATA_BLOB local_lm_blob;
282 DATA_BLOB local_nt_blob;
283 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
284 char *plaintext_password_string;
286 * Not encrypted - do so.
289 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
291 if (plaintext_password.data && plaintext_password.length) {
292 unsigned char local_lm_response[24];
294 #ifdef DEBUG_PASSWORD
295 DEBUG(10,("Unencrypted password (len %d):\n",
296 (int)plaintext_password.length));
297 dump_data(100, plaintext_password.data,
298 plaintext_password.length);
301 SMBencrypt( (const char *)plaintext_password.data,
302 (const uchar*)chal, local_lm_response);
303 local_lm_blob = data_blob(local_lm_response, 24);
305 /* We can't do an NT hash here, as the password needs to be
307 local_nt_blob = data_blob_null;
309 local_lm_blob = data_blob_null;
310 local_nt_blob = data_blob_null;
313 plaintext_password_string = talloc_strndup(talloc_tos(),
314 (const char *)plaintext_password.data,
315 plaintext_password.length);
316 if (!plaintext_password_string) {
320 ret = make_user_info(mem_ctx,
321 user_info, smb_name, smb_name, client_domain, client_domain,
322 get_remote_machine_name(),
326 local_lm_blob.data ? &local_lm_blob : NULL,
327 local_nt_blob.data ? &local_nt_blob : NULL,
329 plaintext_password_string,
330 AUTH_PASSWORD_PLAIN);
332 if (plaintext_password_string) {
333 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
334 talloc_free(plaintext_password_string);
337 data_blob_free(&local_lm_blob);
338 return NT_STATUS_IS_OK(ret) ? true : false;
341 /****************************************************************************
342 Create an auth_usersupplied_data structure
343 ****************************************************************************/
345 NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
346 struct auth_usersupplied_info **user_info,
347 const char *smb_name,
348 const char *client_domain,
349 const struct tsocket_address *remote_address,
350 const struct tsocket_address *local_address,
351 const char *service_description,
352 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
354 bool allow_raw = lp_raw_ntlmv2_auth();
356 if (!allow_raw && nt_resp.length >= 48) {
358 * NTLMv2_RESPONSE has at least 48 bytes
359 * and should only be supported via NTLMSSP.
361 DEBUG(2,("Rejecting raw NTLMv2 authentication with "
362 "user [%s\\%s] from[%s]\n",
363 client_domain, smb_name,
364 tsocket_address_string(remote_address, mem_ctx)));
365 return NT_STATUS_INVALID_PARAMETER;
368 return make_user_info(mem_ctx,
369 user_info, smb_name, smb_name,
370 client_domain, client_domain,
371 get_remote_machine_name(),
375 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
376 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
378 AUTH_PASSWORD_RESPONSE);
381 /****************************************************************************
382 Create a guest user_info blob, for anonymous authentication.
383 ****************************************************************************/
385 bool make_user_info_guest(TALLOC_CTX *mem_ctx,
386 const struct tsocket_address *remote_address,
387 const struct tsocket_address *local_address,
388 const char *service_description,
389 struct auth_usersupplied_info **user_info)
393 nt_status = make_user_info(mem_ctx,
404 AUTH_PASSWORD_RESPONSE);
406 return NT_STATUS_IS_OK(nt_status) ? true : false;
409 static NTSTATUS log_nt_token(struct security_token *token)
411 TALLOC_CTX *frame = talloc_stackframe();
416 if ((lp_log_nt_token_command(frame) == NULL) ||
417 (strlen(lp_log_nt_token_command(frame)) == 0)) {
422 group_sidstr = talloc_strdup(frame, "");
423 for (i=1; i<token->num_sids; i++) {
424 group_sidstr = talloc_asprintf(
425 frame, "%s %s", group_sidstr,
426 sid_string_talloc(frame, &token->sids[i]));
429 command = talloc_string_sub(
430 frame, lp_log_nt_token_command(frame),
431 "%s", sid_string_talloc(frame, &token->sids[0]));
432 command = talloc_string_sub(frame, command, "%t", group_sidstr);
434 if (command == NULL) {
436 return NT_STATUS_NO_MEMORY;
439 DEBUG(8, ("running command: [%s]\n", command));
440 if (smbrun(command, NULL, NULL) != 0) {
441 DEBUG(0, ("Could not log NT token\n"));
443 return NT_STATUS_ACCESS_DENIED;
451 * Create the token to use from server_info->info3 and
452 * server_info->sids (the info3/sam groups). Find the unix gids.
455 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
456 const struct auth_serversupplied_info *server_info,
457 DATA_BLOB *session_key,
458 const char *smb_username, /* for ->sanitized_username, for %U subs */
459 struct auth_session_info **session_info_out)
461 struct security_token *t;
464 struct dom_sid tmp_sid;
465 struct auth_session_info *session_info;
469 /* Ensure we can't possible take a code path leading to a
472 return NT_STATUS_LOGON_FAILURE;
475 if (server_info->cached_session_info != NULL) {
476 session_info = copy_session_info(mem_ctx,
477 server_info->cached_session_info);
478 if (session_info == NULL) {
479 return NT_STATUS_NO_MEMORY;
482 /* This is a potentially untrusted username for use in %U */
483 alpha_strcpy(tmp, smb_username, ". _-$", sizeof(tmp));
484 session_info->unix_info->sanitized_username =
485 talloc_strdup(session_info->unix_info, tmp);
486 if (session_info->unix_info->sanitized_username == NULL) {
487 TALLOC_FREE(session_info);
488 return NT_STATUS_NO_MEMORY;
491 *session_info_out = session_info;
495 session_info = talloc_zero(mem_ctx, struct auth_session_info);
497 return NT_STATUS_NO_MEMORY;
500 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
501 if (!session_info->unix_token) {
502 TALLOC_FREE(session_info);
503 return NT_STATUS_NO_MEMORY;
506 session_info->unix_token->uid = server_info->utok.uid;
507 session_info->unix_token->gid = server_info->utok.gid;
509 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
510 if (!session_info->unix_info) {
511 TALLOC_FREE(session_info);
512 return NT_STATUS_NO_MEMORY;
515 session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
516 if (!session_info->unix_info->unix_name) {
517 TALLOC_FREE(session_info);
518 return NT_STATUS_NO_MEMORY;
521 /* This is a potentially untrusted username for use in %U */
522 alpha_strcpy(tmp, smb_username, ". _-$", sizeof(tmp));
523 session_info->unix_info->sanitized_username =
524 talloc_strdup(session_info->unix_info, tmp);
527 data_blob_free(&session_info->session_key);
528 session_info->session_key = data_blob_talloc(session_info,
530 session_key->length);
531 if (!session_info->session_key.data && session_key->length) {
532 return NT_STATUS_NO_MEMORY;
535 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
536 server_info->session_key.length);
539 /* We need to populate session_info->info with the information found in server_info->info3 */
540 status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
541 server_info->guest == false,
542 &session_info->info);
543 if (!NT_STATUS_IS_OK(status)) {
544 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
545 TALLOC_FREE(session_info);
550 * If winbind is not around, we can not make much use of the SIDs the
551 * domain controller provided us with. Likewise if the user name was
552 * mapped to some local unix user.
555 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
556 (server_info->nss_token)) {
557 char *found_username = NULL;
558 status = create_token_from_username(session_info,
559 server_info->unix_name,
561 &session_info->unix_token->uid,
562 &session_info->unix_token->gid,
564 &session_info->security_token);
565 if (NT_STATUS_IS_OK(status)) {
566 session_info->unix_info->unix_name = found_username;
569 status = create_local_nt_token_from_info3(session_info,
573 &session_info->security_token);
576 if (!NT_STATUS_IS_OK(status)) {
580 /* Convert the SIDs to gids. */
582 session_info->unix_token->ngroups = 0;
583 session_info->unix_token->groups = NULL;
585 t = session_info->security_token;
587 ids = talloc_array(talloc_tos(), struct unixid,
590 return NT_STATUS_NO_MEMORY;
593 if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
595 return NT_STATUS_NO_MEMORY;
598 for (i=0; i<t->num_sids; i++) {
600 if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
604 if (ids[i].type != ID_TYPE_GID &&
605 ids[i].type != ID_TYPE_BOTH) {
606 DEBUG(10, ("Could not convert SID %s to gid, "
608 sid_string_dbg(&t->sids[i])));
611 if (!add_gid_to_array_unique(session_info->unix_token,
613 &session_info->unix_token->groups,
614 &session_info->unix_token->ngroups)) {
615 return NT_STATUS_NO_MEMORY;
620 * Add the "Unix Group" SID for each gid to catch mapped groups
621 * and their Unix equivalent. This is to solve the backwards
622 * compatibility problem of 'valid users = +ntadmin' where
623 * ntadmin has been paired with "Domain Admins" in the group
624 * mapping table. Otherwise smb.conf would need to be changed
625 * to 'valid user = "Domain Admins"'. --jerry
627 * For consistency we also add the "Unix User" SID,
628 * so that the complete unix token is represented within
632 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
633 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
634 &session_info->security_token->sids,
635 &session_info->security_token->num_sids);
637 gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
638 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
639 &session_info->security_token->sids,
640 &session_info->security_token->num_sids);
642 for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
643 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
644 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
645 &session_info->security_token->sids,
646 &session_info->security_token->num_sids);
649 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
650 debug_unix_user_token(DBGC_AUTH, 10,
651 session_info->unix_token->uid,
652 session_info->unix_token->gid,
653 session_info->unix_token->ngroups,
654 session_info->unix_token->groups);
656 status = log_nt_token(session_info->security_token);
657 if (!NT_STATUS_IS_OK(status)) {
661 *session_info_out = session_info;
665 NTSTATUS auth3_user_info_dc_add_hints(struct auth_user_info_dc *user_info_dc,
670 uint32_t orig_num_sids = user_info_dc->num_sids;
671 struct dom_sid tmp_sid = { 0, };
675 * We add S-5-88-1-X in order to pass the uid
676 * for the unix token.
678 sid_compose(&tmp_sid,
679 &global_sid_Unix_NFS_Users,
681 status = add_sid_to_array_unique(user_info_dc->sids,
684 &user_info_dc->num_sids);
685 if (!NT_STATUS_IS_OK(status)) {
686 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
692 * We add S-5-88-2-X in order to pass the gid
693 * for the unix token.
695 sid_compose(&tmp_sid,
696 &global_sid_Unix_NFS_Groups,
698 status = add_sid_to_array_unique(user_info_dc->sids,
701 &user_info_dc->num_sids);
702 if (!NT_STATUS_IS_OK(status)) {
703 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
709 * We add S-5-88-3-X in order to pass some flags
710 * (AUTH3_UNIX_HINT_*) to auth3_create_session_info().
712 sid_compose(&tmp_sid,
713 &global_sid_Unix_NFS_Mode,
715 status = add_sid_to_array_unique(user_info_dc->sids,
718 &user_info_dc->num_sids);
719 if (!NT_STATUS_IS_OK(status)) {
720 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
728 user_info_dc->num_sids = orig_num_sids;
732 NTSTATUS auth3_session_info_create(TALLOC_CTX *mem_ctx,
733 const struct auth_user_info_dc *user_info_dc,
734 const char *original_user_name,
735 uint32_t session_info_flags,
736 struct auth_session_info **session_info_out)
738 TALLOC_CTX *frame = talloc_stackframe();
739 struct auth_session_info *session_info = NULL;
741 bool found_hint_uid = false;
743 bool found_hint_gid = false;
744 uint32_t hint_flags = 0;
745 bool found_hint_flags = false;
746 bool need_getpwuid = false;
747 struct unixid *ids = NULL;
748 uint32_t num_gids = 0;
750 struct dom_sid tmp_sid = { 0, };
751 fstring tmp = { 0, };
756 *session_info_out = NULL;
758 if (user_info_dc->num_sids == 0) {
760 return NT_STATUS_INVALID_TOKEN;
763 if (user_info_dc->info == NULL) {
765 return NT_STATUS_INVALID_TOKEN;
768 if (user_info_dc->info->account_name == NULL) {
770 return NT_STATUS_INVALID_TOKEN;
773 session_info = talloc_zero(mem_ctx, struct auth_session_info);
774 if (session_info == NULL) {
776 return NT_STATUS_NO_MEMORY;
778 /* keep this under frame for easier cleanup */
779 talloc_reparent(mem_ctx, frame, session_info);
781 session_info->info = auth_user_info_copy(session_info,
783 if (session_info->info == NULL) {
785 return NT_STATUS_NO_MEMORY;
788 session_info->security_token = talloc_zero(session_info,
789 struct security_token);
790 if (session_info->security_token == NULL) {
792 return NT_STATUS_NO_MEMORY;
796 * Avoid a lot of reallocations and allocate what we'll
799 session_info->security_token->sids = talloc_zero_array(
800 session_info->security_token,
802 user_info_dc->num_sids);
803 if (session_info->security_token->sids == NULL) {
805 return NT_STATUS_NO_MEMORY;
808 for (i = PRIMARY_USER_SID_INDEX; i < user_info_dc->num_sids; i++) {
809 struct security_token *nt_token = session_info->security_token;
813 * S-1-5-88-X-Y sids are only used to give hints
814 * to the unix token construction.
816 * S-1-5-88-1-Y gives the uid=Y
817 * S-1-5-88-2-Y gives the gid=Y
818 * S-1-5-88-3-Y gives flags=Y: AUTH3_UNIX_HINT_*
820 cmp = dom_sid_compare_domain(&global_sid_Unix_NFS,
821 &user_info_dc->sids[i]);
826 match = sid_peek_rid(&user_info_dc->sids[i], &hint);
831 match = dom_sid_in_domain(&global_sid_Unix_NFS_Users,
832 &user_info_dc->sids[i]);
834 if (found_hint_uid) {
836 return NT_STATUS_INVALID_TOKEN;
838 found_hint_uid = true;
839 hint_uid = (uid_t)hint;
843 match = dom_sid_in_domain(&global_sid_Unix_NFS_Groups,
844 &user_info_dc->sids[i]);
846 if (found_hint_gid) {
848 return NT_STATUS_INVALID_TOKEN;
850 found_hint_gid = true;
851 hint_gid = (gid_t)hint;
855 match = dom_sid_in_domain(&global_sid_Unix_NFS_Mode,
856 &user_info_dc->sids[i]);
858 if (found_hint_flags) {
860 return NT_STATUS_INVALID_TOKEN;
862 found_hint_flags = true;
870 status = add_sid_to_array_unique(nt_token->sids,
871 &user_info_dc->sids[i],
873 &nt_token->num_sids);
874 if (!NT_STATUS_IS_OK(status)) {
881 * We need at least one usable SID
883 if (session_info->security_token->num_sids == 0) {
885 return NT_STATUS_INVALID_TOKEN;
889 * We need all tree hints: uid, gid, flags
892 if (found_hint_uid || found_hint_gid || found_hint_flags) {
893 if (!found_hint_uid) {
895 return NT_STATUS_INVALID_TOKEN;
898 if (!found_hint_gid) {
900 return NT_STATUS_INVALID_TOKEN;
903 if (!found_hint_flags) {
905 return NT_STATUS_INVALID_TOKEN;
909 if (session_info->info->authenticated) {
910 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
913 status = finalize_local_nt_token(session_info->security_token,
915 if (!NT_STATUS_IS_OK(status)) {
921 * unless set otherwise, the session key is the user session
922 * key from the auth subsystem
924 if (user_info_dc->user_session_key.length != 0) {
925 session_info->session_key = data_blob_dup_talloc(session_info,
926 user_info_dc->user_session_key);
927 if (session_info->session_key.data == NULL) {
929 return NT_STATUS_NO_MEMORY;
933 if (!(session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)) {
937 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
938 if (session_info->unix_token == NULL) {
940 return NT_STATUS_NO_MEMORY;
942 session_info->unix_token->uid = -1;
943 session_info->unix_token->gid = -1;
945 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
946 if (session_info->unix_info == NULL) {
948 return NT_STATUS_NO_MEMORY;
951 /* Convert the SIDs to uid/gids. */
953 ids = talloc_zero_array(frame, struct unixid,
954 session_info->security_token->num_sids);
957 return NT_STATUS_NO_MEMORY;
960 if (!(hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS)) {
961 ok = sids_to_unixids(session_info->security_token->sids,
962 session_info->security_token->num_sids,
966 return NT_STATUS_NO_MEMORY;
970 if (found_hint_uid) {
971 session_info->unix_token->uid = hint_uid;
972 } else if (ids[0].type == ID_TYPE_UID) {
974 * The primary SID resolves to a UID only.
976 session_info->unix_token->uid = ids[0].id;
977 } else if (ids[0].type == ID_TYPE_BOTH) {
979 * The primary SID resolves to a UID and GID,
980 * use it as uid and add it as first element
981 * to the groups array.
983 session_info->unix_token->uid = ids[0].id;
985 ok = add_gid_to_array_unique(session_info->unix_token,
986 session_info->unix_token->uid,
987 &session_info->unix_token->groups,
988 &session_info->unix_token->ngroups);
991 return NT_STATUS_NO_MEMORY;
995 * It we can't get a uid, we can't imporsonate
999 return NT_STATUS_INVALID_TOKEN;
1002 if (found_hint_gid) {
1003 session_info->unix_token->gid = hint_gid;
1005 need_getpwuid = true;
1008 if (hint_flags & AUTH3_UNIX_HINT_QUALIFIED_NAME) {
1009 session_info->unix_info->unix_name =
1010 talloc_asprintf(session_info->unix_info,
1012 session_info->info->domain_name,
1013 *lp_winbind_separator(),
1014 session_info->info->account_name);
1015 if (session_info->unix_info->unix_name == NULL) {
1017 return NT_STATUS_NO_MEMORY;
1019 } else if (hint_flags & AUTH3_UNIX_HINT_ISLOLATED_NAME) {
1020 session_info->unix_info->unix_name =
1021 talloc_strdup(session_info->unix_info,
1022 session_info->info->account_name);
1023 if (session_info->unix_info->unix_name == NULL) {
1025 return NT_STATUS_NO_MEMORY;
1028 need_getpwuid = true;
1031 if (need_getpwuid) {
1032 struct passwd *pwd = NULL;
1035 * Ask the system for the primary gid
1036 * and the real unix name.
1038 pwd = getpwuid_alloc(frame, session_info->unix_token->uid);
1041 return NT_STATUS_INVALID_TOKEN;
1043 if (!found_hint_gid) {
1044 session_info->unix_token->gid = pwd->pw_gid;
1047 session_info->unix_info->unix_name =
1048 talloc_strdup(session_info->unix_info, pwd->pw_name);
1049 if (session_info->unix_info->unix_name == NULL) {
1051 return NT_STATUS_NO_MEMORY;
1057 ok = add_gid_to_array_unique(session_info->unix_token,
1058 session_info->unix_token->gid,
1059 &session_info->unix_token->groups,
1060 &session_info->unix_token->ngroups);
1063 return NT_STATUS_NO_MEMORY;
1066 /* This is a potentially untrusted username for use in %U */
1067 alpha_strcpy(tmp, original_user_name, ". _-$", sizeof(tmp));
1068 session_info->unix_info->sanitized_username =
1069 talloc_strdup(session_info->unix_info, tmp);
1070 if (session_info->unix_info->sanitized_username == NULL) {
1072 return NT_STATUS_NO_MEMORY;
1075 for (i=0; i < session_info->security_token->num_sids; i++) {
1077 if (ids[i].type != ID_TYPE_GID &&
1078 ids[i].type != ID_TYPE_BOTH) {
1079 struct security_token *nt_token =
1080 session_info->security_token;
1082 DEBUG(10, ("Could not convert SID %s to gid, "
1084 sid_string_dbg(&nt_token->sids[i])));
1088 ok = add_gid_to_array_unique(session_info->unix_token,
1090 &session_info->unix_token->groups,
1091 &session_info->unix_token->ngroups);
1094 return NT_STATUS_NO_MEMORY;
1100 * Now we must get any groups this user has been
1101 * added to in /etc/group and merge them in.
1102 * This has to be done in every code path
1103 * that creates an NT token, as remote users
1104 * may have been added to the local /etc/group
1105 * database. Tokens created merely from the
1106 * info3 structs (via the DC or via the krb5 PAC)
1107 * won't have these local groups. Note the
1108 * groups added here will only be UNIX groups
1109 * (S-1-22-2-XXXX groups) as getgroups_unix_user()
1110 * turns off winbindd before calling getgroups().
1112 * NB. This is duplicating work already
1113 * done in the 'unix_user:' case of
1114 * create_token_from_sid() but won't
1115 * do anything other than be inefficient
1118 if (!(hint_flags & AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS)) {
1119 ok = getgroups_unix_user(frame,
1120 session_info->unix_info->unix_name,
1121 session_info->unix_token->gid,
1125 return NT_STATUS_INVALID_TOKEN;
1129 for (i=0; i < num_gids; i++) {
1131 ok = add_gid_to_array_unique(session_info->unix_token,
1133 &session_info->unix_token->groups,
1134 &session_info->unix_token->ngroups);
1137 return NT_STATUS_NO_MEMORY;
1142 if (hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS) {
1144 * We should not translate the unix token uid/gids
1145 * to S-1-22-X-Y SIDs.
1151 * Add the "Unix Group" SID for each gid to catch mapped groups
1152 * and their Unix equivalent. This is to solve the backwards
1153 * compatibility problem of 'valid users = +ntadmin' where
1154 * ntadmin has been paired with "Domain Admins" in the group
1155 * mapping table. Otherwise smb.conf would need to be changed
1156 * to 'valid user = "Domain Admins"'. --jerry
1158 * For consistency we also add the "Unix User" SID,
1159 * so that the complete unix token is represented within
1163 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
1164 status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1165 &session_info->security_token->sids,
1166 &session_info->security_token->num_sids);
1167 if (!NT_STATUS_IS_OK(status)) {
1172 gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
1173 status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1174 &session_info->security_token->sids,
1175 &session_info->security_token->num_sids);
1176 if (!NT_STATUS_IS_OK(status)) {
1181 for (i=0; i < session_info->unix_token->ngroups; i++ ) {
1182 struct security_token *nt_token = session_info->security_token;
1184 gid_to_unix_groups_sid(session_info->unix_token->groups[i],
1186 status = add_sid_to_array_unique(nt_token->sids,
1189 &nt_token->num_sids);
1190 if (!NT_STATUS_IS_OK(status)) {
1197 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
1198 if (session_info->unix_token != NULL) {
1199 debug_unix_user_token(DBGC_AUTH, 10,
1200 session_info->unix_token->uid,
1201 session_info->unix_token->gid,
1202 session_info->unix_token->ngroups,
1203 session_info->unix_token->groups);
1206 status = log_nt_token(session_info->security_token);
1207 if (!NT_STATUS_IS_OK(status)) {
1212 *session_info_out = talloc_move(mem_ctx, &session_info);
1214 return NT_STATUS_OK;
1217 /***************************************************************************
1218 Make (and fill) a server_info struct from a 'struct passwd' by conversion
1220 ***************************************************************************/
1222 NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
1223 const char *unix_username,
1224 const struct passwd *pwd,
1225 struct auth_serversupplied_info **server_info)
1228 TALLOC_CTX *tmp_ctx = NULL;
1229 struct auth_serversupplied_info *result;
1231 tmp_ctx = talloc_stackframe();
1232 if (tmp_ctx == NULL) {
1233 return NT_STATUS_NO_MEMORY;
1236 result = make_server_info(tmp_ctx);
1237 if (result == NULL) {
1238 status = NT_STATUS_NO_MEMORY;
1242 status = passwd_to_SamInfo3(result,
1247 if (!NT_STATUS_IS_OK(status)) {
1251 result->unix_name = talloc_strdup(result, unix_username);
1252 if (result->unix_name == NULL) {
1253 status = NT_STATUS_NO_MEMORY;
1257 result->utok.uid = pwd->pw_uid;
1258 result->utok.gid = pwd->pw_gid;
1260 *server_info = talloc_steal(mem_ctx, result);
1261 status = NT_STATUS_OK;
1263 talloc_free(tmp_ctx);
1268 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
1269 struct netr_SamInfo3 *info3)
1271 const char *guest_account = lp_guest_account();
1272 struct dom_sid domain_sid;
1276 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
1278 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
1279 "account [%s]!\n", guest_account));
1280 return NT_STATUS_NO_SUCH_USER;
1283 /* Set account name */
1284 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
1286 return NT_STATUS_NO_MEMORY;
1288 init_lsa_String(&info3->base.account_name, tmp);
1290 /* Set domain name */
1291 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
1293 return NT_STATUS_NO_MEMORY;
1295 init_lsa_StringLarge(&info3->base.logon_domain, tmp);
1298 sid_copy(&domain_sid, get_global_sam_sid());
1300 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
1301 if (info3->base.domain_sid == NULL) {
1302 return NT_STATUS_NO_MEMORY;
1306 info3->base.rid = DOMAIN_RID_GUEST;
1309 info3->base.primary_gid = DOMAIN_RID_GUESTS;
1312 info3->base.user_flags = NETLOGON_GUEST;
1315 return NT_STATUS_OK;
1318 /***************************************************************************
1319 Make (and fill) a user_info struct for a guest login.
1320 This *must* succeed for smbd to start. If there is no mapping entry for
1321 the guest gid, then create one.
1323 The resulting structure is a 'session_info' because
1324 create_local_token() has already been called on it. This is quite
1325 nasty, as the auth subsystem isn't expect this, but the behavior is
1327 ***************************************************************************/
1329 static NTSTATUS make_new_session_info_guest(TALLOC_CTX *mem_ctx,
1330 struct auth_session_info **_session_info,
1331 struct auth_serversupplied_info **_server_info)
1333 struct auth_session_info *session_info = NULL;
1334 struct auth_serversupplied_info *server_info = NULL;
1335 const char *guest_account = lp_guest_account();
1336 const char *domain = lp_netbios_name();
1337 struct netr_SamInfo3 info3;
1338 TALLOC_CTX *tmp_ctx;
1341 tmp_ctx = talloc_stackframe();
1342 if (tmp_ctx == NULL) {
1343 return NT_STATUS_NO_MEMORY;
1348 status = get_guest_info3(tmp_ctx, &info3);
1349 if (!NT_STATUS_IS_OK(status)) {
1350 DEBUG(0, ("get_guest_info3 failed with %s\n",
1351 nt_errstr(status)));
1355 status = make_server_info_info3(tmp_ctx,
1360 if (!NT_STATUS_IS_OK(status)) {
1361 DEBUG(0, ("make_server_info_info3 failed with %s\n",
1362 nt_errstr(status)));
1366 server_info->guest = true;
1368 /* This should not be done here (we should produce a server
1369 * info, and later construct a session info from it), but for
1370 * now this does not change the previous behavior */
1371 status = create_local_token(tmp_ctx, server_info, NULL,
1372 server_info->info3->base.account_name.string,
1374 if (!NT_STATUS_IS_OK(status)) {
1375 DEBUG(0, ("create_local_token failed: %s\n",
1376 nt_errstr(status)));
1380 /* annoying, but the Guest really does have a session key, and it is
1382 session_info->session_key = data_blob_talloc_zero(session_info, 16);
1384 *_session_info = talloc_move(mem_ctx, &session_info);
1385 *_server_info = talloc_move(mem_ctx, &server_info);
1387 status = NT_STATUS_OK;
1389 TALLOC_FREE(tmp_ctx);
1393 /***************************************************************************
1394 Make (and fill) a auth_session_info struct for a system user login.
1395 This *must* succeed for smbd to start.
1396 ***************************************************************************/
1398 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
1399 struct auth_session_info **session_info)
1401 TALLOC_CTX *frame = talloc_stackframe();
1402 struct auth_user_info_dc *user_info_dc = NULL;
1405 uint32_t hint_flags = 0;
1406 uint32_t session_info_flags = 0;
1409 status = auth_system_user_info_dc(frame, lp_netbios_name(),
1411 if (!NT_STATUS_IS_OK(status)) {
1412 DEBUG(0, ("auth_system_user_info_dc failed: %s\n",
1413 nt_errstr(status)));
1418 * Just get the initial uid/gid
1419 * and don't expand the unix groups.
1421 uid = sec_initial_uid();
1422 gid = sec_initial_gid();
1423 hint_flags |= AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS;
1426 * Also avoid sid mapping to gids,
1427 * as well as adding the unix_token uid/gids as
1428 * S-1-22-X-Y SIDs to the nt token.
1430 hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS;
1431 hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS;
1434 * The unix name will be "NT AUTHORITY+SYSTEM",
1435 * where '+' is the "winbind separator" character.
1437 hint_flags |= AUTH3_UNIX_HINT_QUALIFIED_NAME;
1438 status = auth3_user_info_dc_add_hints(user_info_dc,
1442 if (!NT_STATUS_IS_OK(status)) {
1443 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1444 nt_errstr(status)));
1448 session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1449 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1450 status = auth3_session_info_create(mem_ctx, user_info_dc,
1451 user_info_dc->info->account_name,
1454 if (!NT_STATUS_IS_OK(status)) {
1455 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1456 nt_errstr(status)));
1465 static NTSTATUS make_new_session_info_anonymous(TALLOC_CTX *mem_ctx,
1466 struct auth_session_info **session_info)
1468 TALLOC_CTX *frame = talloc_stackframe();
1469 const char *guest_account = lp_guest_account();
1470 struct auth_user_info_dc *user_info_dc = NULL;
1471 struct passwd *pwd = NULL;
1472 uint32_t hint_flags = 0;
1473 uint32_t session_info_flags = 0;
1477 * We use the guest account for the unix token
1478 * while we use a true anonymous nt token.
1480 * It's very important to have a separate
1481 * nt token for anonymous.
1484 pwd = Get_Pwnam_alloc(frame, guest_account);
1486 DBG_ERR("Unable to locate guest account [%s]!\n",
1488 status = NT_STATUS_NO_SUCH_USER;
1492 status = auth_anonymous_user_info_dc(frame, lp_netbios_name(),
1494 if (!NT_STATUS_IS_OK(status)) {
1495 DEBUG(0, ("auth_anonymous_user_info_dc failed: %s\n",
1496 nt_errstr(status)));
1501 * Note we don't pass AUTH3_UNIX_HINT_QUALIFIED_NAME
1502 * nor AUTH3_UNIX_HINT_ISOLATED_NAME here
1503 * as we want the unix name be found by getpwuid_alloc().
1506 status = auth3_user_info_dc_add_hints(user_info_dc,
1510 if (!NT_STATUS_IS_OK(status)) {
1511 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1512 nt_errstr(status)));
1517 * In future we may want to remove
1518 * AUTH_SESSION_INFO_DEFAULT_GROUPS.
1520 * Similar to Windows with EveryoneIncludesAnonymous
1521 * and RestrictAnonymous.
1523 * We may introduce AUTH_SESSION_INFO_ANON_WORLD...
1525 * But for this is required to keep the existing tests
1528 session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
1529 session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1530 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1531 status = auth3_session_info_create(mem_ctx, user_info_dc,
1535 if (!NT_STATUS_IS_OK(status)) {
1536 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1537 nt_errstr(status)));
1546 /****************************************************************************
1547 Fake a auth_session_info just from a username (as a
1548 session_info structure, with create_local_token() already called on
1550 ****************************************************************************/
1552 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
1553 const char *username,
1555 struct auth_session_info **session_info)
1559 struct auth_serversupplied_info *result;
1560 TALLOC_CTX *tmp_ctx;
1562 tmp_ctx = talloc_stackframe();
1563 if (tmp_ctx == NULL) {
1564 return NT_STATUS_NO_MEMORY;
1567 pwd = Get_Pwnam_alloc(tmp_ctx, username);
1569 status = NT_STATUS_NO_SUCH_USER;
1573 status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
1574 if (!NT_STATUS_IS_OK(status)) {
1578 result->nss_token = true;
1579 result->guest = is_guest;
1581 /* Now turn the server_info into a session_info with the full token etc */
1582 status = create_local_token(mem_ctx,
1589 talloc_free(tmp_ctx);
1594 /* This function MUST only used to create the cached server_info for
1597 * This is a lossy conversion. Variables known to be lost so far
1600 * - nss_token (not needed because the only read doesn't happen
1601 * for the GUEST user, as this routine populates ->security_token
1603 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1605 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1607 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1608 const struct auth_session_info *src,
1609 struct auth_serversupplied_info *server_info)
1611 struct auth_serversupplied_info *dst;
1614 dst = make_server_info(mem_ctx);
1619 /* This element must be provided to convert back to an auth_serversupplied_info */
1620 SMB_ASSERT(src->unix_info);
1624 /* This element must be provided to convert back to an
1625 * auth_serversupplied_info. This needs to be from the
1626 * auth_session_info because the group values in particular
1627 * may change during create_local_token() processing */
1628 SMB_ASSERT(src->unix_token);
1629 dst->utok.uid = src->unix_token->uid;
1630 dst->utok.gid = src->unix_token->gid;
1631 dst->utok.ngroups = src->unix_token->ngroups;
1632 if (src->unix_token->ngroups != 0) {
1633 dst->utok.groups = (gid_t *)talloc_memdup(
1634 dst, src->unix_token->groups,
1635 sizeof(gid_t)*dst->utok.ngroups);
1637 dst->utok.groups = NULL;
1640 /* We must have a security_token as otherwise the lossy
1641 * conversion without nss_token would cause create_local_token
1642 * to take the wrong path */
1643 SMB_ASSERT(src->security_token);
1645 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1646 src->session_key.length);
1648 /* This is OK because this functions is only used for the
1649 * GUEST account, which has all-zero keys for both values */
1650 dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1651 src->session_key.length);
1653 status = copy_netr_SamInfo3(dst,
1656 if (!NT_STATUS_IS_OK(status)) {
1661 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1662 if (!dst->unix_name) {
1667 dst->cached_session_info = src;
1671 struct auth_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
1672 const struct auth_session_info *src)
1674 struct auth_session_info *dst;
1676 enum ndr_err_code ndr_err;
1678 ndr_err = ndr_push_struct_blob(
1679 &blob, talloc_tos(), src,
1680 (ndr_push_flags_fn_t)ndr_push_auth_session_info);
1681 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1682 DEBUG(0, ("copy_session_info(): ndr_push_auth_session_info failed: "
1683 "%s\n", ndr_errstr(ndr_err)));
1687 dst = talloc(mem_ctx, struct auth_session_info);
1689 DEBUG(0, ("talloc failed\n"));
1690 TALLOC_FREE(blob.data);
1694 ndr_err = ndr_pull_struct_blob(
1696 (ndr_pull_flags_fn_t)ndr_pull_auth_session_info);
1697 TALLOC_FREE(blob.data);
1699 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1700 DEBUG(0, ("copy_session_info(): ndr_pull_auth_session_info failed: "
1701 "%s\n", ndr_errstr(ndr_err)));
1710 * Set a new session key. Used in the rpc server where we have to override the
1711 * SMB level session key with SystemLibraryDTC
1714 bool session_info_set_session_key(struct auth_session_info *info,
1715 DATA_BLOB session_key)
1717 TALLOC_FREE(info->session_key.data);
1719 info->session_key = data_blob_talloc(
1720 info, session_key.data, session_key.length);
1722 return (info->session_key.data != NULL);
1725 static struct auth_session_info *guest_info = NULL;
1726 static struct auth_session_info *anonymous_info = NULL;
1728 static struct auth_serversupplied_info *guest_server_info = NULL;
1730 bool init_guest_session_info(TALLOC_CTX *mem_ctx)
1734 if (guest_info != NULL)
1737 status = make_new_session_info_guest(mem_ctx,
1739 &guest_server_info);
1740 if (!NT_STATUS_IS_OK(status)) {
1744 status = make_new_session_info_anonymous(mem_ctx,
1746 if (!NT_STATUS_IS_OK(status)) {
1753 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1754 struct auth_serversupplied_info **server_info)
1756 /* This is trickier than it would appear to need to be because
1757 * we are trying to avoid certain costly operations when the
1758 * structure is converted to a 'auth_session_info' again in
1759 * create_local_token() */
1760 *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1761 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1764 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1765 struct auth_session_info **session_info)
1767 *session_info = copy_session_info(mem_ctx, guest_info);
1768 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1771 NTSTATUS make_server_info_anonymous(TALLOC_CTX *mem_ctx,
1772 struct auth_serversupplied_info **server_info)
1774 if (anonymous_info == NULL) {
1775 return NT_STATUS_UNSUCCESSFUL;
1779 * This is trickier than it would appear to need to be because
1780 * we are trying to avoid certain costly operations when the
1781 * structure is converted to a 'auth_session_info' again in
1782 * create_local_token()
1784 * We use a guest server_info, but with the anonymous session info,
1785 * which means create_local_token() will return a copy
1786 * of the anonymous token.
1788 * The server info is just used as legacy in order to
1789 * keep existing code working. Maybe some debug messages
1790 * will still refer to guest instead of anonymous.
1792 *server_info = copy_session_info_serverinfo_guest(mem_ctx, anonymous_info,
1794 if (*server_info == NULL) {
1795 return NT_STATUS_NO_MEMORY;
1798 return NT_STATUS_OK;
1801 NTSTATUS make_session_info_anonymous(TALLOC_CTX *mem_ctx,
1802 struct auth_session_info **session_info)
1804 if (anonymous_info == NULL) {
1805 return NT_STATUS_UNSUCCESSFUL;
1808 *session_info = copy_session_info(mem_ctx, anonymous_info);
1809 if (*session_info == NULL) {
1810 return NT_STATUS_NO_MEMORY;
1813 return NT_STATUS_OK;
1816 static struct auth_session_info *system_info = NULL;
1818 NTSTATUS init_system_session_info(TALLOC_CTX *mem_ctx)
1820 if (system_info != NULL)
1821 return NT_STATUS_OK;
1823 return make_new_session_info_system(mem_ctx, &system_info);
1826 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1827 struct auth_session_info **session_info)
1829 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1830 *session_info = copy_session_info(mem_ctx, system_info);
1831 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1834 const struct auth_session_info *get_session_info_system(void)
1839 /***************************************************************************
1840 Purely internal function for make_server_info_info3
1841 ***************************************************************************/
1843 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1844 const char *username, char **found_username,
1845 struct passwd **pwd,
1846 bool *username_was_mapped)
1848 char *orig_dom_user = NULL;
1849 char *dom_user = NULL;
1850 char *lower_username = NULL;
1851 char *real_username = NULL;
1852 struct passwd *passwd;
1854 lower_username = talloc_strdup(mem_ctx, username);
1855 if (!lower_username) {
1856 return NT_STATUS_NO_MEMORY;
1858 if (!strlower_m( lower_username )) {
1859 return NT_STATUS_INVALID_PARAMETER;
1862 orig_dom_user = talloc_asprintf(mem_ctx,
1865 *lp_winbind_separator(),
1867 if (!orig_dom_user) {
1868 return NT_STATUS_NO_MEMORY;
1871 /* Get the passwd struct. Try to create the account if necessary. */
1873 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1875 return NT_STATUS_NO_MEMORY;
1878 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
1880 DEBUG(3, ("Failed to find authenticated user %s via "
1881 "getpwnam(), denying access.\n", dom_user));
1882 return NT_STATUS_NO_SUCH_USER;
1885 if (!real_username) {
1886 return NT_STATUS_NO_MEMORY;
1891 /* This is pointless -- there is no support for differing
1892 unix and windows names. Make sure to always store the
1893 one we actually looked up and succeeded. Have I mentioned
1894 why I hate the 'winbind use default domain' parameter?
1897 *found_username = talloc_strdup( mem_ctx, real_username );
1899 return NT_STATUS_OK;
1902 /****************************************************************************
1903 Wrapper to allow the getpwnam() call to strip the domain name and
1904 try again in case a local UNIX user is already there. Also run through
1905 the username if we fallback to the username only.
1906 ****************************************************************************/
1908 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1909 char **p_save_username, bool create )
1911 struct passwd *pw = NULL;
1913 char *username = NULL;
1915 /* we only save a copy of the username it has been mangled
1916 by winbindd use default domain */
1917 *p_save_username = NULL;
1919 /* don't call map_username() here since it has to be done higher
1920 up the stack so we don't call it multiple times */
1922 username = talloc_strdup(mem_ctx, domuser);
1927 p = strchr_m( username, *lp_winbind_separator() );
1929 /* code for a DOMAIN\user string */
1932 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1934 /* make sure we get the case of the username correct */
1935 /* work around 'winbind use default domain = yes' */
1937 if ( lp_winbind_use_default_domain() &&
1938 !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1941 /* split the domain and username into 2 strings */
1945 *p_save_username = talloc_asprintf(mem_ctx,
1948 *lp_winbind_separator(),
1950 if (!*p_save_username) {
1955 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1962 /* setup for lookup of just the username */
1963 /* remember that p and username are overlapping memory */
1966 username = talloc_strdup(mem_ctx, p);
1972 /* just lookup a plain username */
1974 pw = Get_Pwnam_alloc(mem_ctx, username);
1976 /* Create local user if requested but only if winbindd
1977 is not running. We need to protect against cases
1978 where winbindd is failing and then prematurely
1979 creating users in /etc/passwd */
1981 if ( !pw && create && !winbind_ping() ) {
1982 /* Don't add a machine account. */
1983 if (username[strlen(username)-1] == '$')
1986 _smb_create_user(NULL, username, NULL);
1987 pw = Get_Pwnam_alloc(mem_ctx, username);
1990 /* one last check for a valid passwd struct */
1993 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1998 /***************************************************************************
1999 Make a server_info struct from the info3 returned by a domain logon
2000 ***************************************************************************/
2002 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
2003 const char *sent_nt_username,
2005 struct auth_serversupplied_info **server_info,
2006 const struct netr_SamInfo3 *info3)
2008 NTSTATUS nt_status = NT_STATUS_OK;
2009 char *found_username = NULL;
2010 const char *nt_domain;
2011 const char *nt_username;
2012 struct dom_sid user_sid;
2013 struct dom_sid group_sid;
2014 bool username_was_mapped;
2016 struct auth_serversupplied_info *result;
2017 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2020 Here is where we should check the list of
2021 trusted domains, and verify that the SID
2025 if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
2026 nt_status = NT_STATUS_INVALID_PARAMETER;
2030 if (!sid_compose(&group_sid, info3->base.domain_sid,
2031 info3->base.primary_gid)) {
2032 nt_status = NT_STATUS_INVALID_PARAMETER;
2036 nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
2038 /* If the server didn't give us one, just use the one we sent
2040 nt_username = sent_nt_username;
2043 nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
2045 /* If the server didn't give us one, just use the one we sent
2050 /* If getpwnam() fails try the add user script (2.2.x behavior).
2052 We use the _unmapped_ username here in an attempt to provide
2053 consistent username mapping behavior between kerberos and NTLM[SSP]
2054 authentication in domain mode security. I.E. Username mapping
2055 should be applied to the fully qualified username
2056 (e.g. DOMAIN\user) and not just the login name. Yes this means we
2057 called map_username() unnecessarily in make_user_info_map() but
2058 that is how the current code is designed. Making the change here
2059 is the least disruptive place. -- jerry */
2061 /* this call will try to create the user if necessary */
2063 nt_status = check_account(tmp_ctx,
2068 &username_was_mapped);
2070 if (!NT_STATUS_IS_OK(nt_status)) {
2071 /* Handle 'map to guest = Bad Uid */
2072 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
2073 (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
2074 lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
2075 DBG_NOTICE("Try to map %s to guest account",
2077 nt_status = make_server_info_guest(tmp_ctx, &result);
2078 if (NT_STATUS_IS_OK(nt_status)) {
2079 *server_info = talloc_move(mem_ctx, &result);
2085 result = make_server_info(tmp_ctx);
2086 if (result == NULL) {
2087 DEBUG(4, ("make_server_info failed!\n"));
2088 nt_status = NT_STATUS_NO_MEMORY;
2092 result->unix_name = talloc_strdup(result, found_username);
2094 /* copy in the info3 */
2095 nt_status = copy_netr_SamInfo3(result,
2098 if (!NT_STATUS_IS_OK(nt_status)) {
2102 /* Fill in the unix info we found on the way */
2104 result->utok.uid = pwd->pw_uid;
2105 result->utok.gid = pwd->pw_gid;
2107 /* ensure we are never given NULL session keys */
2109 if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
2110 result->session_key = data_blob_null;
2112 result->session_key = data_blob_talloc(
2113 result, info3->base.key.key,
2114 sizeof(info3->base.key.key));
2117 if (all_zero(info3->base.LMSessKey.key,
2118 sizeof(info3->base.LMSessKey.key))) {
2119 result->lm_session_key = data_blob_null;
2121 result->lm_session_key = data_blob_talloc(
2122 result, info3->base.LMSessKey.key,
2123 sizeof(info3->base.LMSessKey.key));
2126 result->nss_token |= username_was_mapped;
2128 result->guest = (info3->base.user_flags & NETLOGON_GUEST);
2130 *server_info = talloc_move(mem_ctx, &result);
2132 nt_status = NT_STATUS_OK;
2134 talloc_free(tmp_ctx);
2139 /*****************************************************************************
2140 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
2141 ******************************************************************************/
2143 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
2144 const char *sent_nt_username,
2146 const struct wbcAuthUserInfo *info,
2147 struct auth_serversupplied_info **server_info)
2149 struct netr_SamInfo3 info3;
2150 struct netr_SamInfo6 *info6;
2152 info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
2154 return NT_STATUS_NO_MEMORY;
2157 info3.base = info6->base;
2158 info3.sidcount = info6->sidcount;
2159 info3.sids = info6->sids;
2161 return make_server_info_info3(mem_ctx,
2162 sent_nt_username, domain,
2163 server_info, &info3);
2167 * Verify whether or not given domain is trusted.
2169 * This should only be used on a DC.
2171 * @param domain_name name of the domain to be verified
2172 * @return true if domain is one of the trusted ones or
2173 * false if otherwise
2176 bool is_trusted_domain(const char* dom_name)
2184 if (dom_name == NULL || dom_name[0] == '\0') {
2188 if (strequal(dom_name, get_global_sam_name())) {
2193 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2194 "[%s]\n", dom_name ));
2195 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2204 on a logon error possibly map the error to success if "map to guest"
2207 NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
2211 struct auth_serversupplied_info **server_info)
2213 user = user ? user : "";
2214 domain = domain ? domain : "";
2216 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2217 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
2218 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
2219 DEBUG(3,("No such user %s [%s] - using guest account\n",
2221 return make_server_info_guest(mem_ctx, server_info);
2223 } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2224 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
2225 DEBUG(3,("Registered username %s for guest access\n",
2227 return make_server_info_guest(mem_ctx, server_info);
2235 Extract session key from a session info and return it in a blob
2236 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
2238 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
2239 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
2241 Note that returned session_key is referencing the original key, it is supposed to be
2242 short-lived. If original session_info->session_key is gone, the reference will be broken.
2244 NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
2247 if (session_key == NULL || session_info == NULL) {
2248 return NT_STATUS_INVALID_PARAMETER;
2251 if (session_info->session_key.length == 0) {
2252 return NT_STATUS_NO_USER_SESSION_KEY;
2255 *session_key = session_info->session_key;
2256 if (intent == KEY_USE_16BYTES) {
2257 session_key->length = MIN(session_info->session_key.length, 16);
2259 return NT_STATUS_OK;