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