JSch - 如何以我切换到

时间:2016-12-12 09:47:16

标签: java ssh jsch su

我正在使用Jsch从Windows 7远程连接到Linux服务器。

我必须

(i) login to Linux server with my credentials 
(ii) switch to root using a pmrun command [this is the procedure in our environment], and
(iii) execute su command to switch as "someuser"
(iv) execute further commands as that "someuser"

我完成了步骤(i)和(ii)。

完成步骤(ii)后,来自通道的InputStream将命令提示符显示为root用户的命令提示符。所以我假设我现在已成为root用户。

现在,我是否需要让root用户的会话进一步执行su命令,还是有办法以root用户身份执行更多命令?

有人请帮忙。感谢。

更新:源代码

public class Pmrun {

    public static void main(String[] arg){
        try{
            JSch jsch=new JSch();

            String host=null;
            if(arg.length>0){
                host=arg[0];
            }
            else{
                host="myself@linuxserver.com";
            }
            String user=host.substring(0, host.indexOf('@'));
            host=host.substring(host.indexOf('@')+1);

            Session session=jsch.getSession(user, host, 22);

            UserInfo ui=new MyUserInfo();
            session.setUserInfo(ui);
            session.connect();

            String command=  "pmrun su -";

            Channel channel=session.openChannel("exec");

            ((ChannelExec)channel).setCommand(command);

            InputStream in = channel.getInputStream();
            OutputStream outStream = channel.getOutputStream();
            ((ChannelExec)channel).setPty(true);
            ((ChannelExec)channel).setErrStream(System.err);

            channel.connect();
            TimeUnit.SECONDS.sleep(10);
            outStream.write("xxxxxxx\n".getBytes());
            outStream.flush();

            ((ChannelExec)channel).setCommand("su - someuser");


            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();
        }
        catch(Exception e){
            System.out.println(e);
        }
    }

    public static class MyUserInfo implements UserInfo{
        public String getPassword(){ return passwd; }
        public boolean promptYesNo(String str){
            str = "Yes";
            return true;}

        String passwd;

        public String getPassphrase(){ return null; }
        public boolean promptPassphrase(String message){ return true; }
        public boolean promptPassword(String message){
            passwd="zzzzzzzz";
            return true;
        }
        public void showMessage(String message){

        }

    }


}

4 个答案:

答案 0 :(得分:1)

使用&#34; exec&#34;通道,您只能执行一个命令。

另一个命令在su内执行,而不是在su之后执行。

  • 一个解决方案是在su命令行上提供另一个命令,如:

    su -c command
    
  • 或使用其标准输入将命令提供给su

    outStream.write(("command\n").getBytes());
    

通常,我建议使用第一种方法,因为它使用了更好的API(命令行参数)。

答案 1 :(得分:1)

扩展@ Martin的答案,另一个解决方案是在&#34; shell&#34;中打开频道。将维持会话的模式。像这样......

Channel channel = session.openChannel("shell")

答案 2 :(得分:0)

pmrun的工作方式是将您的用户ID和/或主本地组ID(或netgroup)与已设置的基于角色的配置文件相匹配。此配置文件将授予您执行在配置文件中授权的命令的权限。如果不运行pmrun命令,它将不会使您与其中一个配置文件匹配,因此该命令将被拒绝。如果您查看/ opt / quest / bin文件夹,您将看到可以使用的其他预包装shell。运行pmwrapped_bash与运行pmrun bash相同。然后,您可以发出命令sudo -s以获取Sudo root访问权限和/或su - someuser以输入帐户权限的访问权限。

您最终获得了所需的代码吗?或者这个问题对您来说仍然是一个问题,我可以提供帮助。

对我来说,我需要在/ etc / profile文件中执行pmrun $ shell时传递用户变量,这样用户就不需要输入它,因此它们的脚本也是一样的。

关心Nomadz

答案 3 :(得分:0)

我遇到了类似的问题,但是经过大量的研发和通过SO链接进行扫描终于可以解决它。这是对我有用的程序。

public class SSHConn {

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

    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("\nExecuting 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...");
            }
            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) {
            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()) {
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (Exception ee) {
                System.out.println(ee.getMessage());
            }
        }
    }

    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");
    }

}

输出:

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

Executing command: whoami
Capturing cmdOutput now...
john

Executing command: su - simba -c "whoami ; pwd"
Setting suPasswd now....
Flushed suPasswd to cli...
Capturing cmdOutput now...
simba
/home/simba

Disconnected channel and session