43#if HAVE_GSSAPI && HAVE_PAC_SUPPORT
46static krb5_data *ad_data;
47static unsigned char *p;
50check_k5_err(krb5_context context,
const char *function, krb5_error_code
code);
55 if ( bpos % n != 0 ) {
58 bpos = bpos+(bpos-n*al);
63getustr(RPC_UNICODE_STRING *
string)
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));
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);
89 var=(uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24));
100 var=(uint16_t)((p[bpos]<<0) | (p[bpos+1]<<8));
111 var=(uint8_t)((p[bpos]<<0));
118pstrcpy(
char *src,
const char *dst)
121 if (strlen(dst)>MAX_PAC_GROUP_SIZE)
124 return strcpy(src,dst);
130pstrcat(
char *src,
const char *dst)
133 if (strlen(src)+strlen(dst)+1>MAX_PAC_GROUP_SIZE)
136 return strcat(src,dst);
142checkustr(RPC_UNICODE_STRING *
string)
145 if (string->pointer != 0) {
146 uint32_t
size,off,len;
148 size = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24));
150 off = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24));
152 len = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24));
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",
161 bpos = bpos+
string->length;
167getgids(
char **Rids, uint32_t GroupIds, uint32_t GroupCount)
175 if ( ngroup != GroupCount) {
176 debug((
char *)
"%s| %s: ERROR: Group encoding error => GroupCount: %d Array size: %d\n",
182 Rids=(
char **)
xcalloc(GroupCount*
sizeof(
char*),1);
183 for ( l=0; l<(
int)GroupCount; l++) {
185 Rids[l]=(
char *)
xcalloc(4*
sizeof(
char),1);
186 memcpy((
void *)Rids[l],(
void *)&p[bpos],4);
197getdomaingids(
char *ad_groups, uint32_t DomainLogonId,
char **Rids, uint32_t GroupCount)
200 debug((
char *)
"%s| %s: ERR: No space to store groups\n",
205 if (DomainLogonId!= 0) {
214 uint32_t nauth = get4byt();
217 static uint32_t maxGidCount = (
UINT32_MAX-1-1-6)/4;
218 if (nauth > maxGidCount) {
219 debug((
char *)
"%s| %s: ERROR: Too many groups ! count > %d : %s\n",
223 size_t length = 1+1+6+nauth*4;
226 for (l=0; l<(
int)GroupCount; l++) {
227 ag=(
char *)
xcalloc((length+4)*
sizeof(char),1);
228 memcpy((
void *)ag,(
const void*)&p[bpos],1);
229 memcpy((
void *)&ag[1],(
const void*)&p[bpos+1],1);
231 memcpy((
void *)&ag[2],(
const void*)&p[bpos+2],6+nauth*4);
232 memcpy((
void *)&ag[length],(
const void*)Rids[l],4);
234 if (!pstrcpy(ad_groups,
"group=")) {
235 debug((
char *)
"%s| %s: WARN: Too many groups ! size > %d : %s\n",
239 if (!pstrcat(ad_groups,
" group=")) {
240 debug((
char *)
"%s| %s: WARN: Too many groups ! size > %d : %s\n",
247 char *b64buf =
static_cast<char *
>(
xcalloc(expectedSz, 1));
250 b64buf[expectedSz-1] =
'\0';
251 if (!pstrcat(ad_groups, b64buf)) {
252 debug((
char *)
"%s| %s: WARN: Too many groups ! size > %d : %s\n",
262 idauth = get6byt_be();
264 snprintf(dli,
sizeof(dli),
"S-%d-%lu",rev,(
long unsigned int)idauth);
265 for ( l=0; l<(
int)nauth; l++ ) {
268 snprintf((
char *)&dli[strlen(dli)],
sizeof(dli)-strlen(dli),
"-%u",sauth);
276getextrasids(
char *ad_groups, uint32_t ExtraSids, uint32_t SidCount)
286 if ( ngroup != SidCount) {
287 debug((
char *)
"%s| %s: ERROR: Group encoding error => SidCount: %d Array size: %d\n",
293 pa=(uint32_t *)
xmalloc(SidCount*
sizeof(uint32_t));
294 for ( l=0; l < (
int)SidCount; l++ ) {
299 for ( l=0; l<(
int)SidCount; l++ ) {
306 uint32_t nauth = get4byt();
309 static uint32_t maxGidCount = (
UINT32_MAX-1-1-6)/4;
310 if (nauth > maxGidCount) {
311 debug((
char *)
"%s| %s: ERROR: Too many extra groups ! count > %d : %s\n",
317 size_t length = 1+1+6+nauth*4;
318 ag = (
char *)
xcalloc((length)*
sizeof(char),1);
319 memcpy((
void *)ag,(
const void*)&p[bpos],length);
321 debug((
char *)
"%s| %s: ERR: No space to store groups\n",
327 if (!pstrcat(ad_groups,
" group=")) {
328 debug((
char *)
"%s| %s: WARN: Too many groups ! size > %d : %s\n",
336 char *b64buf =
static_cast<char *
>(
xcalloc(expectedSz, 1));
339 b64buf[expectedSz-1] =
'\0';
340 if (!pstrcat(ad_groups,
reinterpret_cast<char*
>(b64buf))) {
341 debug((
char *)
"%s| %s: WARN: Too many groups ! size > %d : %s\n",
349 idauth = get6byt_be();
351 snprintf(es,
sizeof(es),
"S-%d-%lu",rev,(
long unsigned int)idauth);
352 for (
int k=0; k<(
int)nauth; k++ ) {
355 snprintf((
char *)&es[strlen(es)],
sizeof(es)-strlen(es),
"-%u",sauth);
366get_ad_groups(
char *ad_groups, krb5_context context, krb5_pac pac)
369 RPC_UNICODE_STRING EffectiveName;
370 RPC_UNICODE_STRING FullName;
371 RPC_UNICODE_STRING LogonScript;
372 RPC_UNICODE_STRING ProfilePath;
373 RPC_UNICODE_STRING HomeDirectory;
374 RPC_UNICODE_STRING HomeDirectoryDrive;
375 RPC_UNICODE_STRING LogonServer;
376 RPC_UNICODE_STRING LogonDomainName;
377 uint32_t GroupCount=0;
379 uint32_t LogonDomainId=0;
381 uint32_t ExtraSids=0;
391 debug((
char *)
"%s| %s: ERR: No space to store groups\n",
396 ad_data = (krb5_data *)
xcalloc(1,
sizeof(krb5_data));
398#define KERB_LOGON_INFO 1
399 ret = krb5_pac_get_buffer(context, pac, KERB_LOGON_INFO, ad_data);
403 p = (
unsigned char *)ad_data->data;
405 debug((
char *)
"%s| %s: INFO: Got PAC data of length %d\n",
425 getustr(&EffectiveName);
427 getustr(&LogonScript);
428 getustr(&ProfilePath);
429 getustr(&HomeDirectory);
430 getustr(&HomeDirectoryDrive);
437 GroupCount = get4byt();
438 GroupIds = get4byt();
443 getustr(&LogonServer);
444 getustr(&LogonDomainName);
445 LogonDomainId = get4byt();
455 SidCount = get4byt();
456 ExtraSids = get4byt();
465 if (checkustr(&EffectiveName)<0)
467 if (checkustr(&FullName)<0)
469 if (checkustr(&LogonScript)<0)
471 if (checkustr(&ProfilePath)<0)
473 if (checkustr(&HomeDirectory)<0)
475 if (checkustr(&HomeDirectoryDrive)<0)
477 Rids = getgids(Rids,GroupIds,GroupCount);
478 if (checkustr(&LogonServer)<0)
480 if (checkustr(&LogonDomainName)<0)
482 ad_groups = getdomaingids(ad_groups,LogonDomainId,Rids,GroupCount);
483 if ((ad_groups = getextrasids(ad_groups,ExtraSids,SidCount))==
nullptr)
486 debug((
char *)
"%s| %s: INFO: Read %d of %d bytes \n",
LogTime(),
PROGRAM, bpos, (
int)ad_data->length);
488 for ( l=0; l<(
int)GroupCount; l++) {
493 krb5_free_data(context, ad_data);
497 for ( l=0; l<(
int)GroupCount; l++) {
502 krb5_free_data(context, ad_data);
const char * LogTime(void)
void base64_encode_init(struct base64_encode_ctx *ctx)
size_t base64_encode_update(struct base64_encode_ctx *ctx, char *dst, size_t length, const uint8_t *src)
size_t base64_encode_final(struct base64_encode_ctx *ctx, char *dst)
#define base64_encode_len(length)
void debug(const char *format,...)
int check_k5_err(krb5_context context, const char *msg, krb5_error_code code)
void * xcalloc(size_t n, size_t sz)