Changing User Environment with ProcessBuilder + java - java

I'm trying to change the user of the child process to a user with minor privileges
but when i execute the start method of ProcessBuilder the subprocess exec with the same user of the parent
LinkedList<String> commands = new LinkedList<String>();
commands.add("vlc");
ProcessBuilder builder = new ProcessBuilder(commands);
Map<String,String> enviroment = builder.environment();
enviroment.clear();
enviroment.put("USER", "otheruser");
enviroment.put("LOGNAME", "otheruser");
enviroment.put("PWD", "/home/otheruser");
enviroment.put("HOME", "/home/otheruser");
enviroment.put("USERNAME", "otheruser");
enviroment.put("SHELL", "/bin/false");
builder.directory(new File("/home/otheruser"));
Process process = builder.start();
process.waitFor();
I'm working in Linux(Ubuntu)

Jim is absolutely right.
But if you still want to run your program as different user you have to user platform dependent tools.
Windows:
use runas command, e.g.: runas /user:domain\jamesbond regedt32.exe
Unfortunately runas requires from user to type password manually.
The following article explains how to work around the problem:
http://www.windowsnetworking.com/kbase/WindowsTips/WindowsXP/AdminTips/Miscellaneous/RunprogramsasanotheruserinWindows2000WindowsXP.html
Alternatively you can write your own utility in VBS and run it from java. See this post for details: http://weblogs.asp.net/hernandl/archive/2005/12/02/startprocessasuser.aspx
Unix:
see reference of su and sudo.
su is fine but it requires password too (unless current user is root).
To work around this you can create expect script (see http://en.wikipedia.org/wiki/Expect).
Expect is installed on most unix distributions by default.
Good luck!

You cannot change the effective user just by passing in a different USER environment variable. This is a security feature of Linux (and Unix in general), otherwise a malicious user could just set the USER variable to ROOT. Subprocesses always execute as the same user as the parent unless the executable is marked setuid or the process does a setuid() to change the effective user (and the setuid() is allowed).

Related

Run batch file as administrator in java [duplicate]

I am developing a small shutdown scheduler project in which i have to put the computer in "Stand By" mode. The command that i am using is
Runtime.getRuntime().exec("cmd /c Powrprof.dll,SetSuspendState ");
This command requires Admin rights which i don't know how to get. Also while searching for previous answers i found i can use elevate.exe as
Runtime.getRuntime().exec("c:/elevate Rundll32.exe Powrprof.dll,SetSuspendState ");
Elevate.exe is doing the task but is consuming too much of time i.e. making the software slow. Is there any other speedy way? I am using Netbeans IDE.
Runtime.getRuntime().exec("runas /profile /user:Administrator \"cmd.exe /c Powrprof.dll,SetSuspendState\"");
Also plz see comments
Running as admin without Admin rights
You have a few options
A. Create a shortcut with admin priv.
The shortcut will run cmd /c Rundll32.exe Powrprof.dll,SetSuspendState
Your Java code will run the shortcut:
Runtime rt = Runtime.getRuntime();
rt.exec("cmd /c start \"\" \"myshortcut.lnk\"")
Right click the shortcut icon > properties > advanced > run as administrator
B. Run the java process as administrator
Again, create a shortcut and set to run as administrator. Any processes spawned will also have admin privileges. Your java code will run:
rt.exec("cmd /c Powrprof.dll,SetSuspendState")
C. Use JNA to directly call SetSuspendState routine. The Java process will require admin priv (like B), but you won't have to spawn a process. If you like this, I can provide source code.
D. Use wizmo utility: wizmo quiet standby
Add parameter /savecred
runas /profile /user:Administrator /savecred
Input the password one times. In future OS will not ask you password.
I'm using Windows 10. IDK why but runas isn't working and isn't reporting any errors.
I found this answer on superuser.com:
powershell -Command "Start-Process 'cmd.exe /c Powrprof.dll,SetSuspendState ' -Verb runAs"
No password required if you have permission to elevate.
No shortcut required on client machine
No dependency on runas
Requires powershell
Powershell is installed by default on Windows since Windows 8 and Windows Server 2008 R2, according to an answer found on serverfault.com.

How to discover linux username with administrator privileges in Java

I created a program which needs administrator privileges to be executed (in this program I am using a port which is <1024).
So I use this command to execute:
sudo java -jar example.jar
In my program I try to create a folder in this path:
Paths.get("/home/" + System.getProperty("user.name"))
The problem is that System.getProperty("user.name") answers with "root" and so my new directory is in "/home/root/", but I want it in "/home/my_username".
My question is: how can I discover my username and then create the new folder in the right path?
You can change from
Paths.get("/home/" + System.getProperty("user.name"))
to the user.home System Property like
Paths.get(System.getProperty("user.home"))
If you do
sudo whoami
it responds with
root
however if I do
sudo bash -c 'echo $SUDO_USER'
I get
peter
You do this from Java with
String user = System.getenv("SUDO_USER");
if (user == null)
user = System.getProperty("user.name");
Linux user name is normally bound to the USER environment variable at login(1) time. The best approach is to use this variable, as other means (running who(1) or id(1) command for example) all do inspect it (using the uid as parameter, to scan files for it). The same applies for HOME and SHELL variables. All of these are collected by login(1) on authenticating the user (or by the PAM libraries) and get propagated to all derived processes through the environment.
The weird fact is that you can have several usernames bound to the same uid, and not using the environment can lead you to getting the wrong answer (if you scan the /etc/passwd file with your uid as argument, you can get to a different passwd(5) file entry ---of course, with the same did) Use:
String username = System.getEnv("USER");
for it.
On other side, if you have created a new session (with sudo(1) command or similar) and switched both uid and euid and the environment has been changed (reinitialised), how you distinguish this from a proper login made by root account. In that case there are no traces that the process were invoked by a non-root user.

Call terminal and run command through Java App

I'm using the followig code to run a command from my Java App:
String cmd[] = {"sh","-c", "sudo chmod 777 -R " + path};
Terminal.runCommand(cmd);
I'd like to execute the .jar just by click in it and choose "Open with.." -> "Java";
The problem is that the app keep wating for a password because of the "sudo" command, but no terminal is called, the user can't give the password..
So, how could I call the coomand above AND a terminal to give the user a chance to insert the password and the application finally keep going?
Thank very much!
This is a sudo question, not a Java one; sudo does things as root. Your process doesn't have root priviledges, so sudo needs to authenticate the human being. That's a feature, not a bug. The system is not supposed to allow you to run root commands.
One option might be to use gksu instead, which is shipped by default on some distributions. It works similarly, but will pop up the password dialog in the GUI instead of on the (in this case non-existent) terminal.
Another might be to simply run your Java process as root, with all the security implications that might have. In some situations that can be a valid choice, but be careful.
Or you can check the man page for sudo and sudoers -- it's possible to configure accounts not to require a password, and to limit them to particular commands when they do.

executing java with another id

I was wondering How to execute java Application with different userName and password.
For example:
Right now: When I do,
System.getProperty("user.name");
I get user1.
But I want to program in such a way that it says user2.
Can somebody help me How to accomplish this with Java or bat files.
Any kind of help is appreciated.
The java system property user.name is set by the operating system. So if you login as a different user and start you're java program, it will run under that username.
But You can also change the user under which you execute an program (if you have sufficient rights for it!).
Linux: use the sudo command
sudo -u user2 java yourprogram
(but you need to have sudo rights, for example by being root)
Windows use the runas command:
runas /user:domain\user2 java yourprogram
You can override this value, the same as any other system property with
java -Duser.name=my-new-user
or
System.setProperty("user.name", "my-new-user");
Note: neither solution changes the user-id of the process, just the value returned by System.getProperty("user.name");
You need to switch to user2 (su user2 on linux), then run your program.
If you're doing this on Windows, you can use the runas command in a batch file to run in the context of a different user. On a Unix/Linux system, you can use the su command.

Running UNIX commands as different user, from Java

Trying to write a Java program capable of running a UNIX command as a different UNIX user. I have the user's password, and I know the command I want to run, but the command has to be run as that user - so I have to login as that user first.
For example: say we have a user, jim, who wants to see what's in bob's home directory, and (for whatever reason) jim has access to execute ls whereas bob does not. We are currently logged in as bob. Here is what we (could) do:
bob#host$ su jim && ls ~bob
Problem is, we get prompted for jim's password. Since this is run from a Java program, i.e.
Process p = Runtime.getRuntime().exec("su jim && ls ~bob");
we get prompted for jim's password and hung up. We know jim's password. However, I can't enter it.
Additionally, we can't use an Expect script (don't have it installed) and we can't become the superuser. I also looked into using SSH to try this, since we could technically do
bob#host$ ssh jim#host "ls ~bob"
but this also doesn't work since I don't have permission to setup passwordless SSH.
My last-ditch effort is to try and use an SSH library for Java, since the password is available to the Java program and I would be able to login with that (and execute the proper command). But since I'm going to be running on the same host, it seems like overkill.
Any suggestions?
P.S: Java version 1.4.2, can't upgrade; AIX UNIX 5.3.
Have sudo installed, have the user running the Java program entered in /etc/sudoers for the commands in question, and use sudo -u jim ls ~bob.
Problem solved. Used JSch (http://www.jcraft.com/jsch/) to SSH into the server with known username and password, and execute command. Thanks all for your suggestions!
Possibly a java implementation of Expect? ExpectJ comes up when googling but I couldn't find any documentation regarding running under 1.4.2.
Have you tried redirecting the sudo commands input and writing to that. I haven't used Java in a while but I believe there is a way to get the input stream and write to it. You could use that to write the password followed by a new line and sudo or su should accept the password.
Use getInputStream() and write your password out to that.
su jim -c ls ~Bob
Perhaps this would work:
Process process = Runtime.getRuntime().exec("su jim && ls ~bob");
OutputStream standardInput = process.getOutputStream();
Writer standardInputWriter = new OutputStreamWriter(standardInput);
standardInputWriter.write("password\n");
standardInputWriter.close();
I'm not sure this code:
Process p = Runtime.getRuntime().exec("su jim && ls ~bob");
will be executed in a shell, needed to evaluate the &&, that is a shell command (/bin/sh). You should pass the command "ls ~bob" via a command line swith of su. Something like:
su jim -c 'ls ~bob'

Categories