[C++] Problemen met argv

Pagina: 1
Acties:

  • Slagroom
  • Registratie: Juni 2001
  • Laatst online: 23-08 10:29
Hallo,

Ik ben bezig met een programmatje die ik wil aanroepen met een php script. Het wil alleen niet zo lukken. Dit is het eerste echte C++ programmatje dat ik schrijf.

Wanneer ik dit programma aanroep met
$ ./a.out 1 /hallo
zegt hij gewoon "Dit argument wordt niet herkent" Wanneer ik de " vervang met ' geeft hij compile errors ook als ik de ' helemaal weglaat bij de if statements. Wie weet wat ik fout doe? Ik heb al gekeken op tldp.org, google en GoT

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
        char commando[256];
        setuid(0);
        setgid(0);

        if (argc < 2) {
                printf("U moet wel argumenten meegeven\n");
                return 0;
        } else {
                if (argv[1] == "1") {
                        sprintf(commando, "mkdir %s", argv[2]);
                        system(commando);
                } else if (argv[1] == "2") {
                        sprintf(commando, "rmdir %s", argv[2]);
                        system(commando);
                } else if (argv[1] == "3") {
                        sprintf(commando, "ln -s %s %s", argv[2], argv[3]);
                        system(commando);
                } else {
                        printf("Dit argument wordt niet herkent\n");
                }
        }
        exit(0);
}

  • Nielsz
  • Registratie: Maart 2001
  • Niet online
doe eens een switch case structuur?

  • Slagroom
  • Registratie: Juni 2001
  • Laatst online: 23-08 10:29
Ik heb nu dit:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
        char commando[256];
        setuid(0);
        setgid(0);

        if (argc < 2) {
                printf("U moet wel argumenten meegeven\n");
                return 0;
        } else {
                switch(argv[1]) {
                        case "1":
                                sprintf(commando, "mkdir %s", argv[2]);
                                system(commando);
                                break;
                        case "2":
                                sprintf(commando, "rmdir %s", argv[2]);
                                system(commando);
                                break;
                        case "3":
                                sprintf(commando, "ln -s %s %s", argv[2], argv[3]);
                                system(commando);
                                break;
                        default:
                                printf("Dit argument wordt niet herkent\n");
                }
        }
        exit(0);
}


maar nu geeft hij deze error:

code:
1
2
3
4
5
suexec.c: In function `main':
suexec.c:14: switch quantity not an integer
suexec.c:15: case label does not reduce to an integer constant
suexec.c:19: case label does not reduce to an integer constant
suexec.c:23: case label does not reduce to an integer constant


waar ken dat aan liggen? Ook hier heb ik het al geprobeerd zonder " en '

PS: Het wordt gecompiled op MacOS X

[ Voor 7% gewijzigd door Slagroom op 07-01-2003 23:56 ]


  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 10-07 04:13

PommeFritz

...geen friet

Je kunt in C/C++ strings niet vergelijken met "==".
Je moet str(i)cmp gebruiken:
C++:
1
if (0==strcmp(argv[1], "1") {..... }

FireFox - neem het web in eigen hand


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:13

.oisyn

Moderator Devschuur®

Demotivational Speaker

C-style strings zijn gewoon arrays van chars, en je kunt arrays (of eigenlijk pointers naar het eerste element ervan) niet vergelijken met ==

ja kan wel, maar dan wordt alleen gecontroleerd of het adres waar ze naar wijzen gelijk is aan elkaar, niet wat je nodig hebt dus

Aangezien je met C++ werkt is het misschien handig om eerst alle parameters in een std::vector te zetten? std::string objecten kun je namelijk wel met de == vergelijken

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <vector>
#include <string>

int main (int argc, char ** argv)
{
    std::vector<std::string> arguments (argv, argv + argc);

    if (arguments.size () < 2)
    {
        // dat stukje over een fout aantal argumenten
    }

    if (arguments[1] == "1")
        // en zo verder


    return 0;
}

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

PommeFritz schreef op 07 January 2003 @ 23:58:
Je kunt in C/C++ strings niet vergelijken met "==".
Je moet str(i)cmp gebruiken:
C++:
1
if (0==strcmp(argv[1], "1") {..... }
...of als je een karakter wilt vergelijken enkele quotes:
C++:
1
if (*argv[1] == '1' )

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:13

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 08 januari 2003 @ 00:25:
[...]

...of als je een karakter wilt vergelijken enkele quotes:
C++:
1
if (*argv[1] == '1' )


ja maar dan werkt het ook als je je programma zo opstart:
code:
1
app 1blaat


lijkt me niet helemaal de bedoeling :)
btw check je mail :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 10-07 04:13

PommeFritz

...geen friet

... let dan wel extra op het sterretje ervoor, en als je als argument 1blaatblaat opgeeft dan matcht 'ie ook. Da's meestal niet wat je wilt.

FireFox - neem het web in eigen hand


Verwijderd

Slagroom schreef op 07 January 2003 @ 23:28:
Hallo,

Ik ben bezig met een programmatje die ik wil aanroepen met een php script.
--8<--
C++:
7
8
        setuid(0);
        setgid(0);
Ehm, lijkt je dat wel helemaal veilig zo? Heb je wel root/root acces nodig, en zelfs al heb je dat nodig, dan mag je volgens mij deze setuid/setgid alleen uitvoeren als je al root/root bent...

Tenzij je het programma (de binary) zelf al setuid't/setgid't met "chmod ug+s <filename>" en chown/chgrp, wat de setuid()/setgid() aanroep overbodig maakt, maar dat zou ik ook sterk afraden, tenzij je een fatsoenlijke user-account maakt voor het programma, en deze toevoegd aan enkel de hoognodige groups... (Dus niet uid=0, gid=0)

[ Voor 5% gewijzigd door Verwijderd op 08-01-2003 01:13 ]


Verwijderd

.oisyn schreef op 08 januari 2003 @ 00:38:
lijkt me niet helemaal de bedoeling :)
Wel als je enkel een karakter wilt vergelijken en je daarna verder gaat ;)
En wat je hoe dan ook ook als resultaat krijgt in de code van de TS, d.m.v. een equate (*args[1] == "1" vergelijkt ook alleen het eerste karakter van beide c-strings.)

In context
C++:
1
2
3
4
5
if (*argv[1] == '-')
{
  if (!strcmp(argv[1], "-h"))
    printUsage();
  else if ...

Maar je hebt gelijk...
BTW: chk nu jouw mail


(PommeFritz: dat sterretje is volgens mij juist zo belangrijk voor een goede werking...)

[ Voor 58% gewijzigd door Verwijderd op 08-01-2003 01:12 ]


  • Slagroom
  • Registratie: Juni 2001
  • Laatst online: 23-08 10:29
Verwijderd schreef op 08 January 2003 @ 00:47:
[...]


Ehm, lijkt je dat wel helemaal veilig zo? Heb je wel root/root acces nodig, en zelfs al heb je dat nodig, dan mag je volgens mij deze setuid/setgid alleen uitvoeren als je al root/root bent...

Tenzij je het programma (de binary) zelf al setuid't/setgid't met "chmod ug+s <filename>" en chown/chgrp, wat de setuid()/setgid() aanroep overbodig maakt, maar dat zou ik ook sterk afraden, tenzij je een fatsoenlijke user-account maakt voor het programma, en deze toevoegd aan enkel de hoognodige groups... (Dus niet uid=0, gid=0)
Yep, is wel de bedoeling. Zoals ik al zei wil ik in een php script verschillende root commando's uitvoeren. En dat ga ik met deze doen... chmod 4755 ga ik gebruiken ja

Verwijderd

Slagroom schreef op 08 januari 2003 @ 09:39:Yep, is wel de bedoeling. Zoals ik al zei wil ik in een php script verschillende root commando's uitvoeren. En dat ga ik met deze doen... chmod 4755 ga ik gebruiken ja
Dan kan iedereen die kan inloggen op jouw machine, dit programma gebruiken om dingen als root uit te voeren, mogeijk zelfs misbruiken om volledig root access te verkrijgen... Volgens mij zelfs al door bijvoorbeeld:
./progje 1 'foo;sh'

Volgens mij maakt dit commando een "foo" dir aan en open vervolgens een root-shell!!!

Ik lees dan ook met `man system` :
Do not use system() from a program with suid or sgid priv­
ileges, because strange values for some environment vari­
ables might be used to subvert system integrity. Use the
exec(3) family of functions instead, but not execlp(3) or
execvp(3). system() will not, in fact, work properly from
programs with suid or sgid privileges on systems on which
/bin/sh is bash version 2, since bash 2 drops privileges
on startup. (Debian uses a modified bash which does not
do this when invoked as sh.)
Dus met bash 2 als shell werkt het niet eens... (behalve op debian)

Je kunt dan nog altijd beter een php-groep maken, waar alleen bijvoorbeeld "root" en de php-engine aan toe behoren en de applicatie die je gaat maken vervolgens de gid van deze groep mee te geven en uid root. En dan dus chmod 4750 uiteraard!

Maar waarom moet je speciaal root worden voor mkdir/rmdir/ln?!

  • Slagroom
  • Registratie: Juni 2001
  • Laatst online: 23-08 10:29
Ik heb nu dit trouwens:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
    char commando[256];
        int i = 0, valid = 0;
    char allowed_dirs[255][255];

    setuid(0);
    setgid(0);

    sprintf(allowed_dirs[0], "%s", "/home/vhosts");
    sprintf(allowed_dirs[1], "%s", "/home/webshop");
    sprintf(allowed_dirs[2], "%s", "/home/config");
    allowed_dirs[3][0] = '\0';

    while (allowed_dirs[i][0] != '\0') {
        if(!strncmp(allowed_dirs[i], argv[2], strlen(allowed_dirs[i])))
            valid = 1;
                i++;
        }

    if (argc< 2) {
        printf("U moet wel argumenten meegeven\n");
        return 0;
    } else {
        if(valid) {
            if(strcmp(argv[1], "-mkdir") == 0) {
                sprintf(commando, "mkdir %s", argv[2]);
                system(commando);
                return 1;
            } else if (strcmp(argv[1], "-rmdir") == 0) {
                sprintf(commando, "rmdir %s", argv[2]);
                system(commando);
                return 1;
            } else if (strcmp(argv[1], "-ln") == 0) {
                sprintf(commando, "ln -s %s %s", argv[2], argv[3]);
                system(commando);
                return 1;
            } else {
                printf("Dit argument wordt niet herkent\n");
                return 0;
            }
        } else {
            printf("U mag geen acties uitvoeren in deze directory\n");
            return 0;
        }
    }
    return 0;
}

Ik wil dus met php dirs aanmaken en verwijderen in delen waar de apache deamon geen rechten heeft. Ik wil apache geen ander rechten geven.

Verwijderd

Gebruik in elk geval exec i.p.v. system, zie bovenstaand...
En zorg bij "ln":
C++:
37
38
39
40
41
42
43
44
                if (argc == 2) 
                {
                  sprintf(commando, "ln -s %s", argv[2]]);
                }
                else
                {
                  sprintf(commando, "ln -s %s %s", argv[2], argv[3]);
                }

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Slagroom schreef op 09 January 2003 @ 12:39:
Ik wil dus met php dirs aanmaken en verwijderen in delen waar de apache deamon geen rechten heeft. Ik wil apache geen ander rechten geven.

Waarom geef je apache die rechten niet? Dan heb je hiet iig nog in de hand. Door bijvoorbeeld een nieuwe groep aan te maken en die beperktere rechten te geven, maar precies zoveel als je nodig hebt.

Dat in de hand hebben, heb je niet meer als je dat programma naar root/root gooit en elk lek is potentieel een ontzettend groot gevaar.
Pagina: 1