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/>.
27 #include "lib/util_unixsids.h"
28 #include "../libcli/auth/libcli_auth.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"
42 #include "source3/lib/substitute.h"
45 #define DBGC_CLASS DBGC_AUTH
47 /****************************************************************************
48 Create a UNIX user on demand.
49 ****************************************************************************/
51 static int _smb_create_user(const char *domain
, const char *unix_username
, const char *homedir
)
53 TALLOC_CTX
*ctx
= talloc_tos();
54 const struct loadparm_substitution
*lp_sub
=
55 loadparm_s3_global_substitution();
59 add_script
= lp_add_user_script(ctx
, lp_sub
);
60 if (!add_script
|| !*add_script
) {
63 add_script
= talloc_all_string_sub(ctx
,
71 add_script
= talloc_all_string_sub(ctx
,
80 add_script
= talloc_all_string_sub(ctx
,
88 ret
= smbrun(add_script
, NULL
, NULL
);
91 ("smb_create_user: Running the command `%s' gave %d\n",
96 /****************************************************************************
97 Create an auth_usersupplied_data structure after appropriate mapping.
98 ****************************************************************************/
100 NTSTATUS
make_user_info_map(TALLOC_CTX
*mem_ctx
,
101 struct auth_usersupplied_info
**user_info
,
102 const char *smb_name
,
103 const char *client_domain
,
104 const char *workstation_name
,
105 const struct tsocket_address
*remote_address
,
106 const struct tsocket_address
*local_address
,
107 const char *service_description
,
108 const DATA_BLOB
*lm_pwd
,
109 const DATA_BLOB
*nt_pwd
,
110 const struct samr_Password
*lm_interactive_pwd
,
111 const struct samr_Password
*nt_interactive_pwd
,
112 const char *plaintext
,
113 enum auth_password_state password_state
)
118 char *internal_username
= NULL
;
120 was_mapped
= map_username(talloc_tos(), smb_name
, &internal_username
);
121 if (!internal_username
) {
122 return NT_STATUS_NO_MEMORY
;
125 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
126 client_domain
, smb_name
, workstation_name
));
129 * We let the auth stack canonicalize, username
132 domain
= client_domain
;
134 result
= make_user_info(mem_ctx
, user_info
, smb_name
, internal_username
,
135 client_domain
, domain
, workstation_name
,
136 remote_address
, local_address
,
137 service_description
, lm_pwd
, nt_pwd
,
138 lm_interactive_pwd
, nt_interactive_pwd
,
139 plaintext
, password_state
);
140 if (NT_STATUS_IS_OK(result
)) {
141 /* did we actually map the user to a different name? */
142 (*user_info
)->was_mapped
= was_mapped
;
147 /****************************************************************************
148 Create an auth_usersupplied_data, making the DATA_BLOBs here.
149 Decrypt and encrypt the passwords.
150 ****************************************************************************/
152 bool make_user_info_netlogon_network(TALLOC_CTX
*mem_ctx
,
153 struct auth_usersupplied_info
**user_info
,
154 const char *smb_name
,
155 const char *client_domain
,
156 const char *workstation_name
,
157 const struct tsocket_address
*remote_address
,
158 const struct tsocket_address
*local_address
,
159 uint32_t logon_parameters
,
160 const uchar
*lm_network_pwd
,
162 const uchar
*nt_network_pwd
,
167 DATA_BLOB lm_blob
= data_blob(lm_network_pwd
, lm_pwd_len
);
168 DATA_BLOB nt_blob
= data_blob(nt_network_pwd
, nt_pwd_len
);
170 status
= make_user_info_map(mem_ctx
, user_info
,
171 smb_name
, client_domain
,
176 lm_pwd_len
? &lm_blob
: NULL
,
177 nt_pwd_len
? &nt_blob
: NULL
,
179 AUTH_PASSWORD_RESPONSE
);
181 if (NT_STATUS_IS_OK(status
)) {
182 (*user_info
)->logon_parameters
= logon_parameters
;
184 ret
= NT_STATUS_IS_OK(status
) ? true : false;
186 data_blob_free(&lm_blob
);
187 data_blob_free(&nt_blob
);
191 /****************************************************************************
192 Create an auth_usersupplied_data, making the DATA_BLOBs here.
193 Decrypt and encrypt the passwords.
194 ****************************************************************************/
196 bool make_user_info_netlogon_interactive(TALLOC_CTX
*mem_ctx
,
197 struct auth_usersupplied_info
**user_info
,
198 const char *smb_name
,
199 const char *client_domain
,
200 const char *workstation_name
,
201 const struct tsocket_address
*remote_address
,
202 const struct tsocket_address
*local_address
,
203 uint32_t logon_parameters
,
205 const uchar lm_interactive_pwd
[16],
206 const uchar nt_interactive_pwd
[16])
208 struct samr_Password lm_pwd
;
209 struct samr_Password nt_pwd
;
210 unsigned char local_lm_response
[24];
211 unsigned char local_nt_response
[24];
214 if (lm_interactive_pwd
)
215 memcpy(lm_pwd
.hash
, lm_interactive_pwd
, sizeof(lm_pwd
.hash
));
217 if (nt_interactive_pwd
)
218 memcpy(nt_pwd
.hash
, nt_interactive_pwd
, sizeof(nt_pwd
.hash
));
220 if (lm_interactive_pwd
) {
221 rc
= SMBOWFencrypt(lm_pwd
.hash
, chal
,
228 if (nt_interactive_pwd
) {
229 rc
= SMBOWFencrypt(nt_pwd
.hash
, chal
,
239 DATA_BLOB local_lm_blob
= data_blob_null
;
240 DATA_BLOB local_nt_blob
= data_blob_null
;
242 if (lm_interactive_pwd
) {
243 local_lm_blob
= data_blob(local_lm_response
,
244 sizeof(local_lm_response
));
247 if (nt_interactive_pwd
) {
248 local_nt_blob
= data_blob(local_nt_response
,
249 sizeof(local_nt_response
));
252 nt_status
= make_user_info_map(
255 smb_name
, client_domain
, workstation_name
,
259 lm_interactive_pwd
? &local_lm_blob
: NULL
,
260 nt_interactive_pwd
? &local_nt_blob
: NULL
,
261 lm_interactive_pwd
? &lm_pwd
: NULL
,
262 nt_interactive_pwd
? &nt_pwd
: NULL
,
263 NULL
, AUTH_PASSWORD_HASH
);
265 if (NT_STATUS_IS_OK(nt_status
)) {
266 (*user_info
)->logon_parameters
= logon_parameters
;
267 (*user_info
)->flags
|= USER_INFO_INTERACTIVE_LOGON
;
270 ret
= NT_STATUS_IS_OK(nt_status
) ? true : false;
271 data_blob_free(&local_lm_blob
);
272 data_blob_free(&local_nt_blob
);
278 /****************************************************************************
279 Create an auth_usersupplied_data structure
280 ****************************************************************************/
282 bool make_user_info_for_reply(TALLOC_CTX
*mem_ctx
,
283 struct auth_usersupplied_info
**user_info
,
284 const char *smb_name
,
285 const char *client_domain
,
286 const struct tsocket_address
*remote_address
,
287 const struct tsocket_address
*local_address
,
288 const char *service_description
,
289 const uint8_t chal
[8],
290 DATA_BLOB plaintext_password
)
293 DATA_BLOB local_lm_blob
;
294 DATA_BLOB local_nt_blob
;
296 char *plaintext_password_string
;
298 * Not encrypted - do so.
301 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
303 if (plaintext_password
.data
&& plaintext_password
.length
) {
304 unsigned char local_lm_response
[24];
306 #ifdef DEBUG_PASSWORD
307 DEBUG(10,("Unencrypted password (len %d):\n",
308 (int)plaintext_password
.length
));
309 dump_data(100, plaintext_password
.data
,
310 plaintext_password
.length
);
313 SMBencrypt( (const char *)plaintext_password
.data
,
314 (const uchar
*)chal
, local_lm_response
);
315 local_lm_blob
= data_blob(local_lm_response
, 24);
317 /* We can't do an NT hash here, as the password needs to be
319 local_nt_blob
= data_blob_null
;
321 local_lm_blob
= data_blob_null
;
322 local_nt_blob
= data_blob_null
;
325 plaintext_password_string
= talloc_strndup(talloc_tos(),
326 (const char *)plaintext_password
.data
,
327 plaintext_password
.length
);
328 if (!plaintext_password_string
) {
332 ret
= make_user_info(mem_ctx
,
333 user_info
, smb_name
, smb_name
, client_domain
, client_domain
,
334 get_remote_machine_name(),
338 local_lm_blob
.data
? &local_lm_blob
: NULL
,
339 local_nt_blob
.data
? &local_nt_blob
: NULL
,
341 plaintext_password_string
,
342 AUTH_PASSWORD_PLAIN
);
344 if (plaintext_password_string
) {
345 memset(plaintext_password_string
, '\0', strlen(plaintext_password_string
));
346 talloc_free(plaintext_password_string
);
349 data_blob_free(&local_lm_blob
);
350 return NT_STATUS_IS_OK(ret
) ? true : false;
353 /****************************************************************************
354 Create an auth_usersupplied_data structure
355 ****************************************************************************/
357 NTSTATUS
make_user_info_for_reply_enc(TALLOC_CTX
*mem_ctx
,
358 struct auth_usersupplied_info
**user_info
,
359 const char *smb_name
,
360 const char *client_domain
,
361 const struct tsocket_address
*remote_address
,
362 const struct tsocket_address
*local_address
,
363 const char *service_description
,
364 DATA_BLOB lm_resp
, DATA_BLOB nt_resp
)
366 bool allow_raw
= lp_raw_ntlmv2_auth();
368 if (!allow_raw
&& nt_resp
.length
>= 48) {
370 * NTLMv2_RESPONSE has at least 48 bytes
371 * and should only be supported via NTLMSSP.
373 DEBUG(2,("Rejecting raw NTLMv2 authentication with "
374 "user [%s\\%s] from[%s]\n",
375 client_domain
, smb_name
,
376 tsocket_address_string(remote_address
, mem_ctx
)));
377 return NT_STATUS_INVALID_PARAMETER
;
380 return make_user_info(mem_ctx
,
381 user_info
, smb_name
, smb_name
,
382 client_domain
, client_domain
,
383 get_remote_machine_name(),
387 lm_resp
.data
&& (lm_resp
.length
> 0) ? &lm_resp
: NULL
,
388 nt_resp
.data
&& (nt_resp
.length
> 0) ? &nt_resp
: NULL
,
390 AUTH_PASSWORD_RESPONSE
);
393 /****************************************************************************
394 Create a guest user_info blob, for anonymous authentication.
395 ****************************************************************************/
397 bool make_user_info_guest(TALLOC_CTX
*mem_ctx
,
398 const struct tsocket_address
*remote_address
,
399 const struct tsocket_address
*local_address
,
400 const char *service_description
,
401 struct auth_usersupplied_info
**user_info
)
405 nt_status
= make_user_info(mem_ctx
,
416 AUTH_PASSWORD_RESPONSE
);
418 return NT_STATUS_IS_OK(nt_status
) ? true : false;
421 static NTSTATUS
log_nt_token(struct security_token
*token
)
423 TALLOC_CTX
*frame
= talloc_stackframe();
424 const struct loadparm_substitution
*lp_sub
=
425 loadparm_s3_global_substitution();
428 struct dom_sid_buf buf
;
431 if ((lp_log_nt_token_command(frame
, lp_sub
) == NULL
) ||
432 (strlen(lp_log_nt_token_command(frame
, lp_sub
)) == 0)) {
437 group_sidstr
= talloc_strdup(frame
, "");
438 for (i
=1; i
<token
->num_sids
; i
++) {
439 group_sidstr
= talloc_asprintf(
440 frame
, "%s %s", group_sidstr
,
441 dom_sid_str_buf(&token
->sids
[i
], &buf
));
444 command
= talloc_string_sub(
445 frame
, lp_log_nt_token_command(frame
, lp_sub
),
446 "%s", dom_sid_str_buf(&token
->sids
[0], &buf
));
447 command
= talloc_string_sub(frame
, command
, "%t", group_sidstr
);
449 if (command
== NULL
) {
451 return NT_STATUS_NO_MEMORY
;
454 DEBUG(8, ("running command: [%s]\n", command
));
455 if (smbrun(command
, NULL
, NULL
) != 0) {
456 DEBUG(0, ("Could not log NT token\n"));
458 return NT_STATUS_ACCESS_DENIED
;
466 * Create the token to use from server_info->info3 and
467 * server_info->sids (the info3/sam groups). Find the unix gids.
470 NTSTATUS
create_local_token(TALLOC_CTX
*mem_ctx
,
471 const struct auth_serversupplied_info
*server_info
,
472 DATA_BLOB
*session_key
,
473 const char *smb_username
, /* for ->sanitized_username, for %U subs */
474 struct auth_session_info
**session_info_out
)
476 struct security_token
*t
;
479 struct dom_sid tmp_sid
;
480 struct auth_session_info
*session_info
= NULL
;
482 bool is_allowed
= false;
484 /* Ensure we can't possible take a code path leading to a
487 return NT_STATUS_LOGON_FAILURE
;
490 if (is_allowed_domain(server_info
->info3
->base
.logon_domain
.string
)) {
494 /* Check if we have extra info about the user. */
495 if (dom_sid_in_domain(&global_sid_Unix_Users
,
496 &server_info
->extra
.user_sid
) ||
497 dom_sid_in_domain(&global_sid_Unix_Groups
,
498 &server_info
->extra
.pgid_sid
))
504 DBG_NOTICE("Authentication failed for user [%s] "
505 "from firewalled domain [%s]\n",
506 server_info
->info3
->base
.account_name
.string
,
507 server_info
->info3
->base
.logon_domain
.string
);
508 return NT_STATUS_AUTHENTICATION_FIREWALL_FAILED
;
511 if (server_info
->cached_session_info
!= NULL
) {
512 session_info
= copy_session_info(mem_ctx
,
513 server_info
->cached_session_info
);
514 if (session_info
== NULL
) {
518 /* This is a potentially untrusted username for use in %U */
519 session_info
->unix_info
->sanitized_username
=
520 talloc_alpha_strcpy(session_info
->unix_info
,
522 SAFE_NETBIOS_CHARS
"$");
523 if (session_info
->unix_info
->sanitized_username
== NULL
) {
527 session_info
->unique_session_token
= GUID_random();
529 *session_info_out
= session_info
;
533 session_info
= talloc_zero(mem_ctx
, struct auth_session_info
);
538 session_info
->unix_token
= talloc_zero(session_info
, struct security_unix_token
);
539 if (!session_info
->unix_token
) {
543 session_info
->unix_token
->uid
= server_info
->utok
.uid
;
544 session_info
->unix_token
->gid
= server_info
->utok
.gid
;
546 session_info
->unix_info
= talloc_zero(session_info
, struct auth_user_info_unix
);
547 if (!session_info
->unix_info
) {
551 session_info
->unix_info
->unix_name
= talloc_strdup(session_info
, server_info
->unix_name
);
552 if (!session_info
->unix_info
->unix_name
) {
556 /* This is a potentially untrusted username for use in %U */
557 session_info
->unix_info
->sanitized_username
=
558 talloc_alpha_strcpy(session_info
->unix_info
,
560 SAFE_NETBIOS_CHARS
"$");
561 if (session_info
->unix_info
->sanitized_username
== NULL
) {
566 data_blob_free(&session_info
->session_key
);
567 session_info
->session_key
= data_blob_talloc(session_info
,
569 session_key
->length
);
570 if (!session_info
->session_key
.data
&& session_key
->length
) {
574 session_info
->session_key
= data_blob_talloc( session_info
, server_info
->session_key
.data
,
575 server_info
->session_key
.length
);
578 /* We need to populate session_info->info with the information found in server_info->info3 */
579 status
= make_user_info_SamBaseInfo(session_info
, "", &server_info
->info3
->base
,
580 server_info
->guest
== false,
581 &session_info
->info
);
582 if (!NT_STATUS_IS_OK(status
)) {
583 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
588 * If the user name was mapped to some local unix user,
589 * we can not make much use of the SIDs the
590 * domain controller provided us with.
592 if (server_info
->nss_token
) {
593 char *found_username
= NULL
;
594 status
= create_token_from_username(session_info
,
595 server_info
->unix_name
,
597 &session_info
->unix_token
->uid
,
598 &session_info
->unix_token
->gid
,
600 &session_info
->security_token
);
601 if (NT_STATUS_IS_OK(status
)) {
602 session_info
->unix_info
->unix_name
= found_username
;
605 status
= create_local_nt_token_from_info3(session_info
,
609 &session_info
->security_token
);
612 if (!NT_STATUS_IS_OK(status
)) {
616 /* Convert the SIDs to gids. */
618 session_info
->unix_token
->ngroups
= 0;
619 session_info
->unix_token
->groups
= NULL
;
621 t
= session_info
->security_token
;
623 ids
= talloc_array(talloc_tos(), struct unixid
,
629 if (!sids_to_unixids(t
->sids
, t
->num_sids
, ids
)) {
633 for (i
=0; i
<t
->num_sids
; i
++) {
635 if (i
== 0 && ids
[i
].type
!= ID_TYPE_BOTH
) {
639 if (ids
[i
].type
!= ID_TYPE_GID
&&
640 ids
[i
].type
!= ID_TYPE_BOTH
) {
641 struct dom_sid_buf buf
;
642 DEBUG(10, ("Could not convert SID %s to gid, "
644 dom_sid_str_buf(&t
->sids
[i
], &buf
)));
647 if (!add_gid_to_array_unique(session_info
->unix_token
,
649 &session_info
->unix_token
->groups
,
650 &session_info
->unix_token
->ngroups
)) {
656 * Add the "Unix Group" SID for each gid to catch mapped groups
657 * and their Unix equivalent. This is to solve the backwards
658 * compatibility problem of 'valid users = +ntadmin' where
659 * ntadmin has been paired with "Domain Admins" in the group
660 * mapping table. Otherwise smb.conf would need to be changed
661 * to 'valid user = "Domain Admins"'. --jerry
663 * For consistency we also add the "Unix User" SID,
664 * so that the complete unix token is represented within
668 uid_to_unix_users_sid(session_info
->unix_token
->uid
, &tmp_sid
);
669 status
= add_sid_to_array_unique(
670 session_info
->security_token
,
672 &session_info
->security_token
->sids
,
673 &session_info
->security_token
->num_sids
);
674 if (!NT_STATUS_IS_OK(status
)) {
678 gid_to_unix_groups_sid(session_info
->unix_token
->gid
, &tmp_sid
);
679 status
= add_sid_to_array_unique(
680 session_info
->security_token
,
682 &session_info
->security_token
->sids
,
683 &session_info
->security_token
->num_sids
);
684 if (!NT_STATUS_IS_OK(status
)) {
688 for ( i
=0; i
<session_info
->unix_token
->ngroups
; i
++ ) {
689 gid_to_unix_groups_sid(session_info
->unix_token
->groups
[i
], &tmp_sid
);
690 status
= add_sid_to_array_unique(
691 session_info
->security_token
,
693 &session_info
->security_token
->sids
,
694 &session_info
->security_token
->num_sids
);
695 if (!NT_STATUS_IS_OK(status
)) {
700 security_token_debug(DBGC_AUTH
, 10, session_info
->security_token
);
701 debug_unix_user_token(DBGC_AUTH
, 10,
702 session_info
->unix_token
->uid
,
703 session_info
->unix_token
->gid
,
704 session_info
->unix_token
->ngroups
,
705 session_info
->unix_token
->groups
);
707 status
= log_nt_token(session_info
->security_token
);
708 if (!NT_STATUS_IS_OK(status
)) {
712 session_info
->unique_session_token
= GUID_random();
714 *session_info_out
= session_info
;
717 status
= NT_STATUS_NO_MEMORY
;
719 TALLOC_FREE(session_info
);
723 NTSTATUS
auth3_user_info_dc_add_hints(struct auth_user_info_dc
*user_info_dc
,
728 uint32_t orig_num_sids
= user_info_dc
->num_sids
;
729 struct dom_sid tmp_sid
= { 0, };
733 * We add S-5-88-1-X in order to pass the uid
734 * for the unix token.
736 sid_compose(&tmp_sid
,
737 &global_sid_Unix_NFS_Users
,
739 status
= add_sid_to_array_attrs_unique(user_info_dc
->sids
,
741 SE_GROUP_DEFAULT_FLAGS
,
743 &user_info_dc
->num_sids
);
744 if (!NT_STATUS_IS_OK(status
)) {
745 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
751 * We add S-5-88-2-X in order to pass the gid
752 * for the unix token.
754 sid_compose(&tmp_sid
,
755 &global_sid_Unix_NFS_Groups
,
757 status
= add_sid_to_array_attrs_unique(user_info_dc
->sids
,
759 SE_GROUP_DEFAULT_FLAGS
,
761 &user_info_dc
->num_sids
);
762 if (!NT_STATUS_IS_OK(status
)) {
763 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
769 * We add S-5-88-3-X in order to pass some flags
770 * (AUTH3_UNIX_HINT_*) to auth3_create_session_info().
772 sid_compose(&tmp_sid
,
773 &global_sid_Unix_NFS_Mode
,
775 status
= add_sid_to_array_attrs_unique(user_info_dc
->sids
,
777 SE_GROUP_DEFAULT_FLAGS
,
779 &user_info_dc
->num_sids
);
780 if (!NT_STATUS_IS_OK(status
)) {
781 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
789 user_info_dc
->num_sids
= orig_num_sids
;
793 static NTSTATUS
auth3_session_info_create(
795 const struct auth_user_info_dc
*user_info_dc
,
796 const char *original_user_name
,
797 uint32_t session_info_flags
,
798 struct auth_session_info
**session_info_out
)
800 TALLOC_CTX
*frame
= talloc_stackframe();
801 struct auth_session_info
*session_info
= NULL
;
803 bool found_hint_uid
= false;
805 bool found_hint_gid
= false;
806 uint32_t hint_flags
= 0;
807 bool found_hint_flags
= false;
808 bool need_getpwuid
= false;
809 struct unixid
*ids
= NULL
;
810 uint32_t num_gids
= 0;
812 struct dom_sid tmp_sid
= { 0, };
817 *session_info_out
= NULL
;
819 if (user_info_dc
->num_sids
== 0) {
821 return NT_STATUS_INVALID_TOKEN
;
824 if (user_info_dc
->info
== NULL
) {
826 return NT_STATUS_INVALID_TOKEN
;
829 if (user_info_dc
->info
->account_name
== NULL
) {
831 return NT_STATUS_INVALID_TOKEN
;
834 session_info
= talloc_zero(mem_ctx
, struct auth_session_info
);
835 if (session_info
== NULL
) {
837 return NT_STATUS_NO_MEMORY
;
839 /* keep this under frame for easier cleanup */
840 talloc_reparent(mem_ctx
, frame
, session_info
);
842 session_info
->info
= auth_user_info_copy(session_info
,
844 if (session_info
->info
== NULL
) {
846 return NT_STATUS_NO_MEMORY
;
849 session_info
->security_token
= talloc_zero(session_info
,
850 struct security_token
);
851 if (session_info
->security_token
== NULL
) {
853 return NT_STATUS_NO_MEMORY
;
857 * Avoid a lot of reallocations and allocate what we'll
860 session_info
->security_token
->sids
= talloc_zero_array(
861 session_info
->security_token
,
863 user_info_dc
->num_sids
);
864 if (session_info
->security_token
->sids
== NULL
) {
866 return NT_STATUS_NO_MEMORY
;
869 for (i
= PRIMARY_USER_SID_INDEX
; i
< user_info_dc
->num_sids
; i
++) {
870 struct security_token
*nt_token
= session_info
->security_token
;
874 * S-1-5-88-X-Y sids are only used to give hints
875 * to the unix token construction.
877 * S-1-5-88-1-Y gives the uid=Y
878 * S-1-5-88-2-Y gives the gid=Y
879 * S-1-5-88-3-Y gives flags=Y: AUTH3_UNIX_HINT_*
881 cmp
= dom_sid_compare_domain(&global_sid_Unix_NFS
,
882 &user_info_dc
->sids
[i
].sid
);
887 match
= sid_peek_rid(&user_info_dc
->sids
[i
].sid
, &hint
);
892 match
= dom_sid_in_domain(&global_sid_Unix_NFS_Users
,
893 &user_info_dc
->sids
[i
].sid
);
895 if (found_hint_uid
) {
897 return NT_STATUS_INVALID_TOKEN
;
899 found_hint_uid
= true;
900 hint_uid
= (uid_t
)hint
;
904 match
= dom_sid_in_domain(&global_sid_Unix_NFS_Groups
,
905 &user_info_dc
->sids
[i
].sid
);
907 if (found_hint_gid
) {
909 return NT_STATUS_INVALID_TOKEN
;
911 found_hint_gid
= true;
912 hint_gid
= (gid_t
)hint
;
916 match
= dom_sid_in_domain(&global_sid_Unix_NFS_Mode
,
917 &user_info_dc
->sids
[i
].sid
);
919 if (found_hint_flags
) {
921 return NT_STATUS_INVALID_TOKEN
;
923 found_hint_flags
= true;
931 status
= add_sid_to_array_unique(nt_token
->sids
,
932 &user_info_dc
->sids
[i
].sid
,
934 &nt_token
->num_sids
);
935 if (!NT_STATUS_IS_OK(status
)) {
942 * We need at least one usable SID
944 if (session_info
->security_token
->num_sids
== 0) {
946 return NT_STATUS_INVALID_TOKEN
;
950 * We need all tree hints: uid, gid, flags
953 if (found_hint_uid
|| found_hint_gid
|| found_hint_flags
) {
954 if (!found_hint_uid
) {
956 return NT_STATUS_INVALID_TOKEN
;
959 if (!found_hint_gid
) {
961 return NT_STATUS_INVALID_TOKEN
;
964 if (!found_hint_flags
) {
966 return NT_STATUS_INVALID_TOKEN
;
970 if (!(user_info_dc
->info
->user_flags
& NETLOGON_GUEST
)) {
971 session_info_flags
|= AUTH_SESSION_INFO_AUTHENTICATED
;
974 status
= finalize_local_nt_token(session_info
->security_token
,
976 if (!NT_STATUS_IS_OK(status
)) {
982 * unless set otherwise, the session key is the user session
983 * key from the auth subsystem
985 if (user_info_dc
->user_session_key
.length
!= 0) {
986 session_info
->session_key
= data_blob_dup_talloc(session_info
,
987 user_info_dc
->user_session_key
);
988 if (session_info
->session_key
.data
== NULL
) {
990 return NT_STATUS_NO_MEMORY
;
994 if (!(session_info_flags
& AUTH_SESSION_INFO_UNIX_TOKEN
)) {
998 session_info
->unix_token
= talloc_zero(session_info
, struct security_unix_token
);
999 if (session_info
->unix_token
== NULL
) {
1001 return NT_STATUS_NO_MEMORY
;
1003 session_info
->unix_token
->uid
= -1;
1004 session_info
->unix_token
->gid
= -1;
1006 session_info
->unix_info
= talloc_zero(session_info
, struct auth_user_info_unix
);
1007 if (session_info
->unix_info
== NULL
) {
1009 return NT_STATUS_NO_MEMORY
;
1012 /* Convert the SIDs to uid/gids. */
1014 ids
= talloc_zero_array(frame
, struct unixid
,
1015 session_info
->security_token
->num_sids
);
1018 return NT_STATUS_NO_MEMORY
;
1021 if (!(hint_flags
& AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS
)) {
1022 ok
= sids_to_unixids(session_info
->security_token
->sids
,
1023 session_info
->security_token
->num_sids
,
1027 return NT_STATUS_NO_MEMORY
;
1031 if (found_hint_uid
) {
1032 session_info
->unix_token
->uid
= hint_uid
;
1033 } else if (ids
[0].type
== ID_TYPE_UID
) {
1035 * The primary SID resolves to a UID only.
1037 session_info
->unix_token
->uid
= ids
[0].id
;
1038 } else if (ids
[0].type
== ID_TYPE_BOTH
) {
1040 * The primary SID resolves to a UID and GID,
1041 * use it as uid and add it as first element
1042 * to the groups array.
1044 session_info
->unix_token
->uid
= ids
[0].id
;
1046 ok
= add_gid_to_array_unique(session_info
->unix_token
,
1047 session_info
->unix_token
->uid
,
1048 &session_info
->unix_token
->groups
,
1049 &session_info
->unix_token
->ngroups
);
1052 return NT_STATUS_NO_MEMORY
;
1056 * It we can't get a uid, we can't imporsonate
1060 return NT_STATUS_INVALID_TOKEN
;
1063 if (found_hint_gid
) {
1064 session_info
->unix_token
->gid
= hint_gid
;
1066 need_getpwuid
= true;
1069 if (hint_flags
& AUTH3_UNIX_HINT_QUALIFIED_NAME
) {
1070 session_info
->unix_info
->unix_name
=
1071 talloc_asprintf(session_info
->unix_info
,
1073 session_info
->info
->domain_name
,
1074 *lp_winbind_separator(),
1075 session_info
->info
->account_name
);
1076 if (session_info
->unix_info
->unix_name
== NULL
) {
1078 return NT_STATUS_NO_MEMORY
;
1080 } else if (hint_flags
& AUTH3_UNIX_HINT_ISLOLATED_NAME
) {
1081 session_info
->unix_info
->unix_name
=
1082 talloc_strdup(session_info
->unix_info
,
1083 session_info
->info
->account_name
);
1084 if (session_info
->unix_info
->unix_name
== NULL
) {
1086 return NT_STATUS_NO_MEMORY
;
1089 need_getpwuid
= true;
1092 if (need_getpwuid
) {
1093 struct passwd
*pwd
= NULL
;
1096 * Ask the system for the primary gid
1097 * and the real unix name.
1099 pwd
= getpwuid_alloc(frame
, session_info
->unix_token
->uid
);
1102 return NT_STATUS_INVALID_TOKEN
;
1104 if (!found_hint_gid
) {
1105 session_info
->unix_token
->gid
= pwd
->pw_gid
;
1108 session_info
->unix_info
->unix_name
=
1109 talloc_strdup(session_info
->unix_info
, pwd
->pw_name
);
1110 if (session_info
->unix_info
->unix_name
== NULL
) {
1112 return NT_STATUS_NO_MEMORY
;
1118 ok
= add_gid_to_array_unique(session_info
->unix_token
,
1119 session_info
->unix_token
->gid
,
1120 &session_info
->unix_token
->groups
,
1121 &session_info
->unix_token
->ngroups
);
1124 return NT_STATUS_NO_MEMORY
;
1127 /* This is a potentially untrusted username for use in %U */
1128 session_info
->unix_info
->sanitized_username
=
1129 talloc_alpha_strcpy(session_info
->unix_info
,
1131 SAFE_NETBIOS_CHARS
"$");
1132 if (session_info
->unix_info
->sanitized_username
== NULL
) {
1134 return NT_STATUS_NO_MEMORY
;
1137 for (i
=0; i
< session_info
->security_token
->num_sids
; i
++) {
1139 if (ids
[i
].type
!= ID_TYPE_GID
&&
1140 ids
[i
].type
!= ID_TYPE_BOTH
) {
1141 struct security_token
*nt_token
=
1142 session_info
->security_token
;
1143 struct dom_sid_buf buf
;
1145 DEBUG(10, ("Could not convert SID %s to gid, "
1147 dom_sid_str_buf(&nt_token
->sids
[i
], &buf
)));
1151 ok
= add_gid_to_array_unique(session_info
->unix_token
,
1153 &session_info
->unix_token
->groups
,
1154 &session_info
->unix_token
->ngroups
);
1157 return NT_STATUS_NO_MEMORY
;
1163 * Now we must get any groups this user has been
1164 * added to in /etc/group and merge them in.
1165 * This has to be done in every code path
1166 * that creates an NT token, as remote users
1167 * may have been added to the local /etc/group
1168 * database. Tokens created merely from the
1169 * info3 structs (via the DC or via the krb5 PAC)
1170 * won't have these local groups. Note the
1171 * groups added here will only be UNIX groups
1172 * (S-1-22-2-XXXX groups) as getgroups_unix_user()
1173 * turns off winbindd before calling getgroups().
1175 * NB. This is duplicating work already
1176 * done in the 'unix_user:' case of
1177 * create_token_from_sid() but won't
1178 * do anything other than be inefficient
1181 if (!(hint_flags
& AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS
)) {
1182 ok
= getgroups_unix_user(frame
,
1183 session_info
->unix_info
->unix_name
,
1184 session_info
->unix_token
->gid
,
1188 return NT_STATUS_INVALID_TOKEN
;
1192 for (i
=0; i
< num_gids
; i
++) {
1194 ok
= add_gid_to_array_unique(session_info
->unix_token
,
1196 &session_info
->unix_token
->groups
,
1197 &session_info
->unix_token
->ngroups
);
1200 return NT_STATUS_NO_MEMORY
;
1205 if (hint_flags
& AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS
) {
1207 * We should not translate the unix token uid/gids
1208 * to S-1-22-X-Y SIDs.
1214 * Add the "Unix Group" SID for each gid to catch mapped groups
1215 * and their Unix equivalent. This is to solve the backwards
1216 * compatibility problem of 'valid users = +ntadmin' where
1217 * ntadmin has been paired with "Domain Admins" in the group
1218 * mapping table. Otherwise smb.conf would need to be changed
1219 * to 'valid user = "Domain Admins"'. --jerry
1221 * For consistency we also add the "Unix User" SID,
1222 * so that the complete unix token is represented within
1226 uid_to_unix_users_sid(session_info
->unix_token
->uid
, &tmp_sid
);
1227 status
= add_sid_to_array_unique(session_info
->security_token
, &tmp_sid
,
1228 &session_info
->security_token
->sids
,
1229 &session_info
->security_token
->num_sids
);
1230 if (!NT_STATUS_IS_OK(status
)) {
1235 gid_to_unix_groups_sid(session_info
->unix_token
->gid
, &tmp_sid
);
1236 status
= add_sid_to_array_unique(session_info
->security_token
, &tmp_sid
,
1237 &session_info
->security_token
->sids
,
1238 &session_info
->security_token
->num_sids
);
1239 if (!NT_STATUS_IS_OK(status
)) {
1244 for (i
=0; i
< session_info
->unix_token
->ngroups
; i
++ ) {
1245 struct security_token
*nt_token
= session_info
->security_token
;
1247 gid_to_unix_groups_sid(session_info
->unix_token
->groups
[i
],
1249 status
= add_sid_to_array_unique(nt_token
->sids
,
1252 &nt_token
->num_sids
);
1253 if (!NT_STATUS_IS_OK(status
)) {
1260 security_token_debug(DBGC_AUTH
, 10, session_info
->security_token
);
1261 if (session_info
->unix_token
!= NULL
) {
1262 debug_unix_user_token(DBGC_AUTH
, 10,
1263 session_info
->unix_token
->uid
,
1264 session_info
->unix_token
->gid
,
1265 session_info
->unix_token
->ngroups
,
1266 session_info
->unix_token
->groups
);
1269 status
= log_nt_token(session_info
->security_token
);
1270 if (!NT_STATUS_IS_OK(status
)) {
1275 session_info
->unique_session_token
= GUID_random();
1277 *session_info_out
= talloc_move(mem_ctx
, &session_info
);
1279 return NT_STATUS_OK
;
1282 /***************************************************************************
1283 Make (and fill) a server_info struct from a 'struct passwd' by conversion
1285 ***************************************************************************/
1287 NTSTATUS
make_server_info_pw(TALLOC_CTX
*mem_ctx
,
1288 const char *unix_username
,
1289 const struct passwd
*pwd
,
1290 struct auth_serversupplied_info
**server_info
)
1293 TALLOC_CTX
*tmp_ctx
= NULL
;
1294 struct auth_serversupplied_info
*result
;
1296 tmp_ctx
= talloc_stackframe();
1297 if (tmp_ctx
== NULL
) {
1298 return NT_STATUS_NO_MEMORY
;
1301 result
= make_server_info(tmp_ctx
);
1302 if (result
== NULL
) {
1303 status
= NT_STATUS_NO_MEMORY
;
1307 status
= passwd_to_SamInfo3(result
,
1312 if (!NT_STATUS_IS_OK(status
)) {
1316 result
->unix_name
= talloc_strdup(result
, unix_username
);
1317 if (result
->unix_name
== NULL
) {
1318 status
= NT_STATUS_NO_MEMORY
;
1322 result
->utok
.uid
= pwd
->pw_uid
;
1323 result
->utok
.gid
= pwd
->pw_gid
;
1325 *server_info
= talloc_move(mem_ctx
, &result
);
1326 status
= NT_STATUS_OK
;
1328 talloc_free(tmp_ctx
);
1333 static NTSTATUS
get_guest_info3(TALLOC_CTX
*mem_ctx
,
1334 struct netr_SamInfo3
*info3
)
1336 const char *guest_account
= lp_guest_account();
1337 struct dom_sid domain_sid
;
1341 pwd
= Get_Pwnam_alloc(mem_ctx
, guest_account
);
1343 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
1344 "account [%s]!\n", guest_account
));
1345 return NT_STATUS_NO_SUCH_USER
;
1348 /* Set account name */
1349 tmp
= talloc_strdup(mem_ctx
, pwd
->pw_name
);
1351 return NT_STATUS_NO_MEMORY
;
1353 init_lsa_String(&info3
->base
.account_name
, tmp
);
1355 /* Set domain name */
1356 tmp
= talloc_strdup(mem_ctx
, get_global_sam_name());
1358 return NT_STATUS_NO_MEMORY
;
1360 init_lsa_StringLarge(&info3
->base
.logon_domain
, tmp
);
1363 sid_copy(&domain_sid
, get_global_sam_sid());
1365 info3
->base
.domain_sid
= dom_sid_dup(mem_ctx
, &domain_sid
);
1366 if (info3
->base
.domain_sid
== NULL
) {
1367 return NT_STATUS_NO_MEMORY
;
1371 info3
->base
.rid
= DOMAIN_RID_GUEST
;
1374 info3
->base
.primary_gid
= DOMAIN_RID_GUESTS
;
1377 info3
->base
.user_flags
= NETLOGON_GUEST
;
1380 return NT_STATUS_OK
;
1383 /***************************************************************************
1384 Make (and fill) a user_info struct for a guest login.
1385 This *must* succeed for smbd to start. If there is no mapping entry for
1386 the guest gid, then create one.
1388 The resulting structure is a 'session_info' because
1389 create_local_token() has already been called on it. This is quite
1390 nasty, as the auth subsystem isn't expect this, but the behavior is
1392 ***************************************************************************/
1394 static NTSTATUS
make_new_session_info_guest(TALLOC_CTX
*mem_ctx
,
1395 struct auth_session_info
**_session_info
,
1396 struct auth_serversupplied_info
**_server_info
)
1398 struct auth_session_info
*session_info
= NULL
;
1399 struct auth_serversupplied_info
*server_info
= NULL
;
1400 const char *guest_account
= lp_guest_account();
1401 const char *domain
= lp_netbios_name();
1402 struct netr_SamInfo3 info3
;
1403 TALLOC_CTX
*tmp_ctx
;
1406 tmp_ctx
= talloc_stackframe();
1407 if (tmp_ctx
== NULL
) {
1408 return NT_STATUS_NO_MEMORY
;
1413 status
= get_guest_info3(tmp_ctx
, &info3
);
1414 if (!NT_STATUS_IS_OK(status
)) {
1415 DEBUG(0, ("get_guest_info3 failed with %s\n",
1416 nt_errstr(status
)));
1420 status
= make_server_info_info3(tmp_ctx
,
1425 if (!NT_STATUS_IS_OK(status
)) {
1426 DEBUG(0, ("make_server_info_info3 failed with %s\n",
1427 nt_errstr(status
)));
1431 server_info
->guest
= true;
1433 /* This should not be done here (we should produce a server
1434 * info, and later construct a session info from it), but for
1435 * now this does not change the previous behavior */
1436 status
= create_local_token(tmp_ctx
, server_info
, NULL
,
1437 server_info
->info3
->base
.account_name
.string
,
1439 if (!NT_STATUS_IS_OK(status
)) {
1440 DEBUG(0, ("create_local_token failed: %s\n",
1441 nt_errstr(status
)));
1446 * It's ugly, but for now it's
1447 * needed to force Builtin_Guests
1448 * here, because memberships of
1449 * Builtin_Guests might be incomplete.
1451 status
= add_sid_to_array_unique(session_info
->security_token
,
1452 &global_sid_Builtin_Guests
,
1453 &session_info
->security_token
->sids
,
1454 &session_info
->security_token
->num_sids
);
1455 if (!NT_STATUS_IS_OK(status
)) {
1456 DBG_ERR("Failed to force Builtin_Guests to nt token\n");
1460 /* annoying, but the Guest really does have a session key, and it is
1462 session_info
->session_key
= data_blob_talloc_zero(session_info
, 16);
1464 *_session_info
= talloc_move(mem_ctx
, &session_info
);
1465 *_server_info
= talloc_move(mem_ctx
, &server_info
);
1467 status
= NT_STATUS_OK
;
1469 TALLOC_FREE(tmp_ctx
);
1473 /***************************************************************************
1474 Make (and fill) a auth_session_info struct for a system user login.
1475 This *must* succeed for smbd to start.
1476 ***************************************************************************/
1478 static NTSTATUS
make_new_session_info_system(TALLOC_CTX
*mem_ctx
,
1479 struct auth_session_info
**session_info
)
1481 TALLOC_CTX
*frame
= talloc_stackframe();
1482 struct auth_user_info_dc
*user_info_dc
= NULL
;
1485 uint32_t hint_flags
= 0;
1486 uint32_t session_info_flags
= 0;
1489 status
= auth_system_user_info_dc(frame
, lp_netbios_name(),
1491 if (!NT_STATUS_IS_OK(status
)) {
1492 DEBUG(0, ("auth_system_user_info_dc failed: %s\n",
1493 nt_errstr(status
)));
1498 * Just get the initial uid/gid
1499 * and don't expand the unix groups.
1501 uid
= sec_initial_uid();
1502 gid
= sec_initial_gid();
1503 hint_flags
|= AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS
;
1506 * Also avoid sid mapping to gids,
1507 * as well as adding the unix_token uid/gids as
1508 * S-1-22-X-Y SIDs to the nt token.
1510 hint_flags
|= AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS
;
1511 hint_flags
|= AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS
;
1514 * The unix name will be "NT AUTHORITY+SYSTEM",
1515 * where '+' is the "winbind separator" character.
1517 hint_flags
|= AUTH3_UNIX_HINT_QUALIFIED_NAME
;
1518 status
= auth3_user_info_dc_add_hints(user_info_dc
,
1522 if (!NT_STATUS_IS_OK(status
)) {
1523 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1524 nt_errstr(status
)));
1528 session_info_flags
|= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES
;
1529 session_info_flags
|= AUTH_SESSION_INFO_UNIX_TOKEN
;
1530 status
= auth3_session_info_create(mem_ctx
, user_info_dc
,
1531 user_info_dc
->info
->account_name
,
1534 if (!NT_STATUS_IS_OK(status
)) {
1535 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1536 nt_errstr(status
)));
1545 static NTSTATUS
make_new_session_info_anonymous(TALLOC_CTX
*mem_ctx
,
1546 struct auth_session_info
**session_info
)
1548 TALLOC_CTX
*frame
= talloc_stackframe();
1549 const char *guest_account
= lp_guest_account();
1550 struct auth_user_info_dc
*user_info_dc
= NULL
;
1551 struct passwd
*pwd
= NULL
;
1552 uint32_t hint_flags
= 0;
1553 uint32_t session_info_flags
= 0;
1557 * We use the guest account for the unix token
1558 * while we use a true anonymous nt token.
1560 * It's very important to have a separate
1561 * nt token for anonymous.
1564 pwd
= Get_Pwnam_alloc(frame
, guest_account
);
1566 DBG_ERR("Unable to locate guest account [%s]!\n",
1568 status
= NT_STATUS_NO_SUCH_USER
;
1572 status
= auth_anonymous_user_info_dc(frame
, lp_netbios_name(),
1574 if (!NT_STATUS_IS_OK(status
)) {
1575 DEBUG(0, ("auth_anonymous_user_info_dc failed: %s\n",
1576 nt_errstr(status
)));
1581 * Note we don't pass AUTH3_UNIX_HINT_QUALIFIED_NAME
1582 * nor AUTH3_UNIX_HINT_ISOLATED_NAME here
1583 * as we want the unix name be found by getpwuid_alloc().
1586 status
= auth3_user_info_dc_add_hints(user_info_dc
,
1590 if (!NT_STATUS_IS_OK(status
)) {
1591 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1592 nt_errstr(status
)));
1597 * In future we may want to remove
1598 * AUTH_SESSION_INFO_DEFAULT_GROUPS.
1600 * Similar to Windows with EveryoneIncludesAnonymous
1601 * and RestrictAnonymous.
1603 * We may introduce AUTH_SESSION_INFO_ANON_WORLD...
1605 * But for this is required to keep the existing tests
1608 session_info_flags
|= AUTH_SESSION_INFO_DEFAULT_GROUPS
;
1609 session_info_flags
|= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES
;
1610 session_info_flags
|= AUTH_SESSION_INFO_UNIX_TOKEN
;
1611 status
= auth3_session_info_create(mem_ctx
, user_info_dc
,
1615 if (!NT_STATUS_IS_OK(status
)) {
1616 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1617 nt_errstr(status
)));
1626 /****************************************************************************
1627 Fake a auth_session_info just from a username (as a
1628 session_info structure, with create_local_token() already called on
1630 ****************************************************************************/
1632 NTSTATUS
make_session_info_from_username(TALLOC_CTX
*mem_ctx
,
1633 const char *username
,
1635 struct auth_session_info
**session_info
)
1639 struct auth_serversupplied_info
*result
;
1640 TALLOC_CTX
*tmp_ctx
;
1642 tmp_ctx
= talloc_stackframe();
1643 if (tmp_ctx
== NULL
) {
1644 return NT_STATUS_NO_MEMORY
;
1647 pwd
= Get_Pwnam_alloc(tmp_ctx
, username
);
1649 status
= NT_STATUS_NO_SUCH_USER
;
1653 status
= make_server_info_pw(tmp_ctx
, pwd
->pw_name
, pwd
, &result
);
1654 if (!NT_STATUS_IS_OK(status
)) {
1658 result
->nss_token
= true;
1659 result
->guest
= is_guest
;
1661 /* Now turn the server_info into a session_info with the full token etc */
1662 status
= create_local_token(mem_ctx
,
1669 talloc_free(tmp_ctx
);
1674 /* This function MUST only used to create the cached server_info for
1677 * This is a lossy conversion. Variables known to be lost so far
1680 * - nss_token (not needed because the only read doesn't happen
1681 * for the GUEST user, as this routine populates ->security_token
1683 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1685 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1687 static struct auth_serversupplied_info
*copy_session_info_serverinfo_guest(TALLOC_CTX
*mem_ctx
,
1688 const struct auth_session_info
*src
,
1689 struct auth_serversupplied_info
*server_info
)
1691 struct auth_serversupplied_info
*dst
;
1694 dst
= make_server_info(mem_ctx
);
1699 /* This element must be provided to convert back to an auth_serversupplied_info */
1700 SMB_ASSERT(src
->unix_info
);
1704 /* This element must be provided to convert back to an
1705 * auth_serversupplied_info. This needs to be from the
1706 * auth_session_info because the group values in particular
1707 * may change during create_local_token() processing */
1708 SMB_ASSERT(src
->unix_token
);
1709 dst
->utok
.uid
= src
->unix_token
->uid
;
1710 dst
->utok
.gid
= src
->unix_token
->gid
;
1711 dst
->utok
.ngroups
= src
->unix_token
->ngroups
;
1712 if (src
->unix_token
->ngroups
!= 0) {
1713 dst
->utok
.groups
= (gid_t
*)talloc_memdup(
1714 dst
, src
->unix_token
->groups
,
1715 sizeof(gid_t
)*dst
->utok
.ngroups
);
1717 dst
->utok
.groups
= NULL
;
1720 /* We must have a security_token as otherwise the lossy
1721 * conversion without nss_token would cause create_local_token
1722 * to take the wrong path */
1723 SMB_ASSERT(src
->security_token
);
1725 dst
->session_key
= data_blob_talloc( dst
, src
->session_key
.data
,
1726 src
->session_key
.length
);
1728 /* This is OK because this functions is only used for the
1729 * GUEST account, which has all-zero keys for both values */
1730 dst
->lm_session_key
= data_blob_talloc(dst
, src
->session_key
.data
,
1731 src
->session_key
.length
);
1733 status
= copy_netr_SamInfo3(dst
,
1736 if (!NT_STATUS_IS_OK(status
)) {
1741 dst
->unix_name
= talloc_strdup(dst
, src
->unix_info
->unix_name
);
1742 if (!dst
->unix_name
) {
1747 dst
->cached_session_info
= src
;
1752 * Set a new session key. Used in the rpc server where we have to override the
1753 * SMB level session key with SystemLibraryDTC
1756 bool session_info_set_session_key(struct auth_session_info
*info
,
1757 DATA_BLOB session_key
)
1759 TALLOC_FREE(info
->session_key
.data
);
1761 info
->session_key
= data_blob_talloc(
1762 info
, session_key
.data
, session_key
.length
);
1764 return (info
->session_key
.data
!= NULL
);
1767 static struct auth_session_info
*guest_info
= NULL
;
1768 static struct auth_session_info
*anonymous_info
= NULL
;
1770 static struct auth_serversupplied_info
*guest_server_info
= NULL
;
1772 bool init_guest_session_info(TALLOC_CTX
*mem_ctx
)
1776 if (guest_info
!= NULL
)
1779 status
= make_new_session_info_guest(mem_ctx
,
1781 &guest_server_info
);
1782 if (!NT_STATUS_IS_OK(status
)) {
1786 status
= make_new_session_info_anonymous(mem_ctx
,
1788 if (!NT_STATUS_IS_OK(status
)) {
1795 bool reinit_guest_session_info(TALLOC_CTX
*mem_ctx
)
1797 TALLOC_FREE(guest_info
);
1798 TALLOC_FREE(guest_server_info
);
1799 TALLOC_FREE(anonymous_info
);
1801 DBG_DEBUG("Reinitialing guest info\n");
1803 return init_guest_session_info(mem_ctx
);
1806 NTSTATUS
make_server_info_guest(TALLOC_CTX
*mem_ctx
,
1807 struct auth_serversupplied_info
**server_info
)
1809 /* This is trickier than it would appear to need to be because
1810 * we are trying to avoid certain costly operations when the
1811 * structure is converted to a 'auth_session_info' again in
1812 * create_local_token() */
1813 *server_info
= copy_session_info_serverinfo_guest(mem_ctx
, guest_info
, guest_server_info
);
1814 return (*server_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
1817 NTSTATUS
make_session_info_guest(TALLOC_CTX
*mem_ctx
,
1818 struct auth_session_info
**session_info
)
1820 *session_info
= copy_session_info(mem_ctx
, guest_info
);
1821 return (*session_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
1824 NTSTATUS
make_server_info_anonymous(TALLOC_CTX
*mem_ctx
,
1825 struct auth_serversupplied_info
**server_info
)
1827 if (anonymous_info
== NULL
) {
1828 return NT_STATUS_UNSUCCESSFUL
;
1832 * This is trickier than it would appear to need to be because
1833 * we are trying to avoid certain costly operations when the
1834 * structure is converted to a 'auth_session_info' again in
1835 * create_local_token()
1837 * We use a guest server_info, but with the anonymous session info,
1838 * which means create_local_token() will return a copy
1839 * of the anonymous token.
1841 * The server info is just used as legacy in order to
1842 * keep existing code working. Maybe some debug messages
1843 * will still refer to guest instead of anonymous.
1845 *server_info
= copy_session_info_serverinfo_guest(mem_ctx
, anonymous_info
,
1847 if (*server_info
== NULL
) {
1848 return NT_STATUS_NO_MEMORY
;
1851 return NT_STATUS_OK
;
1854 NTSTATUS
make_session_info_anonymous(TALLOC_CTX
*mem_ctx
,
1855 struct auth_session_info
**session_info
)
1857 if (anonymous_info
== NULL
) {
1858 return NT_STATUS_UNSUCCESSFUL
;
1861 *session_info
= copy_session_info(mem_ctx
, anonymous_info
);
1862 if (*session_info
== NULL
) {
1863 return NT_STATUS_NO_MEMORY
;
1866 return NT_STATUS_OK
;
1869 static struct auth_session_info
*system_info
= NULL
;
1871 NTSTATUS
init_system_session_info(TALLOC_CTX
*mem_ctx
)
1873 if (system_info
!= NULL
)
1874 return NT_STATUS_OK
;
1876 return make_new_session_info_system(mem_ctx
, &system_info
);
1879 NTSTATUS
make_session_info_system(TALLOC_CTX
*mem_ctx
,
1880 struct auth_session_info
**session_info
)
1882 if (system_info
== NULL
) return NT_STATUS_UNSUCCESSFUL
;
1883 *session_info
= copy_session_info(mem_ctx
, system_info
);
1884 return (*session_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
1887 const struct auth_session_info
*get_session_info_system(void)
1892 /***************************************************************************
1893 Purely internal function for make_server_info_info3
1894 ***************************************************************************/
1896 static NTSTATUS
check_account(TALLOC_CTX
*mem_ctx
, const char *domain
,
1897 const char *username
,
1898 const struct dom_sid
*sid
,
1899 char **found_username
,
1900 struct passwd
**pwd
,
1901 bool *username_was_mapped
)
1903 char *orig_dom_user
= NULL
;
1904 char *dom_user
= NULL
;
1905 char *lower_username
= NULL
;
1906 char *real_username
= NULL
;
1907 struct passwd
*passwd
;
1909 lower_username
= talloc_strdup(mem_ctx
, username
);
1910 if (!lower_username
) {
1911 return NT_STATUS_NO_MEMORY
;
1913 if (!strlower_m( lower_username
)) {
1914 return NT_STATUS_INVALID_PARAMETER
;
1917 orig_dom_user
= talloc_asprintf(mem_ctx
,
1920 *lp_winbind_separator(),
1922 if (!orig_dom_user
) {
1923 return NT_STATUS_NO_MEMORY
;
1926 /* Get the passwd struct. Try to create the account if necessary. */
1928 *username_was_mapped
= map_username(mem_ctx
, orig_dom_user
, &dom_user
);
1930 return NT_STATUS_NO_MEMORY
;
1933 passwd
= smb_getpwnam(mem_ctx
, dom_user
, &real_username
, false);
1934 if (!passwd
&& !*username_was_mapped
) {
1935 struct dom_sid_buf buf
;
1939 DBG_DEBUG("Failed to find authenticated user %s via "
1940 "getpwnam(), fallback to sid_to_uid(%s).\n",
1941 dom_user
, dom_sid_str_buf(sid
, &buf
));
1943 ok
= sid_to_uid(sid
, &uid
);
1945 DBG_ERR("Failed to convert SID %s to a UID (dom_user[%s])\n",
1946 dom_sid_str_buf(sid
, &buf
), dom_user
);
1947 return NT_STATUS_NO_SUCH_USER
;
1949 passwd
= getpwuid_alloc(mem_ctx
, uid
);
1951 DBG_ERR("Failed to find local account with UID %lld for SID %s (dom_user[%s])\n",
1953 dom_sid_str_buf(sid
, &buf
),
1955 return NT_STATUS_NO_SUCH_USER
;
1957 real_username
= talloc_strdup(mem_ctx
, passwd
->pw_name
);
1960 DEBUG(3, ("Failed to find authenticated user %s via "
1961 "getpwnam(), denying access.\n", dom_user
));
1962 return NT_STATUS_NO_SUCH_USER
;
1965 if (!real_username
) {
1966 return NT_STATUS_NO_MEMORY
;
1971 /* This is pointless -- there is no support for differing
1972 unix and windows names. Make sure to always store the
1973 one we actually looked up and succeeded. Have I mentioned
1974 why I hate the 'winbind use default domain' parameter?
1977 *found_username
= talloc_strdup( mem_ctx
, real_username
);
1979 return NT_STATUS_OK
;
1982 /****************************************************************************
1983 Wrapper to allow the getpwnam() call to strip the domain name and
1984 try again in case a local UNIX user is already there. Also run through
1985 the username if we fallback to the username only.
1986 ****************************************************************************/
1988 struct passwd
*smb_getpwnam( TALLOC_CTX
*mem_ctx
, const char *domuser
,
1989 char **p_save_username
, bool create
)
1991 struct passwd
*pw
= NULL
;
1993 const char *username
= NULL
;
1995 /* we only save a copy of the username it has been mangled
1996 by winbindd use default domain */
1997 *p_save_username
= NULL
;
1999 /* don't call map_username() here since it has to be done higher
2000 up the stack so we don't call it multiple times */
2002 username
= talloc_strdup(mem_ctx
, domuser
);
2007 p
= strchr_m( username
, *lp_winbind_separator() );
2009 /* code for a DOMAIN\user string */
2012 const char *domain
= NULL
;
2014 /* split the domain and username into 2 strings */
2020 if (strequal(domain
, get_global_sam_name())) {
2022 * This typically don't happen
2023 * as check_sam_Security()
2024 * don't call make_server_info_info3()
2025 * and thus check_account().
2027 * But we better keep this.
2032 pw
= Get_Pwnam_alloc( mem_ctx
, domuser
);
2036 /* make sure we get the case of the username correct */
2037 /* work around 'winbind use default domain = yes' */
2039 if ( lp_winbind_use_default_domain() &&
2040 !strchr_m( pw
->pw_name
, *lp_winbind_separator() ) ) {
2041 *p_save_username
= talloc_asprintf(mem_ctx
,
2044 *lp_winbind_separator(),
2046 if (!*p_save_username
) {
2051 *p_save_username
= talloc_strdup(mem_ctx
, pw
->pw_name
);
2059 /* just lookup a plain username */
2061 pw
= Get_Pwnam_alloc(mem_ctx
, username
);
2063 /* Create local user if requested but only if winbindd
2064 is not running. We need to protect against cases
2065 where winbindd is failing and then prematurely
2066 creating users in /etc/passwd */
2068 if ( !pw
&& create
&& !winbind_ping() ) {
2069 /* Don't add a machine account. */
2070 if (username
[strlen(username
)-1] == '$')
2073 _smb_create_user(NULL
, username
, NULL
);
2074 pw
= Get_Pwnam_alloc(mem_ctx
, username
);
2077 /* one last check for a valid passwd struct */
2080 *p_save_username
= talloc_strdup(mem_ctx
, pw
->pw_name
);
2085 /***************************************************************************
2086 Make a server_info struct from the info3 returned by a domain logon
2087 ***************************************************************************/
2089 NTSTATUS
make_server_info_info3(TALLOC_CTX
*mem_ctx
,
2090 const char *sent_nt_username
,
2092 struct auth_serversupplied_info
**server_info
,
2093 const struct netr_SamInfo3
*info3
)
2096 char *found_username
= NULL
;
2097 const char *nt_domain
;
2098 const char *nt_username
;
2099 struct dom_sid user_sid
;
2100 struct dom_sid group_sid
;
2101 bool username_was_mapped
;
2103 struct auth_serversupplied_info
*result
;
2105 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
2108 Here is where we should check the list of
2109 trusted domains, and verify that the SID
2113 if (!sid_compose(&user_sid
, info3
->base
.domain_sid
, info3
->base
.rid
)) {
2114 nt_status
= NT_STATUS_INVALID_PARAMETER
;
2118 if (!sid_compose(&group_sid
, info3
->base
.domain_sid
,
2119 info3
->base
.primary_gid
)) {
2120 nt_status
= NT_STATUS_INVALID_PARAMETER
;
2124 nt_username
= talloc_strdup(tmp_ctx
, info3
->base
.account_name
.string
);
2126 /* If the server didn't give us one, just use the one we sent
2128 nt_username
= sent_nt_username
;
2131 nt_domain
= talloc_strdup(mem_ctx
, info3
->base
.logon_domain
.string
);
2133 /* If the server didn't give us one, just use the one we sent
2138 /* If getpwnam() fails try the add user script (2.2.x behavior).
2140 We use the _unmapped_ username here in an attempt to provide
2141 consistent username mapping behavior between kerberos and NTLM[SSP]
2142 authentication in domain mode security. I.E. Username mapping
2143 should be applied to the fully qualified username
2144 (e.g. DOMAIN\user) and not just the login name. Yes this means we
2145 called map_username() unnecessarily in make_user_info_map() but
2146 that is how the current code is designed. Making the change here
2147 is the least disruptive place. -- jerry */
2149 /* this call will try to create the user if necessary */
2151 sid_copy(&sid
, info3
->base
.domain_sid
);
2152 sid_append_rid(&sid
, info3
->base
.rid
);
2154 nt_status
= check_account(tmp_ctx
,
2160 &username_was_mapped
);
2162 if (!NT_STATUS_IS_OK(nt_status
)) {
2163 /* Handle 'map to guest = Bad Uid */
2164 if (NT_STATUS_EQUAL(nt_status
, NT_STATUS_NO_SUCH_USER
) &&
2165 (lp_security() == SEC_ADS
|| lp_security() == SEC_DOMAIN
) &&
2166 lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID
) {
2167 DBG_NOTICE("Try to map %s to guest account\n",
2169 nt_status
= make_server_info_guest(tmp_ctx
, &result
);
2170 if (NT_STATUS_IS_OK(nt_status
)) {
2171 *server_info
= talloc_move(mem_ctx
, &result
);
2175 } else if ((lp_security() == SEC_ADS
|| lp_security() == SEC_DOMAIN
) &&
2176 !is_myname(domain
) && pwd
->pw_uid
< lp_min_domain_uid()) {
2178 * !is_myname(domain) because when smbd starts tries to setup
2179 * the guest user info, calling this function with nobody
2180 * username. Nobody is usually uid 65535 but it can be changed
2181 * to a regular user with 'guest account' parameter
2183 nt_status
= NT_STATUS_INVALID_TOKEN
;
2184 DBG_NOTICE("Username '%s%s%s' is invalid on this system, "
2185 "it does not meet 'min domain uid' "
2186 "restriction (%u < %u): %s\n",
2187 nt_domain
, lp_winbind_separator(), nt_username
,
2188 pwd
->pw_uid
, lp_min_domain_uid(),
2189 nt_errstr(nt_status
));
2193 result
= make_server_info(tmp_ctx
);
2194 if (result
== NULL
) {
2195 DEBUG(4, ("make_server_info failed!\n"));
2196 nt_status
= NT_STATUS_NO_MEMORY
;
2200 result
->unix_name
= talloc_strdup(result
, found_username
);
2202 /* copy in the info3 */
2203 nt_status
= copy_netr_SamInfo3(result
,
2206 if (!NT_STATUS_IS_OK(nt_status
)) {
2210 /* Fill in the unix info we found on the way */
2212 result
->utok
.uid
= pwd
->pw_uid
;
2213 result
->utok
.gid
= pwd
->pw_gid
;
2215 /* ensure we are never given NULL session keys */
2217 if (all_zero(info3
->base
.key
.key
, sizeof(info3
->base
.key
.key
))) {
2218 result
->session_key
= data_blob_null
;
2220 result
->session_key
= data_blob_talloc(
2221 result
, info3
->base
.key
.key
,
2222 sizeof(info3
->base
.key
.key
));
2225 if (all_zero(info3
->base
.LMSessKey
.key
,
2226 sizeof(info3
->base
.LMSessKey
.key
))) {
2227 result
->lm_session_key
= data_blob_null
;
2229 result
->lm_session_key
= data_blob_talloc(
2230 result
, info3
->base
.LMSessKey
.key
,
2231 sizeof(info3
->base
.LMSessKey
.key
));
2234 result
->nss_token
|= username_was_mapped
;
2236 result
->guest
= (info3
->base
.user_flags
& NETLOGON_GUEST
);
2238 *server_info
= talloc_move(mem_ctx
, &result
);
2240 nt_status
= NT_STATUS_OK
;
2242 talloc_free(tmp_ctx
);
2247 /*****************************************************************************
2248 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
2249 ******************************************************************************/
2251 NTSTATUS
make_server_info_wbcAuthUserInfo(TALLOC_CTX
*mem_ctx
,
2252 const char *sent_nt_username
,
2254 const struct wbcAuthUserInfo
*info
,
2255 struct auth_serversupplied_info
**server_info
)
2257 struct netr_SamInfo3 info3
;
2258 struct netr_SamInfo6
*info6
;
2260 info6
= wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx
, info
);
2262 return NT_STATUS_NO_MEMORY
;
2265 info3
.base
= info6
->base
;
2266 info3
.sidcount
= info6
->sidcount
;
2267 info3
.sids
= info6
->sids
;
2269 return make_server_info_info3(mem_ctx
,
2270 sent_nt_username
, domain
,
2271 server_info
, &info3
);
2275 * Verify whether or not given domain is trusted.
2277 * This should only be used on a DC.
2279 * @param domain_name name of the domain to be verified
2280 * @return true if domain is one of the trusted ones or
2281 * false if otherwise
2284 bool is_trusted_domain(const char* dom_name
)
2292 if (dom_name
== NULL
|| dom_name
[0] == '\0') {
2296 if (strequal(dom_name
, get_global_sam_name())) {
2301 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2302 "[%s]\n", dom_name
));
2303 ret
= pdb_get_trusteddom_pw(dom_name
, NULL
, NULL
, NULL
);
2312 on a logon error possibly map the error to success if "map to guest"
2313 is set appropriately
2315 NTSTATUS
do_map_to_guest_server_info(TALLOC_CTX
*mem_ctx
,
2319 struct auth_serversupplied_info
**server_info
)
2321 user
= user
? user
: "";
2322 domain
= domain
? domain
: "";
2324 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
2325 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER
) ||
2326 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
)) {
2327 DEBUG(3,("No such user %s [%s] - using guest account\n",
2329 return make_server_info_guest(mem_ctx
, server_info
);
2331 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
2332 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
) {
2333 DEBUG(3,("Registered username %s for guest access\n",
2335 return make_server_info_guest(mem_ctx
, server_info
);
2343 Extract session key from a session info and return it in a blob
2344 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
2346 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
2347 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
2349 Note that returned session_key is referencing the original key, it is supposed to be
2350 short-lived. If original session_info->session_key is gone, the reference will be broken.
2352 NTSTATUS
session_extract_session_key(const struct auth_session_info
*session_info
, DATA_BLOB
*session_key
, enum session_key_use_intent intent
)
2355 if (session_key
== NULL
|| session_info
== NULL
) {
2356 return NT_STATUS_INVALID_PARAMETER
;
2359 if (session_info
->session_key
.length
== 0) {
2360 return NT_STATUS_NO_USER_SESSION_KEY
;
2363 *session_key
= session_info
->session_key
;
2364 if (intent
== KEY_USE_16BYTES
) {
2365 session_key
->length
= MIN(session_info
->session_key
.length
, 16);
2367 return NT_STATUS_OK
;