C mit Konfigdatei

Hallo,

ich hatte letztens schon mal eine Frage in der Richtung gestellt…

Ich habe dieses Mini-C-Programm, dem ich aus einer Datenbank heraus einen bliebigen String übergeben und das Prog mach nichts weiter, als diesen String als Programm auf dem OS auszuführen.

Nun ist das ja ziemich unsicher, also würde ich gerne eine Konfig-Datei dazu packen, in der die ausführbaren Programme aufgelistet sind, damit nicht jeder alles darf.

Leider habe ich von C immer noch keine Ahnung.

In plsql würde ich in einer Schleife eine Tabelle auslesen und die Erebnisse mit dem übergebenen String vergleichen, so a la

if substr(string,1,5) = substr(konfig,1,5) then

wie mache ich das in C ?
Ich habe schon gelesen, das iostream wohl das Mittel der Wahl ist, aber da ich kein Beispiel gefunden habe, wo jemand eine Datei zeilenweise damit ausliest, kann ich mir das nicht zusammenfriemeln.

Kann mir einer hierzu ein kleines kompaktes und vollstäniges Beispiel zeigen ?

Es geht zwar auch schon so, aber schöner wäre es schon, wenn man nur ausgewählte Programme damit starten kann.

Danke und Grüße

Chris

Leider habe ich von C immer noch keine Ahnung.

Das macht nichts. Denn Deine eigentliche Fragestellung hat mit der Programmiersprache recht wenig zu tun.
Wie man Programme, Prozesse, Threads … startet ist sehr vom Betriebssystem und den dort vorhandenen Shells abhängig.

Wahrscheinlich ist Dein gesamtes Problem sogar eher war für eine Shell-Script-Sprache als für ein C-Programm. (Natürlich gibt es für C sogar Standardbibliotheken, die für solche Zwecke gedacht sind.)

Ciao, Allesquatsch

Hi Allesquatsch,

mein Problem ist folgendes: ich kann entweder C oder Java nutzen, wenn ich aus einer Datenbank (Oracle) heraus, ein Programm starten will. Es gibt noch einen Weg, über den ich auch Shellscripte starten kann, die dann aber mit einem unterpriviligierten Benutzer laufen, was mich vor andere Probleme stellt.
Wäre ich in der Lage, direkt ein ksh-Script anzusprechen, dann würde ich hier keine Fragen stellen.

Es geht mir nur darum, dass ich in diese C-Prozedur eine Vorprüfung rein bekomme, ob der Befehl (command) ausgeführt werden darf.

int sh(char *command) {
int num;
num = system(command);
return num;
}

Da der command auch ein ksh-Scriptaufruf inc. Übergabeparameter sein kann, muss es entweder ein Vergleich eines Substrings, oder mit einer like Bedingung sein.

Ich habe noch ein bißchen weiter gesucht, die mittlerweile gefundenen Beispiele zusammen gebastelt und als ausführbares Programm kompiliert.
Leider funktioniert es nicht.

#include
#include
#include
#define MAX_ZEILE 300

int main(char *command) {

FILE *DateiPointer;
DateiPointer = fopen(„ShellKonfig.txt“,„r“);
int num = 0;
int check_bit =0;
char *chk_bt;
char puffer[MAX_ZEILE];

while(fgets(puffer, MAX_ZEILE -1, DateiPointer))
{
chk_bt = strstr(command, puffer);
if (NULL != chk_bt)
{
check_bit = 1;
}
}

fclose(DateiPointer);

if (check_bit == 1)
{
num = system(command);
return num;
}

return 0;
}

Kompilieren klappt, aber wenn ich es aufrufe kommt ein core-dump

bash-3.00$ testscript testscript.ksh
Segmentation Fault (core dumped)

In der ShellKonfig.txt steht nur eine Zeile:
testscript.ksh

Was ist der Fehler ?

Grüße

Chris

Hallo Chris !

Der Fehler steckt wohl schon hier:

int main(char *command)

Die Funktion main() ist in C so definiert:

