1 (изменено: dementor5, 2017-01-16 14:31:17)

Тема: VBS: Отключить наследование NTFS у сетевой папки (файла)

Доброго времени суток!
Задача.
Почистить список acl ntfs у сетевой папки.

Есть код:

Option Explicit
Call ClearACL()
Sub ClearACL()
	Const ADS_PATH_FILE = 1
	Const ADS_SD_FORMAT_IID = 1
	Dim sFile, oADsSecurityUtility, oSD, oDacl, oAce
	sFile = "\\fileserver\Documents\testfolder"
	Set oADsSecurityUtility = CreateObject("ADsSecurityUtility")
	Set oSD = oADsSecurityUtility.GetSecurityDescriptor(sFile, ADS_PATH_FILE, ADS_SD_FORMAT_IID)
	Set oDacl = oSD.DiscretionaryAcl
	For Each oAce In oDacl
		 if (InStr(oAce.Trustee, "Administrators") = 0) and (InStr(oAce.Trustee, "SYSTEM") = 0) and _
			(InStr(oAce.Trustee, "Администраторы") = 0) and (InStr(oAce.Trustee, "СИСТЕМА") = 0) then
		  oDacl.RemoveAce oAce
		 End If
		Next
		oSD.DiscretionaryAcl = oDacl
		oADsSecurityUtility.SetSecurityDescriptor sFile, ADS_PATH_FILE, oSD, ADS_SD_FORMAT_IID
end Sub

Он работает, на windows xp, windows 7 - удаляются все лишние acl, при этом наследование выключается автоматически.

А вот на 2012r2 наследование автоматом не выключается и унаследованные группы не удаляются. Если выключить наследование вручную (снять галочку в свойствах папки),
то скрипт отрабатывает как и положено.

Я подумал, что проблему можно решить просто - снять наследование, а затем уже удалять acl.
Решил пойти по пути наименьшего сопротивления и написал процедуру, использующую wmi, как в соседних темах в примерах:

Option Explicit
Call DisableInheritanceWMI()
Sub DisableInheritanceWMI()
	Const SE_DACL_PROTECTED = 4096
	Dim sFile, oWMI, oSec, oSD
	sFile = "u:\Documents\testfolder"
	On Error Resume Next
	Set oWMI = GetObject("WinMgmts:\\.")
	If Err.Number <> 0 Then MsgBox "Ошибка " & CStr(Err.Number) & vbNewLine & Err.Description : Wscript.Exit
	Set oSec = oWMI.Get("Win32_LogicalFileSecuritySetting.Path='" & sFile & "'")
	If Err.Number <> 0 Then MsgBox "Ошибка2 " & CStr(Err.Number) & vbNewLine & Err.Description : Wscript.Exit
	If oSec.GetSecurityDescriptor(oSD) <> 0 Then MsgBox "Не удалось прочитать дескриптор безопасности каталога " & UCase(strDir) : Wscript.Exit
		If Not CBool(oSD.ControlFlags And SE_DACL_PROTECTED) Then
			oSD.ControlFlags = oSD.ControlFlags + SE_DACL_PROTECTED
			If oSec.SetSecurityDescriptor(oSD) <> 0 Then MsgBox "Не удалось применить настройки" : Wscript.Exit
		End If
End Sub

Процедура работает, но только с локальными папками.
Заставить её работать с сетевой к сожалению не удалось.

Я не сдался и попробовал сделать иначе:
Вот третья процедура, которая должна выключать наследование, перед запуском первой:

Option Explicit
Call DisableInheritance()
Sub DisableInheritance()
	Const ADS_PATH_FILE = 1
	Const ADS_SD_FORMAT_IID = 1
	Const SE_DACL_PROTECTED = 4096
	Dim sFile, oADsSecurityUtility, oSD
	sFile = "\\fileserver\Documents\testfolder"
	Set oADsSecurityUtility = CreateObject("ADsSecurityUtility")
	Set oSD = oADsSecurityUtility.GetSecurityDescriptor(sFile, ADS_PATH_FILE, ADS_SD_FORMAT_IID)
	oSD.Control = oSD.Control + SE_DACL_PROTECTED
	oADsSecurityUtility.SetSecurityDescriptor sFile, ADS_PATH_FILE, oSD, ADS_SD_FORMAT_IID
End Sub

И вот, вроде бы всё должно работать, но к сожалению нет.
Такое ощущение, что галочка снимается, acl переделываются в неунаследованные,
а после галка мгновенно ставится на место.

Ребята, подскажите, что я делаю не так или что не то сделала Microsoft с vbs в 2012r2?

2

Re: VBS: Отключить наследование NTFS у сетевой папки (файла)

dementor5
А с WSHShell.Run "cacls/icacls <keys>", 0 нет желания поиграться?

3 (изменено: dementor5, 2017-01-15 11:06:44)

Re: VBS: Отключить наследование NTFS у сетевой папки (файла)

