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