<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; VBS & WMI: замена объекта класса Win32_Truste в DACL каталога]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=7749&amp;type=atom" />
	<updated>2012-11-01T12:44:38Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=7749</id>
		<entry>
			<title type="html"><![CDATA[VBS & WMI: замена объекта класса Win32_Truste в DACL каталога]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=65307#p65307" />
			<content type="html"><![CDATA[<p>Продолжение темы <a href="http://forum.script-coding.com/viewtopic.php?id=5142">VBS &amp; WMI: безопасность NTFS для каталога, DACL (чтение, изменение)</a>.</p><p><strong>Сценарий 6.<br />Замена объекта класса &quot;Win32_Trustee&quot; в списке управления доступом NTFS (DACL) заданного каталога текущего компьютера <span style="color: green">с сохранением настроек, унаследованных от &quot;родителя&quot;</span>.</strong></p><p>Смысловое назначение сценария состоит в том, чтобы удалить текущую привязку записи DACL к некоторой пользовательской учётной записи, а затем привязать эту же запись DACL к другой пользовательской учётной записи. При этом тип, область действия и маска доступа записи DACL не изменяются.<br />Результат работы сценария аналогичен результату процедуры удаления некоторой записи DACL, а затем создания такой же по типу, области действия и маске доступа записи DACL, но соответствующей иной учётной записи пользователя.</p><p>Предполагается, что участвующие в процедуре пользовательские учётные записи, во-первых, являются доменными, во-вторых, принадлежат одному и тому же домену.<br />Сценарий способен работать и в графическом, и в консольном режимах.<br /></p><div class="codebox"><pre><code>Dim objWsNet, objFS, objWMI
Dim strDomain, strBaseFolder, blnContinue, xResult
Dim strAccountOld, strSIDOld, strAccountNew, strSIDNew

strAccountOld = &quot;user1&quot;: strAccountNew = &quot;user2&quot;
strBaseFolder = &quot;C:\Temp&quot;
Set objWsNet = CreateObject(&quot;WScript.Network&quot;)
strDomain = objWsNet.UserDomain
Set objWsNet = Nothing
Set objFS = CreateObject(&quot;Scripting.FileSystemObject&quot;)
On Error Resume Next
Set objWMI = GetObject(&quot;winmgmts:\\.\root\cimv2&quot;)
If Err.Number = 0 Then
    If objFS.FolderExists(strBaseFolder) Then
        If StrComp(strDomain &amp; &quot;\&quot; &amp; strAccountOld, strDomain &amp; &quot;\&quot; &amp; strAccountNew, vbTextCompare) &lt;&gt; 0 Then
            Set objAccount = objWMI.Get(&quot;Win32_UserAccount.Domain=&#039;&quot; &amp; strDomain &amp; &quot;&#039;,Name=&#039;&quot; &amp; strAccountOld &amp; &quot;&#039;&quot;)
            If Err.Number = 0 Then
                strSIDOld = UCase(objAccount.SID)
                Set objAccount = objWMI.Get(&quot;Win32_UserAccount.Domain=&#039;&quot; &amp; strDomain &amp; &quot;&#039;,Name=&#039;&quot; &amp; strAccountNew &amp; &quot;&#039;&quot;)
                If Err.Number = 0 Then
                    strSIDNew = UCase(objAccount.SID)
                    xResult = Change_Trustee(objWMI, strDomain, strAccountOld, strSIDOld, strAccountNew, strSIDNew, strBaseFolder)
                    WScript.Echo strAccountOld &amp; &quot; &lt;-&gt; &quot; &amp; strAccountNew &amp; &quot;: &quot; &amp; xResult
                Else
                    WScript.Echo strAccountNew &amp; &quot; -&gt; не найдена учётная запись объекта&quot;
                End If
            Else
                WScript.Echo strAccountOld &amp; &quot; -&gt; не найдена учётная запись объекта&quot;
                Err.Clear
            End If
            Set objAccount = Nothing
        Else
            WScript.Echo strAccountOld &amp; &quot; &lt;-&gt; &quot; &amp; strAccountNew &amp; &quot;: бессмысленная операция&quot;
        End If
    Else
        WScript.Echo &quot;Не найден путь &quot; &amp; UCase(strBaseFolder)
    End If
Else
    WScript.Echo &quot;Ошибка &quot; &amp; Err.Number &amp; &quot; при подключении к WMI-пространству&quot; &amp; vbNewLine &amp; Err.Description
    Err.Clear
End If
Set objWMI = Nothing
Set objFS = Nothing
WScript.Quit 0

&#039;======

Function Change_Trustee(objWMIServ, strDom, strSAN1, strSID1, strSAN2, strSID2, strDir)
Dim objSecSettings, objSD, objItem, blnHasInherited
Dim objSID, objTrustee, arrACE, arrLines, xRes, i, j
Const SE_DACL_PROTECTED = 4096 &#039;Флаг-признак отключенного режима наследования управляемым каталогом безопасности NTFS от &quot;родителя&quot;
Const INHERITED_ACE = 16 &#039;Флаг-признак того, что текущая запись DACL унаследована от &quot;родителя&quot;

On Error Resume Next
xRes = 0
Set objSecSettings = objWMIServ.Get(&quot;Win32_LogicalFileSecuritySetting.Path=&#039;&quot; &amp; strDir &amp; &quot;&#039;&quot;)
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 blnHasInherited = True
            arrACE = Array(): i = -1: arrLines = Array(): j = -1
            &#039;--- Выборка из исходного DACL записей, не унаследованных от &quot;родителя&quot;,
            &#039;и поиск среди них (по SID) тех, которые привязаны к заменяемой пользовательской &quot;учётке&quot;
            For Each objItem In objSD.DACL
                If Not CBool(objItem.AceFlags And INHERITED_ACE) Then
                    If UCase(objItem.Trustee.SIDString) = strSID1 Then
                        j = j + 1
                        ReDim Preserve arrLines(j)
                        arrLines(j) = i + 1
                    End If
                    i = i + 1
                    ReDim Preserve arrACE(i)
                    Set arrACE(i) = objItem
                End If
            Next
            Set objItem = Nothing
            &#039;------
            If j &gt;= 0 Then
                If blnHasInherited Then
                    &#039;--- Отключение наследования настроек безопасности от &quot;родителя&quot;
                    objSD.ControlFlags = objSD.ControlFlags + SE_DACL_PROTECTED
                    xRes = objSecSettings.SetSecurityDescriptor(objSD)
                    &#039;------
                End If
                If xRes = 0 Then
                    &#039;--- Создание экземпляра класса &quot;Win32_Trustee&quot;,
                    &#039;привязанного к заменяющей пользовательской &quot;учётке&quot;
                    Set objSID = objWMI.Get(&quot;Win32_SID.SID=&#039;&quot; &amp; strSID2 &amp; &quot;&#039;&quot;)
                    Set objTrustee = objWMIServ.Get(&quot;Win32_Trustee&quot;).Spawninstance_
                    objTrustee.Domain = strDom
                    objTrustee.Name = strSAN2
                    objTrustee.SID = objSID.BinaryRepresentation
                    objTrustee.SidLength = objSID.SidLength
                    objTrustee.SIDString = strSID2
                    Set objSID = Nothing
                    &#039;------
                    &#039;--- Замена объекта класса &quot;Win32_Trustee&quot; у обрабатываемых записей DACL
                    For j = 0 To UBound(arrLines)
                        arrACE(arrLines(j)).Trustee = objTrustee
                    Next
                    &#039;------
                    objSD.DACL = arrACE &#039;собственно изменение DACL
                    Erase arrACE: Erase arrLines
                    &#039;--- Включение наследования настроек безопасности от &quot;родителя&quot;, если первоначально оно было включено
                    If blnHasInherited Then objSD.ControlFlags = objSD.ControlFlags - SE_DACL_PROTECTED
                    &#039;------
                    &#039;--- Итоговое сохраненение изменений, внесённых в дескриптор безопасности
                    xRes = objSecSettings.SetSecurityDescriptor(objSD)
                    Select Case xRes
                        Case 0: xRes = &quot;успешное завершение&quot;
                        Case 2: xRes = &quot;не удалось сохранить изменения DACL (доступ запрещён)&quot;
                        Case 5, 9: xRes = &quot;не удалось сохранить изменения DACL (для выполнения операции недостаточно полномочий)&quot;
                        Case 21: xRes = &quot;не удалось сохранить изменения DACL (заданы недопустимые значения параметров)&quot;
                        Case Else: xRes = &quot;не удалось сохранить изменения DACL (неизвестная ошибка)&quot;
                    End Select
                    &#039;------
                Else
                    xRes = &quot;не удалось отключить наследование безопасности&quot;
                End If
            Else
                xRes = &quot;не обнаружено не унаследованных записей исходного объекта&quot;
            End If
            Set objTrustee = Nothing
        Else
            xRes = &quot;список управления доступом пуст&quot;
        End If
    Else
        xRes = &quot;не удалось прочитать дескриптор безопасности объекта&quot;
    End If
    Set objSD = Nothing
    Set objSecSettings = Nothing
Else
    xRes = &quot;ошибка &quot; &amp; CStr(Err.Number) &amp; vbNewLine &amp; Err.Description
    Err.Clear
End If
On Error GoTo 0
Change_Trustee = xRes
End Function</code></pre></div><p>Примечания.<br />1. Работа сценария проверена в 32-битных версиях: 2000 Pro. + SP4/XP Pro. + SP3/2008 Std. + SP2/7 Pro. + SP1<br />2. Сценарий ориентирован на использование в русифицированных ОС.</p>]]></content>
			<author>
				<name><![CDATA[Dmitrii]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=13351</uri>
			</author>
			<updated>2012-11-01T12:44:38Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=65307#p65307</id>
		</entry>
</feed>
