"su <otheruser>" fails with "standard in must be atty" - java

I researched this question and all answers suggest visudo to add:
Defaults:user !requiretty
It does not work!
I have two Linux boxes (RedHat). I have a Java class which uses ProcessBuilder/Process to execute commands. The class runs under a system account.
On both boxes, I run
su other-user -c 'some-command'
and provide the password for other-user in an input stream to the Process object.
On one box, the command succeeds and on the other I get the error above.
The sudoers files on both machines did not have exclusions for requiretty ('Defaults requiretty' is set on both files).
I tried adding the exclusion as suggested by the answers I found. I tried both the system user running the process and 'other-user'...
Does not work.
What else can be the issue? Do I need to restart the system after adding the requiretty exceptoin(s)?

sudoers is for sudo rather than su so you should use sudo.
According to su manual:
-c, --command COMMAND
Specify a command that will be invoked by the shell using its -c.
The executed command will have no controlling terminal. This option cannot be used to execute interactive programs which need a controlling TTY.

you can use a TTY spawning if you are trying to avoid using sudo or you don't have a sudo privileges.
Just invoke one of the following codes before running the code which giving you the error you mentioned.
here are some examples of codes you can use, depends on the code or the system you are using:
python -c 'import pty; pty.spawn("/bin/sh")'
echo os.system('/bin/bash')
/bin/sh -i
perl —e 'exec "/bin/sh";'
perl: exec "/bin/sh";
ruby: exec "/bin/sh"
lua: os.execute('/bin/sh')
(From within IRB)
exec "/bin/sh"
(From within vi)
:!bash
(From within vi)
:set shell=/bin/bash:shell
(From within nmap)
!sh
the first three choices up are my common used ones, and I am trusting their results.
I am using them while pentesting.

Related

How do I pass a display to a qsub command?

I am running a bash script that, among other things, runs a java program that can be used via GUI or via command line (depending on a parameter).
splitstree --commandLineMode --commandFile comm.txt --version --verbose
EDIT:
When I run it via normal command line or via GUI, it works perfectly. If I echo this command into a file and $(cat file) it also works, and it works as well when I integrate it into a bash script and run the bash script.
If I qsub it to the cluster where I am doing the work, I get an error about a missing display:
java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed
an operation which requires it.
I tried to export DISPLAY=:0.0 within the bash script but the error didn't change.
EDIT 2:
If I pass the DISPLAY variable to the qsub command, the error goes away but the program terminates with an exit status of 1. Like:
qsub -v DISPLAY <job_file>
It also says Picked up _JAVA_OPTIONS: -Xmx4096M but performing unset on this variable didn't change the exit status (so probably is not harming the process).
Re-running the same command outside of qsub (that is: simply copy-paste the cmd into the shell) work perfectly again.
Any suggestion on how to make it so that the qsub command correctly passes the display information to the cluster node?
If you don't need the display run Java with -Djava.awt.headless=true property, as explained in Using Headless Mode in the Java SE Platform.
Alternatively, if your program can't run headless, you can try using Xvfb (X virtual framebuffer). It comes with xvfb-run command, take a look at Running without a Display wiki:
xvfb-run java MainClass
or by configuring DISPLAY environment variable:
sudo Xvfb :1 -screen 0 1024x768x24 </dev/null &
export DISPLAY=":1"
java MainClass
When in a headless environment, you need to use GraphicsEnvironment.isHeadless() in your code to avoid doing anything that requires AWT components. That means you can't do any input/output, of course.

Using PHP (may be commandline using shell_exec() function), how can I determine if a Java application/jar file is currently running or not?

I have a PHP application which executes a Java .jar file through shell_exec():
shell_exec("java jar myJarProgram.jar");
I have a need to determine if an instance this java program myJarProgram.jar is already running, because if it is not, then I can start it using the above PHP statement.
How can I do that?
You can use "jps" utility to grep your process with java
jps -mlvV | grep myJarProgram.jar
jps is a good candidate for this, but please note that
To use the jps command-line tool you need to install a JDK.
Otherwise, you can parse the output of another shell_exec call that uses ps with the arguments you want in order to get the running processes: at this point you can check if the process is present.
$search_string = "[j]ava jar myJarProgram.jar";
$running = shell_exec("ps -A -ww | grep '$search_string'");
or similar.
If $running is empty, you can launch the jar.
Another option is to perform everything with a single shell_exec, both with commands concatanation (simple && and ||) or creating a .sh script and shell_executing that.
EDIT:
According to the user comment, the script must work both for Windows and Linux.
You can use the php PHP_OS predefined constant to check if it's Windows or Linux:
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') etc....
If it's Linux, you can use the shell_exec as reported above.
If it's Windows, you can change the shell_exec string using the tasklist Windows command. I don't know it, but there are already dedicated questions and answers like this one.

