auth/credentials: don't ignore "client use kerberos" and --use-kerberos for machine...
[Samba.git] / source3 / auth / auth_util.c
blobabc5e959aabc41ed5c41b6be42193b01503470a2
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 "dom_sid.h"
25 #include "includes.h"
26 #include "auth.h"
27 #include "lib/util_unixsids.h"
28 #include "../libcli/auth/libcli_auth.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"
39 #include "rpc_client/util_netlogon.h"
40 #include "source4/auth/auth.h"
41 #include "auth/auth_util.h"
42 #include "source3/lib/substitute.h"
44 #undef DBGC_CLASS
45 #define DBGC_CLASS DBGC_AUTH
47 /****************************************************************************
48 Create a UNIX user on demand.
49 ****************************************************************************/
51 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
53 TALLOC_CTX *ctx = talloc_tos();
54 const struct loadparm_substitution *lp_sub =
55 loadparm_s3_global_substitution();
56 char *add_script;
57 int ret;
59 add_script = lp_add_user_script(ctx, lp_sub);
60 if (!add_script || !*add_script) {
61 return -1;
63 add_script = talloc_all_string_sub(ctx,
64 add_script,
65 "%u",
66 unix_username);
67 if (!add_script) {
68 return -1;
70 if (domain) {
71 add_script = talloc_all_string_sub(ctx,
72 add_script,
73 "%D",
74 domain);
75 if (!add_script) {
76 return -1;
79 if (homedir) {
80 add_script = talloc_all_string_sub(ctx,
81 add_script,
82 "%H",
83 homedir);
84 if (!add_script) {
85 return -1;
88 ret = smbrun(add_script, NULL, NULL);
89 flush_pwnam_cache();
90 DEBUG(ret ? 0 : 3,
91 ("smb_create_user: Running the command `%s' gave %d\n",
92 add_script,ret));
93 return ret;
96 /****************************************************************************
97 Create an auth_usersupplied_data structure after appropriate mapping.
98 ****************************************************************************/
100 NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
101 struct auth_usersupplied_info **user_info,
102 const char *smb_name,
103 const char *client_domain,
104 const char *workstation_name,
105 const struct tsocket_address *remote_address,
106 const struct tsocket_address *local_address,
107 const char *service_description,
108 const DATA_BLOB *lm_pwd,
109 const DATA_BLOB *nt_pwd,
110 const struct samr_Password *lm_interactive_pwd,
111 const struct samr_Password *nt_interactive_pwd,
112 const char *plaintext,
113 enum auth_password_state password_state)
115 const char *domain;
116 NTSTATUS result;
117 bool was_mapped;
118 char *internal_username = NULL;
120 was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
121 if (!internal_username) {
122 return NT_STATUS_NO_MEMORY;
125 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
126 client_domain, smb_name, workstation_name));
129 * We let the auth stack canonicalize, username
130 * and domain.
132 domain = client_domain;
134 result = make_user_info(mem_ctx, user_info, smb_name, internal_username,
135 client_domain, domain, workstation_name,
136 remote_address, local_address,
137 service_description, lm_pwd, nt_pwd,
138 lm_interactive_pwd, nt_interactive_pwd,
139 plaintext, password_state);
140 if (NT_STATUS_IS_OK(result)) {
141 /* did we actually map the user to a different name? */
142 (*user_info)->was_mapped = was_mapped;
144 return result;
147 /****************************************************************************
148 Create an auth_usersupplied_data, making the DATA_BLOBs here.
149 Decrypt and encrypt the passwords.
150 ****************************************************************************/
152 bool make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
153 struct auth_usersupplied_info **user_info,
154 const char *smb_name,
155 const char *client_domain,
156 const char *workstation_name,
157 const struct tsocket_address *remote_address,
158 const struct tsocket_address *local_address,
159 uint32_t logon_parameters,
160 const uchar *lm_network_pwd,
161 int lm_pwd_len,
162 const uchar *nt_network_pwd,
163 int nt_pwd_len)
165 bool ret;
166 NTSTATUS status;
167 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
168 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
170 status = make_user_info_map(mem_ctx, user_info,
171 smb_name, client_domain,
172 workstation_name,
173 remote_address,
174 local_address,
175 "SamLogon",
176 lm_pwd_len ? &lm_blob : NULL,
177 nt_pwd_len ? &nt_blob : NULL,
178 NULL, NULL, NULL,
179 AUTH_PASSWORD_RESPONSE);
181 if (NT_STATUS_IS_OK(status)) {
182 (*user_info)->logon_parameters = logon_parameters;
184 ret = NT_STATUS_IS_OK(status) ? true : false;
186 data_blob_free(&lm_blob);
187 data_blob_free(&nt_blob);
188 return ret;
191 /****************************************************************************
192 Create an auth_usersupplied_data, making the DATA_BLOBs here.
193 Decrypt and encrypt the passwords.
194 ****************************************************************************/
196 bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
197 struct auth_usersupplied_info **user_info,
198 const char *smb_name,
199 const char *client_domain,
200 const char *workstation_name,
201 const struct tsocket_address *remote_address,
202 const struct tsocket_address *local_address,
203 uint32_t logon_parameters,
204 const uchar chal[8],
205 const uchar lm_interactive_pwd[16],
206 const uchar nt_interactive_pwd[16])
208 struct samr_Password lm_pwd;
209 struct samr_Password nt_pwd;
210 unsigned char local_lm_response[24];
211 unsigned char local_nt_response[24];
212 int rc;
214 if (lm_interactive_pwd)
215 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
217 if (nt_interactive_pwd)
218 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
220 if (lm_interactive_pwd) {
221 rc = SMBOWFencrypt(lm_pwd.hash, chal,
222 local_lm_response);
223 if (rc != 0) {
224 return false;
228 if (nt_interactive_pwd) {
229 rc = SMBOWFencrypt(nt_pwd.hash, chal,
230 local_nt_response);
231 if (rc != 0) {
232 return false;
237 bool ret;
238 NTSTATUS nt_status;
239 DATA_BLOB local_lm_blob = data_blob_null;
240 DATA_BLOB local_nt_blob = data_blob_null;
242 if (lm_interactive_pwd) {
243 local_lm_blob = data_blob(local_lm_response,
244 sizeof(local_lm_response));
247 if (nt_interactive_pwd) {
248 local_nt_blob = data_blob(local_nt_response,
249 sizeof(local_nt_response));
252 nt_status = make_user_info_map(
253 mem_ctx,
254 user_info,
255 smb_name, client_domain, workstation_name,
256 remote_address,
257 local_address,
258 "SamLogon",
259 lm_interactive_pwd ? &local_lm_blob : NULL,
260 nt_interactive_pwd ? &local_nt_blob : NULL,
261 lm_interactive_pwd ? &lm_pwd : NULL,
262 nt_interactive_pwd ? &nt_pwd : NULL,
263 NULL, AUTH_PASSWORD_HASH);
265 if (NT_STATUS_IS_OK(nt_status)) {
266 (*user_info)->logon_parameters = logon_parameters;
267 (*user_info)->flags |= USER_INFO_INTERACTIVE_LOGON;
270 ret = NT_STATUS_IS_OK(nt_status) ? true : false;
271 data_blob_free(&local_lm_blob);
272 data_blob_free(&local_nt_blob);
273 return ret;
278 /****************************************************************************
279 Create an auth_usersupplied_data structure
280 ****************************************************************************/
282 bool make_user_info_for_reply(TALLOC_CTX *mem_ctx,
283 struct auth_usersupplied_info **user_info,
284 const char *smb_name,
285 const char *client_domain,
286 const struct tsocket_address *remote_address,
287 const struct tsocket_address *local_address,
288 const char *service_description,
289 const uint8_t chal[8],
290 DATA_BLOB plaintext_password)
293 DATA_BLOB local_lm_blob;
294 DATA_BLOB local_nt_blob;
295 NTSTATUS ret;
296 char *plaintext_password_string;
298 * Not encrypted - do so.
301 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
302 "format.\n"));
303 if (plaintext_password.data && plaintext_password.length) {
304 unsigned char local_lm_response[24];
306 #ifdef DEBUG_PASSWORD
307 DEBUG(10,("Unencrypted password (len %d):\n",
308 (int)plaintext_password.length));
309 dump_data(100, plaintext_password.data,
310 plaintext_password.length);
311 #endif
313 SMBencrypt( (const char *)plaintext_password.data,
314 (const uchar*)chal, local_lm_response);
315 local_lm_blob = data_blob(local_lm_response, 24);
317 /* We can't do an NT hash here, as the password needs to be
318 case insensitive */
319 local_nt_blob = data_blob_null;
320 } else {
321 local_lm_blob = data_blob_null;
322 local_nt_blob = data_blob_null;
325 plaintext_password_string = talloc_strndup(talloc_tos(),
326 (const char *)plaintext_password.data,
327 plaintext_password.length);
328 if (!plaintext_password_string) {
329 return false;
332 ret = make_user_info(mem_ctx,
333 user_info, smb_name, smb_name, client_domain, client_domain,
334 get_remote_machine_name(),
335 remote_address,
336 local_address,
337 service_description,
338 local_lm_blob.data ? &local_lm_blob : NULL,
339 local_nt_blob.data ? &local_nt_blob : NULL,
340 NULL, NULL,
341 plaintext_password_string,
342 AUTH_PASSWORD_PLAIN);
344 if (plaintext_password_string) {
345 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
346 talloc_free(plaintext_password_string);
349 data_blob_free(&local_lm_blob);
350 return NT_STATUS_IS_OK(ret) ? true : false;
353 /****************************************************************************
354 Create an auth_usersupplied_data structure
355 ****************************************************************************/
357 NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
358 struct auth_usersupplied_info **user_info,
359 const char *smb_name,
360 const char *client_domain,
361 const struct tsocket_address *remote_address,
362 const struct tsocket_address *local_address,
363 const char *service_description,
364 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
366 bool allow_raw = lp_raw_ntlmv2_auth();
368 if (!allow_raw && nt_resp.length >= 48) {
370 * NTLMv2_RESPONSE has at least 48 bytes
371 * and should only be supported via NTLMSSP.
373 DEBUG(2,("Rejecting raw NTLMv2 authentication with "
374 "user [%s\\%s] from[%s]\n",
375 client_domain, smb_name,
376 tsocket_address_string(remote_address, mem_ctx)));
377 return NT_STATUS_INVALID_PARAMETER;
380 return make_user_info(mem_ctx,
381 user_info, smb_name, smb_name,
382 client_domain, client_domain,
383 get_remote_machine_name(),
384 remote_address,
385 local_address,
386 service_description,
387 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
388 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
389 NULL, NULL, NULL,
390 AUTH_PASSWORD_RESPONSE);
393 /****************************************************************************
394 Create a guest user_info blob, for anonymous authentication.
395 ****************************************************************************/
397 bool make_user_info_guest(TALLOC_CTX *mem_ctx,
398 const struct tsocket_address *remote_address,
399 const struct tsocket_address *local_address,
400 const char *service_description,
401 struct auth_usersupplied_info **user_info)
403 NTSTATUS nt_status;
405 nt_status = make_user_info(mem_ctx,
406 user_info,
407 "","",
408 "","",
410 remote_address,
411 local_address,
412 service_description,
413 NULL, NULL,
414 NULL, NULL,
415 NULL,
416 AUTH_PASSWORD_RESPONSE);
418 return NT_STATUS_IS_OK(nt_status) ? true : false;
421 static NTSTATUS log_nt_token(struct security_token *token)
423 TALLOC_CTX *frame = talloc_stackframe();
424 const struct loadparm_substitution *lp_sub =
425 loadparm_s3_global_substitution();
426 char *command;
427 char *group_sidstr;
428 struct dom_sid_buf buf;
429 size_t i;
431 if ((lp_log_nt_token_command(frame, lp_sub) == NULL) ||
432 (strlen(lp_log_nt_token_command(frame, lp_sub)) == 0)) {
433 TALLOC_FREE(frame);
434 return NT_STATUS_OK;
437 group_sidstr = talloc_strdup(frame, "");
438 for (i=1; i<token->num_sids; i++) {
439 group_sidstr = talloc_asprintf(
440 frame, "%s %s", group_sidstr,
441 dom_sid_str_buf(&token->sids[i], &buf));
444 command = talloc_string_sub(
445 frame, lp_log_nt_token_command(frame, lp_sub),
446 "%s", dom_sid_str_buf(&token->sids[0], &buf));
447 command = talloc_string_sub(frame, command, "%t", group_sidstr);
449 if (command == NULL) {
450 TALLOC_FREE(frame);
451 return NT_STATUS_NO_MEMORY;
454 DEBUG(8, ("running command: [%s]\n", command));
455 if (smbrun(command, NULL, NULL) != 0) {
456 DEBUG(0, ("Could not log NT token\n"));
457 TALLOC_FREE(frame);
458 return NT_STATUS_ACCESS_DENIED;
461 TALLOC_FREE(frame);
462 return NT_STATUS_OK;
466 * Create the token to use from server_info->info3 and
467 * server_info->sids (the info3/sam groups). Find the unix gids.
470 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
471 const struct auth_serversupplied_info *server_info,
472 DATA_BLOB *session_key,
473 const char *smb_username, /* for ->sanitized_username, for %U subs */
474 struct auth_session_info **session_info_out)
476 struct security_token *t;
477 NTSTATUS status;
478 size_t i;
479 struct dom_sid tmp_sid;
480 struct auth_session_info *session_info = NULL;
481 struct unixid *ids;
482 bool is_allowed = false;
484 /* Ensure we can't possible take a code path leading to a
485 * null deref. */
486 if (!server_info) {
487 return NT_STATUS_LOGON_FAILURE;
490 if (is_allowed_domain(server_info->info3->base.logon_domain.string)) {
491 is_allowed = true;
494 /* Check if we have extra info about the user. */
495 if (dom_sid_in_domain(&global_sid_Unix_Users,
496 &server_info->extra.user_sid) ||
497 dom_sid_in_domain(&global_sid_Unix_Groups,
498 &server_info->extra.pgid_sid))
500 is_allowed = true;
503 if (!is_allowed) {
504 DBG_NOTICE("Authentication failed for user [%s] "
505 "from firewalled domain [%s]\n",
506 server_info->info3->base.account_name.string,
507 server_info->info3->base.logon_domain.string);
508 return NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
511 if (server_info->cached_session_info != NULL) {
512 session_info = copy_session_info(mem_ctx,
513 server_info->cached_session_info);
514 if (session_info == NULL) {
515 goto nomem;
518 /* This is a potentially untrusted username for use in %U */
519 session_info->unix_info->sanitized_username =
520 talloc_alpha_strcpy(session_info->unix_info,
521 smb_username,
522 SAFE_NETBIOS_CHARS "$");
523 if (session_info->unix_info->sanitized_username == NULL) {
524 goto nomem;
527 session_info->unique_session_token = GUID_random();
529 *session_info_out = session_info;
530 return NT_STATUS_OK;
533 session_info = talloc_zero(mem_ctx, struct auth_session_info);
534 if (!session_info) {
535 goto nomem;
538 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
539 if (!session_info->unix_token) {
540 goto nomem;
543 session_info->unix_token->uid = server_info->utok.uid;
544 session_info->unix_token->gid = server_info->utok.gid;
546 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
547 if (!session_info->unix_info) {
548 goto nomem;
551 session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
552 if (!session_info->unix_info->unix_name) {
553 goto nomem;
556 /* This is a potentially untrusted username for use in %U */
557 session_info->unix_info->sanitized_username =
558 talloc_alpha_strcpy(session_info->unix_info,
559 smb_username,
560 SAFE_NETBIOS_CHARS "$");
561 if (session_info->unix_info->sanitized_username == NULL) {
562 goto nomem;
565 if (session_key) {
566 data_blob_free(&session_info->session_key);
567 session_info->session_key = data_blob_talloc(session_info,
568 session_key->data,
569 session_key->length);
570 if (!session_info->session_key.data && session_key->length) {
571 goto nomem;
573 } else {
574 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
575 server_info->session_key.length);
578 /* We need to populate session_info->info with the information found in server_info->info3 */
579 status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
580 server_info->guest == false,
581 &session_info->info);
582 if (!NT_STATUS_IS_OK(status)) {
583 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
584 goto fail;
588 * If the user name was mapped to some local unix user,
589 * we can not make much use of the SIDs the
590 * domain controller provided us with.
592 if (server_info->nss_token) {
593 char *found_username = NULL;
594 status = create_token_from_username(session_info,
595 server_info->unix_name,
596 server_info->guest,
597 &session_info->unix_token->uid,
598 &session_info->unix_token->gid,
599 &found_username,
600 &session_info->security_token);
601 if (NT_STATUS_IS_OK(status)) {
602 session_info->unix_info->unix_name = found_username;
604 } else {
605 status = create_local_nt_token_from_info3(session_info,
606 server_info->guest,
607 server_info->info3,
608 &server_info->extra,
609 &session_info->security_token);
612 if (!NT_STATUS_IS_OK(status)) {
613 goto fail;
616 /* Convert the SIDs to gids. */
618 session_info->unix_token->ngroups = 0;
619 session_info->unix_token->groups = NULL;
621 t = session_info->security_token;
623 ids = talloc_array(talloc_tos(), struct unixid,
624 t->num_sids);
625 if (ids == NULL) {
626 goto nomem;
629 if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
630 goto nomem;
633 for (i=0; i<t->num_sids; i++) {
635 if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
636 continue;
639 if (ids[i].type != ID_TYPE_GID &&
640 ids[i].type != ID_TYPE_BOTH) {
641 struct dom_sid_buf buf;
642 DEBUG(10, ("Could not convert SID %s to gid, "
643 "ignoring it\n",
644 dom_sid_str_buf(&t->sids[i], &buf)));
645 continue;
647 if (!add_gid_to_array_unique(session_info->unix_token,
648 ids[i].id,
649 &session_info->unix_token->groups,
650 &session_info->unix_token->ngroups)) {
651 goto nomem;
656 * Add the "Unix Group" SID for each gid to catch mapped groups
657 * and their Unix equivalent. This is to solve the backwards
658 * compatibility problem of 'valid users = +ntadmin' where
659 * ntadmin has been paired with "Domain Admins" in the group
660 * mapping table. Otherwise smb.conf would need to be changed
661 * to 'valid user = "Domain Admins"'. --jerry
663 * For consistency we also add the "Unix User" SID,
664 * so that the complete unix token is represented within
665 * the nt token.
668 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
669 status = add_sid_to_array_unique(
670 session_info->security_token,
671 &tmp_sid,
672 &session_info->security_token->sids,
673 &session_info->security_token->num_sids);
674 if (!NT_STATUS_IS_OK(status)) {
675 goto fail;
678 gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
679 status = add_sid_to_array_unique(
680 session_info->security_token,
681 &tmp_sid,
682 &session_info->security_token->sids,
683 &session_info->security_token->num_sids);
684 if (!NT_STATUS_IS_OK(status)) {
685 goto fail;
688 for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
689 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
690 status = add_sid_to_array_unique(
691 session_info->security_token,
692 &tmp_sid,
693 &session_info->security_token->sids,
694 &session_info->security_token->num_sids);
695 if (!NT_STATUS_IS_OK(status)) {
696 goto fail;
700 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
701 debug_unix_user_token(DBGC_AUTH, 10,
702 session_info->unix_token->uid,
703 session_info->unix_token->gid,
704 session_info->unix_token->ngroups,
705 session_info->unix_token->groups);
707 status = log_nt_token(session_info->security_token);
708 if (!NT_STATUS_IS_OK(status)) {
709 goto fail;
712 session_info->unique_session_token = GUID_random();
714 *session_info_out = session_info;
715 return NT_STATUS_OK;
716 nomem:
717 status = NT_STATUS_NO_MEMORY;
718 fail:
719 TALLOC_FREE(session_info);
720 return status;
723 NTSTATUS auth3_user_info_dc_add_hints(struct auth_user_info_dc *user_info_dc,
724 uid_t uid,
725 gid_t gid,
726 uint32_t flags)
728 uint32_t orig_num_sids = user_info_dc->num_sids;
729 struct dom_sid tmp_sid = { 0, };
730 NTSTATUS status;
733 * We add S-5-88-1-X in order to pass the uid
734 * for the unix token.
736 sid_compose(&tmp_sid,
737 &global_sid_Unix_NFS_Users,
738 (uint32_t)uid);
739 status = add_sid_to_array_attrs_unique(user_info_dc->sids,
740 &tmp_sid,
741 SE_GROUP_DEFAULT_FLAGS,
742 &user_info_dc->sids,
743 &user_info_dc->num_sids);
744 if (!NT_STATUS_IS_OK(status)) {
745 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
746 nt_errstr(status)));
747 goto fail;
751 * We add S-5-88-2-X in order to pass the gid
752 * for the unix token.
754 sid_compose(&tmp_sid,
755 &global_sid_Unix_NFS_Groups,
756 (uint32_t)gid);
757 status = add_sid_to_array_attrs_unique(user_info_dc->sids,
758 &tmp_sid,
759 SE_GROUP_DEFAULT_FLAGS,
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;
769 * We add S-5-88-3-X in order to pass some flags
770 * (AUTH3_UNIX_HINT_*) to auth3_create_session_info().
772 sid_compose(&tmp_sid,
773 &global_sid_Unix_NFS_Mode,
774 flags);
775 status = add_sid_to_array_attrs_unique(user_info_dc->sids,
776 &tmp_sid,
777 SE_GROUP_DEFAULT_FLAGS,
778 &user_info_dc->sids,
779 &user_info_dc->num_sids);
780 if (!NT_STATUS_IS_OK(status)) {
781 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
782 nt_errstr(status)));
783 goto fail;
786 return NT_STATUS_OK;
788 fail:
789 user_info_dc->num_sids = orig_num_sids;
790 return status;
793 static NTSTATUS auth3_session_info_create(
794 TALLOC_CTX *mem_ctx,
795 const struct auth_user_info_dc *user_info_dc,
796 const char *original_user_name,
797 uint32_t session_info_flags,
798 struct auth_session_info **session_info_out)
800 TALLOC_CTX *frame = talloc_stackframe();
801 struct auth_session_info *session_info = NULL;
802 uid_t hint_uid = -1;
803 bool found_hint_uid = false;
804 uid_t hint_gid = -1;
805 bool found_hint_gid = false;
806 uint32_t hint_flags = 0;
807 bool found_hint_flags = false;
808 bool need_getpwuid = false;
809 struct unixid *ids = NULL;
810 uint32_t num_gids = 0;
811 gid_t *gids = NULL;
812 struct dom_sid tmp_sid = { 0, };
813 NTSTATUS status;
814 size_t i;
815 bool ok;
817 *session_info_out = NULL;
819 if (user_info_dc->num_sids == 0) {
820 TALLOC_FREE(frame);
821 return NT_STATUS_INVALID_TOKEN;
824 if (user_info_dc->info == NULL) {
825 TALLOC_FREE(frame);
826 return NT_STATUS_INVALID_TOKEN;
829 if (user_info_dc->info->account_name == NULL) {
830 TALLOC_FREE(frame);
831 return NT_STATUS_INVALID_TOKEN;
834 session_info = talloc_zero(mem_ctx, struct auth_session_info);
835 if (session_info == NULL) {
836 TALLOC_FREE(frame);
837 return NT_STATUS_NO_MEMORY;
839 /* keep this under frame for easier cleanup */
840 talloc_reparent(mem_ctx, frame, session_info);
842 session_info->info = auth_user_info_copy(session_info,
843 user_info_dc->info);
844 if (session_info->info == NULL) {
845 TALLOC_FREE(frame);
846 return NT_STATUS_NO_MEMORY;
849 session_info->security_token = talloc_zero(session_info,
850 struct security_token);
851 if (session_info->security_token == NULL) {
852 TALLOC_FREE(frame);
853 return NT_STATUS_NO_MEMORY;
857 * Avoid a lot of reallocations and allocate what we'll
858 * use in most cases.
860 session_info->security_token->sids = talloc_zero_array(
861 session_info->security_token,
862 struct dom_sid,
863 user_info_dc->num_sids);
864 if (session_info->security_token->sids == NULL) {
865 TALLOC_FREE(frame);
866 return NT_STATUS_NO_MEMORY;
869 for (i = PRIMARY_USER_SID_INDEX; i < user_info_dc->num_sids; i++) {
870 struct security_token *nt_token = session_info->security_token;
871 int cmp;
874 * S-1-5-88-X-Y sids are only used to give hints
875 * to the unix token construction.
877 * S-1-5-88-1-Y gives the uid=Y
878 * S-1-5-88-2-Y gives the gid=Y
879 * S-1-5-88-3-Y gives flags=Y: AUTH3_UNIX_HINT_*
881 cmp = dom_sid_compare_domain(&global_sid_Unix_NFS,
882 &user_info_dc->sids[i].sid);
883 if (cmp == 0) {
884 bool match;
885 uint32_t hint = 0;
887 match = sid_peek_rid(&user_info_dc->sids[i].sid, &hint);
888 if (!match) {
889 continue;
892 match = dom_sid_in_domain(&global_sid_Unix_NFS_Users,
893 &user_info_dc->sids[i].sid);
894 if (match) {
895 if (found_hint_uid) {
896 TALLOC_FREE(frame);
897 return NT_STATUS_INVALID_TOKEN;
899 found_hint_uid = true;
900 hint_uid = (uid_t)hint;
901 continue;
904 match = dom_sid_in_domain(&global_sid_Unix_NFS_Groups,
905 &user_info_dc->sids[i].sid);
906 if (match) {
907 if (found_hint_gid) {
908 TALLOC_FREE(frame);
909 return NT_STATUS_INVALID_TOKEN;
911 found_hint_gid = true;
912 hint_gid = (gid_t)hint;
913 continue;
916 match = dom_sid_in_domain(&global_sid_Unix_NFS_Mode,
917 &user_info_dc->sids[i].sid);
918 if (match) {
919 if (found_hint_flags) {
920 TALLOC_FREE(frame);
921 return NT_STATUS_INVALID_TOKEN;
923 found_hint_flags = true;
924 hint_flags = hint;
925 continue;
928 continue;
931 status = add_sid_to_array_unique(nt_token->sids,
932 &user_info_dc->sids[i].sid,
933 &nt_token->sids,
934 &nt_token->num_sids);
935 if (!NT_STATUS_IS_OK(status)) {
936 TALLOC_FREE(frame);
937 return status;
942 * We need at least one usable SID
944 if (session_info->security_token->num_sids == 0) {
945 TALLOC_FREE(frame);
946 return NT_STATUS_INVALID_TOKEN;
950 * We need all tree hints: uid, gid, flags
951 * or none of them.
953 if (found_hint_uid || found_hint_gid || found_hint_flags) {
954 if (!found_hint_uid) {
955 TALLOC_FREE(frame);
956 return NT_STATUS_INVALID_TOKEN;
959 if (!found_hint_gid) {
960 TALLOC_FREE(frame);
961 return NT_STATUS_INVALID_TOKEN;
964 if (!found_hint_flags) {
965 TALLOC_FREE(frame);
966 return NT_STATUS_INVALID_TOKEN;
970 if (!(user_info_dc->info->user_flags & NETLOGON_GUEST)) {
971 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
974 status = finalize_local_nt_token(session_info->security_token,
975 session_info_flags);
976 if (!NT_STATUS_IS_OK(status)) {
977 TALLOC_FREE(frame);
978 return status;
982 * unless set otherwise, the session key is the user session
983 * key from the auth subsystem
985 if (user_info_dc->user_session_key.length != 0) {
986 session_info->session_key = data_blob_dup_talloc(session_info,
987 user_info_dc->user_session_key);
988 if (session_info->session_key.data == NULL) {
989 TALLOC_FREE(frame);
990 return NT_STATUS_NO_MEMORY;
994 if (!(session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)) {
995 goto done;
998 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
999 if (session_info->unix_token == NULL) {
1000 TALLOC_FREE(frame);
1001 return NT_STATUS_NO_MEMORY;
1003 session_info->unix_token->uid = -1;
1004 session_info->unix_token->gid = -1;
1006 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
1007 if (session_info->unix_info == NULL) {
1008 TALLOC_FREE(frame);
1009 return NT_STATUS_NO_MEMORY;
1012 /* Convert the SIDs to uid/gids. */
1014 ids = talloc_zero_array(frame, struct unixid,
1015 session_info->security_token->num_sids);
1016 if (ids == NULL) {
1017 TALLOC_FREE(frame);
1018 return NT_STATUS_NO_MEMORY;
1021 if (!(hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS)) {
1022 ok = sids_to_unixids(session_info->security_token->sids,
1023 session_info->security_token->num_sids,
1024 ids);
1025 if (!ok) {
1026 TALLOC_FREE(frame);
1027 return NT_STATUS_NO_MEMORY;
1031 if (found_hint_uid) {
1032 session_info->unix_token->uid = hint_uid;
1033 } else if (ids[0].type == ID_TYPE_UID) {
1035 * The primary SID resolves to a UID only.
1037 session_info->unix_token->uid = ids[0].id;
1038 } else if (ids[0].type == ID_TYPE_BOTH) {
1040 * The primary SID resolves to a UID and GID,
1041 * use it as uid and add it as first element
1042 * to the groups array.
1044 session_info->unix_token->uid = ids[0].id;
1046 ok = add_gid_to_array_unique(session_info->unix_token,
1047 session_info->unix_token->uid,
1048 &session_info->unix_token->groups,
1049 &session_info->unix_token->ngroups);
1050 if (!ok) {
1051 TALLOC_FREE(frame);
1052 return NT_STATUS_NO_MEMORY;
1054 } else {
1056 * It we can't get a uid, we can't imporsonate
1057 * the user.
1059 TALLOC_FREE(frame);
1060 return NT_STATUS_INVALID_TOKEN;
1063 if (found_hint_gid) {
1064 session_info->unix_token->gid = hint_gid;
1065 } else {
1066 need_getpwuid = true;
1069 if (hint_flags & AUTH3_UNIX_HINT_QUALIFIED_NAME) {
1070 session_info->unix_info->unix_name =
1071 talloc_asprintf(session_info->unix_info,
1072 "%s%c%s",
1073 session_info->info->domain_name,
1074 *lp_winbind_separator(),
1075 session_info->info->account_name);
1076 if (session_info->unix_info->unix_name == NULL) {
1077 TALLOC_FREE(frame);
1078 return NT_STATUS_NO_MEMORY;
1080 } else if (hint_flags & AUTH3_UNIX_HINT_ISLOLATED_NAME) {
1081 session_info->unix_info->unix_name =
1082 talloc_strdup(session_info->unix_info,
1083 session_info->info->account_name);
1084 if (session_info->unix_info->unix_name == NULL) {
1085 TALLOC_FREE(frame);
1086 return NT_STATUS_NO_MEMORY;
1088 } else {
1089 need_getpwuid = true;
1092 if (need_getpwuid) {
1093 struct passwd *pwd = NULL;
1096 * Ask the system for the primary gid
1097 * and the real unix name.
1099 pwd = getpwuid_alloc(frame, session_info->unix_token->uid);
1100 if (pwd == NULL) {
1101 TALLOC_FREE(frame);
1102 return NT_STATUS_INVALID_TOKEN;
1104 if (!found_hint_gid) {
1105 session_info->unix_token->gid = pwd->pw_gid;
1108 session_info->unix_info->unix_name =
1109 talloc_strdup(session_info->unix_info, pwd->pw_name);
1110 if (session_info->unix_info->unix_name == NULL) {
1111 TALLOC_FREE(frame);
1112 return NT_STATUS_NO_MEMORY;
1115 TALLOC_FREE(pwd);
1118 ok = add_gid_to_array_unique(session_info->unix_token,
1119 session_info->unix_token->gid,
1120 &session_info->unix_token->groups,
1121 &session_info->unix_token->ngroups);
1122 if (!ok) {
1123 TALLOC_FREE(frame);
1124 return NT_STATUS_NO_MEMORY;
1127 /* This is a potentially untrusted username for use in %U */
1128 session_info->unix_info->sanitized_username =
1129 talloc_alpha_strcpy(session_info->unix_info,
1130 original_user_name,
1131 SAFE_NETBIOS_CHARS "$");
1132 if (session_info->unix_info->sanitized_username == NULL) {
1133 TALLOC_FREE(frame);
1134 return NT_STATUS_NO_MEMORY;
1137 for (i=0; i < session_info->security_token->num_sids; i++) {
1139 if (ids[i].type != ID_TYPE_GID &&
1140 ids[i].type != ID_TYPE_BOTH) {
1141 struct security_token *nt_token =
1142 session_info->security_token;
1143 struct dom_sid_buf buf;
1145 DEBUG(10, ("Could not convert SID %s to gid, "
1146 "ignoring it\n",
1147 dom_sid_str_buf(&nt_token->sids[i], &buf)));
1148 continue;
1151 ok = add_gid_to_array_unique(session_info->unix_token,
1152 ids[i].id,
1153 &session_info->unix_token->groups,
1154 &session_info->unix_token->ngroups);
1155 if (!ok) {
1156 TALLOC_FREE(frame);
1157 return NT_STATUS_NO_MEMORY;
1160 TALLOC_FREE(ids);
1163 * Now we must get any groups this user has been
1164 * added to in /etc/group and merge them in.
1165 * This has to be done in every code path
1166 * that creates an NT token, as remote users
1167 * may have been added to the local /etc/group
1168 * database. Tokens created merely from the
1169 * info3 structs (via the DC or via the krb5 PAC)
1170 * won't have these local groups. Note the
1171 * groups added here will only be UNIX groups
1172 * (S-1-22-2-XXXX groups) as getgroups_unix_user()
1173 * turns off winbindd before calling getgroups().
1175 * NB. This is duplicating work already
1176 * done in the 'unix_user:' case of
1177 * create_token_from_sid() but won't
1178 * do anything other than be inefficient
1179 * in that case.
1181 if (!(hint_flags & AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS)) {
1182 ok = getgroups_unix_user(frame,
1183 session_info->unix_info->unix_name,
1184 session_info->unix_token->gid,
1185 &gids, &num_gids);
1186 if (!ok) {
1187 TALLOC_FREE(frame);
1188 return NT_STATUS_INVALID_TOKEN;
1192 for (i=0; i < num_gids; i++) {
1194 ok = add_gid_to_array_unique(session_info->unix_token,
1195 gids[i],
1196 &session_info->unix_token->groups,
1197 &session_info->unix_token->ngroups);
1198 if (!ok) {
1199 TALLOC_FREE(frame);
1200 return NT_STATUS_NO_MEMORY;
1203 TALLOC_FREE(gids);
1205 if (hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS) {
1207 * We should not translate the unix token uid/gids
1208 * to S-1-22-X-Y SIDs.
1210 goto done;
1214 * Add the "Unix Group" SID for each gid to catch mapped groups
1215 * and their Unix equivalent. This is to solve the backwards
1216 * compatibility problem of 'valid users = +ntadmin' where
1217 * ntadmin has been paired with "Domain Admins" in the group
1218 * mapping table. Otherwise smb.conf would need to be changed
1219 * to 'valid user = "Domain Admins"'. --jerry
1221 * For consistency we also add the "Unix User" SID,
1222 * so that the complete unix token is represented within
1223 * the nt token.
1226 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
1227 status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1228 &session_info->security_token->sids,
1229 &session_info->security_token->num_sids);
1230 if (!NT_STATUS_IS_OK(status)) {
1231 TALLOC_FREE(frame);
1232 return status;
1235 gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
1236 status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1237 &session_info->security_token->sids,
1238 &session_info->security_token->num_sids);
1239 if (!NT_STATUS_IS_OK(status)) {
1240 TALLOC_FREE(frame);
1241 return status;
1244 for (i=0; i < session_info->unix_token->ngroups; i++ ) {
1245 struct security_token *nt_token = session_info->security_token;
1247 gid_to_unix_groups_sid(session_info->unix_token->groups[i],
1248 &tmp_sid);
1249 status = add_sid_to_array_unique(nt_token->sids,
1250 &tmp_sid,
1251 &nt_token->sids,
1252 &nt_token->num_sids);
1253 if (!NT_STATUS_IS_OK(status)) {
1254 TALLOC_FREE(frame);
1255 return status;
1259 done:
1260 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
1261 if (session_info->unix_token != NULL) {
1262 debug_unix_user_token(DBGC_AUTH, 10,
1263 session_info->unix_token->uid,
1264 session_info->unix_token->gid,
1265 session_info->unix_token->ngroups,
1266 session_info->unix_token->groups);
1269 status = log_nt_token(session_info->security_token);
1270 if (!NT_STATUS_IS_OK(status)) {
1271 TALLOC_FREE(frame);
1272 return status;
1275 session_info->unique_session_token = GUID_random();
1277 *session_info_out = talloc_move(mem_ctx, &session_info);
1278 TALLOC_FREE(frame);
1279 return NT_STATUS_OK;
1282 /***************************************************************************
1283 Make (and fill) a server_info struct from a 'struct passwd' by conversion
1284 to a struct samu
1285 ***************************************************************************/
1287 NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
1288 const char *unix_username,
1289 const struct passwd *pwd,
1290 struct auth_serversupplied_info **server_info)
1292 NTSTATUS status;
1293 TALLOC_CTX *tmp_ctx = NULL;
1294 struct auth_serversupplied_info *result;
1296 tmp_ctx = talloc_stackframe();
1297 if (tmp_ctx == NULL) {
1298 return NT_STATUS_NO_MEMORY;
1301 result = make_server_info(tmp_ctx);
1302 if (result == NULL) {
1303 status = NT_STATUS_NO_MEMORY;
1304 goto done;
1307 status = passwd_to_SamInfo3(result,
1308 unix_username,
1309 pwd,
1310 &result->info3,
1311 &result->extra);
1312 if (!NT_STATUS_IS_OK(status)) {
1313 goto done;
1316 result->unix_name = talloc_strdup(result, unix_username);
1317 if (result->unix_name == NULL) {
1318 status = NT_STATUS_NO_MEMORY;
1319 goto done;
1322 result->utok.uid = pwd->pw_uid;
1323 result->utok.gid = pwd->pw_gid;
1325 *server_info = talloc_move(mem_ctx, &result);
1326 status = NT_STATUS_OK;
1327 done:
1328 talloc_free(tmp_ctx);
1330 return status;
1333 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
1334 struct netr_SamInfo3 *info3)
1336 const char *guest_account = lp_guest_account();
1337 struct dom_sid domain_sid;
1338 struct passwd *pwd;
1339 const char *tmp;
1341 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
1342 if (pwd == NULL) {
1343 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
1344 "account [%s]!\n", guest_account));
1345 return NT_STATUS_NO_SUCH_USER;
1348 /* Set account name */
1349 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
1350 if (tmp == NULL) {
1351 return NT_STATUS_NO_MEMORY;
1353 init_lsa_String(&info3->base.account_name, tmp);
1355 /* Set domain name */
1356 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
1357 if (tmp == NULL) {
1358 return NT_STATUS_NO_MEMORY;
1360 init_lsa_StringLarge(&info3->base.logon_domain, tmp);
1362 /* Domain sid */
1363 sid_copy(&domain_sid, get_global_sam_sid());
1365 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
1366 if (info3->base.domain_sid == NULL) {
1367 return NT_STATUS_NO_MEMORY;
1370 /* Guest rid */
1371 info3->base.rid = DOMAIN_RID_GUEST;
1373 /* Primary gid */
1374 info3->base.primary_gid = DOMAIN_RID_GUESTS;
1376 /* Set as guest */
1377 info3->base.user_flags = NETLOGON_GUEST;
1379 TALLOC_FREE(pwd);
1380 return NT_STATUS_OK;
1383 /***************************************************************************
1384 Make (and fill) a user_info struct for a guest login.
1385 This *must* succeed for smbd to start. If there is no mapping entry for
1386 the guest gid, then create one.
1388 The resulting structure is a 'session_info' because
1389 create_local_token() has already been called on it. This is quite
1390 nasty, as the auth subsystem isn't expect this, but the behavior is
1391 left as-is for now.
1392 ***************************************************************************/
1394 static NTSTATUS make_new_session_info_guest(TALLOC_CTX *mem_ctx,
1395 struct auth_session_info **_session_info,
1396 struct auth_serversupplied_info **_server_info)
1398 struct auth_session_info *session_info = NULL;
1399 struct auth_serversupplied_info *server_info = NULL;
1400 const char *guest_account = lp_guest_account();
1401 const char *domain = lp_netbios_name();
1402 struct netr_SamInfo3 info3;
1403 TALLOC_CTX *tmp_ctx;
1404 NTSTATUS status;
1406 tmp_ctx = talloc_stackframe();
1407 if (tmp_ctx == NULL) {
1408 return NT_STATUS_NO_MEMORY;
1411 ZERO_STRUCT(info3);
1413 status = get_guest_info3(tmp_ctx, &info3);
1414 if (!NT_STATUS_IS_OK(status)) {
1415 DEBUG(0, ("get_guest_info3 failed with %s\n",
1416 nt_errstr(status)));
1417 goto done;
1420 status = make_server_info_info3(tmp_ctx,
1421 guest_account,
1422 domain,
1423 &server_info,
1424 &info3);
1425 if (!NT_STATUS_IS_OK(status)) {
1426 DEBUG(0, ("make_server_info_info3 failed with %s\n",
1427 nt_errstr(status)));
1428 goto done;
1431 server_info->guest = true;
1433 /* This should not be done here (we should produce a server
1434 * info, and later construct a session info from it), but for
1435 * now this does not change the previous behavior */
1436 status = create_local_token(tmp_ctx, server_info, NULL,
1437 server_info->info3->base.account_name.string,
1438 &session_info);
1439 if (!NT_STATUS_IS_OK(status)) {
1440 DEBUG(0, ("create_local_token failed: %s\n",
1441 nt_errstr(status)));
1442 goto done;
1446 * It's ugly, but for now it's
1447 * needed to force Builtin_Guests
1448 * here, because memberships of
1449 * Builtin_Guests might be incomplete.
1451 status = add_sid_to_array_unique(session_info->security_token,
1452 &global_sid_Builtin_Guests,
1453 &session_info->security_token->sids,
1454 &session_info->security_token->num_sids);
1455 if (!NT_STATUS_IS_OK(status)) {
1456 DBG_ERR("Failed to force Builtin_Guests to nt token\n");
1457 goto done;
1460 /* annoying, but the Guest really does have a session key, and it is
1461 all zeros! */
1462 session_info->session_key = data_blob_talloc_zero(session_info, 16);
1464 *_session_info = talloc_move(mem_ctx, &session_info);
1465 *_server_info = talloc_move(mem_ctx, &server_info);
1467 status = NT_STATUS_OK;
1468 done:
1469 TALLOC_FREE(tmp_ctx);
1470 return status;
1473 /***************************************************************************
1474 Make (and fill) a auth_session_info struct for a system user login.
1475 This *must* succeed for smbd to start.
1476 ***************************************************************************/
1478 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
1479 struct auth_session_info **session_info)
1481 TALLOC_CTX *frame = talloc_stackframe();
1482 struct auth_user_info_dc *user_info_dc = NULL;
1483 uid_t uid = -1;
1484 gid_t gid = -1;
1485 uint32_t hint_flags = 0;
1486 uint32_t session_info_flags = 0;
1487 NTSTATUS status;
1489 status = auth_system_user_info_dc(frame, lp_netbios_name(),
1490 &user_info_dc);
1491 if (!NT_STATUS_IS_OK(status)) {
1492 DEBUG(0, ("auth_system_user_info_dc failed: %s\n",
1493 nt_errstr(status)));
1494 goto done;
1498 * Just get the initial uid/gid
1499 * and don't expand the unix groups.
1501 uid = sec_initial_uid();
1502 gid = sec_initial_gid();
1503 hint_flags |= AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS;
1506 * Also avoid sid mapping to gids,
1507 * as well as adding the unix_token uid/gids as
1508 * S-1-22-X-Y SIDs to the nt token.
1510 hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS;
1511 hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS;
1514 * The unix name will be "NT AUTHORITY+SYSTEM",
1515 * where '+' is the "winbind separator" character.
1517 hint_flags |= AUTH3_UNIX_HINT_QUALIFIED_NAME;
1518 status = auth3_user_info_dc_add_hints(user_info_dc,
1519 uid,
1520 gid,
1521 hint_flags);
1522 if (!NT_STATUS_IS_OK(status)) {
1523 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1524 nt_errstr(status)));
1525 goto done;
1528 session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1529 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1530 status = auth3_session_info_create(mem_ctx, user_info_dc,
1531 user_info_dc->info->account_name,
1532 session_info_flags,
1533 session_info);
1534 if (!NT_STATUS_IS_OK(status)) {
1535 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1536 nt_errstr(status)));
1537 goto done;
1540 done:
1541 TALLOC_FREE(frame);
1542 return status;
1545 static NTSTATUS make_new_session_info_anonymous(TALLOC_CTX *mem_ctx,
1546 struct auth_session_info **session_info)
1548 TALLOC_CTX *frame = talloc_stackframe();
1549 const char *guest_account = lp_guest_account();
1550 struct auth_user_info_dc *user_info_dc = NULL;
1551 struct passwd *pwd = NULL;
1552 uint32_t hint_flags = 0;
1553 uint32_t session_info_flags = 0;
1554 NTSTATUS status;
1557 * We use the guest account for the unix token
1558 * while we use a true anonymous nt token.
1560 * It's very important to have a separate
1561 * nt token for anonymous.
1564 pwd = Get_Pwnam_alloc(frame, guest_account);
1565 if (pwd == NULL) {
1566 DBG_ERR("Unable to locate guest account [%s]!\n",
1567 guest_account);
1568 status = NT_STATUS_NO_SUCH_USER;
1569 goto done;
1572 status = auth_anonymous_user_info_dc(frame, lp_netbios_name(),
1573 &user_info_dc);
1574 if (!NT_STATUS_IS_OK(status)) {
1575 DEBUG(0, ("auth_anonymous_user_info_dc failed: %s\n",
1576 nt_errstr(status)));
1577 goto done;
1581 * Note we don't pass AUTH3_UNIX_HINT_QUALIFIED_NAME
1582 * nor AUTH3_UNIX_HINT_ISOLATED_NAME here
1583 * as we want the unix name be found by getpwuid_alloc().
1586 status = auth3_user_info_dc_add_hints(user_info_dc,
1587 pwd->pw_uid,
1588 pwd->pw_gid,
1589 hint_flags);
1590 if (!NT_STATUS_IS_OK(status)) {
1591 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1592 nt_errstr(status)));
1593 goto done;
1597 * In future we may want to remove
1598 * AUTH_SESSION_INFO_DEFAULT_GROUPS.
1600 * Similar to Windows with EveryoneIncludesAnonymous
1601 * and RestrictAnonymous.
1603 * We may introduce AUTH_SESSION_INFO_ANON_WORLD...
1605 * But for this is required to keep the existing tests
1606 * working.
1608 session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
1609 session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1610 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1611 status = auth3_session_info_create(mem_ctx, user_info_dc,
1613 session_info_flags,
1614 session_info);
1615 if (!NT_STATUS_IS_OK(status)) {
1616 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1617 nt_errstr(status)));
1618 goto done;
1621 done:
1622 TALLOC_FREE(frame);
1623 return status;
1626 /****************************************************************************
1627 Fake a auth_session_info just from a username (as a
1628 session_info structure, with create_local_token() already called on
1630 ****************************************************************************/
1632 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
1633 const char *username,
1634 bool is_guest,
1635 struct auth_session_info **session_info)
1637 struct passwd *pwd;
1638 NTSTATUS status;
1639 struct auth_serversupplied_info *result;
1640 TALLOC_CTX *tmp_ctx;
1642 tmp_ctx = talloc_stackframe();
1643 if (tmp_ctx == NULL) {
1644 return NT_STATUS_NO_MEMORY;
1647 pwd = Get_Pwnam_alloc(tmp_ctx, username);
1648 if (pwd == NULL) {
1649 status = NT_STATUS_NO_SUCH_USER;
1650 goto done;
1653 status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
1654 if (!NT_STATUS_IS_OK(status)) {
1655 goto done;
1658 result->nss_token = true;
1659 result->guest = is_guest;
1661 /* Now turn the server_info into a session_info with the full token etc */
1662 status = create_local_token(mem_ctx,
1663 result,
1664 NULL,
1665 pwd->pw_name,
1666 session_info);
1668 done:
1669 talloc_free(tmp_ctx);
1671 return status;
1674 /* This function MUST only used to create the cached server_info for
1675 * guest.
1677 * This is a lossy conversion. Variables known to be lost so far
1678 * include:
1680 * - nss_token (not needed because the only read doesn't happen
1681 * for the GUEST user, as this routine populates ->security_token
1683 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1685 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1687 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1688 const struct auth_session_info *src,
1689 struct auth_serversupplied_info *server_info)
1691 struct auth_serversupplied_info *dst;
1692 NTSTATUS status;
1694 dst = make_server_info(mem_ctx);
1695 if (dst == NULL) {
1696 return NULL;
1699 /* This element must be provided to convert back to an auth_serversupplied_info */
1700 SMB_ASSERT(src->unix_info);
1702 dst->guest = true;
1704 /* This element must be provided to convert back to an
1705 * auth_serversupplied_info. This needs to be from the
1706 * auth_session_info because the group values in particular
1707 * may change during create_local_token() processing */
1708 SMB_ASSERT(src->unix_token);
1709 dst->utok.uid = src->unix_token->uid;
1710 dst->utok.gid = src->unix_token->gid;
1711 dst->utok.ngroups = src->unix_token->ngroups;
1712 if (src->unix_token->ngroups != 0) {
1713 dst->utok.groups = (gid_t *)talloc_memdup(
1714 dst, src->unix_token->groups,
1715 sizeof(gid_t)*dst->utok.ngroups);
1716 } else {
1717 dst->utok.groups = NULL;
1720 /* We must have a security_token as otherwise the lossy
1721 * conversion without nss_token would cause create_local_token
1722 * to take the wrong path */
1723 SMB_ASSERT(src->security_token);
1725 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1726 src->session_key.length);
1728 /* This is OK because this functions is only used for the
1729 * GUEST account, which has all-zero keys for both values */
1730 dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1731 src->session_key.length);
1733 status = copy_netr_SamInfo3(dst,
1734 server_info->info3,
1735 &dst->info3);
1736 if (!NT_STATUS_IS_OK(status)) {
1737 TALLOC_FREE(dst);
1738 return NULL;
1741 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1742 if (!dst->unix_name) {
1743 TALLOC_FREE(dst);
1744 return NULL;
1747 dst->cached_session_info = src;
1748 return dst;
1752 * Set a new session key. Used in the rpc server where we have to override the
1753 * SMB level session key with SystemLibraryDTC
1756 bool session_info_set_session_key(struct auth_session_info *info,
1757 DATA_BLOB session_key)
1759 TALLOC_FREE(info->session_key.data);
1761 info->session_key = data_blob_talloc(
1762 info, session_key.data, session_key.length);
1764 return (info->session_key.data != NULL);
1767 static struct auth_session_info *guest_info = NULL;
1768 static struct auth_session_info *anonymous_info = NULL;
1770 static struct auth_serversupplied_info *guest_server_info = NULL;
1772 bool init_guest_session_info(TALLOC_CTX *mem_ctx)
1774 NTSTATUS status;
1776 if (guest_info != NULL)
1777 return true;
1779 status = make_new_session_info_guest(mem_ctx,
1780 &guest_info,
1781 &guest_server_info);
1782 if (!NT_STATUS_IS_OK(status)) {
1783 return false;
1786 status = make_new_session_info_anonymous(mem_ctx,
1787 &anonymous_info);
1788 if (!NT_STATUS_IS_OK(status)) {
1789 return false;
1792 return true;
1795 bool reinit_guest_session_info(TALLOC_CTX *mem_ctx)
1797 TALLOC_FREE(guest_info);
1798 TALLOC_FREE(guest_server_info);
1799 TALLOC_FREE(anonymous_info);
1801 DBG_DEBUG("Reinitialing guest info\n");
1803 return init_guest_session_info(mem_ctx);
1806 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1807 struct auth_serversupplied_info **server_info)
1809 /* This is trickier than it would appear to need to be because
1810 * we are trying to avoid certain costly operations when the
1811 * structure is converted to a 'auth_session_info' again in
1812 * create_local_token() */
1813 *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1814 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1817 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1818 struct auth_session_info **session_info)
1820 *session_info = copy_session_info(mem_ctx, guest_info);
1821 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1824 NTSTATUS make_server_info_anonymous(TALLOC_CTX *mem_ctx,
1825 struct auth_serversupplied_info **server_info)
1827 if (anonymous_info == NULL) {
1828 return NT_STATUS_UNSUCCESSFUL;
1832 * This is trickier than it would appear to need to be because
1833 * we are trying to avoid certain costly operations when the
1834 * structure is converted to a 'auth_session_info' again in
1835 * create_local_token()
1837 * We use a guest server_info, but with the anonymous session info,
1838 * which means create_local_token() will return a copy
1839 * of the anonymous token.
1841 * The server info is just used as legacy in order to
1842 * keep existing code working. Maybe some debug messages
1843 * will still refer to guest instead of anonymous.
1845 *server_info = copy_session_info_serverinfo_guest(mem_ctx, anonymous_info,
1846 guest_server_info);
1847 if (*server_info == NULL) {
1848 return NT_STATUS_NO_MEMORY;
1851 return NT_STATUS_OK;
1854 NTSTATUS make_session_info_anonymous(TALLOC_CTX *mem_ctx,
1855 struct auth_session_info **session_info)
1857 if (anonymous_info == NULL) {
1858 return NT_STATUS_UNSUCCESSFUL;
1861 *session_info = copy_session_info(mem_ctx, anonymous_info);
1862 if (*session_info == NULL) {
1863 return NT_STATUS_NO_MEMORY;
1866 return NT_STATUS_OK;
1869 static struct auth_session_info *system_info = NULL;
1871 NTSTATUS init_system_session_info(TALLOC_CTX *mem_ctx)
1873 if (system_info != NULL)
1874 return NT_STATUS_OK;
1876 return make_new_session_info_system(mem_ctx, &system_info);
1879 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1880 struct auth_session_info **session_info)
1882 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1883 *session_info = copy_session_info(mem_ctx, system_info);
1884 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1887 const struct auth_session_info *get_session_info_system(void)
1889 return system_info;
1892 /***************************************************************************
1893 Purely internal function for make_server_info_info3
1894 ***************************************************************************/
1896 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1897 const char *username,
1898 const struct dom_sid *sid,
1899 char **found_username,
1900 struct passwd **pwd,
1901 bool *username_was_mapped)
1903 char *orig_dom_user = NULL;
1904 char *dom_user = NULL;
1905 char *lower_username = NULL;
1906 char *real_username = NULL;
1907 struct passwd *passwd;
1909 lower_username = talloc_strdup(mem_ctx, username);
1910 if (!lower_username) {
1911 return NT_STATUS_NO_MEMORY;
1913 if (!strlower_m( lower_username )) {
1914 return NT_STATUS_INVALID_PARAMETER;
1917 orig_dom_user = talloc_asprintf(mem_ctx,
1918 "%s%c%s",
1919 domain,
1920 *lp_winbind_separator(),
1921 lower_username);
1922 if (!orig_dom_user) {
1923 return NT_STATUS_NO_MEMORY;
1926 /* Get the passwd struct. Try to create the account if necessary. */
1928 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1929 if (!dom_user) {
1930 return NT_STATUS_NO_MEMORY;
1933 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
1934 if (!passwd && !*username_was_mapped) {
1935 struct dom_sid_buf buf;
1936 uid_t uid;
1937 bool ok;
1939 DBG_DEBUG("Failed to find authenticated user %s via "
1940 "getpwnam(), fallback to sid_to_uid(%s).\n",
1941 dom_user, dom_sid_str_buf(sid, &buf));
1943 ok = sid_to_uid(sid, &uid);
1944 if (!ok) {
1945 DBG_ERR("Failed to convert SID %s to a UID (dom_user[%s])\n",
1946 dom_sid_str_buf(sid, &buf), dom_user);
1947 return NT_STATUS_NO_SUCH_USER;
1949 passwd = getpwuid_alloc(mem_ctx, uid);
1950 if (!passwd) {
1951 DBG_ERR("Failed to find local account with UID %lld for SID %s (dom_user[%s])\n",
1952 (long long)uid,
1953 dom_sid_str_buf(sid, &buf),
1954 dom_user);
1955 return NT_STATUS_NO_SUCH_USER;
1957 real_username = talloc_strdup(mem_ctx, passwd->pw_name);
1959 if (!passwd) {
1960 DEBUG(3, ("Failed to find authenticated user %s via "
1961 "getpwnam(), denying access.\n", dom_user));
1962 return NT_STATUS_NO_SUCH_USER;
1965 if (!real_username) {
1966 return NT_STATUS_NO_MEMORY;
1969 *pwd = passwd;
1971 /* This is pointless -- there is no support for differing
1972 unix and windows names. Make sure to always store the
1973 one we actually looked up and succeeded. Have I mentioned
1974 why I hate the 'winbind use default domain' parameter?
1975 --jerry */
1977 *found_username = talloc_strdup( mem_ctx, real_username );
1979 return NT_STATUS_OK;
1982 /****************************************************************************
1983 Wrapper to allow the getpwnam() call to strip the domain name and
1984 try again in case a local UNIX user is already there. Also run through
1985 the username if we fallback to the username only.
1986 ****************************************************************************/
1988 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1989 char **p_save_username, bool create )
1991 struct passwd *pw = NULL;
1992 char *p = NULL;
1993 const char *username = NULL;
1995 /* we only save a copy of the username it has been mangled
1996 by winbindd use default domain */
1997 *p_save_username = NULL;
1999 /* don't call map_username() here since it has to be done higher
2000 up the stack so we don't call it multiple times */
2002 username = talloc_strdup(mem_ctx, domuser);
2003 if (!username) {
2004 return NULL;
2007 p = strchr_m( username, *lp_winbind_separator() );
2009 /* code for a DOMAIN\user string */
2011 if ( p ) {
2012 const char *domain = NULL;
2014 /* split the domain and username into 2 strings */
2015 *p = '\0';
2016 domain = username;
2017 p++;
2018 username = p;
2020 if (strequal(domain, get_global_sam_name())) {
2022 * This typically don't happen
2023 * as check_sam_Security()
2024 * don't call make_server_info_info3()
2025 * and thus check_account().
2027 * But we better keep this.
2029 goto username_only;
2032 pw = Get_Pwnam_alloc( mem_ctx, domuser );
2033 if (pw == NULL) {
2034 return NULL;
2036 /* make sure we get the case of the username correct */
2037 /* work around 'winbind use default domain = yes' */
2039 if ( lp_winbind_use_default_domain() &&
2040 !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
2041 *p_save_username = talloc_asprintf(mem_ctx,
2042 "%s%c%s",
2043 domain,
2044 *lp_winbind_separator(),
2045 pw->pw_name);
2046 if (!*p_save_username) {
2047 TALLOC_FREE(pw);
2048 return NULL;
2050 } else {
2051 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
2054 /* whew -- done! */
2055 return pw;
2059 /* just lookup a plain username */
2060 username_only:
2061 pw = Get_Pwnam_alloc(mem_ctx, username);
2063 /* Create local user if requested but only if winbindd
2064 is not running. We need to protect against cases
2065 where winbindd is failing and then prematurely
2066 creating users in /etc/passwd */
2068 if ( !pw && create && !winbind_ping() ) {
2069 /* Don't add a machine account. */
2070 if (username[strlen(username)-1] == '$')
2071 return NULL;
2073 _smb_create_user(NULL, username, NULL);
2074 pw = Get_Pwnam_alloc(mem_ctx, username);
2077 /* one last check for a valid passwd struct */
2079 if (pw) {
2080 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
2082 return pw;
2085 /***************************************************************************
2086 Make a server_info struct from the info3 returned by a domain logon
2087 ***************************************************************************/
2089 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
2090 const char *sent_nt_username,
2091 const char *domain,
2092 struct auth_serversupplied_info **server_info,
2093 const struct netr_SamInfo3 *info3)
2095 NTSTATUS nt_status;
2096 char *found_username = NULL;
2097 const char *nt_domain;
2098 const char *nt_username;
2099 struct dom_sid user_sid;
2100 struct dom_sid group_sid;
2101 bool username_was_mapped;
2102 struct passwd *pwd;
2103 struct auth_serversupplied_info *result;
2104 struct dom_sid sid;
2105 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2108 Here is where we should check the list of
2109 trusted domains, and verify that the SID
2110 matches.
2113 if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
2114 nt_status = NT_STATUS_INVALID_PARAMETER;
2115 goto out;
2118 if (!sid_compose(&group_sid, info3->base.domain_sid,
2119 info3->base.primary_gid)) {
2120 nt_status = NT_STATUS_INVALID_PARAMETER;
2121 goto out;
2124 nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
2125 if (!nt_username) {
2126 /* If the server didn't give us one, just use the one we sent
2127 * them */
2128 nt_username = sent_nt_username;
2131 nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
2132 if (!nt_domain) {
2133 /* If the server didn't give us one, just use the one we sent
2134 * them */
2135 nt_domain = domain;
2138 /* If getpwnam() fails try the add user script (2.2.x behavior).
2140 We use the _unmapped_ username here in an attempt to provide
2141 consistent username mapping behavior between kerberos and NTLM[SSP]
2142 authentication in domain mode security. I.E. Username mapping
2143 should be applied to the fully qualified username
2144 (e.g. DOMAIN\user) and not just the login name. Yes this means we
2145 called map_username() unnecessarily in make_user_info_map() but
2146 that is how the current code is designed. Making the change here
2147 is the least disruptive place. -- jerry */
2149 /* this call will try to create the user if necessary */
2151 sid_copy(&sid, info3->base.domain_sid);
2152 sid_append_rid(&sid, info3->base.rid);
2154 nt_status = check_account(tmp_ctx,
2155 nt_domain,
2156 nt_username,
2157 &sid,
2158 &found_username,
2159 &pwd,
2160 &username_was_mapped);
2162 if (!NT_STATUS_IS_OK(nt_status)) {
2163 /* Handle 'map to guest = Bad Uid */
2164 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
2165 (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
2166 lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
2167 DBG_NOTICE("Try to map %s to guest account\n",
2168 nt_username);
2169 nt_status = make_server_info_guest(tmp_ctx, &result);
2170 if (NT_STATUS_IS_OK(nt_status)) {
2171 *server_info = talloc_move(mem_ctx, &result);
2174 goto out;
2175 } else if ((lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
2176 !is_myname(domain) && pwd->pw_uid < lp_min_domain_uid()) {
2178 * !is_myname(domain) because when smbd starts tries to setup
2179 * the guest user info, calling this function with nobody
2180 * username. Nobody is usually uid 65535 but it can be changed
2181 * to a regular user with 'guest account' parameter
2183 nt_status = NT_STATUS_INVALID_TOKEN;
2184 DBG_NOTICE("Username '%s%s%s' is invalid on this system, "
2185 "it does not meet 'min domain uid' "
2186 "restriction (%u < %u): %s\n",
2187 nt_domain, lp_winbind_separator(), nt_username,
2188 pwd->pw_uid, lp_min_domain_uid(),
2189 nt_errstr(nt_status));
2190 goto out;
2193 result = make_server_info(tmp_ctx);
2194 if (result == NULL) {
2195 DEBUG(4, ("make_server_info failed!\n"));
2196 nt_status = NT_STATUS_NO_MEMORY;
2197 goto out;
2200 result->unix_name = talloc_strdup(result, found_username);
2202 /* copy in the info3 */
2203 nt_status = copy_netr_SamInfo3(result,
2204 info3,
2205 &result->info3);
2206 if (!NT_STATUS_IS_OK(nt_status)) {
2207 goto out;
2210 /* Fill in the unix info we found on the way */
2212 result->utok.uid = pwd->pw_uid;
2213 result->utok.gid = pwd->pw_gid;
2215 /* ensure we are never given NULL session keys */
2217 if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
2218 result->session_key = data_blob_null;
2219 } else {
2220 result->session_key = data_blob_talloc(
2221 result, info3->base.key.key,
2222 sizeof(info3->base.key.key));
2225 if (all_zero(info3->base.LMSessKey.key,
2226 sizeof(info3->base.LMSessKey.key))) {
2227 result->lm_session_key = data_blob_null;
2228 } else {
2229 result->lm_session_key = data_blob_talloc(
2230 result, info3->base.LMSessKey.key,
2231 sizeof(info3->base.LMSessKey.key));
2234 result->nss_token |= username_was_mapped;
2236 result->guest = (info3->base.user_flags & NETLOGON_GUEST);
2238 *server_info = talloc_move(mem_ctx, &result);
2240 nt_status = NT_STATUS_OK;
2241 out:
2242 talloc_free(tmp_ctx);
2244 return nt_status;
2247 /*****************************************************************************
2248 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
2249 ******************************************************************************/
2251 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
2252 const char *sent_nt_username,
2253 const char *domain,
2254 const struct wbcAuthUserInfo *info,
2255 struct auth_serversupplied_info **server_info)
2257 struct netr_SamInfo3 info3;
2258 struct netr_SamInfo6 *info6;
2260 info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
2261 if (!info6) {
2262 return NT_STATUS_NO_MEMORY;
2265 info3.base = info6->base;
2266 info3.sidcount = info6->sidcount;
2267 info3.sids = info6->sids;
2269 return make_server_info_info3(mem_ctx,
2270 sent_nt_username, domain,
2271 server_info, &info3);
2275 * Verify whether or not given domain is trusted.
2277 * This should only be used on a DC.
2279 * @param domain_name name of the domain to be verified
2280 * @return true if domain is one of the trusted ones or
2281 * false if otherwise
2284 bool is_trusted_domain(const char* dom_name)
2286 bool ret;
2288 if (!IS_DC) {
2289 return false;
2292 if (dom_name == NULL || dom_name[0] == '\0') {
2293 return false;
2296 if (strequal(dom_name, get_global_sam_name())) {
2297 return false;
2300 become_root();
2301 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2302 "[%s]\n", dom_name ));
2303 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2304 unbecome_root();
2306 return ret;
2312 on a logon error possibly map the error to success if "map to guest"
2313 is set appropriately
2315 NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
2316 NTSTATUS status,
2317 const char *user,
2318 const char *domain,
2319 struct auth_serversupplied_info **server_info)
2321 user = user ? user : "";
2322 domain = domain ? domain : "";
2324 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2325 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
2326 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
2327 DEBUG(3,("No such user %s [%s] - using guest account\n",
2328 user, domain));
2329 return make_server_info_guest(mem_ctx, server_info);
2331 } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2332 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
2333 DEBUG(3,("Registered username %s for guest access\n",
2334 user));
2335 return make_server_info_guest(mem_ctx, server_info);
2339 return status;
2343 Extract session key from a session info and return it in a blob
2344 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
2346 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
2347 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
2349 Note that returned session_key is referencing the original key, it is supposed to be
2350 short-lived. If original session_info->session_key is gone, the reference will be broken.
2352 NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
2355 if (session_key == NULL || session_info == NULL) {
2356 return NT_STATUS_INVALID_PARAMETER;
2359 if (session_info->session_key.length == 0) {
2360 return NT_STATUS_NO_USER_SESSION_KEY;
2363 *session_key = session_info->session_key;
2364 if (intent == KEY_USE_16BYTES) {
2365 session_key->length = MIN(session_info->session_key.length, 16);
2367 return NT_STATUS_OK;