Flasher, вообще не хотелось бы, только если иначе нельзя...
Основная идея реализовать эту задачу на vbs, по возможности, не используя других утилит.

4 (изменено: dementor5, 2017-01-16 14:29:20)

Re: VBS: Отключить наследование NTFS у сетевой папки (файла)

В итоге получилось так. Некрасиво, но возложенную задачу выполняет:

Option Explicit
Dim sFolder
sFolder = "\\server\documents\testfolder"

'Вызов функции с проверкой кода возврата:
If DisableInheritance(sFolder) Then MsgBox "There is a problem with disabling inheritance" : Wscript.Quit

'Сама функция:
Function DisableInheritance(sPath)
	Dim sCalCls
	sCalCls= "icacls.exe " & sPath & " /inheritance:d"
	DisableInheritanceIcaCls = CreateObject("Wscript.Shell").Run(sCalCls, 0, True)
End Function

5

Re: VBS: Отключить наследование NTFS у сетевой папки (файла)

dementor5
Ну, а куда деваться? Я бы помог, но у меня нет 2012r2. Да и такой вариант в любом случае быстрее того, что с WMI.

Поправьте вторую строчку в коде.

6 (изменено: dementor5, 2017-01-16 14:25:51)

Re: VBS: Отключить наследование NTFS у сетевой папки (файла)

Flasher, поправил, спасибо.

Вы не могли бы глянуть третий вариант с ADsSecurityUtility

Может я просто как-то не так пытаюсь использовать свойство .Control?

7

Re: VBS: Отключить наследование NTFS у сетевой папки (файла)

dementor5
Не всё. Я там ещё кавычки добавил.
Имеем битовые флаги:

Const SE_OWNER_DEFAULTED       = 1
Const SE_GROUP_DEFAULTED       = 2
Const SE_DACL_PRESENT          = 4
Const SE_DACL_DEFAULTED        = 8
Const SE_SACL_DEFAULTED        = 8
Const SE_SACL_PRESENT          = 16

Const SE_DACL_AUTO_INHERIT_REQ = 256
Const SE_SACL_AUTO_INHERIT_REQ = 512
Const SE_DACL_AUTO_INHERITED   = 1024
Const SE_SACL_AUTO_INHERITED   = 2048
Const SE_DACL_PROTECTED        = 4096
Const SE_SACL_PROTECTED        = 8192

Const SE_RM_CONTROL_VALID      = 16384
Const SE_SELF_RELATIVE         = 32768

Нужно плясать вокруг того, что в середине. Поснимать AUTO_INHERIT и добавить 4096/8192. Т.е.:

  oSD.Control = oSD.Control And _
                Not SE_DACL_AUTO_INHERIT_REQ And _
                Not SE_SACL_AUTO_INHERIT_REQ And _
                Not SE_DACL_AUTO_INHERITED   And _
                Not SE_SACL_AUTO_INHERITED    Or _
                SE_DACL_PROTECTED Or SE_SACL_PROTECTED

Мысли пока такие.

На локальной же машине с Win 7 3-й скрипт отрабатывает.

Чтобы разобраться в деталях, можно поковырять Xcacls.vbs (см. ключ /I) на 4300 строк.

8 (изменено: dementor5, 2017-01-17 12:28:47)

Re: VBS: Отключить наследование NTFS у сетевой папки (файла)

Flasher, я уже пробовал снимать-ставить галочки и смотреть на то, на сколько меняется значение.
Как раз эти злополучные 4096 единиц. Вот только прибавлением-убавлением разницы между снятой галочкой и установленной не достаточно. Так же попробовал сумму флагов на вроде DENY_INHERIT или ALLOW_INHERIT. На windows 7 работает, на windows 2012r2 нет. В общем третья функция рабочая с оглядкой на то, что её надо применять на ос не старше windows 7. Что там Microsoft накрутила - непонятно, но факт.

P.S. Ваш вариант тоже не работает, результат аналогичный моему - добавляются явные копии унаследованных прав (которые можно удалить), но само наследование и наследованные права не удаляются.

9

Re: VBS: Отключить наследование NTFS у сетевой папки (файла)

dementor5
А если так попробовать?:

	oSD.Control = oSD.Control And _
	Not SE_DACL_AUTO_INHERIT_REQ And Not SE_SACL_AUTO_INHERIT_REQ And _
	Not SE_DACL_AUTO_INHERITED   And Not SE_SACL_AUTO_INHERITED
	oADsSecurityUtility.SetSecurityDescriptor sFile, ADS_PATH_FILE, oSD, ADS_SD_FORMAT_IID
	oSD.Control = oSD.Control Or SE_DACL_PROTECTED Or SE_SACL_PROTECTED
	oADsSecurityUtility.SetSecurityDescriptor sFile, ADS_PATH_FILE, oSD, ADS_SD_FORMAT_IID

10

Re: VBS: Отключить наследование NTFS у сетевой папки (файла)

Flasher, та же картина, к сожалению.