# root-Passwort übergeben



## hakoe (20. Jan 2010)

Hallo zusamen,

ich möchte an externe Prozesse das root-Passwort übergeben, da verschiedene Prozesse root-Rechte erfordern.
Der Passwortstring wurde zuvor in ein Byte-Array gewndelt

```
Process pr = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "sudo fdisk -l"});
		//Passwort zum Prozess schreiben 
    		OutputStream os=pr.getOutputStream();
    		os.write(PWbyteArray);
    		os.flush();
```
Der ErrorStream des Prozesses liefert:
sudo: no tty present and no askpass program specified

Was muß ich tun?


----------



## faetzminator (20. Jan 2010)

Du brauchst kein root Passwort für sudo. sudo ist dafür da, dass man nicht root sein muss, um mit den gewünschten Rechten gewisse Aktionen auszuführen. Die Benutzer, welche man für sudo verwenden will, kann man im Configfile erfassen. Ebenfalls kann man sagen, dass Benutzer xy nur den und den Befehl ausführen darf. Schlussendlich noch eine Funktionalität, welche du benötigst: man kann noch angeben, dass gewisse Users und/oder explizit erlaubte Befehle ohne Abfrage des Passwortes (dem Benutzerpasswort, nicht dem Passwort von root!) ausführen dürfen.
Sieh dir dazu das/die Manual(s) von sudo an.


----------



## hakoe (20. Jan 2010)

An sudo soll nicht geschraubt werden.


----------



## faetzminator (20. Jan 2010)

Dann kann ich dir nicht helfen. Nebst dem nötigen Wissen (kann man einfach per Stream das Passwort "einschieben"?) fehlt da von mir aus gesehen der Sinn. Genau für _das_ ist sudo konfigurierbar. :autsch:


----------



## hakoe (20. Jan 2010)

noch mal zur Richtigstellung:
Mit root-Passwort meine ich natürlich das Passwort des Benutzers, der laut sodo-Konfiguration
Programme mit rootrechten starten kann.
Das soll er aber nicht ohne Passwort dürfen und es soll auch nich am möglicherweise gesetztem requiretty-Flag geschraubt werden.

Ich möchte also keine Umwege und Hintertüren per Konfiguration, sondern
Passwort erfragen und an Prozess übergeben.

Danke


----------



## hakoe (20. Jan 2010)

ja faetzminator, man kann!
Wie oben gezeigt. Aber eben nicht für sudo. Dank requiretty.
Aus dem Grund kommt ja auch die gezeigte Fehlermeldung.
Es muss also der gestartete Prozess mit einem Terminal verbunden werden oder sowas in der Art.
Alle anderen Informationen kann man dem Prozess auf diese Weise übergeben, nur das er das Passwort für sudo ablehnt.


----------



## faetzminator (20. Jan 2010)

Ich kann dir leider immer noch nicht helfen, aber das klingt schon besser, ausser...


hakoe hat gesagt.:


> Ich möchte also keine Umwege und Hintertüren per Konfiguration, sondern
> Passwort erfragen und an Prozess übergeben.


Wenn du das Projekt privat machst und/oder keine Systemvorgaben hast, solltest du deine Einstellung schleunigst ändern. Configdateien sind dafür da, um angepasst zu werden (damit haben Win-Linux-Umsteiger immer Probleme  ). Ansonsten, ... wirklich Pech gehabt.

Edit: Hab gerade deinen zweiten Post gesehen. Mit was für einem User läuft dein Programm bzw. die JVM? Warum rufst du sudo nicht direkt sondern über sh auf?


----------



## hakoe (20. Jan 2010)

Hallo faetzminator,
warum sudo in einer Subshell? Gute Frage.
So wie Du meinst, mache ich es zur Zeit.
Terminal öffnen und <sudo java -jar anwendung.jar> eingeben.
Das funktioniert auch.
hat aber den nachteil, dass es 1. nicht über Scheduler funktioniert und 2. die gesamte Anwendung mit rootrechten läuft.
Äusserst unfein!


----------



## faetzminator (21. Jan 2010)

Ich meine damit, dass du anstatt [c]{"/bin/sh", "-c", "sudo fdisk -l"}[/c] einfach [c]{"sudo", "fdisk", "-l"}[/c] bzw. evtl. [c]/usr/bin/sudo[/c] o.ä. aufrufen kannst. Interessant wär auch, was das Programm ausgibt, wenn du mit dem normalen Benutzer [c]whoami[/c] und [c]sudo whoami[/c] ausführst.
Ich denke, dass du hier zwei Probleme hast. Abgesehen davon, dass du das Passwort irgendwie übergeben musst, hat dein Benutzer anscheinend für irgendwas keine Rechte. Was gibt dir [c]cat /etc/passwd/|grep <username>[/c] aus?


----------



