Подтвердить что ты не робот

Зачем мне нужно setuid (0) в рамках программы setuid-root C, которая вызывает административную программу с системой()?

Мне пришлось сделать грязный Linux-хак для кого-то, чтобы они могли запустить принтер с помощью команды оболочки cupsenable printername, будучи пользователем без полномочий root. Я не хотел, чтобы они могли использовать синтаксис cupsenable как root, поэтому я просто написал оболочку C, которая санирует вход в argv[1] и вызывает system("cupsenable sanitizedprintername").

Я сделал программу setuid root, но даже в этом случае cupsenable не удалось с "разрешением отклонить". Затем я вставил вызов setuid(0) до system() и, вот и вот, он работал.

Не обращайте внимания на то, что существует лучший способ предоставить пользователям контроль над принтером. Вероятно, есть лучший способ. Меня интересуют тонкости chmod u+s vs. setuid(0) vs. system(). Почему он так себя ведет?

4b9b3361

Ответ 1

От man system:

Не используйте system() из программы с привилегиями set-user-ID или set-group-ID, потому что странные значения для некоторых переменных среды могут использоваться для разрушения целостности системы. Вместо этого используйте семейство функций exec(3), но не execlp(3) или execvp(3). system(), по сути, не будет корректно работать с программами с привилегиями set-user-ID или set-group-ID в системах, на которых /bin/sh есть bash версия 2, так как bash 2 падает привилегии при запуске.

И от man bash:

Если оболочка запускается с эффективным идентификатором пользователя (группы), не равным идентификатору реального пользователя (группы), а параметр -p не предоставляется, файлы запуска не читаются, функции оболочки не унаследованы от среда, переменная SHELLOPTS, если она появляется в среде, игнорируется, а эффективный идентификатор пользователя устанавливается на реальный идентификатор пользователя.

Кажется, ваш вызов setuid(0) обошел эту защиту.