Need to combine "Sudo" and "ScpTo" examples of JSch - java

I'm unsuccessful with combining "Sudo" and "ScpTo" cases.
I noticed, that both work through "exec" channel.
Clean "ScpTo" case finishes with "Permission denied" message.
"Sudo" case
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand("sudo -S -u <supervisor> whoami");
works fine.
When I connect to my server through FarManager I write server option:
sudo su -l <supervisor> -c /usr/libexec/openssh/sftp-server
Also, I can run usual SFTP client like this:
sftp -s 'sudo su -l <supervisor> -c /usr/libexec/openssh/sftp-server' "usual user"#"host"
and give put command.
But such option (-s) is not implemented in JSch.
How can I configure my case (Sudo & ScpTo) with JSch?

In ScpTo.java example, there's this code:
String command="scp " + (ptimestamp ? "-p" :"") +" -t "+rfile;
Change that to:
String command="sudo su -l <supervisor> -c scp " + (ptimestamp ? "-p" :"") +" -t "+rfile;

Related

Cannot connect from MySQL Workbench to dockerized MySQL server

I'm trying to connect from the MySQL Workbench to my dockerized mysql server. I'm using Windows 10. Here is my Dockerfile:
FROM ubuntu:latest
# package updates & install mysql
RUN apt-get update && apt-get install -y mysql-server
RUN apt-get -y install supervisor
ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# bind sql script
ADD musicdb.sql /tmp/musicdb.sql
RUN sed -i -e"s/^bind-address\s*=\s*127.0.0.1/bind-address = 0.0.0.0/" /etc/mysql/my.cnf
EXPOSE 3306
RUN /bin/bash -c "/usr/bin/mysqld_safe &" && \
sleep 5 && \
mysql -u root -e "CREATE DATABASE musicdb" && \
mysql -u root musicdb < /tmp/musicdb.sql
CMD ["/usr/bin/supervisord", "-n"]
I'm using this library to create, run, etc. the container from Java:
https://github.com/spotify/docker-client
My actual method to do this in Java is:
public static void createContainerWithPorts(){
DockerClient docker;
try {
docker = DefaultDockerClient.fromEnv().build();
//PortBindings
Map<String, List<PortBinding>> portBindings = new HashMap<>();
List<PortBinding> hostPorts = new ArrayList<>();
hostPorts.add(PortBinding.of("0.0.0.0", "3306"));
portBindings.put("3306", hostPorts);
HostConfig hostConfig = HostConfig.builder().portBindings(portBindings).build();
ContainerConfig containerConfig = ContainerConfig.builder().hostConfig(hostConfig).image("mysql-container").exposedPorts("3306").build();
//create container
ContainerCreation contaierCreation = docker.createContainer(containerConfig);
String id = contaierCreation.id();
//start container
docker.startContainer(id);
ContainerInfo containerInfo = docker.inspectContainer(id);
System.out.println(containerInfo.toString());
Scanner scanner = new Scanner(System.in);
scanner.next();
docker.killContainer(id);
docker.removeContainer(id);
docker.close();
} catch (DockerCertificateException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (DockerException e) {
e.printStackTrace();
}
}
Java builds the Container fine from the before created Docker Image. When I'm looking on actual running Docker Container it looks that the port binding works. When I access my container with docker exec -it SQLContainer bash it works fine and I can access my SQL server.
When i try to connect with MySQL Workbench, I got the error message shown in the picture below:
MySQL Workbench Error Message
Does someone know what I'm doing wrong?
Thanks,
I think you need to create a new user for your mysql server and specify from where the user can be used. This is because root access is only available through localhost I believe.
So to create a new user, you need to add a little something to the RUN command where you start your server:
RUN /bin/bash -c "/usr/bin/mysqld_safe &" && \
sleep 5 && \
mysql -u root -e "CREATE DATABASE musicdb" && \
mysql -u root musicdb < /tmp/musicdb.sql && \
mysql -u root -e "CREATE USER 'newUser'#'%' IDENTIFIED BY 'somePassword'" && \
mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'newUser'#'%' WITH GRANT OPTION"
That way you create a new user with the name newUser that can access from anywhere.

Executing PMCMD command from JAVA Client

I want to start workflow from JAVA. I connect to informatica server using SSH and execute the command pmcmd to start workflow
JSch js = new JSch();
Session s = js.getSession("username", "host", 22);
s.setPassword("password");
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
s.setConfig(config);
s.connect();
Channel c = s.openChannel("exec");
ChannelExec ce = (ChannelExec) c;
ce.setCommand("pmcmd startworkflow -sv integrationservice -d Domain_dwhetl -u user -p pass-usd hq -f dvl wf_test");
//ce.setCommand("find -name PMCMD");
ce.setErrStream(System.err);
ce.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(ce.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
ce.disconnect();
s.disconnect();
System.out.println("Exit code: " + ce.getExitStatus());
When I run this I'm getting the error : bash: pmcmd: command not found.
If I add path to pmcmd.exe:
ce.setCommand("/PMRootDir/pmcmd startworkflow -sv integrationservice -d Domain_dwhetl -u user -p pass-usd hq -f dvl wf_test");
I get the error: /PMRootDir/pmcmd: error while loading shared libraries: libpmasrt.so: cannot open shared object file: No such file or directory
But when I run those commands in informatica server directly the workflow starts successfully.
Cand anyone help to solve this problem?
Thank you!
You have set the PATH to where Informatica is installed, or more specifically the directory the pmcmd executable is present.
Add the export command before calling pmcmd.
export PATH=<path Infa installation directory>:$PATH;
#Samik, Thank you!
I've added this
"export INFA_HOME=<path Infa installation directory>; " +
"export PM_HOME=<path Infa installation directory>; " +
"export PATH=$PATH:<path Infa installation directory>/server/bin; " +
"export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:<path Infa installation directory>/server/bin; "
and it worked
You need to set Environment Variable Path
Example
export PATH=$PATH:/pwc/Informatica/10.2/server/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/pwc/Informatica/10.2/server/bi

curl script works on command line but java returns "couldn't connect to host"

I use a curl call in a shell script, curlerWS.sh, to connect to SOAP, REST, and RESTful web services. The issue I have currently is with a SOAP call, specifically connecting to a Sharepoint endpoint, when the script is called from java.
curlerWS.sh works as intended when called from a subshell (another shell script). It returns the expected XML response from sharepoint.
The curl command it calls also works interactively in the main shell.
However, when I call curlerWS.sh from a java class (running in Tomcat on the same server as the aforementioned shell calls) using the same parameters, curl returns curl: (7) couldn't connect to host
This call has worked in the past with other sharepoint endpoints which are currently down for maintenance.
I believe I've ruled out proxies. When I set the proxy explicitly in the ProcessBuilder I get an error from the proxy server, referring to erroneous usage of it to reach an internal site.
The curlerWS.sh call in the script:
curlerWS.sh -X -s https://host.domain/sites/site/subsite/_vti_bin/Lists.asmx \
-f "studies.xml" \
-u "domain\user" \
-p pass \
-a ntlm \
-q '<GetListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/"><listName>{FAC53F9A-F7DC-4511-A675-F23B479C87CB}</listName><viewName></viewName><query></query><viewFields></viewFields><rowLimit>0</rowLimit><queryOptions><QueryOptions></QueryOptions></queryOptions></GetListItems>' \
-t http://schemas.microsoft.com/sharepoint/soap/GetListItems
The curl call in curlerWS.sh:
curl \
-s \
"$DEBUG" \ # -v
--show-error \
-k \
--$AUTH \ # --ntlm
-A "basic" \
-u "$USER:$PASS" \
$FILE \ # -o output
-H "Content-Type: text/xml; charset=utf-8" \
-H "SOAPAction: $ACTION" \
-d "$DATA" \ #<?xml ...><soapenv:Envelope...>...</soapenv:Envelope>
"$SOURCE"
The curl call on the command-line:
curl -s -v --show-error -k --ntlm -A "basic" -u "domain\user:pass" -o studies.xml -H "Content-Type: text/xml; charset=utf-8" -H "SOAPAction: http://schemas.microsoft.com/sharepoint/soap/GetListItems" -d '<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><GetListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/"><listName>{FAC53F9A-F7DC-4511-A675-F23B479C87CB}</listName><viewName></viewName><query></query><viewFields></viewFields><rowLimit>0</rowLimit><queryOptions><QueryOptions></QueryOptions></queryOptions></GetListItems></soapenv:Body></soapenv:Envelope>' "https://host.domain/sites/site/subsite/_vti_bin/Lists.asmx"
The curlerWS.sh call in java:
ArrayList<String> args = new ArrayList<String>();
args.add(new Finder().getEnv(YADA_BIN)+CURL_EXEC);
args.add("-X");
args.add("-s");
args.add(soapSource+soapPath);
args.add("-u");
args.add(soapDomain+"\\"+soapUser);
args.add("-p");
args.add(soapPass);
args.add("-a");
args.add(soapAuth);
args.add("-q");
args.add(soapData);
args.add("-t");
args.add(soapAction);
String[] cmds = args.toArray(new String[0]);
l.debug("Executing soap request via script: "+Arrays.toString(cmds));
String s = null;
try
{
ProcessBuilder pb = new ProcessBuilder(args);
l.debug(pb.environment().toString());
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader si = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((s = si.readLine()) != null)
{
l.debug(s);
if(null == result)
{
result = "";
}
result += s;
}
si.close();
}
catch(IOException e)
{
String msg = "Unable to execute NTLM-authenticated SOAP call using system call to 'curl'. Make sure the curl executable is still accessible.";
throw new YADAAdaptorException(msg,e);
}
The java args array values reported in the log (the first call to l.debug)
Executing soap request via script: [/apps/bioinfo/dev/bin//curlerWS.sh, -X, -s, http://host.domain/sites/site/subsite/_vti_bin/Lists.asmx, -u, domain\user, -p, pass, -a, ntlm, -q, <GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'><listName>{FAC53F9A-F7DC-4511-A675-F23B479C87CB}</listName><rowLimit>10000</rowLimit></GetListItems>, -t, http://schemas.microsoft.com/sharepoint/soap/GetListItems]
After several iterative changes to the configuration, the answer was effectively that my java code was doing a few things wrong. Regrettably, so was I.
First, the different methods of execution of the SOAP request were not in fact identically configured. To wit:
The shell and subshell versions were identical.
However, at first, the java version contained a slightly modified version of the soapBody.
The correct markup:
<GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'><listName>{FAC53F9A-F7DC-4511-A675-F23B479C87CB}</listName><viewName></viewName><query></query><viewFields></viewFields><rowLimit>10</rowLimit><queryOptions><QueryOptions></QueryOptions></queryOptions></GetListItems>
The original markup:
<GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'><listName>{FAC53F9A-F7DC-4511-A675-F23B479C87CB}</listName><rowLimit>10</rowLimit></GetListItems>
I've experienced different results when excluding viewFields and queryOptions in various sharepoint incarnations. In this case, including them, even empty, seems necessary. Excluding them returns a sharepoint error referring to unexpected value or some such. However, I wasn't even getting to this point when I noticed that discrepancy, because of the other errors.
Next, I noticed, upon inspecting the trace output of the shell calls that the webserver address was referring to port 443. By excluding the port from the host config in the java call, java was defaulting to port 80 which was unreachable with the http protocol.
After correcting the port configuration error, by explicitly setting it to 443, the curl response was no longer failing per say, but was returning, instead, an empty response.
This was because the secure https protocol designation was being rewritten to be insecure. Specifically, https was reverting to http in the java call.
A refactoring of the java code to retain https was the ultimate fix. I was also able to omit the explicit port config, because with https, the server redirects from port 80 to 443.
Thanks for your views and comments!

How start jboss service remotely with SSH?

I need to start the service of Jboss 7.1.1 remotely through SSH. But when execute the command does not happened.
The command: ssh user#server '/etc/init.d/jboss-as start' #(no error, no service started)
The script jboss-as:
#!/bin/sh
case "$1" in
start)
echo "Starting JBoss AS 7"
su --command "/path/to/jboss-as-7.1.1.Final/bin/standalone.sh >& /dev/null &" root
;;
stop)
echo "Stopping JBoss AS 7"
su --command "/path/to/jboss-as-7.1.1.Final/bin/jboss-cli.sh --connect command=:shutdown" root
;;
*)
echo "Usage: /etc/init.d/jboss-as {start|stop}"
exit 1
;;
esac
exit 0
How to execute the command: ssh user#server 'service jboss-as start' or ssh user#server '/etc/init.d/jboss-as start'?
The connection with ssh is OK
The Jboss Server is OK
If i execute the code: ssh user#server '/etc/init.d/mysql restart' it happens!
One of a few things are limiting your ability to run this service with the command as that is a valid method of starting the service.
user#server '/etc/init.d/jboss-as start'
All of which you can test remotely after initiating the SSH connection. SSH into the server and start the service with the same user you are going to connect with using the above command.
Firstly make sure the service is actually called 'jboos-as' with ls /etc/init.d/ |grep 'jboss'. The result will be exactly how you will call the command so replace jboss-as with the output from the grep.
Secondly it is a permissions issue on the init script. From what I could see online you have to create this script so if the permissions are not setup correctly it will not execute.
To check run ls -al /etc/init.d/ |grep 'jboss' and your output should appear as follows:
Output:
-rwxr-xr-x. 1 root root 2979 Sep 19 05:34 jboss*
The user issuing the start command will need to match the first user listed. In this case the first 'root' and/or be in the same group as the group listing which is the second 'root' in the example. This can vary if for instance your user is in the wheel group, but generally services are run as root or a specific user for that service.
Lastly The more important aspect is that the file is executable. This is listed as the x value in the ls -al output above. If no 'x's are listed you will need to make the file executable with the following:
chmod +x /etc/init.d/jboss
IMPORTANT all the above command will need you to referrence the file as it output in the first grep command, so /etc/init.d/jboss-as or /etc/init.d/jboss or /etc/init.d/jboss-something different.
I hope this helps you out and if it does not please post the results of the ls -al output and we can help you further.
Ok.
Let`s go.
Search the name of the jboss service:
ls /etc/init.d/ |grep 'jboss' Returned "jboss-as". It is ok!
Permissions:
ls -al /etc/init.d/ |grep 'jboss' Returned exactly the same output: -rwxr-xr-x. 1 root root 2979 Sep 19 05:34 jboss-as Its ok!
Still do not works.
The principal objective to execute this command is an action of button in the Java program using SWT and the lib that implements SSH called JSCH. Look the code:
Session session = jsch.getSession("user", "SERVER_IP_ADDRESS", PORT);
session.setPassword("pass");
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
Channel channel = session.openChannel("exec");
((ChannelExec)channel).setCommand("'/etc/init.d/jboss-as start'"); #command to start jboss service
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream in=channel.getInputStream();
channel.connect();

mysqldump returns code 6 when run from java, but the same command works fine from command line

When I run the same command from Java via Runtime.getRuntime I get the return code 6. The same command works fine from command line:
process = Runtime.getRuntime().exec(mysqldumpCommand);
int processComplete = process.waitFor();
For those 2 commands I get the return code 6 when run from java and no dump. The work fine from command line(I don't have a password on the local env.)
mysqldump --user=root --password= --host=localhost dbname > c:\temp\dumpfile.sql
mysqldump --user=root --password="" --host=localhost dbname > c:\temp\dumpfile.sql
When deliberately put wrong password I get return code 2 in java, and a connection error in command line:
mysqldump --user=root --password= --host=localhost dbname > c:\temp\dumpfile.sql
The return codes as I found them here:
Taken from client/mysqldump.c in MySQL 5.1.59:
#define EX_USAGE 1
#define EX_MYSQLERR 2
#define EX_CONSCHECK 3
#define EX_EOM 4
#define EX_EOF 5 /* ferror for output file was got */
#define EX_ILLEGAL_TABLE 6
How come I get (error) return code 6 when running the same command in java and works fine from command line?
Later Edit: I try it from Windows.
Runtime.exec is not a shell, so redirections with > and < won't work. Currently the command is passing > to mysqldump, which interprets it as the name for the table you want to export. (Hence return code 6, "illegal table".)
There are two solutions:
Run a shell. Use this command instead of the one you have:
cmd.exe /c "mysqldump --user=root --password= --host=localhost dbname > c:\temp\dumpfile.sql"
Write the output from the command to a file yourself, with Process.getInputStream().
The mysqldump now supports --result-file=
So it would look like this.
mysqldump --user=root --password= --host=localhost dbname --result-file=c:\temp\dumpfile.sql

Categories

Resources