Launch Java with a specific argument each time

I have a program which allows me to define the java executable (/usr/bin/java), but does not allow me to add specific arguments to the executable.
I want to be able to run Java with a specific argument each time in order to enable Security Manager.
So far, I have tried to add the argument after /usr/bin/java, so it looks like
java=/usr/bin/java -Djava.security.manager -Djava.security.policy=/home/java.policy
That did not work as the program probably checks to see if a file exists. Another way I tried was to make a bash script called java which contained:
/usr/bin/java -Djava.security.manager -Djava.security.policy=/home/java.policy $*
I then set the java path to /home/java (Location of my script). That however did not work either. Is there some sort of way I can do this?
Thanks.
Put your java call in a shell script java.sh:
#!/bin/bash
/usr/bin/java -Djava.security.manager -Djava.security.policy=/home/java.policy $#
Change permissions with chmod u+x java.sh, then call your program with java=./java.sh (adapt path for your script as needed).
Notes about executable bit and shebang line
Both the shebang line (#!/bin/bash) and execute permission are important here. Without them, system calls of the exec* family will fail because the kernel does not know what to do with the file or because execution is rejected due to the missing executable bit.
This is different when run directly from a shell (./java.sh), because most shells have some compatibility feature for that case so they will run a script in a shell if exec* fails. The execute permission must be set though.
The only case where neither is needed is if you give your script as argument to the shell: bash java.sh.
Your second approach would be ok, but your problem is likely to be that your Multicraft application is not finding your script. More so, it's the environment of your web server (Apache?) that may need to have PATH altered to be able to find your java wrapper script.

Get the name of the java process instead of pid?

jps.exe which found on JDK 1.5 and later could monitor all Java process but is there a way to detect the specify command line and terminate the correct pid?
What if the user have JRE, is there a similar code allow us to terminate any process easily?
Prefer to keep the topic on Windows which I am working on.
The jps command supports a number of options that modify the output of the command. These options are subject to change or removal in the future.
-q Suppress the output of the class name, JAR file name, and arguments passed to the main method, producing only a list of local VM identifiers.
-m Output the arguments passed to the main method. The output may be null for embedded JVMs.
-l Output the full package name for the application's main class or the full path name to the application's JAR file.
-v Output the arguments passed to the JVM.
-V Output the arguments passed to the JVM through the flags file (the .hotspotrc file or the file specified by the -XX:Flags= argument).
Pipe the output of jps to grep or sed or awk or perl or even another Java program for further matching, parsing and action. On Windows, the easiest way to get those utilities is through Cygwin.
Here are some Microsoft downloadable command line utilities which are useful for working with processes on Windows:
pskill
pslist
and the rest of the Sysinternals Suite
If the user don't have jps, you can use ps. The command line options for ps differs between platforms, see man ps on you system. I use ps -C java -o pid,time,cmd to list java processes on a CentOS system. Then kill to terminate.

What's the easiest in a shell script to ensure its not run as root?

I have a Java application executed from a ([ba]sh) shell script and unfortunately sometimes the people responsible for deploying it and starting it fail to switch to the appropriate user before starting the application. In this situation I'd like the application to not run at the very least, and ideally issue a warning not to do that. I thought about trying to alias java or change the path for root to include a fake java which does so, but this might have undesirable side effects and isn't going to be effective easily since the shell script specifies the full path to the java binary.
So, is there a standard idiom in shell scripts for 'don't run if I'm root'?
Example in bash:
if [ `id -u` = 0 ]; then
echo "You are root, go away!"
exit 1
fi
In BASH, you can take the output of whoami and compare it to root.
I use something like this at the beginning of scripts that I want to
be run under a service account:
LUSER='my-service'
if [ `id -un` != $LUSER ]; then
exec su $LUSER -s $SHELL -c "$0 $#"
fi
# actual script commands here.
If run as the correct user, execution will continue as planned. If run
as root, privileges are dropped to the wanted user-id. Other users
will get a password prompt which should tell them that something is
wrong.
su -s $SHELL ... is used to override the shell set in /etc/passwrd
-- it may be set to /bin/false for the service account.
I have used this on Debian systems, using bash and dash. Feel free
to comment if portability can be improved.

Categories