From dd17600f07b4361dd20e3c49cb2ab6c3240649c5 Mon Sep 17 00:00:00 2001 From: Leonty Chudinov Date: Mon, 14 Sep 2020 10:29:21 +0500 Subject: [PATCH] Include owner and group into Unix file metadata and directory listing Signed-off-by: Leonty Chudinov --- c/httpfileservice.c | 20 +++++++ c/httpserver.c | 20 +++++++ c/utils.c | 11 ++++ c/zosaccounts.c | 129 ++++++++++++++++++++++++++++++++++++++++++++ h/utils.h | 2 + h/zosaccounts.h | 9 +++- 6 files changed, 190 insertions(+), 1 deletion(-) diff --git a/c/httpfileservice.c b/c/httpfileservice.c index 30c357858..45af832a4 100644 --- a/c/httpfileservice.c +++ b/c/httpfileservice.c @@ -566,6 +566,24 @@ void respondWithUnixFileMetadata(HttpResponse *response, char *absolutePath) { int unixTime = fileInfoUnixCreationTime(&info); convertUnixToISO(unixTime, &timeStamp); + char owner[USER_NAME_LEN+1] = {0}; + status = userGetName(info.ownerUID, owner, &returnCode, &reasonCode); + if (status != 0) { + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, + "failed to obtain user name for uid=%d, returnCode: %d, reasonCode: 0x%08x\n", + info.ownerUID, returnCode, reasonCode); + } + trimRight(owner, USER_NAME_LEN); + + char group[GROUP_NAME_LEN+1] = {0}; + status = groupGetName(info.ownerGID, group, &returnCode, &reasonCode); + if (status != 0) { + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, + "failed to obtain group name for gid=%d, returnCode: %d, reasonCode: 0x%08x\n", + info.ownerGID, returnCode, reasonCode); + } + trimRight(group, GROUP_NAME_LEN); + jsonStart(out); { jsonAddString(out, "path", absolutePath); @@ -574,6 +592,8 @@ void respondWithUnixFileMetadata(HttpResponse *response, char *absolutePath) { jsonAddInt(out, "ccsid", fileInfoCCSID(&info)); jsonAddString(out, "createdAt", timeStamp.data); jsonAddInt(out, "mode", octalMode); + jsonAddString(out, "owner", owner); + jsonAddString(out, "group", group); } jsonEnd(out); diff --git a/c/httpserver.c b/c/httpserver.c index 0dd6e843e..2c5948073 100644 --- a/c/httpserver.c +++ b/c/httpserver.c @@ -4619,6 +4619,24 @@ int makeJSONForDirectory(HttpResponse *response, char *dirname, int includeDotte int unixTime = fileInfoUnixCreationTime(&info); convertUnixToISO(unixTime, &timeStamp); + char owner[USER_NAME_LEN+1] = {0}; + int status = userGetName(info.ownerUID, owner, &returnCode, &reasonCode); + if (status != 0) { + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, + "failed to obtain user name for uid=%d, returnCode: %d, reasonCode: 0x%08x\n", + info.ownerUID, returnCode, reasonCode); + } + trimRight(owner, USER_NAME_LEN); + + char group[GROUP_NAME_LEN+1] = {0}; + status = groupGetName(info.ownerGID, group, &returnCode, &reasonCode); + if (status != 0) { + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, + "failed to obtain group name for gid=%d, returnCode: %d, reasonCode: 0x%08x\n", + info.ownerGID, returnCode, reasonCode); + } + trimRight(group, GROUP_NAME_LEN); + /* if(status == 0) { */ jsonStartObject(out, NULL); { @@ -4629,6 +4647,8 @@ int makeJSONForDirectory(HttpResponse *response, char *dirname, int includeDotte jsonAddInt(out, "ccsid", fileInfoCCSID(&info)); jsonAddString(out, "createdAt", timeStamp.data); jsonAddInt(out, "mode", octalMode); + jsonAddString(out, "owner", owner); + jsonAddString(out, "group", group); } jsonEndObject(out); /* } diff --git a/c/utils.c b/c/utils.c index f506e318e..c9a9183b3 100644 --- a/c/utils.c +++ b/c/utils.c @@ -2190,6 +2190,17 @@ const char* strrstr(const char * base, const char * find) { return returnPtr; } +/* trimRight removes whitespace from the end of a string. */ +void trimRight(char *str, int length) { + int i; + for (i = length - 1; i >= 0; i--) { + if (str[i] != ' ') { + break; + } + str[i] = '\0'; + } +} + /* This program and the accompanying materials are made available under the terms of the Eclipse Public License v2.0 which accompanies diff --git a/c/zosaccounts.c b/c/zosaccounts.c index ead5cbbfb..3ef29a272 100644 --- a/c/zosaccounts.c +++ b/c/zosaccounts.c @@ -38,20 +38,28 @@ static int accountTrace = FALSE; #ifdef _LP64 # pragma linkage(BPX4GGN,OS) +# pragma linkage(BPX4GGI,OS) # pragma linkage(BPX4GPN,OS) +# pragma linkage(BPX4GPU,OS) # pragma linkage(BPX4PWD,OS) # define BPXGGN BPX4GGN +# define BPXGGI BPX4GGI # define BPXGPN BPX4GPN +# define BPXGPU BPX4GPU # define BPXPWD BPX4PWD #else # pragma linkage(BPX1GGN,OS) +# pragma linkage(BPX1GGI,OS) # pragma linkage(BPX1GPN,OS) +# pragma linkage(BPX1GPU,OS) # pragma linkage(BPX1PWD,OS) # define BPXGGN BPX1GGN +# define BPXGGI BPX1GGI # define BPXGPN BPX1GPN +# define BPXGPU BPX1GPU # define BPXPWD BPX1PWD #endif @@ -107,6 +115,51 @@ int gidGetUserInfo(const char *userName, UserInfo * info, return retValue; } +/* Obtain the user information structure using UID */ +int getUserInfo(int uid, UserInfo *info, int *returnCode, int *reasonCode) { + int *reasonCodePtr; + int returnValue; + int retValue = -1; + + UserInfo *ptrInfo; + +#ifndef _LP64 + reasonCodePtr = (int*) (0x80000000 | ((int)reasonCode)); +#else + reasonCodePtr = reasonCode; +#endif + + BPXGPU(uid, + &returnValue, + returnCode, + reasonCodePtr); + + if (returnValue != 0) { + memcpy (info, (char *)returnValue, sizeof (UserInfo)); + retValue = 0; + } + + if (accountTrace) { + if(returnValue == 0) { +#ifdef METTLE + zowelog(NULL, LOG_COMP_ZOS, ZOWE_LOG_DEBUG, + "BPXGPU (%d) FAILED: returnValue: %d, returnCode: %d, reasonCode: 0x%08x\n", + uid, returnValue, *returnCode, *reasonCode); +#else + zowelog(NULL, LOG_COMP_ZOS, ZOWE_LOG_DEBUG, + "BPXGPU (%d) FAILED: returnValue: %d, returnCode: %d, reasonCode: 0x%08x, strError: (%s)\n", + uid, returnValue, *returnCode, *reasonCode, + strerror(*returnCode)); +#endif + } + else { + zowelog(NULL, LOG_COMP_ZOS, ZOWE_LOG_DEBUG, "BPXGPU (%d) OK: returnVal: %d\n", uid, returnValue); + } + } + + return retValue; +} + /* Obtain the user information structure from user name */ int resetZosUserPassword(const char *userName, const char *password, const char *newPassword, int *returnCode, int *reasonCode) { @@ -202,6 +255,50 @@ int gidGetGroupInfo(const char *groupName, GroupInfo *info, return retValue; } +/* Obtain the group information structure using GID */ +int getGroupInfo(int gid, GroupInfo *info, int *returnCode, int *reasonCode) { + int *reasonCodePtr; + int returnValue; + int retValue = -1; + *returnCode = *reasonCode = 0; + +#ifndef _LP64 + reasonCodePtr = (int*) (0x80000000 | ((int)reasonCode)); +#else + reasonCodePtr = reasonCode; +#endif + + BPXGGI(gid, + &returnValue, + returnCode, + reasonCodePtr); + + if (returnValue > 0) { + memcpy (info, (char *)returnValue, sizeof (GroupInfo)); + retValue = 0; + } + + if (accountTrace) { + if(returnValue == 0) { +#ifdef METTLE + zowelog(NULL, LOG_COMP_ZOS, ZOWE_LOG_DEBUG, + "BPXGGI (%d) FAILED: returnValue: %d, returnCode: %d, reasonCode: 0x%08x\n",, + gid, returnValue, *returnCode, *reasonCode); +#else + zowelog(NULL, LOG_COMP_ZOS, ZOWE_LOG_DEBUG, + "BPXGGI (%d) FAILED: returnValue: %d, returnCode: %d, reasonCode: 0x%08x, strError: (%s)\n", + gid, returnValue, *returnCode, *reasonCode, + strerror(*returnCode)); +#endif + } + else { + zowelog(NULL, LOG_COMP_ZOS, ZOWE_LOG_DEBUG, "BPXGGI (%d) OK: returnVal: %d\n", gid, returnValue); + } + } + + return retValue; +} + /* Return userId from user info structure */ int userInfoGetUserId (UserInfo *info) { int *temp = (int *)info; @@ -211,6 +308,11 @@ int userInfoGetUserId (UserInfo *info) { return userId; } +/* Copy user name from User Info structure into userNameBuffer */ +void userInfoGetUserName (UserInfo *info, char *userNameBuffer) { + memcpy(userNameBuffer, (const char*)&info->GIDN_U_NAME, info->GIDN_U_LEN); +} + /* Return groupId from group info structure */ int groupInfoGetGroupId (GroupInfo *info) { int *temp = (int *)info; @@ -220,6 +322,11 @@ int groupInfoGetGroupId (GroupInfo *info) { return groupId; } +/* Copy group name from Group Info structure into groupNameBuffer*/ +void groupInfoGetGroupName (GroupInfo *info, char *groupNameBuffer) { + memcpy(groupNameBuffer, (const char*)&info->GIDS_G_NAME, info->GIDS_G_LEN); +} + /* Obtain userId from character string */ int userIdGet (char *string, int *returnCode, int *reasonCode) { UserInfo userInfo = {0}; @@ -243,6 +350,17 @@ int userIdGet (char *string, int *returnCode, int *reasonCode) { return userId; } +/* Obtain user name by UID. userNameBuffer must be at least 8 chars long */ +int userGetName(int uid, char *userNameBuffer, int *returnCode, int *reasonCode) { + int status = 0; + UserInfo userInfo = {0}; + status = getUserInfo(uid, &userInfo, returnCode, reasonCode); + if (status == 0) { + userInfoGetUserName(&userInfo, userNameBuffer); + } + return status; +} + /* Obtain groupId from character string */ int groupIdGet (char *string, int *returnCode, int *reasonCode) { GroupInfo groupInfo = {0}; @@ -266,6 +384,17 @@ int groupIdGet (char *string, int *returnCode, int *reasonCode) { return groupId; } +/* Obtain group name by GID, groupNameBuffer must be at least 8 chars long */ +int groupGetName(int gid, char *groupNameBuffer, int *returnCode, int *reasonCode) { + int status = 0; + GroupInfo groupInfo = {0}; + status = getGroupInfo(gid, &groupInfo, returnCode, reasonCode); + if (status == 0) { + groupInfoGetGroupName(&groupInfo, groupNameBuffer); + } + return status; +} + /* This program and the accompanying materials are made available under the diff --git a/h/utils.h b/h/utils.h index 6d3295ff7..ccd56fc41 100644 --- a/h/utils.h +++ b/h/utils.h @@ -404,6 +404,8 @@ bool stringIsDigit(const char * str); const char* strrstr(const char * base, const char * find); #endif +void trimRight(char *str, int length); + #if defined(__cplusplus) } /* end of extern "C" */ #endif diff --git a/h/zosaccounts.h b/h/zosaccounts.h index f3258973e..0687997ba 100644 --- a/h/zosaccounts.h +++ b/h/zosaccounts.h @@ -45,17 +45,24 @@ typedef struct BPXYGIDN_tag { typedef BPXYGIDS GroupInfo; typedef BPXYGIDN UserInfo; - +#define USER_NAME_LEN 8 +#define GROUP_NAME_LEN 8 /* Function Prototype */ int gidGetUserInfo(const char *userName, UserInfo * info, int *returnCode, int *reasonCode); +int getUserInfo(int uid, UserInfo *info, int *returnCode, int *reasonCode); int gidGetGroupInfo(const char *groupName, GroupInfo *info, int *returnCode, int *reasonCode); +int getGroupInfo(int gid, GroupInfo *info, int *returnCode, int *reasonCode); int userInfoGetUserId (UserInfo *info); +void userInfoGetUserName (UserInfo *info, char *userNameBuffer); int groupInfoGetGroupId (GroupInfo *info); +void groupInfoGetGroupName (GroupInfo *info, char *groupNameBuffer); int userIdGet (char *string, int *returnCode, int *reasonCode); +int userGetName(int uid, char *userNameBuffer, int *returnCode, int *reasonCode); int groupIdGet (char *string, int *returnCode, int *reasonCode); +int groupGetName(int gid, char *groupNameBuffer, int *returnCode, int *reasonCode); int resetZosUserPassword(const char *userName, const char *password, const char *newPassword, int *returnCode, int *reasonCode);