s3:auth: Pass mem_ctx to init_guest_session_info()
[Samba.git] / source3 / auth / auth_util.c
blobc81432d277d67235a446d2ef78acfa8bb259e0de
1 /*
2 Unix SMB/CIFS implementation.
3 Authentication utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001-2011
6 Copyright (C) Jeremy Allison 2000-2001
7 Copyright (C) Rafal Szczesniak 2002
8 Copyright (C) Volker Lendecke 2006-2008
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "auth.h"
26 #include "lib/util_unixsids.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../lib/crypto/arcfour.h"
29 #include "rpc_client/init_lsa.h"
30 #include "../libcli/security/security.h"
31 #include "../lib/util/util_pw.h"
32 #include "lib/winbind_util.h"
33 #include "passdb.h"
34 #include "../librpc/gen_ndr/ndr_auth.h"
35 #include "../auth/auth_sam_reply.h"
36 #include "../librpc/gen_ndr/idmap.h"
37 #include "lib/param/loadparm.h"
38 #include "../lib/tsocket/tsocket.h"
39 #include "rpc_client/util_netlogon.h"
41 #undef DBGC_CLASS
42 #define DBGC_CLASS DBGC_AUTH
44 /****************************************************************************
45 Create a UNIX user on demand.
46 ****************************************************************************/
48 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
50 TALLOC_CTX *ctx = talloc_tos();
51 char *add_script;
52 int ret;
54 add_script = lp_add_user_script(ctx);
55 if (!add_script || !*add_script) {
56 return -1;
58 add_script = talloc_all_string_sub(ctx,
59 add_script,
60 "%u",
61 unix_username);
62 if (!add_script) {
63 return -1;
65 if (domain) {
66 add_script = talloc_all_string_sub(ctx,
67 add_script,
68 "%D",
69 domain);
70 if (!add_script) {
71 return -1;
74 if (homedir) {
75 add_script = talloc_all_string_sub(ctx,
76 add_script,
77 "%H",
78 homedir);
79 if (!add_script) {
80 return -1;
83 ret = smbrun(add_script, NULL, NULL);
84 flush_pwnam_cache();
85 DEBUG(ret ? 0 : 3,
86 ("smb_create_user: Running the command `%s' gave %d\n",
87 add_script,ret));
88 return ret;
91 /****************************************************************************
92 Create an auth_usersupplied_data structure after appropriate mapping.
93 ****************************************************************************/
95 NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
96 struct auth_usersupplied_info **user_info,
97 const char *smb_name,
98 const char *client_domain,
99 const char *workstation_name,
100 const struct tsocket_address *remote_address,
101 const struct tsocket_address *local_address,
102 const char *service_description,
103 const DATA_BLOB *lm_pwd,
104 const DATA_BLOB *nt_pwd,
105 const struct samr_Password *lm_interactive_pwd,
106 const struct samr_Password *nt_interactive_pwd,
107 const char *plaintext,
108 enum auth_password_state password_state)
110 const char *domain;
111 NTSTATUS result;
112 bool was_mapped;
113 char *internal_username = NULL;
115 was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
116 if (!internal_username) {
117 return NT_STATUS_NO_MEMORY;
120 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
121 client_domain, smb_name, workstation_name));
124 * We let the auth stack canonicalize, username
125 * and domain.
127 domain = client_domain;
129 result = make_user_info(mem_ctx, user_info, smb_name, internal_username,
130 client_domain, domain, workstation_name,
131 remote_address, local_address,
132 service_description, lm_pwd, nt_pwd,
133 lm_interactive_pwd, nt_interactive_pwd,
134 plaintext, password_state);
135 if (NT_STATUS_IS_OK(result)) {
136 /* We have tried mapping */
137 (*user_info)->mapped_state = true;
138 /* did we actually map the user to a different name? */
139 (*user_info)->was_mapped = was_mapped;
141 return result;
144 /****************************************************************************
145 Create an auth_usersupplied_data, making the DATA_BLOBs here.
146 Decrypt and encrypt the passwords.
147 ****************************************************************************/
149 bool make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
150 struct auth_usersupplied_info **user_info,
151 const char *smb_name,
152 const char *client_domain,
153 const char *workstation_name,
154 const struct tsocket_address *remote_address,
155 const struct tsocket_address *local_address,
156 uint32_t logon_parameters,
157 const uchar *lm_network_pwd,
158 int lm_pwd_len,
159 const uchar *nt_network_pwd,
160 int nt_pwd_len)
162 bool ret;
163 NTSTATUS status;
164 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
165 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
167 status = make_user_info_map(mem_ctx, user_info,
168 smb_name, client_domain,
169 workstation_name,
170 remote_address,
171 local_address,
172 "SamLogon",
173 lm_pwd_len ? &lm_blob : NULL,
174 nt_pwd_len ? &nt_blob : NULL,
175 NULL, NULL, NULL,
176 AUTH_PASSWORD_RESPONSE);
178 if (NT_STATUS_IS_OK(status)) {
179 (*user_info)->logon_parameters = logon_parameters;
181 ret = NT_STATUS_IS_OK(status) ? true : false;
183 data_blob_free(&lm_blob);
184 data_blob_free(&nt_blob);
185 return ret;
188 /****************************************************************************
189 Create an auth_usersupplied_data, making the DATA_BLOBs here.
190 Decrypt and encrypt the passwords.
191 ****************************************************************************/
193 bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
194 struct auth_usersupplied_info **user_info,
195 const char *smb_name,
196 const char *client_domain,
197 const char *workstation_name,
198 const struct tsocket_address *remote_address,
199 const struct tsocket_address *local_address,
200 uint32_t logon_parameters,
201 const uchar chal[8],
202 const uchar lm_interactive_pwd[16],
203 const uchar nt_interactive_pwd[16])
205 struct samr_Password lm_pwd;
206 struct samr_Password nt_pwd;
207 unsigned char local_lm_response[24];
208 unsigned char local_nt_response[24];
210 if (lm_interactive_pwd)
211 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
213 if (nt_interactive_pwd)
214 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
216 if (lm_interactive_pwd)
217 SMBOWFencrypt(lm_pwd.hash, chal,
218 local_lm_response);
220 if (nt_interactive_pwd)
221 SMBOWFencrypt(nt_pwd.hash, chal,
222 local_nt_response);
225 bool ret;
226 NTSTATUS nt_status;
227 DATA_BLOB local_lm_blob = data_blob_null;
228 DATA_BLOB local_nt_blob = data_blob_null;
230 if (lm_interactive_pwd) {
231 local_lm_blob = data_blob(local_lm_response,
232 sizeof(local_lm_response));
235 if (nt_interactive_pwd) {
236 local_nt_blob = data_blob(local_nt_response,
237 sizeof(local_nt_response));
240 nt_status = make_user_info_map(
241 mem_ctx,
242 user_info,
243 smb_name, client_domain, workstation_name,
244 remote_address,
245 local_address,
246 "SamLogon",
247 lm_interactive_pwd ? &local_lm_blob : NULL,
248 nt_interactive_pwd ? &local_nt_blob : NULL,
249 lm_interactive_pwd ? &lm_pwd : NULL,
250 nt_interactive_pwd ? &nt_pwd : NULL,
251 NULL, AUTH_PASSWORD_HASH);
253 if (NT_STATUS_IS_OK(nt_status)) {
254 (*user_info)->logon_parameters = logon_parameters;
257 ret = NT_STATUS_IS_OK(nt_status) ? true : false;
258 data_blob_free(&local_lm_blob);
259 data_blob_free(&local_nt_blob);
260 return ret;
265 /****************************************************************************
266 Create an auth_usersupplied_data structure
267 ****************************************************************************/
269 bool make_user_info_for_reply(TALLOC_CTX *mem_ctx,
270 struct auth_usersupplied_info **user_info,
271 const char *smb_name,
272 const char *client_domain,
273 const struct tsocket_address *remote_address,
274 const struct tsocket_address *local_address,
275 const char *service_description,
276 const uint8_t chal[8],
277 DATA_BLOB plaintext_password)
280 DATA_BLOB local_lm_blob;
281 DATA_BLOB local_nt_blob;
282 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
283 char *plaintext_password_string;
285 * Not encrypted - do so.
288 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
289 "format.\n"));
290 if (plaintext_password.data && plaintext_password.length) {
291 unsigned char local_lm_response[24];
293 #ifdef DEBUG_PASSWORD
294 DEBUG(10,("Unencrypted password (len %d):\n",
295 (int)plaintext_password.length));
296 dump_data(100, plaintext_password.data,
297 plaintext_password.length);
298 #endif
300 SMBencrypt( (const char *)plaintext_password.data,
301 (const uchar*)chal, local_lm_response);
302 local_lm_blob = data_blob(local_lm_response, 24);
304 /* We can't do an NT hash here, as the password needs to be
305 case insensitive */
306 local_nt_blob = data_blob_null;
307 } else {
308 local_lm_blob = data_blob_null;
309 local_nt_blob = data_blob_null;
312 plaintext_password_string = talloc_strndup(talloc_tos(),
313 (const char *)plaintext_password.data,
314 plaintext_password.length);
315 if (!plaintext_password_string) {
316 return false;
319 ret = make_user_info(mem_ctx,
320 user_info, smb_name, smb_name, client_domain, client_domain,
321 get_remote_machine_name(),
322 remote_address,
323 local_address,
324 service_description,
325 local_lm_blob.data ? &local_lm_blob : NULL,
326 local_nt_blob.data ? &local_nt_blob : NULL,
327 NULL, NULL,
328 plaintext_password_string,
329 AUTH_PASSWORD_PLAIN);
331 if (plaintext_password_string) {
332 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
333 talloc_free(plaintext_password_string);
336 data_blob_free(&local_lm_blob);
337 return NT_STATUS_IS_OK(ret) ? true : false;
340 /****************************************************************************
341 Create an auth_usersupplied_data structure
342 ****************************************************************************/
344 NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
345 struct auth_usersupplied_info **user_info,
346 const char *smb_name,
347 const char *client_domain,
348 const struct tsocket_address *remote_address,
349 const struct tsocket_address *local_address,
350 const char *service_description,
351 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
353 bool allow_raw = lp_raw_ntlmv2_auth();
355 if (!allow_raw && nt_resp.length >= 48) {
357 * NTLMv2_RESPONSE has at least 48 bytes
358 * and should only be supported via NTLMSSP.
360 DEBUG(2,("Rejecting raw NTLMv2 authentication with "
361 "user [%s\\%s] from[%s]\n",
362 client_domain, smb_name,
363 tsocket_address_string(remote_address, mem_ctx)));
364 return NT_STATUS_INVALID_PARAMETER;
367 return make_user_info(mem_ctx,
368 user_info, smb_name, smb_name,
369 client_domain, client_domain,
370 get_remote_machine_name(),
371 remote_address,
372 local_address,
373 service_description,
374 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
375 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
376 NULL, NULL, NULL,
377 AUTH_PASSWORD_RESPONSE);
380 /****************************************************************************
381 Create a guest user_info blob, for anonymous authentication.
382 ****************************************************************************/
384 bool make_user_info_guest(TALLOC_CTX *mem_ctx,
385 const struct tsocket_address *remote_address,
386 const struct tsocket_address *local_address,
387 const char *service_description,
388 struct auth_usersupplied_info **user_info)
390 NTSTATUS nt_status;
392 nt_status = make_user_info(mem_ctx,
393 user_info,
394 "","",
395 "","",
396 "",
397 remote_address,
398 local_address,
399 service_description,
400 NULL, NULL,
401 NULL, NULL,
402 NULL,
403 AUTH_PASSWORD_RESPONSE);
405 return NT_STATUS_IS_OK(nt_status) ? true : false;
408 static NTSTATUS log_nt_token(struct security_token *token)
410 TALLOC_CTX *frame = talloc_stackframe();
411 char *command;
412 char *group_sidstr;
413 size_t i;
415 if ((lp_log_nt_token_command(frame) == NULL) ||
416 (strlen(lp_log_nt_token_command(frame)) == 0)) {
417 TALLOC_FREE(frame);
418 return NT_STATUS_OK;
421 group_sidstr = talloc_strdup(frame, "");
422 for (i=1; i<token->num_sids; i++) {
423 group_sidstr = talloc_asprintf(
424 frame, "%s %s", group_sidstr,
425 sid_string_talloc(frame, &token->sids[i]));
428 command = talloc_string_sub(
429 frame, lp_log_nt_token_command(frame),
430 "%s", sid_string_talloc(frame, &token->sids[0]));
431 command = talloc_string_sub(frame, command, "%t", group_sidstr);
433 if (command == NULL) {
434 TALLOC_FREE(frame);
435 return NT_STATUS_NO_MEMORY;
438 DEBUG(8, ("running command: [%s]\n", command));
439 if (smbrun(command, NULL, NULL) != 0) {
440 DEBUG(0, ("Could not log NT token\n"));
441 TALLOC_FREE(frame);
442 return NT_STATUS_ACCESS_DENIED;
445 TALLOC_FREE(frame);
446 return NT_STATUS_OK;
450 * Create the token to use from server_info->info3 and
451 * server_info->sids (the info3/sam groups). Find the unix gids.
454 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
455 const struct auth_serversupplied_info *server_info,
456 DATA_BLOB *session_key,
457 const char *smb_username, /* for ->sanitized_username, for %U subs */
458 struct auth_session_info **session_info_out)
460 struct security_token *t;
461 NTSTATUS status;
462 size_t i;
463 struct dom_sid tmp_sid;
464 struct auth_session_info *session_info;
465 struct unixid *ids;
466 fstring tmp;
468 /* Ensure we can't possible take a code path leading to a
469 * null defref. */
470 if (!server_info) {
471 return NT_STATUS_LOGON_FAILURE;
474 session_info = talloc_zero(mem_ctx, struct auth_session_info);
475 if (!session_info) {
476 return NT_STATUS_NO_MEMORY;
479 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
480 if (!session_info->unix_token) {
481 TALLOC_FREE(session_info);
482 return NT_STATUS_NO_MEMORY;
485 session_info->unix_token->uid = server_info->utok.uid;
486 session_info->unix_token->gid = server_info->utok.gid;
488 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
489 if (!session_info->unix_info) {
490 TALLOC_FREE(session_info);
491 return NT_STATUS_NO_MEMORY;
494 session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
495 if (!session_info->unix_info->unix_name) {
496 TALLOC_FREE(session_info);
497 return NT_STATUS_NO_MEMORY;
500 /* This is a potentially untrusted username for use in %U */
501 alpha_strcpy(tmp, smb_username, ". _-$", sizeof(tmp));
502 session_info->unix_info->sanitized_username =
503 talloc_strdup(session_info->unix_info, tmp);
505 if (session_key) {
506 data_blob_free(&session_info->session_key);
507 session_info->session_key = data_blob_talloc(session_info,
508 session_key->data,
509 session_key->length);
510 if (!session_info->session_key.data && session_key->length) {
511 return NT_STATUS_NO_MEMORY;
513 } else {
514 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
515 server_info->session_key.length);
518 /* We need to populate session_info->info with the information found in server_info->info3 */
519 status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
520 server_info->guest == false,
521 &session_info->info);
522 if (!NT_STATUS_IS_OK(status)) {
523 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
524 TALLOC_FREE(session_info);
525 return status;
528 if (server_info->security_token) {
529 /* Just copy the token, it has already been finalised
530 * (nasty hack to support a cached guest/system session_info
533 session_info->security_token = dup_nt_token(session_info, server_info->security_token);
534 if (!session_info->security_token) {
535 TALLOC_FREE(session_info);
536 return NT_STATUS_NO_MEMORY;
539 session_info->unix_token->ngroups = server_info->utok.ngroups;
540 if (server_info->utok.ngroups != 0) {
541 session_info->unix_token->groups = (gid_t *)talloc_memdup(
542 session_info->unix_token, server_info->utok.groups,
543 sizeof(gid_t)*session_info->unix_token->ngroups);
544 } else {
545 session_info->unix_token->groups = NULL;
548 *session_info_out = session_info;
549 return NT_STATUS_OK;
553 * If winbind is not around, we can not make much use of the SIDs the
554 * domain controller provided us with. Likewise if the user name was
555 * mapped to some local unix user.
558 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
559 (server_info->nss_token)) {
560 char *found_username = NULL;
561 status = create_token_from_username(session_info,
562 server_info->unix_name,
563 server_info->guest,
564 &session_info->unix_token->uid,
565 &session_info->unix_token->gid,
566 &found_username,
567 &session_info->security_token);
568 if (NT_STATUS_IS_OK(status)) {
569 session_info->unix_info->unix_name = found_username;
571 } else {
572 status = create_local_nt_token_from_info3(session_info,
573 server_info->guest,
574 server_info->info3,
575 &server_info->extra,
576 &session_info->security_token);
579 if (!NT_STATUS_IS_OK(status)) {
580 return status;
583 /* Convert the SIDs to gids. */
585 session_info->unix_token->ngroups = 0;
586 session_info->unix_token->groups = NULL;
588 t = session_info->security_token;
590 ids = talloc_array(talloc_tos(), struct unixid,
591 t->num_sids);
592 if (ids == NULL) {
593 return NT_STATUS_NO_MEMORY;
596 if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
597 TALLOC_FREE(ids);
598 return NT_STATUS_NO_MEMORY;
601 for (i=0; i<t->num_sids; i++) {
603 if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
604 continue;
607 if (ids[i].type != ID_TYPE_GID &&
608 ids[i].type != ID_TYPE_BOTH) {
609 DEBUG(10, ("Could not convert SID %s to gid, "
610 "ignoring it\n",
611 sid_string_dbg(&t->sids[i])));
612 continue;
614 if (!add_gid_to_array_unique(session_info->unix_token,
615 ids[i].id,
616 &session_info->unix_token->groups,
617 &session_info->unix_token->ngroups)) {
618 return NT_STATUS_NO_MEMORY;
623 * Add the "Unix Group" SID for each gid to catch mapped groups
624 * and their Unix equivalent. This is to solve the backwards
625 * compatibility problem of 'valid users = +ntadmin' where
626 * ntadmin has been paired with "Domain Admins" in the group
627 * mapping table. Otherwise smb.conf would need to be changed
628 * to 'valid user = "Domain Admins"'. --jerry
630 * For consistency we also add the "Unix User" SID,
631 * so that the complete unix token is represented within
632 * the nt token.
635 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
637 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
638 &session_info->security_token->sids,
639 &session_info->security_token->num_sids);
641 for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
642 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
643 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
644 &session_info->security_token->sids,
645 &session_info->security_token->num_sids);
648 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
649 debug_unix_user_token(DBGC_AUTH, 10,
650 session_info->unix_token->uid,
651 session_info->unix_token->gid,
652 session_info->unix_token->ngroups,
653 session_info->unix_token->groups);
655 status = log_nt_token(session_info->security_token);
656 if (!NT_STATUS_IS_OK(status)) {
657 return status;
660 *session_info_out = session_info;
661 return NT_STATUS_OK;
664 /***************************************************************************
665 Make (and fill) a server_info struct from a 'struct passwd' by conversion
666 to a struct samu
667 ***************************************************************************/
669 NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
670 const char *unix_username,
671 const struct passwd *pwd,
672 struct auth_serversupplied_info **server_info)
674 NTSTATUS status;
675 TALLOC_CTX *tmp_ctx = NULL;
676 struct auth_serversupplied_info *result;
678 tmp_ctx = talloc_stackframe();
679 if (tmp_ctx == NULL) {
680 return NT_STATUS_NO_MEMORY;
683 result = make_server_info(tmp_ctx);
684 if (result == NULL) {
685 status = NT_STATUS_NO_MEMORY;
686 goto done;
689 status = passwd_to_SamInfo3(result,
690 unix_username,
691 pwd,
692 &result->info3,
693 &result->extra);
694 if (!NT_STATUS_IS_OK(status)) {
695 goto done;
698 result->unix_name = talloc_strdup(result, unix_username);
699 if (result->unix_name == NULL) {
700 status = NT_STATUS_NO_MEMORY;
701 goto done;
704 result->utok.uid = pwd->pw_uid;
705 result->utok.gid = pwd->pw_gid;
707 *server_info = talloc_steal(mem_ctx, result);
708 status = NT_STATUS_OK;
709 done:
710 talloc_free(tmp_ctx);
712 return status;
715 static NTSTATUS get_system_info3(TALLOC_CTX *mem_ctx,
716 struct netr_SamInfo3 *info3)
718 NTSTATUS status;
720 /* Set account name */
721 init_lsa_String(&info3->base.account_name, "SYSTEM");
723 /* Set domain name */
724 init_lsa_StringLarge(&info3->base.logon_domain, "NT AUTHORITY");
727 status = dom_sid_split_rid(mem_ctx, &global_sid_System,
728 &info3->base.domain_sid,
729 &info3->base.rid);
730 if (!NT_STATUS_IS_OK(status)) {
731 return status;
734 /* Primary gid is the same */
735 info3->base.primary_gid = info3->base.rid;
737 return NT_STATUS_OK;
740 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
741 struct netr_SamInfo3 *info3)
743 const char *guest_account = lp_guest_account();
744 struct dom_sid domain_sid;
745 struct passwd *pwd;
746 const char *tmp;
748 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
749 if (pwd == NULL) {
750 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
751 "account [%s]!\n", guest_account));
752 return NT_STATUS_NO_SUCH_USER;
755 /* Set account name */
756 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
757 if (tmp == NULL) {
758 return NT_STATUS_NO_MEMORY;
760 init_lsa_String(&info3->base.account_name, tmp);
762 /* Set domain name */
763 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
764 if (tmp == NULL) {
765 return NT_STATUS_NO_MEMORY;
767 init_lsa_StringLarge(&info3->base.logon_domain, tmp);
769 /* Domain sid */
770 sid_copy(&domain_sid, get_global_sam_sid());
772 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
773 if (info3->base.domain_sid == NULL) {
774 return NT_STATUS_NO_MEMORY;
777 /* Guest rid */
778 info3->base.rid = DOMAIN_RID_GUEST;
780 /* Primary gid */
781 info3->base.primary_gid = DOMAIN_RID_GUESTS;
783 /* Set as guest */
784 info3->base.user_flags = NETLOGON_GUEST;
786 TALLOC_FREE(pwd);
787 return NT_STATUS_OK;
790 /***************************************************************************
791 Make (and fill) a user_info struct for a guest login.
792 This *must* succeed for smbd to start. If there is no mapping entry for
793 the guest gid, then create one.
795 The resulting structure is a 'session_info' because
796 create_local_token() has already been called on it. This is quite
797 nasty, as the auth subsystem isn't expect this, but the behavior is
798 left as-is for now.
799 ***************************************************************************/
801 static NTSTATUS make_new_session_info_guest(TALLOC_CTX *mem_ctx,
802 struct auth_session_info **_session_info,
803 struct auth_serversupplied_info **_server_info)
805 struct auth_session_info *session_info = NULL;
806 struct auth_serversupplied_info *server_info = NULL;
807 const char *guest_account = lp_guest_account();
808 const char *domain = lp_netbios_name();
809 struct netr_SamInfo3 info3;
810 TALLOC_CTX *tmp_ctx;
811 NTSTATUS status;
813 tmp_ctx = talloc_stackframe();
814 if (tmp_ctx == NULL) {
815 return NT_STATUS_NO_MEMORY;
818 ZERO_STRUCT(info3);
820 status = get_guest_info3(tmp_ctx, &info3);
821 if (!NT_STATUS_IS_OK(status)) {
822 DEBUG(0, ("get_guest_info3 failed with %s\n",
823 nt_errstr(status)));
824 goto done;
827 status = make_server_info_info3(tmp_ctx,
828 guest_account,
829 domain,
830 &server_info,
831 &info3);
832 if (!NT_STATUS_IS_OK(status)) {
833 DEBUG(0, ("make_server_info_info3 failed with %s\n",
834 nt_errstr(status)));
835 goto done;
838 server_info->guest = true;
840 /* This should not be done here (we should produce a server
841 * info, and later construct a session info from it), but for
842 * now this does not change the previous behavior */
843 status = create_local_token(tmp_ctx, server_info, NULL,
844 server_info->info3->base.account_name.string,
845 &session_info);
846 if (!NT_STATUS_IS_OK(status)) {
847 DEBUG(0, ("create_local_token failed: %s\n",
848 nt_errstr(status)));
849 goto done;
852 /* annoying, but the Guest really does have a session key, and it is
853 all zeros! */
854 session_info->session_key = data_blob_talloc_zero(session_info, 16);
856 *_session_info = talloc_move(mem_ctx, &session_info);
857 *_server_info = talloc_move(mem_ctx, &server_info);
859 status = NT_STATUS_OK;
860 done:
861 TALLOC_FREE(tmp_ctx);
862 return status;
865 /***************************************************************************
866 Make (and fill) a auth_session_info struct for a system user login.
867 This *must* succeed for smbd to start.
868 ***************************************************************************/
870 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
871 struct auth_session_info **session_info)
873 NTSTATUS status;
874 struct auth_serversupplied_info *server_info;
875 TALLOC_CTX *tmp_ctx;
877 tmp_ctx = talloc_stackframe();
878 if (tmp_ctx == NULL) {
879 return NT_STATUS_NO_MEMORY;
882 server_info = make_server_info(tmp_ctx);
883 if (!server_info) {
884 status = NT_STATUS_NO_MEMORY;
885 DEBUG(0, ("failed making server_info\n"));
886 goto done;
889 server_info->info3 = talloc_zero(server_info, struct netr_SamInfo3);
890 if (!server_info->info3) {
891 status = NT_STATUS_NO_MEMORY;
892 DEBUG(0, ("talloc failed setting info3\n"));
893 goto done;
896 status = get_system_info3(server_info, server_info->info3);
897 if (!NT_STATUS_IS_OK(status)) {
898 DEBUG(0, ("Failed creating system info3 with %s\n",
899 nt_errstr(status)));
900 goto done;
903 server_info->utok.uid = sec_initial_uid();
904 server_info->utok.gid = sec_initial_gid();
905 server_info->unix_name = talloc_asprintf(server_info,
906 "NT AUTHORITY%cSYSTEM",
907 *lp_winbind_separator());
909 if (!server_info->unix_name) {
910 status = NT_STATUS_NO_MEMORY;
911 DEBUG(0, ("talloc_asprintf failed setting unix_name\n"));
912 goto done;
915 server_info->security_token = talloc_zero(server_info, struct security_token);
916 if (!server_info->security_token) {
917 status = NT_STATUS_NO_MEMORY;
918 DEBUG(0, ("talloc failed setting security token\n"));
919 goto done;
922 status = add_sid_to_array_unique(server_info->security_token->sids,
923 &global_sid_System,
924 &server_info->security_token->sids,
925 &server_info->security_token->num_sids);
926 if (!NT_STATUS_IS_OK(status)) {
927 goto done;
930 /* SYSTEM has all privilages */
931 server_info->security_token->privilege_mask = ~0;
933 /* Now turn the server_info into a session_info with the full token etc */
934 status = create_local_token(mem_ctx, server_info, NULL, "SYSTEM", session_info);
935 talloc_free(server_info);
937 if (!NT_STATUS_IS_OK(status)) {
938 DEBUG(0, ("create_local_token failed: %s\n",
939 nt_errstr(status)));
940 goto done;
943 talloc_steal(mem_ctx, *session_info);
945 done:
946 TALLOC_FREE(tmp_ctx);
947 return status;
950 /****************************************************************************
951 Fake a auth_session_info just from a username (as a
952 session_info structure, with create_local_token() already called on
954 ****************************************************************************/
956 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
957 const char *username,
958 bool is_guest,
959 struct auth_session_info **session_info)
961 struct passwd *pwd;
962 NTSTATUS status;
963 struct auth_serversupplied_info *result;
964 TALLOC_CTX *tmp_ctx;
966 tmp_ctx = talloc_stackframe();
967 if (tmp_ctx == NULL) {
968 return NT_STATUS_NO_MEMORY;
971 pwd = Get_Pwnam_alloc(tmp_ctx, username);
972 if (pwd == NULL) {
973 status = NT_STATUS_NO_SUCH_USER;
974 goto done;
977 status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
978 if (!NT_STATUS_IS_OK(status)) {
979 goto done;
982 result->nss_token = true;
983 result->guest = is_guest;
985 /* Now turn the server_info into a session_info with the full token etc */
986 status = create_local_token(mem_ctx,
987 result,
988 NULL,
989 pwd->pw_name,
990 session_info);
992 done:
993 talloc_free(tmp_ctx);
995 return status;
998 /* This function MUST only used to create the cached server_info for
999 * guest.
1001 * This is a lossy conversion. Variables known to be lost so far
1002 * include:
1004 * - nss_token (not needed because the only read doesn't happen
1005 * for the GUEST user, as this routine populates ->security_token
1007 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1009 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1011 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1012 const struct auth_session_info *src,
1013 struct auth_serversupplied_info *server_info)
1015 struct auth_serversupplied_info *dst;
1016 NTSTATUS status;
1018 dst = make_server_info(mem_ctx);
1019 if (dst == NULL) {
1020 return NULL;
1023 /* This element must be provided to convert back to an auth_serversupplied_info */
1024 SMB_ASSERT(src->unix_info);
1026 dst->guest = true;
1027 dst->system = false;
1029 /* This element must be provided to convert back to an
1030 * auth_serversupplied_info. This needs to be from the
1031 * auth_session_info because the group values in particular
1032 * may change during create_local_token() processing */
1033 SMB_ASSERT(src->unix_token);
1034 dst->utok.uid = src->unix_token->uid;
1035 dst->utok.gid = src->unix_token->gid;
1036 dst->utok.ngroups = src->unix_token->ngroups;
1037 if (src->unix_token->ngroups != 0) {
1038 dst->utok.groups = (gid_t *)talloc_memdup(
1039 dst, src->unix_token->groups,
1040 sizeof(gid_t)*dst->utok.ngroups);
1041 } else {
1042 dst->utok.groups = NULL;
1045 /* We must have a security_token as otherwise the lossy
1046 * conversion without nss_token would cause create_local_token
1047 * to take the wrong path */
1048 SMB_ASSERT(src->security_token);
1050 dst->security_token = dup_nt_token(dst, src->security_token);
1051 if (!dst->security_token) {
1052 TALLOC_FREE(dst);
1053 return NULL;
1056 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1057 src->session_key.length);
1059 /* This is OK because this functions is only used for the
1060 * GUEST account, which has all-zero keys for both values */
1061 dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1062 src->session_key.length);
1064 status = copy_netr_SamInfo3(dst,
1065 server_info->info3,
1066 &dst->info3);
1067 if (!NT_STATUS_IS_OK(status)) {
1068 TALLOC_FREE(dst);
1069 return NULL;
1072 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1073 if (!dst->unix_name) {
1074 TALLOC_FREE(dst);
1075 return NULL;
1078 return dst;
1081 struct auth_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
1082 const struct auth_session_info *src)
1084 struct auth_session_info *dst;
1085 DATA_BLOB blob;
1086 enum ndr_err_code ndr_err;
1088 ndr_err = ndr_push_struct_blob(
1089 &blob, talloc_tos(), src,
1090 (ndr_push_flags_fn_t)ndr_push_auth_session_info);
1091 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1092 DEBUG(0, ("copy_session_info(): ndr_push_auth_session_info failed: "
1093 "%s\n", ndr_errstr(ndr_err)));
1094 return NULL;
1097 dst = talloc(mem_ctx, struct auth_session_info);
1098 if (dst == NULL) {
1099 DEBUG(0, ("talloc failed\n"));
1100 TALLOC_FREE(blob.data);
1101 return NULL;
1104 ndr_err = ndr_pull_struct_blob(
1105 &blob, dst, dst,
1106 (ndr_pull_flags_fn_t)ndr_pull_auth_session_info);
1107 TALLOC_FREE(blob.data);
1109 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1110 DEBUG(0, ("copy_session_info(): ndr_pull_auth_session_info failed: "
1111 "%s\n", ndr_errstr(ndr_err)));
1112 TALLOC_FREE(dst);
1113 return NULL;
1116 return dst;
1120 * Set a new session key. Used in the rpc server where we have to override the
1121 * SMB level session key with SystemLibraryDTC
1124 bool session_info_set_session_key(struct auth_session_info *info,
1125 DATA_BLOB session_key)
1127 TALLOC_FREE(info->session_key.data);
1129 info->session_key = data_blob_talloc(
1130 info, session_key.data, session_key.length);
1132 return (info->session_key.data != NULL);
1135 static struct auth_session_info *guest_info = NULL;
1137 static struct auth_serversupplied_info *guest_server_info = NULL;
1139 bool init_guest_session_info(TALLOC_CTX *mem_ctx)
1141 NTSTATUS status;
1143 if (guest_info != NULL)
1144 return true;
1146 status = make_new_session_info_guest(mem_ctx,
1147 &guest_info,
1148 &guest_server_info);
1149 return NT_STATUS_IS_OK(status);
1152 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1153 struct auth_serversupplied_info **server_info)
1155 /* This is trickier than it would appear to need to be because
1156 * we are trying to avoid certain costly operations when the
1157 * structure is converted to a 'auth_session_info' again in
1158 * create_local_token() */
1159 *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1160 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1163 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1164 struct auth_session_info **session_info)
1166 *session_info = copy_session_info(mem_ctx, guest_info);
1167 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1170 static struct auth_session_info *system_info = NULL;
1172 NTSTATUS init_system_session_info(void)
1174 if (system_info != NULL)
1175 return NT_STATUS_OK;
1177 return make_new_session_info_system(NULL, &system_info);
1180 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1181 struct auth_session_info **session_info)
1183 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1184 *session_info = copy_session_info(mem_ctx, system_info);
1185 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1188 const struct auth_session_info *get_session_info_system(void)
1190 return system_info;
1193 /***************************************************************************
1194 Purely internal function for make_server_info_info3
1195 ***************************************************************************/
1197 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1198 const char *username, char **found_username,
1199 struct passwd **pwd,
1200 bool *username_was_mapped)
1202 char *orig_dom_user = NULL;
1203 char *dom_user = NULL;
1204 char *lower_username = NULL;
1205 char *real_username = NULL;
1206 struct passwd *passwd;
1208 lower_username = talloc_strdup(mem_ctx, username);
1209 if (!lower_username) {
1210 return NT_STATUS_NO_MEMORY;
1212 if (!strlower_m( lower_username )) {
1213 return NT_STATUS_INVALID_PARAMETER;
1216 orig_dom_user = talloc_asprintf(mem_ctx,
1217 "%s%c%s",
1218 domain,
1219 *lp_winbind_separator(),
1220 lower_username);
1221 if (!orig_dom_user) {
1222 return NT_STATUS_NO_MEMORY;
1225 /* Get the passwd struct. Try to create the account if necessary. */
1227 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1228 if (!dom_user) {
1229 return NT_STATUS_NO_MEMORY;
1232 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
1233 if (!passwd) {
1234 DEBUG(3, ("Failed to find authenticated user %s via "
1235 "getpwnam(), denying access.\n", dom_user));
1236 return NT_STATUS_NO_SUCH_USER;
1239 if (!real_username) {
1240 return NT_STATUS_NO_MEMORY;
1243 *pwd = passwd;
1245 /* This is pointless -- there is no support for differing
1246 unix and windows names. Make sure to always store the
1247 one we actually looked up and succeeded. Have I mentioned
1248 why I hate the 'winbind use default domain' parameter?
1249 --jerry */
1251 *found_username = talloc_strdup( mem_ctx, real_username );
1253 return NT_STATUS_OK;
1256 /****************************************************************************
1257 Wrapper to allow the getpwnam() call to strip the domain name and
1258 try again in case a local UNIX user is already there. Also run through
1259 the username if we fallback to the username only.
1260 ****************************************************************************/
1262 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1263 char **p_save_username, bool create )
1265 struct passwd *pw = NULL;
1266 char *p = NULL;
1267 char *username = NULL;
1269 /* we only save a copy of the username it has been mangled
1270 by winbindd use default domain */
1271 *p_save_username = NULL;
1273 /* don't call map_username() here since it has to be done higher
1274 up the stack so we don't call it multiple times */
1276 username = talloc_strdup(mem_ctx, domuser);
1277 if (!username) {
1278 return NULL;
1281 p = strchr_m( username, *lp_winbind_separator() );
1283 /* code for a DOMAIN\user string */
1285 if ( p ) {
1286 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1287 if ( pw ) {
1288 /* make sure we get the case of the username correct */
1289 /* work around 'winbind use default domain = yes' */
1291 if ( lp_winbind_use_default_domain() &&
1292 !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1293 char *domain;
1295 /* split the domain and username into 2 strings */
1296 *p = '\0';
1297 domain = username;
1299 *p_save_username = talloc_asprintf(mem_ctx,
1300 "%s%c%s",
1301 domain,
1302 *lp_winbind_separator(),
1303 pw->pw_name);
1304 if (!*p_save_username) {
1305 TALLOC_FREE(pw);
1306 return NULL;
1308 } else {
1309 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1312 /* whew -- done! */
1313 return pw;
1316 /* setup for lookup of just the username */
1317 /* remember that p and username are overlapping memory */
1319 p++;
1320 username = talloc_strdup(mem_ctx, p);
1321 if (!username) {
1322 return NULL;
1326 /* just lookup a plain username */
1328 pw = Get_Pwnam_alloc(mem_ctx, username);
1330 /* Create local user if requested but only if winbindd
1331 is not running. We need to protect against cases
1332 where winbindd is failing and then prematurely
1333 creating users in /etc/passwd */
1335 if ( !pw && create && !winbind_ping() ) {
1336 /* Don't add a machine account. */
1337 if (username[strlen(username)-1] == '$')
1338 return NULL;
1340 _smb_create_user(NULL, username, NULL);
1341 pw = Get_Pwnam_alloc(mem_ctx, username);
1344 /* one last check for a valid passwd struct */
1346 if (pw) {
1347 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1349 return pw;
1352 /***************************************************************************
1353 Make a server_info struct from the info3 returned by a domain logon
1354 ***************************************************************************/
1356 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1357 const char *sent_nt_username,
1358 const char *domain,
1359 struct auth_serversupplied_info **server_info,
1360 const struct netr_SamInfo3 *info3)
1362 NTSTATUS nt_status = NT_STATUS_OK;
1363 char *found_username = NULL;
1364 const char *nt_domain;
1365 const char *nt_username;
1366 struct dom_sid user_sid;
1367 struct dom_sid group_sid;
1368 bool username_was_mapped;
1369 struct passwd *pwd;
1370 struct auth_serversupplied_info *result;
1371 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1374 Here is where we should check the list of
1375 trusted domains, and verify that the SID
1376 matches.
1379 if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
1380 nt_status = NT_STATUS_INVALID_PARAMETER;
1381 goto out;
1384 if (!sid_compose(&group_sid, info3->base.domain_sid,
1385 info3->base.primary_gid)) {
1386 nt_status = NT_STATUS_INVALID_PARAMETER;
1387 goto out;
1390 nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
1391 if (!nt_username) {
1392 /* If the server didn't give us one, just use the one we sent
1393 * them */
1394 nt_username = sent_nt_username;
1397 nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
1398 if (!nt_domain) {
1399 /* If the server didn't give us one, just use the one we sent
1400 * them */
1401 nt_domain = domain;
1404 /* If getpwnam() fails try the add user script (2.2.x behavior).
1406 We use the _unmapped_ username here in an attempt to provide
1407 consistent username mapping behavior between kerberos and NTLM[SSP]
1408 authentication in domain mode security. I.E. Username mapping
1409 should be applied to the fully qualified username
1410 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1411 called map_username() unnecessarily in make_user_info_map() but
1412 that is how the current code is designed. Making the change here
1413 is the least disruptive place. -- jerry */
1415 /* this call will try to create the user if necessary */
1417 nt_status = check_account(tmp_ctx,
1418 nt_domain,
1419 nt_username,
1420 &found_username,
1421 &pwd,
1422 &username_was_mapped);
1424 if (!NT_STATUS_IS_OK(nt_status)) {
1425 /* Handle 'map to guest = Bad Uid */
1426 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
1427 (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
1428 lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
1429 DBG_NOTICE("Try to map %s to guest account",
1430 nt_username);
1431 nt_status = make_server_info_guest(tmp_ctx, &result);
1432 if (NT_STATUS_IS_OK(nt_status)) {
1433 *server_info = talloc_move(mem_ctx, &result);
1436 goto out;
1439 result = make_server_info(tmp_ctx);
1440 if (result == NULL) {
1441 DEBUG(4, ("make_server_info failed!\n"));
1442 nt_status = NT_STATUS_NO_MEMORY;
1443 goto out;
1446 result->unix_name = talloc_strdup(result, found_username);
1448 /* copy in the info3 */
1449 nt_status = copy_netr_SamInfo3(result,
1450 info3,
1451 &result->info3);
1452 if (!NT_STATUS_IS_OK(nt_status)) {
1453 goto out;
1456 /* Fill in the unix info we found on the way */
1458 result->utok.uid = pwd->pw_uid;
1459 result->utok.gid = pwd->pw_gid;
1461 /* ensure we are never given NULL session keys */
1463 if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
1464 result->session_key = data_blob_null;
1465 } else {
1466 result->session_key = data_blob_talloc(
1467 result, info3->base.key.key,
1468 sizeof(info3->base.key.key));
1471 if (all_zero(info3->base.LMSessKey.key,
1472 sizeof(info3->base.LMSessKey.key))) {
1473 result->lm_session_key = data_blob_null;
1474 } else {
1475 result->lm_session_key = data_blob_talloc(
1476 result, info3->base.LMSessKey.key,
1477 sizeof(info3->base.LMSessKey.key));
1480 result->nss_token |= username_was_mapped;
1482 result->guest = (info3->base.user_flags & NETLOGON_GUEST);
1484 *server_info = talloc_move(mem_ctx, &result);
1486 nt_status = NT_STATUS_OK;
1487 out:
1488 talloc_free(tmp_ctx);
1490 return nt_status;
1493 /*****************************************************************************
1494 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1495 ******************************************************************************/
1497 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1498 const char *sent_nt_username,
1499 const char *domain,
1500 const struct wbcAuthUserInfo *info,
1501 struct auth_serversupplied_info **server_info)
1503 struct netr_SamInfo3 info3;
1504 struct netr_SamInfo6 *info6;
1506 info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
1507 if (!info6) {
1508 return NT_STATUS_NO_MEMORY;
1511 info3.base = info6->base;
1512 info3.sidcount = info6->sidcount;
1513 info3.sids = info6->sids;
1515 return make_server_info_info3(mem_ctx,
1516 sent_nt_username, domain,
1517 server_info, &info3);
1521 * Verify whether or not given domain is trusted.
1523 * This should only be used on a DC.
1525 * @param domain_name name of the domain to be verified
1526 * @return true if domain is one of the trusted ones or
1527 * false if otherwise
1530 bool is_trusted_domain(const char* dom_name)
1532 bool ret;
1534 if (!IS_DC) {
1535 return false;
1538 if (dom_name == NULL || dom_name[0] == '\0') {
1539 return false;
1542 if (strequal(dom_name, get_global_sam_name())) {
1543 return false;
1546 become_root();
1547 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1548 "[%s]\n", dom_name ));
1549 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1550 unbecome_root();
1552 return ret;
1558 on a logon error possibly map the error to success if "map to guest"
1559 is set approriately
1561 NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
1562 NTSTATUS status,
1563 const char *user,
1564 const char *domain,
1565 struct auth_serversupplied_info **server_info)
1567 user = user ? user : "";
1568 domain = domain ? domain : "";
1570 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1571 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
1572 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
1573 DEBUG(3,("No such user %s [%s] - using guest account\n",
1574 user, domain));
1575 return make_server_info_guest(mem_ctx, server_info);
1577 } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1578 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
1579 DEBUG(3,("Registered username %s for guest access\n",
1580 user));
1581 return make_server_info_guest(mem_ctx, server_info);
1585 return status;
1589 Extract session key from a session info and return it in a blob
1590 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
1592 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
1593 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
1595 Note that returned session_key is referencing the original key, it is supposed to be
1596 short-lived. If original session_info->session_key is gone, the reference will be broken.
1598 NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
1601 if (session_key == NULL || session_info == NULL) {
1602 return NT_STATUS_INVALID_PARAMETER;
1605 if (session_info->session_key.length == 0) {
1606 return NT_STATUS_NO_USER_SESSION_KEY;
1609 *session_key = session_info->session_key;
1610 if (intent == KEY_USE_16BYTES) {
1611 session_key->length = MIN(session_info->session_key.length, 16);
1613 return NT_STATUS_OK;