Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a Java thread running as root, how can we apply Unix rights specific to a logged-in user?

We have a Java program run as root on Unix, that therefore can read for example the content of the folders /home/user1 and /home/user2. However, if the Unix user "user1" is logged in in our application, he should not be able to access "/home/user2" data. We would like to use directly the Unix rights and not recreate all the permissions in our application ! So, could we...

  1. try to change the UID of our program depending on the user logged in ? Sounds difficult, and each file access is in different threads so the UID would be different on each thread of our program...
  2. use JNI to read permissions of "/home/user2"...And then determine if user1 has sufficient permissions on "/home/user2" ? (how ?).
like image 379
Mikael Mechoulam Avatar asked Sep 06 '25 03:09

Mikael Mechoulam


2 Answers

Use SecurityManager!

  1. Put current unix user id into ThreadLocal
  2. Create your own SecurityManager that checks unix user permissions on checkRead() and checkWrite()
  3. System.setSecurityManager(new MySecurityManager())
  4. Enjoy

Update

There is no, of course, standard library to read unix file permissions. It's not WORA.

But I have tried briefly to find a ready to use library, and found this one: http://jan.newmarch.name/java/posix/ It uses JNI, but you don't need to write your own JNI code, which is a big relief. :) I'm sure there must also be others.

Class Stat from there gives you all required access information: http://jan.newmarch.name/java/posix/posix.Stat.html

Update 2

As folks mentioned, this approach fails to check for "non-standard" unix security features, such as ACL or Posix Capabilities (may be; not sure if they apply to files). But if the goal of being totally in sync with host OS security is set, then we even more need to use SecurityManager, because it's a JVM-wide protection mechanism! Yes, we can start a child SUID-process to verify the permissions (and keep it running, talking to it via pipe running while the user is logged in), but we need to do so from SecurityManager!

like image 81
Vladimir Dyuzhev Avatar answered Sep 09 '25 15:09

Vladimir Dyuzhev


The simplest and most portable way would be to spawn a child process, have it exec a wrapper written in C which changes the UID, drops all the privileges (be careful, writting a wrapper to do that is tricky - it is as hard as writing a setuid wrapper), and execs another java instance to which you talk via RMI. That java instance would do all the filesystem manipulation on behalf of the user.

For single-threaded Linux programs, you could instead use setfsuid()/setfsgid(), but that is not an option for portable or multithreaded programs.

like image 26
CesarB Avatar answered Sep 09 '25 17:09

CesarB