libcli/smb: prepare smb2_signing_[de|en]crypt_pdu() to support multiple ciphers
[Samba.git] / source3 / auth / auth_util.c
blob2986fb4372f34235ea1cbd254f15bdd48a709d02
1 /*
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/>.
24 #include "includes.h"
25 #include "auth.h"
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"
32 #include "passdb.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"
38 #undef DBGC_CLASS
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();
48 char *add_script;
49 int ret;
51 add_script = lp_add_user_script(ctx);
52 if (!add_script || !*add_script) {
53 return -1;
55 add_script = talloc_all_string_sub(ctx,
56 add_script,
57 "%u",
58 unix_username);
59 if (!add_script) {
60 return -1;
62 if (domain) {
63 add_script = talloc_all_string_sub(ctx,
64 add_script,
65 "%D",
66 domain);
67 if (!add_script) {
68 return -1;
71 if (homedir) {
72 add_script = talloc_all_string_sub(ctx,
73 add_script,
74 "%H",
75 homedir);
76 if (!add_script) {
77 return -1;
80 ret = smbrun(add_script,NULL);
81 flush_pwnam_cache();
82 DEBUG(ret ? 0 : 3,
83 ("smb_create_user: Running the command `%s' gave %d\n",
84 add_script,ret));
85 return ret;
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,
94 const char *smb_name,
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)
105 const char *domain;
106 NTSTATUS result;
107 bool was_mapped;
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();
134 else
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;
156 return result;
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,
172 int lm_pwd_len,
173 const uchar *nt_network_pwd,
174 int nt_pwd_len)
176 bool ret;
177 NTSTATUS status;
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,
183 workstation_name,
184 remote_address,
185 lm_pwd_len ? &lm_blob : NULL,
186 nt_pwd_len ? &nt_blob : NULL,
187 NULL, NULL, 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);
197 return ret;
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,
212 const uchar chal[8],
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,
229 local_lm_response);
231 if (nt_interactive_pwd)
232 SMBOWFencrypt(nt_pwd.hash, chal,
233 local_nt_response);
236 bool ret;
237 NTSTATUS nt_status;
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(
252 mem_ctx,
253 user_info,
254 smb_name, client_domain, workstation_name,
255 remote_address,
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);
269 return ret;
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,
283 const uint8 chal[8],
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 "
296 "format.\n"));
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);
305 #endif
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
312 case insensitive */
313 local_nt_blob = data_blob_null;
314 } else {
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) {
323 return false;
326 ret = make_user_info(mem_ctx,
327 user_info, smb_name, smb_name, client_domain, client_domain,
328 get_remote_machine_name(),
329 remote_address,
330 local_lm_blob.data ? &local_lm_blob : NULL,
331 local_nt_blob.data ? &local_nt_blob : NULL,
332 NULL, 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(),
360 remote_address,
361 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
362 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
363 NULL, NULL, 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)
375 NTSTATUS nt_status;
377 nt_status = make_user_info(mem_ctx,
378 user_info,
379 "","",
380 "","",
381 "",
382 remote_address,
383 NULL, NULL,
384 NULL, NULL,
385 NULL,
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();
394 char *command;
395 char *group_sidstr;
396 size_t i;
398 if ((lp_log_nt_token_command(frame) == NULL) ||
399 (strlen(lp_log_nt_token_command(frame)) == 0)) {
400 TALLOC_FREE(frame);
401 return NT_STATUS_OK;
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) {
417 TALLOC_FREE(frame);
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"));
424 TALLOC_FREE(frame);
425 return NT_STATUS_ACCESS_DENIED;
428 TALLOC_FREE(frame);
429 return NT_STATUS_OK;
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;
444 NTSTATUS status;
445 size_t i;
446 struct dom_sid tmp_sid;
447 struct auth_session_info *session_info;
448 struct unixid *ids;
449 fstring tmp;
451 /* Ensure we can't possible take a code path leading to a
452 * null defref. */
453 if (!server_info) {
454 return NT_STATUS_LOGON_FAILURE;
457 session_info = talloc_zero(mem_ctx, struct auth_session_info);
458 if (!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);
488 if (session_key) {
489 data_blob_free(&session_info->session_key);
490 session_info->session_key = data_blob_talloc(session_info,
491 session_key->data,
492 session_key->length);
493 if (!session_info->session_key.data && session_key->length) {
494 return NT_STATUS_NO_MEMORY;
496 } else {
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);
508 return status;
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);
527 } else {
528 session_info->unix_token->groups = NULL;
531 *session_info_out = session_info;
532 return NT_STATUS_OK;
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,
546 server_info->guest,
547 &session_info->unix_token->uid,
548 &session_info->unix_token->gid,
549 &found_username,
550 &session_info->security_token);
551 if (NT_STATUS_IS_OK(status)) {
552 session_info->unix_info->unix_name = found_username;
554 } else {
555 status = create_local_nt_token_from_info3(session_info,
556 server_info->guest,
557 server_info->info3,
558 &server_info->extra,
559 &session_info->security_token);
562 if (!NT_STATUS_IS_OK(status)) {
563 return 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,
574 t->num_sids);
575 if (ids == NULL) {
576 return NT_STATUS_NO_MEMORY;
579 if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
580 TALLOC_FREE(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) {
587 continue;
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, "
593 "ignoring it\n",
594 sid_string_dbg(&t->sids[i])));
595 continue;
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
614 * the nt token.
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)) {
639 return status;
642 *session_info_out = session_info;
643 return NT_STATUS_OK;
646 /***************************************************************************
647 Make (and fill) a server_info struct from a 'struct passwd' by conversion
648 to a struct samu
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)
656 NTSTATUS status;
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;
668 goto done;
671 status = passwd_to_SamInfo3(result,
672 unix_username,
673 pwd,
674 &result->info3);
675 if (!NT_STATUS_IS_OK(status)) {
676 goto done;
679 result->unix_name = talloc_strdup(result, unix_username);
680 if (result->unix_name == NULL) {
681 status = NT_STATUS_NO_MEMORY;
682 goto done;
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;
690 done:
691 talloc_free(tmp_ctx);
693 return status;
696 static NTSTATUS get_system_info3(TALLOC_CTX *mem_ctx,
697 struct netr_SamInfo3 *info3)
699 NTSTATUS status;
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,
718 &info3->base.rid);
719 TALLOC_FREE(system_sid);
720 if (!NT_STATUS_IS_OK(status)) {
721 return status;
724 /* Primary gid is the same */
725 info3->base.primary_gid = info3->base.rid;
727 return NT_STATUS_OK;
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;
735 struct passwd *pwd;
736 const char *tmp;
738 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
739 if (pwd == NULL) {
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);
747 if (tmp == NULL) {
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());
754 if (tmp == NULL) {
755 return NT_STATUS_NO_MEMORY;
757 init_lsa_StringLarge(&info3->base.logon_domain, tmp);
759 /* Domain sid */
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;
767 /* Guest rid */
768 info3->base.rid = DOMAIN_RID_GUEST;
770 /* Primary gid */
771 info3->base.primary_gid = DOMAIN_RID_GUESTS;
773 /* Set as guest */
774 info3->base.user_flags = NETLOGON_GUEST;
776 TALLOC_FREE(pwd);
777 return NT_STATUS_OK;
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
788 left as-is for now.
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;
797 TALLOC_CTX *tmp_ctx;
798 NTSTATUS status;
800 tmp_ctx = talloc_stackframe();
801 if (tmp_ctx == NULL) {
802 return NT_STATUS_NO_MEMORY;
805 ZERO_STRUCT(info3);
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",
810 nt_errstr(status)));
811 goto done;
814 status = make_server_info_info3(tmp_ctx,
815 guest_account,
816 domain,
817 server_info,
818 &info3);
819 if (!NT_STATUS_IS_OK(status)) {
820 DEBUG(0, ("make_server_info_info3 failed with %s\n",
821 nt_errstr(status)));
822 goto done;
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,
832 session_info);
833 if (!NT_STATUS_IS_OK(status)) {
834 DEBUG(0, ("create_local_token failed: %s\n",
835 nt_errstr(status)));
836 goto done;
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
842 all zeros! */
843 (*session_info)->session_key = data_blob(zeros, sizeof(zeros));
845 status = NT_STATUS_OK;
846 done:
847 TALLOC_FREE(tmp_ctx);
848 return status;
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)
859 NTSTATUS status;
860 struct auth_serversupplied_info *server_info;
861 TALLOC_CTX *tmp_ctx;
863 tmp_ctx = talloc_stackframe();
864 if (tmp_ctx == NULL) {
865 return NT_STATUS_NO_MEMORY;
868 server_info = make_server_info(tmp_ctx);
869 if (!server_info) {
870 status = NT_STATUS_NO_MEMORY;
871 DEBUG(0, ("failed making server_info\n"));
872 goto done;
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"));
879 goto done;
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",
885 nt_errstr(status)));
886 goto done;
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"));
898 goto done;
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"));
905 goto done;
908 status = add_sid_to_array_unique(server_info->security_token->sids,
909 &global_sid_System,
910 &server_info->security_token->sids,
911 &server_info->security_token->num_sids);
912 if (!NT_STATUS_IS_OK(status)) {
913 goto done;
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",
925 nt_errstr(status)));
926 goto done;
929 talloc_steal(mem_ctx, *session_info);
931 done:
932 TALLOC_FREE(tmp_ctx);
933 return status;
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,
944 bool is_guest,
945 struct auth_session_info **session_info)
947 struct passwd *pwd;
948 NTSTATUS status;
949 struct auth_serversupplied_info *result;
950 TALLOC_CTX *tmp_ctx;
952 tmp_ctx = talloc_stackframe();
953 if (tmp_ctx == NULL) {
954 return NT_STATUS_NO_MEMORY;
957 pwd = Get_Pwnam_alloc(tmp_ctx, username);
958 if (pwd == NULL) {
959 status = NT_STATUS_NO_SUCH_USER;
960 goto done;
963 status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
964 if (!NT_STATUS_IS_OK(status)) {
965 goto done;
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,
973 result,
974 NULL,
975 pwd->pw_name,
976 session_info);
978 done:
979 talloc_free(tmp_ctx);
981 return status;
984 /* This function MUST only used to create the cached server_info for
985 * guest.
987 * This is a lossy conversion. Variables known to be lost so far
988 * include:
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);
1004 if (dst == NULL) {
1005 return NULL;
1008 /* This element must be provided to convert back to an auth_serversupplied_info */
1009 SMB_ASSERT(src->unix_info);
1011 dst->guest = true;
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);
1026 } else {
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) {
1037 TALLOC_FREE(dst);
1038 return NULL;
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);
1050 if (!dst->info3) {
1051 TALLOC_FREE(dst);
1052 return NULL;
1055 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1056 if (!dst->unix_name) {
1057 TALLOC_FREE(dst);
1058 return NULL;
1061 return dst;
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;
1068 DATA_BLOB blob;
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)));
1077 return NULL;
1080 dst = talloc(mem_ctx, struct auth_session_info);
1081 if (dst == NULL) {
1082 DEBUG(0, ("talloc failed\n"));
1083 TALLOC_FREE(blob.data);
1084 return NULL;
1087 ndr_err = ndr_pull_struct_blob(
1088 &blob, dst, dst,
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)));
1095 TALLOC_FREE(dst);
1096 return NULL;
1099 return dst;
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)
1125 return true;
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)
1168 return system_info;
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,
1195 "%s%c%s",
1196 domain,
1197 *lp_winbind_separator(),
1198 lower_username);
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);
1206 if (!dom_user) {
1207 return NT_STATUS_NO_MEMORY;
1210 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
1211 if (!passwd) {
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;
1221 *pwd = passwd;
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?
1227 --jerry */
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;
1244 char *p = 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);
1255 if (!username) {
1256 return NULL;
1259 p = strchr_m( username, *lp_winbind_separator() );
1261 /* code for a DOMAIN\user string */
1263 if ( p ) {
1264 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1265 if ( pw ) {
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() ) ) {
1271 char *domain;
1273 /* split the domain and username into 2 strings */
1274 *p = '\0';
1275 domain = username;
1277 *p_save_username = talloc_asprintf(mem_ctx,
1278 "%s%c%s",
1279 domain,
1280 *lp_winbind_separator(),
1281 pw->pw_name);
1282 if (!*p_save_username) {
1283 TALLOC_FREE(pw);
1284 return NULL;
1286 } else {
1287 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1290 /* whew -- done! */
1291 return pw;
1294 /* setup for lookup of just the username */
1295 /* remember that p and username are overlapping memory */
1297 p++;
1298 username = talloc_strdup(mem_ctx, p);
1299 if (!username) {
1300 return NULL;
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] == '$')
1316 return NULL;
1318 _smb_create_user(NULL, username, NULL);
1319 pw = Get_Pwnam_alloc(mem_ctx, username);
1322 /* one last check for a valid passwd struct */
1324 if (pw) {
1325 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1327 return pw;
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,
1336 const char *domain,
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;
1349 struct passwd *pwd;
1350 struct auth_serversupplied_info *result;
1353 Here is where we should check the list of
1354 trusted domains, and verify that the SID
1355 matches.
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);
1368 if (!nt_username) {
1369 /* If the server didn't give us one, just use the one we sent
1370 * them */
1371 nt_username = sent_nt_username;
1374 nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
1375 if (!nt_domain) {
1376 /* If the server didn't give us one, just use the one we sent
1377 * them */
1378 nt_domain = domain;
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)) {
1399 return 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;
1426 } else {
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;
1434 } else {
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,
1455 const char *domain,
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);
1462 if (!info3) {
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;
1482 bool ret;
1484 /* no trusted domains for a standalone server */
1486 if ( lp_server_role() == ROLE_STANDALONE )
1487 return false;
1489 if (dom_name == NULL || dom_name[0] == '\0') {
1490 return false;
1493 if (strequal(dom_name, get_global_sam_name())) {
1494 return false;
1497 /* if we are a DC, then check for a direct trust relationships */
1499 if ( IS_DC ) {
1500 become_root();
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);
1504 unbecome_root();
1505 if (ret)
1506 return true;
1508 else {
1509 wbcErr result;
1511 /* If winbind is around, ask it */
1513 result = wb_is_trusted_domain(dom_name);
1515 if (result == WBC_ERR_SUCCESS) {
1516 return true;
1519 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1520 /* winbind could not find the domain */
1521 return false;
1524 /* The only other possible result is that winbind is not up
1525 and running. We need to update the trustdom_cache
1526 ourselves */
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) ) {
1536 return true;
1539 return false;
1545 on a logon error possibly map the error to success if "map to guest"
1546 is set approriately
1548 NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
1549 NTSTATUS status,
1550 const char *user,
1551 const char *domain,
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",
1561 user, domain));
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",
1567 user));
1568 return make_server_info_guest(mem_ctx, server_info);
1572 return status;
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;