簡體   English   中英

Java應用程序是否有獲得root權限的方法?

[英]Is there a way for a Java app to gain root permissions?

當運行Files.walk(Paths.get("/var/")).count()作為非特權用戶時,執行可能會拋出異常,因為/var/中的文件夾需要遍歷root權限。

不是在尋找一種以root身份執行bash命令的方法(例如sudo find /var ),使用Process等。

我只想確保Files.walk(Paths.get("/var/")).count()不會拋出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

這只是一個例子。 使用filter(...)可以解決異常問題。 但是這個例子也可以擴展到其他用例。

所以簡而言之這是否可能,CLI,JavaFX等應用程序在通過java -jar app.jar等方法從命令行執行后獲得root權限?

如果你想要的實際上是跳過你無法訪問的路徑,你有兩種方法:

在這個問題的答案中,解釋了如何獲取可以訪問的子樹的所有文件的流。

但是這個例子也可以擴展到其他用例。

FileVisitor的

使用FileVisitor會添加大量代碼,但在處理目錄樹時可以提供更大的靈活性。 要解決同樣的問題,您可以將Files.walk()替換為:

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

擴展SimpleFileVisitor(計算文件)並覆蓋一些方法。

您可以:

  1. 覆蓋visitFileFailed方法,處理由於某些原因無法訪問文件的情況; (Lukasz_Plawny的建議)
  2. (可選)覆蓋preVisitDirectory方法,在訪問目錄之前檢查權限:如果無法訪問它,則可以簡單地跳過其子樹(請記住,您可以訪問目錄,但不能訪問其所有文件) ;

例如1

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

例如2

@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {

    if(!Files.isReadable(dir))
        return FileVisitResult.SKIP_SUBTREE;

    return FileVisitResult.CONTINUE;

}

FileVisitor文檔

FileVisitor教程

希望能幫助到你。

只是一些完全沒有經過考驗的想法:

1)使用root權限運行您的應用程序以開始:

sudo java -jar myapp.jar

2)讓你的應用啟動一個請求root權限的啟動器類,然后繼續運行你的應用程序的其余部分:

java -jar myapp.jar

這反過來執行一個shell命令,但只有一個提示root密碼的xterm,然后繼續運行具有root權限的java程序:

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

或者使用gksudo使用更好看的東西。 記住'"

也許myapp.jar自己提取到一個臨時目錄中 myapp.jar包含myrootapp.jar ,因此它可以如上所述啟動它。 /tmp當然應該從java中檢索,並且最好是具有隨機名稱的目錄,只有運行myapp.jar的用戶才能訪問以防止myrootapp.jar注入。

跨平台

你提到/var/你自己,所以我以為你是在某種Linux上。 如果這應該跨平台工作,例如在Macintosh或Microsoft Windows上,則需要先進行某種系統識別。 然后,您可以在代碼中應用StrategyPattern來處理讓myrootapp.jar獲取root權限或管理員權限的各種方法。

沒有簡單的方法來更改權限。 Java並不擅長這些任務。 在啟動時只有一些技巧,如檢查權限,並嘗試通過su / sudo更改權限,然后重新啟動應用程序或使用Java-gnome。 請在這里閱讀更多內容: Java:在Ubuntu上詢問root權限

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM