3

My application has multiple users and 1 superuser. I am trying to write and store a file in Linux through Java code but i get permission denied error. I used the following code:

Process process = Runtime.getRuntime().exec("/usr/bin/tiff2pdf -o /tmp/tiff_dir/temp.pdf /tmp/tiff_dir/image.tiff");
int returnCode = process.waitFor();

I get following error:

java.io.FileNotFoundException: image.tiff (Permission denied)

From my analysis, it seems that because the user does not have root permissions, i am getting this error. What is the solution to this?

tryingToLearn
  • 10,691
  • 12
  • 80
  • 114
  • use sudo with your commandline. but you will need to enter a password. be careful with root... – Philipp Sander Feb 13 '14 at 09:24
  • 11
    Find out why you're not having the permissions you expect instead of running superuser commands. That does not seem like a command which should be needing root access. – Dolda2000 Feb 13 '14 at 09:25
  • Have you tried with full path to file? Probably the issue is with cwd not being what you think it is. Privilege elevation is never an answer. – Stefano Sanfilippo Feb 13 '14 at 09:33
  • @PhilippSander But i don't want users to be typing in the password for root. – tryingToLearn Feb 13 '14 at 09:33
  • @Stefano Sanfilippo Yes i have tried with the full path to the files. – tryingToLearn Feb 13 '14 at 09:34
  • 2
    Don't you think that it would be a **huge** security hole if random programs were allowed to reach superuser privileges without any password prompt or the like? – Stefano Sanfilippo Feb 13 '14 at 09:35
  • It seems somewhat strange that `Runtime.getRuntime().exec("/usr/bin/tiff2pdf -o temp.pdf image.tiff")` gives you a `FileNotFoundException`: not finding the file should be an error produced by `tiff2pdf`, how would Java know how to interpret its error code (or stderr output) and conveniently produce the right type of Java exception? What else is around in your code? Can you check manually whether the file was created somewhere at least (what do you expect the current directory to be)? – Bruno Feb 13 '14 at 09:35
  • If you login as the user executing the program, can you open the file? Also, is `tiff2pdf` correctly installed where you think it is? – Stefano Sanfilippo Feb 13 '14 at 09:37
  • @Dolda2000 I tried manually changing file permissions to 766 and it worked. But that is not what i want. I want to find a way to do this without manually changing the permissions. Is their a way to code my way through it? – tryingToLearn Feb 13 '14 at 09:41
  • @Bruno the complete error that comes is "java.io.FileNotFoundException: image.tiff (Permission denied)" – tryingToLearn Feb 13 '14 at 09:42
  • @aksay, my point is that I doubt it's thrown by either of these two lines. Where is it thrown from? – Bruno Feb 13 '14 at 09:43
  • @akshay: I can't think of any way to answer that without more context. With only the information given in your question, I have no idea why you're lacking permissions to begin with. – Dolda2000 Feb 13 '14 at 09:44
  • @Bruno It was thrown from this point only and value of returnCode was 1. Also everything worked fine once i manually changed the file permissions from a root user. – tryingToLearn Feb 13 '14 at 10:09
  • @akshay, Non-sense! How could you possibly be able to read a return value if it has thrown an exception on the line before? – Bruno Feb 13 '14 at 10:12
  • @Bruno Sorry! i am new to Java and quite nervous with this issue right now. You are correct the returnCode value = 1 was at a different point of time when i tweaked the code. a little bit. – tryingToLearn Feb 13 '14 at 10:24
  • @akshay, don't be nervous, it's OK to make mistakes when you learn something new. I'm still not convinced that these two lines throw this exception. I'd bet they're thrown later on when you try to open the file from Java. Reading the stderr (as I suggested in my answer) would certainly give you a better clue regarding what went wrong with this command. – Bruno Feb 13 '14 at 10:41
  • Don't try on implementing the super-user segment in the command line because it posses the a huge security risk, systems with such command lines once broken, can influence the working of the entire system, use `chmod` to edit the permissions to the `file`. – D3X Feb 13 '14 at 09:34

3 Answers3

1

You shouldn't run a command like that as a super user because it poses a security risk (i.e. if someone gained control of your java program, then they have the keys to the kingdom). Instead, you should run with lower permissions.

It looks like the issue is with access to image.tiff not with tiff2pdf. Check the owner and permissions of image.tiff.

orourkedd
  • 6,201
  • 5
  • 43
  • 66
  • Yes, i know that the issue is with the permissions of the file "image.tiff". Problem is how do i change permission of this file from a non superuser? – tryingToLearn Feb 13 '14 at 09:56
  • How do you elevate the permissions of the process? Take a look at this: http://stackoverflow.com/questions/4662574/how-do-i-elevate-my-uac-permissions-from-java – orourkedd Feb 13 '14 at 10:07
  • I would add, however, that this should ONLY be the plan if managing permissions is within the application's scope. If its simply a "way to get it done", you need to find another way. – orourkedd Feb 13 '14 at 10:08
  • 1
    Another possible solution would be to create a service whose sole purpose is to run the `tiff2pdf` command. You would run it as a daemon with higher privileges and make calls to it from your lower privileged program. This way you can contain the security risk if you absolutely need to run it as a super-user. – orourkedd Feb 13 '14 at 10:13
  • @orourkedd, this is clearly a Linux question, elevating the UAC isn't particularly relevant here. Anyway, there's something wrong with the question, since it can't possibly throw this exception there. – Bruno Feb 13 '14 at 10:18
  • @orourkedd this seems to be a kind of a solution. – tryingToLearn Feb 13 '14 at 10:25
  • I guess it depends on the scope of the app. If the app is designed to interact with files of many users (think of something like a WHM in a shared hosting environment), then running with elevated privileges would be ok - the app is made for that. I don't know if elevating privileges is possible, however, and the program may have to be started from a user with the required privileges. – orourkedd Feb 13 '14 at 11:05
1

Firstly, these two lines will not produce a java.io.FileNotFoundException: image.tiff (Permission denied):

Process process = Runtime.getRuntime().exec("/usr/bin/tiff2pdf -o temp.pdf image.tiff");
int returnCode = process.waitFor();

If for some reason, the command fail, it will return a non-zero return code will produce some output on the process's standard error (that's the convention). You can get that standard error from process.getErrorStream() (it might be worth having a look at the standard output too, just in case). If there's an issue with the file not being found there, it will not throw a FileNotFoundException like this, since Java cannot understand the expected output from your command.

EDIT, following your comment:

It was thrown from this point only and value of returnCode was 1. Also everything worked fine once i manually changed the file permissions from a root user.

That's just not possible. If your application throws an exception at either of these two lines, it will exit the normal control flow: you will not be able to read the returnCode at all.

Secondly, your should run your exec command with each argument in a String[] instead of having it all in one line, this should prevent quotation problems if file names have spaces for example.

I would also suggest using absolute paths in your command, to make sure you're working in the directories you expect. (*EDIT: * Now that you're using absolute paths, make sure your user has rwx permissions on /tmp/tiff_dir .)

To answer your question more directly, you can certainly run sudo with Runtime.exec(new String[] {"/usr/bin/sudo", ... the rest of your command ... }, but this is a bad idea, for security reasons. You'd also need to change the sudoers file to allow it without password, or find a way to pass in a password, either on the command line (definitely a security risk!) or by passing it to the input stream manually, somehow.)

Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376
0

Try this :

File file = new File("/opt/image.tiff");
Runtime runtime = Runtime.getRuntime();
runtime.exec(new String[] { "/bin/chmod", "777",file.getPath()});

This will execute full permission on the file.

Sandeep
  • 712
  • 1
  • 10
  • 22
  • 1
    Dude... He does *not* want to change permissions on the file. – jww Feb 13 '14 at 09:35
  • @noloader Yes, but changing the permission the file is better than executing it as super user – Sandeep Feb 13 '14 at 09:36
  • 1
    No. Never change what the user set, at least not before asking the user. There might be a certain reason for a file to have a certain permission mode. – Stefano Sanfilippo Feb 13 '14 at 09:39
  • 1
    @Sandeep Can a non-superuser change the file permissions? I am unable to change permissions from a non super user. – tryingToLearn Feb 13 '14 at 10:06
  • @akshay, normal users change change file permissions on files they own. However, once again, the error you get was not produced by the two lines of code you're showing us. – Bruno Feb 13 '14 at 10:08
  • @akshay if the file was created by the program (or user) you can change the permission. I have tried this before when uploading a file to a server.I had to execute these statement to read the file. Otherwise it returned 'Permission denied' error. – Sandeep Feb 13 '14 at 10:37