aspose file tools*
The moose likes Linux / UNIX and the fly likes setuid Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Engineering » Linux / UNIX
Bookmark "setuid" Watch "setuid" New topic
Author

setuid

Manish Hatwalne
Ranch Hand

Joined: Sep 22, 2001
Posts: 2578

What's a setuid script? How does it differ from a common shell script written in Unix/Linux???
TIA,
- Manish
Loren Rosen
Ranch Hand

Joined: Feb 12, 2003
Posts: 156
The only difference is that a setuid script runs with a different login identity.
The user identity determines what files and directories you can read or write, what IP ports you can open, etc. Normally, a script runs with the identity of the login that starts the script. But sometimes you want to give someone a little more power, to do something they couldn't otherwise do, but not give them unlimited power.
For example, usually the low-numbered IP ports can only be opened by root. Now suppose you wanted to give someone the ability to start up a http server on port 80 (the standard port for http). You could give them the root password, and let them su to root. But then they could do all sorts of other things, beyond just running the server. So instead, you could write a script which starts up the server, have the script be owned by root, and setuid root. Then they can run the script, it will run as root, and the server will have the proper permissions to do its job.
Now, there are possible security risks here. And in this particular example there may be a more direct way to give someone permission to use port 80. But this should give the basic idea.
Balaji Soundarajan
Ranch Hand

Joined: Jan 23, 2009
Posts: 59
can we implement this setUID in java program?
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16145
    
  21

Balaji Soundarajan wrote:can we implement this setUID in java program?


Not directly. It's an OS-dependent function, so it couldn't be used in a "write once, run anywhere" environment. So there's no builtin Java support for it.

Customer surveys are for companies who didn't pay proper attention to begin with.
Balaji Soundarajan
Ranch Hand

Joined: Jan 23, 2009
Posts: 59
Please help me to acheive this?
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11481
    
  94

You have the clues to the most common way of handling this already - you know you can make a script that can run as another user, so all you need do is create a script that will start your Java program, change the ownership to the user you want to run the Java program as, then set the user ID flag. Then whenever you run your script, your Java program will be run as the alternate user.

As Loren stated, there are some major security risks here, so many operating systems ignore the suid bit on scripts (you can create a C wrapper to get around that problem if it exists for you). You would also want to ensure that any executable files have permissions set such that few people have access to write to them - I would only want write access by the person whom you are running as.


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11481
    
  94

Concrete example ...

First, I need a Java program:

Note: I did not state that this is a good example of good programming practice, just that it is a Java program! I have taken all sorts of liberties in order to make a very simple concrete example.

Compile and run it to prove that it works:


Now we need to have a C wrapper to make it run as another user:

Compile and run it to see that it works:


Now change the permissions and reduce visibility on everything for security:

Verify that everything looks OK:

And try running it:

So now I have my Java program running as though it were started by the user tomcat.

Note that I would probably not keep the source code for the C program or for the Java program with the executables. In a real-life situation I would probably have a secured section of my source code repository (my choice: SVN) so that it is still checked in, but it is safe from curious eyes. Whatever security I choose would also have to be considered for the continuous integration system - we would not want source code, or test source code, or test method names visible to everyone. And then there are overall considerations - how much of the project can be exposed without loosing security - for example, if I had to develop a screen scraping library as part of the overall project, can it be reasonably put into it's own global project that is exposed to the entire company, and only include the built library in my overall project?

I have only barely skimmed the surface of the security aspects of this - there are more things to consider. But at least there is enough here to get you going.

If you do not understand something, or (given the security concerns with this), if you do not understand why something has been done, please ask.
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11481
    
  94

Just thought of another security concept that I should have implemented ...

I should really have created a brand new Unix group for running these special programs. Then I would have set the permissions such that only the owner and people in that group can run "startup" (at the moment I have it set the "world" execution bit - this is not a good idea). Then I would add only those users who need to run this program to the newly created group.
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4659
    
    5

Loren Rosen wrote:The only difference is that a setuid script runs with a different login identity.
The user identity determines what files and directories you can read or write, what IP ports you can open, etc. Normally, a script runs with the identity of the login that starts the script.
[snip]
Now, there are possible security risks here.


Lets repeat, there are potentially *huge* security risks here. Done properly, it can be a very nice tool, but if its not done securely, it can open your server, and all the other computers on your network to a world of hurt.

Talk to your local network operations folks before you go too far.
Balaji Soundarajan
Ranch Hand

Joined: Jan 23, 2009
Posts: 59
Thanks for the reply.Its really nice logic.

I have to get the user id from command line arguments to my java program and have to perform all the operations as that user. i.e This user should be the owner of the all opereartions doing in java code on UNIX.
So Please tell me how to achieve this ?
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11481
    
  94

Off the top of my head I would probably have the C wrapper application run as the root user, and have it parse the user ID then execute the Java program as that user. This opens up even more security concerns, but it is doable.

If you did go down this route, I would suggest that your C wrapper should specifically exclude the possibility of running the Java application as root.

What is your use case for this? The only one I can think of is that you are trying to have something like the apache httpd setup, where it starts as root then immediately switches over to run as the apache user once it has acquired access to port 80. If you are trying to do this, then it is important to realize that the apache web server starts as root - not as any user. If you start the apache web server using a standard user's privileges then it will run as that user. It is also worth noting that they bypassed this problem with the Tomcat server, by having it run on port 8080 and having Apache httpd or IIS forward requests to Tomcat.
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11481
    
  94

I realized that while giving you a possible working scenario, I did not really answer your question about how to have a pure Java solution. That's because there isn't a pure java solution.

In your other thread, you gave the example of starting the Java application using:

java StorageServer Start -U 100

In theory this should be doable - you would need to create a JNI wrapper around the C setuid function, and start the Java application as root. Note however that:
  • This is not a pure Java solution - each JNI call is specific to the architecture it is run on, so what you compile for Linux is extremely unlikely to work on Solaris or Mac or FTX or ... - there are steps you can take to make this less of an issue, but it still needs to be acknowledged
  • You will need to run the Java program as root in order call the setuid method
  • There are some major hurdles to be overcome in order to run a Java application as root
  • This is even more of a security concern than having a C wrapper.


  • I would not want to go through all the headaches of trying to get this implemented in this manner, hence my thinking on a C wrapper application.

    By the way - going back to the concept of your other thread: continuing to ask questions in both topics is considered bad form. Please limit your questions to one thread or the other. It would be nice if you posted in one of the two that you are now going to only ask questions in the other topic.
    Balaji Soundarajan
    Ranch Hand

    Joined: Jan 23, 2009
    Posts: 59
    Hi Andrew, I am trying to implement the JNI to setUId.

    please tell me how to write the C wrapper class and how to load in the Java class.

    Please give me the steps to create .so file and where i have to put that .so file?
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander

    Joined: Mar 28, 2003
    Posts: 11481
        
      94

    Your questions is far too open at this point. You might want to look at the Sun JNI tutorial. Then come back with some specific questions based on code you have written.
     
    wood burning stoves
     
    subject: setuid