﻿<?xml version="1.0" encoding="utf-8"?>
<!--
This XML document provides a sample Opertaing System Configuration Item that works with Desired Configuration Management (DCM) feature
in System Center Configuration Manager 2007.

The sample configuration item shows how to use DCM scripting capability and sysinternals tool, accesschk.exe, to collect
security configuration data, user right privilege, from Local Security Authority store.

The sample configuration item is authored against Windows Vista SP1 and
OperatingSystemDiscoveryInfo needs change to work with other Windows operating systems.

-->
<DesiredConfigurationDigest xmlns="http://schemas.microsoft.com/SystemsCenterConfigurationManager/2006/03/24/DesiredConfiguration">
  <OperatingSystem AuthoringScopeId="Microsoft.SolutionAccelerator.SecurityCompliance" LogicalName="OperatingSystem_2DF3A4D0-E9E0-457B-AB1A-11509FF7CC70" Version="1">
    <Annotation>
      <DisplayName Text="User Rights Assignment" ResourceId="ID-714A9934-86F9-4C03-9B80-AE6E1014A269" />
      <Description Text="The security options CI contains the settings which control  the security of the computer policies of; allow access from the network, act as part of the operating system, add workstations to the domain, adjust memory quota, change system time and a larger number of others." ResourceId="ID-A35CBBEC-AB72-4A71-92A3-CA85E1D77041" />
    </Annotation>
    <Parts>
      <ParentReferences />
    </Parts>
    <Settings>
      <RootComplexSetting>
        <SimpleSetting LogicalName="CCE-532_BEC4730A-856D-4F51-9687-81BD224AD7DD" DataType="String">
          <Annotation>
            <DisplayName Text="Access this computer from the network" ResourceId="ID-85EAEBD3-EBB1-4FAF-859C-CEC2097F3D56" />
            <Description Text="This setting allows other users on the network to connect to the computer." ResourceId="ID-B9D23530-BFD5-4496-8B12-A2E35FB8DE3A" />
          </Annotation>
          <ExistentialRule Operation="GreaterThan" OperandA="0" OperandB="" Severity="Informational">
            <Annotation>
              <DisplayName Text="Access this computer from the network" />
              <Description Text="Required by various network protocols that include Server Message Block (SMB)–based protocols, NetBIOS, Common Internet File System (CIFS), and Component Object Model Plus (COM+)." />
            </Annotation>
          </ExistentialRule>
          <ScriptDiscoverySource ScriptType="VBScript">
            <!--
This sample setting uses SeNetworkLogonRight user right privilege as example, it can work with other user right privileges listed
below with one line modification (call ValidateSetting with selected user right privilege flag),

  SeCreateTokenPrivilege
  SeAssignPrimaryTokenPrivilege
  SeLockMemoryPrivilege
  SeIncreaseQuotaPrivilege
  SeMachineAccountPrivilege
  SeTcbPrivilege
  SeSecurityPrivilege
  SeTakeOwnershipPrivilege
  SeLoadDriverPrivilege
  SeSystemProfilePrivilege
  SeSystemtimePrivilege
  SeProfileSingleProcessPrivilege
  SeIncreaseBasePriorityPrivilege
  SeCreatePagefilePrivilege
  SeCreatePermanentPrivilege
  SeBackupPrivilege
  SeRestorePrivilege
  SeShutdownPrivilege
  SeDebugPrivilege
  SeAuditPrivilege
  SeSystemEnvironmentPrivilege
  SeChangeNotifyPrivilege
  SeRemoteShutdownPrivilege
  SeUndockPrivilege
  SeSyncAgentPrivilege
  SeEnableDelegationPrivilege
  SeManageVolumePrivilege
  SeImpersonatePrivilege
  SeCreateGlobalPrivilege
  SeTrustedCredManAccessPrivilege
  SeRelabelPrivilege
  SeIncreaseWorkingSetPrivilege
  SeTimeZonePrivilege
  SeCreateSymbolicLinkPrivilege
  SeBatchLogonRight
  SeInteractiveLogonRight
  SeServiceLogonRight
  
