Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : kerberos authorization data (PAC) utility library
4 : Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
5 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
6 : Copyright (C) Andrew Tridgell 2001
7 : Copyright (C) Luke Howard 2002-2003
8 : Copyright (C) Stefan Metzmacher 2004-2005
9 : Copyright (C) Guenther Deschner 2005,2007,2008
10 :
11 : This program is free software; you can redistribute it and/or modify
12 : it under the terms of the GNU General Public License as published by
13 : the Free Software Foundation; either version 3 of the License, or
14 : (at your option) any later version.
15 :
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 :
21 : You should have received a copy of the GNU General Public License
22 : along with this program. If not, see <http://www.gnu.org/licenses/>.
23 : */
24 :
25 : #include "includes.h"
26 :
27 : #undef DBGC_CLASS
28 : #define DBGC_CLASS DBGC_AUTH
29 :
30 : #ifdef HAVE_KRB5
31 :
32 : #include "librpc/gen_ndr/ndr_krb5pac.h"
33 : #include "librpc/gen_ndr/auth.h"
34 : #include "auth/common_auth.h"
35 : #include "auth/kerberos/pac_utils.h"
36 : #include "lib/krb5_wrap/krb5_samba.h"
37 :
38 4961 : krb5_error_code check_pac_checksum(DATA_BLOB pac_data,
39 : struct PAC_SIGNATURE_DATA *sig,
40 : krb5_context context,
41 : const krb5_keyblock *keyblock)
42 : {
43 14 : krb5_error_code ret;
44 14 : krb5_checksum cksum;
45 4961 : krb5_keyusage usage = 0;
46 4961 : krb5_boolean checksum_valid = false;
47 14 : krb5_data input;
48 4961 : size_t idx = 0;
49 14 : struct {
50 : krb5_cksumtype cksum_type;
51 : krb5_enctype enc_type;
52 4961 : } supported_types[] = {
53 : {CKSUMTYPE_HMAC_SHA1_96_AES_256, ENCTYPE_AES256_CTS_HMAC_SHA1_96},
54 : {CKSUMTYPE_HMAC_SHA1_96_AES_128, ENCTYPE_AES128_CTS_HMAC_SHA1_96},
55 : /* RFC8009 types. Not supported by AD yet but used by FreeIPA and MIT Kerberos */
56 : {CKSUMTYPE_HMAC_SHA256_128_AES128, ENCTYPE_AES128_CTS_HMAC_SHA256_128},
57 : {CKSUMTYPE_HMAC_SHA384_192_AES256, ENCTYPE_AES256_CTS_HMAC_SHA384_192},
58 : {0, 0},
59 : };
60 :
61 9617 : for(idx = 0; supported_types[idx].cksum_type != 0; idx++) {
62 8453 : if (sig->type == supported_types[idx].cksum_type) {
63 3797 : if (KRB5_KEY_TYPE(keyblock) != supported_types[idx].enc_type) {
64 1927 : return EINVAL;
65 : }
66 : /* ok */
67 1870 : break;
68 : }
69 : }
70 :
71 : /* do not do key type check for HMAC-MD5 */
72 3034 : if ((sig->type != CKSUMTYPE_HMAC_MD5) &&
73 1914 : (supported_types[idx].cksum_type == 0)) {
74 44 : DEBUG(2,("check_pac_checksum: Checksum Type %d is not supported\n",
75 : (int)sig->type));
76 44 : return EINVAL;
77 : }
78 :
79 : #ifdef HAVE_CHECKSUM_IN_KRB5_CHECKSUM /* Heimdal */
80 1968 : cksum.cksumtype = (krb5_cksumtype)sig->type;
81 1968 : cksum.checksum.length = sig->signature.length;
82 1968 : cksum.checksum.data = sig->signature.data;
83 : #else /* MIT */
84 1022 : cksum.checksum_type = (krb5_cksumtype)sig->type;
85 1022 : cksum.length = sig->signature.length;
86 1022 : cksum.contents = sig->signature.data;
87 : #endif
88 :
89 : #ifdef HAVE_KRB5_KU_OTHER_CKSUM /* Heimdal */
90 1968 : usage = KRB5_KU_OTHER_CKSUM;
91 : #elif defined(HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM) /* MIT */
92 1022 : usage = KRB5_KEYUSAGE_APP_DATA_CKSUM;
93 : #else
94 : #error UNKNOWN_KRB5_KEYUSAGE
95 : #endif
96 :
97 2990 : input.data = (char *)pac_data.data;
98 2990 : input.length = pac_data.length;
99 :
100 2990 : ret = krb5_c_verify_checksum(context,
101 : keyblock,
102 : usage,
103 : &input,
104 : &cksum,
105 : &checksum_valid);
106 2990 : if (!checksum_valid) {
107 802 : ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
108 : }
109 2990 : if (ret){
110 802 : DEBUG(2,("check_pac_checksum: PAC Verification failed: %s (%d)\n",
111 : error_message(ret), ret));
112 802 : return ret;
113 : }
114 :
115 2174 : return ret;
116 : }
117 :
118 : /**
119 : * @brief Decode a blob containing a NDR encoded PAC structure
120 : *
121 : * @param mem_ctx - The memory context
122 : * @param pac_data_blob - The data blob containing the NDR encoded data
123 : * @param context - The Kerberos Context
124 : * @param service_keyblock - The Service Key used to verify the checksum
125 : * @param client_principal - The client principal
126 : * @param tgs_authtime - The ticket timestamp
127 : * @param pac_data_out - [out] The decoded PAC
128 : *
129 : * @return - A NTSTATUS error code
130 : */
131 4804 : NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,
132 : DATA_BLOB pac_data_blob,
133 : krb5_context context,
134 : const krb5_keyblock *krbtgt_keyblock,
135 : const krb5_keyblock *service_keyblock,
136 : krb5_const_principal client_principal,
137 : time_t tgs_authtime,
138 : struct PAC_DATA **pac_data_out)
139 : {
140 7 : NTSTATUS status;
141 7 : enum ndr_err_code ndr_err;
142 7 : krb5_error_code ret;
143 7 : DATA_BLOB modified_pac_blob;
144 :
145 7 : NTTIME tgs_authtime_nttime;
146 7 : int i;
147 :
148 4804 : struct PAC_SIGNATURE_DATA *srv_sig_ptr = NULL;
149 4804 : struct PAC_SIGNATURE_DATA *kdc_sig_ptr = NULL;
150 4804 : struct PAC_SIGNATURE_DATA *srv_sig_wipe = NULL;
151 4804 : struct PAC_SIGNATURE_DATA *kdc_sig_wipe = NULL;
152 4804 : struct PAC_LOGON_NAME *logon_name = NULL;
153 4804 : struct PAC_LOGON_INFO *logon_info = NULL;
154 4804 : struct PAC_DATA *pac_data = NULL;
155 4804 : struct PAC_DATA_RAW *pac_data_raw = NULL;
156 :
157 4804 : DATA_BLOB *srv_sig_blob = NULL;
158 4804 : DATA_BLOB *kdc_sig_blob = NULL;
159 :
160 7 : bool bool_ret;
161 :
162 4804 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
163 4804 : if (!tmp_ctx) {
164 0 : return NT_STATUS_NO_MEMORY;
165 : }
166 :
167 4804 : if (pac_data_out) {
168 3550 : *pac_data_out = NULL;
169 : }
170 :
171 4804 : pac_data = talloc(tmp_ctx, struct PAC_DATA);
172 4804 : pac_data_raw = talloc(tmp_ctx, struct PAC_DATA_RAW);
173 4804 : kdc_sig_wipe = talloc(tmp_ctx, struct PAC_SIGNATURE_DATA);
174 4804 : srv_sig_wipe = talloc(tmp_ctx, struct PAC_SIGNATURE_DATA);
175 4804 : if (!pac_data_raw || !pac_data || !kdc_sig_wipe || !srv_sig_wipe) {
176 0 : talloc_free(tmp_ctx);
177 0 : return NT_STATUS_NO_MEMORY;
178 : }
179 :
180 4804 : ndr_err = ndr_pull_struct_blob(&pac_data_blob, pac_data, pac_data,
181 : (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
182 4804 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
183 0 : status = ndr_map_error2ntstatus(ndr_err);
184 0 : DEBUG(0,("can't parse the PAC: %s\n",
185 : nt_errstr(status)));
186 0 : talloc_free(tmp_ctx);
187 0 : return status;
188 : }
189 :
190 4804 : if (pac_data->num_buffers < 4) {
191 : /* we need logon_info, service_key and kdc_key */
192 0 : DEBUG(0,("less than 4 PAC buffers\n"));
193 0 : talloc_free(tmp_ctx);
194 0 : return NT_STATUS_INVALID_PARAMETER;
195 : }
196 :
197 4804 : ndr_err = ndr_pull_struct_blob(
198 : &pac_data_blob, pac_data_raw, pac_data_raw,
199 : (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW);
200 4804 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
201 0 : status = ndr_map_error2ntstatus(ndr_err);
202 0 : DEBUG(0,("can't parse the PAC: %s\n",
203 : nt_errstr(status)));
204 0 : talloc_free(tmp_ctx);
205 0 : return status;
206 : }
207 :
208 4804 : if (pac_data_raw->num_buffers < 4) {
209 : /* we need logon_info, service_key and kdc_key */
210 0 : DEBUG(0,("less than 4 PAC buffers\n"));
211 0 : talloc_free(tmp_ctx);
212 0 : return NT_STATUS_INVALID_PARAMETER;
213 : }
214 :
215 4804 : if (pac_data->num_buffers != pac_data_raw->num_buffers) {
216 : /* we need logon_info, service_key and kdc_key */
217 0 : DEBUG(0, ("misparse! PAC_DATA has %d buffers while "
218 : "PAC_DATA_RAW has %d\n", pac_data->num_buffers,
219 : pac_data_raw->num_buffers));
220 0 : talloc_free(tmp_ctx);
221 0 : return NT_STATUS_INVALID_PARAMETER;
222 : }
223 :
224 41084 : for (i=0; i < pac_data->num_buffers; i++) {
225 36280 : struct PAC_BUFFER *data_buf = &pac_data->buffers[i];
226 36280 : struct PAC_BUFFER_RAW *raw_buf = &pac_data_raw->buffers[i];
227 :
228 36280 : if (data_buf->type != raw_buf->type) {
229 0 : DEBUG(0, ("misparse! PAC_DATA buffer %d has type "
230 : "%d while PAC_DATA_RAW has %d\n", i,
231 : data_buf->type, raw_buf->type));
232 0 : talloc_free(tmp_ctx);
233 0 : return NT_STATUS_INVALID_PARAMETER;
234 : }
235 36280 : switch (data_buf->type) {
236 4804 : case PAC_TYPE_LOGON_INFO:
237 4804 : if (!data_buf->info) {
238 0 : break;
239 : }
240 4804 : logon_info = data_buf->info->logon_info.info;
241 4804 : break;
242 4804 : case PAC_TYPE_SRV_CHECKSUM:
243 4804 : if (!data_buf->info) {
244 0 : break;
245 : }
246 4804 : srv_sig_ptr = &data_buf->info->srv_cksum;
247 4804 : srv_sig_blob = &raw_buf->info->remaining;
248 4804 : break;
249 4804 : case PAC_TYPE_KDC_CHECKSUM:
250 4804 : if (!data_buf->info) {
251 0 : break;
252 : }
253 4804 : kdc_sig_ptr = &data_buf->info->kdc_cksum;
254 4804 : kdc_sig_blob = &raw_buf->info->remaining;
255 4804 : break;
256 4804 : case PAC_TYPE_LOGON_NAME:
257 4804 : logon_name = &data_buf->info->logon_name;
258 4804 : break;
259 17064 : default:
260 17064 : break;
261 : }
262 : }
263 :
264 4804 : if (!logon_info) {
265 0 : DEBUG(0,("PAC no logon_info\n"));
266 0 : talloc_free(tmp_ctx);
267 0 : return NT_STATUS_INVALID_PARAMETER;
268 : }
269 :
270 4804 : if (!logon_name) {
271 0 : DEBUG(0,("PAC no logon_name\n"));
272 0 : talloc_free(tmp_ctx);
273 0 : return NT_STATUS_INVALID_PARAMETER;
274 : }
275 :
276 4804 : if (!srv_sig_ptr || !srv_sig_blob) {
277 0 : DEBUG(0,("PAC no srv_key\n"));
278 0 : talloc_free(tmp_ctx);
279 0 : return NT_STATUS_INVALID_PARAMETER;
280 : }
281 :
282 4804 : if (!kdc_sig_ptr || !kdc_sig_blob) {
283 0 : DEBUG(0,("PAC no kdc_key\n"));
284 0 : talloc_free(tmp_ctx);
285 0 : return NT_STATUS_INVALID_PARAMETER;
286 : }
287 :
288 : /* Find and zero out the signatures,
289 : * as required by the signing algorithm */
290 :
291 : /* We find the data blobs above,
292 : * now we parse them to get at the exact portion we should zero */
293 4804 : ndr_err = ndr_pull_struct_blob(
294 : kdc_sig_blob, kdc_sig_wipe, kdc_sig_wipe,
295 : (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
296 4804 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
297 0 : status = ndr_map_error2ntstatus(ndr_err);
298 0 : DEBUG(0,("can't parse the KDC signature: %s\n",
299 : nt_errstr(status)));
300 0 : talloc_free(tmp_ctx);
301 0 : return status;
302 : }
303 :
304 4804 : ndr_err = ndr_pull_struct_blob(
305 : srv_sig_blob, srv_sig_wipe, srv_sig_wipe,
306 : (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
307 4804 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
308 0 : status = ndr_map_error2ntstatus(ndr_err);
309 0 : DEBUG(0,("can't parse the SRV signature: %s\n",
310 : nt_errstr(status)));
311 0 : talloc_free(tmp_ctx);
312 0 : return status;
313 : }
314 :
315 : /* Now zero the decoded structure */
316 4804 : memset(kdc_sig_wipe->signature.data,
317 : '\0', kdc_sig_wipe->signature.length);
318 4804 : memset(srv_sig_wipe->signature.data,
319 : '\0', srv_sig_wipe->signature.length);
320 :
321 : /* and re-encode, back into the same place it came from */
322 4804 : ndr_err = ndr_push_struct_blob(
323 : kdc_sig_blob, pac_data_raw, kdc_sig_wipe,
324 : (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
325 4804 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
326 0 : status = ndr_map_error2ntstatus(ndr_err);
327 0 : DEBUG(0,("can't repack the KDC signature: %s\n",
328 : nt_errstr(status)));
329 0 : talloc_free(tmp_ctx);
330 0 : return status;
331 : }
332 4804 : ndr_err = ndr_push_struct_blob(
333 : srv_sig_blob, pac_data_raw, srv_sig_wipe,
334 : (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
335 4804 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
336 0 : status = ndr_map_error2ntstatus(ndr_err);
337 0 : DEBUG(0,("can't repack the SRV signature: %s\n",
338 : nt_errstr(status)));
339 0 : talloc_free(tmp_ctx);
340 0 : return status;
341 : }
342 :
343 : /* push out the whole structure, but now with zero'ed signatures */
344 4804 : ndr_err = ndr_push_struct_blob(
345 : &modified_pac_blob, pac_data_raw, pac_data_raw,
346 : (ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW);
347 4804 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
348 0 : status = ndr_map_error2ntstatus(ndr_err);
349 0 : DEBUG(0,("can't repack the RAW PAC: %s\n",
350 : nt_errstr(status)));
351 0 : talloc_free(tmp_ctx);
352 0 : return status;
353 : }
354 :
355 4804 : if (service_keyblock) {
356 : /* verify by service_key */
357 4786 : ret = check_pac_checksum(modified_pac_blob, srv_sig_ptr,
358 : context,
359 : service_keyblock);
360 4786 : if (ret) {
361 2655 : DEBUG(5, ("PAC Decode: Failed to verify the service "
362 : "signature: %s\n", error_message(ret)));
363 2655 : return NT_STATUS_ACCESS_DENIED;
364 : }
365 :
366 2131 : if (krbtgt_keyblock) {
367 : /* verify the service key checksum by krbtgt_key */
368 7 : ret = check_pac_checksum(srv_sig_ptr->signature, kdc_sig_ptr,
369 : context, krbtgt_keyblock);
370 7 : if (ret) {
371 0 : DEBUG(1, ("PAC Decode: Failed to verify the KDC signature: %s\n",
372 : smb_get_krb5_error_message(context, ret, tmp_ctx)));
373 0 : talloc_free(tmp_ctx);
374 0 : return NT_STATUS_ACCESS_DENIED;
375 : }
376 : }
377 : }
378 :
379 2149 : if (tgs_authtime) {
380 : /* Convert to NT time, so as not to lose accuracy in comparison */
381 1261 : unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime);
382 :
383 1261 : if (tgs_authtime_nttime != logon_name->logon_time) {
384 1 : DEBUG(2, ("PAC Decode: "
385 : "Logon time mismatch between ticket and PAC!\n"));
386 1 : DEBUG(2, ("PAC Decode: PAC: %s\n",
387 : nt_time_string(tmp_ctx, logon_name->logon_time)));
388 1 : DEBUG(2, ("PAC Decode: Ticket: %s\n",
389 : nt_time_string(tmp_ctx, tgs_authtime_nttime)));
390 1 : talloc_free(tmp_ctx);
391 1 : return NT_STATUS_ACCESS_DENIED;
392 : }
393 : }
394 :
395 2148 : if (client_principal) {
396 6 : char *client_principal_string;
397 1260 : ret = krb5_unparse_name_flags(context, client_principal,
398 : KRB5_PRINCIPAL_UNPARSE_NO_REALM|KRB5_PRINCIPAL_UNPARSE_DISPLAY,
399 : &client_principal_string);
400 1260 : if (ret) {
401 0 : DEBUG(2, ("Could not unparse name from ticket to match with name from PAC: [%s]:%s\n",
402 : logon_name->account_name, error_message(ret)));
403 0 : talloc_free(tmp_ctx);
404 0 : return NT_STATUS_INVALID_PARAMETER;
405 : }
406 :
407 1260 : bool_ret = strcmp(client_principal_string, logon_name->account_name) == 0;
408 :
409 1260 : if (!bool_ret) {
410 2 : DEBUG(2, ("Name in PAC [%s] does not match principal name "
411 : "in ticket [%s]\n",
412 : logon_name->account_name,
413 : client_principal_string));
414 2 : SAFE_FREE(client_principal_string);
415 2 : talloc_free(tmp_ctx);
416 2 : return NT_STATUS_ACCESS_DENIED;
417 : }
418 1258 : SAFE_FREE(client_principal_string);
419 :
420 : }
421 :
422 2146 : DEBUG(3,("Found account name from PAC: %s [%s]\n",
423 : logon_info->info3.base.account_name.string,
424 : logon_info->info3.base.full_name.string));
425 :
426 2146 : DEBUG(10,("Successfully validated Kerberos PAC\n"));
427 :
428 2146 : if (DEBUGLEVEL >= 10) {
429 0 : const char *s;
430 0 : s = NDR_PRINT_STRUCT_STRING(tmp_ctx, PAC_DATA, pac_data);
431 0 : if (s) {
432 0 : DEBUGADD(10,("%s\n", s));
433 : }
434 : }
435 :
436 2146 : if (pac_data_out) {
437 892 : *pac_data_out = talloc_steal(mem_ctx, pac_data);
438 : }
439 :
440 2146 : return NT_STATUS_OK;
441 : }
442 :
443 20 : NTSTATUS kerberos_pac_logon_info(TALLOC_CTX *mem_ctx,
444 : DATA_BLOB blob,
445 : krb5_context context,
446 : const krb5_keyblock *krbtgt_keyblock,
447 : const krb5_keyblock *service_keyblock,
448 : krb5_const_principal client_principal,
449 : time_t tgs_authtime,
450 : struct PAC_LOGON_INFO **logon_info)
451 : {
452 2 : NTSTATUS nt_status;
453 2 : struct PAC_DATA *pac_data;
454 2 : int i;
455 20 : nt_status = kerberos_decode_pac(mem_ctx,
456 : blob,
457 : context,
458 : krbtgt_keyblock,
459 : service_keyblock,
460 : client_principal,
461 : tgs_authtime,
462 : &pac_data);
463 20 : if (!NT_STATUS_IS_OK(nt_status)) {
464 0 : return nt_status;
465 : }
466 :
467 20 : *logon_info = NULL;
468 148 : for (i=0; i < pac_data->num_buffers; i++) {
469 128 : if (pac_data->buffers[i].type != PAC_TYPE_LOGON_INFO) {
470 108 : continue;
471 : }
472 20 : *logon_info = pac_data->buffers[i].info->logon_info.info;
473 : }
474 20 : if (!*logon_info) {
475 0 : return NT_STATUS_INVALID_PARAMETER;
476 : }
477 20 : return NT_STATUS_OK;
478 : }
479 :
480 0 : static NTSTATUS auth4_context_fetch_PAC_DATA_CTR(
481 : struct auth4_context *auth_ctx,
482 : TALLOC_CTX *mem_ctx,
483 : struct smb_krb5_context *smb_krb5_context,
484 : DATA_BLOB *pac_blob,
485 : const char *princ_name,
486 : const struct tsocket_address *remote_address,
487 : uint32_t session_info_flags,
488 : struct auth_session_info **session_info)
489 : {
490 0 : struct PAC_DATA_CTR *pac_data_ctr = NULL;
491 0 : NTSTATUS status;
492 :
493 0 : if (pac_blob == NULL) {
494 0 : return NT_STATUS_NO_IMPERSONATION_TOKEN;
495 : }
496 :
497 0 : pac_data_ctr = talloc_zero(mem_ctx, struct PAC_DATA_CTR);
498 0 : if (pac_data_ctr == NULL) {
499 0 : status = NT_STATUS_NO_MEMORY;
500 0 : goto fail;
501 : }
502 :
503 0 : status = kerberos_decode_pac(pac_data_ctr,
504 : *pac_blob,
505 : NULL,
506 : NULL,
507 : NULL,
508 : NULL,
509 : 0,
510 0 : &pac_data_ctr->pac_data);
511 0 : if (!NT_STATUS_IS_OK(status)) {
512 0 : goto fail;
513 : }
514 :
515 0 : pac_data_ctr->pac_blob = data_blob_talloc(pac_data_ctr,
516 : pac_blob->data,
517 : pac_blob->length);
518 0 : if (pac_data_ctr->pac_blob.length != pac_blob->length) {
519 0 : status = NT_STATUS_NO_MEMORY;
520 0 : goto fail;
521 : }
522 :
523 0 : *session_info = talloc_zero(mem_ctx, struct auth_session_info);
524 0 : if (*session_info == NULL) {
525 0 : status = NT_STATUS_NO_MEMORY;
526 0 : goto fail;
527 : }
528 :
529 0 : TALLOC_FREE(auth_ctx->private_data);
530 0 : auth_ctx->private_data = talloc_move(auth_ctx, &pac_data_ctr);
531 :
532 0 : return NT_STATUS_OK;
533 :
534 0 : fail:
535 0 : TALLOC_FREE(pac_data_ctr);
536 :
537 0 : return status;
538 : }
539 :
540 0 : struct auth4_context *auth4_context_for_PAC_DATA_CTR(TALLOC_CTX *mem_ctx)
541 : {
542 0 : struct auth4_context *auth_ctx = NULL;
543 :
544 0 : auth_ctx = talloc_zero(mem_ctx, struct auth4_context);
545 0 : if (auth_ctx == NULL) {
546 0 : return NULL;
547 : }
548 0 : auth_ctx->generate_session_info_pac = auth4_context_fetch_PAC_DATA_CTR;
549 :
550 0 : return auth_ctx;
551 : }
552 :
553 0 : struct PAC_DATA_CTR *auth4_context_get_PAC_DATA_CTR(struct auth4_context *auth_ctx,
554 : TALLOC_CTX *mem_ctx)
555 : {
556 0 : struct PAC_DATA_CTR *p = NULL;
557 0 : SMB_ASSERT(auth_ctx->generate_session_info_pac == auth4_context_fetch_PAC_DATA_CTR);
558 0 : p = talloc_get_type_abort(auth_ctx->private_data, struct PAC_DATA_CTR);
559 0 : auth_ctx->private_data = NULL;
560 0 : return talloc_move(mem_ctx, &p);
561 : }
562 :
563 : #endif
|