1 (изменено: afteroot, 2010-10-01 13:19:12)

Тема: VBS: Разрешения на папку во вкладке безопасность

Вообщем-то сабж!
Помогите организовать скрипт который запрещает полностью доступ к Диску Д, в закладке Безопасности!

2

Re: VBS: Разрешения на папку во вкладке безопасность

Почему именно скриптом? Сие требуется делать на регулярной основе?

3

Re: VBS: Разрешения на папку во вкладке безопасность

Потому как нужно это делать по сети! А к каждому бегать на 1400 компов времени не хватает!

4 (изменено: Dmitrii, 2010-10-01 16:42:29)

Re: VBS: Разрешения на папку во вкладке безопасность

afteroot пишет:

Помогите организовать скрипт который запрещает полностью доступ к Диску Д, в закладке Безопасности!

1. Именно запрещает, а не исключает ненужные записи из ACL?
2. Кому запрещает - всем подряд без исключения?
3. Домен?
4. Какие версии ОС на удалённых компьютерах?

5

Re: VBS: Разрешения на папку во вкладке безопасность

Dmitrii пишет:
afteroot пишет:

Помогите организовать скрипт который запрещает полностью доступ к Диску Д, в закладке Безопасности!

1. Именно запрещает, а не исключает ненужные записи из ACL?
2. Кому запрещает - всем подряд без исключения?
3. Домен?
4. Какие версии ОС на удалённых компьютерах?

1. Запрещает
2. Всем подряд
3. Домен
4. Винда XP

6 (изменено: Dmitrii, 2010-10-06 11:10:50)

Re: VBS: Разрешения на папку во вкладке безопасность

afteroot пишет:

1. Запрещает
2. Всем подряд

Учтите, что в случае настройки полного запрета сменить разрешения после этого сможет только владелец корневой папки.
Ниже - пример решения задачи с помощью WMI (в принципе, можно и с помощью ADSI, но у меня нет под рукой готового примера).