int main(int argc, char \*\*argv, char \*\*envp)

‚argc‘ ist die Anzahl der übergebenen Parameter (mindestens 1 wegen argv[0], siehe unten)
‚argv‘ ist ein Array von Strings die diese Parameter enthalten, wobei argv[0] der Programmname selbst ist, argv[1] der 1. Parameter, argv[2] der 2., …
‚envp‘ ist ein Array von Strings die die Environmentparameter enthalten (hier irrelevant, kannst du also einfach weglassen)

Dein Befehl stünde dann bei deinem Beispiel in argv[1] nicht in ‚command‘, dein ‚command‘ ist in Wirklichkeit ‚argc‘, das löst weiter unten auch den Fehler aus.

Der Vergleich

chk_bt = strstr(command, puffer);

löst dann den Fehler aus:
strstr() erwartet als ersten Parameter einen Pointer auf eine Zeichenkette, du lieferst einen Integer der als Pointer auf Zeichenkette interpretiert sicher einen illegalen Wert liefert (vermutlich ‚2‘ wenn das Programm mit einem Parameter aufgerufen wurde) und den Absturz herbeiführt: Segmentation Fault weil die Speicherstelle mit der Adresse ‚2‘ sicher nicht diesem Programm gehört.

Mich wundert nur dass dein Compiler da keine Fehlermeldung wegen falschen Typs ausgespuckt hat.

mfg
Christof

P.S.:
strstr() scheint mir sehr gefährlich zur Überprüfung ob erlaubt:
wenn ein erlaubter Befehl z.B. ‚findelement‘ heisst wäre mit strstr() auch der Befehl ‚del‘ erlaubt (‚del‘ ist in ‚findelement‘ enthalten) !

P.P.S.:

if (NULL != chk_bt)
{
check_bit = 1;

Hier könntest du dann die while-Schleife (z. B. mit break) bereits verlassen, alle weiteren Überprüfungen bringen ja nichts mehr)

1 Like

Es gibt noch einen Weg, über den ich
auch Shellscripte starten kann, die dann aber mit einem
unterpriviligierten Benutzer laufen, was mich vor andere
Probleme stellt.

Aber Dein C-Programm muss doch auch mit diesen Privilegien starten. Und die system() Aufruf können deshalb keine anderen Rechte haben.

Es geht mir nur darum, dass ich in diese C-Prozedur eine
Vorprüfung rein bekomme, ob der Befehl (command) ausgeführt
werden darf.

Das lässt sich auf mannighaftige Weise realisieren. Beim Vergleichen solltest Du darauf achten, dass die Namen vollständig gefunden werden. Wenn Du es mit Stringsuche realisieren willst, würde ich die Suchbegriffe mit einem im Text nicht vorkommenden Trennzeichen eingrenzen.

test[0]= test[strlen(befehl)+1]´= ‚|‘
strcpy(&test[1],befehl);
strstr("|zulässig|erlaubt|möglich|freigegeben|",test);

Ciao, Allesquatsch

1 Like

Vielen Dank !
Hallo Christof und Allesquatsch,

vielen Dank für eure Hinweise !

Das mit dem Break bei der Überprüfung baue ich auf jeden Fall noch ein und das mit dem Sonderzeichen bei der Stringsuche muß ich schauen, ob und wie ich das verwenden kann.

@ Allesquatsch, Was die Rechte angeht.
Wenn ich das C-Programm direkt aufrufe (Wie das geht, steht hier im Link http://www.idevelopment.info/data/Oracle/DBA_tips/PL…)
dann starten die Programme mit dem Oracle-Betriebssystemuser.
Man kann auch Programme und in dem Fall auch Shell-Scripte über den Oracle Scheduler starten, dann laufen die aber mit dem User nobody.

Die Scripte, die ich letztendlich starte, brauchen jedoch ein paar Rechte auf der Maschine, also bleibt mir nur Variante 1. Und aus dem gleichen Grund muß ich dafür sorgen, dass nur explizit vorgegebene Programme aufgerufen werden können.

Danke und Grüße

Chris