From e0681490b4ef4dcbaaebb787eb75bf25675ee23b Mon Sep 17 00:00:00 2001 From: Jordan Filteau Date: Thu, 21 Nov 2019 14:36:32 -0500 Subject: [PATCH] Bugfixes and features for v1.7.1 Signed-off-by: Jordan Filteau --- c/zis/services/secmgmttss.c | 294 +++++++++++++++++++++++++++++++++--- h/zis/services/tssparsing.h | 8 +- 2 files changed, 279 insertions(+), 23 deletions(-) diff --git a/c/zis/services/secmgmttss.c b/c/zis/services/secmgmttss.c index e1037a02c..689aefb62 100644 --- a/c/zis/services/secmgmttss.c +++ b/c/zis/services/secmgmttss.c @@ -219,7 +219,7 @@ static unsigned int getAcidsInLine(const RadminVLText *currentLine, TSSAcidData unsigned int acidCounter = 0; for (int i = 0; i < 4; i++) { char tmpBuffer[11] = {0}; /* Acid - 8, Admin Indicator - 3 */ - + /* Line can start with spaces. Make sure we get to the actual output. */ for (int j = startPos; j < currentLine->length; j++) { if (currentLine->text[j] != ' ') { @@ -227,38 +227,45 @@ static unsigned int getAcidsInLine(const RadminVLText *currentLine, TSSAcidData break; } } - + /* Check that we aren't going out of bounds. If we reach end of line, * copy up to that index. */ int copySize = sizeof(tmpBuffer); - if (startPos + copySize > currentLine->length - 1) { - copySize = (currentLine->length - 1) - startPos; + + if (startPos + copySize > currentLine->length) { + copySize = currentLine->length - startPos; } - + if (copySize <= 0) { return acidCounter; /* Probably less than four acids on this line... */ } - + memcpy(tmpBuffer, currentLine->text+startPos, copySize); - + memcpy(data[i].acid, tmpBuffer, sizeof(data[i].acid)); + padWithSpaces(data[i].acid, sizeof(data[i].acid), 1, 1); /* All other values are padded with spaces. */ - - int isAdmin = lastIndexOfString(tmpBuffer, sizeof(tmpBuffer), TSS_ADMIN_INDICATOR); - if (isAdmin == -1) { - data[i].isAdmin = FALSE; - } - else { - data[i].isAdmin = TRUE; + + const char *adminIndicators[] = { TSS_ADMIN_INDICATOR_MASTER, TSS_ADMIN_INDICATOR_CENTRAL, + TSS_ADMIN_INDICATOR_LSCA, TSS_ADMIN_INDICATOR_ZCA, + TSS_ADMIN_INDICATOR_VCA, TSS_ADMIN_INDICATOR_DCA }; + + data[i].isAdmin = FALSE; + for (int i = 0; i < sizeof(adminIndicators) / sizeof(adminIndicators[0]); i++) { + int adminIndex = lastIndexOfString(tmpBuffer, sizeof(tmpBuffer), (char*)adminIndicators[i]); + if (adminIndex != -1) { + data[i].isAdmin = TRUE; + break; + } } - + #define ACID_OFFSET 12 startPos+=ACID_OFFSET; /* This is safe enough. */ acidCounter++; } - + CMS_DEBUG2(logData->globalArea, logData->traceLevel, "Returning %d acids...\n", acidCounter); @@ -266,6 +273,163 @@ static unsigned int getAcidsInLine(const RadminVLText *currentLine, TSSAcidData } +typedef struct TSSCallerProfileParms_t { + bool extractGroups; + char *searchGroup; + bool isInGroup; + + bool extractProfiles; + char *searchClass; + ZISGenresProfileEntry *profiles; + unsigned int profilesExtracted; + unsigned int profilesToExtract; + char *filterByPrefix; + char *filterByProfile; + + TSSLogData *logData; +} TSSCallerProfileParms; + +static int callerProfileHandler(RadminAPIStatus status, const RadminCommandOutput *result, + void *userData) { + if (status.racfRC != 0) { + return -1; + } + + TSSCallerProfileParms *parms = userData; + ZISGenresProfileEntry *buffer = parms->profiles; + TSSLogData *logData = parms->logData; + ZISGenresProfileEntry entry = {0}; + + const RadminCommandOutput *currentBlock = result; + + if (currentBlock == NULL) { + CMS_DEBUG2(logData->globalArea, logData->traceLevel, + "No output was found in output message entry on first block...\n"); + return 0; + } + + const RadminVLText *currentLine = ¤tBlock->firstMessageEntry; + + /* Look for an obvious error before we start parsing. + * The output will look something like: + * + * TSS{SOME NUMBERS} {SOME MESSAGE} + * TSS0301I TSS FUNCTION FAILED, RETURN CODE = {SOME NUMBER} + */ + bool errorDetected = tssIsErrorDetected(currentLine->text, currentLine->length); + if (errorDetected) { + CMS_DEBUG2(logData->globalArea, logData->traceLevel, + "Error detected!\n"); + CMS_DEBUG2(logData->globalArea, logData->traceLevel, + "%.*s\n", currentLine->length, currentLine->text); + return -1; + } + + bool foundStartProfile = FALSE; + unsigned int offsetInBlock = 16; + unsigned int numExtracted = 0; + do { + while (offsetInBlock < currentBlock->lastByteOffset) { + if (numExtracted == parms->profilesToExtract || tssIsOutputDone(currentLine->text, currentLine->length)) { + parms->profilesExtracted = numExtracted; + return 0; + } + + TSSKeyData keys[TSS_MAX_NUM_OF_KEYS] = {0}; + + int numberOfKeys = tssParseLineForKeys(currentLine->text, currentLine->length, keys); + if (numberOfKeys == -1) { + /* In this case, print the line in question. */ + CMS_DEBUG2(logData->globalArea, logData->traceLevel, + "An invalid number of keys were detected on line: '" + "%.*s'\n", currentLine->length, currentLine->text); + return -1; + } + else { + if (parms->extractGroups && !parms->isInGroup) { + int keyIndex = tssFindDesiredKey(TSS_PROFILE_KEY, keys); + if (keyIndex != -1) { + int groupIndex = lastIndexOfString((char*)currentLine->text, currentLine->length, parms->searchGroup); + if (groupIndex != -1) { + parms->isInGroup = TRUE; + } + } + } + + if (parms->extractProfiles) { + char tmpKey[12] = {0}; + snprintf(tmpKey, sizeof(tmpKey), "XA %s", parms->searchClass); + + int keyIndex = tssFindDesiredKey(tmpKey, keys); + if (keyIndex != -1) { + int ownerIndex = lastIndexOfString((char*)currentLine->text, currentLine->length, TSS_OWNER_KEY); + if (ownerIndex != -1) { + char currOwner[ZIS_USER_ID_MAX_LENGTH] = {0}; + memcpy(currOwner, currentLine->text+ownerIndex+6, sizeof(currOwner)); + padWithSpaces(currOwner, sizeof(currOwner), 1, 1); + + int status = tssFindValueForKey(currentLine->text, ownerIndex-1, keys, + keyIndex, numberOfKeys, entry.profile, + sizeof(entry.profile)); + if (status != -1) { + if (parms->filterByPrefix) { + if (!memcmp(entry.profile, parms->filterByPrefix, strlen(parms->filterByPrefix))) { + CMS_DEBUG2(logData->globalArea, logData->traceLevel, + "Found value with prefix!\n"); + ZISGenresProfileEntry *p = &buffer[numExtracted++]; + memset(p, 0, sizeof(*p)); + memcpy(p->profile, entry.profile, sizeof(p->profile)); + memcpy(p->owner, currOwner, sizeof(p->owner)); + memset(&entry, 0, sizeof(ZISGenresProfileEntry)); + } + } + else if (parms->filterByProfile) { + if (!foundStartProfile) { + if (!memcmp(entry.profile, parms->filterByProfile, strlen(parms->filterByProfile))) { + ZISGenresProfileEntry *p = &buffer[numExtracted++]; + memset(p, 0, sizeof(*p)); + memcpy(p->profile, entry.profile, sizeof(p->profile)); + memcpy(p->owner, currOwner, sizeof(p->owner)); + memset(&entry, 0, sizeof(ZISGenresProfileEntry)); + foundStartProfile = TRUE; + } + } + else { + ZISGenresProfileEntry *p = &buffer[numExtracted++]; + memset(p, 0, sizeof(*p)); + memcpy(p->profile, entry.profile, sizeof(p->profile)); + memcpy(p->owner, currOwner, sizeof(p->owner)); + memset(&entry, 0, sizeof(ZISGenresProfileEntry)); + } + } + else { + ZISGenresProfileEntry *p = &buffer[numExtracted++]; + memset(p, 0, sizeof(*p)); + memcpy(p->profile, entry.profile, sizeof(p->profile)); + memcpy(p->owner, currOwner, sizeof(p->owner)); + memset(&entry, 0, sizeof(ZISGenresProfileEntry)); + } + } + } + } + } + } + + offsetInBlock += currentLine->length + 2; + currentLine = (RadminVLText *)(currentLine->text + currentLine->length); + } + + currentBlock = currentBlock->next; + if (currentBlock != NULL) { + currentLine = (RadminVLText *)&(currentBlock->firstMessageEntry); + offsetInBlock = 16; + } +} while (currentBlock != NULL); + + return 0; +} + + /* A parameter list passed into the handler function * for the user profiles service. */ @@ -1616,27 +1780,27 @@ int zisGroupAccessListServiceFunctionTSS(CrossMemoryServerGlobalArea *globalArea if (tmpResultBuffer == NULL) { return RC_ZIS_GRPALSRV_ALLOC_FAILED; } - + RadminStatus radminStatus = {0}; - + TSSLogData logData = { .globalArea = globalArea, .traceLevel = traceLevel }; - + TSSGroupAccessListParms parms = { .tmpResultBuffer = tmpResultBuffer, .logData = &logData, .entriesToExtract = localParmList.resultBufferCapacity, }; - + CMS_DEBUG2(globalArea, traceLevel, "ResultBufferCapacity: %d\n", localParmList.resultBufferCapacity); #define TSS_GRP_ACCESS_LIST_EXTR_MAX_LEN 30 /* ACID - 8, Rest of command - 22 */ char extractGroupAccessList[TSS_GRP_ACCESS_LIST_EXTR_MAX_LEN + 1] = {0}; snprintf(extractGroupAccessList, sizeof(extractGroupAccessList), "TSS LIST(%s) DATA(ACIDS)", groupNameNullTerm); - + radminExtractRC = radminRunRACFCommand( authInfo, extractGroupAccessList, @@ -1645,6 +1809,43 @@ int zisGroupAccessListServiceFunctionTSS(CrossMemoryServerGlobalArea *globalArea &radminStatus ); + if (radminExtractRC != RC_RADMIN_OK) { + CMS_DEBUG2(globalArea, traceLevel, "Attempting command with less privileges\n"); + + TSSCallerProfileParms callerParms = { + .extractGroups = TRUE, + .searchGroup = groupNameNullTerm, + .isInGroup = FALSE, + .extractProfiles = FALSE, + .profilesToExtract = localParmList.resultBufferCapacity, + .logData = &logData + }; + +#define TSS_GRP_ACCESS_LIST_EXTR_CALLER_MAX_LEN 28 + char extractGroupAccessListCaller[TSS_GRP_ACCESS_LIST_EXTR_CALLER_MAX_LEN + 1] = {0}; + snprintf(extractGroupAccessListCaller, sizeof(extractGroupAccessListCaller), "TSS LIST(%.*s)", sizeof(caller.value), caller.value); + + radminExtractRC = radminRunRACFCommand( + authInfo, + extractGroupAccessListCaller, + callerProfileHandler, + &callerParms, + &radminStatus + ); + + if (radminExtractRC == RC_RADMIN_OK) { + if (callerParms.isInGroup) { + parms.entriesFound = 1; + parms.entriesExtracted = 1; + + ZISGroupAccessEntry *p = &tmpResultBuffer[0]; + memset(p, 0, sizeof(*p)); + memcpy(p->id, caller.value, sizeof(caller.value)); + memcpy(p->accessType, "USE", sizeof(p->accessType)); + } + } + } + CMS_DEBUG2(globalArea, traceLevel, "Entries Extracted: %d\n", parms.entriesExtracted); @@ -3096,6 +3297,55 @@ int zisGenresProfilesServiceFunctionTSS(CrossMemoryServerGlobalArea *globalArea, } } + if (radminExtractRC != RC_RADMIN_OK) { + CMS_DEBUG2(globalArea, traceLevel, "Attempting command with less privileges\n"); + + TSSCallerProfileParms callerParms = { + .extractProfiles = TRUE, + .searchClass = classNullTerm, + .profilesToExtract = localParmList.profilesToExtract, + .profiles = tmpResultBuffer, + .extractGroups = FALSE, + .logData = &logData + }; + + if (searchByPrefix) { + CMS_DEBUG2(logData.globalArea, logData.traceLevel, + "Searching by prefix...\n"); + callerParms.filterByPrefix = (char*)startProfileNullTerm; + } + else if (startProfileNullTerm) { + CMS_DEBUG2(logData.globalArea, logData.traceLevel, + "Searching by profile...\n"); + callerParms.filterByProfile = (char*)startProfileNullTerm; + } + else { + callerParms.filterByPrefix = NULL; + callerParms.filterByProfile = NULL; + CMS_DEBUG2(logData.globalArea, logData.traceLevel, + "Searching all...\n"); + } + +#define TSS_PRF_EXTR_CALLER_MAX_LEN 30 + char extractProfileCaller[TSS_PRF_EXTR_CALLER_MAX_LEN + 1] = {0}; + snprintf(extractProfileCaller, sizeof(extractProfileCaller), "TSS LIST(%.*s) DATA(XAUTH)", sizeof(caller.value), caller.value); + + radminExtractRC = radminRunRACFCommand( + authInfo, + extractProfileCaller, + callerProfileHandler, + &callerParms, + &radminStatus + ); + + if (radminExtractRC == RC_RADMIN_OK) { + CMS_DEBUG2(globalArea, traceLevel, "command success\n"); + CMS_DEBUG2(globalArea, traceLevel, "extracted %d profiles\n", callerParms.profilesExtracted); + } + + parms.profilesExtracted = callerParms.profilesExtracted; + } + if (radminExtractRC == RC_RADMIN_OK) { copyGenresProfiles(localParmList.resultBuffer, tmpResultBuffer, parms.profilesExtracted, 0); @@ -3110,7 +3360,7 @@ int zisGenresProfilesServiceFunctionTSS(CrossMemoryServerGlobalArea *globalArea, } int freeRC = 0, freeSysRC = 0, freeSysRSN = 0; - + freeRC = safeFree64v3(tmpResultBuffer, tmpResultBufferSize, &freeSysRC, &freeSysRSN); diff --git a/h/zis/services/tssparsing.h b/h/zis/services/tssparsing.h index 2387fb2bd..c689744a4 100644 --- a/h/zis/services/tssparsing.h +++ b/h/zis/services/tssparsing.h @@ -16,7 +16,12 @@ #define TSS_KEY_DELIMITER " = " #define TSS_KEY_DELIMITER_LEN 3 -#define TSS_ADMIN_INDICATOR "-SC" +#define TSS_ADMIN_INDICATOR_MASTER "-MS" +#define TSS_ADMIN_INDICATOR_CENTRAL "-SC" +#define TSS_ADMIN_INDICATOR_LSCA "-LC" +#define TSS_ADMIN_INDICATOR_ZCA "-ZC" +#define TSS_ADMIN_INDICATOR_VCA "-VC" +#define TSS_ADMIN_INDICATOR_DCA "-DC" #define TSS_ADMIN_INDICATOR_LEN 3 #define TSS_MAX_KEY_LENGTH 10 @@ -40,6 +45,7 @@ #define TSS_ACID_KEY "ACID(" #define TSS_ACCESS_KEY "ACCESS" #define TSS_ACIDS_KEY "ACIDS" +#define TSS_PROFILE_KEY "PROFILES" /* Stores information about a specific * key.