Launching java as a service and specifying the user - java

As an introduction, let's just say I'm a real noob using linux. I try to do the things right, don't hit me if it's ugly.
So, the problematic. I'm trying to run some jars as webservices on an ubuntu server. I created a specific user (nuxservice) with no pwd. I edited sudoers to enable a few users (myself & root) to sudo using this account with no password.
I then took a lot of inspiration from : http://www.jcgonzalez.com/linux-java-service-wrapper-example
Most is working, only one real problem, my java process seems to not have the right to create its logging files.
I run my services with a classic
sudo service myservice start/stop/restart
The command line that are launching my services are :
nohup sudo -u nuxservice java -jar myjar.jar myargs
When I do a ps -ef, the services are launches with my nuxservice user.
When I do ls -ld, nuxservice is the owner and have the rights.
If I launch the command in a terminal myself, it works. When launching as a service, my logs files are not created.
Any clues mates ?

So...
It was kinda silly.
My user rights were fine. Problem is, I did not set the working folder in my script so Java was all lost considering the creation of the folder/files for logging.
All I had to do was adding a little
cd $PATH_TO_JAR
And it was all set !

Related

OSX Catalina broke osascript launch with administrator priviledges

All known prior macOS versions were working with this sort of script context:
osascript -e "/path/to/my/app.command" with administrator privileges
Now it just silently fails...after asking for admin password.
The command file is what was originally used to launch the app, and the app has a button to re-launch with privileges...and the prior non privileged app closes.
If I remove the "with administrator privileges", it re-launches. if that is there, it does not.
If I try using:
/usr/bin/security execute-with-privileges /path/to/my/app.command
It also fails...never even shows password prompt.
I tried also "sudo open /Applications/myApp.app" but that of course doesn't actually launch with privileges.
From a shell i can sudo launch my app, and that is fine, but I can't expect an average user to be able to do sudo in a shell.
As I said, this had been a nice method that has worked for probably the past 6 to 8 years...but now fails. Anyone have any tricks or ways to get around it?
At one time....and I have no idea why, I saw the OSX security popup indicating "java" is not a trusted app and my settings only allow app store apps. But that only happened once...and it was strange. I clicked OK, it disappeared. I thought maybe java had been quarantined, so I did the command to clear that flag:
xattr -rd com.apple.quarantine /path/to/the/binary/java
But that made no difference. I'm sure this is new security features in Catalina making things difficult...but I can't figure out why or how to work through them. Its a java app that is launched via the app.command file which finds java on the machine and then launches it...defaulting to finding a local copy in its own subfolder.
Checkout out the sandbox settings of your project. the App Sandbox should be set as false in the entitlements file.
The sandboxing feature prevents your app from elevating the privilege in your app.
reference: https://developer.apple.com/app-sandboxing/

Sudo in Java's Runtime.exec & gksu for umount

I am writing a Java application in which (among other stuff) I'd mount a external device, do some copying, and then unmount it.
//I am mounting several devices in created dirs named sdb, sdc... according to the partitions
String[] command = {"gksu", "mount", "/dev/sd" + letter + "1", "mounter/sd" + letter};
Runtime.getRuntime().exec(command);
This works fine both in the terminal and in my program.
To unmount faster, I thought about using umount -a but gksu umount -a doesn't work in the terminal and consequently not in the Java program. sudo umount -a does work in the terminal, but not in the application. Meanwhile, I got it to work by unmounting the devices 1 by 1, but it would be cleaner if I could get umount -a to work someway.
If you understand why either gksu doesn't work with umount or sudo with Runtime.exec(), I'd take your explanation.
Thanks
I feel the problem is sudo not asking me for a password, as gksu does. But I don't know how to give it a password.
This is very likely the case.
There are a couple of different possible situations here, and each I think has it's own solution:
The user running the program (in the case of a desktop app) already has privileges to run the commands you need. - Prompt the user to enter their password and pass it to sudo through stdin using the -s flag. Check out the sudo man page for more. This is simple and ensures that your application doesn't have greater access than the user running it.
If your application needs to run with different privileges than the user has, or if this is running on a server, then the application should be run as it's own System User. You can then use visudo to give that system user the ability to run ONLY the commands you need without requiring a password. Just be very cautious about editing the sudoers file. I recommend adding it as a separate file and just linking to it in the actual sudoers so that it's easier to undo later.

running application from cmd as administrator through java code

I executed the netsh command from the CMD that was manually opened by me by right clicking the CMD icon from the start and then selecting run as administrator from the options.It worked fine.Now I tried to run the netsh command through my java code,then it is not working.Nothing is happening when i run that code.I want to ask that I can run applications like notepad.exe from the cmd by calling appropriate methods of the runtime class from my java code,But how can I open the same application with the administrator priviliges from my java code.r.exec("notepad"); where r is an object reference to the runtime class will run the application,but the notepad so opened will not be in administrator mode.Actually I guess that learning to run the application in administrator mode from CMD will be enough to do the work done as The corresponding CMD command will be passed as the argument to the exec() method of the Runtime class.So my questions are:
How to run any application from CMD in windows 8 with administrator privilliges?
The way i want to implement the use of netsh is a good thing to practise or there is some other way out i must use these commands from my java code.
I have seen some commands while googling but they where not working out for me,like runas /user:administrator "notepad.exe" etc.
Thanks
You cannot use the runas /user:administrator approach, as that requires a password input which you cannot provide from an external source (such as a Java application) for security reasons.
I had a similar issue to you in the past, and I solved it using PsExec, running the process on localhost with an administrator username and password allowed me to execute external applications as an administrator.
Using your example you could run:
PsExec.exe \\\\127.0.0.1 /accepteula -u USER -p PASSWORD notepad.exe
The "/accepteula" flag prevents the requirement to accept the EULA interactively when run on a machine for the first time.
This approach may require a bit of tweaking to get working with your setup, but hope it gives you a starting point.

Start a process with Java [duplicate]