This sample setting use DCM scripting feature. The rule validation works against only "allow" logic.
In case of "deny" logic, refer the script in another sample setting

            -->
            <ScriptBody>
              option explicit

              WScript.Echo ValidateSetting("SeNetworkLogonRight", "Everyone,Administrators,Authenticated Users,ENTERPRISE DOMAIN CONTROLLERS,Pre-Windows 2000 Compatible Access")

              Function ValidateSetting(userRightProperty, baselineValue)

              on error resume next

              ' Get expected values and actual valuse we are testing against
              Dim ExpectedValues, ActualValues
              ExpectedValues = baselineValue

              ' Poll LSA data through accesschk
              ActualValues = PollAccessChkForSettings (userRightProperty)
              if ActualValues = "" then
              ' below line assumes DCM rule value (OperandA) is "NO ONE" if no one is allowed for the user right privilege
              ActualValues = "NO ONE"
              end if

              ' do our validation
              ValidateSetting = ValidateResults(ExpectedValues, ActualValues)

              ' do error checking, make sure our function return something.
              If ValidateSetting = "" Then
              ValidateSetting = "ValidateSetting return Nothing or Empty"
              If Err.Number &lt;&gt; 0 Then
              ValidateSetting = ValidateSetting &amp; ", Error: " &amp; Err.Number
              ValidateSetting = ValidateSetting &amp; ", Error (Hex): " &amp; Hex(Err.Number)
              ValidateSetting = ValidateSetting &amp; ", Source: " &amp;  Err.Source
              ValidateSetting = ValidateSetting &amp; ", Description: " &amp;  Err.Description
              Err.Clear
              End If
              End If

              End Function


              ' Validate results
              Function ValidateResults(ExpectedValues, ActualValues)

              on error resume next

              ' We are always in compliant if no one has the privilege
              If UCase(Trim(ActualValues)) = "NO ONE" Then
              ValidateResults = ExpectedValues
              Exit Function
              End If

              ' Everify that the actual list of users is a sub-set of the expected list of users.
              Dim ActualValueList, ExpectedValueList, ActualValue, ExpectedValue, Result
              ActualValueList = Split(UCase(ActualValues), ",")
              ExpectedValueList = Split(UCase(ExpectedValues), ",")

              ' Verify all the actual users are in the list of expected users
              For Each ActualValue in ActualValueList
              ' Find if actual value is in list of expected values
              Result = false
              For Each ExpectedValue in ExpectedValueList
              If Trim(ActualValue) = Trim(ExpectedValue) Then
              Result = true
              Exit For
              End If
              Next

              If Result = false Then
              ValidateResults = ActualValues
              Exit Function
              End If
              Next

              ' Passsed all tests
              ValidateResults = ExpectedValues

              End Function


              ' Set ActualValues to a comma deliminated list of values defined by what settings we are polling.
              Function PollAccessChkForSettings(userRightProperty)

              on error resume next

              Dim Result, timeout, accountArray, objWshell, oExec

              Set objWshell = WScript.CreateObject("WScript.Shell")
              Set oExec = objWshell.Exec("accesschk.exe -a " &amp; userRightProperty)

              If oExec is Nothing Then
              PollAccessChkForSettings = "ERROR: objWshell.Exec return null, please check if accesschk.exe exists."

              Exit Function
              End if

              ' Wait for program to finish
              timeout = 200
              Do While oExec.Status = 0 And timeout &gt; 0
              WScript.Sleep 10
              timeout = timeout - 1
              Loop

              If oExec.Status = 0 Then
              PollAccessChkForSettings = "ERROR: Timed Out"
              Exit Function
              Else
              Result = oExec.StdOut.ReadAll
              If Result = "" Then
              PollAccessChkForSettings = "ERROR: Get Data Failed"
              Exit Function
              Else

              ' not found any valid data
              If InStr(Result, "No more data is available") &gt; 0 Then
              PollAccessChkForSettings = ""
              Exit Function
              End If

              ' concat the account to a string with comma delimiter
              Dim i, value
              accountArray = Split(Result, vbCrlf)
              For i = 0 To UBound(accountArray) - 1

              If PollAccessChkForSettings &lt;&gt; "" Then
              PollAccessChkForSettings = PollAccessChkForSettings + ","
              End If

              value = Replace(accountArray(i), Chr(9), "")
              value = Trim(value)

              Dim j
              j = InStrRev(value, "\")
              If j = 0 Then
              PollAccessChkForSettings = PollAccessChkForSettings +  UCase(value)
              Else
              PollAccessChkForSettings = PollAccessChkForSettings +  UCase(Right(value, Len(value) - j))
              End if

              Next
              'WScript.Echo PollAccessChkForSettings

              End If
              End If

              End Function
            </ScriptBody>
          </ScriptDiscoverySource>
          <Rules>
            <Rule LogicalName="Rule_5C86F6E9-5AFA-44BA-9725-2DD5DA123DF2" Operation="Equals" OperandA="BUILTIN\Administrators,BUILTIN\Users" OperandB="" Severity="Informational">
              <Annotation>
                <DisplayName Text="Access this computer from the network" ResourceId="ID-6BA36154-B2B6-40ED-B6CB-9E8E6D91ADEC" />
                <Description Text="Required by various network protocols that include Server Message Block (SMB)–based protocols, NetBIOS, Common Internet File System (CIFS), and Component Object Model Plus (COM+)." ResourceId="ID-1F0D2773-40A9-4D11-BE56-8ECCE9F920BD" />
              </Annotation>
            </Rule>
          </Rules>
        </SimpleSetting>
        <SimpleSetting LogicalName="CCE-165_FE56116A-51EA-40D7-97CD-D233D9233B25" DataType="String">
          <Annotation>
            <DisplayName Text="Deny logon as a batch job" ResourceId="ID-C4B8C9B2-396F-41CD-90BB-A55C01FBBE1F" />
            <Description Text="This policy setting determines which accounts will not be able to log on to the computer as a batch job." ResourceId="ID-8FCB8DC8-6764-4668-A8FA-073E7C5C2B4D" />
          </Annotation>
          <ExistentialRule Operation="GreaterThan" OperandA="0" OperandB="" Severity="Informational">
            <Annotation>
              <DisplayName Text="Deny logon as a batch job" />
              <Description Text="The Deny log on as a batch job user right overrides the Log on as a batch job user right, which could be used to allow accounts to schedule jobs that consume excessive system resources. " />
            </Annotation>
          </ExistentialRule>
          <ScriptDiscoverySource ScriptType="VBScript">
            <!--
This sample setting uses SeDenyBatchLogonRight user right privilege as example, it can work with other user right privileges listed
below with one line modification (call ValidateSetting with selected user right privilege flag),

  SeDenyInteractiveLogonRight
  SeDenyNetworkLogonRight
  SeDenyServiceLogonRight
  
This sample configuration item use DCM scripting feature. The rule validation works against only "deny" logic.
In case of "allow" logic, refer the script in another sample setting

            -->
            <ScriptBody>
              option explicit

              WScript.Echo ValidateSetting("SeDenyBatchLogonRight", "Everyone")

              Function ValidateSetting(userRightProperty, baselineValue)

              on error resume next

              ' Get expected values and actual valuse we are testing against
              Dim ExpectedValues, ActualValues
              ExpectedValues = baselineValue

              ' Poll LSA data through accesschk
              ActualValues = PollAccessChkForSettings (userRightProperty)
              if ActualValues = "" then
              ' below line assumes DCM rule value (OperandA) is "NO ONE" if no one is allowed for the user right privilege
              ActualValues = "NO ONE"
              end if

              ' do our validation
              ValidateSetting = ValidateResults(ExpectedValues, ActualValues)

              ' do error checking, make sure our function return something.
              If ValidateSetting = "" Then
              ValidateSetting = "ValidateSetting return Nothing or Empty"
              If Err.Number &lt;&gt; 0 Then
              ValidateSetting = ValidateSetting &amp; ", Error: " &amp; Err.Number
              ValidateSetting = ValidateSetting &amp; ", Error (Hex): " &amp; Hex(Err.Number)
              ValidateSetting = ValidateSetting &amp; ", Source: " &amp;  Err.Source
              ValidateSetting = ValidateSetting &amp; ", Description: " &amp;  Err.Description
              Err.Clear
              End If
              End If

              End Function


              ' Validate results
              Function ValidateResults(ExpectedValues, ActualValues)

              on error resume next

              ' We are always in compliant if expected no one has been denied the privilege
              If UCase(Trim(ExpectedValues)) = "NO ONE" Then
              ValidateResults = ExpectedValues
              Exit Function
              End If

              ' We are always not in compliant if no one has been denied the privilege but expected someones.
              If UCase(Trim(ActualValues)) = "NO ONE" Then
              ValidateResults = ActualValues
              Exit Function
              End If

              ' Everify that the expected list of users is a sub-set of the actual list of users.
              Dim ActualValueList, ExpectedValueList, ActualValue, ExpectedValue, Result
              ActualValueList = Split(UCase(ActualValues), ",")
              ExpectedValueList = Split(UCase(ExpectedValues), ",")

              ' Verify all the expected users are in the list of actual users
              For Each ExpectedValue in ExpectedValueList
              ' Find if expected value is in list of actual values
              Result = false
              For Each ActualValue in ActualValueList
              If Trim(ActualValue) = Trim(ExpectedValue) Then
              Result = true
              Exit For
              End If
              Next

              If Result = false Then
              ValidateResults = ActualValues
              Exit Function
              End If
              Next

              ' Passsed all tests
              ValidateResults = ExpectedValues

              End Function


              ' Set ActualValues to a comma deliminated list of values defined by what settings we are polling.
              Function PollAccessChkForSettings(userRightProperty)

              on error resume next

              Dim Result, timeout, accountArray, objWshell, oExec

              Set objWshell = WScript.CreateObject("WScript.Shell")
              Set oExec = objWshell.Exec("accesschk.exe -a " &amp; userRightProperty)

              If oExec is Nothing Then
              PollAccessChkForSettings = "ERROR: objWshell.Exec return null, please check if accesschk.exe exists."

              Exit Function
              End if

              ' Wait for program to finish
              timeout = 200
              Do While oExec.Status = 0 And timeout &gt; 0
              WScript.Sleep 10
              timeout = timeout - 1
              Loop

              If oExec.Status = 0 Then
              PollAccessChkForSettings = "ERROR: Timed Out"
              Exit Function
              Else
              Result = oExec.StdOut.ReadAll
              If Result = "" Then
              PollAccessChkForSettings = "ERROR: Get Data Failed"
              Exit Function
              Else

              ' not found any valid data
              If InStr(Result, "No more data is available") &gt; 0 Then
              PollAccessChkForSettings = ""
              Exit Function
              End If

              ' concat the account to a string with comma delimiter
              Dim i, value
              accountArray = Split(Result, vbCrlf)
              For i = 0 To UBound(accountArray) - 1

              If PollAccessChkForSettings &lt;&gt; "" Then
              PollAccessChkForSettings = PollAccessChkForSettings + ","
              End If

              value = Replace(accountArray(i), Chr(9), "")
              value = Trim(value)

              Dim j
              j = InStrRev(value, "\")
              If j = 0 Then
              PollAccessChkForSettings = PollAccessChkForSettings +  UCase(value)
              Else
              PollAccessChkForSettings = PollAccessChkForSettings +  UCase(Right(value, Len(value) - j))
              End if

              Next
              'WScript.Echo PollAccessChkForSettings

              End If
              End If

              End Function
            </ScriptBody>
          </ScriptDiscoverySource>
          <Rules>
            <Rule LogicalName="Rule_816ED5A6-D14C-4D5B-9CDA-87131019CC86" Operation="Equals" OperandA="NT AUTHORITY\NETWORK SERVICE,NT AUTHORITY\LOCAL SERVICE" OperandB="" Severity="Informational">
              <Annotation>
                <DisplayName Text="Deny logon as a batch job" ResourceId="ID-8022010F-F700-4239-A3D7-1666C48019B6" />
                <Description Text="The Deny log on as a batch job user right overrides the Log on as a batch job user right, which could be used to allow accounts to schedule jobs that consume excessive system resources." ResourceId="ID-397C6434-A1E2-4516-9E3B-12D4B3EC2FFF" />
              </Annotation>
            </Rule>
          </Rules>
        </SimpleSetting>
      </RootComplexSetting>
    </Settings>
    <OperatingSystemDiscoveryInfo BuildVersion="6001" MajorVersion="6" MinorVersion="0" />
  </OperatingSystem>
</DesiredConfigurationDigest>