bash program futtatasa perlbol

Sziasztok,

A kovetkezo problmeba futottam bele.

Perl programbol kellene mentenem Zimbras mail fiokokat.
A progi kesz is van , mindenfele csilivili featureval, de elakadtam ott, hogy ezt a bash programot akarom meghivni perl alol:

su - zimbra -c "zmmailbox -z -m $USER getRestURL '//?fmt=tgz' > $USER.tgz"; S ez bash alol szepen megy is.

valahogy igy:
$mktgz="su - zimbra -c "zmmailbox -z -m $lines getRestURL '//?fmt=tgz' > $bckdir/$lines.tgz"";
system($mktgz);

De eldobja hibaval. Biztos vmi trivialis a megoldas de nem latom a szememtol mar.
Legyszi segitsetek

Koszi

Sztupi

Hozzászólások

Két dolgot vélek felfedezni:
- hiányzó backslashek, bár azokat lehet, hogy a hup motorja tüntette el:
$mktgz="su - zimbra -c \"zmmailbox -z -m $lines getRestURL '//?fmt=tgz' > $bckdir/$lines.tgz\"";

- a perl éppúgy behelyettesíti a változókat az idézőjelek közt, mint a bash. Tehát egy $x="$w"; sor eredménye üres string lesz, ha nincs $w változód.

Huhh a backslasheket NEM a hup torolte. Ebben segitenel ? Mar belekavarodtam de uuuuugy

"a perl éppúgy behelyettesíti a változókat..." A $lines $bckdir stb. definaialva van meg korabbrol.

Itt a "" es'' hasznalataban van gebasz , abba zavarodtam bele.

Pl a program ezen resze tokeletesen mukodik.

$users = "su - zimbra -c 'zmprov -l gaa'> $dir/temp.txt";
system($users);

tipushiba. megértéséhez szükséges az execv() syscall család ismerete.
az általad írt példában nagyjából ez történik:
(ha kieszképelted az értékadáskor az idézõjeleket, mert így syntax hibás)
execv('/bin/su', '-', 'zimbra', '-c', '"zmmailbox', '-z', ...)
másik esetben pedig: execv('/bin/sh', '-c', 'su - zimbra -c "zmmailbox -z ...')

tehát az $mktgz stringben átadott bash-es parancssorból a perl nem tudja kitalálni, melyik idézõjelet értetted literálisan és melyiket szántad a szóközökkel (IFS-sel) tagolt string egy paraméterként való értelmezésének kikényszerítéséhez.
Ugyanis az egész "zmmailbox -z -m $USER getRestURL '//?fmt=tgz'" rész a /bin/su 4. agrumentuma.

Viszont van egy másik eset is - talán a redir jel esetén -, amikor a perl elhárítja magáról a parancssor értelmezését, és átadja a $ENV{'SHELL'} -nek.
A >, <, | magic karakterek válthatják ki ezt az indulatot belõle. Mindjárt utánanézek.

Aztán lehet még hiba, a $valtozok behelyettesítése. A példádban már a perl behelyettesíti, de gondolom erre is számítasz, mivel a shellparancsban nem definiálsz valtozót. Viszont a $USER -bõl arra gondolok, hogy a USER environmentet akarod behelyettesíteni, emit perl-bõl $ENV{'USER'} -rel érsz el.

'//?fmt=tgz' -ben nincs bash számára magic karakter, ezért el lehet hagyni az aposztrófot, annyival is olvashatóbb és könnyebb eszképelni.

Beleirányítós kacsacsõr után egy token állhat, máskülönben a bash ambiguous redirect hibával tagadja meg a parancsot; ellenõrizd, hogy a $bckdir és $lines változók nem tartalmaznak space-t.

Mondanám, hogy open() vagy IPC::Open2::open2() -vel futtasd a parancsot, de az úgy lenne szép, ha elõtte $< állapotváltozó beállításával egybõl user-t valtanál (kivaltva ezzel az su -t), ahhoz viszont root-ként kéne futnia a perl scriptnek.

Aztán nem-e az van, hogy az su be akarja kérni a jelszót? És nem talál terminált, amire kiadja a noecho termio parancsot...

~~~~~~~~
http://www.youtube.com/watch?v=VbUVqODL1nE

Na szoval. mar amennyir ertem en ezt.

Kezedem hatulrol.

Ez egy zimbra server , s minden parancssori futtatas csak a su zimbra utan megy (root-kent kiadva)

A su nem ker jelszot .
A $lines s a $bckdir nem tartalmaz spacet.
Igen a su zimbras parancsot perlbol hivom meg , a valtozok ott kapnak erteket.

Nem, en a suid/setuid scriptre gondoltam. Elvben, ha a setuid-dal futtatod a scriptet, akkor a tulajodonos user neveben fut. Ha jol tudom, ez lefele is mukodik, nem csak felfele, tehat nem csak root ownerre lehet setuidozni, hanem root-rol zimbrara is. De ez csak tipp.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

Akkor viszont a másik kollégánál a pont, ui. linuxon - legalábbis 15 éve, amikor pelyhes háttal éppen ilyennel próbálkoztam, még így volt - shell szkript némán ignorálta a setuid flaget.
...

Most is:


