Открыть файл по иноду

Можно ли открыть файл, зная его индекс?

ls -i /tmp/test/test.txt
529965 /tmp/test/test.txt

Я могу указать путь, индексный дескриптор (выше 529965), и я хочу получить взамен файловый дескриптор.


person dev    schedule 18.03.2016    source источник
comment
Возможный дубликат Почему inode не может управлять файлами?   -  person zwol    schedule 18.03.2016


Ответы (2)


Это невозможно, потому что это открыло бы лазейку в правилах контроля доступа. Сможете ли вы открыть файл, зависит не только от его собственных битов разрешения доступа, но и от битов разрешения каждого содержащегося каталога. (Например, в вашем примере, если test.txt был в режиме 644, а содержащий каталог test был в режиме 700, то только root и владелец test могли открыть test.txt.) Номера инодов идентифицируют только файл, а не содержащие каталоги (это возможно для файл должен находиться более чем в одном каталоге; почитайте о «жестких ссылках»), чтобы ядро ​​не могло выполнить полный набор проверок управления доступом только с номером инода.

(Некоторые реализации Unix предлагали нестандартные API-интерфейсы только для root, чтобы открывать файл по номеру inode в обход некоторых правил контроля доступа, но если в текущем Linux есть такой API, я не знаю об этом.)

person Community    schedule 18.03.2016

Не совсем то, о чем вы спрашиваете, но (как намекает zwol) и Linux, и NetBSD/FreeBSD предоставляют возможность открывать файлы с использованием ранее созданных «дескрипторов»: это постоянные имена, подобные inode, которые идентифицируют файл в файловой системе.

В *BSD (getfh и fhopen), используя это так же просто, как:

#include <sys/param.h>
#include <sys/mount.h>


fhandle_t file_handle;
getfh("<file_path>", &file_handle);  // Or `getfhat` for the *at-style API

// … possibly save handle as bytes somewhere and recreate it some time later …

int fd = fhopen(&file_handle, O_RDWR);

Однако последний вызов требует, чтобы вызывающий абонент был пользователем root.

Linux name_to_handle_at и open_by_handle_at аналогичны, но гораздо более явны и требуют, чтобы вызывающая сторона сама отслеживала соответствующие идентификаторы монтирования/UUID файловой системы, поэтому я скромно приведу ссылку на < href="https://man.cx/name_to_handle_at(2)#heading9" rel="nofollow noreferrer">подробный пример на странице руководства. Имейте в виду, что пример не является полным, если вы хотите сохранить дескрипторы при перезагрузке; необходимо преобразовать полученный идентификатор монтирования в постоянный идентификатор файловой системы, такой как UUID файловой системы, а затем преобразовать его обратно в идентификатор монтирования. Однако по сути они делают то же самое. И точно так же, как в *BSD, использование более позднего системного вызова требует повышенных привилегий (точнее, CAP_DAC_READ_SEARCH).

person ntninja    schedule 12.02.2020