Line data Source code
1 : /*
2 : Unix SMB/Netbios implementation.
3 : Version 3.0
4 : handle GENSEC authentication, server side
5 :
6 : Copyright (C) Andrew Tridgell 2001
7 : Copyright (C) Andrew Bartlett 2001-2003,2011
8 : Copyright (C) Simo Sorce 2010.
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 <tevent.h>
26 : #include "../lib/util/tevent_ntstatus.h"
27 : #include "auth.h"
28 : #include "../lib/tsocket/tsocket.h"
29 : #include "auth/gensec/gensec.h"
30 : #include "lib/param/param.h"
31 : #ifdef HAVE_KRB5
32 : #include "auth/kerberos/pac_utils.h"
33 : #include "nsswitch/libwbclient/wbclient.h"
34 : #endif
35 : #include "librpc/crypto/gse.h"
36 : #include "auth/credentials/credentials.h"
37 : #include "lib/param/loadparm.h"
38 : #include "librpc/gen_ndr/dcerpc.h"
39 : #include "source3/lib/substitute.h"
40 :
41 863 : static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
42 : TALLOC_CTX *mem_ctx,
43 : struct smb_krb5_context *smb_krb5_context,
44 : DATA_BLOB *pac_blob,
45 : const char *princ_name,
46 : const struct tsocket_address *remote_address,
47 : uint32_t session_info_flags,
48 : struct auth_session_info **session_info)
49 : {
50 863 : enum server_role server_role = lp_server_role();
51 0 : TALLOC_CTX *tmp_ctx;
52 0 : bool is_mapped;
53 0 : bool is_guest;
54 0 : char *ntuser;
55 0 : char *ntdomain;
56 0 : char *username;
57 0 : const char *rhost;
58 0 : struct passwd *pw;
59 0 : NTSTATUS status;
60 :
61 863 : tmp_ctx = talloc_new(mem_ctx);
62 863 : if (!tmp_ctx) {
63 0 : return NT_STATUS_NO_MEMORY;
64 : }
65 :
66 863 : if (tsocket_address_is_inet(remote_address, "ip")) {
67 863 : rhost = tsocket_address_inet_addr_string(
68 : remote_address, tmp_ctx);
69 863 : if (rhost == NULL) {
70 0 : status = NT_STATUS_NO_MEMORY;
71 0 : goto done;
72 : }
73 : } else {
74 0 : rhost = "127.0.0.1";
75 : }
76 :
77 863 : if (server_role != ROLE_STANDALONE) {
78 863 : struct wbcAuthUserParams params = { 0 };
79 863 : struct wbcAuthUserInfo *info = NULL;
80 863 : struct wbcAuthErrorInfo *err = NULL;
81 863 : struct auth_serversupplied_info *server_info = NULL;
82 863 : char *original_user_name = NULL;
83 863 : char *p = NULL;
84 0 : wbcErr wbc_err;
85 :
86 863 : if (pac_blob == NULL) {
87 : /*
88 : * This should already be caught at the main
89 : * gensec layer, but better check twice
90 : */
91 0 : status = NT_STATUS_INTERNAL_ERROR;
92 0 : goto done;
93 : }
94 :
95 : /*
96 : * Let winbind decode the PAC.
97 : * This will also store the user
98 : * data in the netsamlogon cache.
99 : *
100 : * This used to be a cache prime
101 : * optimization, but now we delegate
102 : * all logic to winbindd, as we require
103 : * winbindd as domain member anyway.
104 : */
105 863 : params.level = WBC_AUTH_USER_LEVEL_PAC;
106 863 : params.password.pac.data = pac_blob->data;
107 863 : params.password.pac.length = pac_blob->length;
108 :
109 : /* we are contacting the privileged pipe */
110 863 : become_root();
111 863 : wbc_err = wbcAuthenticateUserEx(¶ms, &info, &err);
112 863 : unbecome_root();
113 :
114 : /*
115 : * As this is merely a cache prime
116 : * WBC_ERR_WINBIND_NOT_AVAILABLE
117 : * is not a fatal error, treat it
118 : * as success.
119 : */
120 :
121 863 : switch (wbc_err) {
122 861 : case WBC_ERR_SUCCESS:
123 861 : break;
124 0 : case WBC_ERR_WINBIND_NOT_AVAILABLE:
125 0 : status = NT_STATUS_NO_LOGON_SERVERS;
126 0 : DBG_ERR("winbindd not running - "
127 : "but required as domain member: %s\n",
128 : nt_errstr(status));
129 2 : goto done;
130 2 : case WBC_ERR_AUTH_ERROR:
131 2 : status = NT_STATUS(err->nt_status);
132 2 : wbcFreeMemory(err);
133 2 : goto done;
134 0 : case WBC_ERR_NO_MEMORY:
135 0 : status = NT_STATUS_NO_MEMORY;
136 0 : goto done;
137 0 : default:
138 0 : status = NT_STATUS_LOGON_FAILURE;
139 0 : goto done;
140 : }
141 :
142 861 : status = make_server_info_wbcAuthUserInfo(tmp_ctx,
143 861 : info->account_name,
144 861 : info->domain_name,
145 : info, &server_info);
146 861 : wbcFreeMemory(info);
147 861 : if (!NT_STATUS_IS_OK(status)) {
148 4 : DEBUG(10, ("make_server_info_wbcAuthUserInfo failed: %s\n",
149 : nt_errstr(status)));
150 4 : goto done;
151 : }
152 :
153 : /* We skip doing this step if the caller asked us not to */
154 857 : if (!(server_info->guest)) {
155 857 : const char *unix_username = server_info->unix_name;
156 :
157 : /* We might not be root if we are an RPC call */
158 857 : become_root();
159 857 : status = smb_pam_accountcheck(unix_username, rhost);
160 857 : unbecome_root();
161 :
162 857 : if (!NT_STATUS_IS_OK(status)) {
163 0 : DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] "
164 : "FAILED with error %s\n",
165 : unix_username, nt_errstr(status)));
166 0 : goto done;
167 : }
168 :
169 857 : DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] "
170 : "succeeded\n", unix_username));
171 : }
172 :
173 857 : DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
174 :
175 857 : p = strchr_m(princ_name, '@');
176 857 : if (!p) {
177 0 : DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
178 : princ_name));
179 0 : status = NT_STATUS_LOGON_FAILURE;
180 0 : goto done;
181 : }
182 :
183 857 : original_user_name = talloc_strndup(tmp_ctx, princ_name, p - princ_name);
184 857 : if (original_user_name == NULL) {
185 0 : status = NT_STATUS_NO_MEMORY;
186 0 : goto done;
187 : }
188 :
189 857 : status = create_local_token(mem_ctx,
190 : server_info,
191 : NULL,
192 : original_user_name,
193 : session_info);
194 857 : if (!NT_STATUS_IS_OK(status)) {
195 0 : DEBUG(10, ("create_local_token failed: %s\n",
196 : nt_errstr(status)));
197 0 : goto done;
198 : }
199 :
200 857 : goto session_info_ready;
201 : }
202 :
203 : /* This is the standalone legacy code path */
204 :
205 0 : if (pac_blob != NULL) {
206 : /*
207 : * In standalone mode we don't expect a PAC!
208 : * we only support MIT realms
209 : */
210 0 : status = NT_STATUS_BAD_TOKEN_TYPE;
211 0 : DBG_WARNING("Unexpected PAC for [%s] in standalone mode - %s\n",
212 : princ_name, nt_errstr(status));
213 0 : if (!NT_STATUS_IS_OK(status)) {
214 0 : goto done;
215 : }
216 : }
217 :
218 0 : status = get_user_from_kerberos_info(tmp_ctx, rhost,
219 : princ_name,
220 : &is_mapped, &is_guest,
221 : &ntuser, &ntdomain,
222 : &username, &pw);
223 0 : if (!NT_STATUS_IS_OK(status)) {
224 0 : DBG_NOTICE("Failed to map kerberos principal to system user "
225 : "(%s)\n", nt_errstr(status));
226 0 : status = NT_STATUS_ACCESS_DENIED;
227 0 : goto done;
228 : }
229 :
230 0 : status = make_session_info_krb5(mem_ctx,
231 : ntuser, ntdomain, username, pw,
232 : is_guest, is_mapped,
233 : session_info);
234 0 : if (!NT_STATUS_IS_OK(status)) {
235 0 : DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
236 : nt_errstr(status)));
237 0 : status = nt_status_squash(status);
238 0 : goto done;
239 : }
240 :
241 0 : session_info_ready:
242 :
243 : /* setup the string used by %U */
244 857 : set_current_user_info((*session_info)->unix_info->sanitized_username,
245 857 : (*session_info)->unix_info->unix_name,
246 857 : (*session_info)->info->domain_name);
247 :
248 : /* reload services so that the new %U is taken into account */
249 857 : lp_load_with_shares(get_dyn_CONFIGFILE());
250 :
251 857 : DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
252 : (*session_info)->info->account_name,
253 : (*session_info)->info->domain_name,
254 : rhost));
255 :
256 857 : status = NT_STATUS_OK;
257 :
258 863 : done:
259 863 : TALLOC_FREE(tmp_ctx);
260 863 : return status;
261 : }
262 :
263 76987 : static struct auth4_context *make_auth4_context_s3(TALLOC_CTX *mem_ctx, struct auth_context *auth_context)
264 : {
265 76987 : struct auth4_context *auth4_context = talloc_zero(mem_ctx, struct auth4_context);
266 76987 : if (auth4_context == NULL) {
267 0 : DEBUG(10, ("failed to allocate auth4_context failed\n"));
268 0 : return NULL;
269 : }
270 76987 : auth4_context->generate_session_info_pac = auth3_generate_session_info_pac;
271 76987 : auth4_context->generate_session_info = auth3_generate_session_info;
272 76987 : auth4_context->get_ntlm_challenge = auth3_get_challenge;
273 76987 : auth4_context->set_ntlm_challenge = auth3_set_challenge;
274 76987 : auth4_context->check_ntlm_password_send = auth3_check_password_send;
275 76987 : auth4_context->check_ntlm_password_recv = auth3_check_password_recv;
276 76987 : auth4_context->private_data = talloc_steal(auth4_context, auth_context);
277 76987 : return auth4_context;
278 : }
279 :
280 34115 : NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context_out)
281 : {
282 0 : struct auth_context *auth_context;
283 0 : NTSTATUS nt_status;
284 :
285 34115 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
286 34115 : NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
287 :
288 34115 : nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
289 34115 : if (!NT_STATUS_IS_OK(nt_status)) {
290 0 : TALLOC_FREE(tmp_ctx);
291 0 : return nt_status;
292 : }
293 :
294 34115 : if (auth_context->make_auth4_context) {
295 15458 : nt_status = auth_context->make_auth4_context(auth_context, mem_ctx, auth4_context_out);
296 15458 : TALLOC_FREE(tmp_ctx);
297 15458 : return nt_status;
298 :
299 : } else {
300 18657 : struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
301 18657 : if (auth4_context == NULL) {
302 0 : TALLOC_FREE(tmp_ctx);
303 0 : return NT_STATUS_NO_MEMORY;
304 : }
305 18657 : *auth4_context_out = talloc_steal(mem_ctx, auth4_context);
306 18657 : TALLOC_FREE(tmp_ctx);
307 18657 : return NT_STATUS_OK;
308 : }
309 : }
310 :
311 82272 : NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
312 : const struct tsocket_address *remote_address,
313 : const struct tsocket_address *local_address,
314 : const char *service_description,
315 : struct gensec_security **gensec_security_out)
316 : {
317 2087 : struct gensec_security *gensec_security;
318 82272 : struct auth_context *auth_context = NULL;
319 2087 : NTSTATUS nt_status;
320 :
321 82272 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
322 82272 : NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
323 :
324 82272 : nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
325 82272 : if (!NT_STATUS_IS_OK(nt_status)) {
326 0 : goto done;
327 : }
328 :
329 82272 : if (auth_context->prepare_gensec) {
330 23942 : nt_status = auth_context->prepare_gensec(auth_context, tmp_ctx,
331 : &gensec_security);
332 23942 : if (!NT_STATUS_IS_OK(nt_status)) {
333 0 : goto done;
334 : }
335 : } else {
336 58330 : const struct gensec_security_ops **backends = NULL;
337 0 : struct gensec_settings *gensec_settings;
338 0 : struct loadparm_context *lp_ctx;
339 58330 : size_t idx = 0;
340 0 : struct cli_credentials *server_credentials;
341 0 : const char *dns_name;
342 0 : const char *dns_domain;
343 0 : bool ok;
344 58330 : struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
345 58330 : if (auth4_context == NULL) {
346 0 : goto nomem;
347 : }
348 :
349 58330 : lp_ctx = loadparm_init_s3(tmp_ctx, loadparm_s3_helpers());
350 58330 : if (lp_ctx == NULL) {
351 0 : DEBUG(10, ("loadparm_init_s3 failed\n"));
352 0 : nt_status = NT_STATUS_INVALID_SERVER_STATE;
353 0 : goto done;
354 : }
355 :
356 58330 : gensec_settings = lpcfg_gensec_settings(tmp_ctx, lp_ctx);
357 58330 : if (lp_ctx == NULL) {
358 0 : DEBUG(10, ("lpcfg_gensec_settings failed\n"));
359 0 : goto nomem;
360 : }
361 :
362 : /*
363 : * This should be a 'netbios domain -> DNS domain'
364 : * mapping, and can currently validly return NULL on
365 : * poorly configured systems.
366 : *
367 : * This is used for the NTLMSSP server
368 : *
369 : */
370 58330 : dns_name = get_mydnsfullname();
371 58330 : if (dns_name == NULL) {
372 0 : dns_name = "";
373 : }
374 :
375 58330 : dns_domain = get_mydnsdomname(tmp_ctx);
376 58330 : if (dns_domain == NULL) {
377 0 : dns_domain = "";
378 : }
379 :
380 58330 : gensec_settings->server_dns_name = strlower_talloc(gensec_settings, dns_name);
381 58330 : if (gensec_settings->server_dns_name == NULL) {
382 0 : goto nomem;
383 : }
384 :
385 58330 : gensec_settings->server_dns_domain = strlower_talloc(gensec_settings, dns_domain);
386 58330 : if (gensec_settings->server_dns_domain == NULL) {
387 0 : goto nomem;
388 : }
389 :
390 58330 : backends = talloc_zero_array(gensec_settings,
391 : const struct gensec_security_ops *, 6);
392 58330 : if (backends == NULL) {
393 0 : goto nomem;
394 : }
395 58330 : gensec_settings->backends = backends;
396 :
397 58330 : gensec_init();
398 :
399 : /* These need to be in priority order, krb5 before NTLMSSP */
400 : #if defined(HAVE_KRB5)
401 58330 : backends[idx++] = &gensec_gse_krb5_security_ops;
402 : #endif
403 :
404 58330 : backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP);
405 :
406 58330 : backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO);
407 :
408 58330 : backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_SCHANNEL);
409 :
410 58330 : backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM);
411 :
412 : /*
413 : * This is anonymous for now, because we just use it
414 : * to set the kerberos state at the moment
415 : */
416 58330 : server_credentials = cli_credentials_init_anon(tmp_ctx);
417 58330 : if (!server_credentials) {
418 0 : DEBUG(0, ("auth_generic_prepare: Failed to init server credentials\n"));
419 0 : goto nomem;
420 : }
421 :
422 58330 : ok = cli_credentials_set_conf(server_credentials, lp_ctx);
423 58330 : if (!ok) {
424 0 : DBG_ERR("Failed to set server credentials defaults "
425 : "from smb.conf.\n");
426 0 : goto nomem;
427 : }
428 :
429 58330 : if (lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) {
430 4431 : cli_credentials_set_kerberos_state(server_credentials,
431 : CRED_USE_KERBEROS_DESIRED,
432 : CRED_SPECIFIED);
433 : } else {
434 53899 : cli_credentials_set_kerberos_state(server_credentials,
435 : CRED_USE_KERBEROS_DISABLED,
436 : CRED_SPECIFIED);
437 : }
438 :
439 58330 : nt_status = gensec_server_start(tmp_ctx, gensec_settings,
440 : auth4_context, &gensec_security);
441 :
442 58330 : if (!NT_STATUS_IS_OK(nt_status)) {
443 0 : goto done;
444 : }
445 :
446 58330 : nt_status = gensec_set_credentials(
447 : gensec_security, server_credentials);
448 58330 : if (!NT_STATUS_IS_OK(nt_status)) {
449 0 : goto done;
450 : }
451 : }
452 :
453 82272 : nt_status = gensec_set_remote_address(gensec_security,
454 : remote_address);
455 82272 : if (!NT_STATUS_IS_OK(nt_status)) {
456 0 : goto done;
457 : }
458 :
459 82272 : nt_status = gensec_set_local_address(gensec_security,
460 : local_address);
461 82272 : if (!NT_STATUS_IS_OK(nt_status)) {
462 0 : goto done;
463 : }
464 :
465 82272 : nt_status = gensec_set_target_service_description(gensec_security,
466 : service_description);
467 82272 : if (!NT_STATUS_IS_OK(nt_status)) {
468 0 : goto done;
469 : }
470 :
471 82272 : *gensec_security_out = talloc_move(mem_ctx, &gensec_security);
472 82272 : nt_status = NT_STATUS_OK;
473 82272 : goto done;
474 0 : nomem:
475 0 : nt_status = NT_STATUS_NO_MEMORY;
476 82272 : done:
477 82272 : TALLOC_FREE(tmp_ctx);
478 82272 : return nt_status;
479 : }
480 :
481 : /*
482 : * Check a username and password, and return the final session_info.
483 : * We also log the authorization of the session here, just as
484 : * gensec_session_info() does.
485 : */
486 98 : NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
487 : TALLOC_CTX *mem_ctx,
488 : struct auth_usersupplied_info *user_info,
489 : struct auth_session_info **session_info)
490 : {
491 0 : NTSTATUS nt_status;
492 0 : void *server_info;
493 98 : uint8_t authoritative = 1;
494 98 : struct tevent_context *ev = NULL;
495 98 : struct tevent_req *subreq = NULL;
496 0 : bool ok;
497 :
498 98 : ev = samba_tevent_context_init(talloc_tos());
499 98 : if (ev == NULL) {
500 0 : return NT_STATUS_NO_MEMORY;
501 : }
502 :
503 98 : subreq = auth_context->check_ntlm_password_send(ev, ev,
504 : auth_context,
505 : user_info);
506 98 : if (subreq == NULL) {
507 0 : TALLOC_FREE(ev);
508 0 : return NT_STATUS_NO_MEMORY;
509 : }
510 98 : ok = tevent_req_poll_ntstatus(subreq, ev, &nt_status);
511 98 : if (!ok) {
512 0 : TALLOC_FREE(ev);
513 0 : return nt_status;
514 : }
515 98 : nt_status = auth_context->check_ntlm_password_recv(subreq,
516 : talloc_tos(),
517 : &authoritative,
518 : &server_info,
519 : NULL, NULL);
520 98 : TALLOC_FREE(ev);
521 98 : if (!NT_STATUS_IS_OK(nt_status)) {
522 2 : return nt_status;
523 : }
524 :
525 96 : nt_status = auth_context->generate_session_info(auth_context,
526 : mem_ctx,
527 : server_info,
528 : user_info->client.account_name,
529 : AUTH_SESSION_INFO_UNIX_TOKEN |
530 : AUTH_SESSION_INFO_DEFAULT_GROUPS |
531 : AUTH_SESSION_INFO_NTLM,
532 : session_info);
533 96 : TALLOC_FREE(server_info);
534 :
535 96 : if (!NT_STATUS_IS_OK(nt_status)) {
536 0 : return nt_status;
537 : }
538 :
539 : /*
540 : * This is rather redundant (the authentication has just been
541 : * logged, with much the same details), but because we want to
542 : * log all authorizations consistently (be they NLTM, NTLMSSP
543 : * or krb5) we log this info again as an authorization.
544 : */
545 96 : log_successful_authz_event(auth_context->msg_ctx,
546 : auth_context->lp_ctx,
547 : user_info->remote_host,
548 : user_info->local_host,
549 : user_info->service_description,
550 : user_info->auth_description,
551 : AUTHZ_TRANSPORT_PROTECTION_SMB,
552 : *session_info,
553 : NULL /* client_audit_info */,
554 : NULL /* server_audit_info */);
555 :
556 96 : return nt_status;
557 : }
|