## homer65 (21. Jan 2010)

Habe das mal nachgestellt.
Also bei mir funktioniert folgender Code:

```
package pack;
import java.io.*;
public class Main
{
	public static void main(String[] args) 
	{
		String[] cmd = new String[3];
		cmd[0] = "sudo";
		cmd[1] = "fdisk";
		cmd[2] = "-l";
		try
		{
			Process p = Runtime.getRuntime().exec(cmd);
			OutputStream os = p.getOutputStream();
			Writer writer = new OutputStreamWriter(os);
			writer.write("passwort"+ "\n");
			InputStream in = p.getInputStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(in));
			String satz = reader.readLine();
			while (satz != null)
			{
				System.out.println(satz);
				satz = reader.readLine();
			}
			int rc = p.waitFor();
		}
		catch (Exception e)
		{
			System.out.println(e.toString());
		}
	}
}
```


----------



## hakoe (21. Jan 2010)

Die gleiche Meldung:>  sudo: no tty present and no askpass program specified

Warum der Aufruf mit /bin/sh ?
Nicht alles, was man unter Linux von einem Terminal aus starten kann, ist ein standalone Programm.
Es gibt auch viele sogenannte eingebaute Funktionen.
Diese erfordern, das man eine Shell für den Prozess öffnet. Und bei standalone Programmen schadet es nichts.
Darum mache ich es immer so.
Mangelndes Linux know how ist hier die falsche Fährte.
Ich suche eine Möglichkeit, die unsichtbare Passwort-Anforderung von sudo mit dem Java-Script zu verbinden.
Ich habe auch schon eine direkte Übergabe des Passworts an System.in probiert. Fehlanzeige!
???


----------



## hakoe (21. Jan 2010)

Ja, homer65,

dann ist in deiner sudo-Konfiguration requiretty nicht gesetzt.
Unter Ubuntu scheint das aber standadmäßig gesetzt zu sein.
Daher liefert der Error-Stream des Prozesses ja die Meldung,daß ein tty erforderlich ist.
Nun kann man eben nicht verlangen, das ein User erst an seiner sudo-Konfiguration fummelt, damit ein Script für die Dauer eines externen Prozessen root-Rechte bekommt.
Die Frage nach der sauberen Lösung bleibt also.
Trotzdem Danke an Euch beide!


----------



## homer65 (21. Jan 2010)

hakoe hat gesagt.:


> Ja, homer65,
> dann ist in deiner sudo-Konfiguration requiretty nicht gesetzt.
> Unter Ubuntu scheint das aber standadmäßig gesetzt zu sein.


Hmh, wundert mich. Ich habe es auch unter Ubuntu 8.04 ausprobiert.


----------



## hakoe (21. Jan 2010)

Muß ich jetzt mal sehen. Erst mal ein 8.04 kurz aufsetzen.
Ich hab schon 9.10 wegen einiger Multimedia.Geschichten
Wenn nicht irgendwoher noch ein anderer Lichtstrahl kommt, melde ich mich später wieder.
Ich muß auch erst mal mit den Hundeviechern raus.


----------



## faetzminator (21. Jan 2010)

hakoe hat gesagt.:


> Nicht alles, was man unter Linux von einem Terminal aus starten kann, ist ein standalone Programm.
> Es gibt auch viele sogenannte eingebaute Funktionen.
> Diese erfordern, das man eine Shell für den Prozess öffnet. Und bei standalone Programmen schadet es nichts.


Danke für die Info, ich bin aber bestens informiert  Hauptsächlich Bash- und Shellscripts muss man über die jeweilige Shell starten, ebenso wenn man z.B. pipen will. Ich bin mir darüber im Klaren.
Ich habe es aber eben auch schon erlebt, dass gewisse Aufrufe über eine Shell oder Bash ein Bisschen anders reagieren als der Direktaufruf.



hakoe hat gesagt.:


> Ich suche eine Möglichkeit, die unsichtbare Passwort-Anforderung von sudo mit dem Java-Script zu verbinden.
> Ich habe auch schon eine direkte Übergabe des Passworts an System.in probiert. Fehlanzeige!
> ???


Java ist nicht Javascript, wir sprechen hier von Java. Da anscheinend homer65's Testprogramm funktioniert, musst du einfach an den Output Stream das Passwort senden.

Die Frage mit [c]/etc/passwd[/c] habe ich nicht grundlos gestellt. Ich denke, dass dein Benutzer evtl. [c]/bin/false[/c] oder [c]/usr/sbin/nologin[/c] verwendet. Aber da auch dies eine Anpassung einer Config wär...


----------



## hakoe (21. Jan 2010)

Hallo faetzminator,

