Changing permissions to read data/anr files programmatically - java

I want to read the ANR files in the /data/anr/ directory on my device. I have managed to push my apk file to the /system/priv-app/ directory, so I can list the anr files generated by that apk in my program, but I cannot read each file (there are currently 2).
Their current permissions are set to "-rw-------" and when I execute
chmod 644 /data/anr/anr-name using adb shell, the permission changed successfully to "rw-r--r--" and I can read them through my program. However, because it is unpredictable when they generate, I want to change the permission to 644 within my Android Studio java program.
I have tried:
POSIX permissions
Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rw-r--r--"));
This caused my program to hang at that line.
JNA chmod library using the CLibrary interface
private static CLibrary libc = (CLibrary) Native.loadLibrary("c", CLibrary.class);
libc.chmod("/data/anr/anr-name", 0644);
This caused my program to hang as well.
Runtime.getRuntime().exec()
String[] str = new String[3];
str[0] = "chmod";
str[1] = "644";
str[2] = "/data/anr/anr-name";
Process pro = Runtime.getRuntime().exec(str);
pro.waitFor();
pro.waitFor() returns 1 and pro.getErrorStream() returns "Operation not permitted."
java.io.File.setReadable(boolean readable)
file.setReadable()
file.isReadable() returns false and the file permission has not been changed.
For the record, I have a rooted device. My min AND Target SDK Version are API 26.
I also cannot execute "su" in my program because when I tried, it gave me a "Permission denied" error.
I am completely at loss as to what to do. I just want to read the ANR files from my program.

Related

How to enumerate connected USB storage devices Ubuntu Java

I have an application, mostly in Java' that controls an airborne infrared camera via a webpage GUI (served by the Ubuntu machine) which starts running automatically when the computer is powered up and towards the end of the boot. The application runs as a user, not root, even though the user is not logged in.
After a great many images are collected the data need to be archived by using rsync to a folder on the operator's USB drive. I need to have the USB drive mounted and know its name tag. The computer is headless and the operator, who is on the aircraft, cannot be expected to know Linux in any case.
On an Ubuntu I see that logged in and running the xfce4 GUI, and only then, the drives are listed in /media/user-name/drive-tag (I note that /media/username is owned by root but the folder named for the drive is owned by the user.) and are shown in /etc/mtab :
/dev/sdd1 /media/programmer/DATA-02-2TB vfat rw,nosuid,nodev,uid=1001,gid=1001,shortname=mixed,dmask=0077,utf8=1,showexec,flush,uhelper=udisks2 0 0
How can I, through Java or through a combination of Java and bash, detect and mount a USB storage device?
If that's not possible do I need to ask the user, through the GUI, to enter the device tag or name, e.g., 'DATA-02-2TB' and then create the mount point and mount the USB drive via a script using the information above?
First install usbmount, a Ubuntu tool.
sudo apt-get update
sudo apt-get install usbmount
Then edit the /etc/usbmount/usbmount.conf file:
sudo sed -i 's/MOUNTOPTIONS="/MOUNTOPTIONS="user,umask=000,/' /etc/usbmount/usbmount.conf
These steps are described at Serverfault. Note that only a subset of drive formats is supported including the ubiquitous VFAT.
With this in place USB external drives and thumb drives will mount in /media as /media/usb0 through /media/usb7 and will be listed in /etc/mtab.
/dev/sdc1 /media/usb0 vfat rw,noexec,nosuid,nodev,sync,noatime,nodiratime,umask=000 0 0
I've tested this on my 14.04 machine. Now if I could only get the drive label.
Edit: The sync option does not work well with flash drives. Read the /etc/usbmount/usbmount.conf file for details and remove "sync" from the appropriate line in that file. A full backup made with sync option ran for over an hour before I cancelled it but took only about 5 minutes with sync removed. Note the comment about using pumount to unmount the non-synched drive.
public static ArrayList<String> usbDriveList() throws FileNotFoundException {
final String MTB_ADDRESS = "/etc/mtab";
final String TARGET = "^/media/usb[0-7]$"; // REGEX
final File file = new File(MTB_ADDRESS);
final ArrayList<String> driveList = new ArrayList<String>();
try (Scanner in = new Scanner(file)) {
while (in.hasNext()) {
final String[] splitLine = in.nextLine().split(" ");
if (splitLine[1].matches(TARGET)) {
driveList.add(splitLine[1]); // got it!
}
}
} catch (final FileNotFoundException e) {
throw new FileNotFoundException();
}
return driveList;
}

How to run superuser commands on Linux through Java code?

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?
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.
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.)
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.

pm command giving Segmentation fault

I am trying to update an Apk on Android Remotely. To run the update without the need of user intervention, I am using this post Link .
But the process is returning with the exit code 139 which means Segmentation fault. My tablet is rooted and I have confirmed it.
File file = new File(Constants.UPDATE_APK_PATH);
try {
String[] filenames = file.list();
File apk = new File(file, filenames[0]);
Process pid = Runtime.getRuntime().exec(
new String[] { "su", "-c",
"pm install -r "+apk.getAbsolutePath()});
pid.waitFor();
Can anybody tell what exactly i am doing wrong? The file is present at the location and the signature of both the apk is same.
I'm pretty sure if you use adb install instead of pm install would resolve this issue.
But i believe in this case application does not have enough permissions to install packages.

Change permission of a created file so only the current user can read it

I need to set the permission to read a file to a specific user of the operating system, how can I do this in Java?
Edit:
The file will be created with permissions just to the user running the application, than it needs to set read permission to a single user, other users will not have the permissions to read the file.
Use the methods setExecutable, setReadable, and setWritable in java.io.File. You can use these to change any permission bit of a file you own. Direct link: http://download.oracle.com/javase/6/docs/api/java/io/File.html#setReadable%28boolean%29.
Testing this on MacOSX revels that only the user read value is changed. When program
import java.io.File;
public class Test
{
public static void main(String[] args)
{
File f = new File("test.txt");
f.setReadable(true);
}
}
the folloiwng happens.
$ touch test.txt
$ chmod 000 test.txt
$ javac Test.java
$ java Test
$ ls -l test.txt
-r-------- 1 morrison staff 0 Jun 7 13:28 test.txt
If you're targetting Windows Vista/7, build your JAR as EXE and embed a manifest requesting for Admin rights.
If it's just an I/O problem, use the default File methods setReadable, setWritable, setExecutable :)
In regards to making the permissions for a single user, start with using ncmathsadist's code to add read permissions, then change the owner of the file to whoever needs access.
I found in the Ant source code they use for the change-owner task. For unix this can be found in the Ant source tree at org/apache/tools/ant/taskdefs/optional/unix/Chown.java. You might be able to include this and use it as an API call to change the user programmatically.
if you want to change file permissions on old Java versions like Java 5, you can use this:
Runtime.getRuntime().exec("chmod 000 " + PATH + fileName);
on windows you'll have to replace chmod with the appropriate CACLS.exe command syntax

java.io.IOException: Permission denied on network folder

i'm having the the post's title error when trying to write a file on a window folder , mounted on unix system. I've developed a web service which runs inside a Tomcat 6 on a linux os and need to write on a windows network folder. System administrators have mounted it on the Linux sever and have no problem to create and modify a file on it.
When i try to execute the posted code i get the following exception :
Permission denied
java.io.IOException: Permission denied
at java.io.UnixFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:850)
The weird thing is that it seems to be related to the File.createNewFile method on a network folder , in fact the service can write on local file system without problems, both on debug (the pc i use to develop the service) and a tomcat folder system administrators have provided me on the linux server. The file gets created but is empty and the log entry following the create method doesn't get printed. Moreover if i use a plain outputstream to create and write the file i've no problems.
I cannot find any explanation about the exception on the web. Since i'm not very experienced with java , i'd like to understand why i'm getting this error. Am i using it in the wrong way ? Is it a bug of the library ? Do i miss to pass some parameter ?
As stated , i've solved the problem using a plain outputstream, this is a question to improve my understanding of java.
FileOutputStream fos = null;
try{
log.info(String.format("file length: %s",streamAttach.length));
log.info(String.format("check File : %s",filename));
File f = new File(filename);
if(f.exists())
...
boolean done= f.createNewFile();//here comes the exception
//nothing of the following happens
if(!done)
throw new NWSException("error creating file");
log.info(String.format("file %s creato", nomeFile));
thank you in advance for any answer
I ran into this problem recently and found that java.io.File.createNewFile() actually requires the "Change Permissions" permission (you can find this entry under Security->Advanced when checking folder permissions). Without this it will create the file and then subsequently throw an IOException.
It's deceptive because you will still be able to create files on the folder when manually testing, however createNewFile() will still fail if it doesn't have this particular permission (presumably such that it can change the permissions on the file its creating).
If you are using Netapp that shares an NTFS (CIFS) style filesystem to Unix you could be experience "NFS is not allowed to change permissions on a file in an NTFS-style security volume." (TR-3490 page 16)
Options here are to change to a unix filesystem or set the cifs.ntfs_ignore_unix_security_ops flag to on for the file system which quiches the NFS permission error.
java.io.UnixFileSystem.createFileExclusively(Native Method) opens the file with the O_EXCL and 0666 umask so I would get a EACCES, which really was a NFS3RR_ACCES
open("/net/storage01-a/filer/myfile", O_RDWR|O_CREAT|O_EXCL, 0666) Err#13 EACCES
Also you can use OutputStream to create the file, that does not use O_EXCL it seemes
It definitely not Java specific problem. If this Unix folder is mapped to your windows try to open file explorer and create file in this directory. I believe that you will get permission denied too. In this case fix this problem or ask your system administrator to help you.
Good luck!

Categories

Resources