Запуск команд UNIX от имени другого пользователя из Java

Попытка написать программу на Java, способную выполнять команду UNIX от имени другого пользователя UNIX. У меня есть пароль пользователя, и я знаю команду, которую хочу запустить, но команда должна быть запущена от имени этого пользователя, поэтому я должен сначала войти в систему как этот пользователь.

Например: скажем, у нас есть пользователь jim, который хочет посмотреть, что находится в домашнем каталоге bob, и (по какой-то причине) jim имеет доступ для выполнения ls, а bob — нет. В настоящее время мы вошли в систему как bob. Вот что мы (могли) сделать:

bob@host$ su jim && ls ~bob

Проблема в том, что нас просят ввести пароль Джима. Поскольку это запускается из программы Java, т.е.

Process p = Runtime.getRuntime().exec("su jim && ls ~bob");

нас просят ввести пароль Джима, и мы вешаем трубку. Мы знаем пароль Джима. Однако я не могу войти в него.

Кроме того, мы не можем использовать скрипт Expect (он не установлен) и не можем стать суперпользователем. Я также рассматривал возможность использования SSH, чтобы попробовать это, так как технически мы могли бы сделать

bob@host$ ssh jim@host "ls ~bob"

но это также не работает, так как у меня нет разрешения на настройку SSH без пароля.

Моя последняя попытка — попытаться использовать SSH-библиотеку для Java, поскольку пароль доступен для программы Java, и я смогу войти с ним (и выполнить соответствующую команду). Но поскольку я собираюсь работать на том же хосте, это кажется излишним.

Какие-либо предложения?

P.S: Java версии 1.4.2, обновить нельзя; AIX UNIX 5.3.


person Glen Balliet    schedule 18.06.2009    source источник
comment
Удалось ли вам найти обходной путь без использования сторонней библиотеки, если да, не могли бы вы поделиться?   -  person HyperioN    schedule 12.07.2017


Ответы (6)


Установите sudo, попросите пользователя, запускающего программу Java, ввести в /etc/sudoers соответствующие команды и использовать sudo -u jim ls ~bob.

person DevSolar    schedule 18.06.2009
comment
Это не решение. К сожалению, я никак не могу изменить систему, в том числе установить sudo. - person Glen Balliet; 18.06.2009
comment
Тогда вам нужно сменить хост. - person Andrew Austin; 18.06.2009
comment
Согласен с Андреем. Если ваш хост не разрешает вам такие вещи, как pubkey SSH, и вы даже не можете установить sudo, то, скорее всего, все, что вы можете придумать относительно вашей схемы su, возможно, не разрешено вашим хостером, и вы обречены на неприятности. Найдите хостера, разрешающего sudo, это единственное разумное решение. - person DevSolar; 18.06.2009
comment
Только что понял, что никогда не обращался к этим комментариям. Это был вопрос, связанный с работой, и у компании, в которой я работал в то время, было достаточно бюрократии, так что вокруг их серверов получение доступа sudo любым способом было бы невозможно. - person Glen Balliet; 25.09.2012
comment
@GlenHunt: я знаю тип. Бюрократия, написанная людьми, которые ничего не знают о задействованных технологиях, и объявляют вне закона все, чего они не понимают, вынуждая тех, кто знает свое дело, использовать второсортные обходные пути вместо того, чтобы делать все правильно (и безопасно)... соболезную. - person DevSolar; 25.09.2012

Проблема решена. Использовал JSch (http://www.jcraft.com/jsch/) для SSH на сервер с известное имя пользователя и пароль и выполнить команду. Спасибо всем за ваши предложения!

person Glen Balliet    schedule 18.06.2009
comment
пожалуйста, добавьте пример здесь. - person Rajeev; 16.12.2016

Возможно, Java-реализация Expect? ExpectJ появляется при поиске в Google, но я не смог найти никакой документации, касающейся работы под 1.4.2.

person lucas    schedule 18.06.2009
comment
Это может быть решением. Спасибо за совет. - person Glen Balliet; 18.06.2009
comment
Что ж, ExpectJ выглядит так, как будто он должен работать — удалось скопировать и построить зависимости. Однако проблема в том, что ExpectJ использует StringBuilder, который не был реализован до версии 1.5. Какие-либо предложения? - person Glen Balliet; 18.06.2009
comment
Вы можете спросить людей из ExpectJ, есть ли у них старая версия (на sourceforge ее нет). Если единственной проблемой является StringBuilder, вы сможете изменить код самостоятельно. - person Kathy Van Stone; 18.06.2009

Вы пытались перенаправить ввод команд sudo и записать их. Я давно не использовал Java, но я считаю, что есть способ получить входной поток и записать в него. Вы можете использовать это, чтобы написать пароль, за которым следует новая строка, и sudo или su должны принять пароль.

Используйте getInputStream() и запишите туда свой пароль.

su jim -c ls ~Bob
person Stephan    schedule 18.06.2009

Возможно, это сработает:

Process process = Runtime.getRuntime().exec("su jim && ls ~bob");

OutputStream standardInput = process.getOutputStream();
Writer standardInputWriter = new OutputStreamWriter(standardInput);
standardInputWriter.write("password\n");
standardInputWriter.close();
person Adam Paynter    schedule 18.06.2009
comment
Спасибо, но это не сработало. Я пробовал что-то подобное раньше, но с примерно таким же результатом. - person Glen Balliet; 18.06.2009

Я не уверен, что этот код:

Process p = Runtime.getRuntime().exec("su jim && ls ~bob");

будет выполняться в оболочке, необходимой для оценки &&, то есть команды оболочки (/bin/sh). Вы должны передать команду "ls ~bob" через командную строку swith su. Что-то вроде:

su jim -c 'ls ~bob'
person dfa    schedule 18.06.2009
comment
тогда SSH имхо - единственный жизнеспособный вариант - person dfa; 18.06.2009