问题
I am using Jsch to remotely connect to a Linux server from Windows 7.
I have to
(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 completed the steps (i) and (ii).
After completing step (ii), the InputStream from the channel shows the command-prompt as that of the root user. So I assume that I have become the root user now.
Now, do I need to get the root user's session to further execute an su command, or is there a way to execute further commands as the root user?
Someone please help. Thanks.
Update: Source code
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){
}
}
}
回答1:
Extending @Martin's answer, the other solution would be to open the channel in "shell" mode which would maintain the session. Like this...
Channel channel = session.openChannel("shell")
回答2:
With the "exec" channel, you can execute a single command only.
The other command is executed within the su
, not after the su
anyway.
one solution is to provide the other command on a
su
command-line, like:su -c command
or feed the command to the
su
using its standard input:outStream.write(("command\n").getBytes());
In general, I recommend the first approach as it uses a better defined API (command-line argument).
回答3:
The way pmrun works is it matches your User ID and/or primary local group ID (or netgroup) to a role-based profile that has been setup. This profile will give you rights to execute commands they have authorised within the profile. Without running the pmrun command it wont match you to one of their profiles and therefore the command will be rejected. if you have a look in your /opt/quest/bin folder you will see other prewrapped shells that you can use. Running the pmwrapped_bash is the same as running pmrun bash. From their you can then issue the command sudo -s to get Sudo root access and/or su - someuser to enter access that accounts privileges.
Did you end up getting the code you need or is this issue still a problem for you that I could assist.
For me, I need to pass through the users variables as we execute the pmrun $shell from within the /etc/profile file so that users dont need to type this and therefore their scripts works the same.
Regards Nomadz
回答4:
I had a similar issue but after lot of R&D and scanning through SO links was finally able to resolve it. Here is the program that worked for me.
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");
}
}
Output:
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
来源:https://stackoverflow.com/questions/41097999/jsch-how-to-issue-commands-as-the-user-i-have-switched-to