smbd: squash check_path_syntax() variants
[Samba.git] / source3 / auth / auth_util.c
blob9fe407ee5e9870fc8cf740eb851bb4a57848d9ee
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_attrs_unique(user_info_dc->sids,
725 &tmp_sid,
726 SE_GROUP_DEFAULT_FLAGS,
727 &user_info_dc->sids,
728 &user_info_dc->num_sids);
729 if (!NT_STATUS_IS_OK(status)) {
730 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
731 nt_errstr(status)));
732 goto fail;
736 * We add S-5-88-2-X in order to pass the gid
737 * for the unix token.
739 sid_compose(&tmp_sid,
740 &global_sid_Unix_NFS_Groups,
741 (uint32_t)gid);
742 status = add_sid_to_array_attrs_unique(user_info_dc->sids,
743 &tmp_sid,
744 SE_GROUP_DEFAULT_FLAGS,
745 &user_info_dc->sids,
746 &user_info_dc->num_sids);
747 if (!NT_STATUS_IS_OK(status)) {
748 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
749 nt_errstr(status)));
750 goto fail;
754 * We add S-5-88-3-X in order to pass some flags
755 * (AUTH3_UNIX_HINT_*) to auth3_create_session_info().
757 sid_compose(&tmp_sid,
758 &global_sid_Unix_NFS_Mode,
759 flags);
760 status = add_sid_to_array_attrs_unique(user_info_dc->sids,
761 &tmp_sid,
762 SE_GROUP_DEFAULT_FLAGS,
763 &user_info_dc->sids,
764 &user_info_dc->num_sids);
765 if (!NT_STATUS_IS_OK(status)) {
766 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
767 nt_errstr(status)));
768 goto fail;
771 return NT_STATUS_OK;
773 fail:
774 user_info_dc->num_sids = orig_num_sids;
775 return status;
778 static NTSTATUS auth3_session_info_create(
779 TALLOC_CTX *mem_ctx,
780 const struct auth_user_info_dc *user_info_dc,
781 const char *original_user_name,
782 uint32_t session_info_flags,
783 struct auth_session_info **session_info_out)
785 TALLOC_CTX *frame = talloc_stackframe();
786 struct auth_session_info *session_info = NULL;
787 uid_t hint_uid = -1;
788 bool found_hint_uid = false;
789 uid_t hint_gid = -1;
790 bool found_hint_gid = false;
791 uint32_t hint_flags = 0;
792 bool found_hint_flags = false;
793 bool need_getpwuid = false;
794 struct unixid *ids = NULL;
795 uint32_t num_gids = 0;
796 gid_t *gids = NULL;
797 struct dom_sid tmp_sid = { 0, };
798 NTSTATUS status;
799 size_t i;
800 bool ok;
802 *session_info_out = NULL;
804 if (user_info_dc->num_sids == 0) {
805 TALLOC_FREE(frame);
806 return NT_STATUS_INVALID_TOKEN;
809 if (user_info_dc->info == NULL) {
810 TALLOC_FREE(frame);
811 return NT_STATUS_INVALID_TOKEN;
814 if (user_info_dc->info->account_name == NULL) {
815 TALLOC_FREE(frame);
816 return NT_STATUS_INVALID_TOKEN;
819 session_info = talloc_zero(mem_ctx, struct auth_session_info);
820 if (session_info == NULL) {
821 TALLOC_FREE(frame);
822 return NT_STATUS_NO_MEMORY;
824 /* keep this under frame for easier cleanup */
825 talloc_reparent(mem_ctx, frame, session_info);
827 session_info->info = auth_user_info_copy(session_info,
828 user_info_dc->info);
829 if (session_info->info == NULL) {
830 TALLOC_FREE(frame);
831 return NT_STATUS_NO_MEMORY;
834 session_info->security_token = talloc_zero(session_info,
835 struct security_token);
836 if (session_info->security_token == NULL) {
837 TALLOC_FREE(frame);
838 return NT_STATUS_NO_MEMORY;
842 * Avoid a lot of reallocations and allocate what we'll
843 * use in most cases.
845 session_info->security_token->sids = talloc_zero_array(
846 session_info->security_token,
847 struct dom_sid,
848 user_info_dc->num_sids);
849 if (session_info->security_token->sids == NULL) {
850 TALLOC_FREE(frame);
851 return NT_STATUS_NO_MEMORY;
854 for (i = PRIMARY_USER_SID_INDEX; i < user_info_dc->num_sids; i++) {
855 struct security_token *nt_token = session_info->security_token;
856 int cmp;
859 * S-1-5-88-X-Y sids are only used to give hints
860 * to the unix token construction.
862 * S-1-5-88-1-Y gives the uid=Y
863 * S-1-5-88-2-Y gives the gid=Y
864 * S-1-5-88-3-Y gives flags=Y: AUTH3_UNIX_HINT_*
866 cmp = dom_sid_compare_domain(&global_sid_Unix_NFS,
867 &user_info_dc->sids[i].sid);
868 if (cmp == 0) {
869 bool match;
870 uint32_t hint = 0;
872 match = sid_peek_rid(&user_info_dc->sids[i].sid, &hint);
873 if (!match) {
874 continue;
877 match = dom_sid_in_domain(&global_sid_Unix_NFS_Users,
878 &user_info_dc->sids[i].sid);
879 if (match) {
880 if (found_hint_uid) {
881 TALLOC_FREE(frame);
882 return NT_STATUS_INVALID_TOKEN;
884 found_hint_uid = true;
885 hint_uid = (uid_t)hint;
886 continue;
889 match = dom_sid_in_domain(&global_sid_Unix_NFS_Groups,
890 &user_info_dc->sids[i].sid);
891 if (match) {
892 if (found_hint_gid) {
893 TALLOC_FREE(frame);
894 return NT_STATUS_INVALID_TOKEN;
896 found_hint_gid = true;
897 hint_gid = (gid_t)hint;
898 continue;
901 match = dom_sid_in_domain(&global_sid_Unix_NFS_Mode,
902 &user_info_dc->sids[i].sid);
903 if (match) {
904 if (found_hint_flags) {
905 TALLOC_FREE(frame);
906 return NT_STATUS_INVALID_TOKEN;
908 found_hint_flags = true;
909 hint_flags = hint;
910 continue;
913 continue;
916 status = add_sid_to_array_unique(nt_token->sids,
917 &user_info_dc->sids[i].sid,
918 &nt_token->sids,
919 &nt_token->num_sids);
920 if (!NT_STATUS_IS_OK(status)) {
921 TALLOC_FREE(frame);
922 return status;
927 * We need at least one usable SID
929 if (session_info->security_token->num_sids == 0) {
930 TALLOC_FREE(frame);
931 return NT_STATUS_INVALID_TOKEN;
935 * We need all tree hints: uid, gid, flags
936 * or none of them.
938 if (found_hint_uid || found_hint_gid || found_hint_flags) {
939 if (!found_hint_uid) {
940 TALLOC_FREE(frame);
941 return NT_STATUS_INVALID_TOKEN;
944 if (!found_hint_gid) {
945 TALLOC_FREE(frame);
946 return NT_STATUS_INVALID_TOKEN;
949 if (!found_hint_flags) {
950 TALLOC_FREE(frame);
951 return NT_STATUS_INVALID_TOKEN;
955 if (!(user_info_dc->info->user_flags & NETLOGON_GUEST)) {
956 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
959 status = finalize_local_nt_token(session_info->security_token,
960 session_info_flags);
961 if (!NT_STATUS_IS_OK(status)) {
962 TALLOC_FREE(frame);
963 return status;
967 * unless set otherwise, the session key is the user session
968 * key from the auth subsystem
970 if (user_info_dc->user_session_key.length != 0) {
971 session_info->session_key = data_blob_dup_talloc(session_info,
972 user_info_dc->user_session_key);
973 if (session_info->session_key.data == NULL) {
974 TALLOC_FREE(frame);
975 return NT_STATUS_NO_MEMORY;
979 if (!(session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)) {
980 goto done;
983 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
984 if (session_info->unix_token == NULL) {
985 TALLOC_FREE(frame);
986 return NT_STATUS_NO_MEMORY;
988 session_info->unix_token->uid = -1;
989 session_info->unix_token->gid = -1;
991 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
992 if (session_info->unix_info == NULL) {
993 TALLOC_FREE(frame);
994 return NT_STATUS_NO_MEMORY;
997 /* Convert the SIDs to uid/gids. */
999 ids = talloc_zero_array(frame, struct unixid,
1000 session_info->security_token->num_sids);
1001 if (ids == NULL) {
1002 TALLOC_FREE(frame);
1003 return NT_STATUS_NO_MEMORY;
1006 if (!(hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS)) {
1007 ok = sids_to_unixids(session_info->security_token->sids,
1008 session_info->security_token->num_sids,
1009 ids);
1010 if (!ok) {
1011 TALLOC_FREE(frame);
1012 return NT_STATUS_NO_MEMORY;
1016 if (found_hint_uid) {
1017 session_info->unix_token->uid = hint_uid;
1018 } else if (ids[0].type == ID_TYPE_UID) {
1020 * The primary SID resolves to a UID only.
1022 session_info->unix_token->uid = ids[0].id;
1023 } else if (ids[0].type == ID_TYPE_BOTH) {
1025 * The primary SID resolves to a UID and GID,
1026 * use it as uid and add it as first element
1027 * to the groups array.
1029 session_info->unix_token->uid = ids[0].id;
1031 ok = add_gid_to_array_unique(session_info->unix_token,
1032 session_info->unix_token->uid,
1033 &session_info->unix_token->groups,
1034 &session_info->unix_token->ngroups);
1035 if (!ok) {
1036 TALLOC_FREE(frame);
1037 return NT_STATUS_NO_MEMORY;
1039 } else {
1041 * It we can't get a uid, we can't imporsonate
1042 * the user.
1044 TALLOC_FREE(frame);
1045 return NT_STATUS_INVALID_TOKEN;
1048 if (found_hint_gid) {
1049 session_info->unix_token->gid = hint_gid;
1050 } else {
1051 need_getpwuid = true;
1054 if (hint_flags & AUTH3_UNIX_HINT_QUALIFIED_NAME) {
1055 session_info->unix_info->unix_name =
1056 talloc_asprintf(session_info->unix_info,
1057 "%s%c%s",
1058 session_info->info->domain_name,
1059 *lp_winbind_separator(),
1060 session_info->info->account_name);
1061 if (session_info->unix_info->unix_name == NULL) {
1062 TALLOC_FREE(frame);
1063 return NT_STATUS_NO_MEMORY;
1065 } else if (hint_flags & AUTH3_UNIX_HINT_ISLOLATED_NAME) {
1066 session_info->unix_info->unix_name =
1067 talloc_strdup(session_info->unix_info,
1068 session_info->info->account_name);
1069 if (session_info->unix_info->unix_name == NULL) {
1070 TALLOC_FREE(frame);
1071 return NT_STATUS_NO_MEMORY;
1073 } else {
1074 need_getpwuid = true;
1077 if (need_getpwuid) {
1078 struct passwd *pwd = NULL;
1081 * Ask the system for the primary gid
1082 * and the real unix name.
1084 pwd = getpwuid_alloc(frame, session_info->unix_token->uid);
1085 if (pwd == NULL) {
1086 TALLOC_FREE(frame);
1087 return NT_STATUS_INVALID_TOKEN;
1089 if (!found_hint_gid) {
1090 session_info->unix_token->gid = pwd->pw_gid;
1093 session_info->unix_info->unix_name =
1094 talloc_strdup(session_info->unix_info, pwd->pw_name);
1095 if (session_info->unix_info->unix_name == NULL) {
1096 TALLOC_FREE(frame);
1097 return NT_STATUS_NO_MEMORY;
1100 TALLOC_FREE(pwd);
1103 ok = add_gid_to_array_unique(session_info->unix_token,
1104 session_info->unix_token->gid,
1105 &session_info->unix_token->groups,
1106 &session_info->unix_token->ngroups);
1107 if (!ok) {
1108 TALLOC_FREE(frame);
1109 return NT_STATUS_NO_MEMORY;
1112 /* This is a potentially untrusted username for use in %U */
1113 session_info->unix_info->sanitized_username =
1114 talloc_alpha_strcpy(session_info->unix_info,
1115 original_user_name,
1116 SAFE_NETBIOS_CHARS "$");
1117 if (session_info->unix_info->sanitized_username == NULL) {
1118 TALLOC_FREE(frame);
1119 return NT_STATUS_NO_MEMORY;
1122 for (i=0; i < session_info->security_token->num_sids; i++) {
1124 if (ids[i].type != ID_TYPE_GID &&
1125 ids[i].type != ID_TYPE_BOTH) {
1126 struct security_token *nt_token =
1127 session_info->security_token;
1128 struct dom_sid_buf buf;
1130 DEBUG(10, ("Could not convert SID %s to gid, "
1131 "ignoring it\n",
1132 dom_sid_str_buf(&nt_token->sids[i], &buf)));
1133 continue;
1136 ok = add_gid_to_array_unique(session_info->unix_token,
1137 ids[i].id,
1138 &session_info->unix_token->groups,
1139 &session_info->unix_token->ngroups);
1140 if (!ok) {
1141 TALLOC_FREE(frame);
1142 return NT_STATUS_NO_MEMORY;
1145 TALLOC_FREE(ids);
1148 * Now we must get any groups this user has been
1149 * added to in /etc/group and merge them in.
1150 * This has to be done in every code path
1151 * that creates an NT token, as remote users
1152 * may have been added to the local /etc/group
1153 * database. Tokens created merely from the
1154 * info3 structs (via the DC or via the krb5 PAC)
1155 * won't have these local groups. Note the
1156 * groups added here will only be UNIX groups
1157 * (S-1-22-2-XXXX groups) as getgroups_unix_user()
1158 * turns off winbindd before calling getgroups().
1160 * NB. This is duplicating work already
1161 * done in the 'unix_user:' case of
1162 * create_token_from_sid() but won't
1163 * do anything other than be inefficient
1164 * in that case.
1166 if (!(hint_flags & AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS)) {
1167 ok = getgroups_unix_user(frame,
1168 session_info->unix_info->unix_name,
1169 session_info->unix_token->gid,
1170 &gids, &num_gids);
1171 if (!ok) {
1172 TALLOC_FREE(frame);
1173 return NT_STATUS_INVALID_TOKEN;
1177 for (i=0; i < num_gids; i++) {
1179 ok = add_gid_to_array_unique(session_info->unix_token,
1180 gids[i],
1181 &session_info->unix_token->groups,
1182 &session_info->unix_token->ngroups);
1183 if (!ok) {
1184 TALLOC_FREE(frame);
1185 return NT_STATUS_NO_MEMORY;
1188 TALLOC_FREE(gids);
1190 if (hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS) {
1192 * We should not translate the unix token uid/gids
1193 * to S-1-22-X-Y SIDs.
1195 goto done;
1199 * Add the "Unix Group" SID for each gid to catch mapped groups
1200 * and their Unix equivalent. This is to solve the backwards
1201 * compatibility problem of 'valid users = +ntadmin' where
1202 * ntadmin has been paired with "Domain Admins" in the group
1203 * mapping table. Otherwise smb.conf would need to be changed
1204 * to 'valid user = "Domain Admins"'. --jerry
1206 * For consistency we also add the "Unix User" SID,
1207 * so that the complete unix token is represented within
1208 * the nt token.
1211 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
1212 status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1213 &session_info->security_token->sids,
1214 &session_info->security_token->num_sids);
1215 if (!NT_STATUS_IS_OK(status)) {
1216 TALLOC_FREE(frame);
1217 return status;
1220 gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
1221 status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1222 &session_info->security_token->sids,
1223 &session_info->security_token->num_sids);
1224 if (!NT_STATUS_IS_OK(status)) {
1225 TALLOC_FREE(frame);
1226 return status;
1229 for (i=0; i < session_info->unix_token->ngroups; i++ ) {
1230 struct security_token *nt_token = session_info->security_token;
1232 gid_to_unix_groups_sid(session_info->unix_token->groups[i],
1233 &tmp_sid);
1234 status = add_sid_to_array_unique(nt_token->sids,
1235 &tmp_sid,
1236 &nt_token->sids,
1237 &nt_token->num_sids);
1238 if (!NT_STATUS_IS_OK(status)) {
1239 TALLOC_FREE(frame);
1240 return status;
1244 done:
1245 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
1246 if (session_info->unix_token != NULL) {
1247 debug_unix_user_token(DBGC_AUTH, 10,
1248 session_info->unix_token->uid,
1249 session_info->unix_token->gid,
1250 session_info->unix_token->ngroups,
1251 session_info->unix_token->groups);
1254 status = log_nt_token(session_info->security_token);
1255 if (!NT_STATUS_IS_OK(status)) {
1256 TALLOC_FREE(frame);
1257 return status;
1260 session_info->unique_session_token = GUID_random();
1262 *session_info_out = talloc_move(mem_ctx, &session_info);
1263 TALLOC_FREE(frame);
1264 return NT_STATUS_OK;
1267 /***************************************************************************
1268 Make (and fill) a server_info struct from a 'struct passwd' by conversion
1269 to a struct samu
1270 ***************************************************************************/
1272 NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
1273 const char *unix_username,
1274 const struct passwd *pwd,
1275 struct auth_serversupplied_info **server_info)
1277 NTSTATUS status;
1278 TALLOC_CTX *tmp_ctx = NULL;
1279 struct auth_serversupplied_info *result;
1281 tmp_ctx = talloc_stackframe();
1282 if (tmp_ctx == NULL) {
1283 return NT_STATUS_NO_MEMORY;
1286 result = make_server_info(tmp_ctx);
1287 if (result == NULL) {
1288 status = NT_STATUS_NO_MEMORY;
1289 goto done;
1292 status = passwd_to_SamInfo3(result,
1293 unix_username,
1294 pwd,
1295 &result->info3,
1296 &result->extra);
1297 if (!NT_STATUS_IS_OK(status)) {
1298 goto done;
1301 result->unix_name = talloc_strdup(result, unix_username);
1302 if (result->unix_name == NULL) {
1303 status = NT_STATUS_NO_MEMORY;
1304 goto done;
1307 result->utok.uid = pwd->pw_uid;
1308 result->utok.gid = pwd->pw_gid;
1310 *server_info = talloc_move(mem_ctx, &result);
1311 status = NT_STATUS_OK;
1312 done:
1313 talloc_free(tmp_ctx);
1315 return status;
1318 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
1319 struct netr_SamInfo3 *info3)
1321 const char *guest_account = lp_guest_account();
1322 struct dom_sid domain_sid;
1323 struct passwd *pwd;
1324 const char *tmp;
1326 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
1327 if (pwd == NULL) {
1328 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
1329 "account [%s]!\n", guest_account));
1330 return NT_STATUS_NO_SUCH_USER;
1333 /* Set account name */
1334 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
1335 if (tmp == NULL) {
1336 return NT_STATUS_NO_MEMORY;
1338 init_lsa_String(&info3->base.account_name, tmp);
1340 /* Set domain name */
1341 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
1342 if (tmp == NULL) {
1343 return NT_STATUS_NO_MEMORY;
1345 init_lsa_StringLarge(&info3->base.logon_domain, tmp);
1347 /* Domain sid */
1348 sid_copy(&domain_sid, get_global_sam_sid());
1350 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
1351 if (info3->base.domain_sid == NULL) {
1352 return NT_STATUS_NO_MEMORY;
1355 /* Guest rid */
1356 info3->base.rid = DOMAIN_RID_GUEST;
1358 /* Primary gid */
1359 info3->base.primary_gid = DOMAIN_RID_GUESTS;
1361 /* Set as guest */
1362 info3->base.user_flags = NETLOGON_GUEST;
1364 TALLOC_FREE(pwd);
1365 return NT_STATUS_OK;
1368 /***************************************************************************
1369 Make (and fill) a user_info struct for a guest login.
1370 This *must* succeed for smbd to start. If there is no mapping entry for
1371 the guest gid, then create one.
1373 The resulting structure is a 'session_info' because
1374 create_local_token() has already been called on it. This is quite
1375 nasty, as the auth subsystem isn't expect this, but the behavior is
1376 left as-is for now.
1377 ***************************************************************************/
1379 static NTSTATUS make_new_session_info_guest(TALLOC_CTX *mem_ctx,
1380 struct auth_session_info **_session_info,
1381 struct auth_serversupplied_info **_server_info)
1383 struct auth_session_info *session_info = NULL;
1384 struct auth_serversupplied_info *server_info = NULL;
1385 const char *guest_account = lp_guest_account();
1386 const char *domain = lp_netbios_name();
1387 struct netr_SamInfo3 info3;
1388 TALLOC_CTX *tmp_ctx;
1389 NTSTATUS status;
1391 tmp_ctx = talloc_stackframe();
1392 if (tmp_ctx == NULL) {
1393 return NT_STATUS_NO_MEMORY;
1396 ZERO_STRUCT(info3);
1398 status = get_guest_info3(tmp_ctx, &info3);
1399 if (!NT_STATUS_IS_OK(status)) {
1400 DEBUG(0, ("get_guest_info3 failed with %s\n",
1401 nt_errstr(status)));
1402 goto done;
1405 status = make_server_info_info3(tmp_ctx,
1406 guest_account,
1407 domain,
1408 &server_info,
1409 &info3);
1410 if (!NT_STATUS_IS_OK(status)) {
1411 DEBUG(0, ("make_server_info_info3 failed with %s\n",
1412 nt_errstr(status)));
1413 goto done;
1416 server_info->guest = true;
1418 /* This should not be done here (we should produce a server
1419 * info, and later construct a session info from it), but for
1420 * now this does not change the previous behavior */
1421 status = create_local_token(tmp_ctx, server_info, NULL,
1422 server_info->info3->base.account_name.string,
1423 &session_info);
1424 if (!NT_STATUS_IS_OK(status)) {
1425 DEBUG(0, ("create_local_token failed: %s\n",
1426 nt_errstr(status)));
1427 goto done;
1431 * It's ugly, but for now it's
1432 * needed to force Builtin_Guests
1433 * here, because memberships of
1434 * Builtin_Guests might be incomplete.
1436 status = add_sid_to_array_unique(session_info->security_token,
1437 &global_sid_Builtin_Guests,
1438 &session_info->security_token->sids,
1439 &session_info->security_token->num_sids);
1440 if (!NT_STATUS_IS_OK(status)) {
1441 DBG_ERR("Failed to force Builtin_Guests to nt token\n");
1442 goto done;
1445 /* annoying, but the Guest really does have a session key, and it is
1446 all zeros! */
1447 session_info->session_key = data_blob_talloc_zero(session_info, 16);
1449 *_session_info = talloc_move(mem_ctx, &session_info);
1450 *_server_info = talloc_move(mem_ctx, &server_info);
1452 status = NT_STATUS_OK;
1453 done:
1454 TALLOC_FREE(tmp_ctx);
1455 return status;
1458 /***************************************************************************
1459 Make (and fill) a auth_session_info struct for a system user login.
1460 This *must* succeed for smbd to start.
1461 ***************************************************************************/
1463 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
1464 struct auth_session_info **session_info)
1466 TALLOC_CTX *frame = talloc_stackframe();
1467 struct auth_user_info_dc *user_info_dc = NULL;
1468 uid_t uid = -1;
1469 gid_t gid = -1;
1470 uint32_t hint_flags = 0;
1471 uint32_t session_info_flags = 0;
1472 NTSTATUS status;
1474 status = auth_system_user_info_dc(frame, lp_netbios_name(),
1475 &user_info_dc);
1476 if (!NT_STATUS_IS_OK(status)) {
1477 DEBUG(0, ("auth_system_user_info_dc failed: %s\n",
1478 nt_errstr(status)));
1479 goto done;
1483 * Just get the initial uid/gid
1484 * and don't expand the unix groups.
1486 uid = sec_initial_uid();
1487 gid = sec_initial_gid();
1488 hint_flags |= AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS;
1491 * Also avoid sid mapping to gids,
1492 * as well as adding the unix_token uid/gids as
1493 * S-1-22-X-Y SIDs to the nt token.
1495 hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS;
1496 hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS;
1499 * The unix name will be "NT AUTHORITY+SYSTEM",
1500 * where '+' is the "winbind separator" character.
1502 hint_flags |= AUTH3_UNIX_HINT_QUALIFIED_NAME;
1503 status = auth3_user_info_dc_add_hints(user_info_dc,
1504 uid,
1505 gid,
1506 hint_flags);
1507 if (!NT_STATUS_IS_OK(status)) {
1508 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1509 nt_errstr(status)));
1510 goto done;
1513 session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1514 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1515 status = auth3_session_info_create(mem_ctx, user_info_dc,
1516 user_info_dc->info->account_name,
1517 session_info_flags,
1518 session_info);
1519 if (!NT_STATUS_IS_OK(status)) {
1520 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1521 nt_errstr(status)));
1522 goto done;
1525 done:
1526 TALLOC_FREE(frame);
1527 return status;
1530 static NTSTATUS make_new_session_info_anonymous(TALLOC_CTX *mem_ctx,
1531 struct auth_session_info **session_info)
1533 TALLOC_CTX *frame = talloc_stackframe();
1534 const char *guest_account = lp_guest_account();
1535 struct auth_user_info_dc *user_info_dc = NULL;
1536 struct passwd *pwd = NULL;
1537 uint32_t hint_flags = 0;
1538 uint32_t session_info_flags = 0;
1539 NTSTATUS status;
1542 * We use the guest account for the unix token
1543 * while we use a true anonymous nt token.
1545 * It's very important to have a separate
1546 * nt token for anonymous.
1549 pwd = Get_Pwnam_alloc(frame, guest_account);
1550 if (pwd == NULL) {
1551 DBG_ERR("Unable to locate guest account [%s]!\n",
1552 guest_account);
1553 status = NT_STATUS_NO_SUCH_USER;
1554 goto done;
1557 status = auth_anonymous_user_info_dc(frame, lp_netbios_name(),
1558 &user_info_dc);
1559 if (!NT_STATUS_IS_OK(status)) {
1560 DEBUG(0, ("auth_anonymous_user_info_dc failed: %s\n",
1561 nt_errstr(status)));
1562 goto done;
1566 * Note we don't pass AUTH3_UNIX_HINT_QUALIFIED_NAME
1567 * nor AUTH3_UNIX_HINT_ISOLATED_NAME here
1568 * as we want the unix name be found by getpwuid_alloc().
1571 status = auth3_user_info_dc_add_hints(user_info_dc,
1572 pwd->pw_uid,
1573 pwd->pw_gid,
1574 hint_flags);
1575 if (!NT_STATUS_IS_OK(status)) {
1576 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1577 nt_errstr(status)));
1578 goto done;
1582 * In future we may want to remove
1583 * AUTH_SESSION_INFO_DEFAULT_GROUPS.
1585 * Similar to Windows with EveryoneIncludesAnonymous
1586 * and RestrictAnonymous.
1588 * We may introduce AUTH_SESSION_INFO_ANON_WORLD...
1590 * But for this is required to keep the existing tests
1591 * working.
1593 session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
1594 session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1595 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1596 status = auth3_session_info_create(mem_ctx, user_info_dc,
1598 session_info_flags,
1599 session_info);
1600 if (!NT_STATUS_IS_OK(status)) {
1601 DEBUG(0, ("auth3_session_info_create failed: %s\n",
1602 nt_errstr(status)));
1603 goto done;
1606 done:
1607 TALLOC_FREE(frame);
1608 return status;
1611 /****************************************************************************
1612 Fake a auth_session_info just from a username (as a
1613 session_info structure, with create_local_token() already called on
1615 ****************************************************************************/
1617 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
1618 const char *username,
1619 bool is_guest,
1620 struct auth_session_info **session_info)
1622 struct passwd *pwd;
1623 NTSTATUS status;
1624 struct auth_serversupplied_info *result;
1625 TALLOC_CTX *tmp_ctx;
1627 tmp_ctx = talloc_stackframe();
1628 if (tmp_ctx == NULL) {
1629 return NT_STATUS_NO_MEMORY;
1632 pwd = Get_Pwnam_alloc(tmp_ctx, username);
1633 if (pwd == NULL) {
1634 status = NT_STATUS_NO_SUCH_USER;
1635 goto done;
1638 status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
1639 if (!NT_STATUS_IS_OK(status)) {
1640 goto done;
1643 result->nss_token = true;
1644 result->guest = is_guest;
1646 /* Now turn the server_info into a session_info with the full token etc */
1647 status = create_local_token(mem_ctx,
1648 result,
1649 NULL,
1650 pwd->pw_name,
1651 session_info);
1653 done:
1654 talloc_free(tmp_ctx);
1656 return status;
1659 /* This function MUST only used to create the cached server_info for
1660 * guest.
1662 * This is a lossy conversion. Variables known to be lost so far
1663 * include:
1665 * - nss_token (not needed because the only read doesn't happen
1666 * for the GUEST user, as this routine populates ->security_token
1668 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1670 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1672 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1673 const struct auth_session_info *src,
1674 struct auth_serversupplied_info *server_info)
1676 struct auth_serversupplied_info *dst;
1677 NTSTATUS status;
1679 dst = make_server_info(mem_ctx);
1680 if (dst == NULL) {
1681 return NULL;
1684 /* This element must be provided to convert back to an auth_serversupplied_info */
1685 SMB_ASSERT(src->unix_info);
1687 dst->guest = true;
1689 /* This element must be provided to convert back to an
1690 * auth_serversupplied_info. This needs to be from the
1691 * auth_session_info because the group values in particular
1692 * may change during create_local_token() processing */
1693 SMB_ASSERT(src->unix_token);
1694 dst->utok.uid = src->unix_token->uid;
1695 dst->utok.gid = src->unix_token->gid;
1696 dst->utok.ngroups = src->unix_token->ngroups;
1697 if (src->unix_token->ngroups != 0) {
1698 dst->utok.groups = (gid_t *)talloc_memdup(
1699 dst, src->unix_token->groups,
1700 sizeof(gid_t)*dst->utok.ngroups);
1701 } else {
1702 dst->utok.groups = NULL;
1705 /* We must have a security_token as otherwise the lossy
1706 * conversion without nss_token would cause create_local_token
1707 * to take the wrong path */
1708 SMB_ASSERT(src->security_token);
1710 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1711 src->session_key.length);
1713 /* This is OK because this functions is only used for the
1714 * GUEST account, which has all-zero keys for both values */
1715 dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1716 src->session_key.length);
1718 status = copy_netr_SamInfo3(dst,
1719 server_info->info3,
1720 &dst->info3);
1721 if (!NT_STATUS_IS_OK(status)) {
1722 TALLOC_FREE(dst);
1723 return NULL;
1726 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1727 if (!dst->unix_name) {
1728 TALLOC_FREE(dst);
1729 return NULL;
1732 dst->cached_session_info = src;
1733 return dst;
1737 * Set a new session key. Used in the rpc server where we have to override the
1738 * SMB level session key with SystemLibraryDTC
1741 bool session_info_set_session_key(struct auth_session_info *info,
1742 DATA_BLOB session_key)
1744 TALLOC_FREE(info->session_key.data);
1746 info->session_key = data_blob_talloc(
1747 info, session_key.data, session_key.length);
1749 return (info->session_key.data != NULL);
1752 static struct auth_session_info *guest_info = NULL;
1753 static struct auth_session_info *anonymous_info = NULL;
1755 static struct auth_serversupplied_info *guest_server_info = NULL;
1757 bool init_guest_session_info(TALLOC_CTX *mem_ctx)
1759 NTSTATUS status;
1761 if (guest_info != NULL)
1762 return true;
1764 status = make_new_session_info_guest(mem_ctx,
1765 &guest_info,
1766 &guest_server_info);
1767 if (!NT_STATUS_IS_OK(status)) {
1768 return false;
1771 status = make_new_session_info_anonymous(mem_ctx,
1772 &anonymous_info);
1773 if (!NT_STATUS_IS_OK(status)) {
1774 return false;
1777 return true;
1780 bool reinit_guest_session_info(TALLOC_CTX *mem_ctx)
1782 TALLOC_FREE(guest_info);
1783 TALLOC_FREE(guest_server_info);
1784 TALLOC_FREE(anonymous_info);
1786 DBG_DEBUG("Reinitialing guest info\n");
1788 return init_guest_session_info(mem_ctx);
1791 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1792 struct auth_serversupplied_info **server_info)
1794 /* This is trickier than it would appear to need to be because
1795 * we are trying to avoid certain costly operations when the
1796 * structure is converted to a 'auth_session_info' again in
1797 * create_local_token() */
1798 *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1799 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1802 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1803 struct auth_session_info **session_info)
1805 *session_info = copy_session_info(mem_ctx, guest_info);
1806 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1809 NTSTATUS make_server_info_anonymous(TALLOC_CTX *mem_ctx,
1810 struct auth_serversupplied_info **server_info)
1812 if (anonymous_info == NULL) {
1813 return NT_STATUS_UNSUCCESSFUL;
1817 * This is trickier than it would appear to need to be because
1818 * we are trying to avoid certain costly operations when the
1819 * structure is converted to a 'auth_session_info' again in
1820 * create_local_token()
1822 * We use a guest server_info, but with the anonymous session info,
1823 * which means create_local_token() will return a copy
1824 * of the anonymous token.
1826 * The server info is just used as legacy in order to
1827 * keep existing code working. Maybe some debug messages
1828 * will still refer to guest instead of anonymous.
1830 *server_info = copy_session_info_serverinfo_guest(mem_ctx, anonymous_info,
1831 guest_server_info);
1832 if (*server_info == NULL) {
1833 return NT_STATUS_NO_MEMORY;
1836 return NT_STATUS_OK;
1839 NTSTATUS make_session_info_anonymous(TALLOC_CTX *mem_ctx,
1840 struct auth_session_info **session_info)
1842 if (anonymous_info == NULL) {
1843 return NT_STATUS_UNSUCCESSFUL;
1846 *session_info = copy_session_info(mem_ctx, anonymous_info);
1847 if (*session_info == NULL) {
1848 return NT_STATUS_NO_MEMORY;
1851 return NT_STATUS_OK;
1854 static struct auth_session_info *system_info = NULL;
1856 NTSTATUS init_system_session_info(TALLOC_CTX *mem_ctx)
1858 if (system_info != NULL)
1859 return NT_STATUS_OK;
1861 return make_new_session_info_system(mem_ctx, &system_info);
1864 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1865 struct auth_session_info **session_info)
1867 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1868 *session_info = copy_session_info(mem_ctx, system_info);
1869 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1872 const struct auth_session_info *get_session_info_system(void)
1874 return system_info;
1877 /***************************************************************************
1878 Purely internal function for make_server_info_info3
1879 ***************************************************************************/
1881 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1882 const char *username,
1883 const struct dom_sid *sid,
1884 char **found_username,
1885 struct passwd **pwd,
1886 bool *username_was_mapped)
1888 char *orig_dom_user = NULL;
1889 char *dom_user = NULL;
1890 char *lower_username = NULL;
1891 char *real_username = NULL;
1892 struct passwd *passwd;
1894 lower_username = talloc_strdup(mem_ctx, username);
1895 if (!lower_username) {
1896 return NT_STATUS_NO_MEMORY;
1898 if (!strlower_m( lower_username )) {
1899 return NT_STATUS_INVALID_PARAMETER;
1902 orig_dom_user = talloc_asprintf(mem_ctx,
1903 "%s%c%s",
1904 domain,
1905 *lp_winbind_separator(),
1906 lower_username);
1907 if (!orig_dom_user) {
1908 return NT_STATUS_NO_MEMORY;
1911 /* Get the passwd struct. Try to create the account if necessary. */
1913 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1914 if (!dom_user) {
1915 return NT_STATUS_NO_MEMORY;
1918 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
1919 if (!passwd && !*username_was_mapped) {
1920 struct dom_sid_buf buf;
1921 uid_t uid;
1922 bool ok;
1924 DBG_DEBUG("Failed to find authenticated user %s via "
1925 "getpwnam(), fallback to sid_to_uid(%s).\n",
1926 dom_user, dom_sid_str_buf(sid, &buf));
1928 ok = sid_to_uid(sid, &uid);
1929 if (!ok) {
1930 DBG_ERR("Failed to convert SID %s to a UID (dom_user[%s])\n",
1931 dom_sid_str_buf(sid, &buf), dom_user);
1932 return NT_STATUS_NO_SUCH_USER;
1934 passwd = getpwuid_alloc(mem_ctx, uid);
1935 if (!passwd) {
1936 DBG_ERR("Failed to find local account with UID %lld for SID %s (dom_user[%s])\n",
1937 (long long)uid,
1938 dom_sid_str_buf(sid, &buf),
1939 dom_user);
1940 return NT_STATUS_NO_SUCH_USER;
1942 real_username = talloc_strdup(mem_ctx, passwd->pw_name);
1944 if (!passwd) {
1945 DEBUG(3, ("Failed to find authenticated user %s via "
1946 "getpwnam(), denying access.\n", dom_user));
1947 return NT_STATUS_NO_SUCH_USER;
1950 if (!real_username) {
1951 return NT_STATUS_NO_MEMORY;
1954 *pwd = passwd;
1956 /* This is pointless -- there is no support for differing
1957 unix and windows names. Make sure to always store the
1958 one we actually looked up and succeeded. Have I mentioned
1959 why I hate the 'winbind use default domain' parameter?
1960 --jerry */
1962 *found_username = talloc_strdup( mem_ctx, real_username );
1964 return NT_STATUS_OK;
1967 /****************************************************************************
1968 Wrapper to allow the getpwnam() call to strip the domain name and
1969 try again in case a local UNIX user is already there. Also run through
1970 the username if we fallback to the username only.
1971 ****************************************************************************/
1973 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1974 char **p_save_username, bool create )
1976 struct passwd *pw = NULL;
1977 char *p = NULL;
1978 const char *username = NULL;
1980 /* we only save a copy of the username it has been mangled
1981 by winbindd use default domain */
1982 *p_save_username = NULL;
1984 /* don't call map_username() here since it has to be done higher
1985 up the stack so we don't call it multiple times */
1987 username = talloc_strdup(mem_ctx, domuser);
1988 if (!username) {
1989 return NULL;
1992 p = strchr_m( username, *lp_winbind_separator() );
1994 /* code for a DOMAIN\user string */
1996 if ( p ) {
1997 const char *domain = NULL;
1999 /* split the domain and username into 2 strings */
2000 *p = '\0';
2001 domain = username;
2002 p++;
2003 username = p;
2005 if (strequal(domain, get_global_sam_name())) {
2007 * This typically don't happen
2008 * as check_sam_Security()
2009 * don't call make_server_info_info3()
2010 * and thus check_account().
2012 * But we better keep this.
2014 goto username_only;
2017 pw = Get_Pwnam_alloc( mem_ctx, domuser );
2018 if (pw == NULL) {
2019 return NULL;
2021 /* make sure we get the case of the username correct */
2022 /* work around 'winbind use default domain = yes' */
2024 if ( lp_winbind_use_default_domain() &&
2025 !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
2026 *p_save_username = talloc_asprintf(mem_ctx,
2027 "%s%c%s",
2028 domain,
2029 *lp_winbind_separator(),
2030 pw->pw_name);
2031 if (!*p_save_username) {
2032 TALLOC_FREE(pw);
2033 return NULL;
2035 } else {
2036 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
2039 /* whew -- done! */
2040 return pw;
2044 /* just lookup a plain username */
2045 username_only:
2046 pw = Get_Pwnam_alloc(mem_ctx, username);
2048 /* Create local user if requested but only if winbindd
2049 is not running. We need to protect against cases
2050 where winbindd is failing and then prematurely
2051 creating users in /etc/passwd */
2053 if ( !pw && create && !winbind_ping() ) {
2054 /* Don't add a machine account. */
2055 if (username[strlen(username)-1] == '$')
2056 return NULL;
2058 _smb_create_user(NULL, username, NULL);
2059 pw = Get_Pwnam_alloc(mem_ctx, username);
2062 /* one last check for a valid passwd struct */
2064 if (pw) {
2065 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
2067 return pw;
2070 /***************************************************************************
2071 Make a server_info struct from the info3 returned by a domain logon
2072 ***************************************************************************/
2074 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
2075 const char *sent_nt_username,
2076 const char *domain,
2077 struct auth_serversupplied_info **server_info,
2078 const struct netr_SamInfo3 *info3)
2080 NTSTATUS nt_status;
2081 char *found_username = NULL;
2082 const char *nt_domain;
2083 const char *nt_username;
2084 struct dom_sid user_sid;
2085 struct dom_sid group_sid;
2086 bool username_was_mapped;
2087 struct passwd *pwd;
2088 struct auth_serversupplied_info *result;
2089 struct dom_sid sid;
2090 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2093 Here is where we should check the list of
2094 trusted domains, and verify that the SID
2095 matches.
2098 if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
2099 nt_status = NT_STATUS_INVALID_PARAMETER;
2100 goto out;
2103 if (!sid_compose(&group_sid, info3->base.domain_sid,
2104 info3->base.primary_gid)) {
2105 nt_status = NT_STATUS_INVALID_PARAMETER;
2106 goto out;
2109 nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
2110 if (!nt_username) {
2111 /* If the server didn't give us one, just use the one we sent
2112 * them */
2113 nt_username = sent_nt_username;
2116 nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
2117 if (!nt_domain) {
2118 /* If the server didn't give us one, just use the one we sent
2119 * them */
2120 nt_domain = domain;
2123 /* If getpwnam() fails try the add user script (2.2.x behavior).
2125 We use the _unmapped_ username here in an attempt to provide
2126 consistent username mapping behavior between kerberos and NTLM[SSP]
2127 authentication in domain mode security. I.E. Username mapping
2128 should be applied to the fully qualified username
2129 (e.g. DOMAIN\user) and not just the login name. Yes this means we
2130 called map_username() unnecessarily in make_user_info_map() but
2131 that is how the current code is designed. Making the change here
2132 is the least disruptive place. -- jerry */
2134 /* this call will try to create the user if necessary */
2136 sid_copy(&sid, info3->base.domain_sid);
2137 sid_append_rid(&sid, info3->base.rid);
2139 nt_status = check_account(tmp_ctx,
2140 nt_domain,
2141 nt_username,
2142 &sid,
2143 &found_username,
2144 &pwd,
2145 &username_was_mapped);
2147 if (!NT_STATUS_IS_OK(nt_status)) {
2148 /* Handle 'map to guest = Bad Uid */
2149 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
2150 (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
2151 lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
2152 DBG_NOTICE("Try to map %s to guest account",
2153 nt_username);
2154 nt_status = make_server_info_guest(tmp_ctx, &result);
2155 if (NT_STATUS_IS_OK(nt_status)) {
2156 *server_info = talloc_move(mem_ctx, &result);
2159 goto out;
2160 } else if ((lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
2161 !is_myname(domain) && pwd->pw_uid < lp_min_domain_uid()) {
2163 * !is_myname(domain) because when smbd starts tries to setup
2164 * the guest user info, calling this function with nobody
2165 * username. Nobody is usually uid 65535 but it can be changed
2166 * to a regular user with 'guest account' parameter
2168 nt_status = NT_STATUS_INVALID_TOKEN;
2169 DBG_NOTICE("Username '%s%s%s' is invalid on this system, "
2170 "it does not meet 'min domain uid' "
2171 "restriction (%u < %u): %s\n",
2172 nt_domain, lp_winbind_separator(), nt_username,
2173 pwd->pw_uid, lp_min_domain_uid(),
2174 nt_errstr(nt_status));
2175 goto out;
2178 result = make_server_info(tmp_ctx);
2179 if (result == NULL) {
2180 DEBUG(4, ("make_server_info failed!\n"));
2181 nt_status = NT_STATUS_NO_MEMORY;
2182 goto out;
2185 result->unix_name = talloc_strdup(result, found_username);
2187 /* copy in the info3 */
2188 nt_status = copy_netr_SamInfo3(result,
2189 info3,
2190 &result->info3);
2191 if (!NT_STATUS_IS_OK(nt_status)) {
2192 goto out;
2195 /* Fill in the unix info we found on the way */
2197 result->utok.uid = pwd->pw_uid;
2198 result->utok.gid = pwd->pw_gid;
2200 /* ensure we are never given NULL session keys */
2202 if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
2203 result->session_key = data_blob_null;
2204 } else {
2205 result->session_key = data_blob_talloc(
2206 result, info3->base.key.key,
2207 sizeof(info3->base.key.key));
2210 if (all_zero(info3->base.LMSessKey.key,
2211 sizeof(info3->base.LMSessKey.key))) {
2212 result->lm_session_key = data_blob_null;
2213 } else {
2214 result->lm_session_key = data_blob_talloc(
2215 result, info3->base.LMSessKey.key,
2216 sizeof(info3->base.LMSessKey.key));
2219 result->nss_token |= username_was_mapped;
2221 result->guest = (info3->base.user_flags & NETLOGON_GUEST);
2223 *server_info = talloc_move(mem_ctx, &result);
2225 nt_status = NT_STATUS_OK;
2226 out:
2227 talloc_free(tmp_ctx);
2229 return nt_status;
2232 /*****************************************************************************
2233 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
2234 ******************************************************************************/
2236 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
2237 const char *sent_nt_username,
2238 const char *domain,
2239 const struct wbcAuthUserInfo *info,
2240 struct auth_serversupplied_info **server_info)
2242 struct netr_SamInfo3 info3;
2243 struct netr_SamInfo6 *info6;
2245 info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
2246 if (!info6) {
2247 return NT_STATUS_NO_MEMORY;
2250 info3.base = info6->base;
2251 info3.sidcount = info6->sidcount;
2252 info3.sids = info6->sids;
2254 return make_server_info_info3(mem_ctx,
2255 sent_nt_username, domain,
2256 server_info, &info3);
2260 * Verify whether or not given domain is trusted.
2262 * This should only be used on a DC.
2264 * @param domain_name name of the domain to be verified
2265 * @return true if domain is one of the trusted ones or
2266 * false if otherwise
2269 bool is_trusted_domain(const char* dom_name)
2271 bool ret;
2273 if (!IS_DC) {
2274 return false;
2277 if (dom_name == NULL || dom_name[0] == '\0') {
2278 return false;
2281 if (strequal(dom_name, get_global_sam_name())) {
2282 return false;
2285 become_root();
2286 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2287 "[%s]\n", dom_name ));
2288 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2289 unbecome_root();
2291 return ret;
2297 on a logon error possibly map the error to success if "map to guest"
2298 is set approriately
2300 NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
2301 NTSTATUS status,
2302 const char *user,
2303 const char *domain,
2304 struct auth_serversupplied_info **server_info)
2306 user = user ? user : "";
2307 domain = domain ? domain : "";
2309 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2310 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
2311 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
2312 DEBUG(3,("No such user %s [%s] - using guest account\n",
2313 user, domain));
2314 return make_server_info_guest(mem_ctx, server_info);
2316 } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2317 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
2318 DEBUG(3,("Registered username %s for guest access\n",
2319 user));
2320 return make_server_info_guest(mem_ctx, server_info);
2324 return status;
2328 Extract session key from a session info and return it in a blob
2329 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
2331 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
2332 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
2334 Note that returned session_key is referencing the original key, it is supposed to be
2335 short-lived. If original session_info->session_key is gone, the reference will be broken.
2337 NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
2340 if (session_key == NULL || session_info == NULL) {
2341 return NT_STATUS_INVALID_PARAMETER;
2344 if (session_info->session_key.length == 0) {
2345 return NT_STATUS_NO_USER_SESSION_KEY;
2348 *session_key = session_info->session_key;
2349 if (intent == KEY_USE_16BYTES) {
2350 session_key->length = MIN(session_info->session_key.length, 16);
2352 return NT_STATUS_OK;