s3:auth_samba4: make use of imessaging_init_discard_incoming()
[Samba.git] / source3 / auth / auth_util.c
blobb60dd2647c86ba29cd2b9c9b4d66797b435a4bcf
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 "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"
37 #include "../lib/tsocket/tsocket.h"
38 #include "rpc_client/util_netlogon.h"
39 #include "source4/auth/auth.h"
40 #include "auth/auth_util.h"
41 #include "source3/lib/substitute.h"
43 #undef DBGC_CLASS
44 #define DBGC_CLASS DBGC_AUTH
46 /****************************************************************************
47 Create a UNIX user on demand.
48 ****************************************************************************/
50 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
52 TALLOC_CTX *ctx = talloc_tos();
53 const struct loadparm_substitution *lp_sub =
54 loadparm_s3_global_substitution();
55 char *add_script;
56 int ret;
58 add_script = lp_add_user_script(ctx, lp_sub);
59 if (!add_script || !*add_script) {
60 return -1;
62 add_script = talloc_all_string_sub(ctx,
63 add_script,
64 "%u",
65 unix_username);
66 if (!add_script) {
67 return -1;
69 if (domain) {
70 add_script = talloc_all_string_sub(ctx,
71 add_script,
72 "%D",
73 domain);
74 if (!add_script) {
75 return -1;
78 if (homedir) {
79 add_script = talloc_all_string_sub(ctx,
80 add_script,
81 "%H",
82 homedir);
83 if (!add_script) {
84 return -1;
87 ret = smbrun(add_script, NULL, NULL);
88 flush_pwnam_cache();
89 DEBUG(ret ? 0 : 3,
90 ("smb_create_user: Running the command `%s' gave %d\n",
91 add_script,ret));
92 return ret;
95 /****************************************************************************
96 Create an auth_usersupplied_data structure after appropriate mapping.
97 ****************************************************************************/
99 NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
100 struct auth_usersupplied_info **user_info,
101 const char *smb_name,
102 const char *client_domain,
103 const char *workstation_name,
104 const struct tsocket_address *remote_address,
105 const struct tsocket_address *local_address,
106 const char *service_description,
107 const DATA_BLOB *lm_pwd,
108 const DATA_BLOB *nt_pwd,
109 const struct samr_Password *lm_interactive_pwd,
110 const struct samr_Password *nt_interactive_pwd,
111 const char *plaintext,
112 enum auth_password_state password_state)
114 const char *domain;
115 NTSTATUS result;
116 bool was_mapped;
117 char *internal_username = NULL;
119 was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
120 if (!internal_username) {
121 return NT_STATUS_NO_MEMORY;
124 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
125 client_domain, smb_name, workstation_name));
128 * We let the auth stack canonicalize, username
129 * and domain.
131 domain = client_domain;
133 result = make_user_info(mem_ctx, user_info, smb_name, internal_username,
134 client_domain, domain, workstation_name,
135 remote_address, local_address,
136 service_description, lm_pwd, nt_pwd,
137 lm_interactive_pwd, nt_interactive_pwd,
138 plaintext, password_state);
139 if (NT_STATUS_IS_OK(result)) {
140 /* did we actually map the user to a different name? */
141 (*user_info)->was_mapped = was_mapped;
143 return result;
146 /****************************************************************************
147 Create an auth_usersupplied_data, making the DATA_BLOBs here.
148 Decrypt and encrypt the passwords.
149 ****************************************************************************/
151 bool make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
152 struct auth_usersupplied_info **user_info,
153 const char *smb_name,
154 const char *client_domain,
155 const char *workstation_name,
156 const struct tsocket_address *remote_address,
157 const struct tsocket_address *local_address,
158 uint32_t logon_parameters,
159 const uchar *lm_network_pwd,
160 int lm_pwd_len,
161 const uchar *nt_network_pwd,
162 int nt_pwd_len)
164 bool ret;
165 NTSTATUS status;
166 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
167 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
169 status = make_user_info_map(mem_ctx, user_info,
170 smb_name, client_domain,
171 workstation_name,
172 remote_address,
173 local_address,
174 "SamLogon",
175 lm_pwd_len ? &lm_blob : NULL,
176 nt_pwd_len ? &nt_blob : NULL,
177 NULL, NULL, NULL,
178 AUTH_PASSWORD_RESPONSE);
180 if (NT_STATUS_IS_OK(status)) {
181 (*user_info)->logon_parameters = logon_parameters;
183 ret = NT_STATUS_IS_OK(status) ? true : false;
185 data_blob_free(&lm_blob);
186 data_blob_free(&nt_blob);
187 return ret;
190 /****************************************************************************
191 Create an auth_usersupplied_data, making the DATA_BLOBs here.
192 Decrypt and encrypt the passwords.
193 ****************************************************************************/
195 bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
196 struct auth_usersupplied_info **user_info,
197 const char *smb_name,
198 const char *client_domain,
199 const char *workstation_name,
200 const struct tsocket_address *remote_address,
201 const struct tsocket_address *local_address,
202 uint32_t logon_parameters,
203 const uchar chal[8],
204 const uchar lm_interactive_pwd[16],
205 const uchar nt_interactive_pwd[16])
207 struct samr_Password lm_pwd;
208 struct samr_Password nt_pwd;
209 unsigned char local_lm_response[24];
210 unsigned char local_nt_response[24];
211 int rc;
213 if (lm_interactive_pwd)
214 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
216 if (nt_interactive_pwd)
217 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
219 if (lm_interactive_pwd) {
220 rc = SMBOWFencrypt(lm_pwd.hash, chal,
221 local_lm_response);
222 if (rc != 0) {
223 return false;
227 if (nt_interactive_pwd) {
228 rc = SMBOWFencrypt(nt_pwd.hash, chal,
229 local_nt_response);
230 if (rc != 0) {
231 return false;
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 local_address,
257 "SamLogon",
258 lm_interactive_pwd ? &local_lm_blob : NULL,
259 nt_interactive_pwd ? &local_nt_blob : NULL,
260 lm_interactive_pwd ? &lm_pwd : NULL,
261 nt_interactive_pwd ? &nt_pwd : NULL,
262 NULL, AUTH_PASSWORD_HASH);
264 if (NT_STATUS_IS_OK(nt_status)) {
265 (*user_info)->logon_parameters = logon_parameters;
266 (*user_info)->flags |= USER_INFO_INTERACTIVE_LOGON;
269 ret = NT_STATUS_IS_OK(nt_status) ? true : false;
270 data_blob_free(&local_lm_blob);
271 data_blob_free(&local_nt_blob);
272 return ret;
277 /****************************************************************************
278 Create an auth_usersupplied_data structure
279 ****************************************************************************/
281 bool make_user_info_for_reply(TALLOC_CTX *mem_ctx,
282 struct auth_usersupplied_info **user_info,
283 const char *smb_name,
284 const char *client_domain,
285 const struct tsocket_address *remote_address,
286 const struct tsocket_address *local_address,
287 const char *service_description,
288 const uint8_t chal[8],
289 DATA_BLOB plaintext_password)
292 DATA_BLOB local_lm_blob;
293 DATA_BLOB local_nt_blob;
294 NTSTATUS ret;
295 char *plaintext_password_string;
297 * Not encrypted - do so.
300 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
301 "format.\n"));
302 if (plaintext_password.data && plaintext_password.length) {
303 unsigned char local_lm_response[24];
305 #ifdef DEBUG_PASSWORD
306 DEBUG(10,("Unencrypted password (len %d):\n",
307 (int)plaintext_password.length));
308 dump_data(100, plaintext_password.data,
309 plaintext_password.length);
310 #endif
312 SMBencrypt( (const char *)plaintext_password.data,
313 (const uchar*)chal, local_lm_response);
314 local_lm_blob = data_blob(local_lm_response, 24);
316 /* We can't do an NT hash here, as the password needs to be
317 case insensitive */
318 local_nt_blob = data_blob_null;
319 } else {
320 local_lm_blob = data_blob_null;
321 local_nt_blob = data_blob_null;
324 plaintext_password_string = talloc_strndup(talloc_tos(),
325 (const char *)plaintext_password.data,
326 plaintext_password.length);
327 if (!plaintext_password_string) {
328 return false;
331 ret = make_user_info(mem_ctx,
332 user_info, smb_name, smb_name, client_domain, client_domain,
333 get_remote_machine_name(),
334 remote_address,
335 local_address,
336 service_description,
337 local_lm_blob.data ? &local_lm_blob : NULL,
338 local_nt_blob.data ? &local_nt_blob : NULL,
339 NULL, NULL,
340 plaintext_password_string,
341 AUTH_PASSWORD_PLAIN);
343 if (plaintext_password_string) {
344 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
345 talloc_free(plaintext_password_string);
348 data_blob_free(&local_lm_blob);
349 return NT_STATUS_IS_OK(ret) ? true : false;
352 /****************************************************************************
353 Create an auth_usersupplied_data structure
354 ****************************************************************************/
356 NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
357 struct auth_usersupplied_info **user_info,
358 const char *smb_name,
359 const char *client_domain,
360 const struct tsocket_address *remote_address,
361 const struct tsocket_address *local_address,
362 const char *service_description,
363 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
365 bool allow_raw = lp_raw_ntlmv2_auth();
367 if (!allow_raw && nt_resp.length >= 48) {
369 * NTLMv2_RESPONSE has at least 48 bytes
370 * and should only be supported via NTLMSSP.
372 DEBUG(2,("Rejecting raw NTLMv2 authentication with "
373 "user [%s\\%s] from[%s]\n",
374 client_domain, smb_name,
375 tsocket_address_string(remote_address, mem_ctx)));
376 return NT_STATUS_INVALID_PARAMETER;
379 return make_user_info(mem_ctx,
380 user_info, smb_name, smb_name,
381 client_domain, client_domain,
382 get_remote_machine_name(),
383 remote_address,
384 local_address,
385 service_description,
386 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
387 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
388 NULL, NULL, NULL,
389 AUTH_PASSWORD_RESPONSE);
392 /****************************************************************************
393 Create a guest user_info blob, for anonymous authentication.
394 ****************************************************************************/
396 bool make_user_info_guest(TALLOC_CTX *mem_ctx,
397 const struct tsocket_address *remote_address,
398 const struct tsocket_address *local_address,
399 const char *service_description,
400 struct auth_usersupplied_info **user_info)
402 NTSTATUS nt_status;
404 nt_status = make_user_info(mem_ctx,
405 user_info,
406 "","",
407 "","",
408 "",
409 remote_address,
410 local_address,
411 service_description,
412 NULL, NULL,
413 NULL, NULL,
414 NULL,
415 AUTH_PASSWORD_RESPONSE);
417 return NT_STATUS_IS_OK(nt_status) ? true : false;
420 static NTSTATUS log_nt_token(struct security_token *token)
422 TALLOC_CTX *frame = talloc_stackframe();
423 const struct loadparm_substitution *lp_sub =
424 loadparm_s3_global_substitution();
425 char *command;
426 char *group_sidstr;
427 struct dom_sid_buf buf;
428 size_t i;
430 if ((lp_log_nt_token_command(frame, lp_sub) == NULL) ||
431 (strlen(lp_log_nt_token_command(frame, lp_sub)) == 0)) {
432 TALLOC_FREE(frame);
433 return NT_STATUS_OK;
436 group_sidstr = talloc_strdup(frame, "");
437 for (i=1; i<token->num_sids; i++) {
438 group_sidstr = talloc_asprintf(
439 frame, "%s %s", group_sidstr,
440 dom_sid_str_buf(&token->sids[i], &buf));
443 command = talloc_string_sub(
444 frame, lp_log_nt_token_command(frame, lp_sub),
445 "%s", dom_sid_str_buf(&token->sids[0], &buf));
446 command = talloc_string_sub(frame, command, "%t", group_sidstr);
448 if (command == NULL) {
449 TALLOC_FREE(frame);
450 return NT_STATUS_NO_MEMORY;
453 DEBUG(8, ("running command: [%s]\n", command));
454 if (smbrun(command, NULL, NULL) != 0) {
455 DEBUG(0, ("Could not log NT token\n"));
456 TALLOC_FREE(frame);
457 return NT_STATUS_ACCESS_DENIED;
460 TALLOC_FREE(frame);
461 return NT_STATUS_OK;
465 * Create the token to use from server_info->info3 and
466 * server_info->sids (the info3/sam groups). Find the unix gids.
469 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
470 const struct auth_serversupplied_info *server_info,
471 DATA_BLOB *session_key,
472 const char *smb_username, /* for ->sanitized_username, for %U subs */
473 struct auth_session_info **session_info_out)
475 struct security_token *t;
476 NTSTATUS status;
477 size_t i;
478 struct dom_sid tmp_sid;
479 struct auth_session_info *session_info = NULL;
480 struct unixid *ids;
482 /* Ensure we can't possible take a code path leading to a
483 * null deref. */
484 if (!server_info) {
485 return NT_STATUS_LOGON_FAILURE;
488 if (!is_allowed_domain(server_info->info3->base.logon_domain.string)) {
489 DBG_NOTICE("Authentication failed for user [%s] "
490 "from firewalled domain [%s]\n",
491 server_info->info3->base.account_name.string,
492 server_info->info3->base.logon_domain.string);
493 return NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
496 if (server_info->cached_session_info != NULL) {
497 session_info = copy_session_info(mem_ctx,
498 server_info->cached_session_info);
499 if (session_info == NULL) {
500 goto nomem;
503 /* This is a potentially untrusted username for use in %U */
504 session_info->unix_info->sanitized_username =
505 talloc_alpha_strcpy(session_info->unix_info,
506 smb_username,
507 SAFE_NETBIOS_CHARS "$");
508 if (session_info->unix_info->sanitized_username == NULL) {
509 goto nomem;
512 session_info->unique_session_token = GUID_random();
514 *session_info_out = session_info;
515 return NT_STATUS_OK;
518 session_info = talloc_zero(mem_ctx, struct auth_session_info);
519 if (!session_info) {
520 goto nomem;
523 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
524 if (!session_info->unix_token) {
525 goto nomem;
528 session_info->unix_token->uid = server_info->utok.uid;
529 session_info->unix_token->gid = server_info->utok.gid;
531 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
532 if (!session_info->unix_info) {
533 goto nomem;
536 session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
537 if (!session_info->unix_info->unix_name) {
538 goto nomem;
541 /* This is a potentially untrusted username for use in %U */
542 session_info->unix_info->sanitized_username =
543 talloc_alpha_strcpy(session_info->unix_info,
544 smb_username,
545 SAFE_NETBIOS_CHARS "$");
546 if (session_info->unix_info->sanitized_username == NULL) {
547 goto nomem;
550 if (session_key) {
551 data_blob_free(&session_info->session_key);
552 session_info->session_key = data_blob_talloc(session_info,
553 session_key->data,
554 session_key->length);
555 if (!session_info->session_key.data && session_key->length) {
556 goto nomem;
558 } else {
559 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
560 server_info->session_key.length);
563 /* We need to populate session_info->info with the information found in server_info->info3 */
564 status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
565 server_info->guest == false,
566 &session_info->info);
567 if (!NT_STATUS_IS_OK(status)) {
568 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
569 goto fail;
573 * If the user name was mapped to some local unix user,
574 * we can not make much use of the SIDs the
575 * domain controller provided us with.
577 if (server_info->nss_token) {
578 char *found_username = NULL;
579 status = create_token_from_username(session_info,
580 server_info->unix_name,
581 server_info->guest,
582 &session_info->unix_token->uid,
583 &session_info->unix_token->gid,
584 &found_username,
585 &session_info->security_token);
586 if (NT_STATUS_IS_OK(status)) {
587 session_info->unix_info->unix_name = found_username;
589 } else {
590 status = create_local_nt_token_from_info3(session_info,
591 server_info->guest,
592 server_info->info3,
593 &server_info->extra,
594 &session_info->security_token);
597 if (!NT_STATUS_IS_OK(status)) {
598 goto fail;
601 /* Convert the SIDs to gids. */
603 session_info->unix_token->ngroups = 0;
604 session_info->unix_token->groups = NULL;
606 t = session_info->security_token;
608 ids = talloc_array(talloc_tos(), struct unixid,
609 t->num_sids);
610 if (ids == NULL) {
611 goto nomem;
614 if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
615 goto nomem;
618 for (i=0; i<t->num_sids; i++) {
620 if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
621 continue;
624 if (ids[i].type != ID_TYPE_GID &&
625 ids[i].type != ID_TYPE_BOTH) {
626 struct dom_sid_buf buf;
627 DEBUG(10, ("Could not convert SID %s to gid, "
628 "ignoring it\n",
629 dom_sid_str_buf(&t->sids[i], &buf)));
630 continue;
632 if (!add_gid_to_array_unique(session_info->unix_token,
633 ids[i].id,
634 &session_info->unix_token->groups,
635 &session_info->unix_token->ngroups)) {
636 goto nomem;
641 * Add the "Unix Group" SID for each gid to catch mapped groups
642 * and their Unix equivalent. This is to solve the backwards
643 * compatibility problem of 'valid users = +ntadmin' where
644 * ntadmin has been paired with "Domain Admins" in the group
645 * mapping table. Otherwise smb.conf would need to be changed
646 * to 'valid user = "Domain Admins"'. --jerry
648 * For consistency we also add the "Unix User" SID,
649 * so that the complete unix token is represented within
650 * the nt token.
653 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
654 status = add_sid_to_array_unique(
655 session_info->security_token,
656 &tmp_sid,
657 &session_info->security_token->sids,
658 &session_info->security_token->num_sids);
659 if (!NT_STATUS_IS_OK(status)) {
660 goto fail;
663 gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
664 status = add_sid_to_array_unique(
665 session_info->security_token,
666 &tmp_sid,
667 &session_info->security_token->sids,
668 &session_info->security_token->num_sids);
669 if (!NT_STATUS_IS_OK(status)) {
670 goto fail;
673 for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
674 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
675 status = add_sid_to_array_unique(
676 session_info->security_token,
677 &tmp_sid,
678 &session_info->security_token->sids,
679 &session_info->security_token->num_sids);
680 if (!NT_STATUS_IS_OK(status)) {
681 goto fail;
685 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
686 debug_unix_user_token(DBGC_AUTH, 10,
687 session_info->unix_token->uid,
688 session_info->unix_token->gid,
689 session_info->unix_token->ngroups,
690 session_info->unix_token->groups);
692 status = log_nt_token(session_info->security_token);
693 if (!NT_STATUS_IS_OK(status)) {
694 goto fail;
697 session_info->unique_session_token = GUID_random();
699 *session_info_out = session_info;
700 return NT_STATUS_OK;
701 nomem:
702 status = NT_STATUS_NO_MEMORY;
703 fail:
704 TALLOC_FREE(session_info);
705 return status;
708 NTSTATUS auth3_user_info_dc_add_hints(struct auth_user_info_dc *user_info_dc,
709 uid_t uid,
710 gid_t gid,
711 uint32_t flags)
713 uint32_t orig_num_sids = user_info_dc->num_sids;
714 struct dom_sid tmp_sid = { 0, };
715 NTSTATUS status;
718 * We add S-5-88-1-X in order to pass the uid
719 * for the unix token.
721 sid_compose(&tmp_sid,
722 &global_sid_Unix_NFS_Users,
723 (uint32_t)uid);
724 status = add_sid_to_array_unique(user_info_dc->sids,
725 &tmp_sid,
726 &user_info_dc->sids,
727 &user_info_dc->num_sids);
728 if (!NT_STATUS_IS_OK(status)) {
729 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
730 nt_errstr(status)));
731 goto fail;
735 * We add S-5-88-2-X in order to pass the gid
736 * for the unix token.
738 sid_compose(&tmp_sid,
739 &global_sid_Unix_NFS_Groups,
740 (uint32_t)gid);
741 status = add_sid_to_array_unique(user_info_dc->sids,
742 &tmp_sid,
743 &user_info_dc->sids,
744 &user_info_dc->num_sids);
745 if (!NT_STATUS_IS_OK(status)) {
746 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
747 nt_errstr(status)));
748 goto fail;
752 * We add S-5-88-3-X in order to pass some flags
753 * (AUTH3_UNIX_HINT_*) to auth3_create_session_info().
755 sid_compose(&tmp_sid,
756 &global_sid_Unix_NFS_Mode,
757 flags);
758 status = add_sid_to_array_unique(user_info_dc->sids,
759 &tmp_sid,
760 &user_info_dc->sids,
761 &user_info_dc->num_sids);
762 if (!NT_STATUS_IS_OK(status)) {
763 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
764 nt_errstr(status)));
765 goto fail;
768 return NT_STATUS_OK;
770 fail:
771 user_info_dc->num_sids = orig_num_sids;
772 return status;
775 static NTSTATUS auth3_session_info_create(
776 TALLOC_CTX *mem_ctx,
777 const struct auth_user_info_dc *user_info_dc,
778 const char *original_user_name,
779 uint32_t session_info_flags,
780 struct auth_session_info **session_info_out)
782 TALLOC_CTX *frame = talloc_stackframe();
783 struct auth_session_info *session_info = NULL;
784 uid_t hint_uid = -1;
785 bool found_hint_uid = false;
786 uid_t hint_gid = -1;
787 bool found_hint_gid = false;
788 uint32_t hint_flags = 0;
789 bool found_hint_flags = false;
790 bool need_getpwuid = false;
791 struct unixid *ids = NULL;
792 uint32_t num_gids = 0;
793 gid_t *gids = NULL;
794 struct dom_sid tmp_sid = { 0, };
795 NTSTATUS status;
796 size_t i;
797 bool ok;
799 *session_info_out = NULL;
801 if (user_info_dc->num_sids == 0) {
802 TALLOC_FREE(frame);
803 return NT_STATUS_INVALID_TOKEN;
806 if (user_info_dc->info == NULL) {
807 TALLOC_FREE(frame);
808 return NT_STATUS_INVALID_TOKEN;
811 if (user_info_dc->info->account_name == NULL) {
812 TALLOC_FREE(frame);
813 return NT_STATUS_INVALID_TOKEN;
816 session_info = talloc_zero(mem_ctx, struct auth_session_info);
817 if (session_info == NULL) {
818 TALLOC_FREE(frame);
819 return NT_STATUS_NO_MEMORY;
821 /* keep this under frame for easier cleanup */
822 talloc_reparent(mem_ctx, frame, session_info);
824 session_info->info = auth_user_info_copy(session_info,
825 user_info_dc->info);
826 if (session_info->info == NULL) {
827 TALLOC_FREE(frame);
828 return NT_STATUS_NO_MEMORY;
831 session_info->security_token = talloc_zero(session_info,
832 struct security_token);
833 if (session_info->security_token == NULL) {
834 TALLOC_FREE(frame);
835 return NT_STATUS_NO_MEMORY;
839 * Avoid a lot of reallocations and allocate what we'll
840 * use in most cases.
842 session_info->security_token->sids = talloc_zero_array(
843 session_info->security_token,
844 struct dom_sid,
845 user_info_dc->num_sids);
846 if (session_info->security_token->sids == NULL) {
847 TALLOC_FREE(frame);
848 return NT_STATUS_NO_MEMORY;
851 for (i = PRIMARY_USER_SID_INDEX; i < user_info_dc->num_sids; i++) {
852 struct security_token *nt_token = session_info->security_token;
853 int cmp;
856 * S-1-5-88-X-Y sids are only used to give hints
857 * to the unix token construction.
859 * S-1-5-88-1-Y gives the uid=Y
860 * S-1-5-88-2-Y gives the gid=Y
861 * S-1-5-88-3-Y gives flags=Y: AUTH3_UNIX_HINT_*
863 cmp = dom_sid_compare_domain(&global_sid_Unix_NFS,
864 &user_info_dc->sids[i]);
865 if (cmp == 0) {
866 bool match;
867 uint32_t hint = 0;
869 match = sid_peek_rid(&user_info_dc->sids[i], &hint);
870 if (!match) {
871 continue;
874 match = dom_sid_in_domain(&global_sid_Unix_NFS_Users,
875 &user_info_dc->sids[i]);
876 if (match) {
877 if (found_hint_uid) {
878 TALLOC_FREE(frame);
879 return NT_STATUS_INVALID_TOKEN;
881 found_hint_uid = true;
882 hint_uid = (uid_t)hint;
883 continue;
886 match = dom_sid_in_domain(&global_sid_Unix_NFS_Groups,
887 &user_info_dc->sids[i]);
888 if (match) {
889 if (found_hint_gid) {
890 TALLOC_FREE(frame);
891 return NT_STATUS_INVALID_TOKEN;
893 found_hint_gid = true;
894 hint_gid = (gid_t)hint;
895 continue;
898 match = dom_sid_in_domain(&global_sid_Unix_NFS_Mode,
899 &user_info_dc->sids[i]);
900 if (match) {
901 if (found_hint_flags) {
902 TALLOC_FREE(frame);
903 return NT_STATUS_INVALID_TOKEN;
905 found_hint_flags = true;
906 hint_flags = hint;
907 continue;
910 continue;
913 status = add_sid_to_array_unique(nt_token->sids,
914 &user_info_dc->sids[i],
915 &nt_token->sids,
916 &nt_token->num_sids);
917 if (!NT_STATUS_IS_OK(status)) {
918 TALLOC_FREE(frame);
919 return status;
924 * We need at least one usable SID
926 if (session_info->security_token->num_sids == 0) {
927 TALLOC_FREE(frame);
928 return NT_STATUS_INVALID_TOKEN;
932 * We need all tree hints: uid, gid, flags
933 * or none of them.
935 if (found_hint_uid || found_hint_gid || found_hint_flags) {
936 if (!found_hint_uid) {
937 TALLOC_FREE(frame);
938 return NT_STATUS_INVALID_TOKEN;
941 if (!found_hint_gid) {
942 TALLOC_FREE(frame);
943 return NT_STATUS_INVALID_TOKEN;
946 if (!found_hint_flags) {
947 TALLOC_FREE(frame);
948 return NT_STATUS_INVALID_TOKEN;
952 if (session_info->info->authenticated) {
953 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
956 status = finalize_local_nt_token(session_info->security_token,
957 session_info_flags);
958 if (!NT_STATUS_IS_OK(status)) {
959 TALLOC_FREE(frame);
960 return status;
964 * unless set otherwise, the session key is the user session
965 * key from the auth subsystem
967 if (user_info_dc->user_session_key.length != 0) {
968 session_info->session_key = data_blob_dup_talloc(session_info,
969 user_info_dc->user_session_key);
970 if (session_info->session_key.data == NULL) {
971 TALLOC_FREE(frame);
972 return NT_STATUS_NO_MEMORY;
976 if (!(session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)) {
977 goto done;
980 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
981 if (session_info->unix_token == NULL) {
982 TALLOC_FREE(frame);
983 return NT_STATUS_NO_MEMORY;
985 session_info->unix_token->uid = -1;
986 session_info->unix_token->gid = -1;
988 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
989 if (session_info->unix_info == NULL) {
990 TALLOC_FREE(frame);
991 return NT_STATUS_NO_MEMORY;
994 /* Convert the SIDs to uid/gids. */
996 ids = talloc_zero_array(frame, struct unixid,
997 session_info->security_token->num_sids);
998 if (ids == NULL) {
999 TALLOC_FREE(frame);
1000 return NT_STATUS_NO_MEMORY;
1003 if (!(hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS)) {
1004 ok = sids_to_unixids(session_info->security_token->sids,
1005 session_info->security_token->num_sids,
1006 ids);
1007 if (!ok) {
1008 TALLOC_FREE(frame);
1009 return NT_STATUS_NO_MEMORY;
1013 if (found_hint_uid) {
1014 session_info->unix_token->uid = hint_uid;
1015 } else if (ids[0].type == ID_TYPE_UID) {
1017 * The primary SID resolves to a UID only.
1019 session_info->unix_token->uid = ids[0].id;
1020 } else if (ids[0].type == ID_TYPE_BOTH) {
1022 * The primary SID resolves to a UID and GID,
1023 * use it as uid and add it as first element
1024 * to the groups array.
1026 session_info->unix_token->uid = ids[0].id;
1028 ok = add_gid_to_array_unique(session_info->unix_token,
1029 session_info->unix_token->uid,
1030 &session_info->unix_token->groups,
1031 &session_info->unix_token->ngroups);
1032 if (!ok) {
1033 TALLOC_FREE(frame);
1034 return NT_STATUS_NO_MEMORY;
1036 } else {
1038 * It we can't get a uid, we can't imporsonate
1039 * the user.
1041 TALLOC_FREE(frame);
1042 return NT_STATUS_INVALID_TOKEN;
1045 if (found_hint_gid) {
1046 session_info->unix_token->gid = hint_gid;
1047 } else {
1048 need_getpwuid = true;
1051 if (hint_flags & AUTH3_UNIX_HINT_QUALIFIED_NAME) {
1052 session_info->unix_info->unix_name =
1053 talloc_asprintf(session_info->unix_info,
1054 "%s%c%s",
1055 session_info->info->domain_name,
1056 *lp_winbind_separator(),
1057 session_info->info->account_name);
1058 if (session_info->unix_info->unix_name == NULL) {
1059 TALLOC_FREE(frame);
1060 return NT_STATUS_NO_MEMORY;
1062 } else if (hint_flags & AUTH3_UNIX_HINT_ISLOLATED_NAME) {
1063 session_info->unix_info->unix_name =
1064 talloc_strdup(session_info->unix_info,
1065 session_info->info->account_name);
1066 if (session_info->unix_info->unix_name == NULL) {
1067 TALLOC_FREE(frame);
1068 return NT_STATUS_NO_MEMORY;
1070 } else {
1071 need_getpwuid = true;
1074 if (need_getpwuid) {
1075 struct passwd *pwd = NULL;
1078 * Ask the system for the primary gid
1079 * and the real unix name.
1081 pwd = getpwuid_alloc(frame, session_info->unix_token->uid);
1082 if (pwd == NULL) {
1083 TALLOC_FREE(frame);
1084 return NT_STATUS_INVALID_TOKEN;
1086 if (!found_hint_gid) {
1087 session_info->unix_token->gid = pwd->pw_gid;
1090 session_info->unix_info->unix_name =
1091 talloc_strdup(session_info->unix_info, pwd->pw_name);
1092 if (session_info->unix_info->unix_name == NULL) {
1093 TALLOC_FREE(frame);
1094 return NT_STATUS_NO_MEMORY;
1097 TALLOC_FREE(pwd);
1100 ok = add_gid_to_array_unique(session_info->unix_token,
1101 session_info->unix_token->gid,
1102 &session_info->unix_token->groups,
1103 &session_info->unix_token->ngroups);
1104 if (!ok) {
1105 TALLOC_FREE(frame);
1106 return NT_STATUS_NO_MEMORY;
1109 /* This is a potentially untrusted username for use in %U */
1110 session_info->unix_info->sanitized_username =
1111 talloc_alpha_strcpy(session_info->unix_info,
1112 original_user_name,
1113 SAFE_NETBIOS_CHARS "$");
1114 if (session_info->unix_info->sanitized_username == NULL) {
1115 TALLOC_FREE(frame);
1116 return NT_STATUS_NO_MEMORY;
1119 for (i=0; i < session_info->security_token->num_sids; i++) {
1121 if (ids[i].type != ID_TYPE_GID &&
1122 ids[i].type != ID_TYPE_BOTH) {
1123 struct security_token *nt_token =
1124 session_info->security_token;
1125 struct dom_sid_buf buf;
1127 DEBUG(10, ("Could not convert SID %s to gid, "
1128 "ignoring it\n",
1129 dom_sid_str_buf(&nt_token->sids[i], &buf)));
1130 continue;
1133 ok = add_gid_to_array_unique(session_info->unix_token,
1134 ids[i].id,
1135 &session_info->unix_token->groups,
1136 &session_info->unix_token->ngroups);
1137 if (!ok) {
1138 TALLOC_FREE(frame);
1139 return NT_STATUS_NO_MEMORY;
1142 TALLOC_FREE(ids);
1145 * Now we must get any groups this user has been
1146 * added to in /etc/group and merge them in.
1147 * This has to be done in every code path
1148 * that creates an NT token, as remote users
1149 * may have been added to the local /etc/group
1150 * database. Tokens created merely from the
1151 * info3 structs (via the DC or via the krb5 PAC)
1152 * won't have these local groups. Note the
1153 * groups added here will only be UNIX groups
1154 * (S-1-22-2-XXXX groups) as getgroups_unix_user()
1155 * turns off winbindd before calling getgroups().
1157 * NB. This is duplicating work already
1158 * done in the 'unix_user:' case of
1159 * create_token_from_sid() but won't
1160 * do anything other than be inefficient
1161 * in that case.
1163 if (!(hint_flags & AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS)) {
1164 ok = getgroups_unix_user(frame,
1165 session_info->unix_info->unix_name,
1166 session_info->unix_token->gid,
1167 &gids, &num_gids);
1168 if (!ok) {
1169 TALLOC_FREE(frame);
1170 return NT_STATUS_INVALID_TOKEN;
1174 for (i=0; i < num_gids; i++) {
1176 ok = add_gid_to_array_unique(session_info->unix_token,
1177 gids[i],
1178 &session_info->unix_token->groups,
1179 &session_info->unix_token->ngroups);
1180 if (!ok) {
1181 TALLOC_FREE(frame);
1182 return NT_STATUS_NO_MEMORY;
1185 TALLOC_FREE(gids);
1187 if (hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS) {
1189 * We should not translate the unix token uid/gids
1190 * to S-1-22-X-Y SIDs.
1192 goto done;
1196 * Add the "Unix Group" SID for each gid to catch mapped groups
1197 * and their Unix equivalent. This is to solve the backwards
1198 * compatibility problem of 'valid users = +ntadmin' where
1199 * ntadmin has been paired with "Domain Admins" in the group
1200 * mapping table. Otherwise smb.conf would need to be changed
1201 * to 'valid user = "Domain Admins"'. --jerry
1203 * For consistency we also add the "Unix User" SID,
1204 * so that the complete unix token is represented within
1205 * the nt token.
1208 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
1209 status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1210 &session_info->security_token->sids,
1211 &session_info->security_token->num_sids);
1212 if (!NT_STATUS_IS_OK(status)) {
1213 TALLOC_FREE(frame);
1214 return status;
1217 gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
1218 status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1219 &session_info->security_token->sids,
1220 &session_info->security_token->num_sids);
1221 if (!NT_STATUS_IS_OK(status)) {
1222 TALLOC_FREE(frame);
1223 return status;
1226 for (i=0; i < session_info->unix_token->ngroups; i++ ) {
1227 struct security_token *nt_token = session_info->security_token;
1229 gid_to_unix_groups_sid(session_info->unix_token->groups[i],
1230 &tmp_sid);
1231 status = add_sid_to_array_unique(nt_token->sids,
1232 &tmp_sid,
1233 &nt_token->sids,
1234 &nt_token->num_sids);
1235 if (!NT_STATUS_IS_OK(status)) {
1236 TALLOC_FREE(frame);
1237 return status;
1241 done:
1242 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
1243 if (session_info->unix_token != NULL) {
1244 debug_unix_user_token(DBGC_AUTH, 10,
1245 session_info->unix_token->uid,
1246 session_info->unix_token->gid,
1247 session_info->unix_token->ngroups,
1248 session_info->unix_token->groups);
1251 status = log_nt_token(session_info->security_token);
1252 if (!NT_STATUS_IS_OK(status)) {
1253 TALLOC_FREE(frame);
1254 return status;
1257 session_info->unique_session_token = GUID_random();
1259 *session_info_out = talloc_move(mem_ctx, &session_info);
1260 TALLOC_FREE(frame);
1261 return NT_STATUS_OK;
1264 /***************************************************************************
1265 Make (and fill) a server_info struct from a 'struct passwd' by conversion
1266 to a struct samu
1267 ***************************************************************************/
1269 NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
1270 const char *unix_username,
1271 const struct passwd *pwd,
1272 struct auth_serversupplied_info **server_info)
1274 NTSTATUS status;
1275 TALLOC_CTX *tmp_ctx = NULL;
1276 struct auth_serversupplied_info *result;
1278 tmp_ctx = talloc_stackframe();
1279 if (tmp_ctx == NULL) {
1280 return NT_STATUS_NO_MEMORY;
1283 result = make_server_info(tmp_ctx);
1284 if (result == NULL) {
1285 status = NT_STATUS_NO_MEMORY;
1286 goto done;
1289 status = passwd_to_SamInfo3(result,
1290 unix_username,
1291 pwd,
1292 &result->info3,
1293 &result->extra);
1294 if (!NT_STATUS_IS_OK(status)) {
1295 goto done;
1298 result->unix_name = talloc_strdup(result, unix_username);
1299 if (result->unix_name == NULL) {
1300 status = NT_STATUS_NO_MEMORY;
1301 goto done;
1304 result->utok.uid = pwd->pw_uid;
1305 result->utok.gid = pwd->pw_gid;
1307 *server_info = talloc_move(mem_ctx, &result);
1308 status = NT_STATUS_OK;
1309 done:
1310 talloc_free(tmp_ctx);
1312 return status;
1315 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
1316 struct netr_SamInfo3 *info3)
1318 const char *guest_account = lp_guest_account();
1319 struct dom_sid domain_sid;
1320 struct passwd *pwd;
1321 const char *tmp;
1323 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
1324 if (pwd == NULL) {
1325 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
1326 "account [%s]!\n", guest_account));
1327 return NT_STATUS_NO_SUCH_USER;
1330 /* Set account name */
1331 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
1332 if (tmp == NULL) {
1333 return NT_STATUS_NO_MEMORY;
1335 init_lsa_String(&info3->base.account_name, tmp);
1337 /* Set domain name */
1338 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
1339 if (tmp == NULL) {
1340 return NT_STATUS_NO_MEMORY;
1342 init_lsa_StringLarge(&info3->base.logon_domain, tmp);
1344 /* Domain sid */
1345 sid_copy(&domain_sid, get_global_sam_sid());
1347 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
1348 if (info3->base.domain_sid == NULL) {
1349 return NT_STATUS_NO_MEMORY;
1352 /* Guest rid */
1353 info3->base.rid = DOMAIN_RID_GUEST;
1355 /* Primary gid */
1356 info3->base.primary_gid = DOMAIN_RID_GUESTS;
1358 /* Set as guest */
1359 info3->base.user_flags = NETLOGON_GUEST;
1361 TALLOC_FREE(pwd);
1362 return NT_STATUS_OK;
1365 /***************************************************************************
1366 Make (and fill) a user_info struct for a guest login.
1367 This *must* succeed for smbd to start. If there is no mapping entry for
1368 the guest gid, then create one.
1370 The resulting structure is a 'session_info' because
1371 create_local_token() has already been called on it. This is quite
1372 nasty, as the auth subsystem isn't expect this, but the behavior is
1373 left as-is for now.
1374 ***************************************************************************/
1376 static NTSTATUS make_new_session_info_guest(TALLOC_CTX *mem_ctx,
1377 struct auth_session_info **_session_info,
1378 struct auth_serversupplied_info **_server_info)
1380 struct auth_session_info *session_info = NULL;
1381 struct auth_serversupplied_info *server_info = NULL;
1382 const char *guest_account = lp_guest_account();
1383 const char *domain = lp_netbios_name();
1384 struct netr_SamInfo3 info3;
1385 TALLOC_CTX *tmp_ctx;
1386 NTSTATUS status;
1388 tmp_ctx = talloc_stackframe();
1389 if (tmp_ctx == NULL) {
1390 return NT_STATUS_NO_MEMORY;
1393 ZERO_STRUCT(info3);
1395 status = get_guest_info3(tmp_ctx, &info3);
1396 if (!NT_STATUS_IS_OK(status)) {
1397 DEBUG(0, ("get_guest_info3 failed with %s\n",
1398 nt_errstr(status)));
1399 goto done;
1402 status = make_server_info_info3(tmp_ctx,
1403 guest_account,
1404 domain,
1405 &server_info,
1406 &info3);
1407 if (!NT_STATUS_IS_OK(status)) {
1408 DEBUG(0, ("make_server_info_info3 failed with %s\n",
1409 nt_errstr(status)));
1410 goto done;
1413 server_info->guest = true;
1415 /* This should not be done here (we should produce a server
1416 * info, and later construct a session info from it), but for
1417 * now this does not change the previous behavior */
1418 status = create_local_token(tmp_ctx, server_info, NULL,
1419 server_info->info3->base.account_name.string,
1420 &session_info);
1421 if (!NT_STATUS_IS_OK(status)) {
1422 DEBUG(0, ("create_local_token failed: %s\n",
1423 nt_errstr(status)));
1424 goto done;
1428 * It's ugly, but for now it's
1429 * needed to force Builtin_Guests
1430 * here, because memberships of
1431 * Builtin_Guests might be incomplete.
1433 status = add_sid_to_array_unique(session_info->security_token,
1434 &global_sid_Builtin_Guests,
1435 &session_info->security_token->sids,
1436 &session_info->security_token->num_sids);
1437 if (!NT_STATUS_IS_OK(status)) {
1438 DBG_ERR("Failed to force Builtin_Guests to nt token\n");
1439 goto done;
1442 /* annoying, but the Guest really does have a session key, and it is
1443 all zeros! */
1444 session_info->session_key = data_blob_talloc_zero(session_info, 16);
1446 *_session_info = talloc_move(mem_ctx, &session_info);
1447 *_server_info = talloc_move(mem_ctx, &server_info);
1449 status = NT_STATUS_OK;
1450 done:
1451 TALLOC_FREE(tmp_ctx);
1452 return status;
1455 /***************************************************************************
1456 Make (and fill) a auth_session_info struct for a system user login.
1457 This *must* succeed for smbd to start.
1458 ***************************************************************************/
1460 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
1461 struct auth_session_info **session_info)
1463 TALLOC_CTX *frame = talloc_stackframe();
1464 struct auth_user_info_dc *user_info_dc = NULL;
1465 uid_t uid = -1;
1466 gid_t gid = -1;
1467 uint32_t hint_flags = 0;
1468 uint32_t session_info_flags = 0;
1469 NTSTATUS status;
1471 status = auth_system_user_info_dc(frame, lp_netbios_name(),
1472 &user_info_dc);
1473 if (!NT_STATUS_IS_OK(status)) {
1474 DEBUG(0, ("auth_system_user_info_dc failed: %s\n",
1475 nt_errstr(status)));
1476 goto done;
1480 * Just get the initial uid/gid
1481 * and don't expand the unix groups.
1483 uid = sec_initial_uid();
1484 gid = sec_initial_gid();
1485 hint_flags |= AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS;
1488 * Also avoid sid mapping to gids,
1489 * as well as adding the unix_token uid/gids as
1490 * S-1-22-X-Y SIDs to the nt token.
1492 hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS;
1493 hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS;
1496 * The unix name will be "NT AUTHORITY+SYSTEM",
1497 * where '+' is the "winbind separator" character.
1499 hint_flags |= AUTH3_UNIX_HINT_QUALIFIED_NAME;
1500 status = auth3_user_info_dc_add_hints(user_info_dc,
1501 uid,
1502 gid,
1503 hint_flags);
1504 if (!NT_STATUS_IS_OK(status)) {
1505 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1506 nt_errstr(status)));
1507 goto done;
1510 session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1511 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1512 status = auth3_session_info_create(mem_ctx, user_info_dc,
1513 user_info_dc->info->account_name,
1514 session_info_flags,
1515 session_info);
1516 if (!NT_STATUS_IS_OK(status)) {
1517 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1518 nt_errstr(status)));
1519 goto done;
1522 done:
1523 TALLOC_FREE(frame);
1524 return status;
1527 static NTSTATUS make_new_session_info_anonymous(TALLOC_CTX *mem_ctx,
1528 struct auth_session_info **session_info)
1530 TALLOC_CTX *frame = talloc_stackframe();
1531 const char *guest_account = lp_guest_account();
1532 struct auth_user_info_dc *user_info_dc = NULL;
1533 struct passwd *pwd = NULL;
1534 uint32_t hint_flags = 0;
1535 uint32_t session_info_flags = 0;
1536 NTSTATUS status;
1539 * We use the guest account for the unix token
1540 * while we use a true anonymous nt token.
1542 * It's very important to have a separate
1543 * nt token for anonymous.
1546 pwd = Get_Pwnam_alloc(frame, guest_account);
1547 if (pwd == NULL) {
1548 DBG_ERR("Unable to locate guest account [%s]!\n",
1549 guest_account);
1550 status = NT_STATUS_NO_SUCH_USER;
1551 goto done;
1554 status = auth_anonymous_user_info_dc(frame, lp_netbios_name(),
1555 &user_info_dc);
1556 if (!NT_STATUS_IS_OK(status)) {
1557 DEBUG(0, ("auth_anonymous_user_info_dc failed: %s\n",
1558 nt_errstr(status)));
1559 goto done;
1563 * Note we don't pass AUTH3_UNIX_HINT_QUALIFIED_NAME
1564 * nor AUTH3_UNIX_HINT_ISOLATED_NAME here
1565 * as we want the unix name be found by getpwuid_alloc().
1568 status = auth3_user_info_dc_add_hints(user_info_dc,
1569 pwd->pw_uid,
1570 pwd->pw_gid,
1571 hint_flags);
1572 if (!NT_STATUS_IS_OK(status)) {
1573 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1574 nt_errstr(status)));
1575 goto done;
1579 * In future we may want to remove
1580 * AUTH_SESSION_INFO_DEFAULT_GROUPS.
1582 * Similar to Windows with EveryoneIncludesAnonymous
1583 * and RestrictAnonymous.
1585 * We may introduce AUTH_SESSION_INFO_ANON_WORLD...
1587 * But for this is required to keep the existing tests
1588 * working.
1590 session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
1591 session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1592 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1593 status = auth3_session_info_create(mem_ctx, user_info_dc,
1595 session_info_flags,
1596 session_info);
1597 if (!NT_STATUS_IS_OK(status)) {
1598 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1599 nt_errstr(status)));
1600 goto done;
1603 done:
1604 TALLOC_FREE(frame);
1605 return status;
1608 /****************************************************************************
1609 Fake a auth_session_info just from a username (as a
1610 session_info structure, with create_local_token() already called on
1612 ****************************************************************************/
1614 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
1615 const char *username,
1616 bool is_guest,
1617 struct auth_session_info **session_info)
1619 struct passwd *pwd;
1620 NTSTATUS status;
1621 struct auth_serversupplied_info *result;
1622 TALLOC_CTX *tmp_ctx;
1624 tmp_ctx = talloc_stackframe();
1625 if (tmp_ctx == NULL) {
1626 return NT_STATUS_NO_MEMORY;
1629 pwd = Get_Pwnam_alloc(tmp_ctx, username);
1630 if (pwd == NULL) {
1631 status = NT_STATUS_NO_SUCH_USER;
1632 goto done;
1635 status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
1636 if (!NT_STATUS_IS_OK(status)) {
1637 goto done;
1640 result->nss_token = true;
1641 result->guest = is_guest;
1643 /* Now turn the server_info into a session_info with the full token etc */
1644 status = create_local_token(mem_ctx,
1645 result,
1646 NULL,
1647 pwd->pw_name,
1648 session_info);
1650 done:
1651 talloc_free(tmp_ctx);
1653 return status;
1656 /* This function MUST only used to create the cached server_info for
1657 * guest.
1659 * This is a lossy conversion. Variables known to be lost so far
1660 * include:
1662 * - nss_token (not needed because the only read doesn't happen
1663 * for the GUEST user, as this routine populates ->security_token
1665 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1667 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1669 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1670 const struct auth_session_info *src,
1671 struct auth_serversupplied_info *server_info)
1673 struct auth_serversupplied_info *dst;
1674 NTSTATUS status;
1676 dst = make_server_info(mem_ctx);
1677 if (dst == NULL) {
1678 return NULL;
1681 /* This element must be provided to convert back to an auth_serversupplied_info */
1682 SMB_ASSERT(src->unix_info);
1684 dst->guest = true;
1686 /* This element must be provided to convert back to an
1687 * auth_serversupplied_info. This needs to be from the
1688 * auth_session_info because the group values in particular
1689 * may change during create_local_token() processing */
1690 SMB_ASSERT(src->unix_token);
1691 dst->utok.uid = src->unix_token->uid;
1692 dst->utok.gid = src->unix_token->gid;
1693 dst->utok.ngroups = src->unix_token->ngroups;
1694 if (src->unix_token->ngroups != 0) {
1695 dst->utok.groups = (gid_t *)talloc_memdup(
1696 dst, src->unix_token->groups,
1697 sizeof(gid_t)*dst->utok.ngroups);
1698 } else {
1699 dst->utok.groups = NULL;
1702 /* We must have a security_token as otherwise the lossy
1703 * conversion without nss_token would cause create_local_token
1704 * to take the wrong path */
1705 SMB_ASSERT(src->security_token);
1707 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1708 src->session_key.length);
1710 /* This is OK because this functions is only used for the
1711 * GUEST account, which has all-zero keys for both values */
1712 dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1713 src->session_key.length);
1715 status = copy_netr_SamInfo3(dst,
1716 server_info->info3,
1717 &dst->info3);
1718 if (!NT_STATUS_IS_OK(status)) {
1719 TALLOC_FREE(dst);
1720 return NULL;
1723 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1724 if (!dst->unix_name) {
1725 TALLOC_FREE(dst);
1726 return NULL;
1729 dst->cached_session_info = src;
1730 return dst;
1734 * Set a new session key. Used in the rpc server where we have to override the
1735 * SMB level session key with SystemLibraryDTC
1738 bool session_info_set_session_key(struct auth_session_info *info,
1739 DATA_BLOB session_key)
1741 TALLOC_FREE(info->session_key.data);
1743 info->session_key = data_blob_talloc(
1744 info, session_key.data, session_key.length);
1746 return (info->session_key.data != NULL);
1749 static struct auth_session_info *guest_info = NULL;
1750 static struct auth_session_info *anonymous_info = NULL;
1752 static struct auth_serversupplied_info *guest_server_info = NULL;
1754 bool init_guest_session_info(TALLOC_CTX *mem_ctx)
1756 NTSTATUS status;
1758 if (guest_info != NULL)
1759 return true;
1761 status = make_new_session_info_guest(mem_ctx,
1762 &guest_info,
1763 &guest_server_info);
1764 if (!NT_STATUS_IS_OK(status)) {
1765 return false;
1768 status = make_new_session_info_anonymous(mem_ctx,
1769 &anonymous_info);
1770 if (!NT_STATUS_IS_OK(status)) {
1771 return false;
1774 return true;
1777 bool reinit_guest_session_info(TALLOC_CTX *mem_ctx)
1779 TALLOC_FREE(guest_info);
1780 TALLOC_FREE(guest_server_info);
1781 TALLOC_FREE(anonymous_info);
1783 DBG_DEBUG("Reinitialing guest info\n");
1785 return init_guest_session_info(mem_ctx);
1788 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1789 struct auth_serversupplied_info **server_info)
1791 /* This is trickier than it would appear to need to be because
1792 * we are trying to avoid certain costly operations when the
1793 * structure is converted to a 'auth_session_info' again in
1794 * create_local_token() */
1795 *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1796 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1799 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1800 struct auth_session_info **session_info)
1802 *session_info = copy_session_info(mem_ctx, guest_info);
1803 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1806 NTSTATUS make_server_info_anonymous(TALLOC_CTX *mem_ctx,
1807 struct auth_serversupplied_info **server_info)
1809 if (anonymous_info == NULL) {
1810 return NT_STATUS_UNSUCCESSFUL;
1814 * This is trickier than it would appear to need to be because
1815 * we are trying to avoid certain costly operations when the
1816 * structure is converted to a 'auth_session_info' again in
1817 * create_local_token()
1819 * We use a guest server_info, but with the anonymous session info,
1820 * which means create_local_token() will return a copy
1821 * of the anonymous token.
1823 * The server info is just used as legacy in order to
1824 * keep existing code working. Maybe some debug messages
1825 * will still refer to guest instead of anonymous.
1827 *server_info = copy_session_info_serverinfo_guest(mem_ctx, anonymous_info,
1828 guest_server_info);
1829 if (*server_info == NULL) {
1830 return NT_STATUS_NO_MEMORY;
1833 return NT_STATUS_OK;
1836 NTSTATUS make_session_info_anonymous(TALLOC_CTX *mem_ctx,
1837 struct auth_session_info **session_info)
1839 if (anonymous_info == NULL) {
1840 return NT_STATUS_UNSUCCESSFUL;
1843 *session_info = copy_session_info(mem_ctx, anonymous_info);
1844 if (*session_info == NULL) {
1845 return NT_STATUS_NO_MEMORY;
1848 return NT_STATUS_OK;
1851 static struct auth_session_info *system_info = NULL;
1853 NTSTATUS init_system_session_info(TALLOC_CTX *mem_ctx)
1855 if (system_info != NULL)
1856 return NT_STATUS_OK;
1858 return make_new_session_info_system(mem_ctx, &system_info);
1861 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1862 struct auth_session_info **session_info)
1864 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1865 *session_info = copy_session_info(mem_ctx, system_info);
1866 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1869 const struct auth_session_info *get_session_info_system(void)
1871 return system_info;
1874 /***************************************************************************
1875 Purely internal function for make_server_info_info3
1876 ***************************************************************************/
1878 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1879 const char *username,
1880 const struct dom_sid *sid,
1881 char **found_username,
1882 struct passwd **pwd,
1883 bool *username_was_mapped)
1885 char *orig_dom_user = NULL;
1886 char *dom_user = NULL;
1887 char *lower_username = NULL;
1888 char *real_username = NULL;
1889 struct passwd *passwd;
1891 lower_username = talloc_strdup(mem_ctx, username);
1892 if (!lower_username) {
1893 return NT_STATUS_NO_MEMORY;
1895 if (!strlower_m( lower_username )) {
1896 return NT_STATUS_INVALID_PARAMETER;
1899 orig_dom_user = talloc_asprintf(mem_ctx,
1900 "%s%c%s",
1901 domain,
1902 *lp_winbind_separator(),
1903 lower_username);
1904 if (!orig_dom_user) {
1905 return NT_STATUS_NO_MEMORY;
1908 /* Get the passwd struct. Try to create the account if necessary. */
1910 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1911 if (!dom_user) {
1912 return NT_STATUS_NO_MEMORY;
1915 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
1916 if (!passwd && !*username_was_mapped) {
1917 struct dom_sid_buf buf;
1918 uid_t uid;
1919 bool ok;
1921 DBG_DEBUG("Failed to find authenticated user %s via "
1922 "getpwnam(), fallback to sid_to_uid(%s).\n",
1923 dom_user, dom_sid_str_buf(sid, &buf));
1925 ok = sid_to_uid(sid, &uid);
1926 if (!ok) {
1927 DBG_ERR("Failed to convert SID %s to a UID (dom_user[%s])\n",
1928 dom_sid_str_buf(sid, &buf), dom_user);
1929 return NT_STATUS_NO_SUCH_USER;
1931 passwd = getpwuid_alloc(mem_ctx, uid);
1932 if (!passwd) {
1933 DBG_ERR("Failed to find local account with UID %lld for SID %s (dom_user[%s])\n",
1934 (long long)uid,
1935 dom_sid_str_buf(sid, &buf),
1936 dom_user);
1937 return NT_STATUS_NO_SUCH_USER;
1939 real_username = talloc_strdup(mem_ctx, passwd->pw_name);
1941 if (!passwd) {
1942 DEBUG(3, ("Failed to find authenticated user %s via "
1943 "getpwnam(), denying access.\n", dom_user));
1944 return NT_STATUS_NO_SUCH_USER;
1947 if (!real_username) {
1948 return NT_STATUS_NO_MEMORY;
1951 *pwd = passwd;
1953 /* This is pointless -- there is no support for differing
1954 unix and windows names. Make sure to always store the
1955 one we actually looked up and succeeded. Have I mentioned
1956 why I hate the 'winbind use default domain' parameter?
1957 --jerry */
1959 *found_username = talloc_strdup( mem_ctx, real_username );
1961 return NT_STATUS_OK;
1964 /****************************************************************************
1965 Wrapper to allow the getpwnam() call to strip the domain name and
1966 try again in case a local UNIX user is already there. Also run through
1967 the username if we fallback to the username only.
1968 ****************************************************************************/
1970 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1971 char **p_save_username, bool create )
1973 struct passwd *pw = NULL;
1974 char *p = NULL;
1975 const char *username = NULL;
1977 /* we only save a copy of the username it has been mangled
1978 by winbindd use default domain */
1979 *p_save_username = NULL;
1981 /* don't call map_username() here since it has to be done higher
1982 up the stack so we don't call it multiple times */
1984 username = talloc_strdup(mem_ctx, domuser);
1985 if (!username) {
1986 return NULL;
1989 p = strchr_m( username, *lp_winbind_separator() );
1991 /* code for a DOMAIN\user string */
1993 if ( p ) {
1994 const char *domain = NULL;
1996 /* split the domain and username into 2 strings */
1997 *p = '\0';
1998 domain = username;
1999 p++;
2000 username = p;
2002 if (strequal(domain, get_global_sam_name())) {
2004 * This typically don't happen
2005 * as check_sam_Security()
2006 * don't call make_server_info_info3()
2007 * and thus check_account().
2009 * But we better keep this.
2011 goto username_only;
2014 pw = Get_Pwnam_alloc( mem_ctx, domuser );
2015 if (pw == NULL) {
2016 return NULL;
2018 /* make sure we get the case of the username correct */
2019 /* work around 'winbind use default domain = yes' */
2021 if ( lp_winbind_use_default_domain() &&
2022 !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
2023 *p_save_username = talloc_asprintf(mem_ctx,
2024 "%s%c%s",
2025 domain,
2026 *lp_winbind_separator(),
2027 pw->pw_name);
2028 if (!*p_save_username) {
2029 TALLOC_FREE(pw);
2030 return NULL;
2032 } else {
2033 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
2036 /* whew -- done! */
2037 return pw;
2041 /* just lookup a plain username */
2042 username_only:
2043 pw = Get_Pwnam_alloc(mem_ctx, username);
2045 /* Create local user if requested but only if winbindd
2046 is not running. We need to protect against cases
2047 where winbindd is failing and then prematurely
2048 creating users in /etc/passwd */
2050 if ( !pw && create && !winbind_ping() ) {
2051 /* Don't add a machine account. */
2052 if (username[strlen(username)-1] == '$')
2053 return NULL;
2055 _smb_create_user(NULL, username, NULL);
2056 pw = Get_Pwnam_alloc(mem_ctx, username);
2059 /* one last check for a valid passwd struct */
2061 if (pw) {
2062 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
2064 return pw;
2067 /***************************************************************************
2068 Make a server_info struct from the info3 returned by a domain logon
2069 ***************************************************************************/
2071 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
2072 const char *sent_nt_username,
2073 const char *domain,
2074 struct auth_serversupplied_info **server_info,
2075 const struct netr_SamInfo3 *info3)
2077 NTSTATUS nt_status;
2078 char *found_username = NULL;
2079 const char *nt_domain;
2080 const char *nt_username;
2081 struct dom_sid user_sid;
2082 struct dom_sid group_sid;
2083 bool username_was_mapped;
2084 struct passwd *pwd;
2085 struct auth_serversupplied_info *result;
2086 struct dom_sid sid;
2087 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2090 Here is where we should check the list of
2091 trusted domains, and verify that the SID
2092 matches.
2095 if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
2096 nt_status = NT_STATUS_INVALID_PARAMETER;
2097 goto out;
2100 if (!sid_compose(&group_sid, info3->base.domain_sid,
2101 info3->base.primary_gid)) {
2102 nt_status = NT_STATUS_INVALID_PARAMETER;
2103 goto out;
2106 nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
2107 if (!nt_username) {
2108 /* If the server didn't give us one, just use the one we sent
2109 * them */
2110 nt_username = sent_nt_username;
2113 nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
2114 if (!nt_domain) {
2115 /* If the server didn't give us one, just use the one we sent
2116 * them */
2117 nt_domain = domain;
2120 /* If getpwnam() fails try the add user script (2.2.x behavior).
2122 We use the _unmapped_ username here in an attempt to provide
2123 consistent username mapping behavior between kerberos and NTLM[SSP]
2124 authentication in domain mode security. I.E. Username mapping
2125 should be applied to the fully qualified username
2126 (e.g. DOMAIN\user) and not just the login name. Yes this means we
2127 called map_username() unnecessarily in make_user_info_map() but
2128 that is how the current code is designed. Making the change here
2129 is the least disruptive place. -- jerry */
2131 /* this call will try to create the user if necessary */
2133 sid_copy(&sid, info3->base.domain_sid);
2134 sid_append_rid(&sid, info3->base.rid);
2136 nt_status = check_account(tmp_ctx,
2137 nt_domain,
2138 nt_username,
2139 &sid,
2140 &found_username,
2141 &pwd,
2142 &username_was_mapped);
2144 if (!NT_STATUS_IS_OK(nt_status)) {
2145 /* Handle 'map to guest = Bad Uid */
2146 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
2147 (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
2148 lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
2149 DBG_NOTICE("Try to map %s to guest account",
2150 nt_username);
2151 nt_status = make_server_info_guest(tmp_ctx, &result);
2152 if (NT_STATUS_IS_OK(nt_status)) {
2153 *server_info = talloc_move(mem_ctx, &result);
2156 goto out;
2157 } else if ((lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
2158 !is_myname(domain) && pwd->pw_uid < lp_min_domain_uid()) {
2160 * !is_myname(domain) because when smbd starts tries to setup
2161 * the guest user info, calling this function with nobody
2162 * username. Nobody is usually uid 65535 but it can be changed
2163 * to a regular user with 'guest account' parameter
2165 nt_status = NT_STATUS_INVALID_TOKEN;
2166 DBG_NOTICE("Username '%s%s%s' is invalid on this system, "
2167 "it does not meet 'min domain uid' "
2168 "restriction (%u < %u): %s\n",
2169 nt_domain, lp_winbind_separator(), nt_username,
2170 pwd->pw_uid, lp_min_domain_uid(),
2171 nt_errstr(nt_status));
2172 goto out;
2175 result = make_server_info(tmp_ctx);
2176 if (result == NULL) {
2177 DEBUG(4, ("make_server_info failed!\n"));
2178 nt_status = NT_STATUS_NO_MEMORY;
2179 goto out;
2182 result->unix_name = talloc_strdup(result, found_username);
2184 /* copy in the info3 */
2185 nt_status = copy_netr_SamInfo3(result,
2186 info3,
2187 &result->info3);
2188 if (!NT_STATUS_IS_OK(nt_status)) {
2189 goto out;
2192 /* Fill in the unix info we found on the way */
2194 result->utok.uid = pwd->pw_uid;
2195 result->utok.gid = pwd->pw_gid;
2197 /* ensure we are never given NULL session keys */
2199 if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
2200 result->session_key = data_blob_null;
2201 } else {
2202 result->session_key = data_blob_talloc(
2203 result, info3->base.key.key,
2204 sizeof(info3->base.key.key));
2207 if (all_zero(info3->base.LMSessKey.key,
2208 sizeof(info3->base.LMSessKey.key))) {
2209 result->lm_session_key = data_blob_null;
2210 } else {
2211 result->lm_session_key = data_blob_talloc(
2212 result, info3->base.LMSessKey.key,
2213 sizeof(info3->base.LMSessKey.key));
2216 result->nss_token |= username_was_mapped;
2218 result->guest = (info3->base.user_flags & NETLOGON_GUEST);
2220 *server_info = talloc_move(mem_ctx, &result);
2222 nt_status = NT_STATUS_OK;
2223 out:
2224 talloc_free(tmp_ctx);
2226 return nt_status;
2229 /*****************************************************************************
2230 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
2231 ******************************************************************************/
2233 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
2234 const char *sent_nt_username,
2235 const char *domain,
2236 const struct wbcAuthUserInfo *info,
2237 struct auth_serversupplied_info **server_info)
2239 struct netr_SamInfo3 info3;
2240 struct netr_SamInfo6 *info6;
2242 info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
2243 if (!info6) {
2244 return NT_STATUS_NO_MEMORY;
2247 info3.base = info6->base;
2248 info3.sidcount = info6->sidcount;
2249 info3.sids = info6->sids;
2251 return make_server_info_info3(mem_ctx,
2252 sent_nt_username, domain,
2253 server_info, &info3);
2257 * Verify whether or not given domain is trusted.
2259 * This should only be used on a DC.
2261 * @param domain_name name of the domain to be verified
2262 * @return true if domain is one of the trusted ones or
2263 * false if otherwise
2266 bool is_trusted_domain(const char* dom_name)
2268 bool ret;
2270 if (!IS_DC) {
2271 return false;
2274 if (dom_name == NULL || dom_name[0] == '\0') {
2275 return false;
2278 if (strequal(dom_name, get_global_sam_name())) {
2279 return false;
2282 become_root();
2283 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2284 "[%s]\n", dom_name ));
2285 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2286 unbecome_root();
2288 return ret;
2294 on a logon error possibly map the error to success if "map to guest"
2295 is set approriately
2297 NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
2298 NTSTATUS status,
2299 const char *user,
2300 const char *domain,
2301 struct auth_serversupplied_info **server_info)
2303 user = user ? user : "";
2304 domain = domain ? domain : "";
2306 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2307 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
2308 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
2309 DEBUG(3,("No such user %s [%s] - using guest account\n",
2310 user, domain));
2311 return make_server_info_guest(mem_ctx, server_info);
2313 } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2314 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
2315 DEBUG(3,("Registered username %s for guest access\n",
2316 user));
2317 return make_server_info_guest(mem_ctx, server_info);
2321 return status;
2325 Extract session key from a session info and return it in a blob
2326 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
2328 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
2329 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
2331 Note that returned session_key is referencing the original key, it is supposed to be
2332 short-lived. If original session_info->session_key is gone, the reference will be broken.
2334 NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
2337 if (session_key == NULL || session_info == NULL) {
2338 return NT_STATUS_INVALID_PARAMETER;
2341 if (session_info->session_key.length == 0) {
2342 return NT_STATUS_NO_USER_SESSION_KEY;
2345 *session_key = session_info->session_key;
2346 if (intent == KEY_USE_16BYTES) {
2347 session_key->length = MIN(session_info->session_key.length, 16);
2349 return NT_STATUS_OK;