{"record":{"id":"54f7838e96273db7","repo":"pentaho/pentaho-kettle","slug":"cannot-delete-another-users-home-directory","errorCode":null,"errorMessage":"Cannot delete another users home directory","messagePattern":"Cannot delete another users home directory","errorType":"exception","errorClass":"RepositoryObjectAccessException","httpStatus":null,"severity":"error","filePath":"plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/PurRepository.java","lineNumber":576,"sourceCode":"\n    readWriteLock.writeLock().lock();\n    try {\n      // Fetch the folder to be deleted\n      RepositoryFile folder;\n      RepositoryFile homeFolder;\n\n      folder = pur.getFileById( dir.getObjectId().getId() );\n      // Fetch the user's home directory\n      homeFolder = pur.getFile( ClientRepositoryPaths.getUserHomeFolderPath( user.getLogin() ) );\n\n      // Make sure the user is not trying to delete their own home directory\n      if ( isSameOrAncestorFolder( folder, homeFolder ) ) {\n        // Then throw an exception that the user cannot delete their own home directory\n        throw new KettleException( \"You are not allowed to delete your home folder.\" );\n      }\n\n      if ( !deleteHomeDirectories && isUserHomeDirectory( folder ) ) {\n        throw new RepositoryObjectAccessException( \"Cannot delete another users home directory\",\n          RepositoryObjectAccessException.AccessExceptionType.USER_HOME_DIR );\n      }\n\n      pur.deleteFile( dir.getObjectId().getId(), null );\n      rootRef.clearRef();\n    } catch ( Exception e ) {\n      throw new KettleException( \"Unable to delete directory with path [\" + getPath( null, dir, null ) + \"]\", e );\n    } finally {\n      readWriteLock.writeLock().unlock();\n    }\n  }\n\n  @Override\n  public ObjectId renameRepositoryDirectory( final ObjectId dirId, final RepositoryDirectoryInterface newParent,\n                                             final String newName ) throws KettleException {\n    return renameRepositoryDirectory( dirId, newParent, newName, false );\n  }\n","sourceCodeStart":558,"sourceCodeEnd":594,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/PurRepository.java#L558-L594","documentation":"deleteRepositoryDirectory also guards other users' home directories: when deleteHomeDirectories is false and the target is another user's home folder, a RepositoryObjectAccessException with type USER_HOME_DIR and message \"Cannot delete another users home directory\" is thrown.","triggerScenarios":"deleteRepositoryDirectory(dir, deleteHomeDirectories=false) where isUserHomeDirectory(folder) is true and folder is not the caller's own home — e.g. admin tooling deleting /home/otheruser.","commonSituations":"Bulk cleanup of stale user homes by admins; scripts assuming admin rights bypass the plugin-level guard.","solutions":["Pass deleteHomeDirectories=true if deleting other users' home folders is intended (requires admin rights).","Skip folders matching /home/<username> in the deletion loop.","Catch RepositoryObjectAccessException and treat USER_HOME_DIR as a skip, not a fatal error."],"exampleFix":"// before\nrepo.deleteRepositoryDirectory(dir, false);\n// after\ntry { repo.deleteRepositoryDirectory(dir, true); } catch (RepositoryObjectAccessException e) { if (e.getAccessExceptionType() == AccessExceptionType.USER_HOME_DIR) skip(dir); else throw e; }","handlingStrategy":"try-catch","validationCode":"boolean otherUsersHome = folder.getPath().startsWith(\"/home/\") && !folder.getPath().equals(\"/home/\" + user.getLogin()); if (otherUsersHome && !deleteHomeDirectories) skip(folder);","typeGuard":null,"tryCatchPattern":"try { repo.deleteRepositoryDirectory(dir, deleteHomes); } catch (RepositoryObjectAccessException e) { if (e.getAccessExceptionType() == AccessExceptionType.USER_HOME_DIR) { log.info(\"skipped user home {}\", dir.getPath()); } else throw e; }","preventionTips":["Pass deleteHomeDirectories=true only when cleanup of other users' homes is intended","Catch RepositoryObjectAccessException separately from KettleException","Treat USER_HOME_DIR as a skip signal in bulk operations"],"tags":["pentaho","repository","permission"],"backgroundTag":"permission-denied","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}