JNI + setuid Вопрос - PullRequest
       11

JNI + setuid Вопрос

4 голосов
/ 13 мая 2011

У меня есть веб-приложение, которое запускается как пользователь www. Однако в какой-то момент ему нужно прочитать файл из файловой системы Linux от имени пользователей Алисы и Боба.

Один из способов сделать это - запустить оболочку (Runtime.exec ()) и вызвать исполняемый файл C setuid, чтобы изменить идентификатор пользователя и прочитать файл.

Есть ли способ добиться этого с помощью JNI (веб-приложение должно работать как www, а не как root)? Я пытался написать программу Java JNI, которая вызывает собственные методы в Linux (я сделал эти собственные методы принадлежащими root и установил биты setuid). Но если я не запускаю Java-программу от имени пользователя root, она не позволяет мне переключать идентификаторы пользователей. Есть что-то, чего мне не хватает? Есть ли способ добиться этого?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 16 мая 2011

Нет.Нет.setuid и setgid могут использоваться только в двух случаях (в обычном Linux):

  1. Процесс является корневым.
  2. Процесс был запущен из файла с setuid или setgid битов в его режимах.

В первом случае процесс может вызывать эти функции так или иначе, чтобы принять любую идентичность.В последнем случае процесс может переключаться только между uid / gid родителя и uid / gid файла, из которого он был запущен.

То есть, если setuid, он может принятьuid файла, если setgid, gid.

Поскольку вы находитесь в Java, exec-ed - это сама программа Java, и вы не хотите, чтобы , что было setuid или setgid, если только вы не хотите создать колоссальную защиту.

Вы можете написать программу на C или C ++, которая запускает JVM через интерфейс вызова JNI, и установить для этой программы setuid или setgid, а затем код JNI.вызываемый там может сделать соответствующие вызовы для переключения.

0 голосов
/ 28 июня 2017

Да, это возможно.Вы можете увидеть пример здесь:

https://github.com/kebernet/pretty/blob/master/src/main/java/com/reachcall/util/SetUID.java

Вот пример кода:

CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);

   public static int setuid(int uid) {
        if (Platform.isWindows()) {
            return OK;
        }

        return CLibrary.INSTANCE.setuid(uid);
    }

ответ bmargulies не является правильным (или не совсем правильным).Некорневой процесс в UNIX может установить uid или gid, если он имеет соответствующие возможности:

http://man7.org/linux/man-pages/man7/capabilities.7.html

CAP_SETUID

  • Выполнять произвольные манипуляцииUID процесса (setuid (2), setreuid (2), setresuid (2), setfsuid (2));

Так как с точки зрения операционной системы ваша программа работает как "java"процесс, эта возможность setguid должна быть включена для самого исполняемого файла java:

$ sudo setcap cap_setuid,cap_setgid+ep /usr/java/latest/bin/java

Также обратите внимание, что файловая система, в которой находится исполняемый файл java, не смонтирована с опцией " nosuid ".

Вернуться к исходному вопросу

веб-приложение должно работать как www, а не как root

Обычно это нехорошая идея, чтобы веб-сервис имел возможность setuid.Лучше добавить uid в скрипт оболочки, который запускает ваше веб-приложение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...