Runtime.exec() pretty exciting stuff

The Challenge - why i can't ignore the small stuff
I have been creating batch job processes that will call EJBs. The issue with this is that the Application server process runs under a certain user id. The user id might only be accessible to a certain group that maintains the Application servers like a middle ware group. With this, any file that is written out by the EJB process in the application server will be created using the user id running the process. Security access to the output files by the process will default to the user id of the application server process.

So, i want to write a file that has a different user id than the user id of an invoked java process.
for example, if a java program was invoked by a user id A1234 i want the file to be written under a different user id B5678. Simple enough ?

(Please take note that i am running the java process under a unix environment)

My approach to the challenge
I don't think there will be any utilities in Java that i can use to do this so my options were:
1. call a shell script in a Java program that will create the file under the new user id that i want using the unix command sudo or su
2. call a shell script in a Java program that will ftp or telnet under the same directory to move or put the file under the new user id that i want.

The problem with the su command is that it only likes to get the user id and password from an actual terminal. It does not allow STDIN redirection.
The problem with sudo is that we have to ask the administrator to set up the proper sudo access that might be minimal but is still will consume time to configure specially if there are thousands of users using the same unix box.
I got ftp and telnet, i ultimately choose to ftp because if allows me STDIN redirection, i have to trick telnet for the commands that i want to execute after i did the telnet.

So the program and shell below writes a file using the same user id that invoked the java process. In order to write a file that is different from that user id i decided to invoke an shell that will ftp to the same directory logging in as a different user in order to move the file to a different user id

The Java Code
Here is the java code that i have created. I will try to explain the important lines here



1import java.io.*;
2public class UserIdTest{
3 public static void main (String [] args){
4 String [] envp = new String[] {"PROC_DIR=/home/c75193",
"TEST_FILE=userIdTest.out",
"TEST_FILE_DIFFID=diffUserIdTest.out"};
5 try{
6 File file = new File("userIdTest.out");
7 Writer outputWriter = new BufferedWriter(new FileWriter(file));
8 outputWriter.write("This is a test file");
9 outputWriter.close();
10 Runtime rt = Runtime.getRuntime();
11 Process prc = rt.exec("userIdTest.sh", envp);
12 int exitValue = prc.waitFor();
13 System.exit(exitValue);
14 }catch (Exception e){
15 e.printStackTrace();
16 }//end of try
17 }//end of method
18}//end of class

Please take note of the following lines:

Line 4 : This is the array of environment variables that we will pass to the executed shell script (You will see later how we use this in the shell script)

Line 11: The actual call to the shell script

Line 12: Return value of the executed script. Beware that the Process class has an exitValue() method which does not wait for my script to end.



The Shell Script


This is the shell script i will point out the important lines here as well


1 #!/bin/ksh
2 ftp -n localhost >test.out << EOF
3 user <user_id> <password>
4 cd $PROC_DIR
5 put $TEST_FILE $TEST_FILE_DIFFID
6 EOF
7 #(sleep 3;
8 # echo <user_id>;
9 # sleep 3;
10# echo <password>;
11# sleep 5;
12# echo "cd $PROC_DIR";
13# sleep 5;
14# echo "cp $TEST_FILE $TEST_FILE_DIFFID";
15# sleep 3;
16#echo "exit")telnet localhost > test.out

The important lines:
Line 3: Supply the new user id and password
Line 4: Remember in the Java program it passed the environment variable using the envp String Array
Line 5: Same explanation as Line 4
Line 6: Indicates the end of the input redirection
Everything after Line 7: This is the tricking the telnet command part

The Result
I have to circumvent the Java process, su and sudo to write a file under a different user id. But to save you the trouble of doing this, i think that the best solution is to include the user id of the application server process be included in a group that other users can access but that will not come easy if you come in an environment where everything was already setup.

Enjoy!

Comments

Popular posts from this blog

OAuth 1.0a Request Signing and Verification - HMAC-SHA1 - HMAC-SHA256

Spark DataFrame - Array[ByteBuffer] - IllegalAurmentException

Gensim Doc2Vec on Spark - a quest to get the right Vector