with txt read from content java root nio file-permissions

from - read content txt java



¿Hay alguna forma para que una aplicación Java obtenga permisos de root? (3)

Cuando se ejecuta Files.walk(Paths.get("/var/")).count() como un usuario sin privilegios, la ejecución puede generar una excepción, ya que hay carpetas dentro de /var/ que necesitan permiso de root para ser recorridas.

No estoy buscando una manera de ejecutar un comando de bash como root (por ejemplo, sudo find /var ), usando Process , etc.

Solo quiero asegurarme de que Files.walk(Paths.get("/var/")).count() AccessDeniedException Files.walk(Paths.get("/var/")).count() no arroja una AccessDeniedException :

Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0 at sun.reflect.NativeMethodAccessorImpl.invoke at sun.reflect.DelegatingMethodAccessorImpl.invoke at java.lang.reflect.Method.invoke at org.springframework.boot.devtools.restart.RestartLauncher.run Caused by: java.io.UncheckedIOException: java.nio.file.AccessDeniedException: /var/cache/httpd at java.nio.file.FileTreeIterator.fetchNextIfNeeded at java.nio.file.FileTreeIterator.hasNext at java.util.Iterator.forEachRemaining at java.util.Spliterators$IteratorSpliterator.forEachRemaining at java.util.stream.AbstractPipeline.copyInto at java.util.stream.AbstractPipeline.wrapAndCopyInto at java.util.stream.ReduceOps$ReduceOp.evaluateSequential at java.util.stream.AbstractPipeline.evaluate at java.util.stream.LongPipeline.reduce at java.util.stream.LongPipeline.sum at java.util.stream.ReferencePipeline.count at com.example.DemoApplication.main ... 5 more Caused by: java.nio.file.AccessDeniedException: /var/cache/httpd at sun.nio.fs.UnixException.translateToIOException at sun.nio.fs.UnixException.rethrowAsIOException at sun.nio.fs.UnixException.rethrowAsIOException at sun.nio.fs.UnixFileSystemProvider.newDirectoryStream at java.nio.file.Files.newDirectoryStream at java.nio.file.FileTreeWalker.visit at java.nio.file.FileTreeWalker.next at java.nio.file.FileTreeIterator.fetchNextIfNeeded

Esto es solo un ejemplo. Usando el filter(...) es posible evitar la excepción. Pero este ejemplo también puede expandirse a otros casos de uso.

En resumen, ¿es posible que las aplicaciones CLI, JavaFX, etc. obtengan permisos de root después de que se hayan ejecutado desde la línea de comandos a través de un método como java -jar app.jar ?


No hay una manera fácil de cambiar los permisos. Java no es bueno en estas tareas. Solo hay algunos trucos como verificar permisos en el inicio e intentar cambiar los permisos a través de su / sudo, luego reiniciar la aplicación o usar Java-gnome. Por favor lee un poco más aquí: Java: pide privilegios de root en Ubuntu


Sólo algunas ideas completamente no probadas:

1) Ejecute su aplicación con privilegios de raíz para comenzar con:

sudo java -jar myapp.jar

2) Permita que su aplicación inicie una clase iniciadora que solicite permisos de root y luego continúe ejecutando el resto de su aplicación:

java -jar myapp.jar

A su vez, esto ejecuta un comando de shell, pero solo un xterm que solicita una contraseña de root y luego continúa ejecutando un programa java con permisos de root:

xterm -e "sudo sh -c ''java -jar /tmp/myrootapp.jar''"

o tal vez use algo de mejor apariencia usando gksudo. Cuidado con el '' y " .

Tal vez el myapp.jar extrae en un directorio temporal . myapp.jar contiene myrootapp.jar y, por lo tanto, puede iniciarlo como se describe anteriormente. /tmp supuesto, /tmp debe recuperarse desde Java, y preferiblemente debe ser un directorio con un nombre aleatorio al que solo el usuario que ejecuta myapp.jar tenga acceso para evitar la inyección de myrootapp.jar .

Multiplataforma

Usted mencionó /var/ yourself, así que asumí que estaba en algún tipo de Linux. Si se supone que esto funciona en varias plataformas, por ejemplo, en Macintosh o Microsoft Windows, primero debe hacer algún tipo de identificación del sistema. Luego, puede aplicar StrategyPattern en el código para manejar las diversas formas de permitir que myrootapp.jar obtenga permisos de administrador o de administrador.


Si lo que desea es en realidad omitir las rutas donde no tiene acceso, tiene dos enfoques:

Corrientes

En la respuesta a esta pregunta , se explica cómo obtener la secuencia de todos los archivos de un subárbol al que puede acceder.

Pero este ejemplo también puede expandirse a otros casos de uso.

FileVisitor

El uso de FileVisitor agrega una gran cantidad de código, pero le otorga mucha más flexibilidad al recorrer los árboles de directorios. Para resolver el mismo problema, puede reemplazar Files.walk() con:

Files.walkFileTree(Path start, FileVisitor<? super Path> visitor);

extendiendo SimpleFileVisitor (para contar los archivos) y anulando algunos métodos.

Usted puede:

  1. visitFileFailed método visitFileFailed , para manejar el caso, no puede acceder a un archivo por alguna razón; (Consejo de Lukasz_Plawny)
  2. (opcional) preVisitDirectory método preVisitDirectory , preVisitDirectory permisos antes de acceder al directorio: si no puede acceder a él, simplemente puede omitir su subárbol (tenga en cuenta que puede acceder a un directorio, pero no a todos sus archivos) ;

por ejemplo 1

@Override public FileVisitResult visitFileFailed(Path file, IOException exc) { // you can log the exception ''exc'' return FileVisitResult.SKIP_SUBTREE; }

por ejemplo 2

@Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { if(!Files.isReadable(dir)) return FileVisitResult.SKIP_SUBTREE; return FileVisitResult.CONTINUE; }

FileVisitor docs

Tutorial de FileVisitor

Espero eso ayude.