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"
36 #define DBGC_CLASS DBGC_AUTH
38 /****************************************************************************
39 Create a UNIX user on demand.
40 ****************************************************************************/
42 static int _smb_create_user(const char *domain
, const char *unix_username
, const char *homedir
)
44 TALLOC_CTX
*ctx
= talloc_tos();
48 add_script
= talloc_strdup(ctx
, lp_adduser_script());
49 if (!add_script
|| !*add_script
) {
52 add_script
= talloc_all_string_sub(ctx
,
60 add_script
= talloc_all_string_sub(ctx
,
69 add_script
= talloc_all_string_sub(ctx
,
77 ret
= smbrun(add_script
,NULL
);
80 ("smb_create_user: Running the command `%s' gave %d\n",
85 /****************************************************************************
86 Create an auth_usersupplied_data structure after appropriate mapping.
87 ****************************************************************************/
89 NTSTATUS
make_user_info_map(struct auth_usersupplied_info
**user_info
,
91 const char *client_domain
,
92 const char *workstation_name
,
93 const struct tsocket_address
*remote_address
,
96 const struct samr_Password
*lm_interactive_pwd
,
97 const struct samr_Password
*nt_interactive_pwd
,
98 const char *plaintext
,
99 enum auth_password_state password_state
)
104 char *internal_username
= NULL
;
106 was_mapped
= map_username(talloc_tos(), smb_name
, &internal_username
);
107 if (!internal_username
) {
108 return NT_STATUS_NO_MEMORY
;
111 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
112 client_domain
, smb_name
, workstation_name
));
114 domain
= client_domain
;
116 /* If you connect to a Windows domain member using a bogus domain name,
117 * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if
118 * the Windows box is a DC the name will become DOMAIN\user and be
119 * authenticated against AD, if the Windows box is a member server but
120 * not a DC the name will become WORKSTATION\user. A standalone
121 * non-domain member box will also map to WORKSTATION\user.
122 * This also deals with the client passing in a "" domain */
124 if (!is_trusted_domain(domain
) &&
125 !strequal(domain
, my_sam_name()))
127 if (lp_map_untrusted_to_domain())
128 domain
= my_sam_name();
130 domain
= get_global_sam_name();
131 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
132 "workstation [%s]\n",
133 client_domain
, domain
, smb_name
, workstation_name
));
136 /* We know that the given domain is trusted (and we are allowing them),
137 * it is our global SAM name, or for legacy behavior it is our
138 * primary domain name */
140 result
= make_user_info(user_info
, smb_name
, internal_username
,
141 client_domain
, domain
, workstation_name
,
142 remote_address
, lm_pwd
, nt_pwd
,
143 lm_interactive_pwd
, nt_interactive_pwd
,
144 plaintext
, password_state
);
145 if (NT_STATUS_IS_OK(result
)) {
146 /* We have tried mapping */
147 (*user_info
)->mapped_state
= True
;
148 /* did we actually map the user to a different name? */
149 (*user_info
)->was_mapped
= was_mapped
;
154 /****************************************************************************
155 Create an auth_usersupplied_data, making the DATA_BLOBs here.
156 Decrypt and encrypt the passwords.
157 ****************************************************************************/
159 bool make_user_info_netlogon_network(struct auth_usersupplied_info
**user_info
,
160 const char *smb_name
,
161 const char *client_domain
,
162 const char *workstation_name
,
163 const struct tsocket_address
*remote_address
,
164 uint32 logon_parameters
,
165 const uchar
*lm_network_pwd
,
167 const uchar
*nt_network_pwd
,
172 DATA_BLOB lm_blob
= data_blob(lm_network_pwd
, lm_pwd_len
);
173 DATA_BLOB nt_blob
= data_blob(nt_network_pwd
, nt_pwd_len
);
175 status
= make_user_info_map(user_info
,
176 smb_name
, client_domain
,
179 lm_pwd_len
? &lm_blob
: NULL
,
180 nt_pwd_len
? &nt_blob
: NULL
,
182 AUTH_PASSWORD_RESPONSE
);
184 if (NT_STATUS_IS_OK(status
)) {
185 (*user_info
)->logon_parameters
= logon_parameters
;
187 ret
= NT_STATUS_IS_OK(status
) ? True
: False
;
189 data_blob_free(&lm_blob
);
190 data_blob_free(&nt_blob
);
194 /****************************************************************************
195 Create an auth_usersupplied_data, making the DATA_BLOBs here.
196 Decrypt and encrypt the passwords.
197 ****************************************************************************/
199 bool make_user_info_netlogon_interactive(struct auth_usersupplied_info
**user_info
,
200 const char *smb_name
,
201 const char *client_domain
,
202 const char *workstation_name
,
203 const struct tsocket_address
*remote_address
,
204 uint32 logon_parameters
,
206 const uchar lm_interactive_pwd
[16],
207 const uchar nt_interactive_pwd
[16],
208 const uchar
*dc_sess_key
)
210 struct samr_Password lm_pwd
;
211 struct samr_Password nt_pwd
;
212 unsigned char local_lm_response
[24];
213 unsigned char local_nt_response
[24];
214 unsigned char key
[16];
216 memcpy(key
, dc_sess_key
, 16);
218 if (lm_interactive_pwd
)
219 memcpy(lm_pwd
.hash
, lm_interactive_pwd
, sizeof(lm_pwd
.hash
));
221 if (nt_interactive_pwd
)
222 memcpy(nt_pwd
.hash
, nt_interactive_pwd
, sizeof(nt_pwd
.hash
));
224 #ifdef DEBUG_PASSWORD
226 dump_data(100, key
, sizeof(key
));
228 DEBUG(100,("lm owf password:"));
229 dump_data(100, lm_pwd
.hash
, sizeof(lm_pwd
.hash
));
231 DEBUG(100,("nt owf password:"));
232 dump_data(100, nt_pwd
.hash
, sizeof(nt_pwd
.hash
));
235 if (lm_interactive_pwd
)
236 arcfour_crypt(lm_pwd
.hash
, key
, sizeof(lm_pwd
.hash
));
238 if (nt_interactive_pwd
)
239 arcfour_crypt(nt_pwd
.hash
, key
, sizeof(nt_pwd
.hash
));
241 #ifdef DEBUG_PASSWORD
242 DEBUG(100,("decrypt of lm owf password:"));
243 dump_data(100, lm_pwd
.hash
, sizeof(lm_pwd
));
245 DEBUG(100,("decrypt of nt owf password:"));
246 dump_data(100, nt_pwd
.hash
, sizeof(nt_pwd
));
249 if (lm_interactive_pwd
)
250 SMBOWFencrypt(lm_pwd
.hash
, chal
,
253 if (nt_interactive_pwd
)
254 SMBOWFencrypt(nt_pwd
.hash
, chal
,
257 /* Password info paranoia */
263 DATA_BLOB local_lm_blob
;
264 DATA_BLOB local_nt_blob
;
266 if (lm_interactive_pwd
) {
267 local_lm_blob
= data_blob(local_lm_response
,
268 sizeof(local_lm_response
));
271 if (nt_interactive_pwd
) {
272 local_nt_blob
= data_blob(local_nt_response
,
273 sizeof(local_nt_response
));
276 nt_status
= make_user_info_map(
278 smb_name
, client_domain
, workstation_name
,
280 lm_interactive_pwd
? &local_lm_blob
: NULL
,
281 nt_interactive_pwd
? &local_nt_blob
: NULL
,
282 lm_interactive_pwd
? &lm_pwd
: NULL
,
283 nt_interactive_pwd
? &nt_pwd
: NULL
,
284 NULL
, AUTH_PASSWORD_HASH
);
286 if (NT_STATUS_IS_OK(nt_status
)) {
287 (*user_info
)->logon_parameters
= logon_parameters
;
290 ret
= NT_STATUS_IS_OK(nt_status
) ? True
: False
;
291 data_blob_free(&local_lm_blob
);
292 data_blob_free(&local_nt_blob
);
298 /****************************************************************************
299 Create an auth_usersupplied_data structure
300 ****************************************************************************/
302 bool make_user_info_for_reply(struct auth_usersupplied_info
**user_info
,
303 const char *smb_name
,
304 const char *client_domain
,
305 const struct tsocket_address
*remote_address
,
307 DATA_BLOB plaintext_password
)
310 DATA_BLOB local_lm_blob
;
311 DATA_BLOB local_nt_blob
;
312 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
313 char *plaintext_password_string
;
315 * Not encrypted - do so.
318 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
320 if (plaintext_password
.data
&& plaintext_password
.length
) {
321 unsigned char local_lm_response
[24];
323 #ifdef DEBUG_PASSWORD
324 DEBUG(10,("Unencrypted password (len %d):\n",
325 (int)plaintext_password
.length
));
326 dump_data(100, plaintext_password
.data
,
327 plaintext_password
.length
);
330 SMBencrypt( (const char *)plaintext_password
.data
,
331 (const uchar
*)chal
, local_lm_response
);
332 local_lm_blob
= data_blob(local_lm_response
, 24);
334 /* We can't do an NT hash here, as the password needs to be
336 local_nt_blob
= data_blob_null
;
338 local_lm_blob
= data_blob_null
;
339 local_nt_blob
= data_blob_null
;
342 plaintext_password_string
= talloc_strndup(talloc_tos(),
343 (const char *)plaintext_password
.data
,
344 plaintext_password
.length
);
345 if (!plaintext_password_string
) {
349 ret
= make_user_info_map(
350 user_info
, smb_name
, client_domain
,
351 get_remote_machine_name(),
353 local_lm_blob
.data
? &local_lm_blob
: NULL
,
354 local_nt_blob
.data
? &local_nt_blob
: NULL
,
356 plaintext_password_string
,
357 AUTH_PASSWORD_PLAIN
);
359 if (plaintext_password_string
) {
360 memset(plaintext_password_string
, '\0', strlen(plaintext_password_string
));
361 talloc_free(plaintext_password_string
);
364 data_blob_free(&local_lm_blob
);
365 return NT_STATUS_IS_OK(ret
) ? True
: False
;
368 /****************************************************************************
369 Create an auth_usersupplied_data structure
370 ****************************************************************************/
372 NTSTATUS
make_user_info_for_reply_enc(struct auth_usersupplied_info
**user_info
,
373 const char *smb_name
,
374 const char *client_domain
,
375 const struct tsocket_address
*remote_address
,
376 DATA_BLOB lm_resp
, DATA_BLOB nt_resp
)
378 return make_user_info_map(user_info
, smb_name
,
380 get_remote_machine_name(),
382 lm_resp
.data
&& (lm_resp
.length
> 0) ? &lm_resp
: NULL
,
383 nt_resp
.data
&& (nt_resp
.length
> 0) ? &nt_resp
: NULL
,
385 AUTH_PASSWORD_RESPONSE
);
388 /****************************************************************************
389 Create a guest user_info blob, for anonymous authenticaion.
390 ****************************************************************************/
392 bool make_user_info_guest(const struct tsocket_address
*remote_address
,
393 struct auth_usersupplied_info
**user_info
)
397 nt_status
= make_user_info(user_info
,
405 AUTH_PASSWORD_RESPONSE
);
407 return NT_STATUS_IS_OK(nt_status
) ? True
: False
;
410 static NTSTATUS
log_nt_token(struct security_token
*token
)
412 TALLOC_CTX
*frame
= talloc_stackframe();
417 if ((lp_log_nt_token_command() == NULL
) ||
418 (strlen(lp_log_nt_token_command()) == 0)) {
423 group_sidstr
= talloc_strdup(frame
, "");
424 for (i
=1; i
<token
->num_sids
; i
++) {
425 group_sidstr
= talloc_asprintf(
426 frame
, "%s %s", group_sidstr
,
427 sid_string_talloc(frame
, &token
->sids
[i
]));
430 command
= talloc_string_sub(
431 frame
, lp_log_nt_token_command(),
432 "%s", sid_string_talloc(frame
, &token
->sids
[0]));
433 command
= talloc_string_sub(frame
, command
, "%t", group_sidstr
);
435 if (command
== NULL
) {
437 return NT_STATUS_NO_MEMORY
;
440 DEBUG(8, ("running command: [%s]\n", command
));
441 if (smbrun(command
, NULL
) != 0) {
442 DEBUG(0, ("Could not log NT token\n"));
444 return NT_STATUS_ACCESS_DENIED
;
452 * Create the token to use from server_info->info3 and
453 * server_info->sids (the info3/sam groups). Find the unix gids.
456 NTSTATUS
create_local_token(TALLOC_CTX
*mem_ctx
,
457 const struct auth_serversupplied_info
*server_info
,
458 DATA_BLOB
*session_key
,
459 struct auth3_session_info
**session_info_out
)
461 struct security_token
*t
;
464 struct dom_sid tmp_sid
;
465 struct auth3_session_info
*session_info
;
466 struct wbcUnixId
*ids
;
468 /* Ensure we can't possible take a code path leading to a
471 return NT_STATUS_LOGON_FAILURE
;
474 session_info
= make_auth3_session_info(mem_ctx
);
476 return NT_STATUS_NO_MEMORY
;
479 session_info
->unix_token
= talloc_zero(session_info
, struct security_unix_token
);
480 if (!session_info
->unix_token
) {
481 TALLOC_FREE(session_info
);
482 return NT_STATUS_NO_MEMORY
;
485 session_info
->unix_token
->uid
= server_info
->utok
.uid
;
486 session_info
->unix_token
->gid
= server_info
->utok
.gid
;
488 session_info
->info3
= copy_netr_SamInfo3(session_info
, server_info
->info3
);
489 if (!session_info
->info3
) {
490 TALLOC_FREE(session_info
);
491 return NT_STATUS_NO_MEMORY
;
494 session_info
->unix_info
= talloc_zero(session_info
, struct auth_user_info_unix
);
495 if (!session_info
->unix_info
) {
496 TALLOC_FREE(session_info
);
497 return NT_STATUS_NO_MEMORY
;
500 session_info
->unix_info
->unix_name
= talloc_strdup(session_info
, server_info
->unix_name
);
501 if (!session_info
->unix_info
->unix_name
) {
502 TALLOC_FREE(session_info
);
503 return NT_STATUS_NO_MEMORY
;
506 session_info
->unix_info
->sanitized_username
= talloc_strdup(session_info
, server_info
->sanitized_username
);
507 if (!session_info
->unix_info
->sanitized_username
) {
508 TALLOC_FREE(session_info
);
509 return NT_STATUS_NO_MEMORY
;
512 session_info
->unix_info
->guest
= server_info
->guest
;
513 session_info
->unix_info
->system
= server_info
->system
;
516 data_blob_free(&session_info
->session_key
);
517 session_info
->session_key
= data_blob_talloc(session_info
,
519 session_key
->length
);
520 if (!session_info
->session_key
.data
&& session_key
->length
) {
521 return NT_STATUS_NO_MEMORY
;
524 session_info
->session_key
= data_blob_talloc( session_info
, server_info
->session_key
.data
,
525 server_info
->session_key
.length
);
528 if (session_info
->security_token
) {
529 /* Just copy the token, it has already been finalised
530 * (nasty hack to support a cached guest session_info,
531 * and a possible strategy for auth_samba4 to pass in
532 * a finalised session) */
534 session_info
->security_token
= dup_nt_token(session_info
, server_info
->security_token
);
535 if (!session_info
->security_token
) {
536 TALLOC_FREE(session_info
);
537 return NT_STATUS_NO_MEMORY
;
540 session_info
->unix_token
->ngroups
= server_info
->utok
.ngroups
;
541 if (server_info
->utok
.ngroups
!= 0) {
542 session_info
->unix_token
->groups
= (gid_t
*)talloc_memdup(
543 session_info
->unix_token
, server_info
->utok
.groups
,
544 sizeof(gid_t
)*session_info
->unix_token
->ngroups
);
546 session_info
->unix_token
->groups
= NULL
;
549 *session_info_out
= session_info
;
554 * If winbind is not around, we can not make much use of the SIDs the
555 * domain controller provided us with. Likewise if the user name was
556 * mapped to some local unix user.
559 if (((lp_server_role() == ROLE_DOMAIN_MEMBER
) && !winbind_ping()) ||
560 (server_info
->nss_token
)) {
561 status
= create_token_from_username(session_info
,
562 server_info
->unix_name
,
564 &session_info
->unix_token
->uid
,
565 &session_info
->unix_token
->gid
,
566 &session_info
->unix_info
->unix_name
,
567 &session_info
->security_token
);
570 status
= create_local_nt_token_from_info3(session_info
,
574 &session_info
->security_token
);
577 if (!NT_STATUS_IS_OK(status
)) {
581 /* Convert the SIDs to gids. */
583 session_info
->unix_token
->ngroups
= 0;
584 session_info
->unix_token
->groups
= NULL
;
586 t
= session_info
->security_token
;
588 ids
= talloc_array(talloc_tos(), struct wbcUnixId
,
591 return NT_STATUS_NO_MEMORY
;
594 if (!sids_to_unix_ids(t
->sids
, t
->num_sids
, ids
)) {
596 return NT_STATUS_NO_MEMORY
;
599 /* Start at index 1, where the groups start. */
601 for (i
=1; i
<t
->num_sids
; i
++) {
603 if (ids
[i
].type
!= WBC_ID_TYPE_GID
) {
604 DEBUG(10, ("Could not convert SID %s to gid, "
606 sid_string_dbg(&t
->sids
[i
])));
609 if (!add_gid_to_array_unique(session_info
, ids
[i
].id
.gid
,
610 &session_info
->unix_token
->groups
,
611 &session_info
->unix_token
->ngroups
)) {
612 return NT_STATUS_NO_MEMORY
;
617 * Add the "Unix Group" SID for each gid to catch mapped groups
618 * and their Unix equivalent. This is to solve the backwards
619 * compatibility problem of 'valid users = +ntadmin' where
620 * ntadmin has been paired with "Domain Admins" in the group
621 * mapping table. Otherwise smb.conf would need to be changed
622 * to 'valid user = "Domain Admins"'. --jerry
624 * For consistency we also add the "Unix User" SID,
625 * so that the complete unix token is represented within
629 uid_to_unix_users_sid(session_info
->unix_token
->uid
, &tmp_sid
);
631 add_sid_to_array_unique(session_info
->security_token
, &tmp_sid
,
632 &session_info
->security_token
->sids
,
633 &session_info
->security_token
->num_sids
);
635 for ( i
=0; i
<session_info
->unix_token
->ngroups
; i
++ ) {
636 gid_to_unix_groups_sid(session_info
->unix_token
->groups
[i
], &tmp_sid
);
637 add_sid_to_array_unique(session_info
->security_token
, &tmp_sid
,
638 &session_info
->security_token
->sids
,
639 &session_info
->security_token
->num_sids
);
642 security_token_debug(DBGC_AUTH
, 10, session_info
->security_token
);
643 debug_unix_user_token(DBGC_AUTH
, 10,
644 session_info
->unix_token
->uid
,
645 session_info
->unix_token
->gid
,
646 session_info
->unix_token
->ngroups
,
647 session_info
->unix_token
->groups
);
649 status
= log_nt_token(session_info
->security_token
);
650 if (!NT_STATUS_IS_OK(status
)) {
654 *session_info_out
= session_info
;
658 /***************************************************************************
659 Make (and fill) a server_info struct from a 'struct passwd' by conversion
661 ***************************************************************************/
663 NTSTATUS
make_server_info_pw(struct auth_serversupplied_info
**server_info
,
668 struct samu
*sampass
= NULL
;
669 char *qualified_name
= NULL
;
670 TALLOC_CTX
*mem_ctx
= NULL
;
671 struct dom_sid u_sid
;
672 enum lsa_SidType type
;
673 struct auth_serversupplied_info
*result
;
676 * The SID returned in server_info->sam_account is based
677 * on our SAM sid even though for a pure UNIX account this should
678 * not be the case as it doesn't really exist in the SAM db.
679 * This causes lookups on "[in]valid users" to fail as they
680 * will lookup this name as a "Unix User" SID to check against
681 * the user token. Fix this by adding the "Unix User"\unix_username
682 * SID to the sid array. The correct fix should probably be
683 * changing the server_info->sam_account user SID to be a
684 * S-1-22 Unix SID, but this might break old configs where
685 * plaintext passwords were used with no SAM backend.
688 mem_ctx
= talloc_init("make_server_info_pw_tmp");
690 return NT_STATUS_NO_MEMORY
;
693 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
694 unix_users_domain_name(),
696 if (!qualified_name
) {
697 TALLOC_FREE(mem_ctx
);
698 return NT_STATUS_NO_MEMORY
;
701 if (!lookup_name(mem_ctx
, qualified_name
, LOOKUP_NAME_ALL
,
704 TALLOC_FREE(mem_ctx
);
705 return NT_STATUS_NO_SUCH_USER
;
708 TALLOC_FREE(mem_ctx
);
710 if (type
!= SID_NAME_USER
) {
711 return NT_STATUS_NO_SUCH_USER
;
714 if ( !(sampass
= samu_new( NULL
)) ) {
715 return NT_STATUS_NO_MEMORY
;
718 status
= samu_set_unix( sampass
, pwd
);
719 if (!NT_STATUS_IS_OK(status
)) {
723 /* In pathological cases the above call can set the account
724 * name to the DOMAIN\username form. Reset the account name
725 * using unix_username */
726 pdb_set_username(sampass
, unix_username
, PDB_SET
);
728 /* set the user sid to be the calculated u_sid */
729 pdb_set_user_sid(sampass
, &u_sid
, PDB_SET
);
731 result
= make_server_info(NULL
);
732 if (result
== NULL
) {
733 TALLOC_FREE(sampass
);
734 return NT_STATUS_NO_MEMORY
;
737 status
= samu_to_SamInfo3(result
, sampass
, lp_netbios_name(),
738 &result
->info3
, &result
->extra
);
739 TALLOC_FREE(sampass
);
740 if (!NT_STATUS_IS_OK(status
)) {
741 DEBUG(10, ("Failed to convert samu to info3: %s\n",
747 result
->unix_name
= talloc_strdup(result
, unix_username
);
748 result
->sanitized_username
= sanitize_username(result
, unix_username
);
750 if ((result
->unix_name
== NULL
)
751 || (result
->sanitized_username
== NULL
)) {
753 return NT_STATUS_NO_MEMORY
;
756 result
->utok
.uid
= pwd
->pw_uid
;
757 result
->utok
.gid
= pwd
->pw_gid
;
759 *server_info
= result
;
764 static NTSTATUS
get_guest_info3(TALLOC_CTX
*mem_ctx
,
765 struct netr_SamInfo3
*info3
)
767 const char *guest_account
= lp_guestaccount();
768 struct dom_sid domain_sid
;
772 pwd
= Get_Pwnam_alloc(mem_ctx
, guest_account
);
774 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
775 "account [%s]!\n", guest_account
));
776 return NT_STATUS_NO_SUCH_USER
;
779 /* Set acount name */
780 tmp
= talloc_strdup(mem_ctx
, pwd
->pw_name
);
782 return NT_STATUS_NO_MEMORY
;
784 init_lsa_String(&info3
->base
.account_name
, tmp
);
786 /* Set domain name */
787 tmp
= talloc_strdup(mem_ctx
, get_global_sam_name());
789 return NT_STATUS_NO_MEMORY
;
791 init_lsa_StringLarge(&info3
->base
.domain
, tmp
);
794 sid_copy(&domain_sid
, get_global_sam_sid());
796 info3
->base
.domain_sid
= dom_sid_dup(mem_ctx
, &domain_sid
);
797 if (info3
->base
.domain_sid
== NULL
) {
798 return NT_STATUS_NO_MEMORY
;
802 info3
->base
.rid
= DOMAIN_RID_GUEST
;
805 info3
->base
.primary_gid
= BUILTIN_RID_GUESTS
;
811 /***************************************************************************
812 Make (and fill) a user_info struct for a guest login.
813 This *must* succeed for smbd to start. If there is no mapping entry for
814 the guest gid, then create one.
816 The resulting structure is a 'session_info' because
817 create_local_token() has already been called on it. This is quite
818 nasty, as the auth subsystem isn't expect this, but the behaviour is
820 ***************************************************************************/
822 static NTSTATUS
make_new_session_info_guest(struct auth3_session_info
**session_info
, struct auth_serversupplied_info
**server_info
)
824 static const char zeros
[16] = {0};
825 const char *guest_account
= lp_guestaccount();
826 const char *domain
= lp_netbios_name();
827 struct netr_SamInfo3 info3
;
832 tmp_ctx
= talloc_stackframe();
833 if (tmp_ctx
== NULL
) {
834 return NT_STATUS_NO_MEMORY
;
839 status
= get_guest_info3(tmp_ctx
, &info3
);
840 if (!NT_STATUS_IS_OK(status
)) {
841 DEBUG(0, ("get_guest_info3 failed with %s\n",
846 status
= make_server_info_info3(tmp_ctx
,
851 if (!NT_STATUS_IS_OK(status
)) {
852 DEBUG(0, ("make_server_info_info3 failed with %s\n",
857 (*server_info
)->guest
= True
;
859 /* This should not be done here (we should produce a server
860 * info, and later construct a session info from it), but for
861 * now this does not change the previous behaviours */
862 status
= create_local_token(tmp_ctx
, *server_info
, NULL
, session_info
);
863 if (!NT_STATUS_IS_OK(status
)) {
864 DEBUG(0, ("create_local_token failed: %s\n",
868 talloc_steal(NULL
, *session_info
);
869 talloc_steal(NULL
, *server_info
);
871 /* annoying, but the Guest really does have a session key, and it is
873 (*session_info
)->session_key
= data_blob(zeros
, sizeof(zeros
));
875 alpha_strcpy(tmp
, (*session_info
)->info3
->base
.account_name
.string
,
876 ". _-$", sizeof(tmp
));
877 (*session_info
)->unix_info
->sanitized_username
= talloc_strdup(*session_info
, tmp
);
879 status
= NT_STATUS_OK
;
881 TALLOC_FREE(tmp_ctx
);
885 /***************************************************************************
886 Make (and fill) a auth_session_info struct for a system user login.
887 This *must* succeed for smbd to start.
888 ***************************************************************************/
890 static NTSTATUS
make_new_session_info_system(TALLOC_CTX
*mem_ctx
,
891 struct auth3_session_info
**session_info
)
896 pwd
= getpwuid_alloc(mem_ctx
, sec_initial_uid());
898 return NT_STATUS_NO_SUCH_USER
;
901 status
= make_session_info_from_username(mem_ctx
,
906 if (!NT_STATUS_IS_OK(status
)) {
910 (*session_info
)->unix_info
->system
= true;
912 status
= add_sid_to_array_unique((*session_info
)->security_token
->sids
,
914 &(*session_info
)->security_token
->sids
,
915 &(*session_info
)->security_token
->num_sids
);
916 if (!NT_STATUS_IS_OK(status
)) {
917 TALLOC_FREE((*session_info
));
924 /****************************************************************************
925 Fake a auth3_session_info just from a username (as a
926 session_info structure, with create_local_token() already called on
928 ****************************************************************************/
930 NTSTATUS
make_session_info_from_username(TALLOC_CTX
*mem_ctx
,
931 const char *username
,
933 struct auth3_session_info
**session_info
)
935 struct auth_serversupplied_info
*result
;
939 pwd
= Get_Pwnam_alloc(talloc_tos(), username
);
941 return NT_STATUS_NO_SUCH_USER
;
944 status
= make_server_info_pw(&result
, pwd
->pw_name
, pwd
);
948 if (!NT_STATUS_IS_OK(status
)) {
952 result
->nss_token
= true;
953 result
->guest
= is_guest
;
955 /* Now turn the server_info into a session_info with the full token etc */
956 status
= create_local_token(mem_ctx
, result
, NULL
, session_info
);
961 /* This function MUST only used to create the cached server_info for
964 * This is a lossy conversion. Variables known to be lost so far
967 * - nss_token (not needed because the only read doesn't happen
968 * for the GUEST user, as this routine populates ->security_token
970 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
972 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
974 static struct auth_serversupplied_info
*copy_session_info_serverinfo_guest(TALLOC_CTX
*mem_ctx
,
975 const struct auth3_session_info
*src
,
976 struct auth_serversupplied_info
*server_info
)
978 struct auth_serversupplied_info
*dst
;
980 dst
= make_server_info(mem_ctx
);
985 /* This element must be provided to convert back to an auth_serversupplied_info */
986 SMB_ASSERT(src
->unix_info
);
988 dst
->guest
= src
->unix_info
->guest
;
989 dst
->system
= src
->unix_info
->system
;
991 /* This element must be provided to convert back to an
992 * auth_serversupplied_info. This needs to be from hte
993 * auth3_session_info because the group values in particular
994 * may change during create_local_token() processing */
995 SMB_ASSERT(src
->unix_token
);
996 dst
->utok
.uid
= src
->unix_token
->uid
;
997 dst
->utok
.gid
= src
->unix_token
->gid
;
998 dst
->utok
.ngroups
= src
->unix_token
->ngroups
;
999 if (src
->unix_token
->ngroups
!= 0) {
1000 dst
->utok
.groups
= (gid_t
*)talloc_memdup(
1001 dst
, src
->unix_token
->groups
,
1002 sizeof(gid_t
)*dst
->utok
.ngroups
);
1004 dst
->utok
.groups
= NULL
;
1007 /* We must have a security_token as otherwise the lossy
1008 * conversion without nss_token would cause create_local_token
1009 * to take the wrong path */
1010 SMB_ASSERT(src
->security_token
);
1012 dst
->security_token
= dup_nt_token(dst
, src
->security_token
);
1013 if (!dst
->security_token
) {
1018 dst
->session_key
= data_blob_talloc( dst
, src
->session_key
.data
,
1019 src
->session_key
.length
);
1021 /* This is OK because this functions is only used for the
1022 * GUEST account, which has all-zero keys for both values */
1023 dst
->lm_session_key
= data_blob_talloc(dst
, src
->session_key
.data
,
1024 src
->session_key
.length
);
1026 dst
->info3
= copy_netr_SamInfo3(dst
, server_info
->info3
);
1032 dst
->unix_name
= talloc_strdup(dst
, src
->unix_info
->unix_name
);
1033 if (!dst
->unix_name
) {
1038 dst
->sanitized_username
= talloc_strdup(dst
, src
->unix_info
->sanitized_username
);
1039 if (!dst
->sanitized_username
) {
1047 struct auth3_session_info
*copy_session_info(TALLOC_CTX
*mem_ctx
,
1048 const struct auth3_session_info
*src
)
1050 struct auth3_session_info
*dst
;
1052 enum ndr_err_code ndr_err
;
1054 ndr_err
= ndr_push_struct_blob(
1055 &blob
, talloc_tos(), src
,
1056 (ndr_push_flags_fn_t
)ndr_push_auth3_session_info
);
1057 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1058 DEBUG(0, ("copy_session_info(): ndr_push_auth3_session_info failed: "
1059 "%s\n", ndr_errstr(ndr_err
)));
1063 dst
= talloc(mem_ctx
, struct auth3_session_info
);
1065 DEBUG(0, ("talloc failed\n"));
1066 TALLOC_FREE(blob
.data
);
1070 ndr_err
= ndr_pull_struct_blob(
1072 (ndr_pull_flags_fn_t
)ndr_pull_auth3_session_info
);
1073 TALLOC_FREE(blob
.data
);
1075 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1076 DEBUG(0, ("copy_session_info(): ndr_pull_auth3_session_info failed: "
1077 "%s\n", ndr_errstr(ndr_err
)));
1086 * Set a new session key. Used in the rpc server where we have to override the
1087 * SMB level session key with SystemLibraryDTC
1090 bool session_info_set_session_key(struct auth3_session_info
*info
,
1091 DATA_BLOB session_key
)
1093 TALLOC_FREE(info
->session_key
.data
);
1095 info
->session_key
= data_blob_talloc(
1096 info
, session_key
.data
, session_key
.length
);
1098 return (info
->session_key
.data
!= NULL
);
1101 static struct auth3_session_info
*guest_info
= NULL
;
1103 static struct auth_serversupplied_info
*guest_server_info
= NULL
;
1105 bool init_guest_info(void)
1107 if (guest_info
!= NULL
)
1110 return NT_STATUS_IS_OK(make_new_session_info_guest(&guest_info
, &guest_server_info
));
1113 NTSTATUS
make_server_info_guest(TALLOC_CTX
*mem_ctx
,
1114 struct auth_serversupplied_info
**server_info
)
1116 /* This is trickier than it would appear to need to be because
1117 * we are trying to avoid certain costly operations when the
1118 * structure is converted to a 'auth3_session_info' again in
1119 * create_local_token() */
1120 *server_info
= copy_session_info_serverinfo_guest(mem_ctx
, guest_info
, guest_server_info
);
1121 return (*server_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
1124 NTSTATUS
make_session_info_guest(TALLOC_CTX
*mem_ctx
,
1125 struct auth3_session_info
**session_info
)
1127 *session_info
= copy_session_info(mem_ctx
, guest_info
);
1128 return (*session_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
1131 static struct auth3_session_info
*system_info
= NULL
;
1133 NTSTATUS
init_system_info(void)
1135 if (system_info
!= NULL
)
1136 return NT_STATUS_OK
;
1138 return make_new_session_info_system(NULL
, &system_info
);
1141 NTSTATUS
make_session_info_system(TALLOC_CTX
*mem_ctx
,
1142 struct auth3_session_info
**session_info
)
1144 if (system_info
== NULL
) return NT_STATUS_UNSUCCESSFUL
;
1145 *session_info
= copy_session_info(mem_ctx
, system_info
);
1146 return (*session_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
1149 const struct auth3_session_info
*get_session_info_system(void)
1154 bool copy_current_user(struct current_user
*dst
, struct current_user
*src
)
1157 struct security_token
*nt_token
;
1159 groups
= (gid_t
*)memdup(src
->ut
.groups
,
1160 sizeof(gid_t
) * src
->ut
.ngroups
);
1161 if ((src
->ut
.ngroups
!= 0) && (groups
== NULL
)) {
1165 nt_token
= dup_nt_token(NULL
, src
->nt_user_token
);
1166 if (nt_token
== NULL
) {
1171 dst
->conn
= src
->conn
;
1172 dst
->vuid
= src
->vuid
;
1173 dst
->ut
.uid
= src
->ut
.uid
;
1174 dst
->ut
.gid
= src
->ut
.gid
;
1175 dst
->ut
.ngroups
= src
->ut
.ngroups
;
1176 dst
->ut
.groups
= groups
;
1177 dst
->nt_user_token
= nt_token
;
1181 /***************************************************************************
1182 Purely internal function for make_server_info_info3
1183 ***************************************************************************/
1185 static NTSTATUS
check_account(TALLOC_CTX
*mem_ctx
, const char *domain
,
1186 const char *username
, char **found_username
,
1187 struct passwd
**pwd
,
1188 bool *username_was_mapped
)
1190 char *orig_dom_user
= NULL
;
1191 char *dom_user
= NULL
;
1192 char *lower_username
= NULL
;
1193 char *real_username
= NULL
;
1194 struct passwd
*passwd
;
1196 lower_username
= talloc_strdup(mem_ctx
, username
);
1197 if (!lower_username
) {
1198 return NT_STATUS_NO_MEMORY
;
1200 strlower_m( lower_username
);
1202 orig_dom_user
= talloc_asprintf(mem_ctx
,
1205 *lp_winbind_separator(),
1207 if (!orig_dom_user
) {
1208 return NT_STATUS_NO_MEMORY
;
1211 /* Get the passwd struct. Try to create the account if necessary. */
1213 *username_was_mapped
= map_username(mem_ctx
, orig_dom_user
, &dom_user
);
1215 return NT_STATUS_NO_MEMORY
;
1218 passwd
= smb_getpwnam(mem_ctx
, dom_user
, &real_username
, True
);
1220 DEBUG(3, ("Failed to find authenticated user %s via "
1221 "getpwnam(), denying access.\n", dom_user
));
1222 return NT_STATUS_NO_SUCH_USER
;
1225 if (!real_username
) {
1226 return NT_STATUS_NO_MEMORY
;
1231 /* This is pointless -- there is no suport for differing
1232 unix and windows names. Make sure to always store the
1233 one we actually looked up and succeeded. Have I mentioned
1234 why I hate the 'winbind use default domain' parameter?
1237 *found_username
= talloc_strdup( mem_ctx
, real_username
);
1239 return NT_STATUS_OK
;
1242 /****************************************************************************
1243 Wrapper to allow the getpwnam() call to strip the domain name and
1244 try again in case a local UNIX user is already there. Also run through
1245 the username if we fallback to the username only.
1246 ****************************************************************************/
1248 struct passwd
*smb_getpwnam( TALLOC_CTX
*mem_ctx
, const char *domuser
,
1249 char **p_save_username
, bool create
)
1251 struct passwd
*pw
= NULL
;
1253 char *username
= NULL
;
1255 /* we only save a copy of the username it has been mangled
1256 by winbindd use default domain */
1257 *p_save_username
= NULL
;
1259 /* don't call map_username() here since it has to be done higher
1260 up the stack so we don't call it multiple times */
1262 username
= talloc_strdup(mem_ctx
, domuser
);
1267 p
= strchr_m( username
, *lp_winbind_separator() );
1269 /* code for a DOMAIN\user string */
1272 pw
= Get_Pwnam_alloc( mem_ctx
, domuser
);
1274 /* make sure we get the case of the username correct */
1275 /* work around 'winbind use default domain = yes' */
1277 if ( !strchr_m( pw
->pw_name
, *lp_winbind_separator() ) ) {
1280 /* split the domain and username into 2 strings */
1284 *p_save_username
= talloc_asprintf(mem_ctx
,
1287 *lp_winbind_separator(),
1289 if (!*p_save_username
) {
1294 *p_save_username
= talloc_strdup(mem_ctx
, pw
->pw_name
);
1301 /* setup for lookup of just the username */
1302 /* remember that p and username are overlapping memory */
1305 username
= talloc_strdup(mem_ctx
, p
);
1311 /* just lookup a plain username */
1313 pw
= Get_Pwnam_alloc(mem_ctx
, username
);
1315 /* Create local user if requested but only if winbindd
1316 is not running. We need to protect against cases
1317 where winbindd is failing and then prematurely
1318 creating users in /etc/passwd */
1320 if ( !pw
&& create
&& !winbind_ping() ) {
1321 /* Don't add a machine account. */
1322 if (username
[strlen(username
)-1] == '$')
1325 _smb_create_user(NULL
, username
, NULL
);
1326 pw
= Get_Pwnam_alloc(mem_ctx
, username
);
1329 /* one last check for a valid passwd struct */
1332 *p_save_username
= talloc_strdup(mem_ctx
, pw
->pw_name
);
1337 /***************************************************************************
1338 Make a server_info struct from the info3 returned by a domain logon
1339 ***************************************************************************/
1341 NTSTATUS
make_server_info_info3(TALLOC_CTX
*mem_ctx
,
1342 const char *sent_nt_username
,
1344 struct auth_serversupplied_info
**server_info
,
1345 struct netr_SamInfo3
*info3
)
1347 static const char zeros
[16] = {0, };
1349 NTSTATUS nt_status
= NT_STATUS_OK
;
1350 char *found_username
= NULL
;
1351 const char *nt_domain
;
1352 const char *nt_username
;
1353 bool username_was_mapped
;
1355 struct auth_serversupplied_info
*result
;
1356 struct dom_sid
*group_sid
;
1357 struct netr_SamInfo3
*i3
;
1360 Here is where we should check the list of
1361 trusted domains, and verify that the SID
1365 nt_username
= talloc_strdup(mem_ctx
, info3
->base
.account_name
.string
);
1367 /* If the server didn't give us one, just use the one we sent
1369 nt_username
= sent_nt_username
;
1372 nt_domain
= talloc_strdup(mem_ctx
, info3
->base
.domain
.string
);
1374 /* If the server didn't give us one, just use the one we sent
1379 /* If getpwnam() fails try the add user script (2.2.x behavior).
1381 We use the _unmapped_ username here in an attempt to provide
1382 consistent username mapping behavior between kerberos and NTLM[SSP]
1383 authentication in domain mode security. I.E. Username mapping
1384 should be applied to the fully qualified username
1385 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1386 called map_username() unnecessarily in make_user_info_map() but
1387 that is how the current code is designed. Making the change here
1388 is the least disruptive place. -- jerry */
1390 /* this call will try to create the user if necessary */
1392 nt_status
= check_account(mem_ctx
, nt_domain
, sent_nt_username
,
1393 &found_username
, &pwd
,
1394 &username_was_mapped
);
1396 if (!NT_STATUS_IS_OK(nt_status
)) {
1400 result
= make_server_info(NULL
);
1401 if (result
== NULL
) {
1402 DEBUG(4, ("make_server_info failed!\n"));
1403 return NT_STATUS_NO_MEMORY
;
1406 result
->unix_name
= talloc_strdup(result
, found_username
);
1408 result
->sanitized_username
= sanitize_username(result
,
1410 if (result
->sanitized_username
== NULL
) {
1411 TALLOC_FREE(result
);
1412 return NT_STATUS_NO_MEMORY
;
1415 /* copy in the info3 */
1416 result
->info3
= i3
= copy_netr_SamInfo3(result
, info3
);
1417 if (result
->info3
== NULL
) {
1418 TALLOC_FREE(result
);
1419 return NT_STATUS_NO_MEMORY
;
1422 /* Fill in the unix info we found on the way */
1423 result
->utok
.uid
= pwd
->pw_uid
;
1424 result
->utok
.gid
= pwd
->pw_gid
;
1426 /* We can't just trust that the primary group sid sent us is something
1427 * we can really use. Obtain the useable sid, and store the original
1428 * one as an additional group if it had to be replaced */
1429 nt_status
= get_primary_group_sid(mem_ctx
, found_username
,
1431 if (!NT_STATUS_IS_OK(nt_status
)) {
1432 TALLOC_FREE(result
);
1436 /* store and check if it is the same we got originally */
1437 sid_peek_rid(group_sid
, &i3
->base
.primary_gid
);
1438 if (i3
->base
.primary_gid
!= info3
->base
.primary_gid
) {
1439 uint32_t n
= i3
->base
.groups
.count
;
1440 /* not the same, store the original as an additional group */
1441 i3
->base
.groups
.rids
=
1442 talloc_realloc(i3
, i3
->base
.groups
.rids
,
1443 struct samr_RidWithAttribute
, n
+ 1);
1444 if (i3
->base
.groups
.rids
== NULL
) {
1445 TALLOC_FREE(result
);
1446 return NT_STATUS_NO_MEMORY
;
1448 i3
->base
.groups
.rids
[n
].rid
= info3
->base
.primary_gid
;
1449 i3
->base
.groups
.rids
[n
].attributes
= SE_GROUP_ENABLED
;
1450 i3
->base
.groups
.count
= n
+ 1;
1453 /* ensure we are never given NULL session keys */
1455 if (memcmp(info3
->base
.key
.key
, zeros
, sizeof(zeros
)) == 0) {
1456 result
->session_key
= data_blob_null
;
1458 result
->session_key
= data_blob_talloc(
1459 result
, info3
->base
.key
.key
,
1460 sizeof(info3
->base
.key
.key
));
1463 if (memcmp(info3
->base
.LMSessKey
.key
, zeros
, 8) == 0) {
1464 result
->lm_session_key
= data_blob_null
;
1466 result
->lm_session_key
= data_blob_talloc(
1467 result
, info3
->base
.LMSessKey
.key
,
1468 sizeof(info3
->base
.LMSessKey
.key
));
1471 result
->nss_token
|= username_was_mapped
;
1473 result
->guest
= (info3
->base
.user_flags
& NETLOGON_GUEST
);
1475 *server_info
= result
;
1477 return NT_STATUS_OK
;
1480 /*****************************************************************************
1481 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1482 ******************************************************************************/
1484 NTSTATUS
make_server_info_wbcAuthUserInfo(TALLOC_CTX
*mem_ctx
,
1485 const char *sent_nt_username
,
1487 const struct wbcAuthUserInfo
*info
,
1488 struct auth_serversupplied_info
**server_info
)
1490 struct netr_SamInfo3
*info3
;
1492 info3
= wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx
, info
);
1494 return NT_STATUS_NO_MEMORY
;
1497 return make_server_info_info3(mem_ctx
,
1498 sent_nt_username
, domain
,
1499 server_info
, info3
);
1503 * Verify whether or not given domain is trusted.
1505 * @param domain_name name of the domain to be verified
1506 * @return true if domain is one of the trusted ones or
1507 * false if otherwise
1510 bool is_trusted_domain(const char* dom_name
)
1512 struct dom_sid trustdom_sid
;
1515 /* no trusted domains for a standalone server */
1517 if ( lp_server_role() == ROLE_STANDALONE
)
1520 if (dom_name
== NULL
|| dom_name
[0] == '\0') {
1524 if (strequal(dom_name
, get_global_sam_name())) {
1528 /* if we are a DC, then check for a direct trust relationships */
1532 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1533 "[%s]\n", dom_name
));
1534 ret
= pdb_get_trusteddom_pw(dom_name
, NULL
, NULL
, NULL
);
1542 /* If winbind is around, ask it */
1544 result
= wb_is_trusted_domain(dom_name
);
1546 if (result
== WBC_ERR_SUCCESS
) {
1550 if (result
== WBC_ERR_DOMAIN_NOT_FOUND
) {
1551 /* winbind could not find the domain */
1555 /* The only other possible result is that winbind is not up
1556 and running. We need to update the trustdom_cache
1559 update_trustdom_cache();
1562 /* now the trustdom cache should be available a DC could still
1563 * have a transitive trust so fall back to the cache of trusted
1564 * domains (like a domain member would use */
1566 if ( trustdom_cache_fetch(dom_name
, &trustdom_sid
) ) {