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 
48 static int bpos;
49 static krb5_data *ad_data;
50 static unsigned char *p;
51 
52 extern int
53 check_k5_err(krb5_context context, const char *function, krb5_error_code code);
54 
55 void
56 align(int n)
57 {
58  if (const auto r = bpos % n)
59  bpos += (n - r);
60 }
61 
62 void
63 getustr(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 
73 uint64_t
74 get6byt_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 
84 uint32_t
85 get4byt(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 
95 uint16_t
96 get2byt(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 
106 uint8_t
107 get1byt(void)
108 {
109  uint8_t var;
110 
111  var=(uint8_t)((p[bpos]<<0));
112  bpos = bpos+1;
113 
114  return var;
115 }
116 
117 static char *
118 pstrcpy( 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 
129 static char *
130 pstrcat( 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 
141 int
142 checkustr(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 
166 char **
167 getgids(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 
196 char *
197 getdomaingids(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 
281 char *
282 getextrasids(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 
371 static char *
372 get_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 
433 static bool
434 get_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 
499 char *
500 get_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 
642 k5clean:
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 
void * xcalloc(size_t n, size_t sz)
Definition: xalloc.cc:71
#define base64_encode_len(length)
Definition: base64.h:169
#define xmalloc
#define PROGRAM
Definition: support.h:169
void debug(const char *format,...)
Definition: debug.cc:19
size_t base64_encode_final(struct base64_encode_ctx *ctx, char *dst)
Definition: base64.c:308
int check_k5_err(krb5_context context, const char *msg, krb5_error_code code)
#define UINT32_MAX
Definition: types.h:66
int size
Definition: ModDevPoll.cc:70
#define assert(EX)
Definition: assert.h:17
void base64_encode_init(struct base64_encode_ctx *ctx)
Definition: base64.c:232
const char * LogTime(void)
#define xfree
size_t base64_encode_update(struct base64_encode_ctx *ctx, char *dst, size_t length, const uint8_t *src)
Definition: base64.c:265
int unsigned int
Definition: stub_fd.cc:19

 

Introduction

Documentation

Support

Miscellaneous