SO far the ChangeACLS works as it should, because you can verify (by the commented out for loop) that it returns the ACL's of the current users. It's the AddAce function that doesn't work properly yet. Here's the code so far:
Code:
;##################################################### Script #########################################################
$sec = CreateObject("ADsSecurity")
$textusr = "TESTDOMAIN\testuser"
$userdir = "\\PC-TESTDOMAIN-XP-2\d$\TEST"
$filenm = $userdir
$permspart = "add(" + $textusr + ":R)+add(Administrator:F)"
;-- Replace ACL on single file or folder-------
ChangeAcls($filenm, $permspart, "REPLACE", "FOLDER")
;############################################### Functions ##########################################################
FUNCTION ChangeAcls($file, $perms, $redit, $ffolder)
;- Edit ACLS of specified file -----
$ADS_ACETYPE_ACCESS_ALLOWED = 0
$ADS_ACETYPE_ACCESS_DENIED = &1
$ADS_ACEFLAG_INHERIT_ACE = &2
$ADS_ACEFLAG_SUB_NEW = &9
$sd = $sec.GetSecurityDescriptor("FILE://" + $file)
; For Each $ace in $sd.DiscretionaryACL
; ? "Name="$ACE.Trustee
; ? "Type="$ACE.AceType
; ? "Mask="$ACE.AccessMask
; Next
$dacl = $sd.DiscretionaryACL
;if flagged Replace then remove all existing aces from dacl first
IF ucase($redit)="REPLACE"
FOR EACH $existingace IN $dacl
$dacl.removeace($existingace)
NEXT
ENDIF
;break up Perms into individual actions
$cmdarray=split($perms,"+")
For $x = 0 to Ubound($cmdarray)
$tmpvar1=$cmdarray[$x]
IF ucase(left($tmpvar1,3))="DEL"
$aclaction="DEL"
ELSE
$aclaction="ADD"
EndIf
$tmpcmdvar=left($tmpvar1,len($tmpvar1)-1)
$tmpcmdvar=right($tmpcmdvar,len($tmpcmdvar)-4)
$cmdparts=split($tmpcmdvar,":")
$namevar=$cmdparts[0]
$rightvar=$cmdparts[1]
; if flagged edit, delete ACE;s belonging to user about to add an ace for
IF ucase($redit)="EDIT"
FOR EACH $existingAce IN $dacl
$trusteevar=$existingAce.trustee
IF instr($trusteeVar,"\")
$trunamevar=right($trusteevar,len($trusteevar)-instr($trusteevar,"\"))
ELSE
$trunamevar=$trusteevar
ENDIF
$uctrunamevar=ucase($trunamevar)
$ucnamevar=ucase($namevar)
IF $uctrunamevar=$ucnamevar
$dacl.removeace($existingace)
ENDIF
NEXT
ENDIF
; if action is to del ace then following clause skips addace
IF $aclaction="ADD"
IF ucase($ffolder)="FOLDER"
; folders require 2 aces for user (to do with inheritance)
addace($dacl, $namevar, $rightvar, $ADS_ACETYPE_ACCESS_ALLOWED, $ADS_ACEFLAG_SUB_NEW)
addace($dacl, $namevar, $rightvar, $ADS_ACETYPE_ACCESS_ALLOWED, $ADS_ACEFLAG_INHERIT_ACE)
ELSE
addace($dacl, $namevar, $rightvar, $ADS_ACETYPE_ACCESS_ALLOWED, &0)
ENDIF
ENDIF
NEXT
; FOR EACH $ace IN $dacl
; ; for some reason if ace includes "NT AUTHORITY" then existing ace does not get readded to dacl
; IF instr(ucase($ace.trustee),"NT AUTHORITY\")
; $newtrustee=right($ace.trustee, len($ace.trustee)-instr($ace.trustee,"\"))
; $ace.trustee=newtrustee
; ENDIF
; NEXT
; final sets and cleanup
; $sd.discretionaryacl = $dacl
; $sec.setsecuritydescriptor $sd
; $sd=""
$dacl=""
; $sec=""
ENDFUNCTION
FUNCTION addace($dacl, $trustee, $maskvar, $acetype, $aceflags)
; add ace to the specified dacl
$ADS_RIGHT_GENERIC_READ = &80000000
$ADS_RIGHT_GENERIC_EXECUTE = &20000000
$ADS_RIGHT_GENERIC_WRITE = &40000000
$ADS_RIGHT_DELETE = &10000
$ADS_RIGHT_GENERIC_ALL = &10000000
$ADS_RIGHT_WRITE_DAC = &40000
$ADS_RIGHT_WRITE_OWNER = &80000
$ADS_ACEFLAG_UNKNOWN = &1
$ADS_ACEFLAG_INHERITED_ACE = &10
$ADS_ACETYPE_ACCESS_ALLOWED = 0
$ace = CreateObject("AccessControlEntry")
$ace.trustee = $trustee
$case = ucase($maskvar)
SELECT
; CASE
; ucase($maskvar)
; specified rights so far only include FC & R. Could be expanded though
CASE ($case = "F")
$ace.AccessMask = $ADS_RIGHT_GENERIC_ALL
CASE ($case = "C")
$ace.AccessMask = $ADS_RIGHT_GENERIC_READ OR $ADS_RIGHT_GENERIC_WRITE OR $ADS_RIGHT_GENERIC_EXECUTE OR $ADS_RIGHT_DELETE
CASE ($case = "R")
$ace.AccessMask = $ADS_RIGHT_GENERIC_READ OR $ADS_RIGHT_GENERIC_EXECUTE
CASE ($case = "E")
$ace.AccessMask = $ADS_RIGHT_GENERIC_EXECUTE
ENDSELECT
$ace.AccessMask = &80000
$ace.AceType = $acetype
$ace.AceFlags = $aceflags
$dacl.AddAce($ace)
ReorderDacl($dacl)
$sd.DiscretionaryAcl = $dacl
$sec.SetSecurityDescriptor($sd)
ENDFUNCTION
Function ReorderDacl($dacl)
$newdacl = CreateObject("AccessControlList")
$ImpDenyDacl = CreateObject("AccessControlList")
$InheritedDacl = CreateObject("AccessControlList")
$ImpAllowDacl = CreateObject("AccessControlList")
$InhAllowDacl = CreateObject("AccessControlList")
$ImpDenyObjectDacl = CreateObject("AccessControlList")
$ImpAllowObjectDacl = CreateObject("AccessControlList")
For Each $ace In $dacl
If (($ace.AceFlags AND $ADS_ACEFLAG_INHERITED_ACE) = $ADS_ACEFLAG_INHERITED_ACE)
$InheritedDacl.AddAce($ace)
Else
Select Case ace.AceType
Case $ADS_ACETYPE_ACCESS_ALLOWED
$ImpAllowDacl.AddAce($ace)
Case $ADS_ACETYPE_ACCESS_DENIED
$ImpDenyDacl.AddAce($ace)
Case $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
$impAllowObjectDacl.AddAce($ace)
Case $ADS_ACETYPE_ACCESS_DENIED_OBJECT
$ImpDenyObjectDacl.AddAce($ace)
EndSelect
EndIf
Next
For Each $ace In $ImpDenyDacl
$newdacl.AddAce($ace)
Next
For Each $ace In $ImpDenyObjectDacl
$newdacl.AddAce($ace)
Next
For Each $ace In $ImpAllowDacl
$newdacl.AddAce($ace)
Next
For Each $ace In $impAllowObjectDacl
$newdacl.AddAce($ace)
Next
For Each $ace In $InheritedDacl
$newdacl.AddAce($ace)
Next
$InheritedDacl = ""
$ImpAllowDacl = ""
$ImpDenyObjectDacl = ""
$ImpDenyDacl = ""
$newdacl.AclRevision = $dacl.AclRevision
$dacl = ""
$dacl = $newdacl
EndFunction