source: vendor/current/source3/auth/auth_util.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 46.0 KB
Line 
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
9
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.
14
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.
19
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/>.
22*/
23
24#include "includes.h"
25#include "auth.h"
26#include "../libcli/auth/libcli_auth.h"
27#include "../lib/crypto/arcfour.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
39#undef DBGC_CLASS
40#define DBGC_CLASS DBGC_AUTH
41
42/****************************************************************************
43 Create a UNIX user on demand.
44****************************************************************************/
45
46static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
47{
48 TALLOC_CTX *ctx = talloc_tos();
49 char *add_script;
50 int ret;
51
52 add_script = lp_add_user_script(ctx);
53 if (!add_script || !*add_script) {
54 return -1;
55 }
56 add_script = talloc_all_string_sub(ctx,
57 add_script,
58 "%u",
59 unix_username);
60 if (!add_script) {
61 return -1;
62 }
63 if (domain) {
64 add_script = talloc_all_string_sub(ctx,
65 add_script,
66 "%D",
67 domain);
68 if (!add_script) {
69 return -1;
70 }
71 }
72 if (homedir) {
73 add_script = talloc_all_string_sub(ctx,
74 add_script,
75 "%H",
76 homedir);
77 if (!add_script) {
78 return -1;
79 }
80 }
81 ret = smbrun(add_script,NULL);
82 flush_pwnam_cache();
83 DEBUG(ret ? 0 : 3,
84 ("smb_create_user: Running the command `%s' gave %d\n",
85 add_script,ret));
86 return ret;
87}
88
89/****************************************************************************
90 Create an auth_usersupplied_data structure after appropriate mapping.
91****************************************************************************/
92
93NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
94 struct auth_usersupplied_info **user_info,
95 const char *smb_name,
96 const char *client_domain,
97 const char *workstation_name,
98 const struct tsocket_address *remote_address,
99 const DATA_BLOB *lm_pwd,
100 const DATA_BLOB *nt_pwd,
101 const struct samr_Password *lm_interactive_pwd,
102 const struct samr_Password *nt_interactive_pwd,
103 const char *plaintext,
104 enum auth_password_state password_state)
105{
106 const char *domain;
107 NTSTATUS result;
108 bool was_mapped;
109 char *internal_username = NULL;
110
111 was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
112 if (!internal_username) {
113 return NT_STATUS_NO_MEMORY;
114 }
115
116 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
117 client_domain, smb_name, workstation_name));
118
119 domain = client_domain;
120
121 /* If you connect to a Windows domain member using a bogus domain name,
122 * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if
123 * the Windows box is a DC the name will become DOMAIN\user and be
124 * authenticated against AD, if the Windows box is a member server but
125 * not a DC the name will become WORKSTATION\user. A standalone
126 * non-domain member box will also map to WORKSTATION\user.
127 * This also deals with the client passing in a "" domain */
128
129 if (!is_trusted_domain(domain) &&
130 !strequal(domain, my_sam_name()) &&
131 !strequal(domain, get_global_sam_name()))
132 {
133 if (lp_map_untrusted_to_domain())
134 domain = my_sam_name();
135 else
136 domain = get_global_sam_name();
137 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
138 "workstation [%s]\n",
139 client_domain, domain, smb_name, workstation_name));
140 }
141
142 /* We know that the given domain is trusted (and we are allowing them),
143 * it is our global SAM name, or for legacy behavior it is our
144 * primary domain name */
145
146 result = make_user_info(mem_ctx, user_info, smb_name, internal_username,
147 client_domain, domain, workstation_name,
148 remote_address, lm_pwd, nt_pwd,
149 lm_interactive_pwd, nt_interactive_pwd,
150 plaintext, password_state);
151 if (NT_STATUS_IS_OK(result)) {
152 /* We have tried mapping */
153 (*user_info)->mapped_state = true;
154 /* did we actually map the user to a different name? */
155 (*user_info)->was_mapped = was_mapped;
156 }
157 return result;
158}
159
160/****************************************************************************
161 Create an auth_usersupplied_data, making the DATA_BLOBs here.
162 Decrypt and encrypt the passwords.
163****************************************************************************/
164
165bool make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
166 struct auth_usersupplied_info **user_info,
167 const char *smb_name,
168 const char *client_domain,
169 const char *workstation_name,
170 const struct tsocket_address *remote_address,
171 uint32_t logon_parameters,
172 const uchar *lm_network_pwd,
173 int lm_pwd_len,
174 const uchar *nt_network_pwd,
175 int nt_pwd_len)
176{
177 bool ret;
178 NTSTATUS status;
179 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
180 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
181
182 status = make_user_info_map(mem_ctx, user_info,
183 smb_name, client_domain,
184 workstation_name,
185 remote_address,
186 lm_pwd_len ? &lm_blob : NULL,
187 nt_pwd_len ? &nt_blob : NULL,
188 NULL, NULL, NULL,
189 AUTH_PASSWORD_RESPONSE);
190
191 if (NT_STATUS_IS_OK(status)) {
192 (*user_info)->logon_parameters = logon_parameters;
193 }
194 ret = NT_STATUS_IS_OK(status) ? true : false;
195
196 data_blob_free(&lm_blob);
197 data_blob_free(&nt_blob);
198 return ret;
199}
200
201/****************************************************************************
202 Create an auth_usersupplied_data, making the DATA_BLOBs here.
203 Decrypt and encrypt the passwords.
204****************************************************************************/
205
206bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
207 struct auth_usersupplied_info **user_info,
208 const char *smb_name,
209 const char *client_domain,
210 const char *workstation_name,
211 const struct tsocket_address *remote_address,
212 uint32_t logon_parameters,
213 const uchar chal[8],
214 const uchar lm_interactive_pwd[16],
215 const uchar nt_interactive_pwd[16])
216{
217 struct samr_Password lm_pwd;
218 struct samr_Password nt_pwd;
219 unsigned char local_lm_response[24];
220 unsigned char local_nt_response[24];
221
222 if (lm_interactive_pwd)
223 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
224
225 if (nt_interactive_pwd)
226 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
227
228 if (lm_interactive_pwd)
229 SMBOWFencrypt(lm_pwd.hash, chal,
230 local_lm_response);
231
232 if (nt_interactive_pwd)
233 SMBOWFencrypt(nt_pwd.hash, chal,
234 local_nt_response);
235
236 {
237 bool ret;
238 NTSTATUS nt_status;
239 DATA_BLOB local_lm_blob = data_blob_null;
240 DATA_BLOB local_nt_blob = data_blob_null;
241
242 if (lm_interactive_pwd) {
243 local_lm_blob = data_blob(local_lm_response,
244 sizeof(local_lm_response));
245 }
246
247 if (nt_interactive_pwd) {
248 local_nt_blob = data_blob(local_nt_response,
249 sizeof(local_nt_response));
250 }
251
252 nt_status = make_user_info_map(
253 mem_ctx,
254 user_info,
255 smb_name, client_domain, workstation_name,
256 remote_address,
257 lm_interactive_pwd ? &local_lm_blob : NULL,
258 nt_interactive_pwd ? &local_nt_blob : NULL,
259 lm_interactive_pwd ? &lm_pwd : NULL,
260 nt_interactive_pwd ? &nt_pwd : NULL,
261 NULL, AUTH_PASSWORD_HASH);
262
263 if (NT_STATUS_IS_OK(nt_status)) {
264 (*user_info)->logon_parameters = logon_parameters;
265 }
266
267 ret = NT_STATUS_IS_OK(nt_status) ? true : false;
268 data_blob_free(&local_lm_blob);
269 data_blob_free(&local_nt_blob);
270 return ret;
271 }
272}
273
274
275/****************************************************************************
276 Create an auth_usersupplied_data structure
277****************************************************************************/
278
279bool make_user_info_for_reply(TALLOC_CTX *mem_ctx,
280 struct auth_usersupplied_info **user_info,
281 const char *smb_name,
282 const char *client_domain,
283 const struct tsocket_address *remote_address,
284 const uint8_t chal[8],
285 DATA_BLOB plaintext_password)
286{
287
288 DATA_BLOB local_lm_blob;
289 DATA_BLOB local_nt_blob;
290 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
291 char *plaintext_password_string;
292 /*
293 * Not encrypted - do so.
294 */
295
296 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
297 "format.\n"));
298 if (plaintext_password.data && plaintext_password.length) {
299 unsigned char local_lm_response[24];
300
301#ifdef DEBUG_PASSWORD
302 DEBUG(10,("Unencrypted password (len %d):\n",
303 (int)plaintext_password.length));
304 dump_data(100, plaintext_password.data,
305 plaintext_password.length);
306#endif
307
308 SMBencrypt( (const char *)plaintext_password.data,
309 (const uchar*)chal, local_lm_response);
310 local_lm_blob = data_blob(local_lm_response, 24);
311
312 /* We can't do an NT hash here, as the password needs to be
313 case insensitive */
314 local_nt_blob = data_blob_null;
315 } else {
316 local_lm_blob = data_blob_null;
317 local_nt_blob = data_blob_null;
318 }
319
320 plaintext_password_string = talloc_strndup(talloc_tos(),
321 (const char *)plaintext_password.data,
322 plaintext_password.length);
323 if (!plaintext_password_string) {
324 return false;
325 }
326
327 ret = make_user_info(mem_ctx,
328 user_info, smb_name, smb_name, client_domain, client_domain,
329 get_remote_machine_name(),
330 remote_address,
331 local_lm_blob.data ? &local_lm_blob : NULL,
332 local_nt_blob.data ? &local_nt_blob : NULL,
333 NULL, NULL,
334 plaintext_password_string,
335 AUTH_PASSWORD_PLAIN);
336
337 if (plaintext_password_string) {
338 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
339 talloc_free(plaintext_password_string);
340 }
341
342 data_blob_free(&local_lm_blob);
343 return NT_STATUS_IS_OK(ret) ? true : false;
344}
345
346/****************************************************************************
347 Create an auth_usersupplied_data structure
348****************************************************************************/
349
350NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
351 struct auth_usersupplied_info **user_info,
352 const char *smb_name,
353 const char *client_domain,
354 const struct tsocket_address *remote_address,
355 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
356{
357 bool allow_raw = lp_raw_ntlmv2_auth();
358
359 if (!allow_raw && nt_resp.length >= 48) {
360 /*
361 * NTLMv2_RESPONSE has at least 48 bytes
362 * and should only be supported via NTLMSSP.
363 */
364 DEBUG(2,("Rejecting raw NTLMv2 authentication with "
365 "user [%s\\%s] from[%s]\n",
366 client_domain, smb_name,
367 tsocket_address_string(remote_address, mem_ctx)));
368 return NT_STATUS_INVALID_PARAMETER;
369 }
370
371 return make_user_info(mem_ctx,
372 user_info, smb_name, smb_name,
373 client_domain, client_domain,
374 get_remote_machine_name(),
375 remote_address,
376 lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
377 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
378 NULL, NULL, NULL,
379 AUTH_PASSWORD_RESPONSE);
380}
381
382/****************************************************************************
383 Create a guest user_info blob, for anonymous authentication.
384****************************************************************************/
385
386bool make_user_info_guest(TALLOC_CTX *mem_ctx,
387 const struct tsocket_address *remote_address,
388 struct auth_usersupplied_info **user_info)
389{
390 NTSTATUS nt_status;
391
392 nt_status = make_user_info(mem_ctx,
393 user_info,
394 "","",
395 "","",
396 "",
397 remote_address,
398 NULL, NULL,
399 NULL, NULL,
400 NULL,
401 AUTH_PASSWORD_RESPONSE);
402
403 return NT_STATUS_IS_OK(nt_status) ? true : false;
404}
405
406static NTSTATUS log_nt_token(struct security_token *token)
407{
408 TALLOC_CTX *frame = talloc_stackframe();
409 char *command;
410 char *group_sidstr;
411 size_t i;
412
413 if ((lp_log_nt_token_command(frame) == NULL) ||
414 (strlen(lp_log_nt_token_command(frame)) == 0)) {
415 TALLOC_FREE(frame);
416 return NT_STATUS_OK;
417 }
418
419 group_sidstr = talloc_strdup(frame, "");
420 for (i=1; i<token->num_sids; i++) {
421 group_sidstr = talloc_asprintf(
422 frame, "%s %s", group_sidstr,
423 sid_string_talloc(frame, &token->sids[i]));
424 }
425
426 command = talloc_string_sub(
427 frame, lp_log_nt_token_command(frame),
428 "%s", sid_string_talloc(frame, &token->sids[0]));
429 command = talloc_string_sub(frame, command, "%t", group_sidstr);
430
431 if (command == NULL) {
432 TALLOC_FREE(frame);
433 return NT_STATUS_NO_MEMORY;
434 }
435
436 DEBUG(8, ("running command: [%s]\n", command));
437 if (smbrun(command, NULL) != 0) {
438 DEBUG(0, ("Could not log NT token\n"));
439 TALLOC_FREE(frame);
440 return NT_STATUS_ACCESS_DENIED;
441 }
442
443 TALLOC_FREE(frame);
444 return NT_STATUS_OK;
445}
446
447/*
448 * Create the token to use from server_info->info3 and
449 * server_info->sids (the info3/sam groups). Find the unix gids.
450 */
451
452NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
453 const struct auth_serversupplied_info *server_info,
454 DATA_BLOB *session_key,
455 const char *smb_username, /* for ->sanitized_username, for %U subs */
456 struct auth_session_info **session_info_out)
457{
458 struct security_token *t;
459 NTSTATUS status;
460 size_t i;
461 struct dom_sid tmp_sid;
462 struct auth_session_info *session_info;
463 struct unixid *ids;
464 fstring tmp;
465
466 /* Ensure we can't possible take a code path leading to a
467 * null defref. */
468 if (!server_info) {
469 return NT_STATUS_LOGON_FAILURE;
470 }
471
472 session_info = talloc_zero(mem_ctx, struct auth_session_info);
473 if (!session_info) {
474 return NT_STATUS_NO_MEMORY;
475 }
476
477 session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
478 if (!session_info->unix_token) {
479 TALLOC_FREE(session_info);
480 return NT_STATUS_NO_MEMORY;
481 }
482
483 session_info->unix_token->uid = server_info->utok.uid;
484 session_info->unix_token->gid = server_info->utok.gid;
485
486 session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
487 if (!session_info->unix_info) {
488 TALLOC_FREE(session_info);
489 return NT_STATUS_NO_MEMORY;
490 }
491
492 session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
493 if (!session_info->unix_info->unix_name) {
494 TALLOC_FREE(session_info);
495 return NT_STATUS_NO_MEMORY;
496 }
497
498 /* This is a potentially untrusted username for use in %U */
499 alpha_strcpy(tmp, smb_username, ". _-$", sizeof(tmp));
500 session_info->unix_info->sanitized_username =
501 talloc_strdup(session_info->unix_info, tmp);
502
503 if (session_key) {
504 data_blob_free(&session_info->session_key);
505 session_info->session_key = data_blob_talloc(session_info,
506 session_key->data,
507 session_key->length);
508 if (!session_info->session_key.data && session_key->length) {
509 return NT_STATUS_NO_MEMORY;
510 }
511 } else {
512 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
513 server_info->session_key.length);
514 }
515
516 /* We need to populate session_info->info with the information found in server_info->info3 */
517 status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
518 server_info->guest == false,
519 &session_info->info);
520 if (!NT_STATUS_IS_OK(status)) {
521 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
522 TALLOC_FREE(session_info);
523 return status;
524 }
525
526 if (server_info->security_token) {
527 /* Just copy the token, it has already been finalised
528 * (nasty hack to support a cached guest/system session_info
529 */
530
531 session_info->security_token = dup_nt_token(session_info, server_info->security_token);
532 if (!session_info->security_token) {
533 TALLOC_FREE(session_info);
534 return NT_STATUS_NO_MEMORY;
535 }
536
537 session_info->unix_token->ngroups = server_info->utok.ngroups;
538 if (server_info->utok.ngroups != 0) {
539 session_info->unix_token->groups = (gid_t *)talloc_memdup(
540 session_info->unix_token, server_info->utok.groups,
541 sizeof(gid_t)*session_info->unix_token->ngroups);
542 } else {
543 session_info->unix_token->groups = NULL;
544 }
545
546 *session_info_out = session_info;
547 return NT_STATUS_OK;
548 }
549
550 /*
551 * If winbind is not around, we can not make much use of the SIDs the
552 * domain controller provided us with. Likewise if the user name was
553 * mapped to some local unix user.
554 */
555
556 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
557 (server_info->nss_token)) {
558 char *found_username = NULL;
559 status = create_token_from_username(session_info,
560 server_info->unix_name,
561 server_info->guest,
562 &session_info->unix_token->uid,
563 &session_info->unix_token->gid,
564 &found_username,
565 &session_info->security_token);
566 if (NT_STATUS_IS_OK(status)) {
567 session_info->unix_info->unix_name = found_username;
568 }
569 } else {
570 status = create_local_nt_token_from_info3(session_info,
571 server_info->guest,
572 server_info->info3,
573 &server_info->extra,
574 &session_info->security_token);
575 }
576
577 if (!NT_STATUS_IS_OK(status)) {
578 return status;
579 }
580
581 /* Convert the SIDs to gids. */
582
583 session_info->unix_token->ngroups = 0;
584 session_info->unix_token->groups = NULL;
585
586 t = session_info->security_token;
587
588 ids = talloc_array(talloc_tos(), struct unixid,
589 t->num_sids);
590 if (ids == NULL) {
591 return NT_STATUS_NO_MEMORY;
592 }
593
594 if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
595 TALLOC_FREE(ids);
596 return NT_STATUS_NO_MEMORY;
597 }
598
599 for (i=0; i<t->num_sids; i++) {
600
601 if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
602 continue;
603 }
604
605 if (ids[i].type != ID_TYPE_GID &&
606 ids[i].type != ID_TYPE_BOTH) {
607 DEBUG(10, ("Could not convert SID %s to gid, "
608 "ignoring it\n",
609 sid_string_dbg(&t->sids[i])));
610 continue;
611 }
612 if (!add_gid_to_array_unique(session_info, ids[i].id,
613 &session_info->unix_token->groups,
614 &session_info->unix_token->ngroups)) {
615 return NT_STATUS_NO_MEMORY;
616 }
617 }
618
619 /*
620 * Add the "Unix Group" SID for each gid to catch mapped groups
621 * and their Unix equivalent. This is to solve the backwards
622 * compatibility problem of 'valid users = +ntadmin' where
623 * ntadmin has been paired with "Domain Admins" in the group
624 * mapping table. Otherwise smb.conf would need to be changed
625 * to 'valid user = "Domain Admins"'. --jerry
626 *
627 * For consistency we also add the "Unix User" SID,
628 * so that the complete unix token is represented within
629 * the nt token.
630 */
631
632 uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
633
634 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
635 &session_info->security_token->sids,
636 &session_info->security_token->num_sids);
637
638 for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
639 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
640 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
641 &session_info->security_token->sids,
642 &session_info->security_token->num_sids);
643 }
644
645 security_token_debug(DBGC_AUTH, 10, session_info->security_token);
646 debug_unix_user_token(DBGC_AUTH, 10,
647 session_info->unix_token->uid,
648 session_info->unix_token->gid,
649 session_info->unix_token->ngroups,
650 session_info->unix_token->groups);
651
652 status = log_nt_token(session_info->security_token);
653 if (!NT_STATUS_IS_OK(status)) {
654 return status;
655 }
656
657 *session_info_out = session_info;
658 return NT_STATUS_OK;
659}
660
661/***************************************************************************
662 Make (and fill) a server_info struct from a 'struct passwd' by conversion
663 to a struct samu
664***************************************************************************/
665
666NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
667 const char *unix_username,
668 const struct passwd *pwd,
669 struct auth_serversupplied_info **server_info)
670{
671 NTSTATUS status;
672 TALLOC_CTX *tmp_ctx = NULL;
673 struct auth_serversupplied_info *result;
674
675 tmp_ctx = talloc_stackframe();
676 if (tmp_ctx == NULL) {
677 return NT_STATUS_NO_MEMORY;
678 }
679
680 result = make_server_info(tmp_ctx);
681 if (result == NULL) {
682 status = NT_STATUS_NO_MEMORY;
683 goto done;
684 }
685
686 status = passwd_to_SamInfo3(result,
687 unix_username,
688 pwd,
689 &result->info3,
690 &result->extra);
691 if (!NT_STATUS_IS_OK(status)) {
692 goto done;
693 }
694
695 result->unix_name = talloc_strdup(result, unix_username);
696 if (result->unix_name == NULL) {
697 status = NT_STATUS_NO_MEMORY;
698 goto done;
699 }
700
701 result->utok.uid = pwd->pw_uid;
702 result->utok.gid = pwd->pw_gid;
703
704 *server_info = talloc_steal(mem_ctx, result);
705 status = NT_STATUS_OK;
706done:
707 talloc_free(tmp_ctx);
708
709 return status;
710}
711
712static NTSTATUS get_system_info3(TALLOC_CTX *mem_ctx,
713 struct netr_SamInfo3 *info3)
714{
715 NTSTATUS status;
716 struct dom_sid *system_sid;
717
718 /* Set account name */
719 init_lsa_String(&info3->base.account_name, "SYSTEM");
720
721 /* Set domain name */
722 init_lsa_StringLarge(&info3->base.logon_domain, "NT AUTHORITY");
723
724
725 /* The SID set here will be overwirtten anyway, but try and make it SID_NT_SYSTEM anyway */
726 /* Domain sid is NT_AUTHORITY */
727
728 system_sid = dom_sid_parse_talloc(mem_ctx, SID_NT_SYSTEM);
729 if (system_sid == NULL) {
730 return NT_STATUS_NO_MEMORY;
731 }
732
733 status = dom_sid_split_rid(mem_ctx, system_sid, &info3->base.domain_sid,
734 &info3->base.rid);
735 TALLOC_FREE(system_sid);
736 if (!NT_STATUS_IS_OK(status)) {
737 return status;
738 }
739
740 /* Primary gid is the same */
741 info3->base.primary_gid = info3->base.rid;
742
743 return NT_STATUS_OK;
744}
745
746static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
747 struct netr_SamInfo3 *info3)
748{
749 const char *guest_account = lp_guest_account();
750 struct dom_sid domain_sid;
751 struct passwd *pwd;
752 const char *tmp;
753
754 pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
755 if (pwd == NULL) {
756 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
757 "account [%s]!\n", guest_account));
758 return NT_STATUS_NO_SUCH_USER;
759 }
760
761 /* Set account name */
762 tmp = talloc_strdup(mem_ctx, pwd->pw_name);
763 if (tmp == NULL) {
764 return NT_STATUS_NO_MEMORY;
765 }
766 init_lsa_String(&info3->base.account_name, tmp);
767
768 /* Set domain name */
769 tmp = talloc_strdup(mem_ctx, get_global_sam_name());
770 if (tmp == NULL) {
771 return NT_STATUS_NO_MEMORY;
772 }
773 init_lsa_StringLarge(&info3->base.logon_domain, tmp);
774
775 /* Domain sid */
776 sid_copy(&domain_sid, get_global_sam_sid());
777
778 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
779 if (info3->base.domain_sid == NULL) {
780 return NT_STATUS_NO_MEMORY;
781 }
782
783 /* Guest rid */
784 info3->base.rid = DOMAIN_RID_GUEST;
785
786 /* Primary gid */
787 info3->base.primary_gid = DOMAIN_RID_GUESTS;
788
789 /* Set as guest */
790 info3->base.user_flags = NETLOGON_GUEST;
791
792 TALLOC_FREE(pwd);
793 return NT_STATUS_OK;
794}
795
796/***************************************************************************
797 Make (and fill) a user_info struct for a guest login.
798 This *must* succeed for smbd to start. If there is no mapping entry for
799 the guest gid, then create one.
800
801 The resulting structure is a 'session_info' because
802 create_local_token() has already been called on it. This is quite
803 nasty, as the auth subsystem isn't expect this, but the behavior is
804 left as-is for now.
805***************************************************************************/
806
807static NTSTATUS make_new_session_info_guest(struct auth_session_info **session_info, struct auth_serversupplied_info **server_info)
808{
809 static const char zeros[16] = {0};
810 const char *guest_account = lp_guest_account();
811 const char *domain = lp_netbios_name();
812 struct netr_SamInfo3 info3;
813 TALLOC_CTX *tmp_ctx;
814 NTSTATUS status;
815
816 tmp_ctx = talloc_stackframe();
817 if (tmp_ctx == NULL) {
818 return NT_STATUS_NO_MEMORY;
819 }
820
821 ZERO_STRUCT(info3);
822
823 status = get_guest_info3(tmp_ctx, &info3);
824 if (!NT_STATUS_IS_OK(status)) {
825 DEBUG(0, ("get_guest_info3 failed with %s\n",
826 nt_errstr(status)));
827 goto done;
828 }
829
830 status = make_server_info_info3(tmp_ctx,
831 guest_account,
832 domain,
833 server_info,
834 &info3);
835 if (!NT_STATUS_IS_OK(status)) {
836 DEBUG(0, ("make_server_info_info3 failed with %s\n",
837 nt_errstr(status)));
838 goto done;
839 }
840
841 (*server_info)->guest = true;
842
843 /* This should not be done here (we should produce a server
844 * info, and later construct a session info from it), but for
845 * now this does not change the previous behavior */
846 status = create_local_token(tmp_ctx, *server_info, NULL,
847 (*server_info)->info3->base.account_name.string,
848 session_info);
849 if (!NT_STATUS_IS_OK(status)) {
850 DEBUG(0, ("create_local_token failed: %s\n",
851 nt_errstr(status)));
852 goto done;
853 }
854 talloc_steal(NULL, *session_info);
855 talloc_steal(NULL, *server_info);
856
857 /* annoying, but the Guest really does have a session key, and it is
858 all zeros! */
859 (*session_info)->session_key = data_blob(zeros, sizeof(zeros));
860
861 status = NT_STATUS_OK;
862done:
863 TALLOC_FREE(tmp_ctx);
864 return status;
865}
866
867/***************************************************************************
868 Make (and fill) a auth_session_info struct for a system user login.
869 This *must* succeed for smbd to start.
870***************************************************************************/
871
872static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
873 struct auth_session_info **session_info)
874{
875 NTSTATUS status;
876 struct auth_serversupplied_info *server_info;
877 TALLOC_CTX *tmp_ctx;
878
879 tmp_ctx = talloc_stackframe();
880 if (tmp_ctx == NULL) {
881 return NT_STATUS_NO_MEMORY;
882 }
883
884 server_info = make_server_info(tmp_ctx);
885 if (!server_info) {
886 status = NT_STATUS_NO_MEMORY;
887 DEBUG(0, ("failed making server_info\n"));
888 goto done;
889 }
890
891 server_info->info3 = talloc_zero(server_info, struct netr_SamInfo3);
892 if (!server_info->info3) {
893 status = NT_STATUS_NO_MEMORY;
894 DEBUG(0, ("talloc failed setting info3\n"));
895 goto done;
896 }
897
898 status = get_system_info3(server_info, server_info->info3);
899 if (!NT_STATUS_IS_OK(status)) {
900 DEBUG(0, ("Failed creating system info3 with %s\n",
901 nt_errstr(status)));
902 goto done;
903 }
904
905 server_info->utok.uid = sec_initial_uid();
906 server_info->utok.gid = sec_initial_gid();
907 server_info->unix_name = talloc_asprintf(server_info,
908 "NT AUTHORITY%cSYSTEM",
909 *lp_winbind_separator());
910
911 if (!server_info->unix_name) {
912 status = NT_STATUS_NO_MEMORY;
913 DEBUG(0, ("talloc_asprintf failed setting unix_name\n"));
914 goto done;
915 }
916
917 server_info->security_token = talloc_zero(server_info, struct security_token);
918 if (!server_info->security_token) {
919 status = NT_STATUS_NO_MEMORY;
920 DEBUG(0, ("talloc failed setting security token\n"));
921 goto done;
922 }
923
924 status = add_sid_to_array_unique(server_info->security_token->sids,
925 &global_sid_System,
926 &server_info->security_token->sids,
927 &server_info->security_token->num_sids);
928 if (!NT_STATUS_IS_OK(status)) {
929 goto done;
930 }
931
932 /* SYSTEM has all privilages */
933 server_info->security_token->privilege_mask = ~0;
934
935 /* Now turn the server_info into a session_info with the full token etc */
936 status = create_local_token(mem_ctx, server_info, NULL, "SYSTEM", session_info);
937 talloc_free(server_info);
938
939 if (!NT_STATUS_IS_OK(status)) {
940 DEBUG(0, ("create_local_token failed: %s\n",
941 nt_errstr(status)));
942 goto done;
943 }
944
945 talloc_steal(mem_ctx, *session_info);
946
947done:
948 TALLOC_FREE(tmp_ctx);
949 return status;
950}
951
952/****************************************************************************
953 Fake a auth_session_info just from a username (as a
954 session_info structure, with create_local_token() already called on
955 it.
956****************************************************************************/
957
958NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
959 const char *username,
960 bool is_guest,
961 struct auth_session_info **session_info)
962{
963 struct passwd *pwd;
964 NTSTATUS status;
965 struct auth_serversupplied_info *result;
966 TALLOC_CTX *tmp_ctx;
967
968 tmp_ctx = talloc_stackframe();
969 if (tmp_ctx == NULL) {
970 return NT_STATUS_NO_MEMORY;
971 }
972
973 pwd = Get_Pwnam_alloc(tmp_ctx, username);
974 if (pwd == NULL) {
975 status = NT_STATUS_NO_SUCH_USER;
976 goto done;
977 }
978
979 status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
980 if (!NT_STATUS_IS_OK(status)) {
981 goto done;
982 }
983
984 result->nss_token = true;
985 result->guest = is_guest;
986
987 /* Now turn the server_info into a session_info with the full token etc */
988 status = create_local_token(mem_ctx,
989 result,
990 NULL,
991 pwd->pw_name,
992 session_info);
993
994done:
995 talloc_free(tmp_ctx);
996
997 return status;
998}
999
1000/* This function MUST only used to create the cached server_info for
1001 * guest.
1002 *
1003 * This is a lossy conversion. Variables known to be lost so far
1004 * include:
1005 *
1006 * - nss_token (not needed because the only read doesn't happen
1007 * for the GUEST user, as this routine populates ->security_token
1008 *
1009 * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1010 *
1011 * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1012 */
1013static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1014 const struct auth_session_info *src,
1015 struct auth_serversupplied_info *server_info)
1016{
1017 struct auth_serversupplied_info *dst;
1018
1019 dst = make_server_info(mem_ctx);
1020 if (dst == NULL) {
1021 return NULL;
1022 }
1023
1024 /* This element must be provided to convert back to an auth_serversupplied_info */
1025 SMB_ASSERT(src->unix_info);
1026
1027 dst->guest = true;
1028 dst->system = false;
1029
1030 /* This element must be provided to convert back to an
1031 * auth_serversupplied_info. This needs to be from the
1032 * auth_session_info because the group values in particular
1033 * may change during create_local_token() processing */
1034 SMB_ASSERT(src->unix_token);
1035 dst->utok.uid = src->unix_token->uid;
1036 dst->utok.gid = src->unix_token->gid;
1037 dst->utok.ngroups = src->unix_token->ngroups;
1038 if (src->unix_token->ngroups != 0) {
1039 dst->utok.groups = (gid_t *)talloc_memdup(
1040 dst, src->unix_token->groups,
1041 sizeof(gid_t)*dst->utok.ngroups);
1042 } else {
1043 dst->utok.groups = NULL;
1044 }
1045
1046 /* We must have a security_token as otherwise the lossy
1047 * conversion without nss_token would cause create_local_token
1048 * to take the wrong path */
1049 SMB_ASSERT(src->security_token);
1050
1051 dst->security_token = dup_nt_token(dst, src->security_token);
1052 if (!dst->security_token) {
1053 TALLOC_FREE(dst);
1054 return NULL;
1055 }
1056
1057 dst->session_key = data_blob_talloc( dst, src->session_key.data,
1058 src->session_key.length);
1059
1060 /* This is OK because this functions is only used for the
1061 * GUEST account, which has all-zero keys for both values */
1062 dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1063 src->session_key.length);
1064
1065 dst->info3 = copy_netr_SamInfo3(dst, server_info->info3);
1066 if (!dst->info3) {
1067 TALLOC_FREE(dst);
1068 return NULL;
1069 }
1070
1071 dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1072 if (!dst->unix_name) {
1073 TALLOC_FREE(dst);
1074 return NULL;
1075 }
1076
1077 return dst;
1078}
1079
1080struct auth_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
1081 const struct auth_session_info *src)
1082{
1083 struct auth_session_info *dst;
1084 DATA_BLOB blob;
1085 enum ndr_err_code ndr_err;
1086
1087 ndr_err = ndr_push_struct_blob(
1088 &blob, talloc_tos(), src,
1089 (ndr_push_flags_fn_t)ndr_push_auth_session_info);
1090 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1091 DEBUG(0, ("copy_session_info(): ndr_push_auth_session_info failed: "
1092 "%s\n", ndr_errstr(ndr_err)));
1093 return NULL;
1094 }
1095
1096 dst = talloc(mem_ctx, struct auth_session_info);
1097 if (dst == NULL) {
1098 DEBUG(0, ("talloc failed\n"));
1099 TALLOC_FREE(blob.data);
1100 return NULL;
1101 }
1102
1103 ndr_err = ndr_pull_struct_blob(
1104 &blob, dst, dst,
1105 (ndr_pull_flags_fn_t)ndr_pull_auth_session_info);
1106 TALLOC_FREE(blob.data);
1107
1108 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1109 DEBUG(0, ("copy_session_info(): ndr_pull_auth_session_info failed: "
1110 "%s\n", ndr_errstr(ndr_err)));
1111 TALLOC_FREE(dst);
1112 return NULL;
1113 }
1114
1115 return dst;
1116}
1117
1118/*
1119 * Set a new session key. Used in the rpc server where we have to override the
1120 * SMB level session key with SystemLibraryDTC
1121 */
1122
1123bool session_info_set_session_key(struct auth_session_info *info,
1124 DATA_BLOB session_key)
1125{
1126 TALLOC_FREE(info->session_key.data);
1127
1128 info->session_key = data_blob_talloc(
1129 info, session_key.data, session_key.length);
1130
1131 return (info->session_key.data != NULL);
1132}
1133
1134static struct auth_session_info *guest_info = NULL;
1135
1136static struct auth_serversupplied_info *guest_server_info = NULL;
1137
1138bool init_guest_info(void)
1139{
1140 if (guest_info != NULL)
1141 return true;
1142
1143 return NT_STATUS_IS_OK(make_new_session_info_guest(&guest_info, &guest_server_info));
1144}
1145
1146NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1147 struct auth_serversupplied_info **server_info)
1148{
1149 /* This is trickier than it would appear to need to be because
1150 * we are trying to avoid certain costly operations when the
1151 * structure is converted to a 'auth_session_info' again in
1152 * create_local_token() */
1153 *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1154 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1155}
1156
1157NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1158 struct auth_session_info **session_info)
1159{
1160 *session_info = copy_session_info(mem_ctx, guest_info);
1161 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1162}
1163
1164static struct auth_session_info *system_info = NULL;
1165
1166NTSTATUS init_system_session_info(void)
1167{
1168 if (system_info != NULL)
1169 return NT_STATUS_OK;
1170
1171 return make_new_session_info_system(NULL, &system_info);
1172}
1173
1174NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1175 struct auth_session_info **session_info)
1176{
1177 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1178 *session_info = copy_session_info(mem_ctx, system_info);
1179 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1180}
1181
1182const struct auth_session_info *get_session_info_system(void)
1183{
1184 return system_info;
1185}
1186
1187/***************************************************************************
1188 Purely internal function for make_server_info_info3
1189***************************************************************************/
1190
1191static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1192 const char *username, char **found_username,
1193 struct passwd **pwd,
1194 bool *username_was_mapped)
1195{
1196 char *orig_dom_user = NULL;
1197 char *dom_user = NULL;
1198 char *lower_username = NULL;
1199 char *real_username = NULL;
1200 struct passwd *passwd;
1201
1202 lower_username = talloc_strdup(mem_ctx, username);
1203 if (!lower_username) {
1204 return NT_STATUS_NO_MEMORY;
1205 }
1206 if (!strlower_m( lower_username )) {
1207 return NT_STATUS_INVALID_PARAMETER;
1208 }
1209
1210 orig_dom_user = talloc_asprintf(mem_ctx,
1211 "%s%c%s",
1212 domain,
1213 *lp_winbind_separator(),
1214 lower_username);
1215 if (!orig_dom_user) {
1216 return NT_STATUS_NO_MEMORY;
1217 }
1218
1219 /* Get the passwd struct. Try to create the account if necessary. */
1220
1221 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1222 if (!dom_user) {
1223 return NT_STATUS_NO_MEMORY;
1224 }
1225
1226 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
1227 if (!passwd) {
1228 DEBUG(3, ("Failed to find authenticated user %s via "
1229 "getpwnam(), denying access.\n", dom_user));
1230 return NT_STATUS_NO_SUCH_USER;
1231 }
1232
1233 if (!real_username) {
1234 return NT_STATUS_NO_MEMORY;
1235 }
1236
1237 *pwd = passwd;
1238
1239 /* This is pointless -- there is no support for differing
1240 unix and windows names. Make sure to always store the
1241 one we actually looked up and succeeded. Have I mentioned
1242 why I hate the 'winbind use default domain' parameter?
1243 --jerry */
1244
1245 *found_username = talloc_strdup( mem_ctx, real_username );
1246
1247 return NT_STATUS_OK;
1248}
1249
1250/****************************************************************************
1251 Wrapper to allow the getpwnam() call to strip the domain name and
1252 try again in case a local UNIX user is already there. Also run through
1253 the username if we fallback to the username only.
1254 ****************************************************************************/
1255
1256struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1257 char **p_save_username, bool create )
1258{
1259 struct passwd *pw = NULL;
1260 char *p = NULL;
1261 char *username = NULL;
1262
1263 /* we only save a copy of the username it has been mangled
1264 by winbindd use default domain */
1265 *p_save_username = NULL;
1266
1267 /* don't call map_username() here since it has to be done higher
1268 up the stack so we don't call it multiple times */
1269
1270 username = talloc_strdup(mem_ctx, domuser);
1271 if (!username) {
1272 return NULL;
1273 }
1274
1275 p = strchr_m( username, *lp_winbind_separator() );
1276
1277 /* code for a DOMAIN\user string */
1278
1279 if ( p ) {
1280 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1281 if ( pw ) {
1282 /* make sure we get the case of the username correct */
1283 /* work around 'winbind use default domain = yes' */
1284
1285 if ( lp_winbind_use_default_domain() &&
1286 !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1287 char *domain;
1288
1289 /* split the domain and username into 2 strings */
1290 *p = '\0';
1291 domain = username;
1292
1293 *p_save_username = talloc_asprintf(mem_ctx,
1294 "%s%c%s",
1295 domain,
1296 *lp_winbind_separator(),
1297 pw->pw_name);
1298 if (!*p_save_username) {
1299 TALLOC_FREE(pw);
1300 return NULL;
1301 }
1302 } else {
1303 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1304 }
1305
1306 /* whew -- done! */
1307 return pw;
1308 }
1309
1310 /* setup for lookup of just the username */
1311 /* remember that p and username are overlapping memory */
1312
1313 p++;
1314 username = talloc_strdup(mem_ctx, p);
1315 if (!username) {
1316 return NULL;
1317 }
1318 }
1319
1320 /* just lookup a plain username */
1321
1322 pw = Get_Pwnam_alloc(mem_ctx, username);
1323
1324 /* Create local user if requested but only if winbindd
1325 is not running. We need to protect against cases
1326 where winbindd is failing and then prematurely
1327 creating users in /etc/passwd */
1328
1329 if ( !pw && create && !winbind_ping() ) {
1330 /* Don't add a machine account. */
1331 if (username[strlen(username)-1] == '$')
1332 return NULL;
1333
1334 _smb_create_user(NULL, username, NULL);
1335 pw = Get_Pwnam_alloc(mem_ctx, username);
1336 }
1337
1338 /* one last check for a valid passwd struct */
1339
1340 if (pw) {
1341 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1342 }
1343 return pw;
1344}
1345
1346/***************************************************************************
1347 Make a server_info struct from the info3 returned by a domain logon
1348***************************************************************************/
1349
1350NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1351 const char *sent_nt_username,
1352 const char *domain,
1353 struct auth_serversupplied_info **server_info,
1354 const struct netr_SamInfo3 *info3)
1355{
1356 static const char zeros[16] = {0, };
1357
1358 NTSTATUS nt_status = NT_STATUS_OK;
1359 char *found_username = NULL;
1360 const char *nt_domain;
1361 const char *nt_username;
1362 struct dom_sid user_sid;
1363 struct dom_sid group_sid;
1364 bool username_was_mapped;
1365 struct passwd *pwd;
1366 struct auth_serversupplied_info *result;
1367 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1368
1369 /*
1370 Here is where we should check the list of
1371 trusted domains, and verify that the SID
1372 matches.
1373 */
1374
1375 if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
1376 nt_status = NT_STATUS_INVALID_PARAMETER;
1377 goto out;
1378 }
1379
1380 if (!sid_compose(&group_sid, info3->base.domain_sid,
1381 info3->base.primary_gid)) {
1382 nt_status = NT_STATUS_INVALID_PARAMETER;
1383 goto out;
1384 }
1385
1386 nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
1387 if (!nt_username) {
1388 /* If the server didn't give us one, just use the one we sent
1389 * them */
1390 nt_username = sent_nt_username;
1391 }
1392
1393 nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
1394 if (!nt_domain) {
1395 /* If the server didn't give us one, just use the one we sent
1396 * them */
1397 nt_domain = domain;
1398 }
1399
1400 /* If getpwnam() fails try the add user script (2.2.x behavior).
1401
1402 We use the _unmapped_ username here in an attempt to provide
1403 consistent username mapping behavior between kerberos and NTLM[SSP]
1404 authentication in domain mode security. I.E. Username mapping
1405 should be applied to the fully qualified username
1406 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1407 called map_username() unnecessarily in make_user_info_map() but
1408 that is how the current code is designed. Making the change here
1409 is the least disruptive place. -- jerry */
1410
1411 /* this call will try to create the user if necessary */
1412
1413 nt_status = check_account(tmp_ctx,
1414 nt_domain,
1415 nt_username,
1416 &found_username,
1417 &pwd,
1418 &username_was_mapped);
1419
1420 if (!NT_STATUS_IS_OK(nt_status)) {
1421 /* Handle 'map to guest = Bad Uid */
1422 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
1423 (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
1424 lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
1425 DBG_NOTICE("Try to map %s to guest account",
1426 nt_username);
1427 nt_status = make_server_info_guest(tmp_ctx, &result);
1428 if (NT_STATUS_IS_OK(nt_status)) {
1429 *server_info = talloc_move(mem_ctx, &result);
1430 }
1431 }
1432 goto out;
1433 }
1434
1435 result = make_server_info(tmp_ctx);
1436 if (result == NULL) {
1437 DEBUG(4, ("make_server_info failed!\n"));
1438 nt_status = NT_STATUS_NO_MEMORY;
1439 goto out;
1440 }
1441
1442 result->unix_name = talloc_strdup(result, found_username);
1443
1444 /* copy in the info3 */
1445 result->info3 = copy_netr_SamInfo3(result, info3);
1446 if (result->info3 == NULL) {
1447 nt_status = NT_STATUS_NO_MEMORY;
1448 goto out;
1449 }
1450
1451 /* Fill in the unix info we found on the way */
1452
1453 result->utok.uid = pwd->pw_uid;
1454 result->utok.gid = pwd->pw_gid;
1455
1456 /* ensure we are never given NULL session keys */
1457
1458 if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1459 result->session_key = data_blob_null;
1460 } else {
1461 result->session_key = data_blob_talloc(
1462 result, info3->base.key.key,
1463 sizeof(info3->base.key.key));
1464 }
1465
1466 if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1467 result->lm_session_key = data_blob_null;
1468 } else {
1469 result->lm_session_key = data_blob_talloc(
1470 result, info3->base.LMSessKey.key,
1471 sizeof(info3->base.LMSessKey.key));
1472 }
1473
1474 result->nss_token |= username_was_mapped;
1475
1476 result->guest = (info3->base.user_flags & NETLOGON_GUEST);
1477
1478 *server_info = talloc_move(mem_ctx, &result);
1479
1480 nt_status = NT_STATUS_OK;
1481out:
1482 talloc_free(tmp_ctx);
1483
1484 return nt_status;
1485}
1486
1487/*****************************************************************************
1488 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1489******************************************************************************/
1490
1491NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1492 const char *sent_nt_username,
1493 const char *domain,
1494 const struct wbcAuthUserInfo *info,
1495 struct auth_serversupplied_info **server_info)
1496{
1497 struct netr_SamInfo3 *info3;
1498
1499 info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
1500 if (!info3) {
1501 return NT_STATUS_NO_MEMORY;
1502 }
1503
1504 return make_server_info_info3(mem_ctx,
1505 sent_nt_username, domain,
1506 server_info, info3);
1507}
1508
1509/**
1510 * Verify whether or not given domain is trusted.
1511 *
1512 * @param domain_name name of the domain to be verified
1513 * @return true if domain is one of the trusted ones or
1514 * false if otherwise
1515 **/
1516
1517bool is_trusted_domain(const char* dom_name)
1518{
1519 struct dom_sid trustdom_sid;
1520 bool ret;
1521
1522 /* no trusted domains for a standalone server */
1523
1524 if ( lp_server_role() == ROLE_STANDALONE )
1525 return false;
1526
1527 if (dom_name == NULL || dom_name[0] == '\0') {
1528 return false;
1529 }
1530
1531 if (strequal(dom_name, get_global_sam_name())) {
1532 return false;
1533 }
1534
1535 /* if we are a DC, then check for a direct trust relationships */
1536
1537 if ( IS_DC ) {
1538 become_root();
1539 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1540 "[%s]\n", dom_name ));
1541 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1542 unbecome_root();
1543 if (ret)
1544 return true;
1545 }
1546 else {
1547 wbcErr result;
1548
1549 /* If winbind is around, ask it */
1550
1551 result = wb_is_trusted_domain(dom_name);
1552
1553 if (result == WBC_ERR_SUCCESS) {
1554 return true;
1555 }
1556
1557 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1558 /* winbind could not find the domain */
1559 return false;
1560 }
1561
1562 DEBUG(10, ("wb_is_trusted_domain returned error: %s\n",
1563 wbcErrorString(result)));
1564
1565 /* The only other possible result is that winbind is not up
1566 and running. We need to update the trustdom_cache
1567 ourselves */
1568
1569 update_trustdom_cache();
1570 }
1571
1572 /* now the trustdom cache should be available a DC could still
1573 * have a transitive trust so fall back to the cache of trusted
1574 * domains (like a domain member would use */
1575
1576 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1577 return true;
1578 }
1579
1580 return false;
1581}
1582
1583
1584
1585/*
1586 on a logon error possibly map the error to success if "map to guest"
1587 is set approriately
1588*/
1589NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
1590 NTSTATUS status,
1591 const char *user,
1592 const char *domain,
1593 struct auth_serversupplied_info **server_info)
1594{
1595 user = user ? user : "";
1596 domain = domain ? domain : "";
1597
1598 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
1599 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
1600 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
1601 DEBUG(3,("No such user %s [%s] - using guest account\n",
1602 user, domain));
1603 return make_server_info_guest(mem_ctx, server_info);
1604 }
1605 } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1606 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
1607 DEBUG(3,("Registered username %s for guest access\n",
1608 user));
1609 return make_server_info_guest(mem_ctx, server_info);
1610 }
1611 }
1612
1613 return status;
1614}
1615
1616/*
1617 Extract session key from a session info and return it in a blob
1618 if intent is KEY_USE_16BYTES, truncate it to 16 bytes
1619
1620 See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
1621 Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
1622
1623 Note that returned session_key is referencing the original key, it is supposed to be
1624 short-lived. If original session_info->session_key is gone, the reference will be broken.
1625*/
1626NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
1627{
1628
1629 if (session_key == NULL || session_info == NULL) {
1630 return NT_STATUS_INVALID_PARAMETER;
1631 }
1632
1633 if (session_info->session_key.length == 0) {
1634 return NT_STATUS_NO_USER_SESSION_KEY;
1635 }
1636
1637 *session_key = session_info->session_key;
1638 if (intent == KEY_USE_16BYTES) {
1639 session_key->length = MIN(session_info->session_key.length, 16);
1640 }
1641 return NT_STATUS_OK;
1642}
Note: See TracBrowser for help on using the repository browser.