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