Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : Generic Authentication Interface
5 :
6 : Copyright (C) Andrew Tridgell 2003
7 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2006
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "system/network.h"
25 : #define TEVENT_DEPRECATED 1
26 : #include <tevent.h>
27 : #include "lib/tsocket/tsocket.h"
28 : #include "lib/util/tevent_ntstatus.h"
29 : #include "auth/gensec/gensec.h"
30 : #include "auth/gensec/gensec_internal.h"
31 : #include "librpc/gen_ndr/dcerpc.h"
32 : #include "auth/common_auth.h"
33 :
34 : #undef DBGC_CLASS
35 : #define DBGC_CLASS DBGC_AUTH
36 :
37 130051 : _PRIVATE_ NTSTATUS gensec_may_reset_crypto(struct gensec_security *gensec_security,
38 : bool full_reset)
39 : {
40 130051 : if (!gensec_security->ops->may_reset_crypto) {
41 63737 : return NT_STATUS_OK;
42 : }
43 :
44 66314 : return gensec_security->ops->may_reset_crypto(gensec_security, full_reset);
45 : }
46 :
47 : /*
48 : wrappers for the gensec function pointers
49 : */
50 697054 : _PUBLIC_ NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security,
51 : uint8_t *data, size_t length,
52 : const uint8_t *whole_pdu, size_t pdu_length,
53 : const DATA_BLOB *sig)
54 : {
55 697054 : if (!gensec_security->ops->unseal_packet) {
56 0 : return NT_STATUS_NOT_IMPLEMENTED;
57 : }
58 697054 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
59 0 : return NT_STATUS_INVALID_PARAMETER;
60 : }
61 697054 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
62 0 : return NT_STATUS_INVALID_PARAMETER;
63 : }
64 697054 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE)) {
65 0 : return NT_STATUS_INVALID_PARAMETER;
66 : }
67 :
68 697054 : return gensec_security->ops->unseal_packet(gensec_security,
69 : data, length,
70 : whole_pdu, pdu_length,
71 : sig);
72 : }
73 :
74 216417 : _PUBLIC_ NTSTATUS gensec_check_packet(struct gensec_security *gensec_security,
75 : const uint8_t *data, size_t length,
76 : const uint8_t *whole_pdu, size_t pdu_length,
77 : const DATA_BLOB *sig)
78 : {
79 216417 : if (!gensec_security->ops->check_packet) {
80 0 : return NT_STATUS_NOT_IMPLEMENTED;
81 : }
82 216417 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
83 6 : return NT_STATUS_INVALID_PARAMETER;
84 : }
85 :
86 216411 : return gensec_security->ops->check_packet(gensec_security, data, length, whole_pdu, pdu_length, sig);
87 : }
88 :
89 697160 : _PUBLIC_ NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security,
90 : TALLOC_CTX *mem_ctx,
91 : uint8_t *data, size_t length,
92 : const uint8_t *whole_pdu, size_t pdu_length,
93 : DATA_BLOB *sig)
94 : {
95 697160 : if (!gensec_security->ops->seal_packet) {
96 0 : return NT_STATUS_NOT_IMPLEMENTED;
97 : }
98 697160 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
99 0 : return NT_STATUS_INVALID_PARAMETER;
100 : }
101 697160 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
102 0 : return NT_STATUS_INVALID_PARAMETER;
103 : }
104 697160 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE)) {
105 0 : return NT_STATUS_INVALID_PARAMETER;
106 : }
107 :
108 697160 : return gensec_security->ops->seal_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig);
109 : }
110 :
111 220421 : _PUBLIC_ NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security,
112 : TALLOC_CTX *mem_ctx,
113 : const uint8_t *data, size_t length,
114 : const uint8_t *whole_pdu, size_t pdu_length,
115 : DATA_BLOB *sig)
116 : {
117 220421 : if (!gensec_security->ops->sign_packet) {
118 0 : return NT_STATUS_NOT_IMPLEMENTED;
119 : }
120 220421 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
121 0 : return NT_STATUS_INVALID_PARAMETER;
122 : }
123 :
124 220421 : return gensec_security->ops->sign_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig);
125 : }
126 :
127 318233 : _PUBLIC_ size_t gensec_sig_size(struct gensec_security *gensec_security, size_t data_size)
128 : {
129 318233 : if (!gensec_security->ops->sig_size) {
130 1047 : return 0;
131 : }
132 317172 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
133 322 : return 0;
134 : }
135 316850 : if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
136 182330 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE)) {
137 0 : return 0;
138 : }
139 : }
140 :
141 316850 : return gensec_security->ops->sig_size(gensec_security, data_size);
142 : }
143 :
144 103808 : _PUBLIC_ size_t gensec_max_wrapped_size(struct gensec_security *gensec_security)
145 : {
146 103808 : if (!gensec_security->ops->max_wrapped_size) {
147 17471 : return (1 << 17);
148 : }
149 :
150 86337 : return gensec_security->ops->max_wrapped_size(gensec_security);
151 : }
152 :
153 103808 : _PUBLIC_ size_t gensec_max_input_size(struct gensec_security *gensec_security)
154 : {
155 103808 : if (!gensec_security->ops->max_input_size) {
156 17471 : return (1 << 17) - gensec_sig_size(gensec_security, 1 << 17);
157 : }
158 :
159 86337 : return gensec_security->ops->max_input_size(gensec_security);
160 : }
161 :
162 2949830 : _PUBLIC_ NTSTATUS gensec_wrap(struct gensec_security *gensec_security,
163 : TALLOC_CTX *mem_ctx,
164 : const DATA_BLOB *in,
165 : DATA_BLOB *out)
166 : {
167 2949830 : if (!gensec_security->ops->wrap) {
168 0 : return NT_STATUS_NOT_IMPLEMENTED;
169 : }
170 2949830 : return gensec_security->ops->wrap(gensec_security, mem_ctx, in, out);
171 : }
172 :
173 2949274 : _PUBLIC_ NTSTATUS gensec_unwrap(struct gensec_security *gensec_security,
174 : TALLOC_CTX *mem_ctx,
175 : const DATA_BLOB *in,
176 : DATA_BLOB *out)
177 : {
178 2949274 : if (!gensec_security->ops->unwrap) {
179 0 : return NT_STATUS_NOT_IMPLEMENTED;
180 : }
181 2949274 : return gensec_security->ops->unwrap(gensec_security, mem_ctx, in, out);
182 : }
183 :
184 76967 : _PUBLIC_ NTSTATUS gensec_session_key(struct gensec_security *gensec_security,
185 : TALLOC_CTX *mem_ctx,
186 : DATA_BLOB *session_key)
187 : {
188 76967 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SESSION_KEY)) {
189 0 : return NT_STATUS_NO_USER_SESSION_KEY;
190 : }
191 :
192 76967 : if (!gensec_security->ops->session_key) {
193 0 : return NT_STATUS_NOT_IMPLEMENTED;
194 : }
195 :
196 76967 : return gensec_security->ops->session_key(gensec_security, mem_ctx, session_key);
197 : }
198 :
199 171416 : const char *gensec_final_auth_type(struct gensec_security *gensec_security)
200 : {
201 171416 : if (!gensec_security->ops->final_auth_type) {
202 3066 : return gensec_security->ops->name;
203 : }
204 :
205 168350 : return gensec_security->ops->final_auth_type(gensec_security);
206 : }
207 :
208 : /*
209 : * Log details of a successful GENSEC authorization to a service.
210 : *
211 : * Only successful authorizations are logged, as only these call gensec_session_info()
212 : *
213 : * The service may later refuse authorization due to an ACL.
214 : *
215 : */
216 69471 : static void log_successful_gensec_authz_event(struct gensec_security *gensec_security,
217 : struct auth_session_info *session_info)
218 : {
219 1348 : const struct tsocket_address *remote
220 69471 : = gensec_get_remote_address(gensec_security);
221 1348 : const struct tsocket_address *local
222 69471 : = gensec_get_local_address(gensec_security);
223 1348 : const char *service_description
224 69471 : = gensec_get_target_service_description(gensec_security);
225 1348 : const char *final_auth_type
226 69471 : = gensec_final_auth_type(gensec_security);
227 69471 : const char *transport_protection = NULL;
228 69471 : if (gensec_security->want_features & GENSEC_FEATURE_SMB_TRANSPORT) {
229 31953 : transport_protection = AUTHZ_TRANSPORT_PROTECTION_SMB;
230 36716 : } else if (gensec_security->want_features & GENSEC_FEATURE_LDAPS_TRANSPORT) {
231 46 : transport_protection = AUTHZ_TRANSPORT_PROTECTION_TLS;
232 36670 : } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
233 32122 : transport_protection = AUTHZ_TRANSPORT_PROTECTION_SEAL;
234 4163 : } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
235 3230 : transport_protection = AUTHZ_TRANSPORT_PROTECTION_SIGN;
236 : } else {
237 780 : transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
238 : }
239 69471 : log_successful_authz_event(gensec_security->auth_context->msg_ctx,
240 69471 : gensec_security->auth_context->lp_ctx,
241 : remote, local,
242 : service_description,
243 : final_auth_type,
244 : transport_protection,
245 : session_info,
246 : NULL /* client_audit_info */,
247 : NULL /* server_audit_info */);
248 69471 : }
249 :
250 :
251 : /**
252 : * Return the credentials of a logged on user, including session keys
253 : * etc.
254 : *
255 : * Only valid after a successful authentication
256 : *
257 : * May only be called once per authentication. This will also make an
258 : * authorization log entry, as it is already called by all the
259 : * callers.
260 : *
261 : */
262 :
263 134293 : _PUBLIC_ NTSTATUS gensec_session_info(struct gensec_security *gensec_security,
264 : TALLOC_CTX *mem_ctx,
265 : struct auth_session_info **session_info)
266 : {
267 2368 : NTSTATUS status;
268 134293 : if (!gensec_security->ops->session_info) {
269 0 : return NT_STATUS_NOT_IMPLEMENTED;
270 : }
271 134293 : status = gensec_security->ops->session_info(gensec_security, mem_ctx, session_info);
272 :
273 134293 : if (NT_STATUS_IS_OK(status) && !gensec_security->subcontext
274 69567 : && (gensec_security->want_features & GENSEC_FEATURE_NO_AUTHZ_LOG) == 0) {
275 69471 : log_successful_gensec_authz_event(gensec_security, *session_info);
276 : }
277 :
278 134293 : return status;
279 : }
280 :
281 444 : _PUBLIC_ void gensec_set_max_update_size(struct gensec_security *gensec_security,
282 : uint32_t max_update_size)
283 : {
284 444 : gensec_security->max_update_size = max_update_size;
285 444 : }
286 :
287 191166 : _PUBLIC_ size_t gensec_max_update_size(struct gensec_security *gensec_security)
288 : {
289 191166 : if (gensec_security->max_update_size == 0) {
290 187086 : return UINT32_MAX;
291 : }
292 :
293 444 : return gensec_security->max_update_size;
294 : }
295 :
296 273043 : static NTSTATUS gensec_verify_features(struct gensec_security *gensec_security)
297 : {
298 4742 : bool ok;
299 :
300 : /*
301 : * gensec_want_feature(GENSEC_FEATURE_SIGN)
302 : * and
303 : * gensec_want_feature(GENSEC_FEATURE_SEAL)
304 : * require these flags to be available.
305 : */
306 273043 : if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
307 78444 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
308 3 : DEBUG(0,("Did not manage to negotiate mandatory feature "
309 : "SIGN\n"));
310 3 : return NT_STATUS_ACCESS_DENIED;
311 : }
312 : }
313 273040 : if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
314 72457 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
315 3 : DEBUG(0,("Did not manage to negotiate mandatory feature "
316 : "SEAL\n"));
317 3 : return NT_STATUS_ACCESS_DENIED;
318 : }
319 72454 : if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
320 0 : DEBUG(0,("Did not manage to negotiate mandatory feature "
321 : "SIGN for SEAL\n"));
322 0 : return NT_STATUS_ACCESS_DENIED;
323 : }
324 : }
325 :
326 273037 : if (gensec_security->dcerpc_auth_level < DCERPC_AUTH_LEVEL_PACKET) {
327 244149 : return NT_STATUS_OK;
328 : }
329 :
330 28888 : ok = gensec_have_feature(gensec_security,
331 : GENSEC_FEATURE_SIGN_PKT_HEADER);
332 28888 : if (!ok) {
333 0 : DBG_ERR("backend [%s] does not support header signing! "
334 : "auth_level[0x%x]\n",
335 : gensec_security->ops->name,
336 : gensec_security->dcerpc_auth_level);
337 0 : return NT_STATUS_INTERNAL_ERROR;
338 : }
339 :
340 28888 : return NT_STATUS_OK;
341 : }
342 :
343 : /**
344 : * Next state function for the GENSEC state machine
345 : *
346 : * @param gensec_security GENSEC State
347 : * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
348 : * @param in The request, as a DATA_BLOB
349 : * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
350 : * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent,
351 : * or NT_STATUS_OK if the user is authenticated.
352 : */
353 134420 : _PUBLIC_ NTSTATUS gensec_update(struct gensec_security *gensec_security,
354 : TALLOC_CTX *out_mem_ctx,
355 : const DATA_BLOB in, DATA_BLOB *out)
356 : {
357 1653 : NTSTATUS status;
358 134420 : TALLOC_CTX *frame = NULL;
359 134420 : struct tevent_context *ev = NULL;
360 134420 : struct tevent_req *subreq = NULL;
361 1653 : bool ok;
362 :
363 134420 : if (gensec_security->subcontext) {
364 : /*
365 : * gensec modules are not allowed to call the sync version.
366 : */
367 0 : return NT_STATUS_INTERNAL_ERROR;
368 : }
369 :
370 134420 : frame = talloc_stackframe();
371 :
372 134420 : ev = samba_tevent_context_init(frame);
373 134420 : if (ev == NULL) {
374 0 : status = NT_STATUS_NO_MEMORY;
375 0 : goto fail;
376 : }
377 :
378 : /*
379 : * TODO: remove this hack once the backends
380 : * are fixed.
381 : */
382 134420 : tevent_loop_allow_nesting(ev);
383 :
384 134420 : subreq = gensec_update_send(frame, ev, gensec_security, in);
385 134420 : if (subreq == NULL) {
386 0 : status = NT_STATUS_NO_MEMORY;
387 0 : goto fail;
388 : }
389 134420 : ok = tevent_req_poll_ntstatus(subreq, ev, &status);
390 134420 : if (!ok) {
391 0 : goto fail;
392 : }
393 134420 : status = gensec_update_recv(subreq, out_mem_ctx, out);
394 134420 : fail:
395 134420 : TALLOC_FREE(frame);
396 134420 : return status;
397 : }
398 :
399 : struct gensec_update_state {
400 : const struct gensec_security_ops *ops;
401 : struct gensec_security *gensec_security;
402 : NTSTATUS status;
403 : DATA_BLOB out;
404 : };
405 :
406 : static void gensec_update_cleanup(struct tevent_req *req,
407 : enum tevent_req_state req_state);
408 : static void gensec_update_done(struct tevent_req *subreq);
409 :
410 : /**
411 : * Next state function for the GENSEC state machine async version
412 : *
413 : * @param mem_ctx The memory context for the request
414 : * @param ev The event context for the request
415 : * @param gensec_security GENSEC State
416 : * @param in The request, as a DATA_BLOB
417 : *
418 : * @return The request handle or NULL on no memory failure
419 : */
420 :
421 606606 : _PUBLIC_ struct tevent_req *gensec_update_send(TALLOC_CTX *mem_ctx,
422 : struct tevent_context *ev,
423 : struct gensec_security *gensec_security,
424 : const DATA_BLOB in)
425 : {
426 606606 : struct tevent_req *req = NULL;
427 606606 : struct gensec_update_state *state = NULL;
428 606606 : struct tevent_req *subreq = NULL;
429 :
430 606606 : req = tevent_req_create(mem_ctx, &state,
431 : struct gensec_update_state);
432 606606 : if (req == NULL) {
433 0 : return NULL;
434 : }
435 606606 : state->ops = gensec_security->ops;
436 606606 : state->gensec_security = gensec_security;
437 :
438 606606 : if (gensec_security->update_busy_ptr != NULL) {
439 0 : tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
440 0 : return tevent_req_post(req, ev);
441 : }
442 :
443 606606 : if (gensec_security->child_security != NULL) {
444 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
445 0 : return tevent_req_post(req, ev);
446 : }
447 :
448 606606 : gensec_security->update_busy_ptr = &state->gensec_security;
449 606606 : tevent_req_set_cleanup_fn(req, gensec_update_cleanup);
450 :
451 606606 : subreq = state->ops->update_send(state, ev, gensec_security, in);
452 606606 : if (tevent_req_nomem(subreq, req)) {
453 0 : return tevent_req_post(req, ev);
454 : }
455 606606 : tevent_req_set_callback(subreq, gensec_update_done, req);
456 :
457 606606 : DBG_DEBUG("%s[%p]: subreq: %p\n", state->ops->name,
458 : state->gensec_security, subreq);
459 :
460 596848 : return req;
461 : }
462 :
463 1213212 : static void gensec_update_cleanup(struct tevent_req *req,
464 : enum tevent_req_state req_state)
465 : {
466 19516 : struct gensec_update_state *state =
467 1213212 : tevent_req_data(req,
468 : struct gensec_update_state);
469 :
470 1213212 : if (state->gensec_security == NULL) {
471 596848 : return;
472 : }
473 :
474 606606 : if (state->gensec_security->update_busy_ptr == &state->gensec_security) {
475 606606 : state->gensec_security->update_busy_ptr = NULL;
476 : }
477 :
478 606606 : state->gensec_security = NULL;
479 : }
480 :
481 606606 : static void gensec_update_done(struct tevent_req *subreq)
482 : {
483 9758 : struct tevent_req *req =
484 606606 : tevent_req_callback_data(subreq,
485 : struct tevent_req);
486 9758 : struct gensec_update_state *state =
487 606606 : tevent_req_data(req,
488 : struct gensec_update_state);
489 9758 : NTSTATUS status;
490 606606 : const char *debug_subreq = NULL;
491 :
492 606606 : if (CHECK_DEBUGLVL(DBGLVL_DEBUG)) {
493 : /*
494 : * We need to call tevent_req_print()
495 : * before calling the _recv function,
496 : * before tevent_req_received() was called.
497 : * in order to print the pointer value of
498 : * the subreq state.
499 : */
500 14 : debug_subreq = tevent_req_print(state, subreq);
501 : }
502 :
503 606606 : status = state->ops->update_recv(subreq, state, &state->out);
504 606606 : TALLOC_FREE(subreq);
505 606606 : state->status = status;
506 606606 : if (GENSEC_UPDATE_IS_NTERROR(status)) {
507 9477 : NTSTATUS orig_status = status;
508 9477 : bool force_no_such_user = false;
509 :
510 : /*
511 : * callers only expect NT_STATUS_NO_SUCH_USER.
512 : */
513 9477 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_ACCOUNT_NAME)) {
514 0 : force_no_such_user = true;
515 9477 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
516 0 : force_no_such_user = true;
517 : }
518 :
519 9477 : if (state->gensec_security->subcontext) {
520 : /*
521 : * We should only map on the outer
522 : * gensec_update exchange, spnego
523 : * needs the raw status.
524 : */
525 5325 : force_no_such_user = false;
526 : }
527 :
528 9468 : if (force_no_such_user) {
529 : /*
530 : * nt_status_squash() may map
531 : * to NT_STATUS_LOGON_FAILURE later
532 : */
533 0 : status = NT_STATUS_NO_SUCH_USER;
534 : }
535 :
536 9477 : DBG_INFO("%s[%p]: %s%s%s%s%s\n",
537 : state->ops->name,
538 : state->gensec_security,
539 : NT_STATUS_EQUAL(status, orig_status) ?
540 : "" : nt_errstr(orig_status),
541 : NT_STATUS_EQUAL(status, orig_status) ?
542 : "" : " ",
543 : nt_errstr(status),
544 : debug_subreq ? " " : "",
545 : debug_subreq ? debug_subreq : "");
546 9477 : tevent_req_nterror(req, status);
547 9477 : return;
548 : }
549 597129 : DBG_DEBUG("%s[%p]: %s %s\n", state->ops->name,
550 : state->gensec_security, nt_errstr(status),
551 : debug_subreq);
552 597129 : if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
553 324086 : tevent_req_done(req);
554 324086 : return;
555 : }
556 :
557 : /*
558 : * Because callers using the
559 : * gensec_start_mech_by_authtype() never call
560 : * gensec_want_feature(), it isn't sensible for them
561 : * to have to call gensec_have_feature() manually, and
562 : * these are not points of negotiation, but are
563 : * asserted by the client
564 : */
565 273043 : status = gensec_verify_features(state->gensec_security);
566 273043 : if (tevent_req_nterror(req, status)) {
567 6 : return;
568 : }
569 :
570 273037 : tevent_req_done(req);
571 : }
572 :
573 : /**
574 : * Next state function for the GENSEC state machine
575 : *
576 : * @param req request state
577 : * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
578 : * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
579 : * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent,
580 : * or NT_STATUS_OK if the user is authenticated.
581 : */
582 606606 : _PUBLIC_ NTSTATUS gensec_update_recv(struct tevent_req *req,
583 : TALLOC_CTX *out_mem_ctx,
584 : DATA_BLOB *out)
585 : {
586 9758 : struct gensec_update_state *state =
587 606606 : tevent_req_data(req, struct gensec_update_state);
588 9758 : NTSTATUS status;
589 :
590 606606 : *out = data_blob_null;
591 :
592 606606 : if (tevent_req_is_nterror(req, &status)) {
593 9483 : tevent_req_received(req);
594 9483 : return status;
595 : }
596 :
597 597123 : *out = state->out;
598 597123 : talloc_steal(out_mem_ctx, out->data);
599 597123 : status = state->status;
600 597123 : tevent_req_received(req);
601 597123 : return status;
602 : }
603 :
604 : /**
605 : * Set the requirement for a certain feature on the connection
606 : *
607 : */
608 :
609 708470 : _PUBLIC_ void gensec_want_feature(struct gensec_security *gensec_security,
610 : uint32_t feature)
611 : {
612 708470 : if (!gensec_security->ops || !gensec_security->ops->want_feature) {
613 657552 : gensec_security->want_features |= feature;
614 657552 : return;
615 : }
616 50918 : gensec_security->ops->want_feature(gensec_security, feature);
617 : }
618 :
619 : /**
620 : * Check the requirement for a certain feature on the connection
621 : *
622 : */
623 :
624 12228990 : _PUBLIC_ bool gensec_have_feature(struct gensec_security *gensec_security,
625 : uint32_t feature)
626 : {
627 12228990 : if (!gensec_security->ops || !gensec_security->ops->have_feature) {
628 0 : return false;
629 : }
630 :
631 : /* We might 'have' features that we don't 'want', because the
632 : * other end demanded them, or we can't negotiate them off */
633 12228990 : return gensec_security->ops->have_feature(gensec_security, feature);
634 : }
635 :
636 99996 : _PUBLIC_ NTTIME gensec_expire_time(struct gensec_security *gensec_security)
637 : {
638 99996 : if (!gensec_security->ops->expire_time) {
639 25255 : return GENSEC_EXPIRE_TIME_INFINITY;
640 : }
641 :
642 74612 : return gensec_security->ops->expire_time(gensec_security);
643 : }
644 : /**
645 : * Return the credentials structure associated with a GENSEC context
646 : *
647 : */
648 :
649 841463 : _PUBLIC_ struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security)
650 : {
651 841463 : if (!gensec_security) {
652 0 : return NULL;
653 : }
654 841463 : return gensec_security->credentials;
655 : }
656 :
657 : /**
658 : * Set the target service (such as 'http' or 'host') on a GENSEC context - ensures it is talloc()ed
659 : *
660 : * This is used for Kerberos service principal name resolution.
661 : */
662 :
663 185762 : _PUBLIC_ NTSTATUS gensec_set_target_service(struct gensec_security *gensec_security, const char *service)
664 : {
665 185762 : gensec_security->target.service = talloc_strdup(gensec_security, service);
666 185762 : if (!gensec_security->target.service) {
667 0 : return NT_STATUS_NO_MEMORY;
668 : }
669 185762 : return NT_STATUS_OK;
670 : }
671 :
672 198165 : _PUBLIC_ const char *gensec_get_target_service(struct gensec_security *gensec_security)
673 : {
674 198165 : if (gensec_security->target.service) {
675 188167 : return gensec_security->target.service;
676 : }
677 :
678 9806 : return "host";
679 : }
680 :
681 : /**
682 : * Set the target service (such as 'samr') on an GENSEC context - ensures it is talloc()ed.
683 : *
684 : * This is not the Kerberos service principal, instead this is a
685 : * constant value that can be logged as part of authentication and
686 : * authorization logging
687 : */
688 121879 : _PUBLIC_ NTSTATUS gensec_set_target_service_description(struct gensec_security *gensec_security,
689 : const char *service)
690 : {
691 121879 : gensec_security->target.service_description = talloc_strdup(gensec_security, service);
692 121879 : if (!gensec_security->target.service_description) {
693 0 : return NT_STATUS_NO_MEMORY;
694 : }
695 121879 : return NT_STATUS_OK;
696 : }
697 :
698 106783 : _PUBLIC_ const char *gensec_get_target_service_description(struct gensec_security *gensec_security)
699 : {
700 106783 : if (gensec_security->target.service_description) {
701 103823 : return gensec_security->target.service_description;
702 1466 : } else if (gensec_security->target.service) {
703 166 : return gensec_security->target.service;
704 : }
705 :
706 1300 : return NULL;
707 : }
708 :
709 : /**
710 : * Set the target hostname (suitable for kerberos resolutation) on a GENSEC context - ensures it is talloc()ed
711 : *
712 : */
713 :
714 74264 : _PUBLIC_ NTSTATUS gensec_set_target_hostname(struct gensec_security *gensec_security, const char *hostname)
715 : {
716 74264 : gensec_security->target.hostname = talloc_strdup(gensec_security, hostname);
717 74264 : if (hostname && !gensec_security->target.hostname) {
718 0 : return NT_STATUS_NO_MEMORY;
719 : }
720 74264 : return NT_STATUS_OK;
721 : }
722 :
723 198363 : _PUBLIC_ const char *gensec_get_target_hostname(struct gensec_security *gensec_security)
724 : {
725 : /* We allow the target hostname to be overridden for testing purposes */
726 198363 : if (gensec_security->settings->target_hostname) {
727 4648 : return gensec_security->settings->target_hostname;
728 : }
729 :
730 193715 : if (gensec_security->target.hostname) {
731 157154 : return gensec_security->target.hostname;
732 : }
733 :
734 : /* We could add use the 'set sockaddr' call, and do a reverse
735 : * lookup, but this would be both insecure (compromising the
736 : * way kerberos works) and add DNS timeouts */
737 35584 : return NULL;
738 : }
739 :
740 : /**
741 : * Set (and copy) local and peer socket addresses onto a socket
742 : * context on the GENSEC context.
743 : *
744 : * This is so that kerberos can include these addresses in
745 : * cryptographic tokens, to avoid certain attacks.
746 : */
747 :
748 : /**
749 : * @brief Set the local gensec address.
750 : *
751 : * @param gensec_security The gensec security context to use.
752 : *
753 : * @param remote The local address to set.
754 : *
755 : * @return On success NT_STATUS_OK is returned or an NT_STATUS
756 : * error.
757 : */
758 121943 : _PUBLIC_ NTSTATUS gensec_set_local_address(struct gensec_security *gensec_security,
759 : const struct tsocket_address *local)
760 : {
761 121943 : TALLOC_FREE(gensec_security->local_addr);
762 :
763 121943 : if (local == NULL) {
764 0 : return NT_STATUS_OK;
765 : }
766 :
767 121943 : gensec_security->local_addr = tsocket_address_copy(local, gensec_security);
768 121943 : if (gensec_security->local_addr == NULL) {
769 0 : return NT_STATUS_NO_MEMORY;
770 : }
771 :
772 121943 : return NT_STATUS_OK;
773 : }
774 :
775 : /**
776 : * @brief Set the remote gensec address.
777 : *
778 : * @param gensec_security The gensec security context to use.
779 : *
780 : * @param remote The remote address to set.
781 : *
782 : * @return On success NT_STATUS_OK is returned or an NT_STATUS
783 : * error.
784 : */
785 121875 : _PUBLIC_ NTSTATUS gensec_set_remote_address(struct gensec_security *gensec_security,
786 : const struct tsocket_address *remote)
787 : {
788 121875 : TALLOC_FREE(gensec_security->remote_addr);
789 :
790 121875 : if (remote == NULL) {
791 0 : return NT_STATUS_OK;
792 : }
793 :
794 121875 : gensec_security->remote_addr = tsocket_address_copy(remote, gensec_security);
795 121875 : if (gensec_security->remote_addr == NULL) {
796 0 : return NT_STATUS_NO_MEMORY;
797 : }
798 :
799 121875 : return NT_STATUS_OK;
800 : }
801 :
802 : /**
803 : * @brief Get the local address from a gensec security context.
804 : *
805 : * @param gensec_security The security context to get the address from.
806 : *
807 : * @return The address as tsocket_address which could be NULL if
808 : * no address is set.
809 : */
810 108255 : _PUBLIC_ const struct tsocket_address *gensec_get_local_address(struct gensec_security *gensec_security)
811 : {
812 108255 : if (gensec_security == NULL) {
813 0 : return NULL;
814 : }
815 108255 : return gensec_security->local_addr;
816 : }
817 :
818 : /**
819 : * @brief Get the remote address from a gensec security context.
820 : *
821 : * @param gensec_security The security context to get the address from.
822 : *
823 : * @return The address as tsocket_address which could be NULL if
824 : * no address is set.
825 : */
826 141731 : _PUBLIC_ const struct tsocket_address *gensec_get_remote_address(struct gensec_security *gensec_security)
827 : {
828 141731 : if (gensec_security == NULL) {
829 0 : return NULL;
830 : }
831 141731 : return gensec_security->remote_addr;
832 : }
833 :
834 : /**
835 : * Set the target principal (assuming it it known, say from the SPNEGO reply)
836 : * - ensures it is talloc()ed
837 : *
838 : */
839 :
840 219 : _PUBLIC_ NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal)
841 : {
842 219 : gensec_security->target.principal = talloc_strdup(gensec_security, principal);
843 219 : if (!gensec_security->target.principal) {
844 0 : return NT_STATUS_NO_MEMORY;
845 : }
846 219 : return NT_STATUS_OK;
847 : }
848 :
849 144605 : _PUBLIC_ const char *gensec_get_target_principal(struct gensec_security *gensec_security)
850 : {
851 144605 : if (gensec_security->target.principal) {
852 667 : return gensec_security->target.principal;
853 : }
854 :
855 139999 : return NULL;
856 : }
|