diff --git a/dali/base/dadfs.cpp b/dali/base/dadfs.cpp index 713041951fe..97d45c510e0 100644 --- a/dali/base/dadfs.cpp +++ b/dali/base/dadfs.cpp @@ -1181,6 +1181,7 @@ protected: friend class CDistributedFile; IDistributedSuperFile *lookupSuperFile(const char *logicalname, IUserDescriptor *user, AccessMode accessMode, IDistributedFileTransaction *transaction, unsigned timeout=INFINITE); SecAccessFlags getFilePermissions(const char *lname,IUserDescriptor *user,unsigned auditflags); + SecAccessFlags getFScopePermissions(const char *scope,IUserDescriptor *user,unsigned auditflags); SecAccessFlags getNodePermissions(const IpAddress &ip,IUserDescriptor *user,unsigned auditflags); SecAccessFlags getFDescPermissions(IFileDescriptor *,IUserDescriptor *user,unsigned auditflags=0); SecAccessFlags getDLFNPermissions(CDfsLogicalFileName &dlfn,IUserDescriptor *user,unsigned auditflags=0); @@ -11875,6 +11876,11 @@ SecAccessFlags CDistributedFileDirectory::getDropZoneScopePermissions(const char return getScopePermissions(dlfn.get(),user,auditflags); } +SecAccessFlags CDistributedFileDirectory::getFScopePermissions(const char *scope,IUserDescriptor *user,unsigned auditflags) +{ + return getScopePermissions(scope,user,auditflags); +} + void CDistributedFileDirectory::setDefaultUser(IUserDescriptor *user) { if (user) diff --git a/dali/base/dadfs.hpp b/dali/base/dadfs.hpp index 71e29bd750a..813509ee022 100644 --- a/dali/base/dadfs.hpp +++ b/dali/base/dadfs.hpp @@ -642,6 +642,7 @@ interface IDistributedFileDirectory: extends IInterface virtual void removeSuperFile(const char *_logicalname, bool delSubs=false, IUserDescriptor *user=NULL, IDistributedFileTransaction *transaction=NULL)=0; virtual SecAccessFlags getFilePermissions(const char *lname,IUserDescriptor *user,unsigned auditflags=0)=0; // see dasess for auditflags values + virtual SecAccessFlags getFScopePermissions(const char *scope,IUserDescriptor *user,unsigned auditflags=0)=0; // see dasess for auditflags values virtual void setDefaultUser(IUserDescriptor *user)=0; virtual IUserDescriptor* queryDefaultUser()=0; virtual SecAccessFlags getNodePermissions(const IpAddress &ip,IUserDescriptor *user,unsigned auditflags=0)=0; diff --git a/esp/services/ws_fs/ws_fsBinding.cpp b/esp/services/ws_fs/ws_fsBinding.cpp index cac737f66cc..a404e875e93 100644 --- a/esp/services/ws_fs/ws_fsBinding.cpp +++ b/esp/services/ws_fs/ws_fsBinding.cpp @@ -386,19 +386,6 @@ void CFileSpraySoapBindingEx::xsltTransform(const char* xml, const char* sheet, } #endif -static void validateDropZoneReq(IEspContext& ctx, const char* dropZoneName, const char* host, const char* path, SecAccessFlags permissionReq) -{ - if (!validateDropZoneHostAndPath(dropZoneName, host, path)) //The pathStr should be the absolute path for the dropzone. - throw makeStringException(ECLWATCH_INVALID_INPUT, "Invalid DropZoneName, NetAddress or Path."); - - SecAccessFlags permission = getDZPathScopePermissions(ctx, dropZoneName, path, host); - if ((permission < permissionReq) && getGlobalConfigSP()->getPropBool("expert/@failOverToLegacyPhysicalPerms", !isContainerized())) - permission = getLegacyDZPhysicalPerms(ctx, dropZoneName, host, path, true); - if (permission < permissionReq) - throw makeStringExceptionV(ECLWATCH_INVALID_INPUT, "Access DropZone %s %s %s not allowed for user %s (permission:%s). %s permission required.", - dropZoneName, host, path, ctx.queryUserId(), getSecAccessFlagName(permission), getSecAccessFlagName(permissionReq)); -} - int CFileSpraySoapBindingEx::downloadFile(IEspContext &context, CHttpRequest* request, CHttpResponse* response) { try diff --git a/esp/services/ws_fs/ws_fsService.cpp b/esp/services/ws_fs/ws_fsService.cpp index 30f6ba91906..f01f5b03153 100644 --- a/esp/services/ws_fs/ws_fsService.cpp +++ b/esp/services/ws_fs/ws_fsService.cpp @@ -1920,16 +1920,6 @@ static bool parseUNCPath(const char* sprayPath, StringBuffer& localPath, StringB return true; } -static void validateDZFileScopePermission(IEspContext& context, const char* dropZoneName, const char* path, const char* host, SecAccessFlags permissionReq) -{ - SecAccessFlags permission = getDZFileScopePermissions(context, dropZoneName, path, host); - if ((permission < permissionReq) && getGlobalConfigSP()->getPropBool("expert/@failOverToLegacyPhysicalPerms", !isContainerized())) - permission = getLegacyDZPhysicalPerms(context, dropZoneName, host, path, false); - if (permission < permissionReq) - throw makeStringExceptionV(ECLWATCH_INVALID_INPUT, "Access DropZone %s %s not allowed for user %s (permission:%s). %s permission Required.", - dropZoneName, path, context.queryUserId(), getSecAccessFlagName(permission), getSecAccessFlagName(permissionReq)); -} - void CFileSprayEx::readAndCheckSpraySourceReq(IEspContext& context, MemoryBuffer& srcxml, const char* srcIP, const char* srcPath, const char* srcPlane, StringBuffer& sourcePlaneReq, StringBuffer& sourceIPReq, StringBuffer& sourcePathReq) { @@ -2046,7 +2036,7 @@ void CFileSprayEx::readAndCheckSpraySourceReq(IEspContext& context, MemoryBuffer { //Based on the tests, the dfuserver only supports the wildcard inside the file name, like '/path/f*'. //The dfuserver throws an error if the wildcard is inside the path, like /p*ath/file. - validateDZFileScopePermission(context, sourcePlaneReq, path, sourceIPReq, SecAccess_Read); + validateDZFileScopePermissions(context, sourcePlaneReq, path, sourceIPReq, SecAccess_Read); } if (!sourcePathReq.isEmpty()) @@ -2592,7 +2582,7 @@ bool CFileSprayEx::onDespray(IEspContext &context, IEspDespray &req, IEspDespray if (!isEmptyString(destPlane)) // must be true, unless bare-metal and isDropZoneRestrictionEnabled()==false { getDropZoneInfoByDestPlane(version, destPlane, destfile, destfileWithPath, umask, destip); - validateDZFileScopePermission(context, destPlane, destfileWithPath, destip, SecAccess_Write); + validateDZFileScopePermissions(context, destPlane, destfileWithPath, destip, SecAccess_Write); } else destfileWithPath.append(destfile).trim(); @@ -2979,15 +2969,6 @@ bool CFileSprayEx::onDFUWUFile(IEspContext &context, IEspDFUWUFileRequest &req, return true; } -static SecAccessFlags getDZPathScopePermissionsEx(IEspContext &context, const char *dropZoneName, const char *path, - const char *host, SecAccessFlags permissionReq) -{ - SecAccessFlags permission = getDZPathScopePermissions(context, dropZoneName, path, host); - if ((permission < permissionReq) && getGlobalConfigSP()->getPropBool("expert/@failOverToLegacyPhysicalPerms", !isContainerized())) - permission = getLegacyDZPhysicalPerms(context, dropZoneName, host, path, true); - return permission; -} - bool CFileSprayEx::onFileList(IEspContext &context, IEspFileListRequest &req, IEspFileListResponse &resp) { try @@ -3047,7 +3028,7 @@ bool CFileSprayEx::onFileList(IEspContext &context, IEspFileListRequest &req, IE dropZoneName = findDropZonePlaneName(netaddr, sPath, dzName); if (!isEmptyString(dropZoneName)) { - SecAccessFlags permission = getDZPathScopePermissionsEx(context, dropZoneName, sPath, netaddr, SecAccess_Read); + SecAccessFlags permission = getDZPathScopePermsAndLegacyPhysicalPerms(context, dropZoneName, sPath, netaddr, SecAccess_Read); if (permission < SecAccess_Read) throw makeStringExceptionV(ECLWATCH_INVALID_INPUT, "Access DropZone %s %s not allowed for user %s (permission:%s). Read Access Required.", dropZoneName, sPath.str(), context.queryUserId(), getSecAccessFlagName(permission)); @@ -3158,7 +3139,7 @@ void CFileSprayEx::addPhysicalFile(IEspContext& context, IDirectoryIterator* di, bool CFileSprayEx::searchDropZoneFiles(IEspContext& context, const char* dropZoneName, const char* server, const char* dir, const char* relDir, const char* nameFilter, IArrayOf& files, unsigned& filesFound) { - if (getDZPathScopePermissionsEx(context, dropZoneName, dir, server, SecAccess_Read) < SecAccess_Read) + if (getDZPathScopePermsAndLegacyPhysicalPerms(context, dropZoneName, dir, server, SecAccess_Read) < SecAccess_Read) return false; RemoteFilename rfn; @@ -3379,7 +3360,7 @@ void CFileSprayEx::getPhysicalFiles(IEspContext &context, const char *dropZoneNa if (dropZoneName && di->isDir()) { VStringBuffer fullPath("%s%s", path, fileName.str()); - if (getDZPathScopePermissionsEx(context, dropZoneName, fullPath, host, SecAccess_Read) < SecAccess_Read) + if (getDZPathScopePermsAndLegacyPhysicalPerms(context, dropZoneName, fullPath, host, SecAccess_Read) < SecAccess_Read) continue; } @@ -3490,7 +3471,7 @@ bool CFileSprayEx::onDropZoneFiles(IEspContext &context, IEspDropZoneFilesReques StringBuffer planeName; if (isEmptyString(dzName)) dzName = findDropZonePlaneName(netAddress, directoryStr, planeName); - if (!isEmptyString(dzName) && (getDZPathScopePermissionsEx(context, dzName, directoryStr, netAddress, SecAccess_Read) < SecAccess_Read)) + if (!isEmptyString(dzName) && (getDZPathScopePermsAndLegacyPhysicalPerms(context, dzName, directoryStr, netAddress, SecAccess_Read) < SecAccess_Read)) return false; bool directoryOnly = req.getDirectoryOnly(); @@ -3641,7 +3622,7 @@ void CFileSprayEx::checkDropZoneFileScopeAccess(IEspContext &context, const char dropZoneName = findDropZonePlaneName(netAddress, dropZonePath, dzName); if (!isEmptyString(dropZoneName)) { - SecAccessFlags permission = getDZPathScopePermissionsEx(context, dropZoneName, dropZonePath, netAddress, accessReq); + SecAccessFlags permission = getDZPathScopePermsAndLegacyPhysicalPerms(context, dropZoneName, dropZonePath, netAddress, accessReq); if (permission < accessReq) throw makeStringExceptionV(ECLWATCH_INVALID_INPUT, "Access DropZone Scope %s %s not allowed for user %s (permission:%s). %s Permission Required.", dropZoneName, dropZonePath, context.queryUserId(), getSecAccessFlagName(permission), accessReqName); @@ -3688,7 +3669,7 @@ void CFileSprayEx::checkDropZoneFileScopeAccess(IEspContext &context, const char addPathSepChar(fullPath).append(pathToCheck); //If the dropzone name is not found, the DZPathScopePermissions cannot be validated. SecAccessFlags permission = isEmptyString(dropZoneName) ? accessReq - : getDZPathScopePermissionsEx(context, dropZoneName, fullPath, netAddress, accessReq); + : getDZPathScopePermsAndLegacyPhysicalPerms(context, dropZoneName, fullPath, netAddress, accessReq); if (permission < accessReq) { uniquePath.setValue(pathToCheck.str(), false); //add a path denied diff --git a/esp/smc/SMCLib/TpCommon.cpp b/esp/smc/SMCLib/TpCommon.cpp index 7903f7f95a2..74790ba4a2f 100644 --- a/esp/smc/SMCLib/TpCommon.cpp +++ b/esp/smc/SMCLib/TpCommon.cpp @@ -196,7 +196,7 @@ static SecAccessFlags getDropZoneScopePermissions(IEspContext& context, const IP return queryDistributedFileDirectory().getDropZoneScopePermissions(dropZone->queryProp("@name"), dropZonePath, userDesc); } -extern TPWRAPPER_API SecAccessFlags getDZPathScopePermissions(IEspContext& context, const char* dropZoneName, const char* dropZonePath, const char* dropZoneHost) +static SecAccessFlags getDZPathScopePermissions(IEspContext& context, const char* dropZoneName, const char* dropZonePath, const char* dropZoneHost) { if (isEmptyString(dropZonePath)) throw makeStringException(ECLWATCH_INVALID_CLUSTER_NAME, "getDZPathScopePermissions(): DropZone path must be specified."); @@ -207,7 +207,8 @@ extern TPWRAPPER_API SecAccessFlags getDZPathScopePermissions(IEspContext& conte dropZone.setown(findDropZonePlane(dropZonePath, dropZoneHost, true, false)); if (!dropZone) { - throwOrLogDropZoneLookUpError(ECLWATCH_INVALID_INPUT, "getDZPathScopePermissions(): DropZone %s not found.", dropZoneName); + throwOrLogDropZoneLookUpError(ECLWATCH_INVALID_INPUT, "getDZPathScopePermissions(): DropZone %s not found for host '%s' path '%s'.", + isEmptyString(dropZoneHost) ? "unspecified" : dropZoneHost, isEmptyString(dropZonePath) ? "unspecified" : dropZonePath); return SecAccess_Full; } } @@ -221,7 +222,7 @@ extern TPWRAPPER_API SecAccessFlags getDZPathScopePermissions(IEspContext& conte return getDropZoneScopePermissions(context, dropZone, dropZonePath); } -extern TPWRAPPER_API SecAccessFlags getDZFileScopePermissions(IEspContext& context, const char* dropZoneName, const char* dropZonePath, +static SecAccessFlags getDZFileScopePermissions(IEspContext& context, const char* dropZoneName, const char* dropZonePath, const char* dropZoneHost) { StringBuffer dir, fileName; @@ -230,8 +231,8 @@ extern TPWRAPPER_API SecAccessFlags getDZFileScopePermissions(IEspContext& conte return getDZPathScopePermissions(context, dropZoneName, dropZonePath, dropZoneHost); } -extern TPWRAPPER_API SecAccessFlags getLegacyDZPhysicalPerms(IEspContext& context, const char* dropZoneName, const char* dropZoneHost, - const char* dropZoneFile, bool pathOnly) +static SecAccessFlags getLegacyDZPhysicalPerms(IEspContext& context, const char* dropZoneName, const char* dropZoneHost, + const char* dropZoneFile, bool isPath) { if (isEmptyString(dropZoneHost) && isEmptyString(dropZoneName)) throw makeStringException(ECLWATCH_INVALID_INPUT, "Neither dropzone plane or host specified."); @@ -249,18 +250,58 @@ extern TPWRAPPER_API SecAccessFlags getLegacyDZPhysicalPerms(IEspContext& contex dropZoneHost = "localhost"; } - //The setExternal() requests the path with a file name. The file name is not used by the getDLFNPermissions(). - //If the dropZoneFile is a path only, the dropZoneScope + a faked file name is passed to the setExternal(). - StringBuffer pathWithFileName(dropZoneFile); - if (pathOnly) - addNonEmptyPathSepChar(pathWithFileName).append("any"); - CDfsLogicalFileName dlfn; SocketEndpoint ep(dropZoneHost); - dlfn.setExternal(ep, pathWithFileName); - return queryDistributedFileDirectory().getDLFNPermissions(dlfn, userDesc); + dlfn.setExternal(ep, dropZoneFile); + + StringBuffer scopes; + const char *scopesToCheck = nullptr; + if (isPath) + scopesToCheck = dlfn.get(); + else + { + dlfn.getScopes(scopes); + scopesToCheck = scopes; + } + return queryDistributedFileDirectory().getFScopePermissions(scopesToCheck, userDesc); +} + +//Get dropzone file permission when the file path does not contain a file name. To get the permission, +//this function (and the validate functions below) calls the getDZPathScopePermissions() which handles +//isDropZoneRestrictionEnabled if a dropzone cannot be found based on host and path. +extern TPWRAPPER_API SecAccessFlags getDZPathScopePermsAndLegacyPhysicalPerms(IEspContext &context, const char *dropZoneName, const char *path, + const char *host, SecAccessFlags permissionReq) +{ + SecAccessFlags permission = getDZPathScopePermissions(context, dropZoneName, path, host); + if ((permission < permissionReq) && getGlobalConfigSP()->getPropBool("expert/@failOverToLegacyPhysicalPerms", !isContainerized())) + permission = getLegacyDZPhysicalPerms(context, dropZoneName, host, path, true); + return permission; +} + +//Validate dropzone host and file path. Also validate dropzone file permission when the file path does not contain a file name. +extern TPWRAPPER_API void validateDropZoneReq(IEspContext& ctx, const char* dropZoneName, const char* host, const char* path, SecAccessFlags permissionReq) +{ + if (!validateDropZoneHostAndPath(dropZoneName, host, path)) //The pathStr should be the absolute path for the dropzone. + throw makeStringException(ECLWATCH_INVALID_INPUT, "Invalid DropZoneName, NetAddress or Path."); + + SecAccessFlags permission = getDZPathScopePermsAndLegacyPhysicalPerms(ctx, dropZoneName, path, host, permissionReq); + if (permission < permissionReq) + throw makeStringExceptionV(ECLWATCH_INVALID_INPUT, "Access DropZone %s %s %s not allowed for user %s (permission:%s). %s permission required.", + dropZoneName, host, path, ctx.queryUserId(), getSecAccessFlagName(permission), getSecAccessFlagName(permissionReq)); +} + +//Validate dropzone file permission when the file path contains a file name. +extern TPWRAPPER_API void validateDZFileScopePermissions(IEspContext& context, const char* dropZoneName, const char* path, const char* host, SecAccessFlags permissionReq) +{ + SecAccessFlags permission = getDZFileScopePermissions(context, dropZoneName, path, host); + if ((permission < permissionReq) && getGlobalConfigSP()->getPropBool("expert/@failOverToLegacyPhysicalPerms", !isContainerized())) + permission = getLegacyDZPhysicalPerms(context, dropZoneName, host, path, false); + if (permission < permissionReq) + throw makeStringExceptionV(ECLWATCH_INVALID_INPUT, "Access DropZone %s %s not allowed for user %s (permission:%s). %s permission Required.", + dropZoneName, path, context.queryUserId(), getSecAccessFlagName(permission), getSecAccessFlagName(permissionReq)); } +//Validate dropzone file path and permission, Also set the dlfn. extern TPWRAPPER_API void validateDropZoneAccess(IEspContext& context, const char* targetDZNameOrHost, const char* hostReq, SecAccessFlags permissionReq, const char* fileNameWithRelPath, CDfsLogicalFileName& dlfn) { diff --git a/esp/smc/SMCLib/TpWrapper.hpp b/esp/smc/SMCLib/TpWrapper.hpp index 414ad2a1972..c8a882a09ed 100644 --- a/esp/smc/SMCLib/TpWrapper.hpp +++ b/esp/smc/SMCLib/TpWrapper.hpp @@ -241,10 +241,11 @@ extern TPWRAPPER_API bool matchNetAddressRequest(const char* netAddressReg, bool extern TPWRAPPER_API StringBuffer &findDropZonePlaneName(const char* host, const char* path, StringBuffer& planeName); extern TPWRAPPER_API bool validateDropZoneHostAndPath(const char* dropZoneName, const char* hostToCheck, const char* pathToCheck); -extern TPWRAPPER_API SecAccessFlags getDZPathScopePermissions(IEspContext& context, const char* dropZoneName, const char* dropZonePath, const char* dropZoneHost); -extern TPWRAPPER_API SecAccessFlags getDZFileScopePermissions(IEspContext& context, const char* dropZoneName, const char* dropZonePath, const char* dropZoneHost); -extern TPWRAPPER_API SecAccessFlags getLegacyDZPhysicalPerms(IEspContext& context, const char* dropZoneName, const char* dropZoneHost, const char* dropZoneFile, bool pathOnly); extern TPWRAPPER_API void validateDropZoneAccess(IEspContext& context, const char* targetDZNameOrHost, const char* hostReq, SecAccessFlags permissionReq, const char* fileNameWithRelPath, CDfsLogicalFileName& dlfn); +extern TPWRAPPER_API SecAccessFlags getDZPathScopePermsAndLegacyPhysicalPerms(IEspContext &context, const char *dropZoneName, const char *path, + const char *host, SecAccessFlags permissionReq); +extern TPWRAPPER_API void validateDropZoneReq(IEspContext& ctx, const char* dropZoneName, const char* host, const char* path, SecAccessFlags permissionReq); +extern TPWRAPPER_API void validateDZFileScopePermissions(IEspContext& context, const char* dropZoneName, const char* path, const char* host, SecAccessFlags permissionReq); #endif //_ESPWIZ_TpWrapper_HPP__