Line data Source code
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 "lib/util_unixsids.h"
27 : #include "../libcli/auth/libcli_auth.h"
28 : #include "rpc_client/init_lsa.h"
29 : #include "../libcli/security/security.h"
30 : #include "../lib/util/util_pw.h"
31 : #include "lib/winbind_util.h"
32 : #include "passdb.h"
33 : #include "../librpc/gen_ndr/ndr_auth.h"
34 : #include "../auth/auth_sam_reply.h"
35 : #include "../librpc/gen_ndr/idmap.h"
36 : #include "lib/param/loadparm.h"
37 : #include "../lib/tsocket/tsocket.h"
38 : #include "rpc_client/util_netlogon.h"
39 : #include "source4/auth/auth.h"
40 : #include "auth/auth_util.h"
41 : #include "source3/lib/substitute.h"
42 :
43 : #undef DBGC_CLASS
44 : #define DBGC_CLASS DBGC_AUTH
45 :
46 : /****************************************************************************
47 : Create a UNIX user on demand.
48 : ****************************************************************************/
49 :
50 0 : static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
51 : {
52 0 : TALLOC_CTX *ctx = talloc_tos();
53 0 : const struct loadparm_substitution *lp_sub =
54 0 : loadparm_s3_global_substitution();
55 0 : char *add_script;
56 0 : int ret;
57 :
58 0 : add_script = lp_add_user_script(ctx, lp_sub);
59 0 : if (!add_script || !*add_script) {
60 0 : return -1;
61 : }
62 0 : add_script = talloc_all_string_sub(ctx,
63 : add_script,
64 : "%u",
65 : unix_username);
66 0 : if (!add_script) {
67 0 : return -1;
68 : }
69 0 : if (domain) {
70 0 : add_script = talloc_all_string_sub(ctx,
71 : add_script,
72 : "%D",
73 : domain);
74 0 : if (!add_script) {
75 0 : return -1;
76 : }
77 : }
78 0 : if (homedir) {
79 0 : add_script = talloc_all_string_sub(ctx,
80 : add_script,
81 : "%H",
82 : homedir);
83 0 : if (!add_script) {
84 0 : return -1;
85 : }
86 : }
87 0 : ret = smbrun(add_script, NULL, NULL);
88 0 : flush_pwnam_cache();
89 0 : DEBUG(ret ? 0 : 3,
90 : ("smb_create_user: Running the command `%s' gave %d\n",
91 : add_script,ret));
92 0 : return ret;
93 : }
94 :
95 : /****************************************************************************
96 : Create an auth_usersupplied_data structure after appropriate mapping.
97 : ****************************************************************************/
98 :
99 24112 : NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
100 : struct auth_usersupplied_info **user_info,
101 : const char *smb_name,
102 : const char *client_domain,
103 : const char *workstation_name,
104 : const struct tsocket_address *remote_address,
105 : const struct tsocket_address *local_address,
106 : const char *service_description,
107 : const DATA_BLOB *lm_pwd,
108 : const DATA_BLOB *nt_pwd,
109 : const struct samr_Password *lm_interactive_pwd,
110 : const struct samr_Password *nt_interactive_pwd,
111 : const char *plaintext,
112 : enum auth_password_state password_state)
113 : {
114 0 : const char *domain;
115 0 : NTSTATUS result;
116 0 : bool was_mapped;
117 24112 : char *internal_username = NULL;
118 :
119 24112 : was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
120 24112 : if (!internal_username) {
121 0 : return NT_STATUS_NO_MEMORY;
122 : }
123 :
124 24112 : DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
125 : client_domain, smb_name, workstation_name));
126 :
127 : /*
128 : * We let the auth stack canonicalize, username
129 : * and domain.
130 : */
131 24112 : domain = client_domain;
132 :
133 24112 : result = make_user_info(mem_ctx, user_info, smb_name, internal_username,
134 : client_domain, domain, workstation_name,
135 : remote_address, local_address,
136 : service_description, lm_pwd, nt_pwd,
137 : lm_interactive_pwd, nt_interactive_pwd,
138 : plaintext, password_state);
139 24112 : if (NT_STATUS_IS_OK(result)) {
140 : /* did we actually map the user to a different name? */
141 24112 : (*user_info)->was_mapped = was_mapped;
142 : }
143 24112 : return result;
144 : }
145 :
146 : /****************************************************************************
147 : Create an auth_usersupplied_data, making the DATA_BLOBs here.
148 : Decrypt and encrypt the passwords.
149 : ****************************************************************************/
150 :
151 288 : bool make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
152 : struct auth_usersupplied_info **user_info,
153 : const char *smb_name,
154 : const char *client_domain,
155 : const char *workstation_name,
156 : const struct tsocket_address *remote_address,
157 : const struct tsocket_address *local_address,
158 : uint32_t logon_parameters,
159 : const uchar *lm_network_pwd,
160 : int lm_pwd_len,
161 : const uchar *nt_network_pwd,
162 : int nt_pwd_len)
163 : {
164 0 : bool ret;
165 0 : NTSTATUS status;
166 288 : DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
167 288 : DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
168 :
169 288 : status = make_user_info_map(mem_ctx, user_info,
170 : smb_name, client_domain,
171 : workstation_name,
172 : remote_address,
173 : local_address,
174 : "SamLogon",
175 : lm_pwd_len ? &lm_blob : NULL,
176 : nt_pwd_len ? &nt_blob : NULL,
177 : NULL, NULL, NULL,
178 : AUTH_PASSWORD_RESPONSE);
179 :
180 288 : if (NT_STATUS_IS_OK(status)) {
181 288 : (*user_info)->logon_parameters = logon_parameters;
182 : }
183 288 : ret = NT_STATUS_IS_OK(status) ? true : false;
184 :
185 288 : data_blob_free(&lm_blob);
186 288 : data_blob_free(&nt_blob);
187 288 : return ret;
188 : }
189 :
190 : /****************************************************************************
191 : Create an auth_usersupplied_data, making the DATA_BLOBs here.
192 : Decrypt and encrypt the passwords.
193 : ****************************************************************************/
194 :
195 16 : bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
196 : struct auth_usersupplied_info **user_info,
197 : const char *smb_name,
198 : const char *client_domain,
199 : const char *workstation_name,
200 : const struct tsocket_address *remote_address,
201 : const struct tsocket_address *local_address,
202 : uint32_t logon_parameters,
203 : const uchar chal[8],
204 : const uchar lm_interactive_pwd[16],
205 : const uchar nt_interactive_pwd[16])
206 : {
207 0 : struct samr_Password lm_pwd;
208 0 : struct samr_Password nt_pwd;
209 0 : unsigned char local_lm_response[24];
210 0 : unsigned char local_nt_response[24];
211 0 : int rc;
212 :
213 16 : if (lm_interactive_pwd)
214 16 : memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
215 :
216 16 : if (nt_interactive_pwd)
217 16 : memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
218 :
219 16 : if (lm_interactive_pwd) {
220 16 : rc = SMBOWFencrypt(lm_pwd.hash, chal,
221 : local_lm_response);
222 16 : if (rc != 0) {
223 0 : return false;
224 : }
225 : }
226 :
227 16 : if (nt_interactive_pwd) {
228 16 : rc = SMBOWFencrypt(nt_pwd.hash, chal,
229 : local_nt_response);
230 16 : if (rc != 0) {
231 0 : return false;
232 : }
233 : }
234 :
235 : {
236 0 : bool ret;
237 0 : NTSTATUS nt_status;
238 16 : DATA_BLOB local_lm_blob = data_blob_null;
239 16 : DATA_BLOB local_nt_blob = data_blob_null;
240 :
241 16 : if (lm_interactive_pwd) {
242 16 : local_lm_blob = data_blob(local_lm_response,
243 : sizeof(local_lm_response));
244 : }
245 :
246 16 : if (nt_interactive_pwd) {
247 16 : local_nt_blob = data_blob(local_nt_response,
248 : sizeof(local_nt_response));
249 : }
250 :
251 16 : nt_status = make_user_info_map(
252 : mem_ctx,
253 : user_info,
254 : smb_name, client_domain, workstation_name,
255 : remote_address,
256 : local_address,
257 : "SamLogon",
258 : lm_interactive_pwd ? &local_lm_blob : NULL,
259 : nt_interactive_pwd ? &local_nt_blob : NULL,
260 : lm_interactive_pwd ? &lm_pwd : NULL,
261 : nt_interactive_pwd ? &nt_pwd : NULL,
262 : NULL, AUTH_PASSWORD_HASH);
263 :
264 16 : if (NT_STATUS_IS_OK(nt_status)) {
265 16 : (*user_info)->logon_parameters = logon_parameters;
266 16 : (*user_info)->flags |= USER_INFO_INTERACTIVE_LOGON;
267 : }
268 :
269 16 : ret = NT_STATUS_IS_OK(nt_status) ? true : false;
270 16 : data_blob_free(&local_lm_blob);
271 16 : data_blob_free(&local_nt_blob);
272 16 : return ret;
273 : }
274 : }
275 :
276 :
277 : /****************************************************************************
278 : Create an auth_usersupplied_data structure
279 : ****************************************************************************/
280 :
281 0 : bool make_user_info_for_reply(TALLOC_CTX *mem_ctx,
282 : struct auth_usersupplied_info **user_info,
283 : const char *smb_name,
284 : const char *client_domain,
285 : const struct tsocket_address *remote_address,
286 : const struct tsocket_address *local_address,
287 : const char *service_description,
288 : const uint8_t chal[8],
289 : DATA_BLOB plaintext_password)
290 : {
291 :
292 0 : DATA_BLOB local_lm_blob;
293 0 : DATA_BLOB local_nt_blob;
294 0 : NTSTATUS ret;
295 0 : char *plaintext_password_string;
296 : /*
297 : * Not encrypted - do so.
298 : */
299 :
300 0 : DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
301 : "format.\n"));
302 0 : if (plaintext_password.data && plaintext_password.length) {
303 0 : unsigned char local_lm_response[24];
304 :
305 : #ifdef DEBUG_PASSWORD
306 0 : DEBUG(10,("Unencrypted password (len %d):\n",
307 : (int)plaintext_password.length));
308 0 : dump_data(100, plaintext_password.data,
309 0 : plaintext_password.length);
310 : #endif
311 :
312 0 : SMBencrypt( (const char *)plaintext_password.data,
313 : (const uchar*)chal, local_lm_response);
314 0 : local_lm_blob = data_blob(local_lm_response, 24);
315 :
316 : /* We can't do an NT hash here, as the password needs to be
317 : case insensitive */
318 0 : local_nt_blob = data_blob_null;
319 : } else {
320 0 : local_lm_blob = data_blob_null;
321 0 : local_nt_blob = data_blob_null;
322 : }
323 :
324 0 : plaintext_password_string = talloc_strndup(talloc_tos(),
325 0 : (const char *)plaintext_password.data,
326 : plaintext_password.length);
327 0 : if (!plaintext_password_string) {
328 0 : return false;
329 : }
330 :
331 0 : ret = make_user_info(mem_ctx,
332 : user_info, smb_name, smb_name, client_domain, client_domain,
333 : get_remote_machine_name(),
334 : remote_address,
335 : local_address,
336 : service_description,
337 0 : local_lm_blob.data ? &local_lm_blob : NULL,
338 0 : local_nt_blob.data ? &local_nt_blob : NULL,
339 : NULL, NULL,
340 : plaintext_password_string,
341 : AUTH_PASSWORD_PLAIN);
342 :
343 0 : if (plaintext_password_string) {
344 0 : memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
345 0 : talloc_free(plaintext_password_string);
346 : }
347 :
348 0 : data_blob_free(&local_lm_blob);
349 0 : return NT_STATUS_IS_OK(ret) ? true : false;
350 : }
351 :
352 : /****************************************************************************
353 : Create an auth_usersupplied_data structure
354 : ****************************************************************************/
355 :
356 63 : NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
357 : struct auth_usersupplied_info **user_info,
358 : const char *smb_name,
359 : const char *client_domain,
360 : const struct tsocket_address *remote_address,
361 : const struct tsocket_address *local_address,
362 : const char *service_description,
363 : DATA_BLOB lm_resp, DATA_BLOB nt_resp)
364 : {
365 63 : bool allow_raw = lp_raw_ntlmv2_auth();
366 :
367 63 : if (!allow_raw && nt_resp.length >= 48) {
368 : /*
369 : * NTLMv2_RESPONSE has at least 48 bytes
370 : * and should only be supported via NTLMSSP.
371 : */
372 2 : DEBUG(2,("Rejecting raw NTLMv2 authentication with "
373 : "user [%s\\%s] from[%s]\n",
374 : client_domain, smb_name,
375 : tsocket_address_string(remote_address, mem_ctx)));
376 2 : return NT_STATUS_INVALID_PARAMETER;
377 : }
378 :
379 122 : return make_user_info(mem_ctx,
380 : user_info, smb_name, smb_name,
381 : client_domain, client_domain,
382 : get_remote_machine_name(),
383 : remote_address,
384 : local_address,
385 : service_description,
386 61 : lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
387 61 : nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
388 : NULL, NULL, NULL,
389 : AUTH_PASSWORD_RESPONSE);
390 : }
391 :
392 : /****************************************************************************
393 : Create a guest user_info blob, for anonymous authentication.
394 : ****************************************************************************/
395 :
396 37 : bool make_user_info_guest(TALLOC_CTX *mem_ctx,
397 : const struct tsocket_address *remote_address,
398 : const struct tsocket_address *local_address,
399 : const char *service_description,
400 : struct auth_usersupplied_info **user_info)
401 : {
402 0 : NTSTATUS nt_status;
403 :
404 37 : nt_status = make_user_info(mem_ctx,
405 : user_info,
406 : "","",
407 : "","",
408 : "",
409 : remote_address,
410 : local_address,
411 : service_description,
412 : NULL, NULL,
413 : NULL, NULL,
414 : NULL,
415 : AUTH_PASSWORD_RESPONSE);
416 :
417 37 : return NT_STATUS_IS_OK(nt_status) ? true : false;
418 : }
419 :
420 22966 : static NTSTATUS log_nt_token(struct security_token *token)
421 : {
422 22966 : TALLOC_CTX *frame = talloc_stackframe();
423 0 : const struct loadparm_substitution *lp_sub =
424 22966 : loadparm_s3_global_substitution();
425 0 : char *command;
426 0 : char *group_sidstr;
427 0 : struct dom_sid_buf buf;
428 0 : size_t i;
429 :
430 22966 : if ((lp_log_nt_token_command(frame, lp_sub) == NULL) ||
431 22966 : (strlen(lp_log_nt_token_command(frame, lp_sub)) == 0)) {
432 22966 : TALLOC_FREE(frame);
433 22966 : return NT_STATUS_OK;
434 : }
435 :
436 0 : group_sidstr = talloc_strdup(frame, "");
437 0 : for (i=1; i<token->num_sids; i++) {
438 0 : group_sidstr = talloc_asprintf(
439 : frame, "%s %s", group_sidstr,
440 0 : dom_sid_str_buf(&token->sids[i], &buf));
441 : }
442 :
443 0 : command = talloc_string_sub(
444 0 : frame, lp_log_nt_token_command(frame, lp_sub),
445 0 : "%s", dom_sid_str_buf(&token->sids[0], &buf));
446 0 : command = talloc_string_sub(frame, command, "%t", group_sidstr);
447 :
448 0 : if (command == NULL) {
449 0 : TALLOC_FREE(frame);
450 0 : return NT_STATUS_NO_MEMORY;
451 : }
452 :
453 0 : DEBUG(8, ("running command: [%s]\n", command));
454 0 : if (smbrun(command, NULL, NULL) != 0) {
455 0 : DEBUG(0, ("Could not log NT token\n"));
456 0 : TALLOC_FREE(frame);
457 0 : return NT_STATUS_ACCESS_DENIED;
458 : }
459 :
460 0 : TALLOC_FREE(frame);
461 0 : return NT_STATUS_OK;
462 : }
463 :
464 : /*
465 : * Create the token to use from server_info->info3 and
466 : * server_info->sids (the info3/sam groups). Find the unix gids.
467 : */
468 :
469 22252 : NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
470 : const struct auth_serversupplied_info *server_info,
471 : DATA_BLOB *session_key,
472 : const char *smb_username, /* for ->sanitized_username, for %U subs */
473 : struct auth_session_info **session_info_out)
474 : {
475 0 : struct security_token *t;
476 0 : NTSTATUS status;
477 0 : size_t i;
478 0 : struct dom_sid tmp_sid;
479 22252 : struct auth_session_info *session_info = NULL;
480 0 : struct unixid *ids;
481 :
482 : /* Ensure we can't possible take a code path leading to a
483 : * null deref. */
484 22252 : if (!server_info) {
485 0 : return NT_STATUS_LOGON_FAILURE;
486 : }
487 :
488 22252 : if (!is_allowed_domain(server_info->info3->base.logon_domain.string)) {
489 0 : DBG_NOTICE("Authentication failed for user [%s] "
490 : "from firewalled domain [%s]\n",
491 : server_info->info3->base.account_name.string,
492 : server_info->info3->base.logon_domain.string);
493 0 : return NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
494 : }
495 :
496 22252 : if (server_info->cached_session_info != NULL) {
497 644 : session_info = copy_session_info(mem_ctx,
498 644 : server_info->cached_session_info);
499 644 : if (session_info == NULL) {
500 0 : goto nomem;
501 : }
502 :
503 : /* This is a potentially untrusted username for use in %U */
504 1288 : session_info->unix_info->sanitized_username =
505 644 : talloc_alpha_strcpy(session_info->unix_info,
506 : smb_username,
507 : SAFE_NETBIOS_CHARS "$");
508 644 : if (session_info->unix_info->sanitized_username == NULL) {
509 0 : goto nomem;
510 : }
511 :
512 644 : session_info->unique_session_token = GUID_random();
513 :
514 644 : *session_info_out = session_info;
515 644 : return NT_STATUS_OK;
516 : }
517 :
518 21608 : session_info = talloc_zero(mem_ctx, struct auth_session_info);
519 21608 : if (!session_info) {
520 0 : goto nomem;
521 : }
522 :
523 21608 : session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
524 21608 : if (!session_info->unix_token) {
525 0 : goto nomem;
526 : }
527 :
528 21608 : session_info->unix_token->uid = server_info->utok.uid;
529 21608 : session_info->unix_token->gid = server_info->utok.gid;
530 :
531 21608 : session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
532 21608 : if (!session_info->unix_info) {
533 0 : goto nomem;
534 : }
535 :
536 21608 : session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
537 21608 : if (!session_info->unix_info->unix_name) {
538 0 : goto nomem;
539 : }
540 :
541 : /* This is a potentially untrusted username for use in %U */
542 43216 : session_info->unix_info->sanitized_username =
543 21608 : talloc_alpha_strcpy(session_info->unix_info,
544 : smb_username,
545 : SAFE_NETBIOS_CHARS "$");
546 21608 : if (session_info->unix_info->sanitized_username == NULL) {
547 0 : goto nomem;
548 : }
549 :
550 21608 : if (session_key) {
551 0 : data_blob_free(&session_info->session_key);
552 0 : session_info->session_key = data_blob_talloc(session_info,
553 : session_key->data,
554 : session_key->length);
555 0 : if (!session_info->session_key.data && session_key->length) {
556 0 : goto nomem;
557 : }
558 : } else {
559 21608 : session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
560 : server_info->session_key.length);
561 : }
562 :
563 : /* We need to populate session_info->info with the information found in server_info->info3 */
564 21608 : status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
565 21608 : server_info->guest == false,
566 21608 : &session_info->info);
567 21608 : if (!NT_STATUS_IS_OK(status)) {
568 0 : DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
569 0 : goto fail;
570 : }
571 :
572 : /*
573 : * If the user name was mapped to some local unix user,
574 : * we can not make much use of the SIDs the
575 : * domain controller provided us with.
576 : */
577 21608 : if (server_info->nss_token) {
578 270 : char *found_username = NULL;
579 270 : status = create_token_from_username(session_info,
580 270 : server_info->unix_name,
581 270 : server_info->guest,
582 270 : &session_info->unix_token->uid,
583 270 : &session_info->unix_token->gid,
584 : &found_username,
585 : &session_info->security_token);
586 270 : if (NT_STATUS_IS_OK(status)) {
587 270 : session_info->unix_info->unix_name = found_username;
588 : }
589 : } else {
590 21338 : status = create_local_nt_token_from_info3(session_info,
591 21338 : server_info->guest,
592 21338 : server_info->info3,
593 : &server_info->extra,
594 : &session_info->security_token);
595 : }
596 :
597 21608 : if (!NT_STATUS_IS_OK(status)) {
598 0 : goto fail;
599 : }
600 :
601 : /* Convert the SIDs to gids. */
602 :
603 21608 : session_info->unix_token->ngroups = 0;
604 21608 : session_info->unix_token->groups = NULL;
605 :
606 21608 : t = session_info->security_token;
607 :
608 21608 : ids = talloc_array(talloc_tos(), struct unixid,
609 : t->num_sids);
610 21608 : if (ids == NULL) {
611 0 : goto nomem;
612 : }
613 :
614 21608 : if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
615 0 : goto nomem;
616 : }
617 :
618 185633 : for (i=0; i<t->num_sids; i++) {
619 :
620 164025 : if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
621 20971 : continue;
622 : }
623 :
624 143054 : if (ids[i].type != ID_TYPE_GID &&
625 32919 : ids[i].type != ID_TYPE_BOTH) {
626 0 : struct dom_sid_buf buf;
627 28932 : DEBUG(10, ("Could not convert SID %s to gid, "
628 : "ignoring it\n",
629 : dom_sid_str_buf(&t->sids[i], &buf)));
630 28932 : continue;
631 : }
632 114122 : if (!add_gid_to_array_unique(session_info->unix_token,
633 114122 : ids[i].id,
634 114122 : &session_info->unix_token->groups,
635 114122 : &session_info->unix_token->ngroups)) {
636 0 : goto nomem;
637 : }
638 : }
639 :
640 : /*
641 : * Add the "Unix Group" SID for each gid to catch mapped groups
642 : * and their Unix equivalent. This is to solve the backwards
643 : * compatibility problem of 'valid users = +ntadmin' where
644 : * ntadmin has been paired with "Domain Admins" in the group
645 : * mapping table. Otherwise smb.conf would need to be changed
646 : * to 'valid user = "Domain Admins"'. --jerry
647 : *
648 : * For consistency we also add the "Unix User" SID,
649 : * so that the complete unix token is represented within
650 : * the nt token.
651 : */
652 :
653 21608 : uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
654 21608 : status = add_sid_to_array_unique(
655 21608 : session_info->security_token,
656 : &tmp_sid,
657 21608 : &session_info->security_token->sids,
658 21608 : &session_info->security_token->num_sids);
659 21608 : if (!NT_STATUS_IS_OK(status)) {
660 0 : goto fail;
661 : }
662 :
663 21608 : gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
664 21608 : status = add_sid_to_array_unique(
665 21608 : session_info->security_token,
666 : &tmp_sid,
667 21608 : &session_info->security_token->sids,
668 21608 : &session_info->security_token->num_sids);
669 21608 : if (!NT_STATUS_IS_OK(status)) {
670 0 : goto fail;
671 : }
672 :
673 135612 : for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
674 114004 : gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
675 114004 : status = add_sid_to_array_unique(
676 114004 : session_info->security_token,
677 : &tmp_sid,
678 114004 : &session_info->security_token->sids,
679 114004 : &session_info->security_token->num_sids);
680 114004 : if (!NT_STATUS_IS_OK(status)) {
681 0 : goto fail;
682 : }
683 : }
684 :
685 21608 : security_token_debug(DBGC_AUTH, 10, session_info->security_token);
686 21608 : debug_unix_user_token(DBGC_AUTH, 10,
687 21608 : session_info->unix_token->uid,
688 21608 : session_info->unix_token->gid,
689 21608 : session_info->unix_token->ngroups,
690 21608 : session_info->unix_token->groups);
691 :
692 21608 : status = log_nt_token(session_info->security_token);
693 21608 : if (!NT_STATUS_IS_OK(status)) {
694 0 : goto fail;
695 : }
696 :
697 21608 : session_info->unique_session_token = GUID_random();
698 :
699 21608 : *session_info_out = session_info;
700 21608 : return NT_STATUS_OK;
701 0 : nomem:
702 0 : status = NT_STATUS_NO_MEMORY;
703 0 : fail:
704 0 : TALLOC_FREE(session_info);
705 0 : return status;
706 : }
707 :
708 1358 : NTSTATUS auth3_user_info_dc_add_hints(struct auth_user_info_dc *user_info_dc,
709 : uid_t uid,
710 : gid_t gid,
711 : uint32_t flags)
712 : {
713 1358 : uint32_t orig_num_sids = user_info_dc->num_sids;
714 1358 : struct dom_sid tmp_sid = { 0, };
715 0 : NTSTATUS status;
716 :
717 : /*
718 : * We add S-5-88-1-X in order to pass the uid
719 : * for the unix token.
720 : */
721 1358 : sid_compose(&tmp_sid,
722 : &global_sid_Unix_NFS_Users,
723 : (uint32_t)uid);
724 1358 : status = add_sid_to_array_attrs_unique(user_info_dc->sids,
725 : &tmp_sid,
726 : SE_GROUP_DEFAULT_FLAGS,
727 : &user_info_dc->sids,
728 : &user_info_dc->num_sids);
729 1358 : if (!NT_STATUS_IS_OK(status)) {
730 0 : DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
731 : nt_errstr(status)));
732 0 : goto fail;
733 : }
734 :
735 : /*
736 : * We add S-5-88-2-X in order to pass the gid
737 : * for the unix token.
738 : */
739 1358 : sid_compose(&tmp_sid,
740 : &global_sid_Unix_NFS_Groups,
741 : (uint32_t)gid);
742 1358 : status = add_sid_to_array_attrs_unique(user_info_dc->sids,
743 : &tmp_sid,
744 : SE_GROUP_DEFAULT_FLAGS,
745 : &user_info_dc->sids,
746 : &user_info_dc->num_sids);
747 1358 : if (!NT_STATUS_IS_OK(status)) {
748 0 : DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
749 : nt_errstr(status)));
750 0 : goto fail;
751 : }
752 :
753 : /*
754 : * We add S-5-88-3-X in order to pass some flags
755 : * (AUTH3_UNIX_HINT_*) to auth3_create_session_info().
756 : */
757 1358 : sid_compose(&tmp_sid,
758 : &global_sid_Unix_NFS_Mode,
759 : flags);
760 1358 : status = add_sid_to_array_attrs_unique(user_info_dc->sids,
761 : &tmp_sid,
762 : SE_GROUP_DEFAULT_FLAGS,
763 : &user_info_dc->sids,
764 : &user_info_dc->num_sids);
765 1358 : if (!NT_STATUS_IS_OK(status)) {
766 0 : DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
767 : nt_errstr(status)));
768 0 : goto fail;
769 : }
770 :
771 1358 : return NT_STATUS_OK;
772 :
773 0 : fail:
774 0 : user_info_dc->num_sids = orig_num_sids;
775 0 : return status;
776 : }
777 :
778 1358 : static NTSTATUS auth3_session_info_create(
779 : TALLOC_CTX *mem_ctx,
780 : const struct auth_user_info_dc *user_info_dc,
781 : const char *original_user_name,
782 : uint32_t session_info_flags,
783 : struct auth_session_info **session_info_out)
784 : {
785 1358 : TALLOC_CTX *frame = talloc_stackframe();
786 1358 : struct auth_session_info *session_info = NULL;
787 1358 : uid_t hint_uid = -1;
788 1358 : bool found_hint_uid = false;
789 1358 : uid_t hint_gid = -1;
790 1358 : bool found_hint_gid = false;
791 1358 : uint32_t hint_flags = 0;
792 1358 : bool found_hint_flags = false;
793 1358 : bool need_getpwuid = false;
794 1358 : struct unixid *ids = NULL;
795 1358 : uint32_t num_gids = 0;
796 1358 : gid_t *gids = NULL;
797 1358 : struct dom_sid tmp_sid = { 0, };
798 0 : NTSTATUS status;
799 0 : size_t i;
800 0 : bool ok;
801 :
802 1358 : *session_info_out = NULL;
803 :
804 1358 : if (user_info_dc->num_sids == 0) {
805 0 : TALLOC_FREE(frame);
806 0 : return NT_STATUS_INVALID_TOKEN;
807 : }
808 :
809 1358 : if (user_info_dc->info == NULL) {
810 0 : TALLOC_FREE(frame);
811 0 : return NT_STATUS_INVALID_TOKEN;
812 : }
813 :
814 1358 : if (user_info_dc->info->account_name == NULL) {
815 0 : TALLOC_FREE(frame);
816 0 : return NT_STATUS_INVALID_TOKEN;
817 : }
818 :
819 1358 : session_info = talloc_zero(mem_ctx, struct auth_session_info);
820 1358 : if (session_info == NULL) {
821 0 : TALLOC_FREE(frame);
822 0 : return NT_STATUS_NO_MEMORY;
823 : }
824 : /* keep this under frame for easier cleanup */
825 1358 : talloc_reparent(mem_ctx, frame, session_info);
826 :
827 2716 : session_info->info = auth_user_info_copy(session_info,
828 1358 : user_info_dc->info);
829 1358 : if (session_info->info == NULL) {
830 0 : TALLOC_FREE(frame);
831 0 : return NT_STATUS_NO_MEMORY;
832 : }
833 :
834 1358 : session_info->security_token = talloc_zero(session_info,
835 : struct security_token);
836 1358 : if (session_info->security_token == NULL) {
837 0 : TALLOC_FREE(frame);
838 0 : return NT_STATUS_NO_MEMORY;
839 : }
840 :
841 : /*
842 : * Avoid a lot of reallocations and allocate what we'll
843 : * use in most cases.
844 : */
845 1358 : session_info->security_token->sids = talloc_zero_array(
846 : session_info->security_token,
847 : struct dom_sid,
848 : user_info_dc->num_sids);
849 1358 : if (session_info->security_token->sids == NULL) {
850 0 : TALLOC_FREE(frame);
851 0 : return NT_STATUS_NO_MEMORY;
852 : }
853 :
854 6790 : for (i = PRIMARY_USER_SID_INDEX; i < user_info_dc->num_sids; i++) {
855 5432 : struct security_token *nt_token = session_info->security_token;
856 0 : int cmp;
857 :
858 : /*
859 : * S-1-5-88-X-Y sids are only used to give hints
860 : * to the unix token construction.
861 : *
862 : * S-1-5-88-1-Y gives the uid=Y
863 : * S-1-5-88-2-Y gives the gid=Y
864 : * S-1-5-88-3-Y gives flags=Y: AUTH3_UNIX_HINT_*
865 : */
866 5432 : cmp = dom_sid_compare_domain(&global_sid_Unix_NFS,
867 5432 : &user_info_dc->sids[i].sid);
868 5432 : if (cmp == 0) {
869 0 : bool match;
870 4074 : uint32_t hint = 0;
871 :
872 4074 : match = sid_peek_rid(&user_info_dc->sids[i].sid, &hint);
873 4074 : if (!match) {
874 4074 : continue;
875 : }
876 :
877 4074 : match = dom_sid_in_domain(&global_sid_Unix_NFS_Users,
878 4074 : &user_info_dc->sids[i].sid);
879 4074 : if (match) {
880 1358 : if (found_hint_uid) {
881 0 : TALLOC_FREE(frame);
882 0 : return NT_STATUS_INVALID_TOKEN;
883 : }
884 1358 : found_hint_uid = true;
885 1358 : hint_uid = (uid_t)hint;
886 1358 : continue;
887 : }
888 :
889 2716 : match = dom_sid_in_domain(&global_sid_Unix_NFS_Groups,
890 2716 : &user_info_dc->sids[i].sid);
891 2716 : if (match) {
892 1358 : if (found_hint_gid) {
893 0 : TALLOC_FREE(frame);
894 0 : return NT_STATUS_INVALID_TOKEN;
895 : }
896 1358 : found_hint_gid = true;
897 1358 : hint_gid = (gid_t)hint;
898 1358 : continue;
899 : }
900 :
901 1358 : match = dom_sid_in_domain(&global_sid_Unix_NFS_Mode,
902 1358 : &user_info_dc->sids[i].sid);
903 1358 : if (match) {
904 1358 : if (found_hint_flags) {
905 0 : TALLOC_FREE(frame);
906 0 : return NT_STATUS_INVALID_TOKEN;
907 : }
908 1358 : found_hint_flags = true;
909 1358 : hint_flags = hint;
910 1358 : continue;
911 : }
912 :
913 0 : continue;
914 : }
915 :
916 1358 : status = add_sid_to_array_unique(nt_token->sids,
917 1358 : &user_info_dc->sids[i].sid,
918 : &nt_token->sids,
919 : &nt_token->num_sids);
920 1358 : if (!NT_STATUS_IS_OK(status)) {
921 0 : TALLOC_FREE(frame);
922 0 : return status;
923 : }
924 : }
925 :
926 : /*
927 : * We need at least one usable SID
928 : */
929 1358 : if (session_info->security_token->num_sids == 0) {
930 0 : TALLOC_FREE(frame);
931 0 : return NT_STATUS_INVALID_TOKEN;
932 : }
933 :
934 : /*
935 : * We need all tree hints: uid, gid, flags
936 : * or none of them.
937 : */
938 1358 : if (found_hint_uid || found_hint_gid || found_hint_flags) {
939 1358 : if (!found_hint_uid) {
940 0 : TALLOC_FREE(frame);
941 0 : return NT_STATUS_INVALID_TOKEN;
942 : }
943 :
944 1358 : if (!found_hint_gid) {
945 0 : TALLOC_FREE(frame);
946 0 : return NT_STATUS_INVALID_TOKEN;
947 : }
948 :
949 1358 : if (!found_hint_flags) {
950 0 : TALLOC_FREE(frame);
951 0 : return NT_STATUS_INVALID_TOKEN;
952 : }
953 : }
954 :
955 1358 : if (!(user_info_dc->info->user_flags & NETLOGON_GUEST)) {
956 580 : session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
957 : }
958 :
959 1358 : status = finalize_local_nt_token(session_info->security_token,
960 : session_info_flags);
961 1358 : if (!NT_STATUS_IS_OK(status)) {
962 0 : TALLOC_FREE(frame);
963 0 : return status;
964 : }
965 :
966 : /*
967 : * unless set otherwise, the session key is the user session
968 : * key from the auth subsystem
969 : */
970 1358 : if (user_info_dc->user_session_key.length != 0) {
971 1358 : session_info->session_key = data_blob_dup_talloc(session_info,
972 : user_info_dc->user_session_key);
973 1358 : if (session_info->session_key.data == NULL) {
974 0 : TALLOC_FREE(frame);
975 0 : return NT_STATUS_NO_MEMORY;
976 : }
977 : }
978 :
979 1358 : if (!(session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)) {
980 0 : goto done;
981 : }
982 :
983 1358 : session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
984 1358 : if (session_info->unix_token == NULL) {
985 0 : TALLOC_FREE(frame);
986 0 : return NT_STATUS_NO_MEMORY;
987 : }
988 1358 : session_info->unix_token->uid = -1;
989 1358 : session_info->unix_token->gid = -1;
990 :
991 1358 : session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
992 1358 : if (session_info->unix_info == NULL) {
993 0 : TALLOC_FREE(frame);
994 0 : return NT_STATUS_NO_MEMORY;
995 : }
996 :
997 : /* Convert the SIDs to uid/gids. */
998 :
999 1358 : ids = talloc_zero_array(frame, struct unixid,
1000 : session_info->security_token->num_sids);
1001 1358 : if (ids == NULL) {
1002 0 : TALLOC_FREE(frame);
1003 0 : return NT_STATUS_NO_MEMORY;
1004 : }
1005 :
1006 1358 : if (!(hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS)) {
1007 778 : ok = sids_to_unixids(session_info->security_token->sids,
1008 778 : session_info->security_token->num_sids,
1009 : ids);
1010 778 : if (!ok) {
1011 0 : TALLOC_FREE(frame);
1012 0 : return NT_STATUS_NO_MEMORY;
1013 : }
1014 : }
1015 :
1016 1358 : if (found_hint_uid) {
1017 1358 : session_info->unix_token->uid = hint_uid;
1018 0 : } else if (ids[0].type == ID_TYPE_UID) {
1019 : /*
1020 : * The primary SID resolves to a UID only.
1021 : */
1022 0 : session_info->unix_token->uid = ids[0].id;
1023 0 : } else if (ids[0].type == ID_TYPE_BOTH) {
1024 : /*
1025 : * The primary SID resolves to a UID and GID,
1026 : * use it as uid and add it as first element
1027 : * to the groups array.
1028 : */
1029 0 : session_info->unix_token->uid = ids[0].id;
1030 :
1031 0 : ok = add_gid_to_array_unique(session_info->unix_token,
1032 0 : session_info->unix_token->uid,
1033 0 : &session_info->unix_token->groups,
1034 0 : &session_info->unix_token->ngroups);
1035 0 : if (!ok) {
1036 0 : TALLOC_FREE(frame);
1037 0 : return NT_STATUS_NO_MEMORY;
1038 : }
1039 : } else {
1040 : /*
1041 : * It we can't get a uid, we can't imporsonate
1042 : * the user.
1043 : */
1044 0 : TALLOC_FREE(frame);
1045 0 : return NT_STATUS_INVALID_TOKEN;
1046 : }
1047 :
1048 1358 : if (found_hint_gid) {
1049 1358 : session_info->unix_token->gid = hint_gid;
1050 : } else {
1051 0 : need_getpwuid = true;
1052 : }
1053 :
1054 1358 : if (hint_flags & AUTH3_UNIX_HINT_QUALIFIED_NAME) {
1055 1160 : session_info->unix_info->unix_name =
1056 1160 : talloc_asprintf(session_info->unix_info,
1057 : "%s%c%s",
1058 580 : session_info->info->domain_name,
1059 580 : *lp_winbind_separator(),
1060 580 : session_info->info->account_name);
1061 580 : if (session_info->unix_info->unix_name == NULL) {
1062 0 : TALLOC_FREE(frame);
1063 0 : return NT_STATUS_NO_MEMORY;
1064 : }
1065 778 : } else if (hint_flags & AUTH3_UNIX_HINT_ISLOLATED_NAME) {
1066 0 : session_info->unix_info->unix_name =
1067 0 : talloc_strdup(session_info->unix_info,
1068 0 : session_info->info->account_name);
1069 0 : if (session_info->unix_info->unix_name == NULL) {
1070 0 : TALLOC_FREE(frame);
1071 0 : return NT_STATUS_NO_MEMORY;
1072 : }
1073 : } else {
1074 778 : need_getpwuid = true;
1075 : }
1076 :
1077 1358 : if (need_getpwuid) {
1078 778 : struct passwd *pwd = NULL;
1079 :
1080 : /*
1081 : * Ask the system for the primary gid
1082 : * and the real unix name.
1083 : */
1084 778 : pwd = getpwuid_alloc(frame, session_info->unix_token->uid);
1085 778 : if (pwd == NULL) {
1086 0 : TALLOC_FREE(frame);
1087 0 : return NT_STATUS_INVALID_TOKEN;
1088 : }
1089 778 : if (!found_hint_gid) {
1090 0 : session_info->unix_token->gid = pwd->pw_gid;
1091 : }
1092 :
1093 1556 : session_info->unix_info->unix_name =
1094 778 : talloc_strdup(session_info->unix_info, pwd->pw_name);
1095 778 : if (session_info->unix_info->unix_name == NULL) {
1096 0 : TALLOC_FREE(frame);
1097 0 : return NT_STATUS_NO_MEMORY;
1098 : }
1099 :
1100 778 : TALLOC_FREE(pwd);
1101 : }
1102 :
1103 1358 : ok = add_gid_to_array_unique(session_info->unix_token,
1104 1358 : session_info->unix_token->gid,
1105 1358 : &session_info->unix_token->groups,
1106 1358 : &session_info->unix_token->ngroups);
1107 1358 : if (!ok) {
1108 0 : TALLOC_FREE(frame);
1109 0 : return NT_STATUS_NO_MEMORY;
1110 : }
1111 :
1112 : /* This is a potentially untrusted username for use in %U */
1113 2716 : session_info->unix_info->sanitized_username =
1114 1358 : talloc_alpha_strcpy(session_info->unix_info,
1115 : original_user_name,
1116 : SAFE_NETBIOS_CHARS "$");
1117 1358 : if (session_info->unix_info->sanitized_username == NULL) {
1118 0 : TALLOC_FREE(frame);
1119 0 : return NT_STATUS_NO_MEMORY;
1120 : }
1121 :
1122 4272 : for (i=0; i < session_info->security_token->num_sids; i++) {
1123 :
1124 2914 : if (ids[i].type != ID_TYPE_GID &&
1125 1781 : ids[i].type != ID_TYPE_BOTH) {
1126 1315 : struct security_token *nt_token =
1127 1315 : session_info->security_token;
1128 0 : struct dom_sid_buf buf;
1129 :
1130 1315 : DEBUG(10, ("Could not convert SID %s to gid, "
1131 : "ignoring it\n",
1132 : dom_sid_str_buf(&nt_token->sids[i], &buf)));
1133 1315 : continue;
1134 : }
1135 :
1136 1599 : ok = add_gid_to_array_unique(session_info->unix_token,
1137 1599 : ids[i].id,
1138 1599 : &session_info->unix_token->groups,
1139 1599 : &session_info->unix_token->ngroups);
1140 1599 : if (!ok) {
1141 0 : TALLOC_FREE(frame);
1142 0 : return NT_STATUS_NO_MEMORY;
1143 : }
1144 : }
1145 1358 : TALLOC_FREE(ids);
1146 :
1147 : /*
1148 : * Now we must get any groups this user has been
1149 : * added to in /etc/group and merge them in.
1150 : * This has to be done in every code path
1151 : * that creates an NT token, as remote users
1152 : * may have been added to the local /etc/group
1153 : * database. Tokens created merely from the
1154 : * info3 structs (via the DC or via the krb5 PAC)
1155 : * won't have these local groups. Note the
1156 : * groups added here will only be UNIX groups
1157 : * (S-1-22-2-XXXX groups) as getgroups_unix_user()
1158 : * turns off winbindd before calling getgroups().
1159 : *
1160 : * NB. This is duplicating work already
1161 : * done in the 'unix_user:' case of
1162 : * create_token_from_sid() but won't
1163 : * do anything other than be inefficient
1164 : * in that case.
1165 : */
1166 1358 : if (!(hint_flags & AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS)) {
1167 778 : ok = getgroups_unix_user(frame,
1168 778 : session_info->unix_info->unix_name,
1169 778 : session_info->unix_token->gid,
1170 : &gids, &num_gids);
1171 778 : if (!ok) {
1172 0 : TALLOC_FREE(frame);
1173 0 : return NT_STATUS_INVALID_TOKEN;
1174 : }
1175 : }
1176 :
1177 2914 : for (i=0; i < num_gids; i++) {
1178 :
1179 1556 : ok = add_gid_to_array_unique(session_info->unix_token,
1180 1556 : gids[i],
1181 1556 : &session_info->unix_token->groups,
1182 1556 : &session_info->unix_token->ngroups);
1183 1556 : if (!ok) {
1184 0 : TALLOC_FREE(frame);
1185 0 : return NT_STATUS_NO_MEMORY;
1186 : }
1187 : }
1188 1358 : TALLOC_FREE(gids);
1189 :
1190 1358 : if (hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS) {
1191 : /*
1192 : * We should not translate the unix token uid/gids
1193 : * to S-1-22-X-Y SIDs.
1194 : */
1195 580 : goto done;
1196 : }
1197 :
1198 : /*
1199 : * Add the "Unix Group" SID for each gid to catch mapped groups
1200 : * and their Unix equivalent. This is to solve the backwards
1201 : * compatibility problem of 'valid users = +ntadmin' where
1202 : * ntadmin has been paired with "Domain Admins" in the group
1203 : * mapping table. Otherwise smb.conf would need to be changed
1204 : * to 'valid user = "Domain Admins"'. --jerry
1205 : *
1206 : * For consistency we also add the "Unix User" SID,
1207 : * so that the complete unix token is represented within
1208 : * the nt token.
1209 : */
1210 :
1211 778 : uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
1212 778 : status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1213 778 : &session_info->security_token->sids,
1214 778 : &session_info->security_token->num_sids);
1215 778 : if (!NT_STATUS_IS_OK(status)) {
1216 0 : TALLOC_FREE(frame);
1217 0 : return status;
1218 : }
1219 :
1220 778 : gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
1221 778 : status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
1222 778 : &session_info->security_token->sids,
1223 778 : &session_info->security_token->num_sids);
1224 778 : if (!NT_STATUS_IS_OK(status)) {
1225 0 : TALLOC_FREE(frame);
1226 0 : return status;
1227 : }
1228 :
1229 3933 : for (i=0; i < session_info->unix_token->ngroups; i++ ) {
1230 3155 : struct security_token *nt_token = session_info->security_token;
1231 :
1232 3155 : gid_to_unix_groups_sid(session_info->unix_token->groups[i],
1233 : &tmp_sid);
1234 3155 : status = add_sid_to_array_unique(nt_token->sids,
1235 : &tmp_sid,
1236 : &nt_token->sids,
1237 : &nt_token->num_sids);
1238 3155 : if (!NT_STATUS_IS_OK(status)) {
1239 0 : TALLOC_FREE(frame);
1240 0 : return status;
1241 : }
1242 : }
1243 :
1244 778 : done:
1245 1358 : security_token_debug(DBGC_AUTH, 10, session_info->security_token);
1246 1358 : if (session_info->unix_token != NULL) {
1247 1358 : debug_unix_user_token(DBGC_AUTH, 10,
1248 1358 : session_info->unix_token->uid,
1249 1358 : session_info->unix_token->gid,
1250 1358 : session_info->unix_token->ngroups,
1251 1358 : session_info->unix_token->groups);
1252 : }
1253 :
1254 1358 : status = log_nt_token(session_info->security_token);
1255 1358 : if (!NT_STATUS_IS_OK(status)) {
1256 0 : TALLOC_FREE(frame);
1257 0 : return status;
1258 : }
1259 :
1260 1358 : session_info->unique_session_token = GUID_random();
1261 :
1262 1358 : *session_info_out = talloc_move(mem_ctx, &session_info);
1263 1358 : TALLOC_FREE(frame);
1264 1358 : return NT_STATUS_OK;
1265 : }
1266 :
1267 : /***************************************************************************
1268 : Make (and fill) a server_info struct from a 'struct passwd' by conversion
1269 : to a struct samu
1270 : ***************************************************************************/
1271 :
1272 256 : NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
1273 : const char *unix_username,
1274 : const struct passwd *pwd,
1275 : struct auth_serversupplied_info **server_info)
1276 : {
1277 0 : NTSTATUS status;
1278 256 : TALLOC_CTX *tmp_ctx = NULL;
1279 0 : struct auth_serversupplied_info *result;
1280 :
1281 256 : tmp_ctx = talloc_stackframe();
1282 256 : if (tmp_ctx == NULL) {
1283 0 : return NT_STATUS_NO_MEMORY;
1284 : }
1285 :
1286 256 : result = make_server_info(tmp_ctx);
1287 256 : if (result == NULL) {
1288 0 : status = NT_STATUS_NO_MEMORY;
1289 0 : goto done;
1290 : }
1291 :
1292 256 : status = passwd_to_SamInfo3(result,
1293 : unix_username,
1294 : pwd,
1295 256 : &result->info3,
1296 256 : &result->extra);
1297 256 : if (!NT_STATUS_IS_OK(status)) {
1298 0 : goto done;
1299 : }
1300 :
1301 256 : result->unix_name = talloc_strdup(result, unix_username);
1302 256 : if (result->unix_name == NULL) {
1303 0 : status = NT_STATUS_NO_MEMORY;
1304 0 : goto done;
1305 : }
1306 :
1307 256 : result->utok.uid = pwd->pw_uid;
1308 256 : result->utok.gid = pwd->pw_gid;
1309 :
1310 256 : *server_info = talloc_move(mem_ctx, &result);
1311 256 : status = NT_STATUS_OK;
1312 256 : done:
1313 256 : talloc_free(tmp_ctx);
1314 :
1315 256 : return status;
1316 : }
1317 :
1318 778 : static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
1319 : struct netr_SamInfo3 *info3)
1320 : {
1321 778 : const char *guest_account = lp_guest_account();
1322 0 : struct dom_sid domain_sid;
1323 0 : struct passwd *pwd;
1324 0 : const char *tmp;
1325 :
1326 778 : pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
1327 778 : if (pwd == NULL) {
1328 0 : DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
1329 : "account [%s]!\n", guest_account));
1330 0 : return NT_STATUS_NO_SUCH_USER;
1331 : }
1332 :
1333 : /* Set account name */
1334 778 : tmp = talloc_strdup(mem_ctx, pwd->pw_name);
1335 778 : if (tmp == NULL) {
1336 0 : return NT_STATUS_NO_MEMORY;
1337 : }
1338 778 : init_lsa_String(&info3->base.account_name, tmp);
1339 :
1340 : /* Set domain name */
1341 778 : tmp = talloc_strdup(mem_ctx, get_global_sam_name());
1342 778 : if (tmp == NULL) {
1343 0 : return NT_STATUS_NO_MEMORY;
1344 : }
1345 778 : init_lsa_StringLarge(&info3->base.logon_domain, tmp);
1346 :
1347 : /* Domain sid */
1348 778 : sid_copy(&domain_sid, get_global_sam_sid());
1349 :
1350 778 : info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
1351 778 : if (info3->base.domain_sid == NULL) {
1352 0 : return NT_STATUS_NO_MEMORY;
1353 : }
1354 :
1355 : /* Guest rid */
1356 778 : info3->base.rid = DOMAIN_RID_GUEST;
1357 :
1358 : /* Primary gid */
1359 778 : info3->base.primary_gid = DOMAIN_RID_GUESTS;
1360 :
1361 : /* Set as guest */
1362 778 : info3->base.user_flags = NETLOGON_GUEST;
1363 :
1364 778 : TALLOC_FREE(pwd);
1365 778 : return NT_STATUS_OK;
1366 : }
1367 :
1368 : /***************************************************************************
1369 : Make (and fill) a user_info struct for a guest login.
1370 : This *must* succeed for smbd to start. If there is no mapping entry for
1371 : the guest gid, then create one.
1372 :
1373 : The resulting structure is a 'session_info' because
1374 : create_local_token() has already been called on it. This is quite
1375 : nasty, as the auth subsystem isn't expect this, but the behavior is
1376 : left as-is for now.
1377 : ***************************************************************************/
1378 :
1379 778 : static NTSTATUS make_new_session_info_guest(TALLOC_CTX *mem_ctx,
1380 : struct auth_session_info **_session_info,
1381 : struct auth_serversupplied_info **_server_info)
1382 : {
1383 778 : struct auth_session_info *session_info = NULL;
1384 778 : struct auth_serversupplied_info *server_info = NULL;
1385 778 : const char *guest_account = lp_guest_account();
1386 778 : const char *domain = lp_netbios_name();
1387 0 : struct netr_SamInfo3 info3;
1388 0 : TALLOC_CTX *tmp_ctx;
1389 0 : NTSTATUS status;
1390 :
1391 778 : tmp_ctx = talloc_stackframe();
1392 778 : if (tmp_ctx == NULL) {
1393 0 : return NT_STATUS_NO_MEMORY;
1394 : }
1395 :
1396 778 : ZERO_STRUCT(info3);
1397 :
1398 778 : status = get_guest_info3(tmp_ctx, &info3);
1399 778 : if (!NT_STATUS_IS_OK(status)) {
1400 0 : DEBUG(0, ("get_guest_info3 failed with %s\n",
1401 : nt_errstr(status)));
1402 0 : goto done;
1403 : }
1404 :
1405 778 : status = make_server_info_info3(tmp_ctx,
1406 : guest_account,
1407 : domain,
1408 : &server_info,
1409 : &info3);
1410 778 : if (!NT_STATUS_IS_OK(status)) {
1411 0 : DEBUG(0, ("make_server_info_info3 failed with %s\n",
1412 : nt_errstr(status)));
1413 0 : goto done;
1414 : }
1415 :
1416 778 : server_info->guest = true;
1417 :
1418 : /* This should not be done here (we should produce a server
1419 : * info, and later construct a session info from it), but for
1420 : * now this does not change the previous behavior */
1421 778 : status = create_local_token(tmp_ctx, server_info, NULL,
1422 778 : server_info->info3->base.account_name.string,
1423 : &session_info);
1424 778 : if (!NT_STATUS_IS_OK(status)) {
1425 0 : DEBUG(0, ("create_local_token failed: %s\n",
1426 : nt_errstr(status)));
1427 0 : goto done;
1428 : }
1429 :
1430 : /*
1431 : * It's ugly, but for now it's
1432 : * needed to force Builtin_Guests
1433 : * here, because memberships of
1434 : * Builtin_Guests might be incomplete.
1435 : */
1436 778 : status = add_sid_to_array_unique(session_info->security_token,
1437 : &global_sid_Builtin_Guests,
1438 778 : &session_info->security_token->sids,
1439 778 : &session_info->security_token->num_sids);
1440 778 : if (!NT_STATUS_IS_OK(status)) {
1441 0 : DBG_ERR("Failed to force Builtin_Guests to nt token\n");
1442 0 : goto done;
1443 : }
1444 :
1445 : /* annoying, but the Guest really does have a session key, and it is
1446 : all zeros! */
1447 778 : session_info->session_key = data_blob_talloc_zero(session_info, 16);
1448 :
1449 778 : *_session_info = talloc_move(mem_ctx, &session_info);
1450 778 : *_server_info = talloc_move(mem_ctx, &server_info);
1451 :
1452 778 : status = NT_STATUS_OK;
1453 778 : done:
1454 778 : TALLOC_FREE(tmp_ctx);
1455 778 : return status;
1456 : }
1457 :
1458 : /***************************************************************************
1459 : Make (and fill) a auth_session_info struct for a system user login.
1460 : This *must* succeed for smbd to start.
1461 : ***************************************************************************/
1462 :
1463 580 : static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
1464 : struct auth_session_info **session_info)
1465 : {
1466 580 : TALLOC_CTX *frame = talloc_stackframe();
1467 580 : struct auth_user_info_dc *user_info_dc = NULL;
1468 580 : uid_t uid = -1;
1469 580 : gid_t gid = -1;
1470 580 : uint32_t hint_flags = 0;
1471 580 : uint32_t session_info_flags = 0;
1472 0 : NTSTATUS status;
1473 :
1474 580 : status = auth_system_user_info_dc(frame, lp_netbios_name(),
1475 : &user_info_dc);
1476 580 : if (!NT_STATUS_IS_OK(status)) {
1477 0 : DEBUG(0, ("auth_system_user_info_dc failed: %s\n",
1478 : nt_errstr(status)));
1479 0 : goto done;
1480 : }
1481 :
1482 : /*
1483 : * Just get the initial uid/gid
1484 : * and don't expand the unix groups.
1485 : */
1486 580 : uid = sec_initial_uid();
1487 580 : gid = sec_initial_gid();
1488 580 : hint_flags |= AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS;
1489 :
1490 : /*
1491 : * Also avoid sid mapping to gids,
1492 : * as well as adding the unix_token uid/gids as
1493 : * S-1-22-X-Y SIDs to the nt token.
1494 : */
1495 580 : hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS;
1496 580 : hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS;
1497 :
1498 : /*
1499 : * The unix name will be "NT AUTHORITY+SYSTEM",
1500 : * where '+' is the "winbind separator" character.
1501 : */
1502 580 : hint_flags |= AUTH3_UNIX_HINT_QUALIFIED_NAME;
1503 580 : status = auth3_user_info_dc_add_hints(user_info_dc,
1504 : uid,
1505 : gid,
1506 : hint_flags);
1507 580 : if (!NT_STATUS_IS_OK(status)) {
1508 0 : DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1509 : nt_errstr(status)));
1510 0 : goto done;
1511 : }
1512 :
1513 580 : session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1514 580 : session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1515 580 : status = auth3_session_info_create(mem_ctx, user_info_dc,
1516 580 : user_info_dc->info->account_name,
1517 : session_info_flags,
1518 : session_info);
1519 580 : if (!NT_STATUS_IS_OK(status)) {
1520 0 : DEBUG(0, ("auth3_session_info_create failed: %s\n",
1521 : nt_errstr(status)));
1522 0 : goto done;
1523 : }
1524 :
1525 580 : done:
1526 580 : TALLOC_FREE(frame);
1527 580 : return status;
1528 : }
1529 :
1530 778 : static NTSTATUS make_new_session_info_anonymous(TALLOC_CTX *mem_ctx,
1531 : struct auth_session_info **session_info)
1532 : {
1533 778 : TALLOC_CTX *frame = talloc_stackframe();
1534 778 : const char *guest_account = lp_guest_account();
1535 778 : struct auth_user_info_dc *user_info_dc = NULL;
1536 778 : struct passwd *pwd = NULL;
1537 778 : uint32_t hint_flags = 0;
1538 778 : uint32_t session_info_flags = 0;
1539 0 : NTSTATUS status;
1540 :
1541 : /*
1542 : * We use the guest account for the unix token
1543 : * while we use a true anonymous nt token.
1544 : *
1545 : * It's very important to have a separate
1546 : * nt token for anonymous.
1547 : */
1548 :
1549 778 : pwd = Get_Pwnam_alloc(frame, guest_account);
1550 778 : if (pwd == NULL) {
1551 0 : DBG_ERR("Unable to locate guest account [%s]!\n",
1552 : guest_account);
1553 0 : status = NT_STATUS_NO_SUCH_USER;
1554 0 : goto done;
1555 : }
1556 :
1557 778 : status = auth_anonymous_user_info_dc(frame, lp_netbios_name(),
1558 : &user_info_dc);
1559 778 : if (!NT_STATUS_IS_OK(status)) {
1560 0 : DEBUG(0, ("auth_anonymous_user_info_dc failed: %s\n",
1561 : nt_errstr(status)));
1562 0 : goto done;
1563 : }
1564 :
1565 : /*
1566 : * Note we don't pass AUTH3_UNIX_HINT_QUALIFIED_NAME
1567 : * nor AUTH3_UNIX_HINT_ISOLATED_NAME here
1568 : * as we want the unix name be found by getpwuid_alloc().
1569 : */
1570 :
1571 778 : status = auth3_user_info_dc_add_hints(user_info_dc,
1572 : pwd->pw_uid,
1573 : pwd->pw_gid,
1574 : hint_flags);
1575 778 : if (!NT_STATUS_IS_OK(status)) {
1576 0 : DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
1577 : nt_errstr(status)));
1578 0 : goto done;
1579 : }
1580 :
1581 : /*
1582 : * In future we may want to remove
1583 : * AUTH_SESSION_INFO_DEFAULT_GROUPS.
1584 : *
1585 : * Similar to Windows with EveryoneIncludesAnonymous
1586 : * and RestrictAnonymous.
1587 : *
1588 : * We may introduce AUTH_SESSION_INFO_ANON_WORLD...
1589 : *
1590 : * But for this is required to keep the existing tests
1591 : * working.
1592 : */
1593 778 : session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
1594 778 : session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
1595 778 : session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
1596 778 : status = auth3_session_info_create(mem_ctx, user_info_dc,
1597 : "",
1598 : session_info_flags,
1599 : session_info);
1600 778 : if (!NT_STATUS_IS_OK(status)) {
1601 0 : DEBUG(0, ("auth3_session_info_create failed: %s\n",
1602 : nt_errstr(status)));
1603 0 : goto done;
1604 : }
1605 :
1606 778 : done:
1607 778 : TALLOC_FREE(frame);
1608 778 : return status;
1609 : }
1610 :
1611 : /****************************************************************************
1612 : Fake a auth_session_info just from a username (as a
1613 : session_info structure, with create_local_token() already called on
1614 : it.
1615 : ****************************************************************************/
1616 :
1617 256 : NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
1618 : const char *username,
1619 : bool is_guest,
1620 : struct auth_session_info **session_info)
1621 : {
1622 0 : struct passwd *pwd;
1623 0 : NTSTATUS status;
1624 0 : struct auth_serversupplied_info *result;
1625 0 : TALLOC_CTX *tmp_ctx;
1626 :
1627 256 : tmp_ctx = talloc_stackframe();
1628 256 : if (tmp_ctx == NULL) {
1629 0 : return NT_STATUS_NO_MEMORY;
1630 : }
1631 :
1632 256 : pwd = Get_Pwnam_alloc(tmp_ctx, username);
1633 256 : if (pwd == NULL) {
1634 0 : status = NT_STATUS_NO_SUCH_USER;
1635 0 : goto done;
1636 : }
1637 :
1638 256 : status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
1639 256 : if (!NT_STATUS_IS_OK(status)) {
1640 0 : goto done;
1641 : }
1642 :
1643 256 : result->nss_token = true;
1644 256 : result->guest = is_guest;
1645 :
1646 : /* Now turn the server_info into a session_info with the full token etc */
1647 256 : status = create_local_token(mem_ctx,
1648 : result,
1649 : NULL,
1650 256 : pwd->pw_name,
1651 : session_info);
1652 :
1653 256 : done:
1654 256 : talloc_free(tmp_ctx);
1655 :
1656 256 : return status;
1657 : }
1658 :
1659 : /* This function MUST only used to create the cached server_info for
1660 : * guest.
1661 : *
1662 : * This is a lossy conversion. Variables known to be lost so far
1663 : * include:
1664 : *
1665 : * - nss_token (not needed because the only read doesn't happen
1666 : * for the GUEST user, as this routine populates ->security_token
1667 : *
1668 : * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
1669 : *
1670 : * - The 'server_info' parameter allows the missing 'info3' to be copied across.
1671 : */
1672 590 : static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
1673 : const struct auth_session_info *src,
1674 : struct auth_serversupplied_info *server_info)
1675 : {
1676 0 : struct auth_serversupplied_info *dst;
1677 0 : NTSTATUS status;
1678 :
1679 590 : dst = make_server_info(mem_ctx);
1680 590 : if (dst == NULL) {
1681 0 : return NULL;
1682 : }
1683 :
1684 : /* This element must be provided to convert back to an auth_serversupplied_info */
1685 590 : SMB_ASSERT(src->unix_info);
1686 :
1687 590 : dst->guest = true;
1688 :
1689 : /* This element must be provided to convert back to an
1690 : * auth_serversupplied_info. This needs to be from the
1691 : * auth_session_info because the group values in particular
1692 : * may change during create_local_token() processing */
1693 590 : SMB_ASSERT(src->unix_token);
1694 590 : dst->utok.uid = src->unix_token->uid;
1695 590 : dst->utok.gid = src->unix_token->gid;
1696 590 : dst->utok.ngroups = src->unix_token->ngroups;
1697 590 : if (src->unix_token->ngroups != 0) {
1698 590 : dst->utok.groups = (gid_t *)talloc_memdup(
1699 : dst, src->unix_token->groups,
1700 : sizeof(gid_t)*dst->utok.ngroups);
1701 : } else {
1702 0 : dst->utok.groups = NULL;
1703 : }
1704 :
1705 : /* We must have a security_token as otherwise the lossy
1706 : * conversion without nss_token would cause create_local_token
1707 : * to take the wrong path */
1708 590 : SMB_ASSERT(src->security_token);
1709 :
1710 590 : dst->session_key = data_blob_talloc( dst, src->session_key.data,
1711 : src->session_key.length);
1712 :
1713 : /* This is OK because this functions is only used for the
1714 : * GUEST account, which has all-zero keys for both values */
1715 590 : dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1716 : src->session_key.length);
1717 :
1718 590 : status = copy_netr_SamInfo3(dst,
1719 590 : server_info->info3,
1720 : &dst->info3);
1721 590 : if (!NT_STATUS_IS_OK(status)) {
1722 0 : TALLOC_FREE(dst);
1723 0 : return NULL;
1724 : }
1725 :
1726 590 : dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1727 590 : if (!dst->unix_name) {
1728 0 : TALLOC_FREE(dst);
1729 0 : return NULL;
1730 : }
1731 :
1732 590 : dst->cached_session_info = src;
1733 590 : return dst;
1734 : }
1735 :
1736 : /*
1737 : * Set a new session key. Used in the rpc server where we have to override the
1738 : * SMB level session key with SystemLibraryDTC
1739 : */
1740 :
1741 0 : bool session_info_set_session_key(struct auth_session_info *info,
1742 : DATA_BLOB session_key)
1743 : {
1744 0 : TALLOC_FREE(info->session_key.data);
1745 :
1746 0 : info->session_key = data_blob_talloc(
1747 : info, session_key.data, session_key.length);
1748 :
1749 0 : return (info->session_key.data != NULL);
1750 : }
1751 :
1752 : static struct auth_session_info *guest_info = NULL;
1753 : static struct auth_session_info *anonymous_info = NULL;
1754 :
1755 : static struct auth_serversupplied_info *guest_server_info = NULL;
1756 :
1757 778 : bool init_guest_session_info(TALLOC_CTX *mem_ctx)
1758 : {
1759 0 : NTSTATUS status;
1760 :
1761 778 : if (guest_info != NULL)
1762 0 : return true;
1763 :
1764 778 : status = make_new_session_info_guest(mem_ctx,
1765 : &guest_info,
1766 : &guest_server_info);
1767 778 : if (!NT_STATUS_IS_OK(status)) {
1768 0 : return false;
1769 : }
1770 :
1771 778 : status = make_new_session_info_anonymous(mem_ctx,
1772 : &anonymous_info);
1773 778 : if (!NT_STATUS_IS_OK(status)) {
1774 0 : return false;
1775 : }
1776 :
1777 778 : return true;
1778 : }
1779 :
1780 71 : bool reinit_guest_session_info(TALLOC_CTX *mem_ctx)
1781 : {
1782 71 : TALLOC_FREE(guest_info);
1783 71 : TALLOC_FREE(guest_server_info);
1784 71 : TALLOC_FREE(anonymous_info);
1785 :
1786 71 : DBG_DEBUG("Reinitialing guest info\n");
1787 :
1788 71 : return init_guest_session_info(mem_ctx);
1789 : }
1790 :
1791 29 : NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1792 : struct auth_serversupplied_info **server_info)
1793 : {
1794 : /* This is trickier than it would appear to need to be because
1795 : * we are trying to avoid certain costly operations when the
1796 : * structure is converted to a 'auth_session_info' again in
1797 : * create_local_token() */
1798 29 : *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1799 29 : return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1800 : }
1801 :
1802 140 : NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1803 : struct auth_session_info **session_info)
1804 : {
1805 140 : *session_info = copy_session_info(mem_ctx, guest_info);
1806 140 : return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1807 : }
1808 :
1809 561 : NTSTATUS make_server_info_anonymous(TALLOC_CTX *mem_ctx,
1810 : struct auth_serversupplied_info **server_info)
1811 : {
1812 561 : if (anonymous_info == NULL) {
1813 0 : return NT_STATUS_UNSUCCESSFUL;
1814 : }
1815 :
1816 : /*
1817 : * This is trickier than it would appear to need to be because
1818 : * we are trying to avoid certain costly operations when the
1819 : * structure is converted to a 'auth_session_info' again in
1820 : * create_local_token()
1821 : *
1822 : * We use a guest server_info, but with the anonymous session info,
1823 : * which means create_local_token() will return a copy
1824 : * of the anonymous token.
1825 : *
1826 : * The server info is just used as legacy in order to
1827 : * keep existing code working. Maybe some debug messages
1828 : * will still refer to guest instead of anonymous.
1829 : */
1830 561 : *server_info = copy_session_info_serverinfo_guest(mem_ctx, anonymous_info,
1831 : guest_server_info);
1832 561 : if (*server_info == NULL) {
1833 0 : return NT_STATUS_NO_MEMORY;
1834 : }
1835 :
1836 561 : return NT_STATUS_OK;
1837 : }
1838 :
1839 1022 : NTSTATUS make_session_info_anonymous(TALLOC_CTX *mem_ctx,
1840 : struct auth_session_info **session_info)
1841 : {
1842 1022 : if (anonymous_info == NULL) {
1843 0 : return NT_STATUS_UNSUCCESSFUL;
1844 : }
1845 :
1846 1022 : *session_info = copy_session_info(mem_ctx, anonymous_info);
1847 1022 : if (*session_info == NULL) {
1848 0 : return NT_STATUS_NO_MEMORY;
1849 : }
1850 :
1851 1022 : return NT_STATUS_OK;
1852 : }
1853 :
1854 : static struct auth_session_info *system_info = NULL;
1855 :
1856 580 : NTSTATUS init_system_session_info(TALLOC_CTX *mem_ctx)
1857 : {
1858 580 : if (system_info != NULL)
1859 0 : return NT_STATUS_OK;
1860 :
1861 580 : return make_new_session_info_system(mem_ctx, &system_info);
1862 : }
1863 :
1864 245 : NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1865 : struct auth_session_info **session_info)
1866 : {
1867 245 : if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1868 245 : *session_info = copy_session_info(mem_ctx, system_info);
1869 245 : return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1870 : }
1871 :
1872 28569 : const struct auth_session_info *get_session_info_system(void)
1873 : {
1874 28569 : return system_info;
1875 : }
1876 :
1877 : /***************************************************************************
1878 : Purely internal function for make_server_info_info3
1879 : ***************************************************************************/
1880 :
1881 1864 : static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1882 : const char *username,
1883 : const struct dom_sid *sid,
1884 : char **found_username,
1885 : struct passwd **pwd,
1886 : bool *username_was_mapped)
1887 : {
1888 1864 : char *orig_dom_user = NULL;
1889 1864 : char *dom_user = NULL;
1890 1864 : char *lower_username = NULL;
1891 1864 : char *real_username = NULL;
1892 0 : struct passwd *passwd;
1893 :
1894 1864 : lower_username = talloc_strdup(mem_ctx, username);
1895 1864 : if (!lower_username) {
1896 0 : return NT_STATUS_NO_MEMORY;
1897 : }
1898 1864 : if (!strlower_m( lower_username )) {
1899 0 : return NT_STATUS_INVALID_PARAMETER;
1900 : }
1901 :
1902 1864 : orig_dom_user = talloc_asprintf(mem_ctx,
1903 : "%s%c%s",
1904 : domain,
1905 1864 : *lp_winbind_separator(),
1906 : lower_username);
1907 1864 : if (!orig_dom_user) {
1908 0 : return NT_STATUS_NO_MEMORY;
1909 : }
1910 :
1911 : /* Get the passwd struct. Try to create the account if necessary. */
1912 :
1913 1864 : *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1914 1864 : if (!dom_user) {
1915 0 : return NT_STATUS_NO_MEMORY;
1916 : }
1917 :
1918 1864 : passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
1919 1864 : if (!passwd && !*username_was_mapped) {
1920 0 : struct dom_sid_buf buf;
1921 0 : uid_t uid;
1922 0 : bool ok;
1923 :
1924 8 : DBG_DEBUG("Failed to find authenticated user %s via "
1925 : "getpwnam(), fallback to sid_to_uid(%s).\n",
1926 : dom_user, dom_sid_str_buf(sid, &buf));
1927 :
1928 8 : ok = sid_to_uid(sid, &uid);
1929 8 : if (!ok) {
1930 4 : DBG_ERR("Failed to convert SID %s to a UID (dom_user[%s])\n",
1931 : dom_sid_str_buf(sid, &buf), dom_user);
1932 4 : return NT_STATUS_NO_SUCH_USER;
1933 : }
1934 4 : passwd = getpwuid_alloc(mem_ctx, uid);
1935 4 : if (!passwd) {
1936 0 : DBG_ERR("Failed to find local account with UID %lld for SID %s (dom_user[%s])\n",
1937 : (long long)uid,
1938 : dom_sid_str_buf(sid, &buf),
1939 : dom_user);
1940 0 : return NT_STATUS_NO_SUCH_USER;
1941 : }
1942 4 : real_username = talloc_strdup(mem_ctx, passwd->pw_name);
1943 : }
1944 1860 : if (!passwd) {
1945 0 : DEBUG(3, ("Failed to find authenticated user %s via "
1946 : "getpwnam(), denying access.\n", dom_user));
1947 0 : return NT_STATUS_NO_SUCH_USER;
1948 : }
1949 :
1950 1860 : if (!real_username) {
1951 0 : return NT_STATUS_NO_MEMORY;
1952 : }
1953 :
1954 1860 : *pwd = passwd;
1955 :
1956 : /* This is pointless -- there is no support for differing
1957 : unix and windows names. Make sure to always store the
1958 : one we actually looked up and succeeded. Have I mentioned
1959 : why I hate the 'winbind use default domain' parameter?
1960 : --jerry */
1961 :
1962 1860 : *found_username = talloc_strdup( mem_ctx, real_username );
1963 :
1964 1860 : return NT_STATUS_OK;
1965 : }
1966 :
1967 : /****************************************************************************
1968 : Wrapper to allow the getpwnam() call to strip the domain name and
1969 : try again in case a local UNIX user is already there. Also run through
1970 : the username if we fallback to the username only.
1971 : ****************************************************************************/
1972 :
1973 1864 : struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1974 : char **p_save_username, bool create )
1975 : {
1976 1864 : struct passwd *pw = NULL;
1977 1864 : char *p = NULL;
1978 1864 : const char *username = NULL;
1979 :
1980 : /* we only save a copy of the username it has been mangled
1981 : by winbindd use default domain */
1982 1864 : *p_save_username = NULL;
1983 :
1984 : /* don't call map_username() here since it has to be done higher
1985 : up the stack so we don't call it multiple times */
1986 :
1987 1864 : username = talloc_strdup(mem_ctx, domuser);
1988 1864 : if (!username) {
1989 0 : return NULL;
1990 : }
1991 :
1992 1864 : p = strchr_m( username, *lp_winbind_separator() );
1993 :
1994 : /* code for a DOMAIN\user string */
1995 :
1996 1864 : if ( p ) {
1997 1848 : const char *domain = NULL;
1998 :
1999 : /* split the domain and username into 2 strings */
2000 1848 : *p = '\0';
2001 1848 : domain = username;
2002 1848 : p++;
2003 1848 : username = p;
2004 :
2005 1848 : if (strequal(domain, get_global_sam_name())) {
2006 : /*
2007 : * This typically don't happen
2008 : * as check_sam_Security()
2009 : * don't call make_server_info_info3()
2010 : * and thus check_account().
2011 : *
2012 : * But we better keep this.
2013 : */
2014 779 : goto username_only;
2015 : }
2016 :
2017 1069 : pw = Get_Pwnam_alloc( mem_ctx, domuser );
2018 1069 : if (pw == NULL) {
2019 8 : return NULL;
2020 : }
2021 : /* make sure we get the case of the username correct */
2022 : /* work around 'winbind use default domain = yes' */
2023 :
2024 1061 : if ( lp_winbind_use_default_domain() &&
2025 0 : !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
2026 0 : *p_save_username = talloc_asprintf(mem_ctx,
2027 : "%s%c%s",
2028 : domain,
2029 0 : *lp_winbind_separator(),
2030 : pw->pw_name);
2031 0 : if (!*p_save_username) {
2032 0 : TALLOC_FREE(pw);
2033 0 : return NULL;
2034 : }
2035 : } else {
2036 1061 : *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
2037 : }
2038 :
2039 : /* whew -- done! */
2040 1061 : return pw;
2041 :
2042 : }
2043 :
2044 : /* just lookup a plain username */
2045 16 : username_only:
2046 795 : pw = Get_Pwnam_alloc(mem_ctx, username);
2047 :
2048 : /* Create local user if requested but only if winbindd
2049 : is not running. We need to protect against cases
2050 : where winbindd is failing and then prematurely
2051 : creating users in /etc/passwd */
2052 :
2053 795 : if ( !pw && create && !winbind_ping() ) {
2054 : /* Don't add a machine account. */
2055 0 : if (username[strlen(username)-1] == '$')
2056 0 : return NULL;
2057 :
2058 0 : _smb_create_user(NULL, username, NULL);
2059 0 : pw = Get_Pwnam_alloc(mem_ctx, username);
2060 : }
2061 :
2062 : /* one last check for a valid passwd struct */
2063 :
2064 795 : if (pw) {
2065 795 : *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
2066 : }
2067 795 : return pw;
2068 : }
2069 :
2070 : /***************************************************************************
2071 : Make a server_info struct from the info3 returned by a domain logon
2072 : ***************************************************************************/
2073 :
2074 1864 : NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
2075 : const char *sent_nt_username,
2076 : const char *domain,
2077 : struct auth_serversupplied_info **server_info,
2078 : const struct netr_SamInfo3 *info3)
2079 : {
2080 0 : NTSTATUS nt_status;
2081 1864 : char *found_username = NULL;
2082 0 : const char *nt_domain;
2083 0 : const char *nt_username;
2084 0 : struct dom_sid user_sid;
2085 0 : struct dom_sid group_sid;
2086 0 : bool username_was_mapped;
2087 0 : struct passwd *pwd;
2088 0 : struct auth_serversupplied_info *result;
2089 0 : struct dom_sid sid;
2090 1864 : TALLOC_CTX *tmp_ctx = talloc_stackframe();
2091 :
2092 : /*
2093 : Here is where we should check the list of
2094 : trusted domains, and verify that the SID
2095 : matches.
2096 : */
2097 :
2098 1864 : if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
2099 0 : nt_status = NT_STATUS_INVALID_PARAMETER;
2100 0 : goto out;
2101 : }
2102 :
2103 1864 : if (!sid_compose(&group_sid, info3->base.domain_sid,
2104 1864 : info3->base.primary_gid)) {
2105 0 : nt_status = NT_STATUS_INVALID_PARAMETER;
2106 0 : goto out;
2107 : }
2108 :
2109 1864 : nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
2110 1864 : if (!nt_username) {
2111 : /* If the server didn't give us one, just use the one we sent
2112 : * them */
2113 0 : nt_username = sent_nt_username;
2114 : }
2115 :
2116 1864 : nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
2117 1864 : if (!nt_domain) {
2118 : /* If the server didn't give us one, just use the one we sent
2119 : * them */
2120 0 : nt_domain = domain;
2121 : }
2122 :
2123 : /* If getpwnam() fails try the add user script (2.2.x behavior).
2124 :
2125 : We use the _unmapped_ username here in an attempt to provide
2126 : consistent username mapping behavior between kerberos and NTLM[SSP]
2127 : authentication in domain mode security. I.E. Username mapping
2128 : should be applied to the fully qualified username
2129 : (e.g. DOMAIN\user) and not just the login name. Yes this means we
2130 : called map_username() unnecessarily in make_user_info_map() but
2131 : that is how the current code is designed. Making the change here
2132 : is the least disruptive place. -- jerry */
2133 :
2134 : /* this call will try to create the user if necessary */
2135 :
2136 1864 : sid_copy(&sid, info3->base.domain_sid);
2137 1864 : sid_append_rid(&sid, info3->base.rid);
2138 :
2139 1864 : nt_status = check_account(tmp_ctx,
2140 : nt_domain,
2141 : nt_username,
2142 : &sid,
2143 : &found_username,
2144 : &pwd,
2145 : &username_was_mapped);
2146 :
2147 1864 : if (!NT_STATUS_IS_OK(nt_status)) {
2148 : /* Handle 'map to guest = Bad Uid */
2149 8 : if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
2150 8 : (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
2151 4 : lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
2152 0 : DBG_NOTICE("Try to map %s to guest account\n",
2153 : nt_username);
2154 0 : nt_status = make_server_info_guest(tmp_ctx, &result);
2155 0 : if (NT_STATUS_IS_OK(nt_status)) {
2156 0 : *server_info = talloc_move(mem_ctx, &result);
2157 : }
2158 : }
2159 4 : goto out;
2160 1860 : } else if ((lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
2161 1236 : !is_myname(domain) && pwd->pw_uid < lp_min_domain_uid()) {
2162 : /*
2163 : * !is_myname(domain) because when smbd starts tries to setup
2164 : * the guest user info, calling this function with nobody
2165 : * username. Nobody is usually uid 65535 but it can be changed
2166 : * to a regular user with 'guest account' parameter
2167 : */
2168 4 : nt_status = NT_STATUS_INVALID_TOKEN;
2169 4 : DBG_NOTICE("Username '%s%s%s' is invalid on this system, "
2170 : "it does not meet 'min domain uid' "
2171 : "restriction (%u < %u): %s\n",
2172 : nt_domain, lp_winbind_separator(), nt_username,
2173 : pwd->pw_uid, lp_min_domain_uid(),
2174 : nt_errstr(nt_status));
2175 4 : goto out;
2176 : }
2177 :
2178 1856 : result = make_server_info(tmp_ctx);
2179 1856 : if (result == NULL) {
2180 0 : DEBUG(4, ("make_server_info failed!\n"));
2181 0 : nt_status = NT_STATUS_NO_MEMORY;
2182 0 : goto out;
2183 : }
2184 :
2185 1856 : result->unix_name = talloc_strdup(result, found_username);
2186 :
2187 : /* copy in the info3 */
2188 1856 : nt_status = copy_netr_SamInfo3(result,
2189 : info3,
2190 1856 : &result->info3);
2191 1856 : if (!NT_STATUS_IS_OK(nt_status)) {
2192 0 : goto out;
2193 : }
2194 :
2195 : /* Fill in the unix info we found on the way */
2196 :
2197 1856 : result->utok.uid = pwd->pw_uid;
2198 1856 : result->utok.gid = pwd->pw_gid;
2199 :
2200 : /* ensure we are never given NULL session keys */
2201 :
2202 1856 : if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
2203 1635 : result->session_key = data_blob_null;
2204 : } else {
2205 221 : result->session_key = data_blob_talloc(
2206 : result, info3->base.key.key,
2207 : sizeof(info3->base.key.key));
2208 : }
2209 :
2210 1856 : if (all_zero(info3->base.LMSessKey.key,
2211 : sizeof(info3->base.LMSessKey.key))) {
2212 1640 : result->lm_session_key = data_blob_null;
2213 : } else {
2214 216 : result->lm_session_key = data_blob_talloc(
2215 : result, info3->base.LMSessKey.key,
2216 : sizeof(info3->base.LMSessKey.key));
2217 : }
2218 :
2219 1856 : result->nss_token |= username_was_mapped;
2220 :
2221 1856 : result->guest = (info3->base.user_flags & NETLOGON_GUEST);
2222 :
2223 1856 : *server_info = talloc_move(mem_ctx, &result);
2224 :
2225 1856 : nt_status = NT_STATUS_OK;
2226 1864 : out:
2227 1864 : talloc_free(tmp_ctx);
2228 :
2229 1864 : return nt_status;
2230 : }
2231 :
2232 : /*****************************************************************************
2233 : Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
2234 : ******************************************************************************/
2235 :
2236 1085 : NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
2237 : const char *sent_nt_username,
2238 : const char *domain,
2239 : const struct wbcAuthUserInfo *info,
2240 : struct auth_serversupplied_info **server_info)
2241 : {
2242 0 : struct netr_SamInfo3 info3;
2243 0 : struct netr_SamInfo6 *info6;
2244 :
2245 1085 : info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
2246 1085 : if (!info6) {
2247 0 : return NT_STATUS_NO_MEMORY;
2248 : }
2249 :
2250 1085 : info3.base = info6->base;
2251 1085 : info3.sidcount = info6->sidcount;
2252 1085 : info3.sids = info6->sids;
2253 :
2254 1085 : return make_server_info_info3(mem_ctx,
2255 : sent_nt_username, domain,
2256 : server_info, &info3);
2257 : }
2258 :
2259 : /**
2260 : * Verify whether or not given domain is trusted.
2261 : *
2262 : * This should only be used on a DC.
2263 : *
2264 : * @param domain_name name of the domain to be verified
2265 : * @return true if domain is one of the trusted ones or
2266 : * false if otherwise
2267 : **/
2268 :
2269 24 : bool is_trusted_domain(const char* dom_name)
2270 : {
2271 0 : bool ret;
2272 :
2273 24 : if (!IS_DC) {
2274 0 : return false;
2275 : }
2276 :
2277 24 : if (dom_name == NULL || dom_name[0] == '\0') {
2278 0 : return false;
2279 : }
2280 :
2281 24 : if (strequal(dom_name, get_global_sam_name())) {
2282 24 : return false;
2283 : }
2284 :
2285 0 : become_root();
2286 0 : DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2287 : "[%s]\n", dom_name ));
2288 0 : ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2289 0 : unbecome_root();
2290 :
2291 0 : return ret;
2292 : }
2293 :
2294 :
2295 :
2296 : /*
2297 : on a logon error possibly map the error to success if "map to guest"
2298 : is set appropriately
2299 : */
2300 3110 : NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
2301 : NTSTATUS status,
2302 : const char *user,
2303 : const char *domain,
2304 : struct auth_serversupplied_info **server_info)
2305 : {
2306 3110 : user = user ? user : "";
2307 3110 : domain = domain ? domain : "";
2308 :
2309 3110 : if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
2310 5841 : if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
2311 2906 : (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
2312 29 : DEBUG(3,("No such user %s [%s] - using guest account\n",
2313 : user, domain));
2314 29 : return make_server_info_guest(mem_ctx, server_info);
2315 : }
2316 175 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2317 166 : if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
2318 0 : DEBUG(3,("Registered username %s for guest access\n",
2319 : user));
2320 0 : return make_server_info_guest(mem_ctx, server_info);
2321 : }
2322 : }
2323 :
2324 3081 : return status;
2325 : }
2326 :
2327 : /*
2328 : Extract session key from a session info and return it in a blob
2329 : if intent is KEY_USE_16BYTES, truncate it to 16 bytes
2330 :
2331 : See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
2332 : Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
2333 :
2334 : Note that returned session_key is referencing the original key, it is supposed to be
2335 : short-lived. If original session_info->session_key is gone, the reference will be broken.
2336 : */
2337 137 : NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
2338 : {
2339 :
2340 137 : if (session_key == NULL || session_info == NULL) {
2341 0 : return NT_STATUS_INVALID_PARAMETER;
2342 : }
2343 :
2344 137 : if (session_info->session_key.length == 0) {
2345 0 : return NT_STATUS_NO_USER_SESSION_KEY;
2346 : }
2347 :
2348 137 : *session_key = session_info->session_key;
2349 137 : if (intent == KEY_USE_16BYTES) {
2350 137 : session_key->length = MIN(session_info->session_key.length, 16);
2351 : }
2352 137 : return NT_STATUS_OK;
2353 : }
|