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 "../libcli/auth/libcli_auth.h"
27 #include "../lib/crypto/arcfour.h"
28 #include "rpc_client/init_lsa.h"
29 #include "../libcli/security/security.h"
30 #include "../lib/util/util_pw.h"
31 #include "lib/winbind_util.h"
33 #include "../librpc/gen_ndr/ndr_auth.h"
34 #include "../auth/auth_sam_reply.h"
35 #include "../librpc/gen_ndr/idmap.h"
36 #include "lib/param/loadparm.h"
39 #define DBGC_CLASS DBGC_AUTH
41 /****************************************************************************
42 Create a UNIX user on demand.
43 ****************************************************************************/
45 static int _smb_create_user(const char *domain
, const char *unix_username
, const char *homedir
)
47 TALLOC_CTX
*ctx
= talloc_tos();
51 add_script
= lp_add_user_script(ctx
);
52 if (!add_script
|| !*add_script
) {
55 add_script
= talloc_all_string_sub(ctx
,
63 add_script
= talloc_all_string_sub(ctx
,
72 add_script
= talloc_all_string_sub(ctx
,
80 ret
= smbrun(add_script
,NULL
);
83 ("smb_create_user: Running the command `%s' gave %d\n",
88 /****************************************************************************
89 Create an auth_usersupplied_data structure after appropriate mapping.
90 ****************************************************************************/
92 NTSTATUS
make_user_info_map(TALLOC_CTX
*mem_ctx
,
93 struct auth_usersupplied_info
**user_info
,
95 const char *client_domain
,
96 const char *workstation_name
,
97 const struct tsocket_address
*remote_address
,
98 const DATA_BLOB
*lm_pwd
,
99 const DATA_BLOB
*nt_pwd
,
100 const struct samr_Password
*lm_interactive_pwd
,
101 const struct samr_Password
*nt_interactive_pwd
,
102 const char *plaintext
,
103 enum auth_password_state password_state
)
108 char *internal_username
= NULL
;
110 was_mapped
= map_username(talloc_tos(), smb_name
, &internal_username
);
111 if (!internal_username
) {
112 return NT_STATUS_NO_MEMORY
;
115 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
116 client_domain
, smb_name
, workstation_name
));
118 domain
= client_domain
;
120 /* If you connect to a Windows domain member using a bogus domain name,
121 * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if
122 * the Windows box is a DC the name will become DOMAIN\user and be
123 * authenticated against AD, if the Windows box is a member server but
124 * not a DC the name will become WORKSTATION\user. A standalone
125 * non-domain member box will also map to WORKSTATION\user.
126 * This also deals with the client passing in a "" domain */
128 if (!is_trusted_domain(domain
) &&
129 !strequal(domain
, my_sam_name()) &&
130 !strequal(domain
, get_global_sam_name()))
132 if (lp_map_untrusted_to_domain())
133 domain
= my_sam_name();
135 domain
= get_global_sam_name();
136 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
137 "workstation [%s]\n",
138 client_domain
, domain
, smb_name
, workstation_name
));
141 /* We know that the given domain is trusted (and we are allowing them),
142 * it is our global SAM name, or for legacy behavior it is our
143 * primary domain name */
145 result
= make_user_info(mem_ctx
, user_info
, smb_name
, internal_username
,
146 client_domain
, domain
, workstation_name
,
147 remote_address
, lm_pwd
, nt_pwd
,
148 lm_interactive_pwd
, nt_interactive_pwd
,
149 plaintext
, password_state
);
150 if (NT_STATUS_IS_OK(result
)) {
151 /* We have tried mapping */
152 (*user_info
)->mapped_state
= true;
153 /* did we actually map the user to a different name? */
154 (*user_info
)->was_mapped
= was_mapped
;
159 /****************************************************************************
160 Create an auth_usersupplied_data, making the DATA_BLOBs here.
161 Decrypt and encrypt the passwords.
162 ****************************************************************************/
164 bool make_user_info_netlogon_network(TALLOC_CTX
*mem_ctx
,
165 struct auth_usersupplied_info
**user_info
,
166 const char *smb_name
,
167 const char *client_domain
,
168 const char *workstation_name
,
169 const struct tsocket_address
*remote_address
,
170 uint32 logon_parameters
,
171 const uchar
*lm_network_pwd
,
173 const uchar
*nt_network_pwd
,
178 DATA_BLOB lm_blob
= data_blob(lm_network_pwd
, lm_pwd_len
);
179 DATA_BLOB nt_blob
= data_blob(nt_network_pwd
, nt_pwd_len
);
181 status
= make_user_info_map(mem_ctx
, user_info
,
182 smb_name
, client_domain
,
185 lm_pwd_len
? &lm_blob
: NULL
,
186 nt_pwd_len
? &nt_blob
: NULL
,
188 AUTH_PASSWORD_RESPONSE
);
190 if (NT_STATUS_IS_OK(status
)) {
191 (*user_info
)->logon_parameters
= logon_parameters
;
193 ret
= NT_STATUS_IS_OK(status
) ? true : false;
195 data_blob_free(&lm_blob
);
196 data_blob_free(&nt_blob
);
200 /****************************************************************************
201 Create an auth_usersupplied_data, making the DATA_BLOBs here.
202 Decrypt and encrypt the passwords.
203 ****************************************************************************/
205 bool make_user_info_netlogon_interactive(TALLOC_CTX
*mem_ctx
,
206 struct auth_usersupplied_info
**user_info
,
207 const char *smb_name
,
208 const char *client_domain
,
209 const char *workstation_name
,
210 const struct tsocket_address
*remote_address
,
211 uint32 logon_parameters
,
213 const uchar lm_interactive_pwd
[16],
214 const uchar nt_interactive_pwd
[16])
216 struct samr_Password lm_pwd
;
217 struct samr_Password nt_pwd
;
218 unsigned char local_lm_response
[24];
219 unsigned char local_nt_response
[24];
221 if (lm_interactive_pwd
)
222 memcpy(lm_pwd
.hash
, lm_interactive_pwd
, sizeof(lm_pwd
.hash
));
224 if (nt_interactive_pwd
)
225 memcpy(nt_pwd
.hash
, nt_interactive_pwd
, sizeof(nt_pwd
.hash
));
227 if (lm_interactive_pwd
)
228 SMBOWFencrypt(lm_pwd
.hash
, chal
,
231 if (nt_interactive_pwd
)
232 SMBOWFencrypt(nt_pwd
.hash
, chal
,
238 DATA_BLOB local_lm_blob
= data_blob_null
;
239 DATA_BLOB local_nt_blob
= data_blob_null
;
241 if (lm_interactive_pwd
) {
242 local_lm_blob
= data_blob(local_lm_response
,
243 sizeof(local_lm_response
));
246 if (nt_interactive_pwd
) {
247 local_nt_blob
= data_blob(local_nt_response
,
248 sizeof(local_nt_response
));
251 nt_status
= make_user_info_map(
254 smb_name
, client_domain
, workstation_name
,
256 lm_interactive_pwd
? &local_lm_blob
: NULL
,
257 nt_interactive_pwd
? &local_nt_blob
: NULL
,
258 lm_interactive_pwd
? &lm_pwd
: NULL
,
259 nt_interactive_pwd
? &nt_pwd
: NULL
,
260 NULL
, AUTH_PASSWORD_HASH
);
262 if (NT_STATUS_IS_OK(nt_status
)) {
263 (*user_info
)->logon_parameters
= logon_parameters
;
266 ret
= NT_STATUS_IS_OK(nt_status
) ? true : false;
267 data_blob_free(&local_lm_blob
);
268 data_blob_free(&local_nt_blob
);
274 /****************************************************************************
275 Create an auth_usersupplied_data structure
276 ****************************************************************************/
278 bool make_user_info_for_reply(TALLOC_CTX
*mem_ctx
,
279 struct auth_usersupplied_info
**user_info
,
280 const char *smb_name
,
281 const char *client_domain
,
282 const struct tsocket_address
*remote_address
,
284 DATA_BLOB plaintext_password
)
287 DATA_BLOB local_lm_blob
;
288 DATA_BLOB local_nt_blob
;
289 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
290 char *plaintext_password_string
;
292 * Not encrypted - do so.
295 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
297 if (plaintext_password
.data
&& plaintext_password
.length
) {
298 unsigned char local_lm_response
[24];
300 #ifdef DEBUG_PASSWORD
301 DEBUG(10,("Unencrypted password (len %d):\n",
302 (int)plaintext_password
.length
));
303 dump_data(100, plaintext_password
.data
,
304 plaintext_password
.length
);
307 SMBencrypt( (const char *)plaintext_password
.data
,
308 (const uchar
*)chal
, local_lm_response
);
309 local_lm_blob
= data_blob(local_lm_response
, 24);
311 /* We can't do an NT hash here, as the password needs to be
313 local_nt_blob
= data_blob_null
;
315 local_lm_blob
= data_blob_null
;
316 local_nt_blob
= data_blob_null
;
319 plaintext_password_string
= talloc_strndup(talloc_tos(),
320 (const char *)plaintext_password
.data
,
321 plaintext_password
.length
);
322 if (!plaintext_password_string
) {
326 ret
= make_user_info(mem_ctx
,
327 user_info
, smb_name
, smb_name
, client_domain
, client_domain
,
328 get_remote_machine_name(),
330 local_lm_blob
.data
? &local_lm_blob
: NULL
,
331 local_nt_blob
.data
? &local_nt_blob
: NULL
,
333 plaintext_password_string
,
334 AUTH_PASSWORD_PLAIN
);
336 if (plaintext_password_string
) {
337 memset(plaintext_password_string
, '\0', strlen(plaintext_password_string
));
338 talloc_free(plaintext_password_string
);
341 data_blob_free(&local_lm_blob
);
342 return NT_STATUS_IS_OK(ret
) ? true : false;
345 /****************************************************************************
346 Create an auth_usersupplied_data structure
347 ****************************************************************************/
349 NTSTATUS
make_user_info_for_reply_enc(TALLOC_CTX
*mem_ctx
,
350 struct auth_usersupplied_info
**user_info
,
351 const char *smb_name
,
352 const char *client_domain
,
353 const struct tsocket_address
*remote_address
,
354 DATA_BLOB lm_resp
, DATA_BLOB nt_resp
)
356 return make_user_info(mem_ctx
,
357 user_info
, smb_name
, smb_name
,
358 client_domain
, client_domain
,
359 get_remote_machine_name(),
361 lm_resp
.data
&& (lm_resp
.length
> 0) ? &lm_resp
: NULL
,
362 nt_resp
.data
&& (nt_resp
.length
> 0) ? &nt_resp
: NULL
,
364 AUTH_PASSWORD_RESPONSE
);
367 /****************************************************************************
368 Create a guest user_info blob, for anonymous authentication.
369 ****************************************************************************/
371 bool make_user_info_guest(TALLOC_CTX
*mem_ctx
,
372 const struct tsocket_address
*remote_address
,
373 struct auth_usersupplied_info
**user_info
)
377 nt_status
= make_user_info(mem_ctx
,
386 AUTH_PASSWORD_RESPONSE
);
388 return NT_STATUS_IS_OK(nt_status
) ? true : false;
391 static NTSTATUS
log_nt_token(struct security_token
*token
)
393 TALLOC_CTX
*frame
= talloc_stackframe();
398 if ((lp_log_nt_token_command(frame
) == NULL
) ||
399 (strlen(lp_log_nt_token_command(frame
)) == 0)) {
404 group_sidstr
= talloc_strdup(frame
, "");
405 for (i
=1; i
<token
->num_sids
; i
++) {
406 group_sidstr
= talloc_asprintf(
407 frame
, "%s %s", group_sidstr
,
408 sid_string_talloc(frame
, &token
->sids
[i
]));
411 command
= talloc_string_sub(
412 frame
, lp_log_nt_token_command(frame
),
413 "%s", sid_string_talloc(frame
, &token
->sids
[0]));
414 command
= talloc_string_sub(frame
, command
, "%t", group_sidstr
);
416 if (command
== NULL
) {
418 return NT_STATUS_NO_MEMORY
;
421 DEBUG(8, ("running command: [%s]\n", command
));
422 if (smbrun(command
, NULL
) != 0) {
423 DEBUG(0, ("Could not log NT token\n"));
425 return NT_STATUS_ACCESS_DENIED
;
433 * Create the token to use from server_info->info3 and
434 * server_info->sids (the info3/sam groups). Find the unix gids.
437 NTSTATUS
create_local_token(TALLOC_CTX
*mem_ctx
,
438 const struct auth_serversupplied_info
*server_info
,
439 DATA_BLOB
*session_key
,
440 const char *smb_username
, /* for ->sanitized_username, for %U subs */
441 struct auth_session_info
**session_info_out
)
443 struct security_token
*t
;
446 struct dom_sid tmp_sid
;
447 struct auth_session_info
*session_info
;
451 /* Ensure we can't possible take a code path leading to a
454 return NT_STATUS_LOGON_FAILURE
;
457 session_info
= talloc_zero(mem_ctx
, struct auth_session_info
);
459 return NT_STATUS_NO_MEMORY
;
462 session_info
->unix_token
= talloc_zero(session_info
, struct security_unix_token
);
463 if (!session_info
->unix_token
) {
464 TALLOC_FREE(session_info
);
465 return NT_STATUS_NO_MEMORY
;
468 session_info
->unix_token
->uid
= server_info
->utok
.uid
;
469 session_info
->unix_token
->gid
= server_info
->utok
.gid
;
471 session_info
->unix_info
= talloc_zero(session_info
, struct auth_user_info_unix
);
472 if (!session_info
->unix_info
) {
473 TALLOC_FREE(session_info
);
474 return NT_STATUS_NO_MEMORY
;
477 session_info
->unix_info
->unix_name
= talloc_strdup(session_info
, server_info
->unix_name
);
478 if (!session_info
->unix_info
->unix_name
) {
479 TALLOC_FREE(session_info
);
480 return NT_STATUS_NO_MEMORY
;
483 /* This is a potentially untrusted username for use in %U */
484 alpha_strcpy(tmp
, smb_username
, ". _-$", sizeof(tmp
));
485 session_info
->unix_info
->sanitized_username
=
486 talloc_strdup(session_info
->unix_info
, tmp
);
489 data_blob_free(&session_info
->session_key
);
490 session_info
->session_key
= data_blob_talloc(session_info
,
492 session_key
->length
);
493 if (!session_info
->session_key
.data
&& session_key
->length
) {
494 return NT_STATUS_NO_MEMORY
;
497 session_info
->session_key
= data_blob_talloc( session_info
, server_info
->session_key
.data
,
498 server_info
->session_key
.length
);
501 /* We need to populate session_info->info with the information found in server_info->info3 */
502 status
= make_user_info_SamBaseInfo(session_info
, "", &server_info
->info3
->base
,
503 server_info
->guest
== false,
504 &session_info
->info
);
505 if (!NT_STATUS_IS_OK(status
)) {
506 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
507 TALLOC_FREE(session_info
);
511 if (server_info
->security_token
) {
512 /* Just copy the token, it has already been finalised
513 * (nasty hack to support a cached guest/system session_info
516 session_info
->security_token
= dup_nt_token(session_info
, server_info
->security_token
);
517 if (!session_info
->security_token
) {
518 TALLOC_FREE(session_info
);
519 return NT_STATUS_NO_MEMORY
;
522 session_info
->unix_token
->ngroups
= server_info
->utok
.ngroups
;
523 if (server_info
->utok
.ngroups
!= 0) {
524 session_info
->unix_token
->groups
= (gid_t
*)talloc_memdup(
525 session_info
->unix_token
, server_info
->utok
.groups
,
526 sizeof(gid_t
)*session_info
->unix_token
->ngroups
);
528 session_info
->unix_token
->groups
= NULL
;
531 *session_info_out
= session_info
;
536 * If winbind is not around, we can not make much use of the SIDs the
537 * domain controller provided us with. Likewise if the user name was
538 * mapped to some local unix user.
541 if (((lp_server_role() == ROLE_DOMAIN_MEMBER
) && !winbind_ping()) ||
542 (server_info
->nss_token
)) {
543 char *found_username
= NULL
;
544 status
= create_token_from_username(session_info
,
545 server_info
->unix_name
,
547 &session_info
->unix_token
->uid
,
548 &session_info
->unix_token
->gid
,
550 &session_info
->security_token
);
551 if (NT_STATUS_IS_OK(status
)) {
552 session_info
->unix_info
->unix_name
= found_username
;
555 status
= create_local_nt_token_from_info3(session_info
,
559 &session_info
->security_token
);
562 if (!NT_STATUS_IS_OK(status
)) {
566 /* Convert the SIDs to gids. */
568 session_info
->unix_token
->ngroups
= 0;
569 session_info
->unix_token
->groups
= NULL
;
571 t
= session_info
->security_token
;
573 ids
= talloc_array(talloc_tos(), struct unixid
,
576 return NT_STATUS_NO_MEMORY
;
579 if (!sids_to_unixids(t
->sids
, t
->num_sids
, ids
)) {
581 return NT_STATUS_NO_MEMORY
;
584 for (i
=0; i
<t
->num_sids
; i
++) {
586 if (i
== 0 && ids
[i
].type
!= ID_TYPE_BOTH
) {
590 if (ids
[i
].type
!= ID_TYPE_GID
&&
591 ids
[i
].type
!= ID_TYPE_BOTH
) {
592 DEBUG(10, ("Could not convert SID %s to gid, "
594 sid_string_dbg(&t
->sids
[i
])));
597 if (!add_gid_to_array_unique(session_info
, ids
[i
].id
,
598 &session_info
->unix_token
->groups
,
599 &session_info
->unix_token
->ngroups
)) {
600 return NT_STATUS_NO_MEMORY
;
605 * Add the "Unix Group" SID for each gid to catch mapped groups
606 * and their Unix equivalent. This is to solve the backwards
607 * compatibility problem of 'valid users = +ntadmin' where
608 * ntadmin has been paired with "Domain Admins" in the group
609 * mapping table. Otherwise smb.conf would need to be changed
610 * to 'valid user = "Domain Admins"'. --jerry
612 * For consistency we also add the "Unix User" SID,
613 * so that the complete unix token is represented within
617 uid_to_unix_users_sid(session_info
->unix_token
->uid
, &tmp_sid
);
619 add_sid_to_array_unique(session_info
->security_token
, &tmp_sid
,
620 &session_info
->security_token
->sids
,
621 &session_info
->security_token
->num_sids
);
623 for ( i
=0; i
<session_info
->unix_token
->ngroups
; i
++ ) {
624 gid_to_unix_groups_sid(session_info
->unix_token
->groups
[i
], &tmp_sid
);
625 add_sid_to_array_unique(session_info
->security_token
, &tmp_sid
,
626 &session_info
->security_token
->sids
,
627 &session_info
->security_token
->num_sids
);
630 security_token_debug(DBGC_AUTH
, 10, session_info
->security_token
);
631 debug_unix_user_token(DBGC_AUTH
, 10,
632 session_info
->unix_token
->uid
,
633 session_info
->unix_token
->gid
,
634 session_info
->unix_token
->ngroups
,
635 session_info
->unix_token
->groups
);
637 status
= log_nt_token(session_info
->security_token
);
638 if (!NT_STATUS_IS_OK(status
)) {
642 *session_info_out
= session_info
;
646 /***************************************************************************
647 Make (and fill) a server_info struct from a 'struct passwd' by conversion
649 ***************************************************************************/
651 NTSTATUS
make_server_info_pw(TALLOC_CTX
*mem_ctx
,
652 const char *unix_username
,
653 const struct passwd
*pwd
,
654 struct auth_serversupplied_info
**server_info
)
657 TALLOC_CTX
*tmp_ctx
= NULL
;
658 struct auth_serversupplied_info
*result
;
660 tmp_ctx
= talloc_stackframe();
661 if (tmp_ctx
== NULL
) {
662 return NT_STATUS_NO_MEMORY
;
665 result
= make_server_info(tmp_ctx
);
666 if (result
== NULL
) {
667 status
= NT_STATUS_NO_MEMORY
;
671 status
= passwd_to_SamInfo3(result
,
675 if (!NT_STATUS_IS_OK(status
)) {
679 result
->unix_name
= talloc_strdup(result
, unix_username
);
680 if (result
->unix_name
== NULL
) {
681 status
= NT_STATUS_NO_MEMORY
;
685 result
->utok
.uid
= pwd
->pw_uid
;
686 result
->utok
.gid
= pwd
->pw_gid
;
688 *server_info
= talloc_steal(mem_ctx
, result
);
689 status
= NT_STATUS_OK
;
691 talloc_free(tmp_ctx
);
696 static NTSTATUS
get_system_info3(TALLOC_CTX
*mem_ctx
,
697 struct netr_SamInfo3
*info3
)
700 struct dom_sid
*system_sid
;
702 /* Set account name */
703 init_lsa_String(&info3
->base
.account_name
, "SYSTEM");
705 /* Set domain name */
706 init_lsa_StringLarge(&info3
->base
.logon_domain
, "NT AUTHORITY");
709 /* The SID set here will be overwirtten anyway, but try and make it SID_NT_SYSTEM anyway */
710 /* Domain sid is NT_AUTHORITY */
712 system_sid
= dom_sid_parse_talloc(mem_ctx
, SID_NT_SYSTEM
);
713 if (system_sid
== NULL
) {
714 return NT_STATUS_NO_MEMORY
;
717 status
= dom_sid_split_rid(mem_ctx
, system_sid
, &info3
->base
.domain_sid
,
719 TALLOC_FREE(system_sid
);
720 if (!NT_STATUS_IS_OK(status
)) {
724 /* Primary gid is the same */
725 info3
->base
.primary_gid
= info3
->base
.rid
;
730 static NTSTATUS
get_guest_info3(TALLOC_CTX
*mem_ctx
,
731 struct netr_SamInfo3
*info3
)
733 const char *guest_account
= lp_guest_account();
734 struct dom_sid domain_sid
;
738 pwd
= Get_Pwnam_alloc(mem_ctx
, guest_account
);
740 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
741 "account [%s]!\n", guest_account
));
742 return NT_STATUS_NO_SUCH_USER
;
745 /* Set account name */
746 tmp
= talloc_strdup(mem_ctx
, pwd
->pw_name
);
748 return NT_STATUS_NO_MEMORY
;
750 init_lsa_String(&info3
->base
.account_name
, tmp
);
752 /* Set domain name */
753 tmp
= talloc_strdup(mem_ctx
, get_global_sam_name());
755 return NT_STATUS_NO_MEMORY
;
757 init_lsa_StringLarge(&info3
->base
.logon_domain
, tmp
);
760 sid_copy(&domain_sid
, get_global_sam_sid());
762 info3
->base
.domain_sid
= dom_sid_dup(mem_ctx
, &domain_sid
);
763 if (info3
->base
.domain_sid
== NULL
) {
764 return NT_STATUS_NO_MEMORY
;
768 info3
->base
.rid
= DOMAIN_RID_GUEST
;
771 info3
->base
.primary_gid
= DOMAIN_RID_GUESTS
;
774 info3
->base
.user_flags
= NETLOGON_GUEST
;
780 /***************************************************************************
781 Make (and fill) a user_info struct for a guest login.
782 This *must* succeed for smbd to start. If there is no mapping entry for
783 the guest gid, then create one.
785 The resulting structure is a 'session_info' because
786 create_local_token() has already been called on it. This is quite
787 nasty, as the auth subsystem isn't expect this, but the behavior is
789 ***************************************************************************/
791 static NTSTATUS
make_new_session_info_guest(struct auth_session_info
**session_info
, struct auth_serversupplied_info
**server_info
)
793 static const char zeros
[16] = {0};
794 const char *guest_account
= lp_guest_account();
795 const char *domain
= lp_netbios_name();
796 struct netr_SamInfo3 info3
;
800 tmp_ctx
= talloc_stackframe();
801 if (tmp_ctx
== NULL
) {
802 return NT_STATUS_NO_MEMORY
;
807 status
= get_guest_info3(tmp_ctx
, &info3
);
808 if (!NT_STATUS_IS_OK(status
)) {
809 DEBUG(0, ("get_guest_info3 failed with %s\n",
814 status
= make_server_info_info3(tmp_ctx
,
819 if (!NT_STATUS_IS_OK(status
)) {
820 DEBUG(0, ("make_server_info_info3 failed with %s\n",
825 (*server_info
)->guest
= true;
827 /* This should not be done here (we should produce a server
828 * info, and later construct a session info from it), but for
829 * now this does not change the previous behavior */
830 status
= create_local_token(tmp_ctx
, *server_info
, NULL
,
831 (*server_info
)->info3
->base
.account_name
.string
,
833 if (!NT_STATUS_IS_OK(status
)) {
834 DEBUG(0, ("create_local_token failed: %s\n",
838 talloc_steal(NULL
, *session_info
);
839 talloc_steal(NULL
, *server_info
);
841 /* annoying, but the Guest really does have a session key, and it is
843 (*session_info
)->session_key
= data_blob(zeros
, sizeof(zeros
));
845 status
= NT_STATUS_OK
;
847 TALLOC_FREE(tmp_ctx
);
851 /***************************************************************************
852 Make (and fill) a auth_session_info struct for a system user login.
853 This *must* succeed for smbd to start.
854 ***************************************************************************/
856 static NTSTATUS
make_new_session_info_system(TALLOC_CTX
*mem_ctx
,
857 struct auth_session_info
**session_info
)
860 struct auth_serversupplied_info
*server_info
;
863 tmp_ctx
= talloc_stackframe();
864 if (tmp_ctx
== NULL
) {
865 return NT_STATUS_NO_MEMORY
;
868 server_info
= make_server_info(tmp_ctx
);
870 status
= NT_STATUS_NO_MEMORY
;
871 DEBUG(0, ("failed making server_info\n"));
875 server_info
->info3
= talloc_zero(server_info
, struct netr_SamInfo3
);
876 if (!server_info
->info3
) {
877 status
= NT_STATUS_NO_MEMORY
;
878 DEBUG(0, ("talloc failed setting info3\n"));
882 status
= get_system_info3(server_info
, server_info
->info3
);
883 if (!NT_STATUS_IS_OK(status
)) {
884 DEBUG(0, ("Failed creating system info3 with %s\n",
889 server_info
->utok
.uid
= sec_initial_uid();
890 server_info
->utok
.gid
= sec_initial_gid();
891 server_info
->unix_name
= talloc_asprintf(server_info
,
892 "NT AUTHORITY%cSYSTEM",
893 *lp_winbind_separator());
895 if (!server_info
->unix_name
) {
896 status
= NT_STATUS_NO_MEMORY
;
897 DEBUG(0, ("talloc_asprintf failed setting unix_name\n"));
901 server_info
->security_token
= talloc_zero(server_info
, struct security_token
);
902 if (!server_info
->security_token
) {
903 status
= NT_STATUS_NO_MEMORY
;
904 DEBUG(0, ("talloc failed setting security token\n"));
908 status
= add_sid_to_array_unique(server_info
->security_token
->sids
,
910 &server_info
->security_token
->sids
,
911 &server_info
->security_token
->num_sids
);
912 if (!NT_STATUS_IS_OK(status
)) {
916 /* SYSTEM has all privilages */
917 server_info
->security_token
->privilege_mask
= ~0;
919 /* Now turn the server_info into a session_info with the full token etc */
920 status
= create_local_token(mem_ctx
, server_info
, NULL
, "SYSTEM", session_info
);
921 talloc_free(server_info
);
923 if (!NT_STATUS_IS_OK(status
)) {
924 DEBUG(0, ("create_local_token failed: %s\n",
929 talloc_steal(mem_ctx
, *session_info
);
932 TALLOC_FREE(tmp_ctx
);
936 /****************************************************************************
937 Fake a auth_session_info just from a username (as a
938 session_info structure, with create_local_token() already called on
940 ****************************************************************************/
942 NTSTATUS
make_session_info_from_username(TALLOC_CTX
*mem_ctx
,
943 const char *username
,
945 struct auth_session_info
**session_info
)
949 struct auth_serversupplied_info
*result
;
952 tmp_ctx
= talloc_stackframe();
953 if (tmp_ctx
== NULL
) {
954 return NT_STATUS_NO_MEMORY
;
957 pwd
= Get_Pwnam_alloc(tmp_ctx
, username
);
959 status
= NT_STATUS_NO_SUCH_USER
;
963 status
= make_server_info_pw(tmp_ctx
, pwd
->pw_name
, pwd
, &result
);
964 if (!NT_STATUS_IS_OK(status
)) {
968 result
->nss_token
= true;
969 result
->guest
= is_guest
;
971 /* Now turn the server_info into a session_info with the full token etc */
972 status
= create_local_token(mem_ctx
,
979 talloc_free(tmp_ctx
);
984 /* This function MUST only used to create the cached server_info for
987 * This is a lossy conversion. Variables known to be lost so far
990 * - nss_token (not needed because the only read doesn't happen
991 * for the GUEST user, as this routine populates ->security_token
993 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
995 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
997 static struct auth_serversupplied_info
*copy_session_info_serverinfo_guest(TALLOC_CTX
*mem_ctx
,
998 const struct auth_session_info
*src
,
999 struct auth_serversupplied_info
*server_info
)
1001 struct auth_serversupplied_info
*dst
;
1003 dst
= make_server_info(mem_ctx
);
1008 /* This element must be provided to convert back to an auth_serversupplied_info */
1009 SMB_ASSERT(src
->unix_info
);
1012 dst
->system
= false;
1014 /* This element must be provided to convert back to an
1015 * auth_serversupplied_info. This needs to be from the
1016 * auth_session_info because the group values in particular
1017 * may change during create_local_token() processing */
1018 SMB_ASSERT(src
->unix_token
);
1019 dst
->utok
.uid
= src
->unix_token
->uid
;
1020 dst
->utok
.gid
= src
->unix_token
->gid
;
1021 dst
->utok
.ngroups
= src
->unix_token
->ngroups
;
1022 if (src
->unix_token
->ngroups
!= 0) {
1023 dst
->utok
.groups
= (gid_t
*)talloc_memdup(
1024 dst
, src
->unix_token
->groups
,
1025 sizeof(gid_t
)*dst
->utok
.ngroups
);
1027 dst
->utok
.groups
= NULL
;
1030 /* We must have a security_token as otherwise the lossy
1031 * conversion without nss_token would cause create_local_token
1032 * to take the wrong path */
1033 SMB_ASSERT(src
->security_token
);
1035 dst
->security_token
= dup_nt_token(dst
, src
->security_token
);
1036 if (!dst
->security_token
) {
1041 dst
->session_key
= data_blob_talloc( dst
, src
->session_key
.data
,
1042 src
->session_key
.length
);
1044 /* This is OK because this functions is only used for the
1045 * GUEST account, which has all-zero keys for both values */
1046 dst
->lm_session_key
= data_blob_talloc(dst
, src
->session_key
.data
,
1047 src
->session_key
.length
);
1049 dst
->info3
= copy_netr_SamInfo3(dst
, server_info
->info3
);
1055 dst
->unix_name
= talloc_strdup(dst
, src
->unix_info
->unix_name
);
1056 if (!dst
->unix_name
) {
1064 struct auth_session_info
*copy_session_info(TALLOC_CTX
*mem_ctx
,
1065 const struct auth_session_info
*src
)
1067 struct auth_session_info
*dst
;
1069 enum ndr_err_code ndr_err
;
1071 ndr_err
= ndr_push_struct_blob(
1072 &blob
, talloc_tos(), src
,
1073 (ndr_push_flags_fn_t
)ndr_push_auth_session_info
);
1074 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1075 DEBUG(0, ("copy_session_info(): ndr_push_auth_session_info failed: "
1076 "%s\n", ndr_errstr(ndr_err
)));
1080 dst
= talloc(mem_ctx
, struct auth_session_info
);
1082 DEBUG(0, ("talloc failed\n"));
1083 TALLOC_FREE(blob
.data
);
1087 ndr_err
= ndr_pull_struct_blob(
1089 (ndr_pull_flags_fn_t
)ndr_pull_auth_session_info
);
1090 TALLOC_FREE(blob
.data
);
1092 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1093 DEBUG(0, ("copy_session_info(): ndr_pull_auth_session_info failed: "
1094 "%s\n", ndr_errstr(ndr_err
)));
1103 * Set a new session key. Used in the rpc server where we have to override the
1104 * SMB level session key with SystemLibraryDTC
1107 bool session_info_set_session_key(struct auth_session_info
*info
,
1108 DATA_BLOB session_key
)
1110 TALLOC_FREE(info
->session_key
.data
);
1112 info
->session_key
= data_blob_talloc(
1113 info
, session_key
.data
, session_key
.length
);
1115 return (info
->session_key
.data
!= NULL
);
1118 static struct auth_session_info
*guest_info
= NULL
;
1120 static struct auth_serversupplied_info
*guest_server_info
= NULL
;
1122 bool init_guest_info(void)
1124 if (guest_info
!= NULL
)
1127 return NT_STATUS_IS_OK(make_new_session_info_guest(&guest_info
, &guest_server_info
));
1130 NTSTATUS
make_server_info_guest(TALLOC_CTX
*mem_ctx
,
1131 struct auth_serversupplied_info
**server_info
)
1133 /* This is trickier than it would appear to need to be because
1134 * we are trying to avoid certain costly operations when the
1135 * structure is converted to a 'auth_session_info' again in
1136 * create_local_token() */
1137 *server_info
= copy_session_info_serverinfo_guest(mem_ctx
, guest_info
, guest_server_info
);
1138 return (*server_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
1141 NTSTATUS
make_session_info_guest(TALLOC_CTX
*mem_ctx
,
1142 struct auth_session_info
**session_info
)
1144 *session_info
= copy_session_info(mem_ctx
, guest_info
);
1145 return (*session_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
1148 static struct auth_session_info
*system_info
= NULL
;
1150 NTSTATUS
init_system_session_info(void)
1152 if (system_info
!= NULL
)
1153 return NT_STATUS_OK
;
1155 return make_new_session_info_system(NULL
, &system_info
);
1158 NTSTATUS
make_session_info_system(TALLOC_CTX
*mem_ctx
,
1159 struct auth_session_info
**session_info
)
1161 if (system_info
== NULL
) return NT_STATUS_UNSUCCESSFUL
;
1162 *session_info
= copy_session_info(mem_ctx
, system_info
);
1163 return (*session_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
1166 const struct auth_session_info
*get_session_info_system(void)
1171 /***************************************************************************
1172 Purely internal function for make_server_info_info3
1173 ***************************************************************************/
1175 static NTSTATUS
check_account(TALLOC_CTX
*mem_ctx
, const char *domain
,
1176 const char *username
, char **found_username
,
1177 struct passwd
**pwd
,
1178 bool *username_was_mapped
)
1180 char *orig_dom_user
= NULL
;
1181 char *dom_user
= NULL
;
1182 char *lower_username
= NULL
;
1183 char *real_username
= NULL
;
1184 struct passwd
*passwd
;
1186 lower_username
= talloc_strdup(mem_ctx
, username
);
1187 if (!lower_username
) {
1188 return NT_STATUS_NO_MEMORY
;
1190 if (!strlower_m( lower_username
)) {
1191 return NT_STATUS_INVALID_PARAMETER
;
1194 orig_dom_user
= talloc_asprintf(mem_ctx
,
1197 *lp_winbind_separator(),
1199 if (!orig_dom_user
) {
1200 return NT_STATUS_NO_MEMORY
;
1203 /* Get the passwd struct. Try to create the account if necessary. */
1205 *username_was_mapped
= map_username(mem_ctx
, orig_dom_user
, &dom_user
);
1207 return NT_STATUS_NO_MEMORY
;
1210 passwd
= smb_getpwnam(mem_ctx
, dom_user
, &real_username
, true );
1212 DEBUG(3, ("Failed to find authenticated user %s via "
1213 "getpwnam(), denying access.\n", dom_user
));
1214 return NT_STATUS_NO_SUCH_USER
;
1217 if (!real_username
) {
1218 return NT_STATUS_NO_MEMORY
;
1223 /* This is pointless -- there is no support for differing
1224 unix and windows names. Make sure to always store the
1225 one we actually looked up and succeeded. Have I mentioned
1226 why I hate the 'winbind use default domain' parameter?
1229 *found_username
= talloc_strdup( mem_ctx
, real_username
);
1231 return NT_STATUS_OK
;
1234 /****************************************************************************
1235 Wrapper to allow the getpwnam() call to strip the domain name and
1236 try again in case a local UNIX user is already there. Also run through
1237 the username if we fallback to the username only.
1238 ****************************************************************************/
1240 struct passwd
*smb_getpwnam( TALLOC_CTX
*mem_ctx
, const char *domuser
,
1241 char **p_save_username
, bool create
)
1243 struct passwd
*pw
= NULL
;
1245 char *username
= NULL
;
1247 /* we only save a copy of the username it has been mangled
1248 by winbindd use default domain */
1249 *p_save_username
= NULL
;
1251 /* don't call map_username() here since it has to be done higher
1252 up the stack so we don't call it multiple times */
1254 username
= talloc_strdup(mem_ctx
, domuser
);
1259 p
= strchr_m( username
, *lp_winbind_separator() );
1261 /* code for a DOMAIN\user string */
1264 pw
= Get_Pwnam_alloc( mem_ctx
, domuser
);
1266 /* make sure we get the case of the username correct */
1267 /* work around 'winbind use default domain = yes' */
1269 if ( lp_winbind_use_default_domain() &&
1270 !strchr_m( pw
->pw_name
, *lp_winbind_separator() ) ) {
1273 /* split the domain and username into 2 strings */
1277 *p_save_username
= talloc_asprintf(mem_ctx
,
1280 *lp_winbind_separator(),
1282 if (!*p_save_username
) {
1287 *p_save_username
= talloc_strdup(mem_ctx
, pw
->pw_name
);
1294 /* setup for lookup of just the username */
1295 /* remember that p and username are overlapping memory */
1298 username
= talloc_strdup(mem_ctx
, p
);
1304 /* just lookup a plain username */
1306 pw
= Get_Pwnam_alloc(mem_ctx
, username
);
1308 /* Create local user if requested but only if winbindd
1309 is not running. We need to protect against cases
1310 where winbindd is failing and then prematurely
1311 creating users in /etc/passwd */
1313 if ( !pw
&& create
&& !winbind_ping() ) {
1314 /* Don't add a machine account. */
1315 if (username
[strlen(username
)-1] == '$')
1318 _smb_create_user(NULL
, username
, NULL
);
1319 pw
= Get_Pwnam_alloc(mem_ctx
, username
);
1322 /* one last check for a valid passwd struct */
1325 *p_save_username
= talloc_strdup(mem_ctx
, pw
->pw_name
);
1330 /***************************************************************************
1331 Make a server_info struct from the info3 returned by a domain logon
1332 ***************************************************************************/
1334 NTSTATUS
make_server_info_info3(TALLOC_CTX
*mem_ctx
,
1335 const char *sent_nt_username
,
1337 struct auth_serversupplied_info
**server_info
,
1338 const struct netr_SamInfo3
*info3
)
1340 static const char zeros
[16] = {0, };
1342 NTSTATUS nt_status
= NT_STATUS_OK
;
1343 char *found_username
= NULL
;
1344 const char *nt_domain
;
1345 const char *nt_username
;
1346 struct dom_sid user_sid
;
1347 struct dom_sid group_sid
;
1348 bool username_was_mapped
;
1350 struct auth_serversupplied_info
*result
;
1353 Here is where we should check the list of
1354 trusted domains, and verify that the SID
1358 if (!sid_compose(&user_sid
, info3
->base
.domain_sid
, info3
->base
.rid
)) {
1359 return NT_STATUS_INVALID_PARAMETER
;
1362 if (!sid_compose(&group_sid
, info3
->base
.domain_sid
,
1363 info3
->base
.primary_gid
)) {
1364 return NT_STATUS_INVALID_PARAMETER
;
1367 nt_username
= talloc_strdup(mem_ctx
, info3
->base
.account_name
.string
);
1369 /* If the server didn't give us one, just use the one we sent
1371 nt_username
= sent_nt_username
;
1374 nt_domain
= talloc_strdup(mem_ctx
, info3
->base
.logon_domain
.string
);
1376 /* If the server didn't give us one, just use the one we sent
1381 /* If getpwnam() fails try the add user script (2.2.x behavior).
1383 We use the _unmapped_ username here in an attempt to provide
1384 consistent username mapping behavior between kerberos and NTLM[SSP]
1385 authentication in domain mode security. I.E. Username mapping
1386 should be applied to the fully qualified username
1387 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1388 called map_username() unnecessarily in make_user_info_map() but
1389 that is how the current code is designed. Making the change here
1390 is the least disruptive place. -- jerry */
1392 /* this call will try to create the user if necessary */
1394 nt_status
= check_account(mem_ctx
, nt_domain
, sent_nt_username
,
1395 &found_username
, &pwd
,
1396 &username_was_mapped
);
1398 if (!NT_STATUS_IS_OK(nt_status
)) {
1402 result
= make_server_info(NULL
);
1403 if (result
== NULL
) {
1404 DEBUG(4, ("make_server_info failed!\n"));
1405 return NT_STATUS_NO_MEMORY
;
1408 result
->unix_name
= talloc_strdup(result
, found_username
);
1410 /* copy in the info3 */
1411 result
->info3
= copy_netr_SamInfo3(result
, info3
);
1412 if (result
->info3
== NULL
) {
1413 TALLOC_FREE(result
);
1414 return NT_STATUS_NO_MEMORY
;
1417 /* Fill in the unix info we found on the way */
1419 result
->utok
.uid
= pwd
->pw_uid
;
1420 result
->utok
.gid
= pwd
->pw_gid
;
1422 /* ensure we are never given NULL session keys */
1424 if (memcmp(info3
->base
.key
.key
, zeros
, sizeof(zeros
)) == 0) {
1425 result
->session_key
= data_blob_null
;
1427 result
->session_key
= data_blob_talloc(
1428 result
, info3
->base
.key
.key
,
1429 sizeof(info3
->base
.key
.key
));
1432 if (memcmp(info3
->base
.LMSessKey
.key
, zeros
, 8) == 0) {
1433 result
->lm_session_key
= data_blob_null
;
1435 result
->lm_session_key
= data_blob_talloc(
1436 result
, info3
->base
.LMSessKey
.key
,
1437 sizeof(info3
->base
.LMSessKey
.key
));
1440 result
->nss_token
|= username_was_mapped
;
1442 result
->guest
= (info3
->base
.user_flags
& NETLOGON_GUEST
);
1444 *server_info
= result
;
1446 return NT_STATUS_OK
;
1449 /*****************************************************************************
1450 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1451 ******************************************************************************/
1453 NTSTATUS
make_server_info_wbcAuthUserInfo(TALLOC_CTX
*mem_ctx
,
1454 const char *sent_nt_username
,
1456 const struct wbcAuthUserInfo
*info
,
1457 struct auth_serversupplied_info
**server_info
)
1459 struct netr_SamInfo3
*info3
;
1461 info3
= wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx
, info
);
1463 return NT_STATUS_NO_MEMORY
;
1466 return make_server_info_info3(mem_ctx
,
1467 sent_nt_username
, domain
,
1468 server_info
, info3
);
1472 * Verify whether or not given domain is trusted.
1474 * @param domain_name name of the domain to be verified
1475 * @return true if domain is one of the trusted ones or
1476 * false if otherwise
1479 bool is_trusted_domain(const char* dom_name
)
1481 struct dom_sid trustdom_sid
;
1484 /* no trusted domains for a standalone server */
1486 if ( lp_server_role() == ROLE_STANDALONE
)
1489 if (dom_name
== NULL
|| dom_name
[0] == '\0') {
1493 if (strequal(dom_name
, get_global_sam_name())) {
1497 /* if we are a DC, then check for a direct trust relationships */
1501 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1502 "[%s]\n", dom_name
));
1503 ret
= pdb_get_trusteddom_pw(dom_name
, NULL
, NULL
, NULL
);
1511 /* If winbind is around, ask it */
1513 result
= wb_is_trusted_domain(dom_name
);
1515 if (result
== WBC_ERR_SUCCESS
) {
1519 if (result
== WBC_ERR_DOMAIN_NOT_FOUND
) {
1520 /* winbind could not find the domain */
1524 /* The only other possible result is that winbind is not up
1525 and running. We need to update the trustdom_cache
1528 update_trustdom_cache();
1531 /* now the trustdom cache should be available a DC could still
1532 * have a transitive trust so fall back to the cache of trusted
1533 * domains (like a domain member would use */
1535 if ( trustdom_cache_fetch(dom_name
, &trustdom_sid
) ) {
1545 on a logon error possibly map the error to success if "map to guest"
1548 NTSTATUS
do_map_to_guest_server_info(TALLOC_CTX
*mem_ctx
,
1552 struct auth_serversupplied_info
**server_info
)
1554 user
= user
? user
: "";
1555 domain
= domain
? domain
: "";
1557 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
1558 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER
) ||
1559 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
)) {
1560 DEBUG(3,("No such user %s [%s] - using guest account\n",
1562 return make_server_info_guest(mem_ctx
, server_info
);
1564 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1565 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
) {
1566 DEBUG(3,("Registered username %s for guest access\n",
1568 return make_server_info_guest(mem_ctx
, server_info
);
1576 Extract session key from a session info and return it in a blob
1577 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
1579 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
1580 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
1582 Note that returned session_key is referencing the original key, it is supposed to be
1583 short-lived. If original session_info->session_key is gone, the reference will be broken.
1585 NTSTATUS
session_extract_session_key(const struct auth_session_info
*session_info
, DATA_BLOB
*session_key
, enum session_key_use_intent intent
)
1588 if (session_key
== NULL
|| session_info
== NULL
) {
1589 return NT_STATUS_INVALID_PARAMETER
;
1592 if (session_info
->session_key
.length
== 0) {
1593 return NT_STATUS_NO_USER_SESSION_KEY
;
1596 *session_key
= session_info
->session_key
;
1597 if (intent
== KEY_USE_16BYTES
) {
1598 session_key
->length
= MIN(session_info
->session_key
.length
, 16);
1600 return NT_STATUS_OK
;