Sudo Java calling C app and Permissions - java

I am calling a C application (console only) from my Java application.
I am calling it with: Process proc = rt.exec("./Debug/CPP_CL --device 0");
The CPP_CL needs access to clinfo() hardware .. so the GPU hardware as its processing on the GPU's. Hence, in this case needs to run as sudo/root.
Its all working fine at the moment but only if I run the Java JAR as sudo. Currently for testing only the CPG is chmod 777 (I know bad).
What I would like to know is what’s the best way to do this ? Will the CPP run as SUDO if called by SUDO java ? Or does it need to be chmod'ed ? If so what’s the best chmod value ?
Thanks.

Running Java with root is, as you said, one possibilty, but not exactly good.
The usual chmod flags (rwx) too won´t help you.
Just call it with a sudo won´t solve anything. Usually, a password is required, and if the java program can enter it (ie. it knows the root password) ... well, then it´s the same as above again.
As said in the comments, you can add a exception to sudo, but there are some catches:
You can only specify a program/script file, but no parameter limitation. You will need a script file which calls ./Debug/CPP_CL --device 0 (better with full path) and add the batch file as exception.
Furthermore, you have to make sure that the script file can´t be modified by users (chmod of the file) and can´t be deleted (chmod of the containing directory). File modification would mean that the modifying user can put anything in it and run it as root, and deletion would let the user place another file there with this name = same effect. Given that, you can call with with sudo.
If you wnat to call it without sudo, make another script file which just calls file 1 with sudo.
Another possibility is the special chmod flag SUID on the program itself (if it is enabled/supported in your distro). But here again, you can´t limit the parameters.
About the data files: A file created by a root program will be owned by root. chmod/chown as root can change that. If you only need to read the file, default umasks will allow that on many systems (if the files are in not-only-root-directories like /root)

Answer:
https://unix.stackexchange.com/questions/18830/how-to-run-a-specific-program-as-root-without-a-password-prompt
This worked.. I was able to sudo from Java and with the above no PWD is required for that application.

Related

How do I make my directory give the executable permissions to script files which are going to be created by my Java program?

I want my directory to give executable permissions (by default) to all the shell scripts which are going to be created in that directory after I run my Java program. I tried the following commands:
setfacl -d -m group:name:rwx /path/to/your/dir
find ./ -name "*.sh" -exec chmod +x {} \;
The first one is not showing any response while the second one works fine but I have to execute this command manually in terminal after my Java program has created all the scripts. This is not what i seek. I want this thing to be automatic. Here is what I am trying to achieve:
My Java program creates the .sh files in a directory.
Now the program would try to execute this script file.
Here is a Java code snippet which shows how it is going to execute the script files:
ExecuteShellComand obj = new ExecuteShellComand();
String command2 = "./script.sh";
String output2 = obj.executeCommand(command2);
It doesn't run unless I give the executable permissions to the script.sh. How do I do it? Is there any way around it? If I am not doing something in a way it should be done, feel free to give your suggestions. Thanks
Default ACL permissions are masked by the file's creation mode as specified in open and mkdir syscalls.
Since files are usually created with a default mode of 0666, execute permissions will be masked instead of inherited.
It's the responsibility of the program that creates the files to create them with the right permissions. If you set the permissions correctly when creating the scripts, you won't need ACL or chmod at all. The best way to fix this would be for your program to set the mode in the open call to 0777.
Java appears to have Files.createFile for this. Additionally, you have a more fuzzy File.setExecutable to do it after the fact, which is not Unix canonical behavior, but probably fine for your use case.

Linux permissions to run but not read files

I currently have a Java based application stored on my CentOS server that is probably worth a lot of money and I need to some how give somebody access to restart the application in case it crashes without allowing them to actually get access to the java class files where they could be compromised.
Was just wondering if there's a way I could do this ? IE if there is a way I could have a jailed shell with commands restricted only to running the bash script that starts the application or if I would need to write a 3rd party application to handle all this for me?
Thanks for reading
You can absolutely have a file with the executable bit set and the readable bit not and it will do what you expect. Consider the following program:
#include <stdio.h>
int
main()
{
printf("hello, world\n");
return 0;
}
Now you can do
$ cc -o main main.c -static
$ chmod 0100 main
$ ls -l
---x------ 1 user user 821801 Sep 28 16:39 main
-rw-r----- 1 user user 75 Sep 28 16:39 main.c
$ ./main
hello, world
$ cat ./main
cat: main: Permission denied
The problem with JAR files is that they are not executables. They are not mapped into RAM by the operating system but opened and read by the JVM and it cannot do this without having read permissions set on them.
That said, your concerns are probably unwarranted. Granting world read permissions on a *.class file should be harmless. They cannot be compromised unless they are writeable which is not needed. If you store sensitive data like passwords in a *.class file, I think you should reconsider that decision.
Write a small wrapper which starts the application. The simplest way to do this would be to create a shell wrapper:
#!/bin/sh
java ...
But it's likely that that won't work on a server installation. See below.
Change the owner and group of the wrapper to a user and group which have permission to read the jar files:
$ chown user:group wrapper
Change the permissions of the wrapper to make it world-executable, and setuid (so that it will run as the owner of the wrapper, set in the previous step):
$ chmod a+rx,og-w,u+s wrapper
Then the wrapper will be run as the indicated user, without giving anybody additional privileges over the executable or its support files.
I strongly recommend not making the owner of the wrapper root. Use some user created for this purpose, which you control but which does not have root access.
In case your system doesn't honour the setuid bit for interpreters (that is, scripts with a shebang (#!) line), here's a simple C wrapper which should work. You'll have to modify it as indicated below and then compile it:
cc -Wall -o wrapper wrapper.c
(-o wrapper means "the binary to produce will be called wrapper.) Substitute whatever name you like, and put the wrapper file in a place where it can be found, such as /usr/local/bin/wrapper. It's hard to give precise instructions without knowing anything about your system configuration. Good luck.
I have no idea how you run your application, but you'll have to insert the command line into the following code, replacing java with the actual command used, and /path/to/java with the output of which java (again, use the actual command name if it isn't "java"). The arguments in the command line get inserted instead of arg1, arg2, etc. Don't use extra quotes; just the characters which form the command-line.
#include <stdio.h>
#include <unistd.h>
int main() {
execl("/path/to/java",
"java",
"arg1",
"arg2",
/* ... */
(char*)0);
/* If we get here, the exec didn't work */
perror("Failed to execute /path/to/java");
return 1;
}
If the untrusted user does not have any other access to the host on which the application is running, the above wrapper could also be used as a "restricted shell"; making it the shell of the user (or otherwise configuring ssh so that a login by that user will run the wrapper) will cause an automatic restart on login. However, that's not really a great idea, unless the application knows not to start itself up if it is already running, or can be modified to do this check. Alternatively, the wrapper could be modified to attempt to detect whether the application is currently running before restarting it. Either of these two possibilities involves more details than could be inserted into this answer.

