Reputation: 1054
I am currently working on a project which is an implementation similar to FTP. For this, I need to implement virtual chrooting, which should also work on Windows platforms.
My current approach is that each user has a specific home directory (represented by a File
object) and every time the user is trying to access a file or directory, the server will check whether this file or directory is inside this home directory or not.
Sadly, I am not sure, how I can implement this check in a way that is not taking up too much CPU time and HDD access time. One could simply try to walk up the directories and if we land on a directory that equals the given home directory, we are satisfied. If we reach the root directory, we return false
because it's very likely that the given file is not inside the home directory.
I am sure this check would work, but I also assume that this would be very costly and maybe very unefficient in a multi-user environment.
I would appreciate any help to design this algorithm better. Maybe there even exists a method for that? I did not find one yet though.
Thanks in advance!
// EDIT: As requested, here are some examples for this file structure
- /
- home/
- user1/
- file1.txt
- file2.txt
- user2/
- picture.png
- someDir/
We assume 2 users ("user1" and "user2") with the home directories "/home/user1" for user1 and "/home/user2" for user2.
The method I am looking for should give the following results, if applied on this scenario:
isInsideHome("/home/user2/picture.png", "user1") -> false
isInsideHome("/home/user1/file1.txt", "user1") -> true
isInsideHome("/", "user1") -> false
isInsideHome("/home", "user2") -> false
I hope these examples clarify what I am looking for.
Upvotes: 1
Views: 98
Reputation: 36703
Assuming you're not calling methods such as createNewFile(), exists() etc java.io.File doesn't require HDD access, and will only minimal CPU.
For example, none of following paths exist on my computer, but the code executes without exception.
public static void main(String[] args) {
System.out.println(isInsideHome("/home/user2/picture.png", "user1"));
System.out.println(isInsideHome("/home/user1/file1.txt", "user1"));
System.out.println(isInsideHome("/", "user1"));
System.out.println(isInsideHome("/home", "user2"));
}
private static boolean isInsideHome(String pathStr, String leaf) {
File path = new File(pathStr);
File search = new File(leaf);
while ((path = path.getParentFile()) != null) {
if (search.getName().equals(path.getName())) {
return true;
}
}
return false;
}
The source for java.io.File.getParentFile() shows that no HDD access is involved...
public static void main(String[] args) {
System.out.println(isInsideHome("/home/user2/picture.png", "user1"));
System.out.println(isInsideHome("/home/user1/file1.txt", "user1"));
System.out.println(isInsideHome("/", "user1"));
System.out.println(isInsideHome("/home", "user2"));
}
private static boolean isInsideHome(String pathStr, String leafStr) {
File path = new File(pathStr);
File leaf = new File(leafStr);
while ((path = path.getParentFile()) != null) {
if (leaf.getName().equals(path.getName())) {
return true;
}
}
return false;
}
Upvotes: 1