如何使用Jsch libary以编程方式在Unix框中使用su命令切换用户?

时间:2019-06-05 19:09:38

标签: java ssh redhat jsch

我有一个非常基本的Java程序,该程序使用Jsch库自动执行位于Unix框中的某些Shell脚本。

为了自动执行这些shell脚本,需要执行以下步骤:

  • 使用用户john登录Unix框
  • 切换到另一个用户simba
  • 使用OutputStream提供此新用户的凭据,绕过cli的输入提示,然后使用os.flush()刷新它
  • 使用whoami命令检查用户切换是否发生

我编写了以下程序来实现此功能,但是正如您在控制台输出中看到的那样,用户切换没有发生,第二条whoami命令为我提供了相同的用户名(即:john)< / p>

我想到的另一个问题是,对于clisu -logout等没有bash输出的命令,我应该怎么做。当什么也不会返回时,在无限while(true)循环中等待输出是没有意义的。

请指导。

当前控制台输出

Connecting SSH to my-unix-box.net - Please wait for few seconds... 
Connected!

Executing command: whoami
john
Executing command: su - simba
Setting suPasswd now....
Executing command: whoami
john  //WRONG: SHOULD BE "simba" 

Disconnected channel and session

Process finished with exit code 0

SSHConn.java

public class SSHConn {

    static Session session;
    static String[] commands = {"whoami", "su - simba", "whoami"};

    public static void main(String[] args) throws Exception {
        open();
        runCmd(commands);
        close();
    }

    public static void runCmd(String[] commands) throws JSchException, IOException {
        for (String cmd : commands) {
            System.out.println("Executing command: " + cmd);
            Channel channel = session.openChannel("exec");
            ((ChannelExec) channel).setCommand(cmd);
            InputStream in = channel.getInputStream();
            OutputStream out = channel.getOutputStream();
            channel.connect();
            //passing creds only when you switch user
            if (cmd.startsWith("su -")) {
                System.out.println("Setting suPasswd now....");
                out.write((Constants.suPasswd + "\n").getBytes());
                out.flush();
            }
            System.out.println("Flushed suPasswd to cli...");
            //capture output that we receive from cli (note: some commands such as "su -" does not return anything)
            if (!cmd.startsWith("su -")) {
                captureCmdOutput(in, channel);
            }
            channel.setInputStream(null);
            channel.disconnect();
        }
    }

    public static void captureCmdOutput(InputStream in, Channel channel) throws IOException {
        System.out.println("Capturing cmdOutput now...");
        byte[] tmp = new byte[1024];
        while (true) {
            System.out.println("in the while loop...");
            while (in.available() > 0) {
                System.out.println("into the available loop...");
                int i = in.read(tmp, 0, 1024);
                if (i < 0) {
                    break;
                }
                System.out.print(new String(tmp, 0, i));
            }
            if (channel.isClosed()) {
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (Exception ee) {
                System.out.println(ee.getMessage());
            }
        }
        System.out.println("Command output captured...");
    }

    public static void open() throws JSchException {
        JSch jSch = new JSch();
        session = jSch.getSession(Constants.userId, Constants.host, 22);
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.setPassword(Constants.userPasswd);
        System.out.println("Connecting SSH to " + Constants.host + " - Please wait for few seconds... ");
        session.connect();
        System.out.println("Connected!\n");
    }

    public static void close() {
        session.disconnect();
        System.out.println("\nDisconnected channel and session");
    }

}

pom.xml

<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.51</version>
</dependency>

su命令用法:

 su [options] [-] [USER [arg]...]

Change the effective user id and group id to that of USER.
A mere - implies -l.   If USER not given, assume root.

Options:
 -m, -p, --preserve-environment  do not reset environment variables
 -g, --group <group>             specify the primary group
 -G, --supp-group <group>        specify a supplemental group

 -, -l, --login                  make the shell a login shell
 -c, --command <command>         pass a single command to the shell with -c
 --session-command <command>     pass a single command to the shell with -c
                                 and do not create a new session
 -f, --fast                      pass -f to the shell (for csh or tcsh)
 -s, --shell <shell>             run shell if /etc/shells allows it

 -h, --help     display this help and exit
 -V, --version  output version information and exit

For more details see su(1).

0 个答案:

没有答案