Java switch user using su on linux

I am writing a java program dor Oracle EBS that needs to switch user because of specific permissions defined on an user different than applmgr.
The approach we're taking is to have a java class that will switch user on a separate session and then will list the file from a folder that the new user has access.
Any options available?
So far I could create two shell script files and then I run these shell scripts, one that will store environment variables and the other one will actually switch user and list the files.
Appreciate your help.
you could change the group permissions on the file. You could start a System.process( "su user && cat file" ); You could have the other user copy the file to you using a cronjob...
You can try having Java launch a local command on the system then as part of that command launch another program (far from being very clean, but probably would work)
Check out this Class file for examples on launching local commands:
https://github.com/SnakeDoc/RPi_SerialGPS/blob/master/src/com/vanomaly/rpi/serial/gps/util/System.java
You should be able to use setuid - I expect there is a version available directly in Java, but otherwise, it shouldn't be that hard to make your own JNI code to do that.
However, it may be simpler to run a command that switches user (using su or sudo, for example) and then runs the required Java code.

From java code file getting created with a lock symbol in Linux

From java, I use the following code to create a file:
File dirName = new File("/var/www/html/nyk/app/webroot/MusicDB/music.db");
But the file gets created with a 'lock symbol' on top of it which indicates restricted permissions. I am able to change the permissions of this file manually from terminal using cgmod -R 777 filename . But I am using another code in the same program, which copies the created file to another destination. Due to the restricted permission, it is not able to copy the file.
How can I create the file eliminating the restricted permsiion issue in first place?
have you tried this?
myFile.setReadable(true);
myFile.setWritable(true);
You can use the File.setReadable(), File.setWritable() methods for that! You can either grant the permission, or revoke them as per your needs! Currently in your case, you need to provide true to grant the permissions!
Or a dirty workaround would be
Runtime.getRuntime().exec("chmod 777 file")
You could either use umask outside of Java before starting the application.
umask 000
or use
dirName.setReadable(true);
dirName.setWritable(true);

Runtime exec output path

I am trying to run a perl command with Java runtime exec in linux/ubuntu/gnome. The command generates an pdf file, but it saves it in my home folder. Is there any way that the exec method can set an output path for the commands executed? Thanks in advance.
The exec method just runs the command on the operating system, so you'll want to change the command you're running with exec more than anything in "Java" per se.
There are a few possibilities:
Change the working directory of your java program. The .pdf is being saved in your working directory because this is where the program is being run.
Unfortunately it's not simple to change this value after the program has been launched. It is, however, trivial to change before the program starts; just change the working directory before starting the program.
Move the file to it's desired location after it's been created in your home directory.
Change the command so that it includes the target location. Your perl script may have an option that will enable you to save it's output to a certain location (usually -o or --output). Using this your program would change from:
Runtime.exec("perl someprogram");
to something like:
Runtime.exec("perl someprogram -o /path/to/some.file")
You might be able to use "output redirection", if there is no option to do this.
Try something like what's below as your argument:
Runtime.exec("perl someprogram > /path/to/some.file")
Unfortunately, without knowing more details of your situation I can't provide more concrete advice.
While each approach has benefits and drawbacks, it's probably best to just implement the one that you understand best; if you can't get one to work, try another.
A good, free online resource for learning is Introduction to Linux: A Hands On Guide.
Section 2.2 has details on cd which you can use for 1..
Section 3.3, section 3 teaches about the mv command, which will be useful in 2..
Section 5.1 is about I/O redirection. Knowing about "output redirection" and the > operator, are important for 4..
For 3., you'll have to consult the documentation of the perl program you're using.
You could modify the Perl script to accept an absolute path for the output.
You can trying setting the working directory using exec(java.lang.String[], java.lang.String[], java.io.File) where File is the directory the command is executed from.
If all else fails, you'll can always copy the generated file from the Home directory to your final location.

Categories

Resources