ifup/ifdown aus C aufrufen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
S_O
Beiträge: 138
Registriert: 25.02.2005 12:38:44

ifup/ifdown aus C aufrufen

Beitrag von S_O » 09.07.2006 15:59:59

Hallo,
ich baste gerade ein kleines Programm, welches vom Benutzer ausgeführt werden kann, das WLAN an/ausschaltet.
Zuerst habe ich einfach ein script geschrieben, suid root gesetzt, aber es ging nicht. Dann habe gelesen, das es mit scripten suid nicht geht. Also hab ich es in C geschrieben:

Code: Alles auswählen

#include <stdlib.h>
#include <stdio.h>

#define WLANDEV "eth2"
#define ETHDEV "eth0"

int main(int argc, char* argv[])
{
	
	if(argc!=2) exit(EXIT_FAILURE);
	
	char *commands[4];
	asprintf(&commands[0], "ifdown %s",ETHDEV);
	asprintf(&commands[1], "ifup %s",ETHDEV);
	asprintf(&commands[2], "ifdown %s",WLANDEV);
	asprintf(&commands[3], "ifup %s",WLANDEV);

	if(strcmp(argv[1],"wlan")==0)
	{
		system(commands[0]);
		system(commands[3]);
		exit(EXIT_SUCCESS);
	}
	if(strcmp(argv[1],"eth")==0)
	{
		system(commands[2]);
		system(commands[1]);
		exit(EXIT_SUCCESS);
	}
	exit(EXIT_FAILURE);
}
Als root gehts wieder, als benutzer nicht. Dann habe ich gelesen, das system() suid ignoriert. Ich habe etwas rumgesucht und es dann so gemacht:

Code: Alles auswählen

		execlp("/sbin/ifdown","ifdown",ETHDEV,0);
		execlp("/sbin/ifup","ifup",WLANDEV,0);
Das merkwürdige: Der erste Befehl wird immer korrekt ausgeführt, der zweite nicht. Was mache ich falsch?

Viele Grüße,
S_O

aspettl
Beiträge: 318
Registriert: 15.02.2006 22:05:37
Lizenz eigener Beiträge: MIT Lizenz
Kontaktdaten:

Beitrag von aspettl » 09.07.2006 16:22:45

Manpage:
Die exec-Bibliotheksfunktionen ersetzen den aktuellen Programmcode im Speicher mit neuem Programmcode.
Alle exec-Befehle ersetzen den laufenden Prozess durch einen neuen. Du müsstest bei diesem Vorgehen also vorher jeweils ein fork machen, so dass nur ein Kindprozess ersetzt wird.

Gruß
Aaron

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Beitrag von cosmac » 09.07.2006 16:33:58

hi,

Eigentlich wurde für solche Aufgaben doch "super" bzw. "sudo"
erfunden -- geht das nicht?
Beware of programmers who carry screwdrivers.

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 09.07.2006 16:45:43

denke auch, daß hier sudo die bessere Wahl wäre
wenn du trotzdem bei dem C-Programm bleiben möchtest, dann kannst du vorher mit "seteuid" zum "root" wechseln und dann mittels "system" deine Kommandos als "root" ausführen

Code: Alles auswählen

seteuid(0);
system(commands[n1]);
system(commands[n2])
Bei der obigen fork-Lösung müßtest du die Prozesse auch synchronisieren, sprich den zweiten Kindprozeß erst starten, wenn der erste gestorben ist

Gruß
gms
Zuletzt geändert von gms am 09.07.2006 17:00:01, insgesamt 1-mal geändert.

S_O
Beiträge: 138
Registriert: 25.02.2005 12:38:44

Beitrag von S_O » 09.07.2006 16:57:14

Hallo,
ich möchte das ja machen ohne irgendein Passwort eintippen zu müssen.
Bei seteuid(0) muss man ja sicher auch ein Passwort eintippen, oder geht das nur wenn das Programm schon mit suid root gestartet wurde?

Ich habs jetzt mit fork gemacht, klappt wunderbar:

Code: Alles auswählen

#include <stdlib.h>
#include <unistd.h>

#define WLANDEV "eth2"
#define ETHDEV "eth0"

int main(int argc, char* argv[])
{
	if(argc!=2) exit(EXIT_FAILURE);
	pid_t pid;
	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);
	if(strcmp(argv[1],"wlan")==0)
	{
		pid = fork();
		if (pid==0) execlp("/sbin/ifdown","ifdown",ETHDEV,0);
		pid = fork();
		if (pid==0) execlp("/sbin/ifup","ifup",WLANDEV,0);
		exit(EXIT_SUCCESS);
	}
	if(strcmp(argv[1],"eth")==0)
	{
		pid = fork();
		if (pid==0) execlp("/sbin/ifdown","ifdown",WLANDEV,0);
		pid = fork();
		if (pid==0) execlp("/sbin/ifup","ifup",ETHDEV,0);
		exit(EXIT_SUCCESS);
	}
	exit(EXIT_FAILURE);
}
Vielen Dank,
S_O

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 09.07.2006 17:06:36

S_O hat geschrieben: Bei seteuid(0) muss man ja sicher auch ein Passwort eintippen, oder geht das nur wenn das Programm schon mit suid root gestartet wurde?
seteuid verlangt niemals nach einem Passwort
seteuid(0) funktioniert nur, wenn der Prozeß als root oder mit suid gestartet wurde.

Bei deiner jetzigen Lösung mit fork könnte es Probleme geben, wenn das ifdown einmal längere Zeit benötigt, dann wird das ifup eventuell zu früh gestartet


Gruß
gms

S_O
Beiträge: 138
Registriert: 25.02.2005 12:38:44

Beitrag von S_O » 09.07.2006 17:25:59

seteuid verlangt niemals nach einem Passwort
seteuid(0) funktioniert nur, wenn der Prozeß als root oder mit suid gestartet wurde.
Geht nicht.
Wenn ich es als Benutzer starte werde ich darüber informiert das es ifup/ifdown nicht gibt. Wie gesagt mit suid root gestartet.
Kann man denn ifup/ifdown nicht parallel aufrufen? Es sind ja zwei verschiedene Interfaces. Es ist ja egal in welcher reihenfolge ich es aufrufe.

Viele Grüße,
S_O

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 09.07.2006 17:50:35

das habe ich übersehen, wenn unterschiedliche Interfaces betroffen sind, kannst du diese natürlich auch parallel aufrufen.

seteuid sollte eigentlich funktionieren, ist eigentlich die Standardmethode


Gruß
gms

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 09.07.2006 17:55:19

S_O hat geschrieben: Wenn ich es als Benutzer starte werde ich darüber informiert das es ifup/ifdown nicht gibt.
Hast du hier auch den Pfad mit angegeben ? Also "/sbin/ifdown" und "/sbin/ifup" ?

Benutzeravatar
Savar
Beiträge: 7174
Registriert: 30.07.2004 09:28:58
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Berlin

Beitrag von Savar » 09.07.2006 17:56:52

was hat setuid(0) für einen Rückgabewert bei dir?
MODVOICE/MYVOICE
Debianforum Verhaltensregeln
Log Dateien? -> NoPaste

S_O
Beiträge: 138
Registriert: 25.02.2005 12:38:44

Beitrag von S_O » 09.07.2006 19:04:45

Hast du hier auch den Pfad mit angegeben ? Also "/sbin/ifdown" und "/sbin/ifup" ?
Ah, jetzt gehts.
was hat setuid(0) für einen Rückgabewert bei dir?
0. Wie erwartet.

Vielen Dank,
S_O

Antworten