Search code examples
javalinuxsudo

How to execute sudo command with password with a given userid in linux server using Java program?


I want to execute a linux command similar as below using Java program:

sudo - su (userid)

It then prompts for password

[sudo] password for (userid):

I have a java program which connects to a linux server with my valid credentials and able to execute/return basic linux commands like "ls -ltr, pwd ..". However, I am stuck and facing issues to execute sudo commands as mentioned above.

Please suggest what is the code that I need to add to my program to execute/run sudo with a given userid. The requirement is to run a script in a given directory and it can be run only with a specific user which has privileges to run and hence the need of sudo - su .

Here is my code:

    String host="IP";
    String user="myusername";
    String password="mypassword";
    String command1="ls -ltr";


    try{

        java.util.Properties config = new java.util.Properties(); 
        config.put("StrictHostKeyChecking", "no");
        JSch jsch = new JSch();
        Session session=jsch.getSession(user, host, 22);
        session.setPassword(password);
        session.setConfig(config);
        session.connect();
        System.out.println("Connected");

        Channel channel=session.openChannel("exec");
        ((ChannelExec)channel).setCommand(command1);

        channel.setInputStream(null);
        ((ChannelExec)channel).setErrStream(System.err);


        InputStream in=channel.getInputStream();
        channel.connect();
        byte[] tmp=new byte[1024];
        while(true){
          while(in.available()>0){
            int i=in.read(tmp, 0, 1024);
            if(i<0)break;
            System.out.print(new String(tmp, 0, i));
          }



          if(channel.isClosed()){
            System.out.println("exit-status: "+channel.getExitStatus());
            break;
          }
          try{Thread.sleep(1000);}catch(Exception ee){}
        }
        channel.disconnect();
        session.disconnect();
        System.out.println("DONE");
    }

    catch(Exception e)
    {
        e.printStackTrace();
    }

I tried adding the below code as suggested in the one of the questions posted earlier.

public static void main(String[] args) throws IOException {

String[] cmd = {"/bin/bash","-c","echo password| sudo -S ls"};
Process pb = Runtime.getRuntime().exec(cmd);

String line;
BufferedReader input = new BufferedReader(new InputStreamReader(pb.getInputStream()));
while ((line = input.readLine()) != null) {
    System.out.println(line);
}
input.close();
}

I get the below error:

>java.io.IOException: Cannot run program "/bin/bash": CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at java.lang.Runtime.exec(Runtime.java:620)
    at java.lang.Runtime.exec(Runtime.java:485)
    at com.fedex.sample.LeanFtTest.test(LeanFtTest.java:82)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
    at org.testng.SuiteRunner.run(SuiteRunner.java:240)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1198)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1123)
    at org.testng.TestNG.run(TestNG.java:1031)
    at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:132)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:230)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:76)
    Caused by: java.io.IOException: CreateProcess error=2, The system cannot 
    find the file specified
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(ProcessImpl.java:386)
    at java.lang.ProcessImpl.start(ProcessImpl.java:137)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    ... 27 more

Solution

  • I have used the method as below to add the key associated with the sudo user I wished to execute in the given server. And ensure that key location is given as input string. It worked!

    jsch.addIdentity(key);