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