Oracle DB. Run OS command from database itself using Java stored procedure.



There are some cases, when you need to access an OS running your database. You need it just right now, but you don’t have an accees or permissions. Let’s do it from database using java stored procedure.

If you want to run following commands under non-system user, don’t forget to grant appropriate permissions to your user.
begin
dbms_java.grant_permission(‘MYUSER’, ‘SYS:java.lang.RuntimePermission’, ‘writeFileDescriptor’, ”);
dbms_java.grant_permission(‘MYUSER’, ‘SYS:java.lang.RuntimePermission’, ‘readFileDescriptor’, ”);
dbms_java.grant_permission(‘MYUSER’, ‘SYS:java.io.FilePermission’, ‘/bin/sh’, ‘execute’);
end;

First, compile java class:

create or replace and compile java source named host as
import java.io.*;
public class Host {
  public static String executeCommand(String command) {
    String buff = null;
    String tmp ="";
    try {
      String[] finalCommand;
      if (System.getProperty("os.name").toLowerCase().indexOf("windows") != -1) {
        finalCommand = new String[4];
        finalCommand[0] = "C:\\winnt\\system32\\cmd.exe";
        finalCommand[1] = "/y";
        finalCommand[2] = "/c";
        finalCommand[3] = command;
      } else {                                                // Linux or Unix System
        finalCommand = new String[3];
        finalCommand[0] = "/bin/sh";
        //finalCommand[0] = "";
        finalCommand[1] = "-c";
        finalCommand[2] = command;
      }

      // Execute the command...
      final Process pr = Runtime.getRuntime().exec(finalCommand);
      
      // Capture output from STDOUT...
      BufferedReader br_in = null;
      try {
        br_in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
        tmp =tmp+"STDOUT: "+"\n";
        while ((buff = br_in.readLine()) != null) {
          //System.out.println("stdout: " + buff);
          tmp=tmp+buff+"\n";
          try {Thread.sleep(100); } catch(Exception e) {}
        }
        br_in.close();
      } catch (IOException ioe) {
        //System.out.println("Error printing process output.");
        tmp =tmp+ "Error printing process output."+"\n";
        //ioe.printStackTrace();
      } finally {
        try {
          br_in.close();
        } catch (Exception ex) {}
      }
      
      // Capture output from STDERR...
      BufferedReader br_err = null;
      try {
        br_err = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
        tmp =tmp+"\n"+"STDERR: "+"\n";
        while ((buff = br_err.readLine()) != null) {
          //System.out.println("stderr: " + buff);
          tmp=tmp+buff+"\n";
          try {Thread.sleep(100); } catch(Exception e) {}
        }
        br_err.close();
        return tmp;
      } catch (IOException ioe) {
        //System.out.println("Error printing execution errors.");
        tmp =tmp+ "Error printing execution errors."+"\n";
        //ioe.printStackTrace();
      } finally {
        try {
          br_err.close();
        } catch (Exception ex) {}
      }
    }
    catch (Exception ex) {
      tmp =tmp+ ex.getLocalizedMessage()+"\n";
    }
    return tmp;
  }

};

Second, compile a PL/SQL-wrapper for java class.

create or replace function host (p_command IN VARCHAR2) return varchar2
   AS LANGUAGE JAVA
   NAME 'Host.executeCommand (java.lang.String) return String';

Now you can run your command, ls for example:

begin
  dbms_output.put_line(host('/bin/ls /opt'));
end;

Leave a Reply

Your email address will not be published. Required fields are marked *