diff --git a/c/embeddedjs.c b/c/embeddedjs.c index ebee05c53..a5b46f97a 100644 --- a/c/embeddedjs.c +++ b/c/embeddedjs.c @@ -1990,8 +1990,39 @@ JSModuleDef *ejsModuleLoader(JSContext *ctx, } buf = js_load_file(ctx, &buf_len, nameToLoad); if (!buf){ - fprintf(stderr,"Could not load module name '%s'\n",nativeName); + fprintf(stderr,"js_load_file failure. A file requested module '%s' but it could not be loaded.\n",nativeName); fflush(stderr); +#ifdef __ZOWE_OS_ZOS + fprintf(stderr,"Getting file info for diagnosis\n"); + int returnCode = 0, reasonCode = 0, status = 0; + FileInfo info = {0}; + char nativeExtension[modNameLen+4]; + snprintf(nativeExtension, modNameLen+4, "%s.js", nativeName); + status = fileInfo(nativeExtension, &info, &returnCode, &reasonCode); + if (status) { + fprintf(stderr, "Could not get file info for %s.js. status=%d, rc=%d, rsn=%d\n", nativeName, status, returnCode, reasonCode); + fflush(stderr); + } else { + short ccsid = info.ccsid; + fprintf(stderr, "File found with ccsid=%d\n",ccsid); + fflush(stderr); + char readBuf[256]; + UnixFile *moduleFile = fileOpen(nativeExtension, FILE_OPTION_READ_ONLY, 0, 0, &returnCode, &reasonCode); + if (returnCode==0) { + int bytesRead = fileRead(moduleFile, readBuf, 256, &returnCode, &reasonCode); + if (returnCode==0) { + fprintf(stderr, "First 256 bytes of module=%256.256s\n",readBuf); + fflush(stderr); + } else { + fprintf(stderr, "Could not read the file. rc=%d, rsn=%d\n",returnCode, reasonCode); + fflush(stderr); + } + } else { + fprintf(stderr, "Could not open file, rc=%d, rsn=%d\n", returnCode, reasonCode); + } + } +#endif + JS_ThrowReferenceError(ctx, "could not load module filename '%s'", nameToLoad); return NULL; diff --git a/c/rusermap.c b/c/rusermap.c new file mode 100644 index 000000000..22e1c096b --- /dev/null +++ b/c/rusermap.c @@ -0,0 +1,217 @@ + +/* + This program and the accompanying materials are + made available under the terms of the Eclipse Public License v2.0 which accompanies + this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html + + SPDX-License-Identifier: EPL-2.0 + + Copyright Contributors to the Zowe Project. +*/ + +#ifdef METTLE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "metalio.h" +#include "qsam.h" + +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + +#include "zowetypes.h" +#include "alloc.h" +#include "utils.h" +#include "rusermap.h" + +#define MAP_USERID_TO_LOTUS_NOTES_ID 0x0001 /* Lotus Notes, hahahahahahaha */ +#define MAP_LOTUS_NOTES_ID_TO_USERID 0x0002 + +#define MAP_CERTIFICATE_TO_USERID 0x0006 +#define MAP_DN_TO_USERID 0x0008 + +#define MAX_CERT_SIZE 4096 +#define MAX_DN_SIZE 246 /* according to doc! */ +#define MAX_REGISTRY_SIZE 255 + +#define IRRSIM00_WORKAREA_LENGTH 1024 + +/* last arg must be at least 9 chars in length */ +static int getUseridByExternalInfo(int functionCode, + char *data, int dataLength, char *registry, int registryLength, char *useridBuffer, + int *racfRC, int *racfReason){ + +#pragma pack(packed) + ALLOC_STRUCT31( + STRUCT31_NAME(parms31), + STRUCT31_FIELDS + ( + Addr31 parmlistStorage[15]; + uint32_t zero; /* must be initted to zero, used for all the ALET's and NULL pointers */ + uint32_t highbitZero; + uint32_t safRC; + uint32_t racfRC; + uint32_t racfReason; + uint16_t functionCode; + uint8_t reserved; + uint8_t useridLength; + char userid[8]; + char workArea[IRRSIM00_WORKAREA_LENGTH]; + uint32_t certificateLength; + char certificate[MAX_CERT_SIZE]; + uint16_t distinguishedNameLength; + char distinguishedName[MAX_DN_SIZE]; + uint16_t registryNameLength; + char registryName[MAX_REGISTRY_SIZE]; + ) + ); +#pragma pack(reset) + + memset(parms31,0,sizeof(*parms31)); + parms31->functionCode = functionCode; + parms31->highbitZero = 0x80000000; + parms31->useridLength = 0; + switch (functionCode){ + case MAP_CERTIFICATE_TO_USERID: + if (dataLength > MAX_CERT_SIZE){ + FREE_STRUCT31(STRUCT31_NAME(parms31)); + return RUSERMAP_PARM_TOO_BIG; + } else{ + memcpy(parms31->certificate, data, dataLength); + parms31->certificateLength = dataLength; + } + break; + case MAP_DN_TO_USERID: + if (dataLength > MAX_DN_SIZE || registryLength > MAX_REGISTRY_SIZE){ + FREE_STRUCT31(STRUCT31_NAME(parms31)); + return RUSERMAP_PARM_TOO_BIG; + } else{ + memcpy(parms31->distinguishedName, data, dataLength); + parms31->distinguishedNameLength = dataLength; + memcpy(parms31->registryName, registry, registryLength); + parms31->registryNameLength = registryLength; + e2a(parms31->distinguishedName, dataLength); + e2a(parms31->registryName, registryLength); + } + break; + default: + return RUSERMAP_BAD_FUNCTION_CODE; + } + + int rc = 0; + /* + printf(" before call parms31Len=0x%x\n",(int)sizeof(*parms31));fflush(stdout); + dumpbuffer((char*)parms31,sizeof(*parms31)); + */ + __asm(ASM_PREFIX + /* We get the routine pointer for IRRSIM00 by an, *ahem*, direct approach. + These offsets are stable, and this avoids linker/pragma mojo, + This offsets are available in SYS1.CSSLIB(IRRSIM00) + + 4002 8000 5F01 5F02 5F02 1F 5F00 0F + 1008 9002 8000 8F20 8F08 E0 8F00 7F + + This means 28th 4byte slot (0x28 * 4 = 0xA0), + put that in register 0 + of CVT-CSRTABLE->SAF + put that in register 15 + add the two togeter (1EF0) + and there's your routine + */ + " LLGT 15,X'10'(,0) \n" /* Get the CVT */ + " LLGT 15,X'220'(,15) \n" /* CSRTABLE */ + " LLGT 15,X'28'(,15) \n" /* Some RACF Routin Vector */ + " LLGT 15,X'A0'(,15) \n" /* IRRSIM00 itself */ +#ifdef _LP64 + " SAM31 \n" + " SYSSTATE AMODE64=NO \n" +#endif + " CALL (15),(%[wa]" + ",%[z],%[safRC]" + ",%[z],%[racfRC]" + ",%[z],%[racfRSN]" + ",%[z],%[fc]" + ",%[z]" /* options */ + ",%[userid]" + ",%[cert]" + ",%[z]" /* appl userid */ + ",%[dn]" /* Distinguished name */ + ",%[registry])" /* registry name */ + ",VL,MF=(E,%[parmlist]) \n" + +#ifdef _LP64 + " SAM64 \n" + " SYSSTATE AMODE64=YES \n" +#endif + " ST 15,%[rc]" + : [rc]"=m"(rc) + : [wa]"m"(parms31->workArea), + [z]"m"(parms31->zero), + [highbit]"m"(parms31->highbitZero), + [fc]"m"(parms31->functionCode), + [safRC]"m"(parms31->safRC), + [racfRC]"m"(parms31->racfRC), + [racfRSN]"m"(parms31->racfReason), + [userid]"m"(parms31->useridLength), /* must point at pre-pended length */ + [dn]"m"(parms31->distinguishedNameLength), + [registry]"m"(parms31->registryNameLength), + [cert]"m"(parms31->certificateLength), + [parmlist]"m"(parms31->parmlistStorage) + :"r14","r15"); + + + int safRC = parms31->safRC; + *racfRC = parms31->racfRC; + *racfReason = parms31->racfReason; + + if (safRC == 0){ + memcpy(useridBuffer,parms31->userid,parms31->useridLength); + } + + FREE_STRUCT31( + STRUCT31_NAME(parms31) + ); + + return safRC; +} + +int getUseridByCertificate(char *certificate, int certificateLength, char *useridBuffer, + int *racfRC, int *racfReason){ + return getUseridByExternalInfo(MAP_CERTIFICATE_TO_USERID,certificate,certificateLength,NULL,0,useridBuffer,racfRC,racfReason); +} + +int getUseridByDN(char *distinguishedName, int distinguishedNameLength, char *registry, int registryLength, char *useridBuffer, + int *racfRC, int *racfReason){ + return getUseridByExternalInfo(MAP_DN_TO_USERID,distinguishedName,distinguishedNameLength,registry,registryLength,useridBuffer,racfRC,racfReason); +} + + +/* + This program and the accompanying materials are + made available under the terms of the Eclipse Public License v2.0 which accompanies + this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html + + SPDX-License-Identifier: EPL-2.0 + + Copyright Contributors to the Zowe Project. +*/ diff --git a/h/rusermap.h b/h/rusermap.h new file mode 100644 index 000000000..d140a28b8 --- /dev/null +++ b/h/rusermap.h @@ -0,0 +1,63 @@ + +/* + This program and the accompanying materials are + made available under the terms of the Eclipse Public License v2.0 which accompanies + this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html + + SPDX-License-Identifier: EPL-2.0 + + Copyright Contributors to the Zowe Project. +*/ + +#ifndef __ZOWE_RUSERMAP__ +#define __ZOWE_RUSERMAP__ 1 + +#define RUSERMAP_SAF_SUCCESS 0 +/* zowe-defined top-level return codes */ +#define RUSERMAP_PARM_TOO_BIG 16 +#define RUSERMAP_BAD_FUNCTION_CODE 20 + +#define RUSERMAP_RACF_FAILURE 8 +#define RUSERMAP_RACF_REASON_NOAUTH 0x14 +#define RUSERMAP_RACF_REASON_NOUSERID 0x18 +#define RUSERMAP_RACF_REASON_BADCERT 0x1C +#define RUSERMAP_RACF_REASON_NOUSER_FOR_CERT 0x20 +#define RUSERMAP_RACF_REASON_BAD_DN 0x28 + +/** + getUseridByCertificate() gets the SAF Userid for a certificate, if one had been previously + defined for that user. + + The certificate is a standard DER format certificate and must have the proper length passed + in the second argument. The useridBuffer must be at least 9 bytes or bad thing will happen. + + The saf return code is returned and must be 0 for success. Non-Zero returns are further explained + in the racfRC and racfReason values + + Please consult the following IBM doc for a full explanation of return codes: + + https://www.ibm.com/docs/en/zos/2.5.0?topic=descriptions-r-usermap-irrsim00-map-application-user + */ + +int getUseridByCertificate(char *certificate, int certificateLength, char *useridBuffer, + int *racfRC, int *racfReason); + +/* getUseridByDN works just like getUseridByCertificate, except it takes Distinguihed Name (aka DN) + in UTF-8 format. + */ + +int getUseridByDN(char *distinguishedName, int distinguishedNameLength, char *registry, int registryLength, char *useridBuffer, + int *racfRC, int *racfReason); + + +#endif + +/* + This program and the accompanying materials are + made available under the terms of the Eclipse Public License v2.0 which accompanies + this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html + + SPDX-License-Identifier: EPL-2.0 + + Copyright Contributors to the Zowe Project. +*/ diff --git a/tests/rusermaptest.c b/tests/rusermaptest.c new file mode 100644 index 000000000..0bb073cfc --- /dev/null +++ b/tests/rusermaptest.c @@ -0,0 +1,102 @@ +/* + This program and the accompanying materials are + made available under the terms of the Eclipse Public License v2.0 which accompanies + this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html + + SPDX-License-Identifier: EPL-2.0 + + Copyright Contributors to the Zowe Project. +*/ + +#ifdef METTLE +#include +#include +#include +#include +#include +#include +#include "metalio.h" + +#else +#include +#include +#include +#include +#include + +#endif /* METTLE */ + +#include "zowetypes.h" +#include "alloc.h" +#include "utils.h" +#include "charsets.h" +#include "unixfile.h" +#include "rusermap.h" + + +/* + + Testing on ZOS: (This program can *ONLY* run on ZOS). + + 64-bit build + + xlclang -q64 -I ../h -D_OPEN_SYS_FILE_EXT=1 -D_XOPEN_SOURCE=600 -D_OPEN_THREADS=1 -DSUBPOOL=132 "-Wc,float(ieee),longname,langlvl(extc99),gonum,goff,ASM,asmlib('CEE.SCEEMAC','SYS1.MACLIB','SYS1.MODGEN')" -o rusermaptest rusermaptest.c ../c/rusermap.c ../c/charsets.c ../c/zosfile.c ../c/timeutls.c ../c/utils.c ../c/alloc.c ../c/logging.c ../c/collections.c ../c/le.c ../c/recovery.c ../c/zos.c ../c/scheduling.c + + 31-bit build + + xlc -I ../h -D_OPEN_SYS_FILE_EXT=1 -D_XOPEN_SOURCE=600 -D_OPEN_THREADS=1 -DSUBPOOL=132 "-Wc,float(ieee),longname,langlvl(extc99),gonum,goff,ASM,asmlib('CEE.SCEEMAC','SYS1.MACLIB','SYS1.MODGEN')" -o rusermaptest31 rusermaptest.c ../c/rusermap.c ../c/charsets.c ../c/zosfile.c ../c/timeutls.c ../c/utils.c ../c/alloc.c ../c/logging.c ../c/collections.c ../c/le.c ../c/recovery.c ../c/zos.c ../c/scheduling.c + + + Configuring the user to have a certificate: + + Note for the following call the cert should be B64: + + tsocmd "racdcert add('{{ zowe_dataset_prefix }}.CERT.{{ dataset }}') id({{ zowe_runtime_user }}) withlabel('{{ label }}') trust" + tsocmd "SETROPTS RACLIST(DIGTCERT, DIGTRING) REFRESH" + +*/ + +int main(int argc, char **argv){ + if (argc < 2){ + printf("must supply a command of either 'cert' or 'dn'\n"); + } + char *command = argv[1]; + char userid[9]; + int retCode = 0; + int reason = 0; + + + + if (!strcmp(command,"cert")){ + FILE *ptr; + ptr = fopen("apimtst.der","rb"); + printf("pointer=%p\n",ptr); + fflush(stdout); + char buffer[4096]; + memset(buffer,0,4096); + int bytesRead = fread(buffer,1,4096,ptr); + printf("bytesRead=%d\n",bytesRead); + fflush(stdout); + fclose( ptr ); + dumpbuffer(buffer,bytesRead); + int rc = getUseridByCertificate(buffer, bytesRead, userid, &retCode, &reason); + if (rc){ + printf("Could not get userid, racfFC=0x%x, reason=0x%x\n",retCode,reason); + } else { + printf("Userid: %s\n",userid); + } + } else if (!strcmp(command,"dn")){ + char *fakeDN = "FooBarBaz"; + char *fakeRegistry = "zowe.org"; + int rc = getUseridByDN(fakeDN, strlen(fakeDN), fakeRegistry, strlen(fakeRegistry), userid, &retCode, &reason); + if (rc){ + printf("Could not get userid, racfFC=0x%x, reason=0x%x\n",retCode,reason); + } else { + printf("Userid: %s\n",userid); + } + } else{ + printf("unknown command '%s'\n",command); + } + + return 0; +}