Zapisać do pliku bez przekierowania?

13

Piszę regularnie skompilowaną aplikację, która musi utworzyć specjalny plik i zapisać w nim magiczne ciasteczko. Nie mogę zapisać pliku bezpośrednio z aplikacji, model bezpieczeństwa systemu wymaga ode mnie uruchomienia narzędzia pomocniczego o podwyższonych uprawnieniach. Mogę podać dowolną liczbę argumentów do narzędzia pomocnika. Teraz chciałbym wybrać bardzo proste polecenie systemowe, które posłuży jako narzędzie pomocnicze i utworzy plik dla mnie. Coś takiego:

/bin/sh -c "/bin/echo -n 'magic' > /some/where/file"

Simple touchnie tnie go, ponieważ muszę zapisać plik cookie w pliku, prosty echobez opakowania powłoki nie działa, ponieważ wymaga przekierowania, aby zapisać plik. Nie czuję się dobrze wzywając powłokę z uprawnieniami roota, aby wykonać tak trywialne zadanie. Czy jest jakieś naprawdę proste, ograniczone polecenie systemowe, które mógłbym wywołać, aby napisać plik dla mnie?

zoul
źródło
Czy istnieje powód, dla którego /bin/sh -c 'echo magic > /path/to/magic/file'nie działa? Byłby to plik wykonywalny i dwa argumenty. Będziesz musiał zbudować ostatni argument jako ciąg znaków (z sprintf lub odpowiednikiem). Czy istnieje powód, dla którego to nie działałoby dla Ciebie? Z twojego pytania wynika, że ​​doCommandAsRoot () nie pobiera danych wejściowych do strumienia do polecenia, prawda? W przeciwnym razie możesz zastąpić ostatni argument 'cat > /path/to/magic/file'i przekazać dane zamiast budować ciąg.
Arcege
Przykład powłoki działa, ale nie chciałbym wywoływać powłoki z uprawnieniami roota, aby utworzyć prosty plik. Biblioteka pobiera argument potoku komunikacyjnego (jest to AuthorizationExecuteWithPrivileges ), którego można użyć do zapisania pliku cookie tee. Dzięki!
zoul
Zobacz także stackoverflow.com/a/18146890/2032064
Mifeet,

Odpowiedzi:

11

Co powiesz na to:

echo -n 'magic' | sudo tee /some/where/file > /dev/null

Jasne, że są w tym przekierowania, ale tylko tee działa jako root, a nie shell. Działa dd of=...również z .

stribika
źródło
2
Niestety, najwyraźniej ostatnio mam problem z wyjaśnieniem siebie. Problem polega na tym, że gdy chcę uruchomić coś z podwyższonymi uprawnieniami, muszę przejść specjalne wywołanie biblioteki (coś w rodzaju doCommandAsRoot). Ta funkcja akceptuje tylko ścieżkę do polecenia i jego argumentów, więc nie mogę od razu użyć przekierowania wyjściowego. Mógłbym przejść przez powłokę (jak pokazano w pytaniu), ale nie podoba mi się to pod względem bezpieczeństwa.
zoul
@zoul: Myślałem, że piszesz skrypt powłoki. Czy można zapisać magiczny plik cookie w pliku, który jest dostępny dla nieuprzywilejowanych procesów? Jeśli tak, to zapisz go do takiego pliku i wywołaj doCommandAsRoot("dd", "if=/tmp/unprotected_file", "of=/some/where/file").
stribika
Nie, to zwykła skompilowana aplikacja (pytanie zaktualizowane). Po prostu szukam poleceń „powłoki”, które mogłyby służyć jako pomocnik, aby nie musiałem sam pisać. Tak, ciasteczko nie jest wrażliwe. ddPrzykładem jest dość blisko tego, co chcę, dziękuję. Czy możesz wymyślić coś jeszcze prostszego?
zoul
Jasne - możesz użyć cplub mvzamiast dd.
mattdm
Mam na myśli prostsze, jak bez potrzeby kopiowania :)
zoul
9

Bez przekierowania danych wyjściowych, bez potoku, ale z ciągiem „tutaj”:

dd of=/some/where/file <<<'magic'
Rainer Perske
źródło
Jednym minusem tego podejścia jest to, że dd zapisuje pewne statystyki na standardowe wyjście. Możesz użyć> / dev / null, aby je ukryć, ale w tym momencie równie dobrze możesz użyć tee.
studgeek
1
Działa to dla mnie w nietypowej sytuacji, w której nie mogłem użyć przekierowania wyjścia ani potoków. status=nonestłumi wszystkie inne dane wyjściowe z nowoczesnych wersji jąder GNU dd.
Michael Hampton
5

Jest jeszcze jedna uwaga: nie chcesz umieszczać wartości magicznego ciasteczka w wierszu poleceń, ponieważ inni użytkownicy mogą to zaobserwować. Nawet jeśli program jest krótkotrwały (w tym jeśli program zeruje ciąg wiersza poleceń), istnieje możliwość ataku. Więc teoretyczna:

writestringtofile 'magic' /some/where/file

jest niebezpiecznym podejściem. Dlatego popieram sugestię @ stribika: zapisz wartość do pliku tymczasowego i skopiuj na miejsce. Upewnij się, że korzystasz z bezpiecznej funkcji, aby utworzyć plik tymczasowy ( mkstemp()), aby nie było tam również warunków wyścigu.

mattdm
źródło
Dziękuję, to przydatna dyskusja. Na szczęście „magiczne ciasteczko” nie jest urządzeniem zabezpieczającym, każdy może je zobaczyć.
zoul
0

gąbka z moreutils - wchłoń standardowe wejście i zapisz do pliku:

echo -n 'magic' | sponge /some/where/file

W przeciwieństwie do przekierowania powłoki, gąbka wchłania wszystkie dane wejściowe przed zapisaniem pliku wyjściowego. Jeśli to możliwe, gąbka tworzy lub aktualizuje plik wyjściowy atomowo, zmieniając nazwę pliku tymczasowego na swoje miejsce.

Zobacz więcej

Ilya Murav'jov
źródło