This question already has answers here:
How do I run a batch file from my Java Application?
(12 answers)
How to input password to sudo using java Runtime?
(7 answers)
Closed 9 years ago.
Recently I am stuck with a Java program. My requirement is, I have to restart my snmp service through java code in my Ubuntu machine. Normally We can do the same with
Runtime.getRuntime().exec("service snmpd restart");
Above code is working fine if I log in to the system with ROOT user.
But now the requirement came that, it may possible client machine doesn't have root permission. In that case to restart the snmp one need to execute the command with sudo "sudo service snmpd restart". This command will ask for machine password and after entering the password system will restart the service.
Now whenever I am trying to execute the java code with the below code, it's not restarting the service. ecasue it doesn't have the option to receive the password.
Runtime.getRuntime().exec("sudo service snmpd restart");
So, please help me to find out a way to restart a service with java when user is not a root user and need to start a service with sudo command.
I'm almost sure that you will not be able to intercept the input for password as that would be a security issue. -- See Ricardo Cachiera's answer.
Regardless I don't recommend you do -S. My recommendation is that you configure sudo to let the java user run the snmpd with out a password (ie NOPASSWD).
So you'll have to know what user you are going to use to the Java code. Once you do, do this in a terminal:
sudo visudo
Add a line something like:
myusername ALL = (root) NOPASSWD: /etc/init.d/snmpd
You may have to make a wrapping shell script (as sudo doesn't support argument security) if you want to use the service command instead of sudo /etc/init.d/snmpd.
try that:
Runtime.getRuntime().exec("$echo <password> | sudo -S service snmpd restart");
It's a work solution although it's not the best solution in matter of security, because the password can be read by anyone that have access to JAR File.
My suggestion has nothing to do with programming. Just modify your Sudoers file to allow users of your program to run the desired commands with NOPASSWD.
For a generic solution:
MY_APP_USERS MY_APP_HOSTS= NOPASSWD: MY_APP_CMDS.
When, the user tom (Part of MY_APP_USERS) runs sudo service snmpd restart (Part of MY_APP_CMDS) in one of the MY_APP_HOSTS he will be granted permission without using a password.
And a specific solution (without Aliases):
# tom will be able to run sudo /usr/sbin/service snmpd restart at userver
tom userver=(root) NOPASSWD: /usr/sbin/service snmpd restart

Execute shell command in Tomcat

So I have the following problem: I have a web service running inside a Tomcat7 server on Linux. The web service however has to execute some commands (mostly file operations such as copy and mount). Copy I've replaced with java.nio, but I don't think that there is a replacement for mount.
So I'm trying to execute shell commands out of my Tomcat Java process. Unfortunately it doesn't execute my commands. I've implemented the execution of shell commands in Java before. So my code should be correct:
Process pr = Runtime.getRuntime().exec("mount -o loop -t iso9660 <myimage> <mymountpoint>");
pr.waitFor();
<myimage> and <mymountpoint> are absolute paths, so no issues there either.
I've debugged my commands and they are working when executed on the console.
I've tried sending other commands. Simple commands such as id and pwd are working!
I've tried using /bin/bash -c "<command>", which didn't work.
I've tried executing a shell script, which executes the command, which didn't work.
I've tried escaping the spaces in my command, which didn't work.
So I've digged even deeper and now I'm suspecting some Tomcat security policy (Sandbox?), which prevents me from executing the command. Since security is no issue for me (it's an internal system, completely isolated from the outside world), I've tried a hack, which became quite popular just recently:
System.setSecurityManager(null);
This didn't work either. I'm using Java7 and Tomcat7 on RHEL6. Tomcat7 is just extracted! I don't have any files in /etc/.. or any other folder than /opt/tomcat/, where I've extracted the zip from the Tomcat home page. I've searched the /opt/tomcat/conf folder for security settings, but all I could find was the file catalina.policy, where it didn't seem like I could set some security level for shell commands.
Any ideas?
A few things:
System.setSecurityManager(null);
you have just killed the security of your application.
Yes, Tomcat is running as root. If I execute id I'm root as well.
Fix this immediately!
Now on to the question. You shouldnt have Tomcat executing anything, you need to defer this to a separate process whether that be a shell script or another Java program. This should also remove what (I hope) was a dependency on root running Tomcat. It should be possible to perform this command as a non-privileged user that cannot log into the system normally. You would do this by configuring /etc/fstab and supplying that same user the permissions to do this. From a pure security POV the process that mounts should not be owned by the tomcat user. Nor should the tomcat user ever be root. So to recap:
1) Stop running Tomcat as root
2) Create a separate process outside of the context of Tomcat to run this mount
3) Create a tomcat user, this user should not be able to log into the system nor should it be a privileged user (admin,super user, etc)
4) Create a process user, this user should be configured exactly as the tomcat user
5) Edit /etc/fstab giving the process user the necessary permissions to mount correctly.
It's generally a bad idea to use the single-string form of Runtime.exec. A better option is to use ProcessBuilder, and split up the arguments yourself rather than relying on Java to split them for you (which it does very naïvely).
ProcessBuilder pb = new ProcessBuilder("/bin/mount", "-o", "loop", /*...*/);
pb.redirectErrorStream(true); // equivalent of 2>&1
Process p = pb.start();
You say you're on RHEL so do you have selinux active? Check your logs and see if this is what's blocking you (I think it's audit.log you're looking for, it's been a few years since I've used selinux). If this does turn out to be the problem then you should probably ask on superuser or serverfault rather than SO...
I'm not sure if that's the problem you are having, but I've seen issues when Runtime.exec() is used without reading the associated output buffers. You can find a detailed explanation and potential solutions here. Reading the output and error streams can also help you figure out what's going on at the OS level when you run the command.
I've recently had to do something like this from a Swing app.
You'll probably be able to pull it off with ProcessBuilder, as in Ian's answer, but I found that once things start to get complex, it's easier to write a shell script that does what you want, enabling you to pass as few parameters as possible. Then use ProcessBuilder to invoke the shell script.
If you're invoking anything that has more than really minimal output, you'll also have to read the output and error streams to keep the process from blocking when the output buffers fill, as it seems you are already doing.
I use sudo -S before command and for the tomcat7 user: tomcat7 ALL=(ALL) NOPASSWD:ALL

Categories