Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Password and authentication handling
4 : Copyright (C) Andrew Bartlett 2001-2002
5 : Copyright (C) Stefan Metzmacher 2005
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "includes.h"
22 : #include <tevent.h>
23 : #include "../lib/util/tevent_ntstatus.h"
24 : #include "../lib/util/dlinklist.h"
25 : #include "auth/auth.h"
26 : #include "auth/ntlm/auth_proto.h"
27 : #include "param/param.h"
28 : #include "dsdb/samdb/samdb.h"
29 : #include "libcli/wbclient/wbclient.h"
30 : #include "lib/util/samba_modules.h"
31 : #include "auth/credentials/credentials.h"
32 : #include "system/kerberos.h"
33 : #include "auth/kerberos/kerberos.h"
34 : #include "auth/kerberos/kerberos_util.h"
35 : #include "libds/common/roles.h"
36 :
37 : #undef DBGC_CLASS
38 : #define DBGC_CLASS DBGC_AUTH
39 :
40 : static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_context,
41 : TALLOC_CTX *mem_ctx,
42 : void *server_returned_info,
43 : const char *original_user_name,
44 : uint32_t session_info_flags,
45 : struct auth_session_info **session_info);
46 :
47 : /***************************************************************************
48 : Set a fixed challenge
49 : ***************************************************************************/
50 14136 : _PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by)
51 : {
52 14136 : auth_ctx->challenge.set_by = talloc_strdup(auth_ctx, set_by);
53 14136 : NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.set_by);
54 :
55 14136 : auth_ctx->challenge.data = data_blob_talloc(auth_ctx, chal, 8);
56 14136 : NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data);
57 :
58 14136 : return NT_STATUS_OK;
59 : }
60 :
61 : /****************************************************************************
62 : Try to get a challenge out of the various authentication modules.
63 : Returns a const char of length 8 bytes.
64 : ****************************************************************************/
65 44714 : _PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8])
66 : {
67 :
68 44714 : if (auth_ctx->challenge.data.length == 8) {
69 29536 : DEBUG(5, ("auth_get_challenge: returning previous challenge by module %s (normal)\n",
70 : auth_ctx->challenge.set_by));
71 29536 : memcpy(chal, auth_ctx->challenge.data.data, 8);
72 29536 : return NT_STATUS_OK;
73 : }
74 :
75 15178 : if (!auth_ctx->challenge.set_by) {
76 15178 : generate_random_buffer(chal, 8);
77 :
78 15178 : auth_ctx->challenge.data = data_blob_talloc(auth_ctx, chal, 8);
79 15178 : NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data);
80 15178 : auth_ctx->challenge.set_by = "random";
81 : }
82 :
83 15178 : DEBUG(10,("auth_get_challenge: challenge set by %s\n",
84 : auth_ctx->challenge.set_by));
85 :
86 15178 : return NT_STATUS_OK;
87 : }
88 :
89 : /**
90 : * Check a user's Plaintext, LM or NTLM password.
91 : * (sync version)
92 : *
93 : * Check a user's password, as given in the user_info struct and return various
94 : * interesting details in the user_info_dc struct.
95 : *
96 : * The return value takes precedence over the contents of the user_info_dc
97 : * struct. When the return is other than NT_STATUS_OK the contents
98 : * of that structure is undefined.
99 : *
100 : * @param auth_ctx Supplies the challenges and some other data.
101 : * Must be created with auth_context_create(), and the challenges should be
102 : * filled in, either at creation or by calling the challenge generation
103 : * function auth_get_challenge().
104 : *
105 : * @param user_info Contains the user supplied components, including the passwords.
106 : *
107 : * @param mem_ctx The parent memory context for the user_info_dc structure
108 : *
109 : * @param user_info_dc If successful, contains information about the authentication,
110 : * including a SAM_ACCOUNT struct describing the user.
111 : *
112 : * @return An NTSTATUS with NT_STATUS_OK or an appropriate error.
113 : *
114 : **/
115 :
116 1 : _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
117 : TALLOC_CTX *mem_ctx,
118 : const struct auth_usersupplied_info *user_info,
119 : struct auth_user_info_dc **user_info_dc,
120 : uint8_t *pauthoritative)
121 : {
122 0 : struct tevent_req *subreq;
123 0 : struct tevent_context *ev;
124 0 : bool ok;
125 0 : NTSTATUS status;
126 :
127 : /*TODO: create a new event context here! */
128 1 : ev = auth_ctx->event_ctx;
129 :
130 : /*
131 : * We are authoritative by default
132 : */
133 1 : *pauthoritative = 1;
134 :
135 1 : subreq = auth_check_password_send(mem_ctx,
136 : ev,
137 : auth_ctx,
138 : user_info);
139 1 : if (subreq == NULL) {
140 0 : return NT_STATUS_NO_MEMORY;
141 : }
142 :
143 1 : ok = tevent_req_poll(subreq, ev);
144 1 : if (!ok) {
145 0 : return NT_STATUS_INTERNAL_ERROR;
146 : }
147 :
148 1 : status = auth_check_password_recv(subreq, mem_ctx,
149 : user_info_dc, pauthoritative);
150 1 : TALLOC_FREE(subreq);
151 :
152 1 : return status;
153 : }
154 :
155 : struct auth_check_password_state {
156 : struct tevent_context *ev;
157 : struct auth4_context *auth_ctx;
158 : const struct auth_usersupplied_info *user_info;
159 : struct auth_user_info_dc *user_info_dc;
160 : struct auth_method_context *method;
161 : const struct authn_audit_info *client_audit_info;
162 : const struct authn_audit_info *server_audit_info;
163 : uint8_t authoritative;
164 : };
165 :
166 : static void auth_check_password_next(struct tevent_req *req);
167 :
168 : /**
169 : * Check a user's Plaintext, LM or NTLM password.
170 : * async send hook
171 : *
172 : * Check a user's password, as given in the user_info struct and return various
173 : * interesting details in the user_info_dc struct.
174 : *
175 : * The return value takes precedence over the contents of the user_info_dc
176 : * struct. When the return is other than NT_STATUS_OK the contents
177 : * of that structure is undefined.
178 : *
179 : * @param mem_ctx The memory context the request should operate on
180 : *
181 : * @param ev The tevent context the request should operate on
182 : *
183 : * @param auth_ctx Supplies the challenges and some other data. Must
184 : * be created with make_auth_context(), and the
185 : * challenges should be filled in, either at creation
186 : * or by calling the challenge generation function
187 : * auth_get_challenge().
188 : *
189 : * @param user_info Contains the user supplied components, including the passwords.
190 : *
191 : * @return The request handle or NULL on no memory error.
192 : *
193 : **/
194 :
195 29195 : _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
196 : struct tevent_context *ev,
197 : struct auth4_context *auth_ctx,
198 : const struct auth_usersupplied_info *user_info)
199 : {
200 1420 : struct tevent_req *req;
201 1420 : struct auth_check_password_state *state;
202 : /* if all the modules say 'not for me' this is reasonable */
203 1420 : NTSTATUS nt_status;
204 1420 : uint8_t chal[8];
205 :
206 29195 : DEBUG(3,("auth_check_password_send: "
207 : "Checking password for unmapped user [%s]\\[%s]@[%s]\n",
208 : user_info->client.domain_name, user_info->client.account_name,
209 : user_info->workstation_name));
210 :
211 29195 : req = tevent_req_create(mem_ctx, &state,
212 : struct auth_check_password_state);
213 29195 : if (req == NULL) {
214 0 : return NULL;
215 : }
216 :
217 : /*
218 : * We are authoritative by default.
219 : */
220 29195 : state->ev = ev;
221 29195 : state->auth_ctx = auth_ctx;
222 29195 : state->user_info = user_info;
223 29195 : state->authoritative = 1;
224 :
225 29195 : if (user_info->mapped.account_name == NULL) {
226 1420 : struct auth_usersupplied_info *user_info_tmp;
227 :
228 : /*
229 : * We don't really do any mapping here.
230 : *
231 : * It's up to the backends to do mappings
232 : * for their authentication.
233 : */
234 29181 : user_info_tmp = talloc_zero(state, struct auth_usersupplied_info);
235 29181 : if (tevent_req_nomem(user_info_tmp, req)) {
236 0 : return tevent_req_post(req, ev);
237 : }
238 :
239 : /*
240 : * The lifetime of user_info is longer than
241 : * user_info_tmp, so we don't need to copy the
242 : * strings.
243 : */
244 29181 : *user_info_tmp = *user_info;
245 29181 : user_info_tmp->mapped.domain_name = user_info->client.domain_name;
246 29181 : user_info_tmp->mapped.account_name = user_info->client.account_name;
247 :
248 29181 : user_info = user_info_tmp;
249 29181 : state->user_info = user_info_tmp;
250 : }
251 :
252 29195 : DEBUGADD(3,("auth_check_password_send: "
253 : "user is: [%s]\\[%s]@[%s]\n",
254 : user_info->mapped.domain_name,
255 : user_info->mapped.account_name,
256 : user_info->workstation_name));
257 :
258 29195 : nt_status = auth_get_challenge(auth_ctx, chal);
259 29195 : if (tevent_req_nterror(req, nt_status)) {
260 0 : DEBUG(0,("auth_check_password_send: "
261 : "Invalid challenge (length %u) stored for "
262 : "this auth context set_by %s - cannot continue: %s\n",
263 : (unsigned)auth_ctx->challenge.data.length,
264 : auth_ctx->challenge.set_by,
265 : nt_errstr(nt_status)));
266 0 : return tevent_req_post(req, ev);
267 : }
268 :
269 29195 : if (auth_ctx->challenge.set_by) {
270 29195 : DEBUG(10,("auth_check_password_send: "
271 : "auth_context challenge created by %s\n",
272 : auth_ctx->challenge.set_by));
273 : }
274 :
275 29195 : DEBUG(10, ("auth_check_password_send: challenge is: \n"));
276 29195 : dump_data(5, auth_ctx->challenge.data.data,
277 29195 : auth_ctx->challenge.data.length);
278 :
279 29195 : state->method = state->auth_ctx->methods;
280 29195 : auth_check_password_next(req);
281 29195 : if (!tevent_req_is_in_progress(req)) {
282 14 : return tevent_req_post(req, ev);
283 : }
284 :
285 27761 : return req;
286 : }
287 :
288 : static void auth_check_password_done(struct tevent_req *subreq);
289 :
290 45692 : static void auth_check_password_next(struct tevent_req *req)
291 : {
292 1568 : struct auth_check_password_state *state =
293 45834 : tevent_req_data(req, struct auth_check_password_state);
294 45834 : struct tevent_req *subreq = NULL;
295 1568 : NTSTATUS status;
296 :
297 45834 : if (state->method == NULL) {
298 52 : state->authoritative = 0;
299 52 : tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
300 52 : return;
301 : }
302 :
303 : /* check if the module wants to check the password */
304 45782 : status = state->method->ops->want_check(state->method, state,
305 : state->user_info);
306 45782 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
307 15283 : DEBUG(11,("auth_check_password_send: "
308 : "%s doesn't want to check\n",
309 : state->method->ops->name));
310 15283 : state->method = state->method->next;
311 15283 : auth_check_password_next(req);
312 15141 : return;
313 : }
314 :
315 30499 : if (tevent_req_nterror(req, status)) {
316 0 : return;
317 : }
318 :
319 30499 : subreq = state->method->ops->check_password_send(
320 : state, state->ev, state->method, state->user_info);
321 30499 : if (tevent_req_nomem(subreq, req)) {
322 0 : return;
323 : }
324 30499 : tevent_req_set_callback(subreq, auth_check_password_done, req);
325 : }
326 :
327 30499 : static void auth_check_password_done(struct tevent_req *subreq)
328 : {
329 1426 : struct tevent_req *req =
330 30499 : tevent_req_callback_data(subreq,
331 : struct tevent_req);
332 1426 : struct auth_check_password_state *state =
333 30499 : tevent_req_data(req,
334 : struct auth_check_password_state);
335 30499 : bool authoritative = true;
336 1426 : NTSTATUS status;
337 :
338 30499 : status = state->method->ops->check_password_recv(subreq, state,
339 : &state->user_info_dc,
340 : &state->client_audit_info,
341 : &state->server_audit_info,
342 : &authoritative);
343 30499 : TALLOC_FREE(subreq);
344 30499 : if (!authoritative ||
345 29268 : NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
346 1356 : DEBUG(11,("auth_check_password_send: "
347 : "%s passes to the next method\n",
348 : state->method->ops->name));
349 1356 : state->method = state->method->next;
350 1356 : auth_check_password_next(req);
351 1356 : return;
352 : }
353 :
354 : /* the backend has handled the request */
355 :
356 29143 : if (tevent_req_nterror(req, status)) {
357 5252 : return;
358 : }
359 :
360 23884 : tevent_req_done(req);
361 : }
362 :
363 : /**
364 : * Check a user's Plaintext, LM or NTLM password.
365 : * async receive function
366 : *
367 : * The return value takes precedence over the contents of the user_info_dc
368 : * struct. When the return is other than NT_STATUS_OK the contents
369 : * of that structure is undefined.
370 : *
371 : *
372 : * @param req The async request state
373 : *
374 : * @param mem_ctx The parent memory context for the user_info_dc structure
375 : *
376 : * @param user_info_dc If successful, contains information about the authentication,
377 : * including a SAM_ACCOUNT struct describing the user.
378 : *
379 : * @return An NTSTATUS with NT_STATUS_OK or an appropriate error.
380 : *
381 : **/
382 :
383 29195 : _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
384 : TALLOC_CTX *mem_ctx,
385 : struct auth_user_info_dc **user_info_dc,
386 : uint8_t *pauthoritative)
387 : {
388 1420 : struct auth_check_password_state *state =
389 29195 : tevent_req_data(req, struct auth_check_password_state);
390 29195 : NTSTATUS status = NT_STATUS_OK;
391 :
392 29195 : *pauthoritative = state->authoritative;
393 :
394 29195 : if (tevent_req_is_nterror(req, &status)) {
395 : /*
396 : * Please try not to change this string, it is probably in use
397 : * in audit logging tools
398 : */
399 5311 : DEBUG(2,("auth_check_password_recv: "
400 : "%s authentication for user [%s\\%s] "
401 : "FAILED with error %s, authoritative=%u\n",
402 : (state->method ? state->method->ops->name : "NO_METHOD"),
403 : state->user_info->mapped.domain_name,
404 : state->user_info->mapped.account_name,
405 : nt_errstr(status), state->authoritative));
406 :
407 5311 : log_authentication_event(state->auth_ctx->msg_ctx,
408 5304 : state->auth_ctx->lp_ctx,
409 5311 : &state->auth_ctx->start_time,
410 : state->user_info, status,
411 : NULL, NULL, NULL,
412 : state->client_audit_info,
413 : state->server_audit_info);
414 5311 : tevent_req_received(req);
415 5311 : return status;
416 : }
417 :
418 23884 : DEBUG(5,("auth_check_password_recv: "
419 : "%s authentication for user [%s\\%s] succeeded\n",
420 : state->method->ops->name,
421 : state->user_info_dc->info->domain_name,
422 : state->user_info_dc->info->account_name));
423 :
424 23884 : log_authentication_event(state->auth_ctx->msg_ctx,
425 22471 : state->auth_ctx->lp_ctx,
426 23884 : &state->auth_ctx->start_time,
427 : state->user_info, status,
428 22471 : state->user_info_dc->info->domain_name,
429 23884 : state->user_info_dc->info->account_name,
430 23884 : &state->user_info_dc->sids[PRIMARY_USER_SID_INDEX].sid,
431 : state->client_audit_info,
432 : state->server_audit_info);
433 :
434 : /*
435 : * Release our handle to state->user_info_dc.
436 : * state->{client,server}_audit_info, if non-NULL, becomes the new
437 : * parent.
438 : */
439 23884 : *user_info_dc = talloc_reparent(state, mem_ctx, state->user_info_dc);
440 23884 : state->user_info_dc = NULL;
441 :
442 23884 : tevent_req_received(req);
443 23884 : return NT_STATUS_OK;
444 : }
445 :
446 : struct auth_check_password_wrapper_state {
447 : uint8_t authoritative;
448 : struct auth_user_info_dc *user_info_dc;
449 : };
450 :
451 : static void auth_check_password_wrapper_done(struct tevent_req *subreq);
452 :
453 13929 : static struct tevent_req *auth_check_password_wrapper_send(TALLOC_CTX *mem_ctx,
454 : struct tevent_context *ev,
455 : struct auth4_context *auth_ctx,
456 : const struct auth_usersupplied_info *user_info)
457 : {
458 13929 : struct tevent_req *req = NULL;
459 13929 : struct auth_check_password_wrapper *state = NULL;
460 13929 : struct tevent_req *subreq = NULL;
461 :
462 13929 : req = tevent_req_create(mem_ctx, &state,
463 : struct auth_check_password_wrapper_state);
464 13929 : if (req == NULL) {
465 0 : return NULL;
466 : }
467 :
468 13929 : subreq = auth_check_password_send(state, ev, auth_ctx, user_info);
469 13929 : if (tevent_req_nomem(subreq, req)) {
470 0 : return tevent_req_post(req, ev);
471 : }
472 13929 : tevent_req_set_callback(subreq,
473 : auth_check_password_wrapper_done,
474 : req);
475 :
476 13929 : return req;
477 : }
478 :
479 13929 : static void auth_check_password_wrapper_done(struct tevent_req *subreq)
480 : {
481 146 : struct tevent_req *req =
482 13929 : tevent_req_callback_data(subreq,
483 : struct tevent_req);
484 146 : struct auth_check_password_wrapper_state *state =
485 13929 : tevent_req_data(req,
486 : struct auth_check_password_wrapper_state);
487 146 : NTSTATUS status;
488 :
489 13929 : status = auth_check_password_recv(subreq, state,
490 : &state->user_info_dc,
491 : &state->authoritative);
492 13929 : TALLOC_FREE(subreq);
493 13929 : if (tevent_req_nterror(req, status)) {
494 1434 : return;
495 : }
496 :
497 12495 : tevent_req_done(req);
498 : }
499 :
500 13929 : static NTSTATUS auth_check_password_wrapper_recv(struct tevent_req *req,
501 : TALLOC_CTX *mem_ctx,
502 : uint8_t *pauthoritative,
503 : void **server_returned_info,
504 : DATA_BLOB *user_session_key,
505 : DATA_BLOB *lm_session_key)
506 : {
507 146 : struct auth_check_password_wrapper_state *state =
508 13929 : tevent_req_data(req,
509 : struct auth_check_password_wrapper_state);
510 13929 : struct auth_user_info_dc *user_info_dc = state->user_info_dc;
511 13929 : NTSTATUS status = NT_STATUS_OK;
512 :
513 13929 : *pauthoritative = state->authoritative;
514 :
515 13929 : if (tevent_req_is_nterror(req, &status)) {
516 1434 : tevent_req_received(req);
517 1434 : return status;
518 : }
519 :
520 12495 : talloc_steal(mem_ctx, user_info_dc);
521 12495 : *server_returned_info = user_info_dc;
522 :
523 12495 : if (user_session_key) {
524 12484 : DEBUG(10, ("Got NT session key of length %u\n",
525 : (unsigned)user_info_dc->user_session_key.length));
526 12484 : *user_session_key = user_info_dc->user_session_key;
527 12484 : talloc_steal(mem_ctx, user_session_key->data);
528 12484 : user_info_dc->user_session_key = data_blob_null;
529 : }
530 :
531 12495 : if (lm_session_key) {
532 12484 : DEBUG(10, ("Got LM session key of length %u\n",
533 : (unsigned)user_info_dc->lm_session_key.length));
534 12484 : *lm_session_key = user_info_dc->lm_session_key;
535 12484 : talloc_steal(mem_ctx, lm_session_key->data);
536 12484 : user_info_dc->lm_session_key = data_blob_null;
537 : }
538 :
539 12495 : tevent_req_received(req);
540 12495 : return NT_STATUS_OK;
541 : }
542 :
543 : /* Wrapper because we don't want to expose all callers to needing to
544 : * know that session_info is generated from the main ldb, and because
545 : * we need to break a dependency loop between the DCE/RPC layer and the
546 : * generation of unix tokens via IRPC */
547 46989 : static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_context,
548 : TALLOC_CTX *mem_ctx,
549 : void *server_returned_info,
550 : const char *original_user_name,
551 : uint32_t session_info_flags,
552 : struct auth_session_info **session_info)
553 : {
554 1348 : NTSTATUS status;
555 46989 : struct auth_user_info_dc *user_info_dc = talloc_get_type_abort(server_returned_info, struct auth_user_info_dc);
556 :
557 46989 : if (!(user_info_dc->info->user_flags & NETLOGON_GUEST)) {
558 43992 : session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
559 : }
560 :
561 46989 : status = auth_generate_session_info(mem_ctx,
562 : auth_context->lp_ctx,
563 : auth_context->sam_ctx,
564 : user_info_dc,
565 : session_info_flags,
566 : session_info);
567 46989 : if (!NT_STATUS_IS_OK(status)) {
568 0 : return status;
569 : }
570 :
571 46989 : if ((session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)
572 8560 : && NT_STATUS_IS_OK(status)) {
573 9362 : status = auth_session_info_fill_unix(auth_context->lp_ctx,
574 : original_user_name,
575 : *session_info);
576 9362 : if (!NT_STATUS_IS_OK(status)) {
577 0 : TALLOC_FREE(*session_info);
578 : }
579 : }
580 46989 : return status;
581 : }
582 :
583 : /* Wrapper because we don't want to expose all callers to needing to
584 : * know anything about the PAC or auth subsystem internal structures
585 : * before we output a struct auth session_info */
586 31335 : static NTSTATUS auth_generate_session_info_pac(struct auth4_context *auth_ctx,
587 : TALLOC_CTX *mem_ctx,
588 : struct smb_krb5_context *smb_krb5_context,
589 : DATA_BLOB *pac_blob,
590 : const char *principal_name,
591 : const struct tsocket_address *remote_address,
592 : uint32_t session_info_flags,
593 : struct auth_session_info **session_info)
594 : {
595 881 : NTSTATUS status;
596 881 : struct auth_user_info_dc *user_info_dc;
597 881 : TALLOC_CTX *tmp_ctx;
598 :
599 31335 : if (!pac_blob) {
600 : /*
601 : * This should already have been caught at the main
602 : * gensec layer, but better check twice
603 : */
604 0 : return NT_STATUS_INTERNAL_ERROR;
605 : }
606 :
607 31335 : tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context");
608 31335 : NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
609 :
610 : /*
611 : * FIXME: To correctly create the security token, we also need to get the
612 : * claims info, device info, and device claims info from the PAC. For now,
613 : * we support claims only in the KDC.
614 : */
615 31335 : status = kerberos_pac_blob_to_user_info_dc(tmp_ctx,
616 : *pac_blob,
617 : smb_krb5_context->krb5_context,
618 : &user_info_dc, NULL, NULL);
619 31335 : if (!NT_STATUS_IS_OK(status)) {
620 0 : talloc_free(tmp_ctx);
621 0 : return status;
622 : }
623 :
624 31335 : if (!(user_info_dc->info->user_flags & NETLOGON_GUEST)) {
625 31335 : session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
626 : }
627 :
628 31335 : status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx,
629 : user_info_dc,
630 30454 : user_info_dc->info->account_name,
631 : session_info_flags, session_info);
632 31335 : talloc_free(tmp_ctx);
633 31335 : return status;
634 : }
635 :
636 : /***************************************************************************
637 : Make a auth_info struct for the auth subsystem
638 : - Allow the caller to specify the methods to use, including optionally the SAM to use
639 : ***************************************************************************/
640 149739 : _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char * const *methods,
641 : struct tevent_context *ev,
642 : struct imessaging_context *msg,
643 : struct loadparm_context *lp_ctx,
644 : struct ldb_context *sam_ctx,
645 : struct auth4_context **auth_ctx)
646 : {
647 4151 : int i;
648 4151 : struct auth4_context *ctx;
649 :
650 149739 : auth4_init();
651 :
652 149739 : if (!ev) {
653 0 : DEBUG(0,("auth_context_create: called with out event context\n"));
654 0 : return NT_STATUS_INTERNAL_ERROR;
655 : }
656 :
657 149739 : ctx = talloc_zero(mem_ctx, struct auth4_context);
658 149739 : NT_STATUS_HAVE_NO_MEMORY(ctx);
659 149739 : ctx->challenge.data = data_blob(NULL, 0);
660 149739 : ctx->methods = NULL;
661 149739 : ctx->event_ctx = ev;
662 149739 : ctx->msg_ctx = msg;
663 149739 : ctx->lp_ctx = lp_ctx;
664 149739 : ctx->start_time = timeval_current();
665 :
666 149739 : if (sam_ctx) {
667 7 : ctx->sam_ctx = sam_ctx;
668 : } else {
669 149732 : ctx->sam_ctx = samdb_connect(ctx,
670 : ctx->event_ctx,
671 : ctx->lp_ctx,
672 : system_session(ctx->lp_ctx),
673 : NULL,
674 : 0);
675 : }
676 :
677 719057 : for (i=0; methods && methods[i] ; i++) {
678 14056 : struct auth_method_context *method;
679 :
680 569318 : method = talloc(ctx, struct auth_method_context);
681 569318 : NT_STATUS_HAVE_NO_MEMORY(method);
682 :
683 569318 : method->ops = auth_backend_byname(methods[i]);
684 569318 : if (!method->ops) {
685 0 : DEBUG(1,("auth_context_create: failed to find method=%s\n",
686 : methods[i]));
687 0 : return NT_STATUS_INTERNAL_ERROR;
688 : }
689 569318 : method->auth_ctx = ctx;
690 569318 : method->depth = i;
691 569318 : DLIST_ADD_END(ctx->methods, method);
692 : }
693 :
694 149739 : ctx->check_ntlm_password_send = auth_check_password_wrapper_send;
695 149739 : ctx->check_ntlm_password_recv = auth_check_password_wrapper_recv;
696 149739 : ctx->get_ntlm_challenge = auth_get_challenge;
697 149739 : ctx->set_ntlm_challenge = auth_context_set_challenge;
698 149739 : ctx->generate_session_info = auth_generate_session_info_wrapper;
699 149739 : ctx->generate_session_info_pac = auth_generate_session_info_pac;
700 :
701 149739 : *auth_ctx = ctx;
702 :
703 149739 : return NT_STATUS_OK;
704 : }
705 :
706 134945 : const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
707 : {
708 134945 : char **auth_methods = NULL;
709 :
710 134945 : switch (lpcfg_server_role(lp_ctx)) {
711 20 : case ROLE_STANDALONE:
712 20 : auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain", NULL);
713 20 : break;
714 134925 : case ROLE_DOMAIN_MEMBER:
715 : case ROLE_DOMAIN_BDC:
716 : case ROLE_DOMAIN_PDC:
717 : case ROLE_ACTIVE_DIRECTORY_DC:
718 : case ROLE_IPA_DC:
719 134925 : auth_methods = str_list_make(mem_ctx, "anonymous sam winbind sam_ignoredomain", NULL);
720 134925 : break;
721 : }
722 134945 : return discard_const_p(const char *, auth_methods);
723 : }
724 :
725 : /***************************************************************************
726 : Make a auth_info struct for the auth subsystem
727 : - Uses default auth_methods, depending on server role and smb.conf settings
728 : ***************************************************************************/
729 134943 : _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
730 : struct tevent_context *ev,
731 : struct imessaging_context *msg,
732 : struct loadparm_context *lp_ctx,
733 : struct auth4_context **auth_ctx)
734 : {
735 2877 : NTSTATUS status;
736 2877 : const char **auth_methods;
737 134943 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
738 134943 : if (!tmp_ctx) {
739 0 : return NT_STATUS_NO_MEMORY;
740 : }
741 :
742 134943 : auth_methods = auth_methods_from_lp(tmp_ctx, lp_ctx);
743 134943 : if (!auth_methods) {
744 0 : return NT_STATUS_INVALID_PARAMETER;
745 : }
746 134943 : status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg, lp_ctx, NULL, auth_ctx);
747 134943 : talloc_free(tmp_ctx);
748 134943 : return status;
749 : }
750 :
751 14789 : _PUBLIC_ NTSTATUS auth_context_create_for_netlogon(TALLOC_CTX *mem_ctx,
752 : struct tevent_context *ev,
753 : struct imessaging_context *msg,
754 : struct loadparm_context *lp_ctx,
755 : struct auth4_context **auth_ctx)
756 : {
757 1274 : NTSTATUS status;
758 14789 : char **_auth_methods = NULL;
759 14789 : const char **auth_methods = NULL;
760 :
761 : /*
762 : * Here we only allow 'sam winbind' instead of
763 : * the 'anonymous sam winbind sam_ignoredomain'
764 : * we typically use for authentication from clients.
765 : */
766 14789 : _auth_methods = str_list_make(mem_ctx, "sam winbind", NULL);
767 14789 : if (_auth_methods == NULL) {
768 0 : return NT_STATUS_NO_MEMORY;
769 : }
770 14789 : auth_methods = discard_const_p(const char *, _auth_methods);
771 :
772 14789 : status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg,
773 : lp_ctx, NULL, auth_ctx);
774 14789 : talloc_free(_auth_methods);
775 14789 : return status;
776 : }
777 :
778 : /* the list of currently registered AUTH backends */
779 : static struct auth_backend {
780 : const struct auth_operations *ops;
781 : } *backends = NULL;
782 : static int num_backends;
783 :
784 : /*
785 : register a AUTH backend.
786 :
787 : The 'name' can be later used by other backends to find the operations
788 : structure for this backend.
789 : */
790 48405 : _PUBLIC_ NTSTATUS auth_register(TALLOC_CTX *mem_ctx,
791 : const struct auth_operations *ops)
792 : {
793 4185 : struct auth_operations *new_ops;
794 :
795 48405 : if (auth_backend_byname(ops->name) != NULL) {
796 : /* its already registered! */
797 0 : DEBUG(0,("AUTH backend '%s' already registered\n",
798 : ops->name));
799 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
800 : }
801 :
802 48405 : backends = talloc_realloc(mem_ctx, backends,
803 : struct auth_backend, num_backends+1);
804 48405 : NT_STATUS_HAVE_NO_MEMORY(backends);
805 :
806 48405 : new_ops = (struct auth_operations *)talloc_memdup(backends, ops, sizeof(*ops));
807 48405 : NT_STATUS_HAVE_NO_MEMORY(new_ops);
808 48405 : new_ops->name = talloc_strdup(new_ops, ops->name);
809 48405 : NT_STATUS_HAVE_NO_MEMORY(new_ops->name);
810 :
811 48405 : backends[num_backends].ops = new_ops;
812 :
813 48405 : num_backends++;
814 :
815 48405 : DEBUG(3,("AUTH backend '%s' registered\n",
816 : ops->name));
817 :
818 48405 : return NT_STATUS_OK;
819 : }
820 :
821 : /*
822 : return the operations structure for a named backend of the specified type
823 : */
824 617723 : const struct auth_operations *auth_backend_byname(const char *name)
825 : {
826 18241 : int i;
827 :
828 1568510 : for (i=0;i<num_backends;i++) {
829 1520105 : if (strcmp(backends[i].ops->name, name) == 0) {
830 569318 : return backends[i].ops;
831 : }
832 : }
833 :
834 44220 : return NULL;
835 : }
836 :
837 : /*
838 : return the AUTH interface version, and the size of some critical types
839 : This can be used by backends to either detect compilation errors, or provide
840 : multiple implementations for different smbd compilation options in one module
841 : */
842 0 : const struct auth_critical_sizes *auth_interface_version(void)
843 : {
844 0 : static const struct auth_critical_sizes critical_sizes = {
845 : AUTH4_INTERFACE_VERSION,
846 : sizeof(struct auth_operations),
847 : sizeof(struct auth_method_context),
848 : sizeof(struct auth4_context),
849 : sizeof(struct auth_usersupplied_info),
850 : sizeof(struct auth_user_info_dc)
851 : };
852 :
853 0 : return &critical_sizes;
854 : }
855 :
856 149805 : _PUBLIC_ NTSTATUS auth4_init(void)
857 : {
858 4154 : static bool initialized = false;
859 : #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
860 4154 : STATIC_auth4_MODULES_PROTO;
861 149805 : init_module_fn static_init[] = { STATIC_auth4_MODULES };
862 :
863 149805 : if (initialized) return NT_STATUS_OK;
864 9681 : initialized = true;
865 :
866 9681 : run_init_functions(NULL, static_init);
867 :
868 9681 : return NT_STATUS_OK;
869 : }
|