Вступление
Мне кажется, что при проектировании системы прав доступа к файлам в NTFS сознательно заложили логическую ошибку. Система, где нет (привычного для Unix) пользователя с полными и абсолютными правами ко всему, существовать не может. И если администратору системы чтобы провести какие-либо манипуляции с файлами нужно предварительно отобрать права на файл у пользователя - это самая странная логика, какую только можно было заложить в систему.
Что же использовать
Для начала нужно разобраться, чем и как лучше скопировать файловую систему. После всего потраченного мной времени, я могу совершенно авторитетно заявить: если у вас есть возможность использовать блочное копирование, вместо файлового - используйте его. С вероятностью в 99% вы потратите меньше времени, даже при условии, что вам придется перезагрузиться в какой-нибудь LiveCD (например замечательный и горячо мной любимый CloneZilla).
Точно так же, если ваш раздел с данными больше 1 ТБ - тоже смотрите в сторону блочных методов. Почти наверняка на разделе такого объема вам попадется не один и не два файлами с неправильными правами. А сидеть более 5 часов ожидая очередную ошибку - очень неприятное занятие.
Всё описанное ниже относится только к небольшим (до 1 ТБ) объемам данных.
xcopy
Утилита xcopy
- это copy
для каталогов и деревьев каталогов. Зачем нужна была отдельная утилита - известно только Microsoft. С ключами всё очень просто:
Приводить расшифровку ключей здесь я не буду - всё есть в мануале. Но это, пожалуй, минимальный набор, чтобы получить полную копию, со всеми правами и правильными владельцами.
robocopy
Утилиту robocopy
позиционируют как замену для xcopy
, которая теперь считается deprecated. Два главных её преимущества перед конкурентами это во-первых достаточно большой набор разнообразных ключей, а во-вторых, натыкаясь на ошибку, она не падает и не заставляет начинать всё с нуля, а начинает периодически переобращаться к файлу, давая вам что-нибудь пофиксить и продолжить.
Для себя я выбрал примерно такой набор ключей:
Отдельно стоит сказать, что ключ /B
или /ZB
предназначен для использования так называемого backup-режима (не буду показывать пальцем, где подсмотрено такое название) и главной целью несет якобы использование специальных методик сохранения всех атрибутов, даже если у администратора нет прав доступа к файлу. К сожалению это не работает примерно в половине случаев.
Возможные проблемы
А теперь поговорим о том, ради чего я всё это пишу. К сожалению проблем с файловой системой в Windows больше, чем даже можно себе представить. Например в этой статье рассказывается о том, как robocopy
победил длинные пути к файлам, и хоть Explorer их и не видит - они по-крайней мере успешно скопировались.
Отсутствие прав доступа
Как я и писал выше, в Windows системах Администратор не всесилен и периодически приходится сталкиваться с тем, что если пользователь оставил в правах на файл только себя - придется забирать у него этот файл, чтобы что-то с ним сделать. Опять же, как я писал выше, решать эту проблему должен запуск robocopy /B
, но в моем случае я всё равно получил ошибку:
2016/10/30 14:44:49 ERROR 5 (0x00000005) Copying File C:\sourcedir\filename
Access is denied.
Waiting 3 seconds... Retrying...
Первое, что нужно попробовать в таком случае - деликатно добавить себя (т.е. Администратора) в разрешения доступа к файлу:
Если вам повезло, и команда сообщит, что все файлы успешно обработаны - то robocopy
в соседней консоли автоматически продолжит работу. Если же вам не повезло, то придется полностью забрать себе все права на директорию:
А после - снова выполнить команду icacls
. В большинстве случаев это поможет, но есть еще один нюанс...
Отсутствие прав доступа у назначения
Удивительно, но да, может быть и такое. Возникает эта проблема из-за особенностей наследования прав доступа: когда вы копируете директорию A
в директорию B
, директория A\A1
имеет набор прав доступа, состоящих из её личных и наследованных от директории A
, а при перемещении в директорию B
наследованные права меняются. В результате, robocopy
создает директорию-назначение и сам же теряет к ней доступ! Вы увидите ошибку идентичную предыдущей, начнете исправлять права на файл-источник, а на самом деле - исправлять права нужно на директории-назначении. Проблема, которую сложно представить для пользователя root, может забрать у вас не один десяток минут, особенно учитывая то, что она может снова и снова повторяться на протяжении копирования и предугадать её появление сложно. По-идее помочь может только изначальное полное соответствие прав на директории A
и B
- но мне оно не помогло.
Невалидные имена
Следующее, с чем я столкнулся, это неправильные имена файлов. Мне пришлось копировать сетевой том, доступный всему офису, куда складывались файлы не только с рабочих станций под управлением других Windows, но и с Linux. И вот здесь внезапно выяснилось, что пользователь никсов вполне может залить на сетевой диск по smb файл с невалидным именем, а вот сделать с ним на Windows системе ничего не получится. Причем невалидными являются такие совсем безобидные точка в конце названия каталога (напр. directory.
) или даже пробел.
Что делать с таким файлом? Здесь нам придет на помощь другая фича семейства Windows: обращаться к файлам, к которым нельзя обращаться, можно используя специальную конструкцию: \\?\
. Подробнее о ней написано здесь, а переименовать проблеммную директорию мы можем так:
Комбо
Ну и теперь самый интересный вариант. Представим (если бы...), что нам на сетевой диск не просто залили файл/директорию с невалидным именем, а еще и убрали с неё все права, позволяющие Администратору хоть что-то с ней сделать. Казалось бы - два примера выше использованные вместе должны полностью решать задачу. Однако это не так. И проблема в том, что ни takeown
, ни icacls
- не умеют работать с расширенными путями (\\?\
). Вот и получается, что переименовать у нас нет прав, а выставить права мы не можем.
Остается только копаться в истории. Когда-то, во времена Windows XP и Server 2003, существовала замечательная утилита SubInACL. Сейчас она считается deprecated, но её по-прежнему можно скачать и даже установить в новые системы. Хороша она по двум причинам: работает почти безотказно и понимает расширенные пути: