I have to make some code for java classes about files permission, and I found FilePermission class. But when I tried to use it to change my files permissions, nothing happened. I know i can use file.setReadable or something. But my question is whether I can change permissions using FilePermission class and if not what this class is meant for
String pathToFolder="C:\\tmp\\file.txt";
FilePermission folderPermission = new FilePermission("C:\\tmp\\*", "read");
PermissionCollection permission = folderPermission.newPermissionCollection();
permission.add(folderPermission);
FilePermission dataPermission = new FilePermission(pathToFolder, "write");
permission.add(dataPermission);
if(permission.implies(new FilePermission(pathToFolder, "read, write"))) {
System.out.println("Read, Write permission is granted for the path "+pathToFolder);
}
else {
System.out.println("No Read, Write permission is granted for the path " + pathToFolder);
}
Now I can use it to compare two permissions on PermissioCollection, but it still doesnt change permissions on real files.
Thanks for all your help and sorry for my English.
Java documentation for FilePermission, clearly states that, this java class is used to represent the actions (i.e read/write/delete/execute/readlink). It does NOT change the permission of existing file/folder.
You can tough perform an "implies" action as you have defined in your example.
FilePermission class helps to resolve crucial file access decisions (using implies method) which if implemented manually can lead to errors or security breaches like any other permission class.
Related
I have a series of folders containing books on a server which I am accessing with this piece of code. I want to make each of these folders an object so I can do some work with the files inside them later on. I'm trying to use this method to return a list of the folders as Book objects.
public List<Book> getBooks(File folder){
List<Book> books = new ArrayList<Book>();
for (File f : folder.listFiles()){
if (f.isDirectory()){
System.out.println(f.getAbsolutePath() + "" + f.listFiles());
books.add(new Book(f));
}
}
return books;
}
The println statement in this block is printing, as it should, the direct path to the folder and then the memory address along with some other information. However, somewhere in the folder it is printing out null when listFiles() is called. The folder that it is doing this on is not empty. This supposedly empty folder is then passed to my class init method.
public Book(File bookFolder) {
this.bookFolder = bookFolder;
this.bookPath = bookFolder.getAbsolutePath();
System.out.println(bookFolder + " " + bookFolder.listFiles());
for (File f : bookFolder.listFiles()) {
...
}
}
The println statement in this block prints out the exact same path to the folder and then a different memory address, which is also expected. When it hits the "empty" folder it prints null for the memory address again.
Now, for the real issue, the line with the for loop is where the program crashes and throws a NullPointerException which isn't even described in the documentation for the listFiles method.
Why could this be happening? Also, why are my non-empty folders returning null?
The documentation for the listFiles() method clearly states that it "Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs."
One of the most common reasons that a directory cannot be listed is that the process lacks the right permissions. Are you running this as yourself, or in some sort of service that runs as a different user?
By the way, the File API is a great example of how bad life can be without exceptions.
For developers who have already included the following solutions :
Added the storage permission
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
2.The directory from you want to list the files exists.
Enabled the permission in the device you are testing in the app permission settings
BELOW CODE WILL SOLVE YOUR PROBLEM IF YOUR DEVICE SDK IS GREATER THAN OR EQUALS TO ANDROID 10(Q)
In the manifest file include this code inside tag
<application android:requestLegacyExternalStorage="true"...</application>
Let me know if your problem is solved!
I had a similar problem with dir.listfiles(); returning null for the user folder \AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\
it was the folder had by default Permissions set on "everyone" Deny all
what screwed me over i think was the fact that I never expected any Deny permission to exist there.
also for any one thats unclear on what i mean by a deny permission
when you set deny for user permissions it overrides the allow for user permissions unless you remove it and it was on a default install of windows 10 home.
For me it was caused by trailing spaces. Use variable.trim()
I want to know whether the user launched our Java-based application from a read-only file system like from a .dmg, so functions like auto-update will be able to show meaningful information instead of aborting with an error. I first thought checking the .app's path would be sufficient (when launched from a .dmg it is something like /Volumes/MyApp 1.2.3/MyApp.app, but this won't work, because the user might have installed the application on a different partition. What other things may I check?
You can use -[NSURL getResourceValue:forKey:error:] with the key NSURLVolumeIsReadOnlyKey. You would apply this to the app bundle URL as returned by [[NSBundle mainBundle] bundleURL]. So:
NSBundle* bundle = [NSBundle mainBundle];
NSURL* bundleURL = bundle.bundleURL;
NSNumber* readOnly;
NSError* error;
if ([bundleURL getResourceValue:&readOnly forKey:NSURLVolumeIsReadOnlyKey error:&error])
{
BOOL isReadOnly = [readOnly boolValue];
// act on isReadOnly value
}
else
{
// Handle error
}
If OSX is POSIX compliant, to determine if filesystem is mounted R/O, You can use statvfs() or fstatvfs(), returned struct statvfs field f_flag should have ST_RDONLY bit set for R/O filesystem.
As it was pointed in comments, check if this information is correctly provided by OS.
JNA and this question may be usefull for Java.
A few more ideas, which may be usefull here (access(), open(), utime() ).
OS X specific statfs() may be used too, but this function is not portable (Linux and *BSD have slightly different statfs() functions).
You can also check directly from Java whether a certain path points to something within a read-only directory by querying the FileStore associated with your path:
File classpathRoot = new File(MyClass.class.getClassLoader().getResource("").getPath());
/* getPath() actually returns a String instead of a Path object,
* so we need to take this little detour */
Path yourAppPath = classpathRoot.toPath();
boolean isReadOnly = Files.getFileStore(yourAppPath).isReadOnly();
I am running into a Java security problem. I have an agent which uses the pdfbox-1.7.1.jar to decrypt a PDF whose password I know. The jar has been placed in /jvm/lib/ext on both the server and my client, and I get this little beauty of a stack trace:
java.lang.SecurityException
at java.lang.SecurityManager.checkPermission(SecurityManager.java:582)
at COM.ibm.JEmpower.applet.AppletSecurity.checkSecurityPermission(AppletSecurity.java:1332)
at COM.ibm.JEmpower.applet.AppletSecurity.checkPermission(AppletSecurity.java:1613)
at COM.ibm.JEmpower.applet.AppletSecurity.checkPermission(AppletSecurity.java:1464)
at java.lang.SecurityManager.checkSecurityAccess(SecurityManager.java:1725)
at java.security.Security.insertProviderAt(Security.java:190)
at java.security.Security.addProvider(Security.java:210)
at org.apache.pdfbox.pdmodel.encryption.SecurityHandlersManager.getInstance(SecurityHandlersManager.java:146)
at org.apache.pdfbox.pdmodel.PDDocument.openProtection(PDDocument.java:1365)
at org.apache.pdfbox.pdmodel.PDDocument.decrypt(PDDocument.java:798)
at com.magerman.hremail.prep1docc.PDFDecryptor.decrypt(Unknown Source)
at com.magerman.hremail.prep1docc.MetaAttachment.decrypt(Unknown Source)
at com.magerman.hremail.prep1docc.MetaDocContainingAttachments.removePasswordOfPDFAttachments(Unknown Source)
at com.magerman.hremail.prep1docc.EPDFPreparerFactory.generateAttachmentsTriggerDocs(Unknown Source)
at com.magerman.hremail.prep1docc.EPDFPreparerFactory.run(Unknown Source)
at com.magerman.hremail.prep1docc.BaseClass.NotesMain(Unknown Source)
at lotus.domino.AgentBase.runNotes(Unknown Source)
at lotus.domino.NotesThread.run(Unknown Source)
Both Client and Server are using 8.5.3.
The Agent security level is set to 3.
Putting the jars in the agent itself does not help.
The signer of the agent is full admin on the server.
The security exception seems to point at "insertProviderAt"
This is what I tried:
putting
grant {
permission java.security.AllPermission;
}
solves my problem, but I will never get this past my eagle-eyed admin.
I am trying to reduce the scope of the permission to just the database but the documentation here: http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html did not really tell me how to input a notes database.
I looked into Stephan Wissel's article on Xpages Java security here: http://www.wissel.net/blog/d6plinks/SHWL-8JYAT5 and inserted the following into my /jvm/lib/security/java.policy file:
grant codeBase "xspnsf://server:0/development/hre-mail/hre-mail2_0/hre-mail_(2_0)_dev.nsf/-" {
permission java.security.AllPermission;
};
but that did not work either, I suppose because my codeBase syntax is not valid for the nsf database but only for webpages.
I am also trying to reduce the Permission to that which is really needed, and looking at the documentation here: http://docs.oracle.com/javase/1.4.2/docs/guide/security/permissions.html
implies that I have to do something like
java.security.SecurityPermission "insertProvider.{name}"
but I have no idea what {name} should be.
I also read Mikkel's article on http://lekkimworld.com/2013/06/20/java_in_notes_domino_explained_on_java_security_and_how_it_relates_to_notes_domino.html
but my brain fried at about the middle of the page. In particular, I am not sure how to actually implement this method. Could you hold my hand and walk me through please?
Whilst I'm at it, am I right in assuming that whenever I put new jars in /jvm/lib/ext, all I need to do is a
tell http restart
to have the JVM reload? I am assuming Domino is using a single JVM for Xpages, Agents, and the HTTP Task, is this right.
Also, am I right that I need to restart the server for any new policies in java.policy to be effective?
Any ideas?
Thanks to Richard, Simon, Mark Myers, and giulio for looking at the question.
I finally got round to understanding Mikkel's article (by reading it really slowly) on:
http://lekkimworld.com/2013/06/20/java_in_notes_domino_explained_on_java_security_and_how_it_relates_to_notes_domino.html
The solution was easier than I thought, I was confused by the reflection example.
It's a more elegant way than modifying the java.policy file (which I didn't manage, btw).
I modified the class that was creating troubles when I was calling its decrypt() method by adding a new method dopriviledgeddecrypt() which is a cunning wrapper around the method that was causing troubles. I then modified all the callers to PDFDecryptor.decrypt() so that they were calling PDFDecryptor.dopriviledgeddecrypt(). The last step involves exporting the whole class to a jar file, which is then placed in the \jvm\lib\ext folder on both the machine where you are developing (in the client) and on all the servers where this code will run.
I was also unable to find out whether there is a syntax for modifying the java.policy file so that it affects only a single Notes Database. (Update: I now know that this is not possible)
package com.magerman.hremail.prep1docc;
public class PDFDecryptor {
/**
* Instantiates a new pDF decryptor.
*
* #param inputFile
* the input file
* #param inputPassword
* the input password
*/
public PDFDecryptor(final File inputFile, final String inputPassword) {
originalFile = inputFile;
password = inputPassword;
}
/**
* Decrypt. Given an inputted PDF File, will try to remove the security of
* the PDF and save in-place. Done after the attachments have been extracted
*/
public final void decrypt() {
// naughty code here
}
public final void doproviledgeddecrypt() throws Exception {
AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception {
PDFDecryptor.this.decrypt();
return null;
}
});
}
}
The Java Security Manager allows to specify the permissions of some piece of code by defining clauses like:
...
grant codebase http://foo.bar.com/test.jar {
permission java.io.FilePermission "${user.dir}/*", "read,write"; };
...
in a policy file (default: <JRE_root>\lib\security.
This grants code stemming from the given URL to read and write from/to the user's home directory (which is of course a no-no but that's another story).
But how do I define "NO permission", i.e. if that piece of code should NOT be allowed to read or write anywhere? I tried to specify:
...
permission java.io.FilePermission "/-", "";
...
"/-" means the root directory and everything below it (i.e. everything) and the second argument "" was meant to signal "". But when I specify this like above I get a "token error". Apparently "" is not a valid "action". But how else does one then express "nothing" or "no permission" in these policy files?
Simply don't add any permissions lines. Classes will typically be given permissions to read their own code and resources. (See the API docs for java.io.FilePermission.)
i am trying to check whether a file is writable or not. i have changed the file permission by myself for all users. but if i try to run the program, it show "true" as a response. if i allow the permissions, then also it is showing "true".
Whats is my problem?
try
{
File file = new File("D:/myproject_log/delivery_report_edr.out");
if(!file.canWrite())
{
System.out.println("you can't write!!!");
}
else
System.out.println("you can write!!!");
}
catch(Exception e)
{
e.printStackTrace();
}
It is working fine. I copied your code and run it twice. First I got You can write, then right click on the file folder, go to properties and select read only and run the program again and I got you can't write
So as per the documentation of the method canWrite() it gave me the expected output. Please confirm your settings once again and check.
Have you tried using the java.nio.file.Files#isWritable method. as well as File#canWrite ?
I have also found that File.canWrite() cannot be trusted, especially over network drives, often returning true even though a file write will fail or vice-versa. I made my own method that actually tries to write a dummy file to the dir. That is simple to write and foolproof. Maybe they fixed it though.
I had the same issue with a file located in c:\programFiles\folder and the File.canWrite method returned true and i was getting the same exception.
when i changed the permission of write as allowed true for USER defined in security tab of Folder properties, It gave me no exception.