muß das wirklich sein, das ich Dir jetzt auch noch beweisen soll, daß ich den Unterschied zwischen einem Java-Script und einem Javascript-Script kenne?
Die ursprüngliche Frage war:
Kann ein in der Programmiersprache Java geschriebenes Script einem Prozess das root-Passwort
übergenben, und wenn ja, wie.
Offensichtlich ist es für Dein Verständnis der Wunsch, ein Programm zu schreiben, daß vom User das root-Passwort erfragt und einen Prozess dann mit diesem Passwort starten, exorbitant  überzogen.

Wenn ich die Lösung gefunden habe, führe ich sie hier vor.
Bemüh Dich bitte nicht weiter mit nichtzielführenden Belehrungen. Schade um die Zeit.


----------



## faetzminator (21. Jan 2010)

Hi hakoe

Nicht gleich so genervt, ich wollte eigentlich wirklich helfen.
Aber da ich keine Möglichkeit sehe, dies in Java zu umgehen, kann ich dir nicht helfen. Man schaue sich da die Beschreibung des requiretty Flag an ( - und nein, das ist kein Vorwurf, dass du dies nicht bereits schon gelesen hättest):


> If set, sudo will only run when the user is logged in to a real tty. When this flag is set, sudo can only be run from a login session and not via other means such as cron(8) or cgi-bin scripts. This flag is off by default.





hakoe hat gesagt.:


> muß das wirklich sein, das ich Dir jetzt auch noch beweisen soll, daß ich den Unterschied zwischen einem Java-Script und einem Javascript-Script kenne?


Ups, da habe ich mich zwischen dem Gehirn und den Fingern verknotet. Natürlich meine ich, dass es IMHO keine Java Scripts gibt, da Java keine Scriptsprache ist. Bitte um Entschuldigung 



hakoe hat gesagt.:


> Wenn ich die Lösung gefunden habe, führe ich sie hier vor.


Natürlich würde ich mich über eine Lösung freuen, aber wie gesagt: Weder sehe ich eine Lösung des Problems noch denke ich, dass man dies in Java lösen muss - lediglich meine Meinung. Und schlussendlich wollte ich mit meinen Gegenvorschlägen ebenfalls nur helfen.

Gruss, faetzminator


----------



## hakoe (21. Jan 2010)

So, Tagesgeschäft erledigt. Ich bin noch mal da.
Homer65, Du bietest an:
[JAVA=1]
package pack;
import java.io.*;
public class Main
{
	public static void main(String[] args) 
	{
		String[] cmd = new String[3];
		cmd[0] = "sudo";
		cmd[1] = "fdisk";
		cmd[2] = "-l";
		try
		{
			Process p = Runtime.getRuntime().exec(cmd);
			OutputStream os = p.getOutputStream();
			Writer writer = new OutputStreamWriter(os);
			writer.write("passwort"+ "\n");
			InputStream in = p.getInputStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(in));
			String satz = reader.readLine();
			while (satz != null)
			{
				System.out.println(satz);
				satz = reader.readLine();
			}
			int rc = p.waitFor();
		}
		catch (Exception e)
		{
			System.out.println(e.toString());
		}
	}
}
[/Java]
und meinst, es läuft bei Dir.
Ich hab nun auch noch mal Ubuntu 8.04.1 instaliert.
Es läuft wie unter Ubuntu 9.10!
Wenn man Dein Script kompiliert und aus einer Konsole heraus startet,
erscheint in der Konsole die Frage nach dem Passwort.
Was soll daran funktionieren?
Das Passwort soll er doch schon ohne Eingabe durch die Zeile 16
writer.write("passwort"+ "\n");
erhalten.
Nun kann man  Class-Dateien nicht durch Doppelklick starten, um die Funktion ohne Konsole zu Testen.
Schreib einfach noch ein Schell-Script main.sh:

      #!/bin/sh
      java main

mach es ausführbar und starte es mit ./main.sh von einer Konsole.
Es erscheint wieder die Passwortabfrage. Also Scheisse!!
Starte main.sh per Doppelklick.
Nichts passiert. Ohne Konsole (Terminal) keine Passwortabfrage.
Die Passwort-Übergabe im Script  "writer.write("passwort"+ "\n");"
funktioniert nicht.
"fdisk -l" ohne root-Rechte liefert nun mal keine Ausgabe zurückt.
Was ist nun so schwer zu verstehen?


----------



## homer65 (22. Jan 2010)

Ich muß gestehen, das es bisher von Eclipse aus lief. Habe es nun als jar Datei exportiert und dann mit java -jar test.jar aufgerufen. Es wird wie du schon sagtest nach dem root Passwort gefragt. Ich verstehe noch nicht warum. Allerdings kommt dann die Ausgabe von fdisk -l.


----------



## homer65 (22. Jan 2010)

Habe weiter getestet. Die Passwortabfrage kam nicht immer sondern nur manchmal. Ich denke es fehlt:
writer.flush(); nach den writer.write...


----------



## homer65 (22. Jan 2010)

Zum Thema Ubuntu 8.04. Du hast es frisch installiert, während es bei uns schon seit über einem Jahr läuft und mit Updates versorgt wurde und wird. Da kann auch noch ein Unterschied liegen.


----------



## homer65 (22. Jan 2010)

Habe weiter getestet. Muß gestehen das die Lösung mit dem flush auch nicht perfekt ist. Jetzt kommt manchmal (allerdings nicht immer) java.io.IOException: Broken pipe
Hmh, grübel


----------



## hakoe (24. Jan 2010)

Ja, Ubuntu 8.04.1 frisch installier, aber sofort ca 340 Updates nachgezogen. Also aktueller Stand.
Das Die Passwort-Abfrage mal kommt und mal funktioniert es ach ohne, hat folgenden Grund:
Erster Aufruf von java -jar test.jar bringt die Passwortabfrage.
Alle weiteren Aufrufe für die Dauer von standardmäßig 15 Minuten wird für sudo in der selben Konsole kein Password mehr benötigt. Bei Aufrufen nach diesen 15 Min. muß man es dann mal wieder eintippen usw.
Wenn das direkte Schreiben in den Prozeß nicht funktioniert, kann man es auch weglassen und 
sudo java -jar test.jar ins Terminal schreiben.
Grundsätzlich könnte man ja damit leben.
Aber es stinkt mir maßlos. Das Schreiben zum Prozess wird von Java angeboten, aber es funktioniert nicht. Und es gibt weltweit! wohl kein einziges Beispiel, das man nachvollziehen könnte.
Es gibt millionen Schlaumeier, die aus einem Process lesen können. (Kann ich auch)
Nur das Schreiben zeigt niemand.
Ich denke aber, ich bleib noch 'ne Weile dran.
Also homer65, Dir auch noch Spaß beim Grübeln

hakoe


----------



## JohannisderKaeufer (25. Jan 2010)

Hab jetzt vielleicht nicht 100% alle Anforderungen wahrgenommen.

Aber ist gksudo, bzw. kdesudo keine Lösung?

gksudo liefert die Passwortabfrage von sudo als Popupdialog.


Oder wie möchtest du an das sudo Passwort kommen?


----------



## homer65 (25. Jan 2010)

So jetzt funktioniert es. Man muss bei sudo die Option -S verwenden.

```
package pack;
import java.io.*;
public class Main
{
	public static void main(String[] args) 
	{
		String[] cmd = new String[4];
		cmd[0] = "sudo";
		cmd[1] = "-S";
		cmd[2] = "fdisk";
		cmd[3] = "-l";
		try
		{
			Process p = Runtime.getRuntime().exec(cmd);
			OutputStream os = p.getOutputStream();
			Writer writer = new OutputStreamWriter(os);
			writer.write("passwort" + "\n");
			writer.close();
			InputStream in = p.getInputStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(in));
			String satz = reader.readLine();
			while (satz != null)
			{
				System.out.println(satz);
				satz = reader.readLine();
			}
			int rc = p.waitFor();
		}
		catch (Exception e)
		{
			System.out.println(e.toString());
		}
	}
}
```


----------



## faetzminator (25. Jan 2010)

Ach, das ist mir wirklich peinlich. War bereits im man, hab das aber irgendwie übersehen. Vollständigkeitshalber der man-Entry:


> The -S (stdin) option causes sudo to read the password from the standard input instead of the terminal device.


----------



## hakoe (25. Jan 2010)

Hallo JohannesderKäufer,
wäre schon schön.
Das Fenster poppt zwar auf, aber fdisk funktioniert nicht.
Das klappt nicht mal aus der Konsole heraus, da gksu/kdesu grafische Anwendungen mit root-Rechten ausstatten,
fdisk aber ein Konsolenprogramm ist. Schade !


----------



## hakoe (25. Jan 2010)

Hallo Freunde,

die Variante sudo -S ist die Lösung.
so, wie von Homer65 ausformuliert, klappt es perfekt.
Danke euch allen.

faetzminator möchte ich nach einigem Überlegen ausdrücklich um Entschuldigung bitten für meinen Frust. Es ist in Ordnung, Alternativen anzubieten und dran zu bleiben. Vielen Dank.

hakoe


----------



## faetzminator (25. Jan 2010)

hakoe hat gesagt.:


> faetzminator möchte ich nach einigem Überlegen ausdrücklich um Entschuldigung bitten für meinen Frust. Es ist in Ordnung, Alternativen anzubieten und dran zu bleiben.



Schon ok, kenn die Situation. Man ist im Stress, genervt, ... und die App sollte ASAP (also am Besten Vorgestern) funktionieren. Hauptsache nun funktioniert alles


----------