$ cat /tmp/wai.sh
#!/bin/sh
whoami
$ ls -l /tmp/wai.sh
-rwsr-xr-x 1 root root 17 Dec  1 13:42 /tmp/wai.sh
$ /tmp/wai.sh
lx

De...


# grep -i wai /etc/sudoers
Cmnd_Alias      WAI= /tmp/wai.sh
lx      ALL=NOPASSWD: WAI
# chmod 0755 /tmp/wai.sh

$ sudo /tmp/wai.sh
root

http://www.tuxation.com/setuid-on-shell-scripts.html

egy picit tuningoltam rajta:


#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char **argv) {
    if(argc < 2) {
        printf("Usage: %s script\n", argv[0]);
        return 1;
    }
    setuid( 0 );
    return system( argv[1] );

}

--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

Megtenné valaki helyettem, hogy minősíti mind az eredeti program szerzőjének, mind az előttem szólónak a munkáját? :)

Tévedés jogát fenntartva, ez amolyan öntökönbökésnek tűnik.
Ellenőrizetlen forrásból származó programokat root joggal futtatna... Vagy valamit nem vettem észre? (az már csak mellékes apróság, hogy a meghívott scriptek nem paraméterezhetők)

Némi olvasnivaló, hogy miért nem lehet scriptre setuid-t tenni: http://www.faqs.org/faqs/unix-faq/faq/part4/section-7.html

Nem, sajat scripteket. A runscript binaris csak a suid-ban segit, hogy hogyan hasznalod, meg hova rakod, az mar rajtad mulik.

Raadasul ugye itt lefele suid-ozunk, tehat pont nem user => root hanem root => user iranyba szeretnenk.

Ennyi erovel a zimbra is ellenorizetlen forras.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

Továbbra sem tiszta:
root-ként futtatva ennek mi értelme? Egyszerűbb és biztonságosabb a már bejáratott su/sudo parancsokkal intézni, nem?

Aztán...
setuid(0) - ennek a világon semmi értelme, eddigi ismereteim szerint. Ezt ugyanis csak root-ként lehet kiadni. Tévedek? (kipróbáltam a kódod, ha kivettem a setuid hívást, akkor sem változott a működése)

Ha a programra ráteszek egy setuid-ot és odaadom x usernek, akkor bárki, akinek joga van futtatni a programodat, x user nevében futtathat gyakorlatilag bármit és nincs semmi más ellenőrzés, mint a binárison lévő jogosultságok.

Ha tudom, hogy a script eleve rootként fut, akkor még mindig elegánsabb adott esetben egy seteuid hívással jogosultságot váltani(nem setuid, mert onnan nincs visszatérés a root-hoz), bár ettől csak a processz jogosultsága változik, a környezete nem - gondolom, e tekintetben a perl is úgy működik, ahogy a python. Viszont ahogy elnéztem, a kérdezőnek egy megadott userhez tartozó login shell kell, tehát ez nem igazán használható nála.

Szóval biztosan a felfogásom nehéz, de továbbra sem látom értelmét ennek az egésznek.

Nem a login shell kell, az csak a su benasaga, hogy o a su - -ra fellovi a login shell-t is, vagy annak a tutorialnak a benasaga, amit olvasott a kerdezo.

A feladat amugy rem egyszeru: van egy parancs, ami zimbra userkent kell fusson, mert maskepp nem tud futni, gondolom mert tamaszkodik pl. a HOME valtozo ertekere, ami menet kozben szamolodik ki, vagy nem tudom, nem ismerem a zimbrat. A kerdezo ezt is szeretne, annyi kitetellel, hogy o a parancsot nem siman konzolbol akarja kiadni, hanem egy perl scriptbol, mert a zimbra parancsbol kijovo kimenettel tovabb szeretne dolgozni. A su szerintem reszben overkill ehhez, reszben pedig a su borzasztoan nem eleg rugalmas. A sudo mar jo lenne, de megertem, ha valaki nem akarja hasznalni, tenyleg sok CVE meg hasonlo harombetus kotheto a nevehez, sokan gondolnak ugy ra, mint egy idozitett bombara. Akkor mar hasznosabb egy olyan cucc, amit az ember maga ir, maga kontrollal, es magat rugja seggbe, ha nem vagy nem ugy mukodik, ahogy kell.

Erre a feladatra jo megoldas lehet az, hogy lerakja egy shell scriptbe, amit zimbra userkent majd hivni akar, majd rahiv ezzel a runscripttel. A setuid-dal kapcsolatban egyebkent igazad lehet, azt talan ki lehet hagyni, hiszen a suid bit miatt a rendszer mar egyszer elvegzi az ehhez kapcsolodo kernel hivast.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

$mktgz = qq!su - zimbra -c "zmmailbox -z -m $lines getRestURL '//?fmt=tgz' > $bckdir/$lines.tgz"!;

A qq operátor úgy viselkedik, mint a "", azaz interpolálja a változókat, de a string idézőjeleket is tartalmazhat.

A system parancs kétféleképpen működhet perlben: ha egy listát kap paraméterként, akkor közvetlenül a fentebb említett execve rendszerhívást használja, átadva annak a paraméterlistát. De ha egy szóközöket is tartalmazó stringet kap, akkor azt a shellnek adja tovább.