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_adduser_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(struct auth_usersupplied_info
**user_info
,
94 const char *client_domain
,
95 const char *workstation_name
,
96 const struct tsocket_address
*remote_address
,
97 const DATA_BLOB
*lm_pwd
,
98 const DATA_BLOB
*nt_pwd
,
99 const struct samr_Password
*lm_interactive_pwd
,
100 const struct samr_Password
*nt_interactive_pwd
,
101 const char *plaintext
,
102 enum auth_password_state password_state
)
107 char *internal_username
= NULL
;
109 was_mapped
= map_username(talloc_tos(), smb_name
, &internal_username
);
110 if (!internal_username
) {
111 return NT_STATUS_NO_MEMORY
;
114 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
115 client_domain
, smb_name
, workstation_name
));
117 domain
= client_domain
;
119 /* If you connect to a Windows domain member using a bogus domain name,
120 * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if
121 * the Windows box is a DC the name will become DOMAIN\user and be
122 * authenticated against AD, if the Windows box is a member server but
123 * not a DC the name will become WORKSTATION\user. A standalone
124 * non-domain member box will also map to WORKSTATION\user.
125 * This also deals with the client passing in a "" domain */
127 if (!is_trusted_domain(domain
) &&
128 !strequal(domain
, my_sam_name()))
130 if (lp_map_untrusted_to_domain())
131 domain
= my_sam_name();
133 domain
= get_global_sam_name();
134 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
135 "workstation [%s]\n",
136 client_domain
, domain
, smb_name
, workstation_name
));
139 /* We know that the given domain is trusted (and we are allowing them),
140 * it is our global SAM name, or for legacy behavior it is our
141 * primary domain name */
143 result
= make_user_info(user_info
, smb_name
, internal_username
,
144 client_domain
, domain
, workstation_name
,
145 remote_address
, lm_pwd
, nt_pwd
,
146 lm_interactive_pwd
, nt_interactive_pwd
,
147 plaintext
, password_state
);
148 if (NT_STATUS_IS_OK(result
)) {
149 /* We have tried mapping */
150 (*user_info
)->mapped_state
= true;
151 /* did we actually map the user to a different name? */
152 (*user_info
)->was_mapped
= was_mapped
;
157 /****************************************************************************
158 Create an auth_usersupplied_data, making the DATA_BLOBs here.
159 Decrypt and encrypt the passwords.
160 ****************************************************************************/
162 bool make_user_info_netlogon_network(struct auth_usersupplied_info
**user_info
,
163 const char *smb_name
,
164 const char *client_domain
,
165 const char *workstation_name
,
166 const struct tsocket_address
*remote_address
,
167 uint32 logon_parameters
,
168 const uchar
*lm_network_pwd
,
170 const uchar
*nt_network_pwd
,
175 DATA_BLOB lm_blob
= data_blob(lm_network_pwd
, lm_pwd_len
);
176 DATA_BLOB nt_blob
= data_blob(nt_network_pwd
, nt_pwd_len
);
178 status
= make_user_info_map(user_info
,
179 smb_name
, client_domain
,
182 lm_pwd_len
? &lm_blob
: NULL
,
183 nt_pwd_len
? &nt_blob
: NULL
,
185 AUTH_PASSWORD_RESPONSE
);
187 if (NT_STATUS_IS_OK(status
)) {
188 (*user_info
)->logon_parameters
= logon_parameters
;
190 ret
= NT_STATUS_IS_OK(status
) ? true : false;
192 data_blob_free(&lm_blob
);
193 data_blob_free(&nt_blob
);
197 /****************************************************************************
198 Create an auth_usersupplied_data, making the DATA_BLOBs here.
199 Decrypt and encrypt the passwords.
200 ****************************************************************************/
202 bool make_user_info_netlogon_interactive(struct auth_usersupplied_info
**user_info
,
203 const char *smb_name
,
204 const char *client_domain
,
205 const char *workstation_name
,
206 const struct tsocket_address
*remote_address
,
207 uint32 logon_parameters
,
209 const uchar lm_interactive_pwd
[16],
210 const uchar nt_interactive_pwd
[16],
211 const uchar
*dc_sess_key
)
213 struct samr_Password lm_pwd
;
214 struct samr_Password nt_pwd
;
215 unsigned char local_lm_response
[24];
216 unsigned char local_nt_response
[24];
217 unsigned char key
[16];
219 memcpy(key
, dc_sess_key
, 16);
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 #ifdef DEBUG_PASSWORD
229 dump_data(100, key
, sizeof(key
));
231 DEBUG(100,("lm owf password:"));
232 dump_data(100, lm_pwd
.hash
, sizeof(lm_pwd
.hash
));
234 DEBUG(100,("nt owf password:"));
235 dump_data(100, nt_pwd
.hash
, sizeof(nt_pwd
.hash
));
238 if (lm_interactive_pwd
)
239 arcfour_crypt(lm_pwd
.hash
, key
, sizeof(lm_pwd
.hash
));
241 if (nt_interactive_pwd
)
242 arcfour_crypt(nt_pwd
.hash
, key
, sizeof(nt_pwd
.hash
));
244 #ifdef DEBUG_PASSWORD
245 DEBUG(100,("decrypt of lm owf password:"));
246 dump_data(100, lm_pwd
.hash
, sizeof(lm_pwd
));
248 DEBUG(100,("decrypt of nt owf password:"));
249 dump_data(100, nt_pwd
.hash
, sizeof(nt_pwd
));
252 if (lm_interactive_pwd
)
253 SMBOWFencrypt(lm_pwd
.hash
, chal
,
256 if (nt_interactive_pwd
)
257 SMBOWFencrypt(nt_pwd
.hash
, chal
,
260 /* Password info paranoia */
266 DATA_BLOB local_lm_blob
;
267 DATA_BLOB local_nt_blob
;
269 if (lm_interactive_pwd
) {
270 local_lm_blob
= data_blob(local_lm_response
,
271 sizeof(local_lm_response
));
274 if (nt_interactive_pwd
) {
275 local_nt_blob
= data_blob(local_nt_response
,
276 sizeof(local_nt_response
));
279 nt_status
= make_user_info_map(
281 smb_name
, client_domain
, workstation_name
,
283 lm_interactive_pwd
? &local_lm_blob
: NULL
,
284 nt_interactive_pwd
? &local_nt_blob
: NULL
,
285 lm_interactive_pwd
? &lm_pwd
: NULL
,
286 nt_interactive_pwd
? &nt_pwd
: NULL
,
287 NULL
, AUTH_PASSWORD_HASH
);
289 if (NT_STATUS_IS_OK(nt_status
)) {
290 (*user_info
)->logon_parameters
= logon_parameters
;
293 ret
= NT_STATUS_IS_OK(nt_status
) ? true : false;
294 data_blob_free(&local_lm_blob
);
295 data_blob_free(&local_nt_blob
);
301 /****************************************************************************
302 Create an auth_usersupplied_data structure
303 ****************************************************************************/
305 bool make_user_info_for_reply(struct auth_usersupplied_info
**user_info
,
306 const char *smb_name
,
307 const char *client_domain
,
308 const struct tsocket_address
*remote_address
,
310 DATA_BLOB plaintext_password
)
313 DATA_BLOB local_lm_blob
;
314 DATA_BLOB local_nt_blob
;
315 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
316 char *plaintext_password_string
;
318 * Not encrypted - do so.
321 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
323 if (plaintext_password
.data
&& plaintext_password
.length
) {
324 unsigned char local_lm_response
[24];
326 #ifdef DEBUG_PASSWORD
327 DEBUG(10,("Unencrypted password (len %d):\n",
328 (int)plaintext_password
.length
));
329 dump_data(100, plaintext_password
.data
,
330 plaintext_password
.length
);
333 SMBencrypt( (const char *)plaintext_password
.data
,
334 (const uchar
*)chal
, local_lm_response
);
335 local_lm_blob
= data_blob(local_lm_response
, 24);
337 /* We can't do an NT hash here, as the password needs to be
339 local_nt_blob
= data_blob_null
;
341 local_lm_blob
= data_blob_null
;
342 local_nt_blob
= data_blob_null
;
345 plaintext_password_string
= talloc_strndup(talloc_tos(),
346 (const char *)plaintext_password
.data
,
347 plaintext_password
.length
);
348 if (!plaintext_password_string
) {
352 ret
= make_user_info(
353 user_info
, smb_name
, smb_name
, client_domain
, client_domain
,
354 get_remote_machine_name(),
356 local_lm_blob
.data
? &local_lm_blob
: NULL
,
357 local_nt_blob
.data
? &local_nt_blob
: NULL
,
359 plaintext_password_string
,
360 AUTH_PASSWORD_PLAIN
);
362 if (plaintext_password_string
) {
363 memset(plaintext_password_string
, '\0', strlen(plaintext_password_string
));
364 talloc_free(plaintext_password_string
);
367 data_blob_free(&local_lm_blob
);
368 return NT_STATUS_IS_OK(ret
) ? true : false;
371 /****************************************************************************
372 Create an auth_usersupplied_data structure
373 ****************************************************************************/
375 NTSTATUS
make_user_info_for_reply_enc(struct auth_usersupplied_info
**user_info
,
376 const char *smb_name
,
377 const char *client_domain
,
378 const struct tsocket_address
*remote_address
,
379 DATA_BLOB lm_resp
, DATA_BLOB nt_resp
)
381 return make_user_info(user_info
, smb_name
, smb_name
,
382 client_domain
, client_domain
,
383 get_remote_machine_name(),
385 lm_resp
.data
&& (lm_resp
.length
> 0) ? &lm_resp
: NULL
,
386 nt_resp
.data
&& (nt_resp
.length
> 0) ? &nt_resp
: NULL
,
388 AUTH_PASSWORD_RESPONSE
);
391 /****************************************************************************
392 Create a guest user_info blob, for anonymous authentication.
393 ****************************************************************************/
395 bool make_user_info_guest(const struct tsocket_address
*remote_address
,
396 struct auth_usersupplied_info
**user_info
)
400 nt_status
= make_user_info(user_info
,
408 AUTH_PASSWORD_RESPONSE
);
410 return NT_STATUS_IS_OK(nt_status
) ? true : false;
413 static NTSTATUS
log_nt_token(struct security_token
*token
)
415 TALLOC_CTX
*frame
= talloc_stackframe();
420 if ((lp_log_nt_token_command(frame
) == NULL
) ||
421 (strlen(lp_log_nt_token_command(frame
)) == 0)) {
426 group_sidstr
= talloc_strdup(frame
, "");
427 for (i
=1; i
<token
->num_sids
; i
++) {
428 group_sidstr
= talloc_asprintf(
429 frame
, "%s %s", group_sidstr
,
430 sid_string_talloc(frame
, &token
->sids
[i
]));
433 command
= talloc_string_sub(
434 frame
, lp_log_nt_token_command(frame
),
435 "%s", sid_string_talloc(frame
, &token
->sids
[0]));
436 command
= talloc_string_sub(frame
, command
, "%t", group_sidstr
);
438 if (command
== NULL
) {
440 return NT_STATUS_NO_MEMORY
;
443 DEBUG(8, ("running command: [%s]\n", command
));
444 if (smbrun(command
, NULL
) != 0) {
445 DEBUG(0, ("Could not log NT token\n"));
447 return NT_STATUS_ACCESS_DENIED
;
455 * Create the token to use from server_info->info3 and
456 * server_info->sids (the info3/sam groups). Find the unix gids.
459 NTSTATUS
create_local_token(TALLOC_CTX
*mem_ctx
,
460 const struct auth_serversupplied_info
*server_info
,
461 DATA_BLOB
*session_key
,
462 const char *smb_username
, /* for ->sanitized_username, for %U subs */
463 struct auth_session_info
**session_info_out
)
465 struct security_token
*t
;
468 struct dom_sid tmp_sid
;
469 struct auth_session_info
*session_info
;
473 /* Ensure we can't possible take a code path leading to a
476 return NT_STATUS_LOGON_FAILURE
;
479 session_info
= talloc_zero(mem_ctx
, struct auth_session_info
);
481 return NT_STATUS_NO_MEMORY
;
484 session_info
->unix_token
= talloc_zero(session_info
, struct security_unix_token
);
485 if (!session_info
->unix_token
) {
486 TALLOC_FREE(session_info
);
487 return NT_STATUS_NO_MEMORY
;
490 session_info
->unix_token
->uid
= server_info
->utok
.uid
;
491 session_info
->unix_token
->gid
= server_info
->utok
.gid
;
493 session_info
->unix_info
= talloc_zero(session_info
, struct auth_user_info_unix
);
494 if (!session_info
->unix_info
) {
495 TALLOC_FREE(session_info
);
496 return NT_STATUS_NO_MEMORY
;
499 session_info
->unix_info
->unix_name
= talloc_strdup(session_info
, server_info
->unix_name
);
500 if (!session_info
->unix_info
->unix_name
) {
501 TALLOC_FREE(session_info
);
502 return NT_STATUS_NO_MEMORY
;
505 /* This is a potentially untrusted username for use in %U */
506 alpha_strcpy(tmp
, smb_username
, ". _-$", sizeof(tmp
));
507 session_info
->unix_info
->sanitized_username
=
508 talloc_strdup(session_info
->unix_info
, tmp
);
511 data_blob_free(&session_info
->session_key
);
512 session_info
->session_key
= data_blob_talloc(session_info
,
514 session_key
->length
);
515 if (!session_info
->session_key
.data
&& session_key
->length
) {
516 return NT_STATUS_NO_MEMORY
;
519 session_info
->session_key
= data_blob_talloc( session_info
, server_info
->session_key
.data
,
520 server_info
->session_key
.length
);
523 /* We need to populate session_info->info with the information found in server_info->info3 */
524 status
= make_user_info_SamBaseInfo(session_info
, "", &server_info
->info3
->base
,
525 server_info
->guest
== false,
526 &session_info
->info
);
527 if (!NT_STATUS_IS_OK(status
)) {
528 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
529 TALLOC_FREE(session_info
);
533 if (server_info
->security_token
) {
534 /* Just copy the token, it has already been finalised
535 * (nasty hack to support a cached guest/system session_info
538 session_info
->security_token
= dup_nt_token(session_info
, server_info
->security_token
);
539 if (!session_info
->security_token
) {
540 TALLOC_FREE(session_info
);
541 return NT_STATUS_NO_MEMORY
;
544 session_info
->unix_token
->ngroups
= server_info
->utok
.ngroups
;
545 if (server_info
->utok
.ngroups
!= 0) {
546 session_info
->unix_token
->groups
= (gid_t
*)talloc_memdup(
547 session_info
->unix_token
, server_info
->utok
.groups
,
548 sizeof(gid_t
)*session_info
->unix_token
->ngroups
);
550 session_info
->unix_token
->groups
= NULL
;
553 *session_info_out
= session_info
;
558 * If winbind is not around, we can not make much use of the SIDs the
559 * domain controller provided us with. Likewise if the user name was
560 * mapped to some local unix user.
563 if (((lp_server_role() == ROLE_DOMAIN_MEMBER
) && !winbind_ping()) ||
564 (server_info
->nss_token
)) {
565 char *found_username
= NULL
;
566 status
= create_token_from_username(session_info
,
567 server_info
->unix_name
,
569 &session_info
->unix_token
->uid
,
570 &session_info
->unix_token
->gid
,
572 &session_info
->security_token
);
573 if (NT_STATUS_IS_OK(status
)) {
574 session_info
->unix_info
->unix_name
= found_username
;
577 status
= create_local_nt_token_from_info3(session_info
,
581 &session_info
->security_token
);
584 if (!NT_STATUS_IS_OK(status
)) {
588 /* Convert the SIDs to gids. */
590 session_info
->unix_token
->ngroups
= 0;
591 session_info
->unix_token
->groups
= NULL
;
593 t
= session_info
->security_token
;
595 ids
= talloc_array(talloc_tos(), struct unixid
,
598 return NT_STATUS_NO_MEMORY
;
601 if (!sids_to_unixids(t
->sids
, t
->num_sids
, ids
)) {
603 return NT_STATUS_NO_MEMORY
;
606 for (i
=0; i
<t
->num_sids
; i
++) {
608 if (i
== 0 && ids
[i
].type
!= ID_TYPE_BOTH
) {
612 if (ids
[i
].type
!= ID_TYPE_GID
&&
613 ids
[i
].type
!= ID_TYPE_BOTH
) {
614 DEBUG(10, ("Could not convert SID %s to gid, "
616 sid_string_dbg(&t
->sids
[i
])));
619 if (!add_gid_to_array_unique(session_info
, ids
[i
].id
,
620 &session_info
->unix_token
->groups
,
621 &session_info
->unix_token
->ngroups
)) {
622 return NT_STATUS_NO_MEMORY
;
627 * Add the "Unix Group" SID for each gid to catch mapped groups
628 * and their Unix equivalent. This is to solve the backwards
629 * compatibility problem of 'valid users = +ntadmin' where
630 * ntadmin has been paired with "Domain Admins" in the group
631 * mapping table. Otherwise smb.conf would need to be changed
632 * to 'valid user = "Domain Admins"'. --jerry
634 * For consistency we also add the "Unix User" SID,
635 * so that the complete unix token is represented within
639 uid_to_unix_users_sid(session_info
->unix_token
->uid
, &tmp_sid
);
641 add_sid_to_array_unique(session_info
->security_token
, &tmp_sid
,
642 &session_info
->security_token
->sids
,
643 &session_info
->security_token
->num_sids
);
645 for ( i
=0; i
<session_info
->unix_token
->ngroups
; i
++ ) {
646 gid_to_unix_groups_sid(session_info
->unix_token
->groups
[i
], &tmp_sid
);
647 add_sid_to_array_unique(session_info
->security_token
, &tmp_sid
,
648 &session_info
->security_token
->sids
,
649 &session_info
->security_token
->num_sids
);
652 security_token_debug(DBGC_AUTH
, 10, session_info
->security_token
);
653 debug_unix_user_token(DBGC_AUTH
, 10,
654 session_info
->unix_token
->uid
,
655 session_info
->unix_token
->gid
,
656 session_info
->unix_token
->ngroups
,
657 session_info
->unix_token
->groups
);
659 status
= log_nt_token(session_info
->security_token
);
660 if (!NT_STATUS_IS_OK(status
)) {
664 *session_info_out
= session_info
;
668 /***************************************************************************
669 Make (and fill) a server_info struct from a 'struct passwd' by conversion
671 ***************************************************************************/
673 NTSTATUS
make_server_info_pw(struct auth_serversupplied_info
**server_info
,
678 struct samu
*sampass
= NULL
;
679 char *qualified_name
= NULL
;
680 TALLOC_CTX
*mem_ctx
= NULL
;
681 struct dom_sid u_sid
;
682 enum lsa_SidType type
;
683 struct auth_serversupplied_info
*result
;
686 * The SID returned in server_info->sam_account is based
687 * on our SAM sid even though for a pure UNIX account this should
688 * not be the case as it doesn't really exist in the SAM db.
689 * This causes lookups on "[in]valid users" to fail as they
690 * will lookup this name as a "Unix User" SID to check against
691 * the user token. Fix this by adding the "Unix User"\unix_username
692 * SID to the sid array. The correct fix should probably be
693 * changing the server_info->sam_account user SID to be a
694 * S-1-22 Unix SID, but this might break old configs where
695 * plaintext passwords were used with no SAM backend.
698 mem_ctx
= talloc_init("make_server_info_pw_tmp");
700 return NT_STATUS_NO_MEMORY
;
703 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
704 unix_users_domain_name(),
706 if (!qualified_name
) {
707 TALLOC_FREE(mem_ctx
);
708 return NT_STATUS_NO_MEMORY
;
711 if (!lookup_name(mem_ctx
, qualified_name
, LOOKUP_NAME_ALL
,
714 TALLOC_FREE(mem_ctx
);
715 return NT_STATUS_NO_SUCH_USER
;
718 TALLOC_FREE(mem_ctx
);
720 if (type
!= SID_NAME_USER
) {
721 return NT_STATUS_NO_SUCH_USER
;
724 if ( !(sampass
= samu_new( NULL
)) ) {
725 return NT_STATUS_NO_MEMORY
;
728 status
= samu_set_unix( sampass
, pwd
);
729 if (!NT_STATUS_IS_OK(status
)) {
733 /* In pathological cases the above call can set the account
734 * name to the DOMAIN\username form. Reset the account name
735 * using unix_username */
736 pdb_set_username(sampass
, unix_username
, PDB_SET
);
738 /* set the user sid to be the calculated u_sid */
739 pdb_set_user_sid(sampass
, &u_sid
, PDB_SET
);
741 result
= make_server_info(NULL
);
742 if (result
== NULL
) {
743 TALLOC_FREE(sampass
);
744 return NT_STATUS_NO_MEMORY
;
747 status
= samu_to_SamInfo3(result
, sampass
, lp_netbios_name(),
748 &result
->info3
, &result
->extra
);
749 TALLOC_FREE(sampass
);
750 if (!NT_STATUS_IS_OK(status
)) {
751 DEBUG(10, ("Failed to convert samu to info3: %s\n",
757 result
->unix_name
= talloc_strdup(result
, unix_username
);
759 if (result
->unix_name
== NULL
) {
761 return NT_STATUS_NO_MEMORY
;
764 result
->utok
.uid
= pwd
->pw_uid
;
765 result
->utok
.gid
= pwd
->pw_gid
;
767 *server_info
= result
;
772 static NTSTATUS
get_system_info3(TALLOC_CTX
*mem_ctx
,
773 struct netr_SamInfo3
*info3
)
776 struct dom_sid
*system_sid
;
778 /* Set account name */
779 init_lsa_String(&info3
->base
.account_name
, "SYSTEM");
781 /* Set domain name */
782 init_lsa_StringLarge(&info3
->base
.logon_domain
, "NT AUTHORITY");
785 /* The SID set here will be overwirtten anyway, but try and make it SID_NT_SYSTEM anyway */
786 /* Domain sid is NT_AUTHORITY */
788 system_sid
= dom_sid_parse_talloc(mem_ctx
, SID_NT_SYSTEM
);
789 if (system_sid
== NULL
) {
790 return NT_STATUS_NO_MEMORY
;
793 status
= dom_sid_split_rid(mem_ctx
, system_sid
, &info3
->base
.domain_sid
,
795 TALLOC_FREE(system_sid
);
796 if (!NT_STATUS_IS_OK(status
)) {
800 /* Primary gid is the same */
801 info3
->base
.primary_gid
= info3
->base
.rid
;
806 static NTSTATUS
get_guest_info3(TALLOC_CTX
*mem_ctx
,
807 struct netr_SamInfo3
*info3
)
809 const char *guest_account
= lp_guestaccount();
810 struct dom_sid domain_sid
;
814 pwd
= Get_Pwnam_alloc(mem_ctx
, guest_account
);
816 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
817 "account [%s]!\n", guest_account
));
818 return NT_STATUS_NO_SUCH_USER
;
821 /* Set account name */
822 tmp
= talloc_strdup(mem_ctx
, pwd
->pw_name
);
824 return NT_STATUS_NO_MEMORY
;
826 init_lsa_String(&info3
->base
.account_name
, tmp
);
828 /* Set domain name */
829 tmp
= talloc_strdup(mem_ctx
, get_global_sam_name());
831 return NT_STATUS_NO_MEMORY
;
833 init_lsa_StringLarge(&info3
->base
.logon_domain
, tmp
);
836 sid_copy(&domain_sid
, get_global_sam_sid());
838 info3
->base
.domain_sid
= dom_sid_dup(mem_ctx
, &domain_sid
);
839 if (info3
->base
.domain_sid
== NULL
) {
840 return NT_STATUS_NO_MEMORY
;
844 info3
->base
.rid
= DOMAIN_RID_GUEST
;
847 info3
->base
.primary_gid
= DOMAIN_RID_GUESTS
;
850 info3
->base
.user_flags
= NETLOGON_GUEST
;
856 /***************************************************************************
857 Make (and fill) a user_info struct for a guest login.
858 This *must* succeed for smbd to start. If there is no mapping entry for
859 the guest gid, then create one.
861 The resulting structure is a 'session_info' because
862 create_local_token() has already been called on it. This is quite
863 nasty, as the auth subsystem isn't expect this, but the behavior is
865 ***************************************************************************/
867 static NTSTATUS
make_new_session_info_guest(struct auth_session_info
**session_info
, struct auth_serversupplied_info
**server_info
)
869 static const char zeros
[16] = {0};
870 const char *guest_account
= lp_guestaccount();
871 const char *domain
= lp_netbios_name();
872 struct netr_SamInfo3 info3
;
876 tmp_ctx
= talloc_stackframe();
877 if (tmp_ctx
== NULL
) {
878 return NT_STATUS_NO_MEMORY
;
883 status
= get_guest_info3(tmp_ctx
, &info3
);
884 if (!NT_STATUS_IS_OK(status
)) {
885 DEBUG(0, ("get_guest_info3 failed with %s\n",
890 status
= make_server_info_info3(tmp_ctx
,
895 if (!NT_STATUS_IS_OK(status
)) {
896 DEBUG(0, ("make_server_info_info3 failed with %s\n",
901 (*server_info
)->guest
= true;
903 /* This should not be done here (we should produce a server
904 * info, and later construct a session info from it), but for
905 * now this does not change the previous behavior */
906 status
= create_local_token(tmp_ctx
, *server_info
, NULL
,
907 (*server_info
)->info3
->base
.account_name
.string
,
909 if (!NT_STATUS_IS_OK(status
)) {
910 DEBUG(0, ("create_local_token failed: %s\n",
914 talloc_steal(NULL
, *session_info
);
915 talloc_steal(NULL
, *server_info
);
917 /* annoying, but the Guest really does have a session key, and it is
919 (*session_info
)->session_key
= data_blob(zeros
, sizeof(zeros
));
921 status
= NT_STATUS_OK
;
923 TALLOC_FREE(tmp_ctx
);
927 /***************************************************************************
928 Make (and fill) a auth_session_info struct for a system user login.
929 This *must* succeed for smbd to start.
930 ***************************************************************************/
932 static NTSTATUS
make_new_session_info_system(TALLOC_CTX
*mem_ctx
,
933 struct auth_session_info
**session_info
)
936 struct auth_serversupplied_info
*server_info
;
939 tmp_ctx
= talloc_stackframe();
940 if (tmp_ctx
== NULL
) {
941 return NT_STATUS_NO_MEMORY
;
944 server_info
= make_server_info(tmp_ctx
);
946 status
= NT_STATUS_NO_MEMORY
;
947 DEBUG(0, ("failed making server_info\n"));
951 server_info
->info3
= talloc_zero(server_info
, struct netr_SamInfo3
);
952 if (!server_info
->info3
) {
953 status
= NT_STATUS_NO_MEMORY
;
954 DEBUG(0, ("talloc failed setting info3\n"));
958 status
= get_system_info3(server_info
, server_info
->info3
);
959 if (!NT_STATUS_IS_OK(status
)) {
960 DEBUG(0, ("Failed creating system info3 with %s\n",
965 server_info
->utok
.uid
= sec_initial_uid();
966 server_info
->utok
.gid
= sec_initial_gid();
967 server_info
->unix_name
= talloc_asprintf(server_info
,
968 "NT AUTHORITY%cSYSTEM",
969 *lp_winbind_separator());
971 if (!server_info
->unix_name
) {
972 status
= NT_STATUS_NO_MEMORY
;
973 DEBUG(0, ("talloc_asprintf failed setting unix_name\n"));
977 server_info
->security_token
= talloc_zero(server_info
, struct security_token
);
978 if (!server_info
->security_token
) {
979 status
= NT_STATUS_NO_MEMORY
;
980 DEBUG(0, ("talloc failed setting security token\n"));
984 status
= add_sid_to_array_unique(server_info
->security_token
->sids
,
986 &server_info
->security_token
->sids
,
987 &server_info
->security_token
->num_sids
);
988 if (!NT_STATUS_IS_OK(status
)) {
992 /* SYSTEM has all privilages */
993 server_info
->security_token
->privilege_mask
= ~0;
995 /* Now turn the server_info into a session_info with the full token etc */
996 status
= create_local_token(mem_ctx
, server_info
, NULL
, "SYSTEM", session_info
);
997 talloc_free(server_info
);
999 if (!NT_STATUS_IS_OK(status
)) {
1000 DEBUG(0, ("create_local_token failed: %s\n",
1001 nt_errstr(status
)));
1005 talloc_steal(mem_ctx
, *session_info
);
1008 TALLOC_FREE(tmp_ctx
);
1012 /****************************************************************************
1013 Fake a auth_session_info just from a username (as a
1014 session_info structure, with create_local_token() already called on
1016 ****************************************************************************/
1018 NTSTATUS
make_session_info_from_username(TALLOC_CTX
*mem_ctx
,
1019 const char *username
,
1021 struct auth_session_info
**session_info
)
1025 struct auth_serversupplied_info
*result
;
1027 pwd
= Get_Pwnam_alloc(talloc_tos(), username
);
1029 return NT_STATUS_NO_SUCH_USER
;
1032 status
= make_server_info_pw(&result
, pwd
->pw_name
, pwd
);
1034 if (!NT_STATUS_IS_OK(status
)) {
1038 result
->nss_token
= true;
1039 result
->guest
= is_guest
;
1041 /* Now turn the server_info into a session_info with the full token etc */
1042 status
= create_local_token(mem_ctx
, result
, NULL
, pwd
->pw_name
, session_info
);
1043 TALLOC_FREE(result
);
1049 /* This function MUST only used to create the cached server_info for
1052 * This is a lossy conversion. Variables known to be lost so far
1055 * - nss_token (not needed because the only read doesn't happen
1056 * for the GUEST user, as this routine populates ->security_token
1058 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1060 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1062 static struct auth_serversupplied_info
*copy_session_info_serverinfo_guest(TALLOC_CTX
*mem_ctx
,
1063 const struct auth_session_info
*src
,
1064 struct auth_serversupplied_info
*server_info
)
1066 struct auth_serversupplied_info
*dst
;
1068 dst
= make_server_info(mem_ctx
);
1073 /* This element must be provided to convert back to an auth_serversupplied_info */
1074 SMB_ASSERT(src
->unix_info
);
1077 dst
->system
= false;
1079 /* This element must be provided to convert back to an
1080 * auth_serversupplied_info. This needs to be from the
1081 * auth_session_info because the group values in particular
1082 * may change during create_local_token() processing */
1083 SMB_ASSERT(src
->unix_token
);
1084 dst
->utok
.uid
= src
->unix_token
->uid
;
1085 dst
->utok
.gid
= src
->unix_token
->gid
;
1086 dst
->utok
.ngroups
= src
->unix_token
->ngroups
;
1087 if (src
->unix_token
->ngroups
!= 0) {
1088 dst
->utok
.groups
= (gid_t
*)talloc_memdup(
1089 dst
, src
->unix_token
->groups
,
1090 sizeof(gid_t
)*dst
->utok
.ngroups
);
1092 dst
->utok
.groups
= NULL
;
1095 /* We must have a security_token as otherwise the lossy
1096 * conversion without nss_token would cause create_local_token
1097 * to take the wrong path */
1098 SMB_ASSERT(src
->security_token
);
1100 dst
->security_token
= dup_nt_token(dst
, src
->security_token
);
1101 if (!dst
->security_token
) {
1106 dst
->session_key
= data_blob_talloc( dst
, src
->session_key
.data
,
1107 src
->session_key
.length
);
1109 /* This is OK because this functions is only used for the
1110 * GUEST account, which has all-zero keys for both values */
1111 dst
->lm_session_key
= data_blob_talloc(dst
, src
->session_key
.data
,
1112 src
->session_key
.length
);
1114 dst
->info3
= copy_netr_SamInfo3(dst
, server_info
->info3
);
1120 dst
->unix_name
= talloc_strdup(dst
, src
->unix_info
->unix_name
);
1121 if (!dst
->unix_name
) {
1129 struct auth_session_info
*copy_session_info(TALLOC_CTX
*mem_ctx
,
1130 const struct auth_session_info
*src
)
1132 struct auth_session_info
*dst
;
1134 enum ndr_err_code ndr_err
;
1136 ndr_err
= ndr_push_struct_blob(
1137 &blob
, talloc_tos(), src
,
1138 (ndr_push_flags_fn_t
)ndr_push_auth_session_info
);
1139 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1140 DEBUG(0, ("copy_session_info(): ndr_push_auth_session_info failed: "
1141 "%s\n", ndr_errstr(ndr_err
)));
1145 dst
= talloc(mem_ctx
, struct auth_session_info
);
1147 DEBUG(0, ("talloc failed\n"));
1148 TALLOC_FREE(blob
.data
);
1152 ndr_err
= ndr_pull_struct_blob(
1154 (ndr_pull_flags_fn_t
)ndr_pull_auth_session_info
);
1155 TALLOC_FREE(blob
.data
);
1157 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1158 DEBUG(0, ("copy_session_info(): ndr_pull_auth_session_info failed: "
1159 "%s\n", ndr_errstr(ndr_err
)));
1168 * Set a new session key. Used in the rpc server where we have to override the
1169 * SMB level session key with SystemLibraryDTC
1172 bool session_info_set_session_key(struct auth_session_info
*info
,
1173 DATA_BLOB session_key
)
1175 TALLOC_FREE(info
->session_key
.data
);
1177 info
->session_key
= data_blob_talloc(
1178 info
, session_key
.data
, session_key
.length
);
1180 return (info
->session_key
.data
!= NULL
);
1183 static struct auth_session_info
*guest_info
= NULL
;
1185 static struct auth_serversupplied_info
*guest_server_info
= NULL
;
1187 bool init_guest_info(void)
1189 if (guest_info
!= NULL
)
1192 return NT_STATUS_IS_OK(make_new_session_info_guest(&guest_info
, &guest_server_info
));
1195 NTSTATUS
make_server_info_guest(TALLOC_CTX
*mem_ctx
,
1196 struct auth_serversupplied_info
**server_info
)
1198 /* This is trickier than it would appear to need to be because
1199 * we are trying to avoid certain costly operations when the
1200 * structure is converted to a 'auth_session_info' again in
1201 * create_local_token() */
1202 *server_info
= copy_session_info_serverinfo_guest(mem_ctx
, guest_info
, guest_server_info
);
1203 return (*server_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
1206 NTSTATUS
make_session_info_guest(TALLOC_CTX
*mem_ctx
,
1207 struct auth_session_info
**session_info
)
1209 *session_info
= copy_session_info(mem_ctx
, guest_info
);
1210 return (*session_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
1213 static struct auth_session_info
*system_info
= NULL
;
1215 NTSTATUS
init_system_session_info(void)
1217 if (system_info
!= NULL
)
1218 return NT_STATUS_OK
;
1220 return make_new_session_info_system(NULL
, &system_info
);
1223 NTSTATUS
make_session_info_system(TALLOC_CTX
*mem_ctx
,
1224 struct auth_session_info
**session_info
)
1226 if (system_info
== NULL
) return NT_STATUS_UNSUCCESSFUL
;
1227 *session_info
= copy_session_info(mem_ctx
, system_info
);
1228 return (*session_info
!= NULL
) ? NT_STATUS_OK
: NT_STATUS_NO_MEMORY
;
1231 const struct auth_session_info
*get_session_info_system(void)
1236 /***************************************************************************
1237 Purely internal function for make_server_info_info3
1238 ***************************************************************************/
1240 static NTSTATUS
check_account(TALLOC_CTX
*mem_ctx
, const char *domain
,
1241 const char *username
, char **found_username
,
1242 struct passwd
**pwd
,
1243 bool *username_was_mapped
)
1245 char *orig_dom_user
= NULL
;
1246 char *dom_user
= NULL
;
1247 char *lower_username
= NULL
;
1248 char *real_username
= NULL
;
1249 struct passwd
*passwd
;
1251 lower_username
= talloc_strdup(mem_ctx
, username
);
1252 if (!lower_username
) {
1253 return NT_STATUS_NO_MEMORY
;
1255 if (!strlower_m( lower_username
)) {
1256 return NT_STATUS_INVALID_PARAMETER
;
1259 orig_dom_user
= talloc_asprintf(mem_ctx
,
1262 *lp_winbind_separator(),
1264 if (!orig_dom_user
) {
1265 return NT_STATUS_NO_MEMORY
;
1268 /* Get the passwd struct. Try to create the account if necessary. */
1270 *username_was_mapped
= map_username(mem_ctx
, orig_dom_user
, &dom_user
);
1272 return NT_STATUS_NO_MEMORY
;
1275 passwd
= smb_getpwnam(mem_ctx
, dom_user
, &real_username
, true );
1277 DEBUG(3, ("Failed to find authenticated user %s via "
1278 "getpwnam(), denying access.\n", dom_user
));
1279 return NT_STATUS_NO_SUCH_USER
;
1282 if (!real_username
) {
1283 return NT_STATUS_NO_MEMORY
;
1288 /* This is pointless -- there is no support for differing
1289 unix and windows names. Make sure to always store the
1290 one we actually looked up and succeeded. Have I mentioned
1291 why I hate the 'winbind use default domain' parameter?
1294 *found_username
= talloc_strdup( mem_ctx
, real_username
);
1296 return NT_STATUS_OK
;
1299 /****************************************************************************
1300 Wrapper to allow the getpwnam() call to strip the domain name and
1301 try again in case a local UNIX user is already there. Also run through
1302 the username if we fallback to the username only.
1303 ****************************************************************************/
1305 struct passwd
*smb_getpwnam( TALLOC_CTX
*mem_ctx
, const char *domuser
,
1306 char **p_save_username
, bool create
)
1308 struct passwd
*pw
= NULL
;
1310 char *username
= NULL
;
1312 /* we only save a copy of the username it has been mangled
1313 by winbindd use default domain */
1314 *p_save_username
= NULL
;
1316 /* don't call map_username() here since it has to be done higher
1317 up the stack so we don't call it multiple times */
1319 username
= talloc_strdup(mem_ctx
, domuser
);
1324 p
= strchr_m( username
, *lp_winbind_separator() );
1326 /* code for a DOMAIN\user string */
1329 pw
= Get_Pwnam_alloc( mem_ctx
, domuser
);
1331 /* make sure we get the case of the username correct */
1332 /* work around 'winbind use default domain = yes' */
1334 if ( !strchr_m( pw
->pw_name
, *lp_winbind_separator() ) ) {
1337 /* split the domain and username into 2 strings */
1341 *p_save_username
= talloc_asprintf(mem_ctx
,
1344 *lp_winbind_separator(),
1346 if (!*p_save_username
) {
1351 *p_save_username
= talloc_strdup(mem_ctx
, pw
->pw_name
);
1358 /* setup for lookup of just the username */
1359 /* remember that p and username are overlapping memory */
1362 username
= talloc_strdup(mem_ctx
, p
);
1368 /* just lookup a plain username */
1370 pw
= Get_Pwnam_alloc(mem_ctx
, username
);
1372 /* Create local user if requested but only if winbindd
1373 is not running. We need to protect against cases
1374 where winbindd is failing and then prematurely
1375 creating users in /etc/passwd */
1377 if ( !pw
&& create
&& !winbind_ping() ) {
1378 /* Don't add a machine account. */
1379 if (username
[strlen(username
)-1] == '$')
1382 _smb_create_user(NULL
, username
, NULL
);
1383 pw
= Get_Pwnam_alloc(mem_ctx
, username
);
1386 /* one last check for a valid passwd struct */
1389 *p_save_username
= talloc_strdup(mem_ctx
, pw
->pw_name
);
1394 /***************************************************************************
1395 Make a server_info struct from the info3 returned by a domain logon
1396 ***************************************************************************/
1398 NTSTATUS
make_server_info_info3(TALLOC_CTX
*mem_ctx
,
1399 const char *sent_nt_username
,
1401 struct auth_serversupplied_info
**server_info
,
1402 struct netr_SamInfo3
*info3
)
1404 static const char zeros
[16] = {0, };
1406 NTSTATUS nt_status
= NT_STATUS_OK
;
1407 char *found_username
= NULL
;
1408 const char *nt_domain
;
1409 const char *nt_username
;
1410 struct dom_sid user_sid
;
1411 struct dom_sid group_sid
;
1412 bool username_was_mapped
;
1414 struct auth_serversupplied_info
*result
;
1417 Here is where we should check the list of
1418 trusted domains, and verify that the SID
1422 if (!sid_compose(&user_sid
, info3
->base
.domain_sid
, info3
->base
.rid
)) {
1423 return NT_STATUS_INVALID_PARAMETER
;
1426 if (!sid_compose(&group_sid
, info3
->base
.domain_sid
,
1427 info3
->base
.primary_gid
)) {
1428 return NT_STATUS_INVALID_PARAMETER
;
1431 nt_username
= talloc_strdup(mem_ctx
, info3
->base
.account_name
.string
);
1433 /* If the server didn't give us one, just use the one we sent
1435 nt_username
= sent_nt_username
;
1438 nt_domain
= talloc_strdup(mem_ctx
, info3
->base
.logon_domain
.string
);
1440 /* If the server didn't give us one, just use the one we sent
1445 /* If getpwnam() fails try the add user script (2.2.x behavior).
1447 We use the _unmapped_ username here in an attempt to provide
1448 consistent username mapping behavior between kerberos and NTLM[SSP]
1449 authentication in domain mode security. I.E. Username mapping
1450 should be applied to the fully qualified username
1451 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1452 called map_username() unnecessarily in make_user_info_map() but
1453 that is how the current code is designed. Making the change here
1454 is the least disruptive place. -- jerry */
1456 /* this call will try to create the user if necessary */
1458 nt_status
= check_account(mem_ctx
, nt_domain
, sent_nt_username
,
1459 &found_username
, &pwd
,
1460 &username_was_mapped
);
1462 if (!NT_STATUS_IS_OK(nt_status
)) {
1466 result
= make_server_info(NULL
);
1467 if (result
== NULL
) {
1468 DEBUG(4, ("make_server_info failed!\n"));
1469 return NT_STATUS_NO_MEMORY
;
1472 result
->unix_name
= talloc_strdup(result
, found_username
);
1474 /* copy in the info3 */
1475 result
->info3
= copy_netr_SamInfo3(result
, info3
);
1476 if (result
->info3
== NULL
) {
1477 TALLOC_FREE(result
);
1478 return NT_STATUS_NO_MEMORY
;
1481 /* Fill in the unix info we found on the way */
1483 result
->utok
.uid
= pwd
->pw_uid
;
1484 result
->utok
.gid
= pwd
->pw_gid
;
1486 /* ensure we are never given NULL session keys */
1488 if (memcmp(info3
->base
.key
.key
, zeros
, sizeof(zeros
)) == 0) {
1489 result
->session_key
= data_blob_null
;
1491 result
->session_key
= data_blob_talloc(
1492 result
, info3
->base
.key
.key
,
1493 sizeof(info3
->base
.key
.key
));
1496 if (memcmp(info3
->base
.LMSessKey
.key
, zeros
, 8) == 0) {
1497 result
->lm_session_key
= data_blob_null
;
1499 result
->lm_session_key
= data_blob_talloc(
1500 result
, info3
->base
.LMSessKey
.key
,
1501 sizeof(info3
->base
.LMSessKey
.key
));
1504 result
->nss_token
|= username_was_mapped
;
1506 result
->guest
= (info3
->base
.user_flags
& NETLOGON_GUEST
);
1508 *server_info
= result
;
1510 return NT_STATUS_OK
;
1513 /*****************************************************************************
1514 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1515 ******************************************************************************/
1517 NTSTATUS
make_server_info_wbcAuthUserInfo(TALLOC_CTX
*mem_ctx
,
1518 const char *sent_nt_username
,
1520 const struct wbcAuthUserInfo
*info
,
1521 struct auth_serversupplied_info
**server_info
)
1523 struct netr_SamInfo3
*info3
;
1525 info3
= wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx
, info
);
1527 return NT_STATUS_NO_MEMORY
;
1530 return make_server_info_info3(mem_ctx
,
1531 sent_nt_username
, domain
,
1532 server_info
, info3
);
1536 * Verify whether or not given domain is trusted.
1538 * @param domain_name name of the domain to be verified
1539 * @return true if domain is one of the trusted ones or
1540 * false if otherwise
1543 bool is_trusted_domain(const char* dom_name
)
1545 struct dom_sid trustdom_sid
;
1548 /* no trusted domains for a standalone server */
1550 if ( lp_server_role() == ROLE_STANDALONE
)
1553 if (dom_name
== NULL
|| dom_name
[0] == '\0') {
1557 if (strequal(dom_name
, get_global_sam_name())) {
1561 /* if we are a DC, then check for a direct trust relationships */
1565 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1566 "[%s]\n", dom_name
));
1567 ret
= pdb_get_trusteddom_pw(dom_name
, NULL
, NULL
, NULL
);
1575 /* If winbind is around, ask it */
1577 result
= wb_is_trusted_domain(dom_name
);
1579 if (result
== WBC_ERR_SUCCESS
) {
1583 if (result
== WBC_ERR_DOMAIN_NOT_FOUND
) {
1584 /* winbind could not find the domain */
1588 /* The only other possible result is that winbind is not up
1589 and running. We need to update the trustdom_cache
1592 update_trustdom_cache();
1595 /* now the trustdom cache should be available a DC could still
1596 * have a transitive trust so fall back to the cache of trusted
1597 * domains (like a domain member would use */
1599 if ( trustdom_cache_fetch(dom_name
, &trustdom_sid
) ) {
1609 on a logon error possibly map the error to success if "map to guest"
1612 NTSTATUS
do_map_to_guest_server_info(NTSTATUS status
,
1613 struct auth_serversupplied_info
**server_info
,
1614 const char *user
, const char *domain
)
1616 user
= user
? user
: "";
1617 domain
= domain
? domain
: "";
1619 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_SUCH_USER
)) {
1620 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER
) ||
1621 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
)) {
1622 DEBUG(3,("No such user %s [%s] - using guest account\n",
1624 return make_server_info_guest(NULL
, server_info
);
1626 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_WRONG_PASSWORD
)) {
1627 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
) {
1628 DEBUG(3,("Registered username %s for guest access\n",
1630 return make_server_info_guest(NULL
, server_info
);
1638 Extract session key from a session info and return it in a blob
1639 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
1641 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
1642 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
1644 Note that returned session_key is referencing the original key, it is supposed to be
1645 short-lived. If original session_info->session_key is gone, the reference will be broken.
1647 NTSTATUS
session_extract_session_key(const struct auth_session_info
*session_info
, DATA_BLOB
*session_key
, enum session_key_use_intent intent
)
1650 if (session_key
== NULL
|| session_info
== NULL
) {
1651 return NT_STATUS_INVALID_PARAMETER
;
1654 if (session_info
->session_key
.length
== 0) {
1655 return NT_STATUS_NO_USER_SESSION_KEY
;
1658 *session_key
= session_info
->session_key
;
1659 if (intent
== KEY_USE_16BYTES
) {
1660 session_key
->length
= MIN(session_info
->session_key
.length
, 16);
1662 return NT_STATUS_OK
;