s3:auth: remove "map untrusted to domain" handling
[Samba.git] / source3 / auth / auth_util.c
blobfbc36423e2b33fcce4aea03d87865ad352ca0e49
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 "lib/util_unixsids.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../lib/crypto/arcfour.h"
29 #include "rpc_client/init_lsa.h"
30 #include "../libcli/security/security.h"
31 #include "../lib/util/util_pw.h"
32 #include "lib/winbind_util.h"
33 #include "passdb.h"
34 #include "../librpc/gen_ndr/ndr_auth.h"
35 #include "../auth/auth_sam_reply.h"
36 #include "../librpc/gen_ndr/idmap.h"
37 #include "lib/param/loadparm.h"
38 #include "../lib/tsocket/tsocket.h"
40 #undef DBGC_CLASS
41 #define DBGC_CLASS DBGC_AUTH
43 /****************************************************************************
44 Create a UNIX user on demand.
45 ****************************************************************************/
47 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
49 TALLOC_CTX *ctx = talloc_tos();
50 char *add_script;
51 int ret;
53 add_script = lp_add_user_script(ctx);
54 if (!add_script || !*add_script) {
55 return -1;
57 add_script = talloc_all_string_sub(ctx,
58 add_script,
59 "%u",
60 unix_username);
61 if (!add_script) {
62 return -1;
64 if (domain) {
65 add_script = talloc_all_string_sub(ctx,
66 add_script,
67 "%D",
68 domain);
69 if (!add_script) {
70 return -1;
73 if (homedir) {
74 add_script = talloc_all_string_sub(ctx,
75 add_script,
76 "%H",
77 homedir);
78 if (!add_script) {
79 return -1;
82 ret = smbrun(add_script, NULL, NULL);
83 flush_pwnam_cache();
84 DEBUG(ret ? 0 : 3,
85 ("smb_create_user: Running the command `%s' gave %d\n",
86 add_script,ret));
87 return ret;
90 /****************************************************************************
91 Create an auth_usersupplied_data structure after appropriate mapping.
92 ****************************************************************************/
94 NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
95 struct auth_usersupplied_info **user_info,
96 const char *smb_name,
97 const char *client_domain,
98 const char *workstation_name,
99 const struct tsocket_address *remote_address,
100 const struct tsocket_address *local_address,
101 const char *service_description,
102 const DATA_BLOB *lm_pwd,
103 const DATA_BLOB *nt_pwd,
104 const struct samr_Password *lm_interactive_pwd,
105 const struct samr_Password *nt_interactive_pwd,
106 const char *plaintext,
107 enum auth_password_state password_state)
109 const char *domain;
110 NTSTATUS result;
111 bool was_mapped;
112 char *internal_username = NULL;
114 was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
115 if (!internal_username) {
116 return NT_STATUS_NO_MEMORY;
119 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
120 client_domain, smb_name, workstation_name));
123 * We let the auth stack canonicalize, username
124 * and domain.
126 domain = client_domain;
128 result = make_user_info(mem_ctx, user_info, smb_name, internal_username,
129 client_domain, domain, workstation_name,
130 remote_address, local_address,
131 service_description, lm_pwd, nt_pwd,
132 lm_interactive_pwd, nt_interactive_pwd,
133 plaintext, password_state);
134 if (NT_STATUS_IS_OK(result)) {
135 /* We have tried mapping */
136 (*user_info)->mapped_state = true;
137 /* did we actually map the user to a different name? */
138 (*user_info)->was_mapped = was_mapped;
140 return result;
143 /****************************************************************************
144 Create an auth_usersupplied_data, making the DATA_BLOBs here.
145 Decrypt and encrypt the passwords.
146 ****************************************************************************/
148 bool make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
149 struct auth_usersupplied_info **user_info,
150 const char *smb_name,
151 const char *client_domain,
152 const char *workstation_name,
153 const struct tsocket_address *remote_address,
154 const struct tsocket_address *local_address,
155 uint32_t logon_parameters,
156 const uchar *lm_network_pwd,
157 int lm_pwd_len,
158 const uchar *nt_network_pwd,
159 int nt_pwd_len)
161 bool ret;
162 NTSTATUS status;
163 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
164 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
166 status = make_user_info_map(mem_ctx, user_info,
167 smb_name, client_domain,
168 workstation_name,
169 remote_address,
170 local_address,
171 "SamLogon",
172 lm_pwd_len ? &lm_blob : NULL,
173 nt_pwd_len ? &nt_blob : NULL,
174 NULL, NULL, NULL,
175 AUTH_PASSWORD_RESPONSE);
177 if (NT_STATUS_IS_OK(status)) {
178 (*user_info)->logon_parameters = logon_parameters;
180 ret = NT_STATUS_IS_OK(status) ? true : false;
182 data_blob_free(&lm_blob);
183 data_blob_free(&nt_blob);
184 return ret;
187 /****************************************************************************
188 Create an auth_usersupplied_data, making the DATA_BLOBs here.
189 Decrypt and encrypt the passwords.
190 ****************************************************************************/
192 bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
193 struct auth_usersupplied_info **user_info,
194 const char *smb_name,
195 const char *client_domain,
196 const char *workstation_name,
197 const struct tsocket_address *remote_address,
198 const struct tsocket_address *local_address,
199 uint32_t logon_parameters,
200 const uchar chal[8],
201 const uchar lm_interactive_pwd[16],
202 const uchar nt_interactive_pwd[16])
204 struct samr_Password lm_pwd;
205 struct samr_Password nt_pwd;
206 unsigned char local_lm_response[24];
207 unsigned char local_nt_response[24];
209 if (lm_interactive_pwd)
210 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
212 if (nt_interactive_pwd)
213 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
215 if (lm_interactive_pwd)
216 SMBOWFencrypt(lm_pwd.hash, chal,
217 local_lm_response);
219 if (nt_interactive_pwd)
220 SMBOWFencrypt(nt_pwd.hash, chal,
221 local_nt_response);
224 bool ret;
225 NTSTATUS nt_status;
226 DATA_BLOB local_lm_blob = data_blob_null;
227 DATA_BLOB local_nt_blob = data_blob_null;
229 if (lm_interactive_pwd) {
230 local_lm_blob = data_blob(local_lm_response,
231 sizeof(local_lm_response));
234 if (nt_interactive_pwd) {
235 local_nt_blob = data_blob(local_nt_response,
236 sizeof(local_nt_response));
239 nt_status = make_user_info_map(
240 mem_ctx,
241 user_info,
242 smb_name, client_domain, workstation_name,
243 remote_address,
244 local_address,
245 "SamLogon",
246 lm_interactive_pwd ? &local_lm_blob : NULL,
247 nt_interactive_pwd ? &local_nt_blob : NULL,
248 lm_interactive_pwd ? &lm_pwd : NULL,
249 nt_interactive_pwd ? &nt_pwd : NULL,
250 NULL, AUTH_PASSWORD_HASH);
252 if (NT_STATUS_IS_OK(nt_status)) {
253 (*user_info)->logon_parameters = logon_parameters;
256 ret = NT_STATUS_IS_OK(nt_status) ? true : false;
257 data_blob_free(&local_lm_blob);
258 data_blob_free(&local_nt_blob);
259 return ret;
264 /****************************************************************************
265 Create an auth_usersupplied_data structure
266 ****************************************************************************/
268 bool make_user_info_for_reply(TALLOC_CTX *mem_ctx,
269 struct auth_usersupplied_info **user_info,
270 const char *smb_name,
271 const char *client_domain,
272 const struct tsocket_address *remote_address,
273 const struct tsocket_address *local_address,
274 const char *service_description,
275 const uint8_t chal[8],
276 DATA_BLOB plaintext_password)
279 DATA_BLOB local_lm_blob;
280 DATA_BLOB local_nt_blob;
281 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
282 char *plaintext_password_string;
284 * Not encrypted - do so.
287 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
288 "format.\n"));
289 if (plaintext_password.data && plaintext_password.length) {
290 unsigned char local_lm_response[24];
292 #ifdef DEBUG_PASSWORD
293 DEBUG(10,("Unencrypted password (len %d):\n",
294 (int)plaintext_password.length));
295 dump_data(100, plaintext_password.data,
296 plaintext_password.length);
297 #endif
299 SMBencrypt( (const char *)plaintext_password.data,
300 (const uchar*)chal, local_lm_response);
301 local_lm_blob = data_blob(local_lm_response, 24);
303 /* We can't do an NT hash here, as the password needs to be
304 case insensitive */
305 local_nt_blob = data_blob_null;
306 } else {
307 local_lm_blob = data_blob_null;
308 local_nt_blob = data_blob_null;
311 plaintext_password_string = talloc_strndup(talloc_tos(),
312 (const char *)plaintext_password.data,
313 plaintext_password.length);
314 if (!plaintext_password_string) {
315 return false;
318 ret = make_user_info(mem_ctx,
319 user_info, smb_name, smb_name, client_domain, client_domain,
320 get_remote_machine_name(),
321 remote_address,
322 local_address,
323 service_description,
324 local_lm_blob.data ? &local_lm_blob : NULL,
325 local_nt_blob.data ? &local_nt_blob : NULL,
326 NULL, NULL,
327 plaintext_password_string,
328 AUTH_PASSWORD_PLAIN);
330 if (plaintext_password_string) {
331 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
332 talloc_free(plaintext_password_string);
335 data_blob_free(&local_lm_blob);
336 return NT_STATUS_IS_OK(ret) ? true : false;
339 /****************************************************************************
340 Create an auth_usersupplied_data structure
341 ****************************************************************************/
343 NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
344 struct auth_usersupplied_info **user_info,
345 const char *smb_name,
346 const char *client_domain,
347 const struct tsocket_address *remote_address,
348 const struct tsocket_address *local_address,
349 const char *service_description,
350 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
352 bool allow_raw = lp_raw_ntlmv2_auth();
354 if (!allow_raw && nt_resp.length >= 48) {
356 * NTLMv2_RESPONSE has at least 48 bytes
357 * and should only be supported via NTLMSSP.
359 DEBUG(2,("Rejecting raw NTLMv2 authentication with "
360 "user [%s\\%s] from[%s]\n",
361 client_domain, smb_name,
362 tsocket_address_string(remote_address, mem_ctx)));
363 return NT_STATUS_INVALID_PARAMETER;
366 return make_user_info(mem_ctx,
367 user_info, smb_name, smb_name,
368 client_domain, client_domain,
369 get_remote_machine_name(),
370 remote_address,
371 local_address,
372 service_description,
373 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
374 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
375 NULL, NULL, NULL,
376 AUTH_PASSWORD_RESPONSE);
379 /****************************************************************************
380 Create a guest user_info blob, for anonymous authentication.
381 ****************************************************************************/
383 bool make_user_info_guest(TALLOC_CTX *mem_ctx,
384 const struct tsocket_address *remote_address,
385 const struct tsocket_address *local_address,
386 const char *service_description,
387 struct auth_usersupplied_info **user_info)
389 NTSTATUS nt_status;
391 nt_status = make_user_info(mem_ctx,
392 user_info,
393 "","",
394 "","",
395 "",
396 remote_address,
397 local_address,
398 service_description,
399 NULL, NULL,
400 NULL, NULL,
401 NULL,
402 AUTH_PASSWORD_RESPONSE);
404 return NT_STATUS_IS_OK(nt_status) ? true : false;
407 static NTSTATUS log_nt_token(struct security_token *token)
409 TALLOC_CTX *frame = talloc_stackframe();
410 char *command;
411 char *group_sidstr;
412 size_t i;
414 if ((lp_log_nt_token_command(frame) == NULL) ||
415 (strlen(lp_log_nt_token_command(frame)) == 0)) {
416 TALLOC_FREE(frame);
417 return NT_STATUS_OK;
420 group_sidstr = talloc_strdup(frame, "");
421 for (i=1; i<token->num_sids; i++) {
422 group_sidstr = talloc_asprintf(
423 frame, "%s %s", group_sidstr,
424 sid_string_talloc(frame, &token->sids[i]));
427 command = talloc_string_sub(
428 frame, lp_log_nt_token_command(frame),
429 "%s", sid_string_talloc(frame, &token->sids[0]));
430 command = talloc_string_sub(frame, command, "%t", group_sidstr);
432 if (command == NULL) {
433 TALLOC_FREE(frame);
434 return NT_STATUS_NO_MEMORY;
437 DEBUG(8, ("running command: [%s]\n", command));
438 if (smbrun(command, NULL, NULL) != 0) {
439 DEBUG(0, ("Could not log NT token\n"));
440 TALLOC_FREE(frame);
441 return NT_STATUS_ACCESS_DENIED;
444 TALLOC_FREE(frame);
445 return NT_STATUS_OK;
449 * Create the token to use from server_info->info3 and
450 * server_info->sids (the info3/sam groups). Find the unix gids.
453 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
454 const struct auth_serversupplied_info *server_info,
455 DATA_BLOB *session_key,
456 const char *smb_username, /* for ->sanitized_username, for %U subs */
457 struct auth_session_info **session_info_out)
459 struct security_token *t;
460 NTSTATUS status;
461 size_t i;
462 struct dom_sid tmp_sid;
463 struct auth_session_info *session_info;
464 struct unixid *ids;
465 fstring tmp;
467 /* Ensure we can't possible take a code path leading to a
468 * null defref. */
469 if (!server_info) {
470 return NT_STATUS_LOGON_FAILURE;
473 session_info = talloc_zero(mem_ctx, struct auth_session_info);
474 if (!session_info) {
475 return NT_STATUS_NO_MEMORY;
478 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
479 if (!session_info->unix_token) {
480 TALLOC_FREE(session_info);
481 return NT_STATUS_NO_MEMORY;
484 session_info->unix_token->uid = server_info->utok.uid;
485 session_info->unix_token->gid = server_info->utok.gid;
487 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
488 if (!session_info->unix_info) {
489 TALLOC_FREE(session_info);
490 return NT_STATUS_NO_MEMORY;
493 session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
494 if (!session_info->unix_info->unix_name) {
495 TALLOC_FREE(session_info);
496 return NT_STATUS_NO_MEMORY;
499 /* This is a potentially untrusted username for use in %U */
500 alpha_strcpy(tmp, smb_username, ". _-$", sizeof(tmp));
501 session_info->unix_info->sanitized_username =
502 talloc_strdup(session_info->unix_info, tmp);
504 if (session_key) {
505 data_blob_free(&session_info->session_key);
506 session_info->session_key = data_blob_talloc(session_info,
507 session_key->data,
508 session_key->length);
509 if (!session_info->session_key.data && session_key->length) {
510 return NT_STATUS_NO_MEMORY;
512 } else {
513 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
514 server_info->session_key.length);
517 /* We need to populate session_info->info with the information found in server_info->info3 */
518 status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
519 server_info->guest == false,
520 &session_info->info);
521 if (!NT_STATUS_IS_OK(status)) {
522 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
523 TALLOC_FREE(session_info);
524 return status;
527 if (server_info->security_token) {
528 /* Just copy the token, it has already been finalised
529 * (nasty hack to support a cached guest/system session_info
532 session_info->security_token = dup_nt_token(session_info, server_info->security_token);
533 if (!session_info->security_token) {
534 TALLOC_FREE(session_info);
535 return NT_STATUS_NO_MEMORY;
538 session_info->unix_token->ngroups = server_info->utok.ngroups;
539 if (server_info->utok.ngroups != 0) {
540 session_info->unix_token->groups = (gid_t *)talloc_memdup(
541 session_info->unix_token, server_info->utok.groups,
542 sizeof(gid_t)*session_info->unix_token->ngroups);
543 } else {
544 session_info->unix_token->groups = NULL;
547 *session_info_out = session_info;
548 return NT_STATUS_OK;
552 * If winbind is not around, we can not make much use of the SIDs the
553 * domain controller provided us with. Likewise if the user name was
554 * mapped to some local unix user.
557 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
558 (server_info->nss_token)) {
559 char *found_username = NULL;
560 status = create_token_from_username(session_info,
561 server_info->unix_name,
562 server_info->guest,
563 &session_info->unix_token->uid,
564 &session_info->unix_token->gid,
565 &found_username,
566 &session_info->security_token);
567 if (NT_STATUS_IS_OK(status)) {
568 session_info->unix_info->unix_name = found_username;
570 } else {
571 status = create_local_nt_token_from_info3(session_info,
572 server_info->guest,
573 server_info->info3,
574 &server_info->extra,
575 &session_info->security_token);
578 if (!NT_STATUS_IS_OK(status)) {
579 return status;
582 /* Convert the SIDs to gids. */
584 session_info->unix_token->ngroups = 0;
585 session_info->unix_token->groups = NULL;
587 t = session_info->security_token;
589 ids = talloc_array(talloc_tos(), struct unixid,
590 t->num_sids);
591 if (ids == NULL) {
592 return NT_STATUS_NO_MEMORY;
595 if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
596 TALLOC_FREE(ids);
597 return NT_STATUS_NO_MEMORY;
600 for (i=0; i<t->num_sids; i++) {
602 if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
603 continue;
606 if (ids[i].type != ID_TYPE_GID &&
607 ids[i].type != ID_TYPE_BOTH) {
608 DEBUG(10, ("Could not convert SID %s to gid, "
609 "ignoring it\n",
610 sid_string_dbg(&t->sids[i])));
611 continue;
613 if (!add_gid_to_array_unique(session_info->unix_token,
614 ids[i].id,
615 &session_info->unix_token->groups,
616 &session_info->unix_token->ngroups)) {
617 return NT_STATUS_NO_MEMORY;
622 * Add the "Unix Group" SID for each gid to catch mapped groups
623 * and their Unix equivalent. This is to solve the backwards
624 * compatibility problem of 'valid users = +ntadmin' where
625 * ntadmin has been paired with "Domain Admins" in the group
626 * mapping table. Otherwise smb.conf would need to be changed
627 * to 'valid user = "Domain Admins"'. --jerry
629 * For consistency we also add the "Unix User" SID,
630 * so that the complete unix token is represented within
631 * the nt token.
634 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
636 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
637 &session_info->security_token->sids,
638 &session_info->security_token->num_sids);
640 for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
641 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
642 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
643 &session_info->security_token->sids,
644 &session_info->security_token->num_sids);
647 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
648 debug_unix_user_token(DBGC_AUTH, 10,
649 session_info->unix_token->uid,
650 session_info->unix_token->gid,
651 session_info->unix_token->ngroups,
652 session_info->unix_token->groups);
654 status = log_nt_token(session_info->security_token);
655 if (!NT_STATUS_IS_OK(status)) {
656 return status;
659 *session_info_out = session_info;
660 return NT_STATUS_OK;
663 /***************************************************************************
664 Make (and fill) a server_info struct from a 'struct passwd' by conversion
665 to a struct samu
666 ***************************************************************************/
668 NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
669 const char *unix_username,
670 const struct passwd *pwd,
671 struct auth_serversupplied_info **server_info)
673 NTSTATUS status;
674 TALLOC_CTX *tmp_ctx = NULL;
675 struct auth_serversupplied_info *result;
677 tmp_ctx = talloc_stackframe();
678 if (tmp_ctx == NULL) {
679 return NT_STATUS_NO_MEMORY;
682 result = make_server_info(tmp_ctx);
683 if (result == NULL) {
684 status = NT_STATUS_NO_MEMORY;
685 goto done;
688 status = passwd_to_SamInfo3(result,
689 unix_username,
690 pwd,
691 &result->info3,
692 &result->extra);
693 if (!NT_STATUS_IS_OK(status)) {
694 goto done;
697 result->unix_name = talloc_strdup(result, unix_username);
698 if (result->unix_name == NULL) {
699 status = NT_STATUS_NO_MEMORY;
700 goto done;
703 result->utok.uid = pwd->pw_uid;
704 result->utok.gid = pwd->pw_gid;
706 *server_info = talloc_steal(mem_ctx, result);
707 status = NT_STATUS_OK;
708 done:
709 talloc_free(tmp_ctx);
711 return status;
714 static NTSTATUS get_system_info3(TALLOC_CTX *mem_ctx,
715 struct netr_SamInfo3 *info3)
717 NTSTATUS status;
719 /* Set account name */
720 init_lsa_String(&info3->base.account_name, "SYSTEM");
722 /* Set domain name */
723 init_lsa_StringLarge(&info3->base.logon_domain, "NT AUTHORITY");
726 status = dom_sid_split_rid(mem_ctx, &global_sid_System,
727 &info3->base.domain_sid,
728 &info3->base.rid);
729 if (!NT_STATUS_IS_OK(status)) {
730 return status;
733 /* Primary gid is the same */
734 info3->base.primary_gid = info3->base.rid;
736 return NT_STATUS_OK;
739 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
740 struct netr_SamInfo3 *info3)
742 const char *guest_account = lp_guest_account();
743 struct dom_sid domain_sid;
744 struct passwd *pwd;
745 const char *tmp;
747 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
748 if (pwd == NULL) {
749 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
750 "account [%s]!\n", guest_account));
751 return NT_STATUS_NO_SUCH_USER;
754 /* Set account name */
755 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
756 if (tmp == NULL) {
757 return NT_STATUS_NO_MEMORY;
759 init_lsa_String(&info3->base.account_name, tmp);
761 /* Set domain name */
762 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
763 if (tmp == NULL) {
764 return NT_STATUS_NO_MEMORY;
766 init_lsa_StringLarge(&info3->base.logon_domain, tmp);
768 /* Domain sid */
769 sid_copy(&domain_sid, get_global_sam_sid());
771 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
772 if (info3->base.domain_sid == NULL) {
773 return NT_STATUS_NO_MEMORY;
776 /* Guest rid */
777 info3->base.rid = DOMAIN_RID_GUEST;
779 /* Primary gid */
780 info3->base.primary_gid = DOMAIN_RID_GUESTS;
782 /* Set as guest */
783 info3->base.user_flags = NETLOGON_GUEST;
785 TALLOC_FREE(pwd);
786 return NT_STATUS_OK;
789 /***************************************************************************
790 Make (and fill) a user_info struct for a guest login.
791 This *must* succeed for smbd to start. If there is no mapping entry for
792 the guest gid, then create one.
794 The resulting structure is a 'session_info' because
795 create_local_token() has already been called on it. This is quite
796 nasty, as the auth subsystem isn't expect this, but the behavior is
797 left as-is for now.
798 ***************************************************************************/
800 static NTSTATUS make_new_session_info_guest(struct auth_session_info **session_info, struct auth_serversupplied_info **server_info)
802 const char *guest_account = lp_guest_account();
803 const char *domain = lp_netbios_name();
804 struct netr_SamInfo3 info3;
805 TALLOC_CTX *tmp_ctx;
806 NTSTATUS status;
808 tmp_ctx = talloc_stackframe();
809 if (tmp_ctx == NULL) {
810 return NT_STATUS_NO_MEMORY;
813 ZERO_STRUCT(info3);
815 status = get_guest_info3(tmp_ctx, &info3);
816 if (!NT_STATUS_IS_OK(status)) {
817 DEBUG(0, ("get_guest_info3 failed with %s\n",
818 nt_errstr(status)));
819 goto done;
822 status = make_server_info_info3(tmp_ctx,
823 guest_account,
824 domain,
825 server_info,
826 &info3);
827 if (!NT_STATUS_IS_OK(status)) {
828 DEBUG(0, ("make_server_info_info3 failed with %s\n",
829 nt_errstr(status)));
830 goto done;
833 (*server_info)->guest = true;
835 /* This should not be done here (we should produce a server
836 * info, and later construct a session info from it), but for
837 * now this does not change the previous behavior */
838 status = create_local_token(tmp_ctx, *server_info, NULL,
839 (*server_info)->info3->base.account_name.string,
840 session_info);
841 if (!NT_STATUS_IS_OK(status)) {
842 DEBUG(0, ("create_local_token failed: %s\n",
843 nt_errstr(status)));
844 goto done;
846 talloc_steal(NULL, *session_info);
847 talloc_steal(NULL, *server_info);
849 /* annoying, but the Guest really does have a session key, and it is
850 all zeros! */
851 (*session_info)->session_key = data_blob_talloc_zero(NULL, 16);
853 status = NT_STATUS_OK;
854 done:
855 TALLOC_FREE(tmp_ctx);
856 return status;
859 /***************************************************************************
860 Make (and fill) a auth_session_info struct for a system user login.
861 This *must* succeed for smbd to start.
862 ***************************************************************************/
864 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
865 struct auth_session_info **session_info)
867 NTSTATUS status;
868 struct auth_serversupplied_info *server_info;
869 TALLOC_CTX *tmp_ctx;
871 tmp_ctx = talloc_stackframe();
872 if (tmp_ctx == NULL) {
873 return NT_STATUS_NO_MEMORY;
876 server_info = make_server_info(tmp_ctx);
877 if (!server_info) {
878 status = NT_STATUS_NO_MEMORY;
879 DEBUG(0, ("failed making server_info\n"));
880 goto done;
883 server_info->info3 = talloc_zero(server_info, struct netr_SamInfo3);
884 if (!server_info->info3) {
885 status = NT_STATUS_NO_MEMORY;
886 DEBUG(0, ("talloc failed setting info3\n"));
887 goto done;
890 status = get_system_info3(server_info, server_info->info3);
891 if (!NT_STATUS_IS_OK(status)) {
892 DEBUG(0, ("Failed creating system info3 with %s\n",
893 nt_errstr(status)));
894 goto done;
897 server_info->utok.uid = sec_initial_uid();
898 server_info->utok.gid = sec_initial_gid();
899 server_info->unix_name = talloc_asprintf(server_info,
900 "NT AUTHORITY%cSYSTEM",
901 *lp_winbind_separator());
903 if (!server_info->unix_name) {
904 status = NT_STATUS_NO_MEMORY;
905 DEBUG(0, ("talloc_asprintf failed setting unix_name\n"));
906 goto done;
909 server_info->security_token = talloc_zero(server_info, struct security_token);
910 if (!server_info->security_token) {
911 status = NT_STATUS_NO_MEMORY;
912 DEBUG(0, ("talloc failed setting security token\n"));
913 goto done;
916 status = add_sid_to_array_unique(server_info->security_token->sids,
917 &global_sid_System,
918 &server_info->security_token->sids,
919 &server_info->security_token->num_sids);
920 if (!NT_STATUS_IS_OK(status)) {
921 goto done;
924 /* SYSTEM has all privilages */
925 server_info->security_token->privilege_mask = ~0;
927 /* Now turn the server_info into a session_info with the full token etc */
928 status = create_local_token(mem_ctx, server_info, NULL, "SYSTEM", session_info);
929 talloc_free(server_info);
931 if (!NT_STATUS_IS_OK(status)) {
932 DEBUG(0, ("create_local_token failed: %s\n",
933 nt_errstr(status)));
934 goto done;
937 talloc_steal(mem_ctx, *session_info);
939 done:
940 TALLOC_FREE(tmp_ctx);
941 return status;
944 /****************************************************************************
945 Fake a auth_session_info just from a username (as a
946 session_info structure, with create_local_token() already called on
948 ****************************************************************************/
950 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
951 const char *username,
952 bool is_guest,
953 struct auth_session_info **session_info)
955 struct passwd *pwd;
956 NTSTATUS status;
957 struct auth_serversupplied_info *result;
958 TALLOC_CTX *tmp_ctx;
960 tmp_ctx = talloc_stackframe();
961 if (tmp_ctx == NULL) {
962 return NT_STATUS_NO_MEMORY;
965 pwd = Get_Pwnam_alloc(tmp_ctx, username);
966 if (pwd == NULL) {
967 status = NT_STATUS_NO_SUCH_USER;
968 goto done;
971 status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
972 if (!NT_STATUS_IS_OK(status)) {
973 goto done;
976 result->nss_token = true;
977 result->guest = is_guest;
979 /* Now turn the server_info into a session_info with the full token etc */
980 status = create_local_token(mem_ctx,
981 result,
982 NULL,
983 pwd->pw_name,
984 session_info);
986 done:
987 talloc_free(tmp_ctx);
989 return status;
992 /* This function MUST only used to create the cached server_info for
993 * guest.
995 * This is a lossy conversion. Variables known to be lost so far
996 * include:
998 * - nss_token (not needed because the only read doesn't happen
999 * for the GUEST user, as this routine populates ->security_token
1001 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1003 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1005 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1006 const struct auth_session_info *src,
1007 struct auth_serversupplied_info *server_info)
1009 struct auth_serversupplied_info *dst;
1011 dst = make_server_info(mem_ctx);
1012 if (dst == NULL) {
1013 return NULL;
1016 /* This element must be provided to convert back to an auth_serversupplied_info */
1017 SMB_ASSERT(src->unix_info);
1019 dst->guest = true;
1020 dst->system = false;
1022 /* This element must be provided to convert back to an
1023 * auth_serversupplied_info. This needs to be from the
1024 * auth_session_info because the group values in particular
1025 * may change during create_local_token() processing */
1026 SMB_ASSERT(src->unix_token);
1027 dst->utok.uid = src->unix_token->uid;
1028 dst->utok.gid = src->unix_token->gid;
1029 dst->utok.ngroups = src->unix_token->ngroups;
1030 if (src->unix_token->ngroups != 0) {
1031 dst->utok.groups = (gid_t *)talloc_memdup(
1032 dst, src->unix_token->groups,
1033 sizeof(gid_t)*dst->utok.ngroups);
1034 } else {
1035 dst->utok.groups = NULL;
1038 /* We must have a security_token as otherwise the lossy
1039 * conversion without nss_token would cause create_local_token
1040 * to take the wrong path */
1041 SMB_ASSERT(src->security_token);
1043 dst->security_token = dup_nt_token(dst, src->security_token);
1044 if (!dst->security_token) {
1045 TALLOC_FREE(dst);
1046 return NULL;
1049 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1050 src->session_key.length);
1052 /* This is OK because this functions is only used for the
1053 * GUEST account, which has all-zero keys for both values */
1054 dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1055 src->session_key.length);
1057 dst->info3 = copy_netr_SamInfo3(dst, server_info->info3);
1058 if (!dst->info3) {
1059 TALLOC_FREE(dst);
1060 return NULL;
1063 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1064 if (!dst->unix_name) {
1065 TALLOC_FREE(dst);
1066 return NULL;
1069 return dst;
1072 struct auth_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
1073 const struct auth_session_info *src)
1075 struct auth_session_info *dst;
1076 DATA_BLOB blob;
1077 enum ndr_err_code ndr_err;
1079 ndr_err = ndr_push_struct_blob(
1080 &blob, talloc_tos(), src,
1081 (ndr_push_flags_fn_t)ndr_push_auth_session_info);
1082 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1083 DEBUG(0, ("copy_session_info(): ndr_push_auth_session_info failed: "
1084 "%s\n", ndr_errstr(ndr_err)));
1085 return NULL;
1088 dst = talloc(mem_ctx, struct auth_session_info);
1089 if (dst == NULL) {
1090 DEBUG(0, ("talloc failed\n"));
1091 TALLOC_FREE(blob.data);
1092 return NULL;
1095 ndr_err = ndr_pull_struct_blob(
1096 &blob, dst, dst,
1097 (ndr_pull_flags_fn_t)ndr_pull_auth_session_info);
1098 TALLOC_FREE(blob.data);
1100 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1101 DEBUG(0, ("copy_session_info(): ndr_pull_auth_session_info failed: "
1102 "%s\n", ndr_errstr(ndr_err)));
1103 TALLOC_FREE(dst);
1104 return NULL;
1107 return dst;
1111 * Set a new session key. Used in the rpc server where we have to override the
1112 * SMB level session key with SystemLibraryDTC
1115 bool session_info_set_session_key(struct auth_session_info *info,
1116 DATA_BLOB session_key)
1118 TALLOC_FREE(info->session_key.data);
1120 info->session_key = data_blob_talloc(
1121 info, session_key.data, session_key.length);
1123 return (info->session_key.data != NULL);
1126 static struct auth_session_info *guest_info = NULL;
1128 static struct auth_serversupplied_info *guest_server_info = NULL;
1130 bool init_guest_info(void)
1132 if (guest_info != NULL)
1133 return true;
1135 return NT_STATUS_IS_OK(make_new_session_info_guest(&guest_info, &guest_server_info));
1138 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1139 struct auth_serversupplied_info **server_info)
1141 /* This is trickier than it would appear to need to be because
1142 * we are trying to avoid certain costly operations when the
1143 * structure is converted to a 'auth_session_info' again in
1144 * create_local_token() */
1145 *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1146 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1149 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1150 struct auth_session_info **session_info)
1152 *session_info = copy_session_info(mem_ctx, guest_info);
1153 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1156 static struct auth_session_info *system_info = NULL;
1158 NTSTATUS init_system_session_info(void)
1160 if (system_info != NULL)
1161 return NT_STATUS_OK;
1163 return make_new_session_info_system(NULL, &system_info);
1166 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1167 struct auth_session_info **session_info)
1169 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1170 *session_info = copy_session_info(mem_ctx, system_info);
1171 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1174 const struct auth_session_info *get_session_info_system(void)
1176 return system_info;
1179 /***************************************************************************
1180 Purely internal function for make_server_info_info3
1181 ***************************************************************************/
1183 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1184 const char *username, char **found_username,
1185 struct passwd **pwd,
1186 bool *username_was_mapped)
1188 char *orig_dom_user = NULL;
1189 char *dom_user = NULL;
1190 char *lower_username = NULL;
1191 char *real_username = NULL;
1192 struct passwd *passwd;
1194 lower_username = talloc_strdup(mem_ctx, username);
1195 if (!lower_username) {
1196 return NT_STATUS_NO_MEMORY;
1198 if (!strlower_m( lower_username )) {
1199 return NT_STATUS_INVALID_PARAMETER;
1202 orig_dom_user = talloc_asprintf(mem_ctx,
1203 "%s%c%s",
1204 domain,
1205 *lp_winbind_separator(),
1206 lower_username);
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);
1214 if (!dom_user) {
1215 return NT_STATUS_NO_MEMORY;
1218 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
1219 if (!passwd) {
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;
1229 *pwd = passwd;
1231 /* This is pointless -- there is no support 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?
1235 --jerry */
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;
1252 char *p = 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);
1263 if (!username) {
1264 return NULL;
1267 p = strchr_m( username, *lp_winbind_separator() );
1269 /* code for a DOMAIN\user string */
1271 if ( p ) {
1272 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1273 if ( pw ) {
1274 /* make sure we get the case of the username correct */
1275 /* work around 'winbind use default domain = yes' */
1277 if ( lp_winbind_use_default_domain() &&
1278 !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1279 char *domain;
1281 /* split the domain and username into 2 strings */
1282 *p = '\0';
1283 domain = username;
1285 *p_save_username = talloc_asprintf(mem_ctx,
1286 "%s%c%s",
1287 domain,
1288 *lp_winbind_separator(),
1289 pw->pw_name);
1290 if (!*p_save_username) {
1291 TALLOC_FREE(pw);
1292 return NULL;
1294 } else {
1295 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1298 /* whew -- done! */
1299 return pw;
1302 /* setup for lookup of just the username */
1303 /* remember that p and username are overlapping memory */
1305 p++;
1306 username = talloc_strdup(mem_ctx, p);
1307 if (!username) {
1308 return NULL;
1312 /* just lookup a plain username */
1314 pw = Get_Pwnam_alloc(mem_ctx, username);
1316 /* Create local user if requested but only if winbindd
1317 is not running. We need to protect against cases
1318 where winbindd is failing and then prematurely
1319 creating users in /etc/passwd */
1321 if ( !pw && create && !winbind_ping() ) {
1322 /* Don't add a machine account. */
1323 if (username[strlen(username)-1] == '$')
1324 return NULL;
1326 _smb_create_user(NULL, username, NULL);
1327 pw = Get_Pwnam_alloc(mem_ctx, username);
1330 /* one last check for a valid passwd struct */
1332 if (pw) {
1333 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1335 return pw;
1338 /***************************************************************************
1339 Make a server_info struct from the info3 returned by a domain logon
1340 ***************************************************************************/
1342 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1343 const char *sent_nt_username,
1344 const char *domain,
1345 struct auth_serversupplied_info **server_info,
1346 const struct netr_SamInfo3 *info3)
1348 NTSTATUS nt_status = NT_STATUS_OK;
1349 char *found_username = NULL;
1350 const char *nt_domain;
1351 const char *nt_username;
1352 struct dom_sid user_sid;
1353 struct dom_sid group_sid;
1354 bool username_was_mapped;
1355 struct passwd *pwd;
1356 struct auth_serversupplied_info *result;
1357 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1360 Here is where we should check the list of
1361 trusted domains, and verify that the SID
1362 matches.
1365 if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
1366 nt_status = NT_STATUS_INVALID_PARAMETER;
1367 goto out;
1370 if (!sid_compose(&group_sid, info3->base.domain_sid,
1371 info3->base.primary_gid)) {
1372 nt_status = NT_STATUS_INVALID_PARAMETER;
1373 goto out;
1376 nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
1377 if (!nt_username) {
1378 /* If the server didn't give us one, just use the one we sent
1379 * them */
1380 nt_username = sent_nt_username;
1383 nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
1384 if (!nt_domain) {
1385 /* If the server didn't give us one, just use the one we sent
1386 * them */
1387 nt_domain = domain;
1390 /* If getpwnam() fails try the add user script (2.2.x behavior).
1392 We use the _unmapped_ username here in an attempt to provide
1393 consistent username mapping behavior between kerberos and NTLM[SSP]
1394 authentication in domain mode security. I.E. Username mapping
1395 should be applied to the fully qualified username
1396 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1397 called map_username() unnecessarily in make_user_info_map() but
1398 that is how the current code is designed. Making the change here
1399 is the least disruptive place. -- jerry */
1401 /* this call will try to create the user if necessary */
1403 nt_status = check_account(tmp_ctx,
1404 nt_domain,
1405 nt_username,
1406 &found_username,
1407 &pwd,
1408 &username_was_mapped);
1410 if (!NT_STATUS_IS_OK(nt_status)) {
1411 /* Handle 'map to guest = Bad Uid */
1412 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
1413 (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
1414 lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
1415 DBG_NOTICE("Try to map %s to guest account",
1416 nt_username);
1417 nt_status = make_server_info_guest(tmp_ctx, &result);
1418 if (NT_STATUS_IS_OK(nt_status)) {
1419 *server_info = talloc_move(mem_ctx, &result);
1422 goto out;
1425 result = make_server_info(tmp_ctx);
1426 if (result == NULL) {
1427 DEBUG(4, ("make_server_info failed!\n"));
1428 nt_status = NT_STATUS_NO_MEMORY;
1429 goto out;
1432 result->unix_name = talloc_strdup(result, found_username);
1434 /* copy in the info3 */
1435 result->info3 = copy_netr_SamInfo3(result, info3);
1436 if (result->info3 == NULL) {
1437 nt_status = NT_STATUS_NO_MEMORY;
1438 goto out;
1441 /* Fill in the unix info we found on the way */
1443 result->utok.uid = pwd->pw_uid;
1444 result->utok.gid = pwd->pw_gid;
1446 /* ensure we are never given NULL session keys */
1448 if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
1449 result->session_key = data_blob_null;
1450 } else {
1451 result->session_key = data_blob_talloc(
1452 result, info3->base.key.key,
1453 sizeof(info3->base.key.key));
1456 if (all_zero(info3->base.LMSessKey.key,
1457 sizeof(info3->base.LMSessKey.key))) {
1458 result->lm_session_key = data_blob_null;
1459 } else {
1460 result->lm_session_key = data_blob_talloc(
1461 result, info3->base.LMSessKey.key,
1462 sizeof(info3->base.LMSessKey.key));
1465 result->nss_token |= username_was_mapped;
1467 result->guest = (info3->base.user_flags & NETLOGON_GUEST);
1469 *server_info = talloc_move(mem_ctx, &result);
1471 nt_status = NT_STATUS_OK;
1472 out:
1473 talloc_free(tmp_ctx);
1475 return nt_status;
1478 /*****************************************************************************
1479 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1480 ******************************************************************************/
1482 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1483 const char *sent_nt_username,
1484 const char *domain,
1485 const struct wbcAuthUserInfo *info,
1486 struct auth_serversupplied_info **server_info)
1488 struct netr_SamInfo3 info3;
1489 struct netr_SamInfo6 *info6;
1491 info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
1492 if (!info6) {
1493 return NT_STATUS_NO_MEMORY;
1496 info3.base = info6->base;
1497 info3.sidcount = info6->sidcount;
1498 info3.sids = info6->sids;
1500 return make_server_info_info3(mem_ctx,
1501 sent_nt_username, domain,
1502 server_info, &info3);
1506 * Verify whether or not given domain is trusted.
1508 * @param domain_name name of the domain to be verified
1509 * @return true if domain is one of the trusted ones or
1510 * false if otherwise
1513 bool is_trusted_domain(const char* dom_name)
1515 struct dom_sid trustdom_sid;
1516 bool ret;
1518 /* no trusted domains for a standalone server */
1520 if ( lp_server_role() == ROLE_STANDALONE )
1521 return false;
1523 if (dom_name == NULL || dom_name[0] == '\0') {
1524 return false;
1527 if (strequal(dom_name, get_global_sam_name())) {
1528 return false;
1531 /* if we are a DC, then check for a direct trust relationships */
1533 if ( IS_DC ) {
1534 become_root();
1535 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1536 "[%s]\n", dom_name ));
1537 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1538 unbecome_root();
1539 if (ret)
1540 return true;
1542 else {
1543 wbcErr result;
1545 /* If winbind is around, ask it */
1547 result = wb_is_trusted_domain(dom_name);
1549 if (result == WBC_ERR_SUCCESS) {
1550 return true;
1553 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1554 /* winbind could not find the domain */
1555 return false;
1558 DEBUG(10, ("wb_is_trusted_domain returned error: %s\n",
1559 wbcErrorString(result)));
1561 /* The only other possible result is that winbind is not up
1562 and running. We need to update the trustdom_cache
1563 ourselves */
1565 update_trustdom_cache();
1568 /* now the trustdom cache should be available a DC could still
1569 * have a transitive trust so fall back to the cache of trusted
1570 * domains (like a domain member would use */
1572 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1573 return true;
1576 return false;
1582 on a logon error possibly map the error to success if "map to guest"
1583 is set approriately
1585 NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
1586 NTSTATUS status,
1587 const char *user,
1588 const char *domain,
1589 struct auth_serversupplied_info **server_info)
1591 user = user ? user : "";
1592 domain = domain ? domain : "";
1594 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1595 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
1596 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
1597 DEBUG(3,("No such user %s [%s] - using guest account\n",
1598 user, domain));
1599 return make_server_info_guest(mem_ctx, server_info);
1601 } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1602 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
1603 DEBUG(3,("Registered username %s for guest access\n",
1604 user));
1605 return make_server_info_guest(mem_ctx, server_info);
1609 return status;
1613 Extract session key from a session info and return it in a blob
1614 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
1616 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
1617 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
1619 Note that returned session_key is referencing the original key, it is supposed to be
1620 short-lived. If original session_info->session_key is gone, the reference will be broken.
1622 NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
1625 if (session_key == NULL || session_info == NULL) {
1626 return NT_STATUS_INVALID_PARAMETER;
1629 if (session_info->session_key.length == 0) {
1630 return NT_STATUS_NO_USER_SESSION_KEY;
1633 *session_key = session_info->session_key;
1634 if (intent == KEY_USE_16BYTES) {
1635 session_key->length = MIN(session_info->session_key.length, 16);
1637 return NT_STATUS_OK;