Вызов setreuid не может восстановить права доступа к процессу
Я немного запутался с setreuid.
Сценарий: процесс запускается от имени обычного пользователя (id: cateof), но в течение очень короткого промежутка времени должен выполняться от имени пользователя root. Я должен поднять права на root от cateof и затем вернуться к обычному пользователю. Моей первой мыслью было, что я вложу свой "корневой вызов" между setreuid(0, 0); и сетреид (руид, эйид); было бы достаточно, но я был неправ. Единственный способ вернуться к обычному пользователю - это вызвать setreuid(ruid, euid) дважды в сыром виде после "корневого вызова".
Вот код:
int main(...) {
//check the permission, that the program is setuid
//become normal user
ruid = getuid ();
euid = geteuid ();
setreuid(ruid, euid);
...
setreuid(0, 0);
root_action();
setreuid(ruid, euid); //undo root #1
setreuid(geteuid(), getuid()); //undo root#2
Если я не вызову setreuid(geteuid(), getuid()) в последней строке, процесс продолжит работать от имени пользователя root. Зачем мне звонить дважды???
1 ответ
Ваш первый вызов setreuid на самом деле не работает - он не сбрасывает привилегии, вы, по сути, говорите, установите мой настоящий uid для моего getuid
и мой эффективный идентификатор для моего geteuid
, что в случае приложения setuid такое же, как вы получили.
В начале setuid root
программа запускается как пользователь bob
, затем getuid() == bob
, geteuid() == root
Если вы хотите отказаться от привилегий, то вам, вероятно, следовало позвонить:
setreuid(euid, ruid);
Тэд установил бы эффективный идентификатор bob
и настоящая помощь rood
, Все, что будет сделано после этого момента, будет похоже на действия непривилегированного пользователя Боба, понимающего, что вы еще не полностью утратили способность переключаться обратно на root
привилегии на этом этапе, потому что вы не уничтожили сохраненную информацию об идентификаторе пользователя.
Получение корневых привилегий будет сделано:
setreuid(ruid, euid);
Аналогично, в конце, когда вы повторно отбрасываете привилегии, вам нужно сделать то же самое:
setreuid(euid, ruid);
т.е. установить эффективный идентификатор идентификатора bob
, [ответ здесь][1] - похожая ситуация, которая объясняет детали немного более кратко.
Как правило, при проверке этой информации, маленький принтер помогает:
void printids(char *header) {
uid_t ruid, euid, saveduid;
getresuid(&ruid, &euid, &saveduid);
printf("%s ruid=%d euid=%d saveduid=%d\n", header, ruid, euid, saveduid);
}
помогает в определении привилегий / UID информации на всех этапах.
было бы немного проще просто использовать seteuid()
для временного изменения привилегий, а не чуть более жестким setreuid()
, Вы также можете использовать setresuid()
призывать быть более точным в отношении установки реальных, эффективных и сохраненных значений идентификаторов пользователей.
Сохранение и удаление привилегий:
setresuid(ruid, ruid, euid);
Повторное получение привилегий root:
setresuid(euid, euid, -1);
Откат к некорневым привилегиям:
setresuid(ruid, ruid, -1);
т.е. мы позволяем сохраненному идентификатору пользователя хранить корневую информацию и манипулировать realuid
а также euid
значения переключаются между root / non-root