Dim xResult
xResult = Forbid_Access("computer", "D:\")
Select Case xResult
    Case "0": WScript.Echo "Успешное завершение."
    Case "2": WScript.Echo "Доступ запрещён."
    Case "8": WScript.Echo "Неизвестная ошибка."
    Case "5", "9": WScript.Echo "Для выполнения операции недостаточно полномочий."
    Case "21": WScript.Echo "Заданы недопустимые значения параметров."
    Case Else: WScript.Echo xResult
End Select
WScript.Quit 0

'======

Function Forbid_Access(strComputer, strPath)
Dim objWMI, objSecSettings, objSD, objACE, xRes
Const ACCESS_ALLOWED_ACE_TYPE = 0
Const ACCESS_DENIED_ACE_TYPE = 1
Const FULL_ACCESS = 2032127
Const FULL_DENIED_ACCESS = 983551

On Error Resume Next
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
If Err.Number = 0 Then
    Set objSecSettings = objWMI.Get("Win32_LogicalFileSecuritySetting.Path='" & strPath & "'")
    If Err.Number = 0 Then
        If objSecSettings.GetSecurityDescriptor(objSD) = 0 Then
            If Not IsNull(objSD.DACL) Then
                For Each objACE In objSD.DACL
                    If objACE.AceType = ACCESS_ALLOWED_ACE_TYPE Then
                        objACE.AceType = ACCESS_DENIED_ACE_TYPE
                        'objACE.AccessMask = FULL_DENIED_ACCESS
                        'Раскомментировать предыдущий оператор в случае необходимости
                        'установить полный запрет доступа для всех записей в ACL.
                    End If
                Next
                Set objACE = Nothing
                xRes = CStr(objSecSettings.SetSecurityDescriptor(objSD))
            Else
                xRes = "Список управления доступом (ACL) к заданному объекту пуст."
            End If
        Else
            xRes = "Не удалось прочитать дескриптор безопасности объекта."
        End If
        Set objSD = Nothing
        Set objSecSettings = Nothing
    Else
        xRes = "Ошибка " & CStr(Err.Number) & vbNewLine & Err.Description
        Err.Clear
    End If
Else
    xRes = "Ошибка " & CStr(Err.Number) & vbNewLine & Err.Description
    Err.Clear
End If
Set objWMI = Nothing
On Error GoTo 0
Forbid_Access = xRes
End Function

Вам осталось:
- каким-либо образом сформировать список имён нужных станций и организовать его циклическую обработку;
- добавить к сценарию функцию предварительной проверки доступности станции (иначе будете ждать "до посинения" при 1400 компьютерах).

7

Re: VBS: Разрешения на папку во вкладке безопасность

2 Dmitrii если не сложно, то не могли бы Вы написать на VBS скриптец, который определённому пользователю на определённую папку даёт право на чтение/запись(полный доступ), а то никак меня не возьмёт дружба с Win32_LogicalFileSecuritySetting...  (применимо к локальным учёткам)

Времени не хватает... :-(

8

Re: VBS: Разрешения на папку во вкладке безопасность

Евген пишет:

... если не сложно, то не могли бы Вы написать на VBS скриптец, который определённому пользователю на определённую папку даёт право на чтение/запись(полный доступ)...

В принципе, несложно. Однако здесь многое зависит от частностей, поэтому требуется уточнение условий.
1. Версия ОС?
2. Локальные "учётки" удалённого или текущего компьютера? Если удалённого,- то домен или одноранговая сеть?
3. Запись "учётки" уже существует в ACL управляемой папки? Если существует, то править её маску доступа или добавлять дубликат с другой маской?
4. Управляемая папка наследует разрешения от "родителя"? Если наследует, то отключать ли наследование?
5. Настройки безопасности наследуются дочерними объектами управляемой папки? Если - не наследуются, то распространять внесённые изменения "вниз"?
6. Нужен один сценарий, работающий как переключатель, или два отдельных сценария?

9 (изменено: Евген, 2010-10-06 18:51:45)

Re: VBS: Разрешения на папку во вкладке безопасность

1 - XP
2 - Локальные
3 - добавлять дубликат с другой маской
4 - отключать наследование "родителей"
5 - Настройки безопасности наследуются дочерними объектами управляемой папки,распространять внесённые изменения "вниз".
6 - Лучше два...

Заранее благодарен.
Очень выручите...

Времени не хватает... :-(

10 (изменено: Dmitrii, 2010-10-22 15:06:51)

Re: VBS: Разрешения на папку во вкладке безопасность

Евген пишет:

3 - добавлять дубликат с другой маской
4 - отключать наследование "родителей"

При отключенном наследовании добавление дубликата невозможно, т.к. система (при выполнении процедуры упорядочивания ACL) обязательно объединит записи-дубликаты, выполнив соответствующее преобразование маски.

Евген пишет:

5 - Настройки безопасности наследуются дочерними объектами управляемой папки,распространять внесённые изменения "вниз".

При включенном наследовании все изменения распространятся "вниз" автоматически.

Предварительные примечания:
1. Поскольку сразу забыл спросить о том, в каком режиме должны работать сценарии, то выложу GUI-варианты (как более наглядные).
2. Сценарии предполагают возможность работы с некоторыми встроенными системными "учётками" (на всякий случай).
3. Сценарии предполагают возможность добавления указанной "учётки" в ACL, если на момент выполнения настройки безопасности NTFS её там нет.
4. Сценарии ориентированы на использование в русифицированной ОС.

Сценарий 1 - назначение полного доступа:

Dim objWsNet, strDomain, strComputer, strAccount
Dim objShell, objFolder, strPath, xResult

strAccount = InputBox("Имя учётной записи:", "Настройка безопасности NTFS")
If Len(strAccount) > 0 Then
    If StrComp(strAccount, "Система", vbTextCompare) = 0 Then strAccount = "System"
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.BrowseForFolder(0, "Выбор каталога", &h10 + &h200, &h11)
    If Not objFolder Is Nothing Then
        strPath = objFolder.Self.Path
        Set objWsNet = CreateObject("WScript.Network")
        strComputer = objWsNet.ComputerName
        Set objWsNet = Nothing        
        If StrComp(strAccount, "System", vbTextCompare) <> 0 And StrComp(strAccount, "Все", vbTextCompare) <> 0 Then
            strDomain = strComputer
        Else
            strDomain = vbNullString
        End If
        xResult = Set_FullAccess(strDomain, strComputer, strAccount, strPath)
        If IsNumeric(xResult) Then xResult = CStr(xResult)
        Select Case xResult
            Case "-3": Wscript.Echo "Не удалось настроить параметры доступа существующей записи " & UCase(strDomain & "\" & strAccount)
            Case "-2": Wscript.Echo "Не найдена учётная запись объекта " & UCase(strDomain & "\" & strAccount)
            Case "-1": Wscript.Echo "Не удалось отключить наследование безопасности у папки " & UCase(strPath)
            Case "0": Wscript.Echo "Успешное завершение."
            Case "2": Wscript.Echo "Доступ запрещён."
            Case "8": Wscript.Echo "Неизвестная ошибка."
            Case "5", "9": Wscript.Echo "Для выполнения операции недостаточно полномочий."
            Case "21": Wscript.Echo "Заданы недопустимые значения параметров."
            Case Else: WScript.Echo xResult
        End Select
    Else
        WScript.Echo "Каталог не выбран."
    End If
    Set objShell = Nothing
    Set objFolder = Nothing
Else
    WScript.Echo "Учётная запись не указана."
End If
WScript.Quit 0

'======

Function Set_FullAccess(strDom, strComp, strSAN, strDir)
Dim objWMI, objSecSettings, objSD, objACE
Dim xRes, arrACE, objCollection, objItem, strSID
Dim objSID, objTrustee, objNewACE
Dim blnHasACE, i
Const SE_DACL_PROTECTED = 4096
Const ACCESS_ALLOWED_ACE_TYPE = 0
Const FULL_ACCESS = 2032127
'Const READ_WRITE_EXECUTE = 1180095
Const OBJECT_INHERIT_ACE = 1
Const CONTAINER_INHERIT_ACE = 2

On Error Resume Next
xRes = 0
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComp & "\root\cimv2")
If Err.Number = 0 Then
    Set objSecSettings = objWMI.Get("Win32_LogicalFileSecuritySetting.Path='" & strDir & "'")
    If Err.Number = 0 Then
        If objSecSettings.GetSecurityDescriptor(objSD) = 0 Then
            If Not IsNull(objSD.DACL) Then
                If Not CBool(objSD.ControlFlags And SE_DACL_PROTECTED) Then
                    objSD.ControlFlags = objSD.ControlFlags + SE_DACL_PROTECTED
                    xRes = objSecSettings.SetSecurityDescriptor(objSD)
                End If
                If xRes = 0 Then
                    If Len(strDom) > 0 Then
                        Set objCollection = objWMI.ExecQuery("SELECT SID FROM Win32_Account WHERE Domain='" & strDom & "' AND Name='" & strSAN & "'")
                    Else
                        Set objCollection = objWMI.ExecQuery("SELECT SID FROM Win32_Account WHERE Name='" & strSAN & "'")
                    End If
                    If objCollection.Count > 0 Then
                        For Each objItem In objCollection
                            strSID = UCase(objItem.SID)
                        Next
                        Set objItem = Nothing
                        For Each objACE In objSD.DACL
                            If UCase(objACE.Trustee.SIDString) = strSID Then
                                blnHasACE = True
                                objACE.AceType = ACCESS_ALLOWED_ACE_TYPE
                                objACE.AccessMask = FULL_ACCESS
                            End If
                        Next
                        xRes = objSecSettings.SetSecurityDescriptor(objSD)
                        If xRes = 0 Then
                            If Not blnHasACE Then
                                arrACE = objSD.DACL
                                Set objSID = objWMI.Get("Win32_SID.SID='" & strSID & "'")
                                Set objTrustee = objWMI.Get("Win32_Trustee").Spawninstance_()
                                objTrustee.Domain = strDom
                                objTrustee.Name = strSAN
                                objTrustee.SID = objSID.BinaryRepresentation
                                objTrustee.SidLength = objSID.SidLength
                                objTrustee.SIDString = strSID
                                Set objSID = Nothing
                                Set objNewACE = objWMI.Get("Win32_Ace").Spawninstance_()
                                objNewACE.AceType  = ACCESS_ALLOWED_ACE_TYPE
                                objNewACE.AceFlags = OBJECT_INHERIT_ACE + CONTAINER_INHERIT_ACE
                                objNewACE.AccessMask = FULL_ACCESS
                                objNewACE.Trustee = objTrustee
                                Set objTrustee = Nothing
                                i = UBound(arrACE) + 1
                                ReDim Preserve arrACE(i)
                                Set arrACE(i) = objNewACE
                                objSD.DACL = arrACE
                                Set objNewACE = Nothing
                                Erase arrACE
                                xRes = objSecSettings.SetSecurityDescriptor(objSD)
                            End If
                        Else
                            xRes = -3
                        End If
                    Else
                        xRes = -2
                    End If
                    Set objCollection = Nothing
                Else
                    xRes = -1
                End If
            Else
                xRes = "Список управления доступом (ACL) к заданному объекту пуст."
            End If
        Else
            xRes = "Не удалось прочитать дескриптор безопасности объекта."
        End If
        Set objSD = Nothing
        Set objSecSettings = Nothing
    Else
        xRes = "Ошибка " & CStr(Err.Number) & vbNewLine & Err.Description
        Err.Clear
    End If
Else
    xRes = "Ошибка " & CStr(Err.Number) & vbNewLine & Err.Description
    Err.Clear
End If
Set objWMI = Nothing
On Error GoTo 0
Set_FullAccess = xRes
End Function

Сценарий 2 - назначение доступа на чтение, запись, выполнение:

Dim objWsNet, strDomain, strComputer, strAccount
Dim objShell, objFolder, strPath, xResult

strAccount = InputBox("Имя учётной записи:", "Настройка безопасности NTFS")
If Len(strAccount) > 0 Then
    If StrComp(strAccount, "Система", vbTextCompare) = 0 Then strAccount = "System"
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.BrowseForFolder(0, "Выбор каталога", &h10 + &h200, &h11)
    If Not objFolder Is Nothing Then
        strPath = objFolder.Self.Path
        Set objWsNet = CreateObject("WScript.Network")
        strComputer = objWsNet.ComputerName
        Set objWsNet = Nothing        
        If StrComp(strAccount, "System", vbTextCompare) <> 0 And StrComp(strAccount, "Все", vbTextCompare) <> 0 Then
            strDomain = strComputer
        Else
            strDomain = vbNullString
        End If
        xResult = Set_RWEAccess(strDomain, strComputer, strAccount, strPath)
        If IsNumeric(xResult) Then xResult = CStr(xResult)
        Select Case xResult
            Case "-3": Wscript.Echo "Не удалось настроить параметры доступа существующей записи " & UCase(strDomain & "\" & strAccount)
            Case "-2": Wscript.Echo "Не найдена учётная запись объекта " & UCase(strDomain & "\" & strAccount)
            Case "-1": Wscript.Echo "Не удалось отключить наследование безопасности у папки " & UCase(strPath)
            Case "0": Wscript.Echo "Успешное завершение."
            Case "2": Wscript.Echo "Доступ запрещён."
            Case "8": Wscript.Echo "Неизвестная ошибка."
            Case "5", "9": Wscript.Echo "Для выполнения операции недостаточно полномочий."
            Case "21": Wscript.Echo "Заданы недопустимые значения параметров."
            Case Else: WScript.Echo xResult
        End Select
    Else
        WScript.Echo "Каталог не выбран."
    End If
    Set objShell = Nothing
    Set objFolder = Nothing
Else
    WScript.Echo "Учётная запись не указана."
End If
WScript.Quit 0

'======

Function Set_RWEAccess(strDom, strComp, strSAN, strDir)
Dim objWMI, objSecSettings, objSD, objACE
Dim xRes, arrACE, objCollection, objItem, strSID
Dim objSID, objTrustee, objNewACE
Dim blnHasACE, i
Const SE_DACL_PROTECTED = 4096
Const ACCESS_ALLOWED_ACE_TYPE = 0
'Const FULL_ACCESS = 2032127
Const READ_WRITE_EXECUTE = 1180095
Const OBJECT_INHERIT_ACE = 1
Const CONTAINER_INHERIT_ACE = 2
Const INHERITED_ACE = 16

On Error Resume Next
xRes = 0
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComp & "\root\cimv2")
If Err.Number = 0 Then
    Set objSecSettings = objWMI.Get("Win32_LogicalFileSecuritySetting.Path='" & strDir & "'")
    If Err.Number = 0 Then
        If objSecSettings.GetSecurityDescriptor(objSD) = 0 Then
            If Not IsNull(objSD.DACL) Then
                If Not CBool(objSD.ControlFlags And SE_DACL_PROTECTED) Then
                    objSD.ControlFlags = objSD.ControlFlags + SE_DACL_PROTECTED
                    xRes = objSecSettings.SetSecurityDescriptor(objSD)
                End If
                If xRes = 0 Then
                    If Len(strDom) > 0 Then
                        Set objCollection = objWMI.ExecQuery("SELECT SID FROM Win32_Account WHERE Domain='" & strDom & "' AND Name='" & strSAN & "'")
                    Else
                        Set objCollection = objWMI.ExecQuery("SELECT SID FROM Win32_Account WHERE Name='" & strSAN & "'")
                    End If
                    If objCollection.Count > 0 Then
                        For Each objItem In objCollection
                            strSID = UCase(objItem.SID)
                        Next
                        Set objItem = Nothing
                        For Each objACE In objSD.DACL
                            If UCase(objACE.Trustee.SIDString) = strSID Then
                                blnHasACE = True
                                objACE.AceType = ACCESS_ALLOWED_ACE_TYPE
                                objACE.AccessMask = READ_WRITE_EXECUTE
                            End If
                        Next
                        xRes = objSecSettings.SetSecurityDescriptor(objSD)
                        If xRes = 0 Then
                            If Not blnHasACE Then
                                arrACE = objSD.DACL
                                Set objSID = objWMI.Get("Win32_SID.SID='" & strSID & "'")
                                Set objTrustee = objWMI.Get("Win32_Trustee").Spawninstance_()
                                objTrustee.Domain = strDom
                                objTrustee.Name = strSAN
                                objTrustee.SID = objSID.BinaryRepresentation
                                objTrustee.SidLength = objSID.SidLength
                                objTrustee.SIDString = strSID
                                Set objSID = Nothing
                                Set objNewACE = objWMI.Get("Win32_Ace").Spawninstance_()
                                objNewACE.AceType  = ACCESS_ALLOWED_ACE_TYPE
                                objNewACE.AceFlags = OBJECT_INHERIT_ACE + CONTAINER_INHERIT_ACE
                                objNewACE.AccessMask = READ_WRITE_EXECUTE
                                objNewACE.Trustee = objTrustee
                                Set objTrustee = Nothing
                                i = UBound(arrACE) + 1
                                ReDim Preserve arrACE(i)
                                Set arrACE(i) = objNewACE
                                objSD.DACL = arrACE
                                Set objNewACE = Nothing
                                Erase arrACE
                                xRes = objSecSettings.SetSecurityDescriptor(objSD)
                            End If
                        Else
                            xRes = -3
                        End If
                    Else
                        xRes = -2
                    End If
                    Set objCollection = Nothing
                Else
                    xRes = -1
                End If
            Else
                xRes = "Список управления доступом (ACL) к заданному объекту пуст."
            End If
        Else
            xRes = "Не удалось прочитать дескриптор безопасности объекта."
        End If
        Set objSD = Nothing
        Set objSecSettings = Nothing
    Else
        xRes = "Ошибка " & CStr(Err.Number) & vbNewLine & Err.Description
        Err.Clear
    End If
Else
    xRes = "Ошибка " & CStr(Err.Number) & vbNewLine & Err.Description
    Err.Clear
End If
Set objWMI = Nothing
On Error GoTo 0
Set_RWEAccess = xRes
End Function

Сценарий 3 (бонус ) - получение обобщённого полного списка безопасности NTFS указанного каталога (упрощает тестировании предыдущих сценариев):

Dim objWsNet, strComputer
Dim objShell, objFolder, strPath
Dim objWMI, objSecSettings, objSD, objACE
Dim strList, strTemp
Const ACCESS_ALLOWED_ACE_TYPE = &H0
Const ACCESS_DENIED_ACE_TYPE  = &H1
Const INHERITED_ACE = &H10

Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.BrowseForFolder(0, "Выбор каталога", &h10 + &h200, &h11)
If Not objFolder Is Nothing Then
    strPath = objFolder.Self.Path
    Set objWsNet = CreateObject("WScript.Network")
    strComputer = objWsNet.ComputerName
    Set objWsNet = Nothing
    Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set objSecSettings = objWMI.Get("Win32_LogicalFileSecuritySetting.Path='" & strPath & "'")
    If objSecSettings.GetSecurityDescriptor(objSD) = 0 Then
        If Not IsNull(objSD.DACL) Then
            strList = vbNullString
            For Each objACE In objSD.DACL
                If CBool(objACE.AceFlags And INHERITED_ACE) Then
                    strTemp = " - унаследовано; "
                Else
                    strTemp = " - не унаследовано; "
                End If
                If objACE.AceType = ACCESS_ALLOWED_ACE_TYPE Then
                    strTemp = strTemp & "Разрешено с маской"
                Else
                    strTemp = strTemp & "Запрещено с маской"
                End If
                strTemp = strTemp & " -> " & CStr(objACE.AccessMask) & " (&h" & Hex(objACE.AccessMask) & ")"
                strList = strList & objACE.Trustee.Domain & "\" & objACE.Trustee.Name & strTemp & vbNewLine
            Next
            Set objACE = Nothing
            WScript.Echo strList
        Else
            WScript.Echo "Список управления доступом (ACL) к заданному объекту пуст."
        End If
    Else
        WScript.Echo "Не удалось прочитать дескриптор безопасности объекта."
    End If
    Set objSD = Nothing
    Set objSecSettings = Nothing
    Set objWMI = Nothing
Else
    WScript.Echo "Каталог не выбран."
End If
Set objFolder = Nothing
Set objShell = Nothing
WScript.Quit 0

11 (изменено: Евген, 2010-10-08 18:06:10)

Re: VBS: Разрешения на папку во вкладке безопасность

Просто большущее человеческое спасибо !!!

2 Dmitrii я ещё не совсем чётко свою мысль выразил, можно сделать ещё один вариант второго скрипта, который давал бы права только на чтение
и ещё до полной клиники, хотелось бы скрипт который удалял бы имеющегося пользователя из прав на папку (не запрещал доступ - а не давал никаких прав).

2 alexii - обращаюсь к Вам с просьбой занести данные скрипты в Коллекцию !!!

Времени не хватает... :-(

12

Re: VBS: Разрешения на папку во вкладке безопасность

не просче воспользоваться утилитой командной строки ?

Я конечно далек от мысли... (с)

13 (изменено: Евген, 2010-10-08 18:05:19)

Re: VBS: Разрешения на папку во вкладке безопасность

smaharbA пишет:

не просче воспользоваться утилитой командной строки ?

Интересует именно VBS+WMI вариант...

Времени не хватает... :-(

14

Re: VBS: Разрешения на папку во вкладке безопасность

Евген пишет:

2 alexii - обращаюсь к Вам с просьбой занести данные скрипты в Коллекцию !!!

Я обеими руками «за», но ведь коллега Dmitrii сам имеет возможность сделать это. Так что, просим его .

15 (изменено: Евген, 2010-10-08 20:12:29)

Re: VBS: Разрешения на папку во вкладке безопасность

Кстати, нашёл вразумительную статейку MS TechNet'a по поводу использования  Win32_LogicalFileSecuritySetting
Постараюсь сам тоже подтянуться по данной теме.
Ещё раз выражаю коллеге Dmitrii свою признательность, по поводу написанных скриптов, занесите пожалуйста скрипты в коллекцию, им место там.

Времени не хватает... :-(

16

Re: VBS: Разрешения на папку во вкладке безопасность

Евген пишет:

... сделать ещё один вариант второго скрипта, который давал бы права только на чтение...

Я думаю, Вы уже поняли, что и первый, и второй сценарии почти тождественны. Разница между ними лишь в том, какая маска доступа назначается указанной "учётке".
Вы сами без труда получите желаемое, если в качестве значения свойства AccessMask зададите число 1179785 (это и будет "только чтение").

Евген пишет:

... хотелось бы скрипт который удалял бы имеющегося пользователя из прав на папку (не запрещал доступ - а не давал никаких прав).

При отключенном наследовании всё очень просто: назначить маске доступа значение 0. В процессе упорядочения ACL система сама удалит такие записи.
Примечание: обратите внимание на то, что по сравнению с предыдущими вариантами (сценарии 1 и 2) несколько изменилась диагностика ошибок.

Dim objWsNet, strDomain, strComputer, strAccount
Dim objShell, objFolder, strPath, xResult

strAccount = InputBox("Имя учётной записи:", "Настройка безопасности NTFS")
If Len(strAccount) > 0 Then
    If StrComp(strAccount, "Система", vbTextCompare) = 0 Then strAccount = "System"
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.BrowseForFolder(0, "Выбор каталога", &h10 + &h200, &h11)
    If Not objFolder Is Nothing Then
        strPath = objFolder.Self.Path
        Set objWsNet = CreateObject("WScript.Network")
        strComputer = objWsNet.ComputerName
        Set objWsNet = Nothing        
        If StrComp(strAccount, "System", vbTextCompare) <> 0 And StrComp(strAccount, "Все", vbTextCompare) <> 0 Then
            strDomain = strComputer
        Else
            strDomain = vbNullString
        End If
        xResult = Remove_ACE(strDomain, strComputer, strAccount, strPath)
        If IsNumeric(xResult) Then xResult = CStr(xResult)
        Select Case xResult
            Case "-2": Wscript.Echo "Не найдена учётная запись объекта " & UCase(strDomain & "\" & strAccount)
            Case "-1": Wscript.Echo "Не удалось отключить наследование безопасности у папки " & UCase(strPath)
            Case "0": Wscript.Echo "Успешное завершение."
            Case "2": Wscript.Echo "Доступ запрещён."
            Case "8": Wscript.Echo "Неизвестная ошибка."
            Case "5", "9": Wscript.Echo "Для выполнения операции недостаточно полномочий."
            Case "21": Wscript.Echo "Заданы недопустимые значения параметров."
            Case Else: WScript.Echo xResult
        End Select
    Else
        WScript.Echo "Каталог не выбран."
    End If
    Set objShell = Nothing
    Set objFolder = Nothing
Else
    WScript.Echo "Учётная запись не указана."
End If
WScript.Quit 0

'======

Function Remove_ACE(strDom, strComp, strSAN, strDir)
Dim objWMI, objSecSettings, objSD, objACE
Dim xRes, objCollection, objItem, strSID, i
Const SE_DACL_PROTECTED = 4096
Const INHERITED_ACE = 16

On Error Resume Next
xRes = 0
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComp & "\root\cimv2")
If Err.Number = 0 Then
    Set objSecSettings = objWMI.Get("Win32_LogicalFileSecuritySetting.Path='" & strDir & "'")
    If Err.Number = 0 Then
        If objSecSettings.GetSecurityDescriptor(objSD) = 0 Then
            If Not IsNull(objSD.DACL) Then
                If Not CBool(objSD.ControlFlags And SE_DACL_PROTECTED) Then
                    objSD.ControlFlags = objSD.ControlFlags + SE_DACL_PROTECTED
                    xRes = objSecSettings.SetSecurityDescriptor(objSD)
                End If
                If xRes = 0 Then
                    If Len(strDom) > 0 Then
                        Set objCollection = objWMI.ExecQuery("SELECT SID FROM Win32_Account WHERE Domain='" & strDom & "' AND Name='" & strSAN & "'")
                    Else
                        Set objCollection = objWMI.ExecQuery("SELECT SID FROM Win32_Account WHERE Name='" & strSAN & "'")
                    End If
                    If objCollection.Count > 0 Then
                        For Each objItem In objCollection
                            strSID = UCase(objItem.SID)
                        Next
                        Set objItem = Nothing
                        For Each objACE In objSD.DACL
                            If UCase(objACE.Trustee.SIDString) = strSID Then
                                If Not CBool(objACE.AceFlags And INHERITED_ACE) Then
                                    objACE.AccessMask = 0
                                End If
                            End If
                        Next
                        xRes = objSecSettings.SetSecurityDescriptor(objSD)
                    Else
                        xRes = -2
                    End If
                    Set objCollection = Nothing
                Else
                    xRes = -1
                End If
            Else
                xRes = "Список управления доступом (ACL) к заданному объекту пуст."
            End If
        Else
            xRes = "Не удалось прочитать дескриптор безопасности объекта."
        End If
        Set objSD = Nothing
        Set objSecSettings = Nothing
    Else
        xRes = "Ошибка " & CStr(Err.Number) & vbNewLine & Err.Description
        Err.Clear
    End If
Else
    xRes = "Ошибка " & CStr(Err.Number) & vbNewLine & Err.Description
    Err.Clear
End If
Set objWMI = Nothing
On Error GoTo 0
Remove_ACE = xRes
End Function

Предыдущие варианты сценариев поправлю и размещу в коллекции позже. Пока недосуг.

17

Re: VBS: Разрешения на папку во вкладке безопасность

2 Dmitrii большущее спасибо, вопросов больше не имею, для меня тема полностью разобрана.

Времени не хватает... :-(

18 (изменено: Dmitrii, 2010-11-09 18:45:02)

Re: VBS: Разрешения на папку во вкладке безопасность

Dmitrii пишет:

... Предыдущие варианты сценариев поправлю и размещу в коллекции позже.

Наконец-то "дошли руки":
- поправил диагностику ошибок в сценариях 1 и 2;
- поместил в коллекцию: сценарий 3 (в теме коллекции - сценарий 1), его более развитый вариант (в теме коллекции - сценарий 2), универсализированный сценарий изменений DACL (в теме коллекции - сценарий 3).
Тема: VBS+WMI: безопасность NTFS для каталога, DACL (чтение, изменение)

19 (изменено: abasov, 2011-03-05 08:59:11)

Re: VBS: Разрешения на папку во вкладке безопасность

для служб такой же принцип назначения ACL'ов. Т.е. используя SecurityDescriptor в коллекции применяем AccessMask?

20

Re: VBS: Разрешения на папку во вкладке безопасность

abasov пишет:

для служб такой же принцип назначения ACL'ов..?

Да. Вот только методы GetSecurityDescriptor и SetSecurityDescriptor у класса Win32_Service доступны лишь начиная с Win Vista.

21 (изменено: abasov, 2011-03-05 10:43:41)

Re: VBS: Разрешения на папку во вкладке безопасность

Dmitrii пишет:
abasov пишет:

для служб такой же принцип назначения ACL'ов..?

Да. Вот только методы GetSecurityDescriptor и SetSecurityDescriptor у класса Win32_Service доступны лишь начиная с Win Vista.

Значит в XP чтобы назначить права службе я должен редактировать права на ветку реестра, либо sc.exe?
пример:

sc.exe sdset "service" "D:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;DA)(A;;LCSWRPWPDTLOCRRC;;;SY)(A;;CCLCSWRPWPDTLOCRRC;;;LA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)"

Установит: Domain Admins - Full, System - Read, Execute, Local Admin - Read, Execute


Security Descriptor Definition Language (Windows)

22

Re: VBS: Разрешения на папку во вкладке безопасность

abasov пишет:

Значит в XP чтобы назначить права службе я должен редактировать права на ветку реестра, либо sc.exe?..

В общем,- да.
Однако можно попробовать (если есть хотя бы одна станция под ОС версии не ниже Vista) "обойти" непосредственную работу с SDDL:
- сформировать дескриптор безопасности в формате класса Win32_SecurityDescriptor;
- с помощью метода Win32SDToSDDL класса Win32_SecurityDescriptorHelper преобразовать его в формат SDDL;
- передать утилите SC.EXE полученное значение в качестве параметра.

23 (изменено: abasov, 2011-03-05 14:06:30)

Re: VBS: Разрешения на папку во вкладке безопасность

Dmitrii пишет:

передать утилите SC.EXE

Жаль, что нельзя использовать объект в XP, опять ждать обновления своего парка машин. Из своих, рабочих GUI'ёвых средств рекомендую svcadmin.exe (c исходником) из статьи на rsdn. Для анализа очень полезно.

По мере накопления опыта в дальнейшем выкладывайте для семерки код пожалуйста.


Dmitrii пишет:

преобразовать его в формат SDDL

Можно сразу sc.exe sdshow, предварительно сформировать себе шаблон с помощью svcadmin.exe

24

Re: VBS: Разрешения на папку во вкладке безопасность

abasov пишет:

... предварительно сформировать себе шаблон с помощью svcadmin.exe

Можно, конечно, но я подразумевал использование только встроенных инструментов "Окошек".