Squid Web Cache v8/master
Loading...
Searching...
No Matches
negotiate_kerberos_pac.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2026 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/*
10 * -----------------------------------------------------------------------------
11 *
12 * Author: Markus Moeller (markus_moeller at compuserve.com)
13 *
14 * Copyright (C) 2007 Markus Moeller. All rights reserved.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, see <https://www.gnu.org/licenses/>.
28 *
29 * As a special exemption, M Moeller gives permission to link this program
30 * with MIT, Heimdal or other GSS/Kerberos libraries, and distribute
31 * the resulting executable, without including the source code for
32 * the Libraries in the source distribution.
33 *
34 * -----------------------------------------------------------------------------
35 */
36
37#include "squid.h"
38#include "rfc1738.h"
39
40#include "negotiate_kerberos.h"
41
42#if HAVE_GSSAPI && HAVE_KRB5_PAC_SUPPORT
43
44#define LOGON_EXTRA_SIDS 0x0020
45#define LOGON_RESOURCE_GROUPS 0x0200
46
47static int bpos;
48static krb5_data *ad_data;
49static unsigned char *p;
50
51extern int
52check_k5_err(krb5_context context, const char *function, krb5_error_code code);
53
54void
55align(int n)
56{
57 if (const auto r = bpos % n)
58 bpos += (n - r);
59}
60
61void
62getustr(RPC_UNICODE_STRING *string)
63{
64
65 string->length = (uint16_t)((p[bpos]<<0) | (p[bpos+1]<<8));
66 string->maxlength = (uint16_t)((p[bpos+2]<<0) | (p[bpos+2+1]<<8));
67 string->pointer = (uint32_t)((p[bpos+4]<<0) | (p[bpos+4+1]<<8) | (p[bpos+4+2]<<16) | (p[bpos+4+3]<<24));
68 bpos = bpos+8;
69
70}
71
72uint64_t
73get6byt_be(void)
74{
75 uint64_t var;
76
77 var = ((uint64_t)p[bpos+5]<<0) | ((uint64_t)p[bpos+4]<<8) | ((uint64_t)p[bpos+3]<<16) | ((uint64_t)p[bpos+2]<<24) | ((uint64_t)p[bpos+1]<<32) | ((uint64_t)p[bpos]<<40);
78 bpos = bpos+6;
79
80 return var;
81}
82
83uint32_t
84get4byt(void)
85{
86 uint32_t var;
87
88 var=(uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24));
89 bpos = bpos+4;
90
91 return var;
92}
93
94uint16_t
95get2byt(void)
96{
97 uint16_t var;
98
99 var=(uint16_t)((p[bpos]<<0) | (p[bpos+1]<<8));
100 bpos = bpos+2;
101
102 return var;
103}
104
105uint8_t
106get1byt(void)
107{
108 uint8_t var;
109
110 var=(uint8_t)((p[bpos]<<0));
111 bpos = bpos+1;
112
113 return var;
114}
115
116static char *
117pstrcpy( char *src, const char *dst)
118{
119 if (dst) {
120 if (strlen(dst)>MAX_PAC_GROUP_SIZE)
121 return nullptr;
122 else
123 return strcpy(src,dst);
124 } else
125 return src;
126}
127
128static char *
129pstrcat( char *src, const char *dst)
130{
131 if (dst) {
132 if (strlen(src)+strlen(dst)+1>MAX_PAC_GROUP_SIZE)
133 return nullptr;
134 else
135 return strcat(src,dst);
136 } else
137 return src;
138}
139
140int
141checkustr(RPC_UNICODE_STRING *string)
142{
143
144 if (string->pointer != 0) {
145 uint32_t size,off,len;
146 align(4);
147 size = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24));
148 bpos = bpos+4;
149 off = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24));
150 bpos = bpos+4;
151 len = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24));
152 bpos = bpos+4;
153 if (len > size || off != 0 ||
154 string->length > string->maxlength || len != string->length/2) {
155 debug((char *) "%s| %s: ERROR: RPC_UNICODE_STRING encoding error => size: %d len: %d/%d maxlength: %d offset: %d\n",
156 LogTime(), PROGRAM, size, len, string->length, string->maxlength, off);
157 return -1;
158 }
159 /* UNICODE string */
160 bpos = bpos+string->length;
161 }
162 return 0;
163}
164
165char **
166getgids(char **Rids, uint32_t GroupIds, uint32_t GroupCount)
167{
168 if (GroupIds!= 0) {
169 uint32_t ngroup;
170 int l;
171
172 align(4);
173 ngroup = get4byt();
174 if ( ngroup != GroupCount) {
175 debug((char *) "%s| %s: ERROR: Group encoding error => GroupCount: %d Array size: %d\n",
176 LogTime(), PROGRAM, GroupCount, ngroup);
177 return nullptr;
178 }
179 debug((char *) "%s| %s: INFO: Found %d rids\n", LogTime(), PROGRAM, GroupCount);
180
181 Rids=(char **)xcalloc(GroupCount*sizeof(char*),1);
182 for ( l=0; l<(int)GroupCount; l++) {
183 uint32_t sauth;
184 Rids[l]=(char *)xcalloc(4*sizeof(char),1);
185 memcpy((void *)Rids[l],(void *)&p[bpos],4);
186 sauth = get4byt();
187 debug((char *) "%s| %s: Info: Got rid: %u\n", LogTime(), PROGRAM, sauth);
188 /* attribute */
189 bpos = bpos+4;
190 }
191 }
192 return Rids;
193}
194
195char *
196getdomaingids(char *ad_groups, uint32_t DomainLogonId, char **Rids, uint32_t GroupCount)
197{
198 if (!ad_groups) {
199 debug((char *) "%s| %s: ERR: No space to store groups\n",
200 LogTime(), PROGRAM);
201 return nullptr;
202 }
203
204 if (!Rids) {
205 debug((char *) "%s| %s: ERR: Invalid RIDS list\n",
206 LogTime(), PROGRAM);
207 return nullptr;
208 }
209
210 if (DomainLogonId!= 0) {
211 uint8_t rev;
212 uint64_t idauth;
213 char dli[256];
214 char *ag;
215 int l;
216
217 align(4);
218
219 uint32_t nauth = get4byt();
220
221 // check if nauth math will produce invalid length values on 32-bit
222 static uint32_t maxGidCount = (UINT32_MAX-1-1-6)/4;
223 if (nauth > maxGidCount) {
224 debug((char *) "%s| %s: ERROR: Too many groups ! count > %d : %s\n",
225 LogTime(), PROGRAM, maxGidCount, ad_groups);
226 return nullptr;
227 }
228 size_t length = 1+1+6+nauth*4;
229
230 /* prepend rids with DomainID */
231 for (l=0; l<(int)GroupCount; l++) {
232 ag=(char *)xcalloc((length+4)*sizeof(char),1);
233 memcpy((void *)ag,(const void*)&p[bpos],1);
234 memcpy((void *)&ag[1],(const void*)&p[bpos+1],1);
235 ag[1] = ag[1]+1;
236 memcpy((void *)&ag[2],(const void*)&p[bpos+2],6+nauth*4);
237 memcpy((void *)&ag[length],(const void*)Rids[l],4);
238 if (l==0) {
239 if (!pstrcpy(ad_groups,"group=")) {
240 debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n",
241 LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
242 }
243 } else {
244 if (!pstrcat(ad_groups," group=")) {
245 debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n",
246 LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
247 }
248 }
249 struct base64_encode_ctx ctx;
250 base64_encode_init(&ctx);
251 const uint32_t expectedSz = base64_encode_len(length+4) +1 /* terminator */;
252 char *b64buf = static_cast<char *>(xcalloc(expectedSz, 1));
253 size_t blen = base64_encode_update(&ctx, b64buf, length+4, reinterpret_cast<uint8_t*>(ag));
254 blen += base64_encode_final(&ctx, b64buf+blen);
255 b64buf[expectedSz-1] = '\0';
256 if (!pstrcat(ad_groups, b64buf)) {
257 debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n",
258 LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
259 }
260 xfree(b64buf);
261 xfree(ag);
262 }
263
264 /* mainly for debug only */
265 rev = get1byt();
266 bpos = bpos + 1; /*nsub*/
267 idauth = get6byt_be();
268
269 snprintf(dli,sizeof(dli),"S-%d-%lu",rev,(long unsigned int)idauth);
270 for ( l=0; l<(int)nauth; l++ ) {
271 uint32_t sauth;
272 sauth = get4byt();
273 snprintf((char *)&dli[strlen(dli)],sizeof(dli)-strlen(dli),"-%u",sauth);
274 }
275 debug((char *) "%s| %s: INFO: Got DomainLogonId %s\n", LogTime(), PROGRAM, dli);
276 }
277 return ad_groups;
278}
279
280char *
281getextrasids(char *ad_groups, uint32_t ExtraSids, uint32_t SidCount)
282{
283 if (ExtraSids!= 0) {
284 uint32_t ngroup;
285 uint32_t *pa;
286 char *ag;
287 int l;
288
289 align(4);
290 ngroup = get4byt();
291 if ( ngroup != SidCount) {
292 debug((char *) "%s| %s: ERROR: Group encoding error => SidCount: %d Array size: %d\n",
293 LogTime(), PROGRAM, SidCount, ngroup);
294 return nullptr;
295 }
296 debug((char *) "%s| %s: INFO: Found %d ExtraSIDs\n", LogTime(), PROGRAM, SidCount);
297
298 pa=(uint32_t *)xmalloc(SidCount*sizeof(uint32_t));
299 for ( l=0; l < (int)SidCount; l++ ) {
300 pa[l] = get4byt();
301 bpos = bpos+4; /* attr */
302 }
303
304 for ( l=0; l<(int)SidCount; l++ ) {
305 char es[256];
306
307 if (pa[l] != 0) {
308 uint8_t rev;
309 uint64_t idauth;
310
311 uint32_t nauth = get4byt();
312
313 // check if nauth math will produce invalid length values on 32-bit
314 static uint32_t maxGidCount = (UINT32_MAX-1-1-6)/4;
315 if (nauth > maxGidCount) {
316 debug((char *) "%s| %s: ERROR: Too many extra groups ! count > %d : %s\n",
317 LogTime(), PROGRAM, maxGidCount, ad_groups);
318 xfree(pa);
319 return nullptr;
320 }
321
322 size_t length = 1+1+6+nauth*4;
323 ag = (char *)xcalloc((length)*sizeof(char),1);
324 memcpy((void *)ag,(const void*)&p[bpos],length);
325 if (!ad_groups) {
326 debug((char *) "%s| %s: ERR: No space to store groups\n",
327 LogTime(), PROGRAM);
328 xfree(pa);
329 xfree(ag);
330 return nullptr;
331 } else {
332 if (!pstrcat(ad_groups," group=")) {
333 debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n",
334 LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
335 }
336 }
337
338 struct base64_encode_ctx ctx;
339 base64_encode_init(&ctx);
340 const uint32_t expectedSz = base64_encode_len(length) +1 /* terminator */;
341 char *b64buf = static_cast<char *>(xcalloc(expectedSz, 1));
342 size_t blen = base64_encode_update(&ctx, b64buf, length, reinterpret_cast<uint8_t*>(ag));
343 blen += base64_encode_final(&ctx, b64buf+blen);
344 b64buf[expectedSz-1] = '\0';
345 if (!pstrcat(ad_groups, reinterpret_cast<char*>(b64buf))) {
346 debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n",
347 LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
348 }
349 xfree(b64buf);
350 xfree(ag);
351
352 rev = get1byt();
353 bpos = bpos + 1; /* nsub */
354 idauth = get6byt_be();
355
356 snprintf(es,sizeof(es),"S-%d-%lu",rev,(long unsigned int)idauth);
357 for (int k=0; k<(int)nauth; k++ ) {
358 uint32_t sauth;
359 sauth = get4byt();
360 snprintf((char *)&es[strlen(es)],sizeof(es)-strlen(es),"-%u",sauth);
361 }
362 debug((char *) "%s| %s: INFO: Got ExtraSid %s\n", LogTime(), PROGRAM, es);
363 }
364 }
365 xfree(pa);
366 }
367 return ad_groups;
368}
369
370static char *
371get_resource_group_domain_sid(const uint32_t ResourceGroupDomainSid, size_t &length)
372{
373 if (ResourceGroupDomainSid != 0) {
374 uint8_t rev;
375 uint64_t idauth;
376 char dli[256];
377
378 align(4);
379
380 // ResourceGroupDomainSid structure:
381 // 4 bytes nauth
382 // 1 byte revision = 1
383 // 1 byte nsub (it is equal to the number of dashes minus two)
384 // 6 bytes idauth (for NT Authority it is 5)
385 // 4 bytes sauth1
386 // ... nauth timss
387 // 4 bytes sauthN
388
389 uint32_t nauth = get4byt();
390
391 // check if nauth math will produce invalid length values on 32-bit
392 static uint32_t maxGidCount = (UINT32_MAX - 4 - 1 - 1 - 6)/4;
393 if (nauth > maxGidCount) {
394 debug((char *) "%s| %s: ERROR: Too many subAuths in the ResourceGroupDomainSID: nauth = %d > %d\n",
395 LogTime(), PROGRAM, nauth, maxGidCount);
396 return nullptr;
397 }
398
399 // length = revision[1byte]+nsub[1byte]+idauth[6bytes]+nauth*sauth[4bytes]
400 length = 1 + 1 + 6 + nauth*4;
401
402 auto sid = static_cast<char *>(xcalloc(length, 1));
403 // 1 byte revision
404 // 1 byte nsub
405 // 6 bytes+nauth*4bytes idauth+sauths
406 memcpy((void *)&sid[0], (const void*)&p[bpos], 1);
407 memcpy((void *)&sid[1], (const void*)&p[bpos+1], 1);
408 sid[1]++; // ++ as it will be used in a rid concatenation
409 memcpy((void *)&sid[2], (const void*)&p[bpos+2], 6 + nauth*4);
410
411 /* mainly for debug only */
412 rev = get1byt();
413 bpos = bpos + 1; /* nsub */
414 idauth = get6byt_be();
415
416 int rv = snprintf(dli, sizeof(dli), "S-%d-%lu", rev, (long unsigned int)idauth);
417 assert(rv > 0);
418 for (int l=0; l<(int)nauth; l++) {
419 uint32_t sauth;
420 sauth = get4byt();
421 rv = snprintf((char *)&dli[strlen(dli)], sizeof(dli) - strlen(dli), "-%u", sauth);
422 assert(rv > 0);
423 }
424 debug((char *) "%s| %s: INFO: Got ResourceGroupDomainSid %s\n", LogTime(), PROGRAM, dli);
425 return sid;
426 }
427
428 length = 0;
429 return nullptr;
430}
431
432static bool
433get_resource_groups(char *ad_groups, uint32_t ResourceGroupDomainSid, uint32_t ResourceGroupIds, uint32_t ResourceGroupCount)
434{
435 if (!ad_groups) {
436 debug((char *) "%s| %s: ERR: No space to store resource groups\n",
437 LogTime(), PROGRAM);
438 return false;
439 }
440
441 size_t group_domain_sid_len = 0;
442 const auto resource_group_domain_sid = get_resource_group_domain_sid(ResourceGroupDomainSid, group_domain_sid_len);
443 if (!resource_group_domain_sid)
444 return false;
445
446 if (ResourceGroupIds != 0) {
447 align(4);
448 uint32_t ngroup = get4byt();
449 if (ngroup != ResourceGroupCount) {
450 debug((char *) "%s| %s: ERROR: Group encoding error => ResourceGroupCount: %d != Array size: %d\n",
451 LogTime(), PROGRAM, ResourceGroupCount, ngroup);
452 xfree(resource_group_domain_sid);
453 return false;
454 }
455 debug((char *) "%s| %s: INFO: Found %d Resource Group rids\n", LogTime(), PROGRAM, ResourceGroupCount);
456
457 // prepare a group template which begins with the resource_group_domain_sid
458 size_t length = group_domain_sid_len + 4; // +4 for a rid concatenation
459 auto *st = static_cast<char *>(xcalloc(length, 1));
460
461 memcpy((void *)st, (const void*)resource_group_domain_sid, group_domain_sid_len); // template
462
463 for (int l=0; l < (int)ResourceGroupCount; l++) {
464 uint32_t sauth;
465 memcpy((void *)&st[group_domain_sid_len], (const void*)&p[bpos], 4); // rid concatenation
466
467 if (!pstrcat(ad_groups, " group=")) {
468 debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n",
469 LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
470 }
471
472 struct base64_encode_ctx ctx;
473 base64_encode_init(&ctx);
474 const uint32_t expectedSz = base64_encode_len(length) + 1 /* terminator */;
475 char *b64buf = static_cast<char *>(xcalloc(expectedSz, 1));
476 size_t blen = base64_encode_update(&ctx, b64buf, length, reinterpret_cast<uint8_t*>(st));
477 blen += base64_encode_final(&ctx, b64buf + blen);
478 b64buf[expectedSz - 1] = '\0';
479 if (!pstrcat(ad_groups, reinterpret_cast<char*>(b64buf))) {
480 debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n",
481 LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups);
482 }
483 xfree(b64buf);
484
485 sauth = get4byt();
486 debug((char *) "%s| %s: Info: Got rid: %u\n", LogTime(), PROGRAM, sauth);
487 /* attribute */
488 bpos = bpos + 4;
489 }
490
491 xfree(st);
492 }
493
494 xfree(resource_group_domain_sid);
495 return true;
496}
497
498char *
499get_ad_groups(char *ad_groups, krb5_context context, krb5_pac pac)
500{
501 krb5_error_code ret;
502 RPC_UNICODE_STRING EffectiveName;
503 RPC_UNICODE_STRING FullName;
504 RPC_UNICODE_STRING LogonScript;
505 RPC_UNICODE_STRING ProfilePath;
506 RPC_UNICODE_STRING HomeDirectory;
507 RPC_UNICODE_STRING HomeDirectoryDrive;
508 RPC_UNICODE_STRING LogonServer;
509 RPC_UNICODE_STRING LogonDomainName;
510 uint32_t GroupCount=0;
511 uint32_t GroupIds=0;
512 uint32_t LogonDomainId=0;
513 uint32_t SidCount=0;
514 uint32_t UserFlags=0;
515 uint32_t ExtraSids=0;
516 uint32_t ResourceGroupDomainSid=0;
517 uint32_t ResourceGroupCount=0;
518 uint32_t ResourceGroupIds=0;
519 char **Rids=nullptr;
520 int l=0;
521
522 if (!ad_groups) {
523 debug((char *) "%s| %s: ERR: No space to store groups\n",
524 LogTime(), PROGRAM);
525 return nullptr;
526 }
527
528 ad_data = (krb5_data *)xcalloc(1,sizeof(krb5_data));
529
530#define KERB_LOGON_INFO 1
531 ret = krb5_pac_get_buffer(context, pac, KERB_LOGON_INFO, ad_data);
532 if (check_k5_err(context, "krb5_pac_get_buffer", ret))
533 goto k5clean;
534
535 p = (unsigned char *)ad_data->data;
536
537 debug((char *) "%s| %s: INFO: Got PAC data of length %d\n",
538 LogTime(), PROGRAM, (int)ad_data->length);
539
540 /* Skip 16 bytes icommon RPC header
541 * Skip 4 bytes RPC unique pointer referent
542 * http://msdn.microsoft.com/en-gb/library/cc237933.aspx
543 */
544 /* Some data are pointers to data which follows the main KRB5 LOGON structure =>
545 * So need to read the data
546 * some logical consistency checks are done when analysineg the pointer data
547 */
548 bpos = 20;
549 /* 8 bytes LogonTime
550 * 8 bytes LogoffTime
551 * 8 bytes KickOffTime
552 * 8 bytes PasswordLastSet
553 * 8 bytes PasswordCanChange
554 * 8 bytes PasswordMustChange
555 */
556 bpos = bpos+48;
557 getustr(&EffectiveName);
558 getustr(&FullName);
559 getustr(&LogonScript);
560 getustr(&ProfilePath);
561 getustr(&HomeDirectory);
562 getustr(&HomeDirectoryDrive);
563 /* 2 bytes LogonCount
564 * 2 bytes BadPasswordCount
565 * 4 bytes UserID
566 * 4 bytes PrimaryGroupId
567 */
568 bpos = bpos+12;
569 GroupCount = get4byt();
570 GroupIds = get4byt();
571 UserFlags = get4byt();
573 bpos = bpos+16;
574 getustr(&LogonServer);
575 getustr(&LogonDomainName);
576 LogonDomainId = get4byt();
577 /* 8 bytes Reserved1
578 * 4 bytes UserAccountControl
579 * 4 bytes SubAuthStatus
580 * 8 bytes LastSuccessfullLogon
581 * 8 bytes LastFailedLogon
582 * 4 bytes FailedLogonCount
583 * 4 bytes Reserved2
584 */
585 bpos = bpos+40;
586 SidCount = get4byt();
587 ExtraSids = get4byt();
588
589 ResourceGroupDomainSid = get4byt();
590 ResourceGroupCount = get4byt();
591 ResourceGroupIds = get4byt();
592
593 /*
594 * Read all data from structure => Now check pointers
595 */
596 if (checkustr(&EffectiveName)<0)
597 goto k5clean;
598 if (checkustr(&FullName)<0)
599 goto k5clean;
600 if (checkustr(&LogonScript)<0)
601 goto k5clean;
602 if (checkustr(&ProfilePath)<0)
603 goto k5clean;
604 if (checkustr(&HomeDirectory)<0)
605 goto k5clean;
606 if (checkustr(&HomeDirectoryDrive)<0)
607 goto k5clean;
608 Rids = getgids(Rids,GroupIds,GroupCount);
609 if (checkustr(&LogonServer)<0)
610 goto k5clean;
611 if (checkustr(&LogonDomainName)<0)
612 goto k5clean;
613 ad_groups = getdomaingids(ad_groups,LogonDomainId,Rids,GroupCount);
614
615 // https://learn.microsoft.com/en-us/previous-versions/aa302203(v=msdn.10)?redirectedfrom=MSDN#top-level-pac-structure
616 if ((UserFlags&LOGON_EXTRA_SIDS) != 0) {
617 // EXTRA_SIDS structures are present and valid
618 debug((char *) "%s| %s: Info: EXTRA_SIDS are present\n", LogTime(), PROGRAM);
619 if ((ad_groups = getextrasids(ad_groups,ExtraSids,SidCount)) == nullptr)
620 goto k5clean;
621 }
622
623 if ((UserFlags&LOGON_RESOURCE_GROUPS) != 0 && ResourceGroupDomainSid && ResourceGroupIds && ResourceGroupCount) {
624 // RESOURCE_GROUPS structures are present and valid
625 debug((char *) "%s| %s: Info: RESOURCE_GROUPS are present\n", LogTime(), PROGRAM);
626 if (!get_resource_groups(ad_groups, ResourceGroupDomainSid, ResourceGroupIds, ResourceGroupCount))
627 goto k5clean;
628 }
629
630 debug((char *) "%s| %s: INFO: Read %d of %d bytes \n", LogTime(), PROGRAM, bpos, (int)ad_data->length);
631
632 if (Rids) {
633 for ( l=0; l<(int)GroupCount; l++) {
634 xfree(Rids[l]);
635 }
636 xfree(Rids);
637 }
638 krb5_free_data(context, ad_data);
639 return ad_groups;
640
641k5clean:
642 if (Rids) {
643 for ( l=0; l<(int)GroupCount; l++) {
644 xfree(Rids[l]);
645 }
646 xfree(Rids);
647 }
648 krb5_free_data(context, ad_data);
649 return nullptr;
650}
651
652#endif /* HAVE_GSSAPI && HAVE_KRB5_PAC_SUPPORT */
int size
Definition ModDevPoll.cc:70
#define PROGRAM
Definition support.h:168
const char * LogTime(void)
#define assert(EX)
Definition assert.h:17
void base64_encode_init(struct base64_encode_ctx *ctx)
Definition base64.cc:232
size_t base64_encode_update(struct base64_encode_ctx *ctx, char *dst, size_t length, const uint8_t *src)
Definition base64.cc:265
size_t base64_encode_final(struct base64_encode_ctx *ctx, char *dst)
Definition base64.cc:308
#define base64_encode_len(length)
Definition base64.h:161
void debug(const char *format,...)
Definition debug.cc:19
int check_k5_err(krb5_context context, const char *msg, krb5_error_code code)
#define xfree
#define xmalloc
void unsigned int
Definition stub_fd.cc:16
#define UINT32_MAX
Definition types.h:66
void * xcalloc(size_t n, size_t sz)
Definition xalloc.cc:71