Управління ACL з PowerShell.
Як ви знаєте, в файлової системі NTFS кожен об'єкт (файл або папка) має свій список контролю доступу (Access Control List, ACL). ACL визначає, хто (або що) має доступ до об'єкта, і які операції дозволено (або заборонено) цього суб'єкту проводити над об'єктом.
В PowerShell для керування ACL є цілих два командлет :
• Get-ACL - витягує список ACL для об'єкта.Отримані дані можна передати для подальшої обробки (напр. По конвеєру) або просто зберегти в файл;
• Set-ACL - встановлює нові або змінює існуючі списки ACL для об'єкта.
Як найпростіший приклад скопіюємо дозволу однієї папки на іншу:
Get-Acl C: \ test | Set-Acl C: \ test2
Порівняємо ACL до і після.Як бачите, зміни в наявності.
При копіюванні ACL потрібно мати на увазі, що користувач, під яким виконується ця операція, повинен бути власником (Owner) вихідного ресурсу (в прикладі це папка Test) і мати право Take Ownership. Справа в тому, що при перенесенні дозволів не можна перенести іншого власника.Якщо власником папки Test є поточний користувач і він має право Take Ownership, то всі дозволи включаючи власника будуть скопійовані на папку Test2. Якщо ж одна з умов не виконується, то буде видана помилка.
Копіювання штука корисна, але частіше доводиться ставити дозволу більш детально.Для установки дозволів NTFS використовується .NET клас FileSystemAccessRule, а список прав перерахований в FileSystemRights Enumeration. Вивести список можливих дозволів можна командою:
[system.enum] :: getnames ([System.Security.AccessControl.FileSystemRights])
У списку будуть показані як основні, так і детальні дозволу (зазвичай вони показуються на вкладці Advanced).
Для прикладу спробуємо дати користувачеві Testuser1 повні права на папку Test2:
# зчитуємо поточний список ACL папки Test2
$ acl = Get-Acl C: \ Test2;
# Створено змінну із зазначенням користувача, прав доступу і типу дозволу
$ AccessRule = New-Object System .Security.AccessControl.FileSystemAccessRule ( "Testuser1", "FullControl", "Allow");
# Передаємо змінну в клас FileSystemAccessRule для створення об'єкта
$ acl.SetAccessRule ($ AccessRule);
# Застосовуємо дозволу до папки
$ acl | Set-Acl c: \ Test2;
За замовчуванням створене правило дає користувачеві права тільки на саму папку. Якщо потрібно поширити це правило на дочірні об'єкти, то в створюваному правилі потрібно додатково вказати параметри успадкування:
"ContainerInherit", "None" - правило застосовується для папки і її підпапок;
"ObjectInherit", "None" - правило застосовується для папки і її файлів;
"ContainerInherit, ObjectInherit", "None" - правило застосовується для самої папки, її підпапок і файлів;
"ContainerInherit", "InheritOnly" - правило застосовується тільки для підпапок;
"ObjectInherit", "InheritOnly" - правило застосовується тільки для файлів;
"ContainerInherit, ObjectInherit", "InheritOnly" - правило застосовується тільки для підпапок і файлів.
Наприклад таке правило буде поширюватися на саму папку і всі її вміст:
$ AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule ( "Testuser1", " FullControl "," ContainerInherit, ObjectInherit "," None "," Allow ")
Видалення дозволів проводиться за такою ж схемою, що і додавання, тільки замість методу SetAccessRule буде використовуватися метод RemoveAccessRule:
$ acl = Get-Acl C: \ Test2;
$ AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule ( "Testuser1", "FullControl", "Allow");
$ acl.RemoveAccessRule ($ AccessRule);
$ acl | Set-Acl c: \ Test2;
І ще один момент. Метод SetAccessRule повністю замінює дозволу для користувача. Тому, якщо потрібно додати нові права до вже наявних, то використовуємо метод AddAccessRule.
Для видалення всіх дозволів користувача (повне видалення з ACL) використовується метод PurgeAccessRules, для роботи якого в якості параметра потрібно передати ім'я користувача або групи.У роботі цього методу є одна особливість - він не вміє працювати із строковими значеннями імен користувачів і груп, тому потрібен механізм перетворення строкових значень в SID. Для прикладу видалимо групу Users зі списку доступу папки Test2:
# Прочитуємо ACL
$ acl = Get-Acl C: \ Test2;
# Перетворимо строкове значення групи users в SID.Для перетворення скористаємося
# класом Ntaccout
$ users = New-Object System.Security.Principal.Ntaccount ( "users");
# Застосовуємо метод, передавши в нього в якості аргументу змінну $ users
$ acl.PurgeAccessRules ($ users);
# Застосовуємо ACL до папки
$ acl | Set-Acl C: \ Test2;
Варто мати на увазі, що подібним чином можна видаляти тільки явно призначені (не успадковане) дозволу.
Наступний етап налаштування дозволів - це управління успадкуванням. За керування спадкуванням відповідає метод SetAccessRuleProtection. Метод має два параметри, кожен з яких може бути $ true або $ false. Значення першого параметра $ true блокує успадкування дозволів від батька, $ false включає спадкування для об'єкта.Другий параметр відповідає за долю поточних дозволів для об'єкта при відключенні успадкування. Значення $ true залишає успадковані дозволи у вигляді явно заданих дозволів, $ false навпаки видалить успадковані дозволу і залишить тільки ті, які були явно задані. Наприклад SetAccessRuleProtection ($ true, $ false) - прибираємо успадкування і видаляємо успадковані дозволу.
За замовчуванням знову створений об'єкт успадковує дозволи від батьків. Для прикладу створимо новий об'єкт (папку Test3) і відключимо у неї спадкування:
# Створюємо нову папку і виводимо її ACL
md C: \ Test3 | Get-Acl | fl;
# Прочитуємо ACL папки Test3
$ acl = Get-Acl C: \ Test3;
# Відключаємо успадкування і видаляємо всі успадковані дозволу
$ acl.SetAccessRuleProtection ($ true, $ false);
# Застосовуємо ACL до папки Test3
$ acl | Set-Acl C: \ Test3;
Якщо тепер подивитися на вирішення папки Test3, то в поле Access ми побачимо порожнечу. І не дивно, адже всі успадковані дозволу ми видалили, а явно заданих у неї не було. Тепер доступ до теки зможе отримати тільки її власник (Owner).
І раз мова зайшла про власника. Власником об'єкта автоматично стає користувач, цей об'єкт створив (Creator Owner). Є політика Take Ownership, що дозволяє захоплювати права володіння об'єктом. За замовчуванням це право є тільки у членів групи локальних адміністраторів.
Для управління власниками об'єктів в PowerShell використовується метод SetOwner. Як приклад поміняємо власника папки Test2:
# Прочитуємо ACL
$ acl = Get-Acl C: \ Test2;
# Перетворимо строковий параметр групи Administrators в SID
$ group = New-Object System.Security.Principal.Ntaccount ( "Administrators");
# Застосовуємо метод SetOwner
$ acl.SetOwner ($ group);
# Застосовуємо ACL об'єкта
$ acl | Set-Acl C: \ Test2;
Чесно кажучи, управління власниками об'єктів в PowerShell не дуже зручно. Наприклад, не можна вказати в якості власника іншого користувача або групу. Власником об'єкта можна призначити тільки поточного користувача або його групу.Крім того, користувач, під яким виконується ця операція, повинен мати такі права:
• Право Take Ownership для даного об'єкта;
• Права Read і Change Permissions для даного об'єкта;
• право Restore files and directories в локальній політиці безпеки.
Ну ніби все.Список методів, що використовуються для управління ACL, докладно описаний в класі FileSystemSecurity на MSDN. Детальніше про дозволи NTFS можна почитати тут.
.