Scriptaufruf mit root Rechten.



  • Hallo Leute....
    ich suche eine Möglichkeit ein Dienst neuzustarten und das soll auch ein anderer Benutzer können. (Unter Linux).
    Sicherheitstechnisch sehe ich die Möglichkeit mit einem kleinen C/C++ Programm immer noch am liebsten. Dort werden die Befehle fest einprogrammiert.

    Leider habe ich keine Ahnung wie das aber aussehen soll.
    Normaleweise würde so ähnlich aussehen:
    /etc/rc.d/rc.red stop
    /etc/rc.d/rc.red start

    wie packe ich das nun in ein funktionierendes Binär-Programm?



  • Schau Dir einfach an, wie die anderen Startskripte aufgebaut sind. Und dann erstellst Du einen entsprechenden Eintrag in /etc/sudoers.



  • Auf mein Rechner ist kein sudo drauf. Ich dachte mir schon das so ein Vorschlag kommt. Aber ich habe wiederum gedacht, das ich gesagt habe .. das ich eine Binärdatei haben möchte 😉
    Das hat schon seine Gründe.

    rufe ich mit
    system("pwd");
    beipw. ein Befehl auf?
    kann ich die Ausgabe gleich in ein string packen?
    #include <string>
    using namespace std;

    int main()
    {
    string aktueller_pfad = system("pwd");
    return 0;
    }

    Ist das ungefähr so richtig? Brauche ich nicht noch eine Bibo um auf das System zuzugreifen zu können?



  • Evolu schrieb:

    Auf mein Rechner ist kein sudo drauf. Ich dachte mir schon das so ein Vorschlag kommt. Aber ich habe wiederum gedacht, das ich gesagt habe .. das ich eine Binärdatei haben möchte 😉
    Das hat schon seine Gründe.

    Die da wären? Kann mir irgendwie für Dein Beispiel gerade kein vernünftiges Anwendungsszenario vorstellen.

    kann ich die Ausgabe gleich in ein string packen?

    Nein, Du suchst popen oä.



  • Muss du den die Ausgabe weiterverarbeiten?
    Sonst kannst du auch http://www.pronix.de/pronix-157.html verwenden und ein chmod +s machen.

    Be carefull
    strcpy(char [50],stdin);
    wäre nicht so toll wenn das Programm suid hat...



  • Hallo nochmal ...

    nein so richtig weiterverarbeiten muss ich das nicht. Die Seite hab ich aber auch schon gefunden. Die ist gut ...
    Das Stichwort popen() hat schon geholfen.
    Danke.



  • Nach langer Arbeit habe ich mein Programm soweit ... das ich sagen kann das es fertig ist. Nun habe ich aber nur noch mit den Rechten Probleme.

    Also ich benutze nun popen() um z.b. einen Dienst zu beenden:
    /etc/init.d/dhcpd stop

    Kompiliere und setzt die Rechte dementsprechend:
    -rws---r-x 1 root root

    Das Sticky-Bit ist dafür verantwortlich das ich das mit root-rechten ausführe. Wie wir wissen funktioniert Sticky-Bit nur mit Binärdateien (um es mit Userrechten auszuführen). Das macht die Fehlermeldung um so komischer:
    sh: line 1: /etc/init.d/dhcpd: Permission denied

    Das "sh" bedeutet das es in eine Shell gestartet wird und hierfür hat er keine Rechte oder ähnliches....
    Hat jemand einen Plan?



  • Evolu schrieb:

    Kompiliere und setzt die Rechte dementsprechend:
    -rws---r-x 1 root root

    Das Sticky-Bit ist dafür verantwortlich das ich das mit root-rechten ausführe. Wie wir wissen funktioniert Sticky-Bit nur mit Binärdateien (um es mit Userrechten auszuführen). Das macht die Fehlermeldung um so komischer:
    sh: line 1: /etc/init.d/dhcpd: Permission denied

    Das Sticky-Bit ist ja nur für Root gesetzt. Also hat auch nur root das Recht, die Datei als root auszuführen.

    Aber das Sticky-Bit funktioniert auch für Shell-Skripte. Deine Aussage ist diesbezüglich einfach falsch. Die Datei muss nur ausführbar sein. Aber Shell-Skripte mit root-Rechten sind sehr gefährlich.

    Aber warum installierst du nicht einfach sudo und benutzt es? Das Programm scheint genau für dein Problem gemacht zu sein.



  • Dein Grundwissen ist hier diesbezüglich Falsch. Mehr Infos bei Wiki:
    http://de.wikipedia.org/wiki/Setuid



  • Evolu schrieb:

    Dein Grundwissen ist hier diesbezüglich Falsch. Mehr Infos bei Wiki:
    http://de.wikipedia.org/wiki/Setuid

    Okay... es war zugegebener Weise Blödsinn, was ich geschrieben habe. Ich war mir so sicher... 😃

    Um das zu erklären. Ich hab mal von einem Bug in MacOS gelesen, welcher darauf beruhte, das Setuid-Rechte auf einer Shell-Datei angelegt waren. Darum bin ich davon ausgegangen, dass das wohl allgemein funktionieren müsste.

    Was ich aber immer noch nicht verstehe, warum du nicht das sudo-Programm verwenden willst.

    Die Frage ist, ob dein Programm ebenfalls nicht funktioniert, wenn du es als root startest. Wenn ja, dann ist es kein Problem mit Setuid, sondern es liegt wo anders. Und dann müsstest du mal Quelltext zeigen.



  • Hallo ..
    "Verdammt! Ich war mir so sicher ..." ist wirklich gut 😃

    Also ich habe kein sudo auf diesen Rechner. Hatte ich schon im Zweiten Beitrag von mir gesagt 😉 Auf dem Rechner habe ich auch kein einziges Paketverwaltungssytem (wie dpkg) installiert. Aber um ehrlich zu sein, werde ich mich jetzt mal doch darum bemühen müssen sudo zu "installieren". Das muss natürlich mit dem zweiten Admin besprochen werden ...
    Also wenn ihr noch eine Idee mit dem SUID (SUID ist die richtige Bezeichnung.. und nicht Sticky-Bit .. aber im Allgemeinen wird dazu auch Sticky-Bit gesagt) ... also wenn ihr noch eine Idee habt, dann sagt einfach Bescheid. Denn eigentlich müsste es so funktionieren.

    Mit root auszuführen funktioniert auch.
    Danke ... guten Rutsch.



  • Und ich denke, wenn du in dein Programm ein

    system("whoami");
    

    einbaust, dann gibt er dir auch root als Benutzer aus. Teste das trotzdem mal.

    Was du noch testen könntest:

    Melde dich als normaler Nutzer an und wechsele mit

    $ su
    

    zum Nutzer root. Und dann teste das mal mit

    $ su -
    

    .
    Was ich vermute. Wenn du dich als root anmeldest, dann werden andere Umgebungsvariablen und Pfade gesetzt, als wenn du einfach nur als normaler Nutzer angemeldet bist und ein Programm mit root-Rechten startest. Kann es sein, dass das Startskript z.B. auf ein Programm in /sbin zugreift, aber das beim normalen Nutzer nicht in der Path Variable drin ist?

    Btw. das ist der Grund, warum SUID Programme so gefährlich sind und immer absolute Pfadangaben enthalten müssen. Und am besten auch niemals Skripte starten sollten, die keine absoluten Pfadangaben enthalten. Der Nutzer hat ne Menge Möglichkeiten mit den Pfadvariablen etc. zu manipulieren.



  • Mit system("whoami"); oder popen("whoami", "w"); bekomme ich root raus.
    Diese Option hatte ich die ganze Zeit als Testausgabe mit dabei. Also bin ich mir auch sicher, das ich das immer als root ausgeführt habe. Unabhängig davon das ich das auch direkt mit root ausgeführt habe.

    Zu aller erst die Antworten:
    Ich benutze feste absolute Pfade.
    Ich greife noch nicht auf sbin zu.

    Und dann teste das mal mit su -

    Meinst du ich soll erst "su -" und dann das Programm ausführen. Damit die Shell zur Loginshell wird ... und ich so andere Umgebungsvariablen habe .. oder ähnlich.
    So habe ich das unter anderem auch auch gemacht .. aber leider funktioniert das nicht.

    Ich habe jetzt unter Knoppix was getestet.
    /etc/init.d/dhcp3-server stop
    im Programm kompeliert und mit SUID ausgeführt.
    Zwar gab es ein Fehler mit syslog aber im Prinzip hatte ich die Berechtigung das auszuführen.
    Auf meinen Rechner greife ich auf /etc/rc.d/
    und dort kommt ein Berechtigungsfehler. Alles sehr eigenartig.



  • Evolu schrieb:

    Zu aller erst die Antworten:
    Ich benutze feste absolute Pfade.
    Ich greife noch nicht auf sbin zu.

    Aber vielleicht das Skript, was du aufrufst nicht!

    Evolu schrieb:

    Und dann teste das mal mit su -

    Meinst du ich soll erst "su -" und dann das Programm ausführen. Damit die Shell zur Loginshell wird ... und ich so andere Umgebungsvariablen habe .. oder ähnlich.
    So habe ich das unter anderem auch auch gemacht .. aber leider funktioniert das nicht.

    D.h. wenn du den Nutzer wechselst und dich nicht direkt als root anmeldest, dann Funktioniert dein Programm schon nicht?



  • Ich habe zu Testzwecken nur noch ein zwei Zeilen.
    Das heißt ich rufe da kein Script auf.

    Ja wenn ich das als angemeldeten root ausführe dann funktioniert das. Aber nicht als anderer Benutzer. Obwohl er laut whoami als root unterwegs ist.



  • Wenn es nur noch ein, zwei Zeilen sind. Dann zeig doch mal den Quelltext.



  • Zu Testzwecken hab ich den ja gekürzt:

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      popen("whoami", "w");
      popen("/etc/init.d/dhcp3-server start"); //oder stop
      return 0;
    }
    


  • upps hab mich vertippt:
    popen("/etc/init.d/dhcp3-server start", "w"); //oder stop

    oder man verwendet gleich system() aber das hab ich z.Z. nicht.



  • Evolu schrieb:

    popen("/etc/init.d/dhcp3-server start");
    

    Ich rede von dem Skript /etc/init.d/dhcp3-server . Was steht da drin? Kann es sein, dass da entsprechende Aufrufe drin sind, die Probleme machen?

    Ich habe gerade noch ein paar Tests gemacht. Offensichtlich machen Programme, wie su noch weitere Dinge, um den Nutzer zu wechseln. Z.b. ein Terminal für ihn anlegen. Ich habe es mit der Folgenden Zeile probiert:

    system("su -c \"/etc/init.d/dhcp3-server restart\"");
    

    . Und trotz SUID wurde ich nach einem Passwort gefragt.



  • Ja das mit su -c habe ich auch schon getestet. Leider funktioniert das nicht so wie es soll.

    Achso du wolltest wissen was in der dhcp3-server steht:

    #!/bin/sh
    #
    # $Id: dhcp3-server.init.d,v 1.4 2003/07/13 19:12:41 mdz Exp $
    #
    
    ### BEGIN INIT INFO
    # Provides:          dhcp3-server
    # Required-Start:    $network
    # Required-Stop:     $network
    # Should-Start:      $local_fs
    # Should-Stop:       $local_fs
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Short-Description: DHCP server
    # Description:       Dynamic Host Configuration Protocol Server
    ### END INIT INFO
    
    PATH=/sbin:/bin:/usr/sbin:/usr/bin
    
    test -f /usr/sbin/dhcpd3 || exit 0
    
    # It is not safe to start if we don't have a default configuration...
    if [ ! -f /etc/default/dhcp3-server ]; then
    	echo "/etc/default/dhcp3-server does not exist! - Aborting..."
    	echo "Run 'dpkg-reconfigure dhcp3-server' to fix the problem."
    	exit 0
    fi
    
    # Read init script configuration (so far only interfaces the daemon
    # should listen on.)
    . /etc/default/dhcp3-server
    
    NAME=dhcpd3
    DESC="DHCP server"
    DHCPDPID=/var/run/dhcpd.pid
    
    test_config()
    {
    	if ! /usr/sbin/dhcpd3 -t > /dev/null 2>&1; then
    		echo "dhcpd self-test failed. Please fix the config file."
    		echo "The error was: "
    		/usr/sbin/dhcpd3 -t
    		exit 1
    	fi
    }
    
    # single arg is -v for messages, -q for none
    check_status()
    {
        if [ ! -r "$DHCPDPID" ]; then
    	test "$1" != -v || echo "$NAME is not running."
    	return 3
        fi
        if read pid < "$DHCPDPID" && ps -p "$pid" > /dev/null 2>&1; then
    	test "$1" != -v || echo "$NAME is running."
    	return 0
        else
    	test "$1" != -v || echo "$NAME is not running but $DHCPDPID exists."
    	return 1
        fi
    }
    
    case "$1" in
    	start)
    		test_config
    		echo -n "Starting $DESC: "
    		start-stop-daemon --start --quiet --pidfile $DHCPDPID \
    			--exec /usr/sbin/dhcpd3 -- -q $INTERFACES
    		sleep 2
    
    		if check_status -q; then
    			echo "$NAME."
    		else
    			echo "$NAME failed to start - check syslog for diagnostics."
    			exit 1
    		fi
    		;;
    	stop)
    		echo -n "Stopping $DESC: $NAME"
    		start-stop-daemon --stop --quiet --pidfile $DHCPDPID
    		rm -f "$DHCPDPID"
    		echo "."
    		;;
    	restart | force-reload)
    		test_config
    		$0 stop
    		sleep 2
    		$0 start
    		if [ "$?" != "0" ]; then
    			exit 1
    		fi
    		;;
    	status)
    		echo -n "Status of $DESC: "
    		check_status -v
    		exit "$?"
    		;;
    	*)
    		echo "Usage: $0 {start|stop|restart|force-reload|status}"
    		exit 1 
    esac
    
    exit 0
    

    Aber das ist ja momentan ja nur ein dienst ... wir können uns nicht alle Dienste anschauen. Aber vielleicht fällt dir was generelles auf.

    PS: Ich habe jetzt mal Parallel sudo herüberkopiert. Und der verlangt auch eine Passwortabfrage nicht von root sondern vom User selber. Ich muss ehrlich sagen, dass es jetzt viele unbenutzte Dateien rumliegen aber das mach ich später ...
    Wenn man sudo richtig einstellt, umgehe ich mein Problem einfach ... aber das funktioniert auch nicht so richtig.



  • Evolu schrieb:

    Ja das mit su -c habe ich auch schon getestet. Leider funktioniert das nicht so wie es soll.
    [...]

    Aber das ist ja momentan ja nur ein dienst ... wir können uns nicht alle Dienste anschauen. Aber vielleicht fällt dir was generelles auf.

    Mir fällt jetzt spontan nichts auf. Die Pfad-Variable wird in dem Skript ja nochmals gesetzt.

    Was mir halt aufgefallen ist, ist der unterschied zwischen su und SUID-Rechten. Da scheint noch was zu tun zu sein. Du kannst dir die Quellen von su anschauen und gucken, wie es funktioniert. Damit sollte dein Problem gelöst sein.

    Evolu schrieb:

    PS: Ich habe jetzt mal Parallel sudo herüberkopiert. Und der verlangt auch eine Passwortabfrage nicht von root sondern vom User selber. Ich muss ehrlich sagen, dass es jetzt viele unbenutzte Dateien rumliegen aber das mach ich später ...
    Wenn man sudo richtig einstellt, umgehe ich mein Problem einfach ... aber das funktioniert auch nicht so richtig.

    sudo fragt nach dem Passwort, wenn du in sudo eingestellt hast, dass es fragen soll. Das kannst du auch ausschalten.


Anmelden zum Antworten