• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

setuid

 
Ranch Hand
Posts: 2596
Android Firefox Browser Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What's a setuid script? How does it differ from a common shell script written in Unix/Linux???
TIA,
- Manish
 
Ranch Hand
Posts: 156
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 59
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
can we implement this setUID in java program?
 
Saloon Keeper
Posts: 27807
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Balaji Soundarajan
Ranch Hand
Posts: 59
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please help me to acheive this?
 
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.

 
Andrew Monkhouse
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Rancher
Posts: 4803
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 59
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
    Posts: 59
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    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
    Posts: 12200
    280
    Mac IntelliJ IDE Firefox Browser Oracle C++ Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    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.
     
    permaculture is giving a gift to your future self. After reading this tiny ad:
    a bit of art, as a gift, that will fit in a stocking
    https://gardener-gift.com
    reply
      Bookmark Topic Watch Topic
    • New Topic