Arend_
(MM club member)
2005-01-17 09:04 AM
VBS to Kix translation

Hi,

I have been trying to translate a VBS script provided by Microsoft for ADsSecurity.dll to Kix but have been unsuccessfull for over a month now. Could anyone help me translating this script: How To Use ADsSecurity.dll to Add an Access Control Entry to an NTFS Folder

At this point I want to thank the board members for providing information about problems. It helped me alot in earlier stages.


LonkeroAdministrator
(KiX Master Guru)
2005-01-17 12:50 PM
Re: VBS to Kix translation

this looks familiar.
iirc, it was never successfull translating this.


Arend_
(MM club member)
2005-01-17 03:56 PM
Re: VBS to Kix translation

Thats bad news, after months of research this was the only solution I could find that let's me remotely add users to folder rights.

I've made a kix script with a GUI thx to KixForms that let's administrators on our networks create new users but the only thing that isn't working is to set the rights of the profile folder to both the user and administrator as full access. After alot of trial and error eventually I stumbled onto this VBS script and was unsuccesfull translating it to kix. So I came here as a last hope.

Anyway thank you for your quick reply I apreciate it


LonkeroAdministrator
(KiX Master Guru)
2005-01-17 04:39 PM
Re: VBS to Kix translation

well.
I never set the folder rights, as I don't see the point.
and for sharing, I use rmtshare which also allows you to set the permissions.
or you could go with win32admin -> http://home.comcast.net/~habullock/kix_solutions.htm


Arend_
(MM club member)
2005-01-17 04:56 PM
Re: VBS to Kix translation

The reason I do this is because the administrator and the user both must have read/write access to the Profile folder, if kix makes the folder only the administrator has access and not the user. And if I dont use kix to make the folder the folder is created by AD as soon as the user logs in but then the administrator has no access to the folder. The administrator needs access to the folder because he will run other scripts to backup profiles weekly to an external HDD. Which is why I need both to have read/write access. The folder itself isn't shared tho. The hierarchy is like this:
@lserver\personal$\%username%\My Profile\
@lserver\personal$\%username%\My Documents\
@lserver\personal$\%username%\My Mail\

The AdsSecurity.dll does just that. Which is why I need that script to work or at least a script for the AdsSecurity.dll that lets me set folder permissions like that VBS script does. So I hope I've shed some light on the subject as to why I need both to have folder permissions.



Sealeopard
(KiX Master)
2005-01-17 07:07 PM
Re: VBS to Kix translation

Thre are enough tools out there that set file/folder-level permissions, e.g. XCACLS.EXE. Search the BBS for related threads. There are also tools/utilities/ways/USDs to remotley execute CLIs. Again, search the BBS as this has been discussed multiple times.

Mart
(KiX Supporter)
2005-01-17 10:19 PM
Re: VBS to Kix translation

Apronk,

Good to see another dutchie on the board.

Just a little side step from the original topic.

Using a hidden share could give you problems (at least i've had enough troubles with it) because the $ symbol is ussed for variables by kix.
More info here: http://www.kixtart.org/ubbthreads/showflat.php?Cat=&Number=81652&page=1&view=collapsed&sb=5&o=&fpart=1



Sealeopard
(KiX Master)
2005-01-17 10:51 PM
Re: VBS to Kix translation

The '$' sign only causes problems if one doesn't follow the KiXtart syntax guidelines or doesn't use SETOPTION('NoVarsInStrings'.'ON').

**DONOTDELETE**
(Lurker)
2005-01-18 09:19 AM
Re: VBS to Kix translation

I have been scripting in Kix for over a year now, I know my way around variables and hidden shares they pose no problems, I also tried using cacls, xcacls and the sorts but I need a kix only solution with the exeption of ADsSecutiry.dll which provides the solution, the only thing needed is the code in kix and not vbs. Which is possible I won't stop till I get it working one way or another. I hope you can provide a solution, so far I tranlated it into this part of code:
Code:
 $sec = CreateObject("ADsSecurity")
$textusr = "BLAH\testuser"
$userdir = "\\PC-BLAH-XP-4\d$\TEST"
$filenm = $userdir
$permspart = "add(" + $textusr + ":F)+add(Administrators:F)"
ChangeAcls($filenm, $permspart, "EDIT", "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)
$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=nothing
$dacl=nothing
$sec=nothing
ENDFUNCTION

FUNCTION addace($dacl, $trustee, $maskvar, $acetype, $aceflags)
; add ace to the specified dacl
Const RIGHT_READ = &H80000000
Const RIGHT_EXECUTE = &H20000000
Const RIGHT_WRITE = &H40000000
Const RIGHT_DELETE = &H10000
Const RIGHT_FULL = &H10000000
Const RIGHT_CHANGE_PERMS = &H40000
Const RIGHT_TAKE_OWNERSHIP = &H80000

$ace = CreateObject("AccessControlEntry")
$ace.trustee = $trustee

SELECT
CASE
ucase($maskvar)
; specified rights so far only include FC & R. Could be expanded though
CASE
"F"
$ace.accessmask = RIGHT_FULL
CASE
"C"
$ace.accessmask = RIGHT_READ OR RIGHT_WRITE OR RIGHT_EXECUTE OR RIGHT_DELETE
CASE
"R"
$ace.accessmask = RIGHT_READ OR RIGHT_EXECUTE
ENDSELECT

$ace.acetype = $acetype
$ace.aceflags = $aceflags
$dacl.addace $ace
$ace=nothing
ENDFUNCTION



But gets stuck in ubound


Arend_
(MM club member)
2005-01-18 09:20 AM
Re: VBS to Kix translation

Sorry forgot to login.

Arend_
(MM club member)
2005-01-18 07:26 PM
Re: VBS to Kix translation

This is the last I can make of it, I get no error returns anymore but it doesn't work either :/
If anyone can take a look at it I'd apreciate it.

Code:

$ofs = CreateObject("Scripting.FileSystemObject")
$sec = CreateObject("ADsSecurity")
$textusr = "BLAH\testuser"
$userdir = "\\PC-BLAH-XP-4\d$\TEST"
$filenm = $userdir
$permspart = "add(" + $textusr + ":E)+add(Administrators:F)"
;-- Replace ACL on single file or folder-------
ChangeAcls($filenm, $permspart, "EDIT", "FOLDER")
; $ofs=nothing

;############################################### 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)
$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
ENDFUNCTION

FUNCTION addace($dacl, $trustee, $maskvar, $acetype, $aceflags)
; add ace to the specified dacl
$RIGHT_READ = +H80000000
$RIGHT_EXECUTE = +H20000000
$RIGHT_WRITE = +H40000000
$RIGHT_DELETE = +H10000
$RIGHT_FULL = +H10000000
$RIGHT_CHANGE_PERMS = +H40000
$RIGHT_TAKE_OWNERSHIP = +H80000

$ace = CreateObject("AccessControlEntry")
$ace.trustee = $trustee

$case = ucase($maskvar)
SELECT

CASE ($case = "F")
$ace.accessmask = $RIGHT_FULL
CASE ($case = "C")
$ace.accessmask = $RIGHT_READ OR $RIGHT_WRITE OR $RIGHT_EXECUTE OR $RIGHT_DELETE
CASE ($case = "R")
$ace.accessmask = $RIGHT_READ OR $RIGHT_EXECUTE
CASE ($case = "E")
$ace.accessmask = $RIGHT_EXECUTE
ENDSELECT

$ace.acetype = $acetype
$ace.aceflags = $aceflags
$dacl.addace($ace.trustee)
ENDFUNCTION



AllenAdministrator
(KiX Supporter)
2005-01-18 08:42 PM
Re: VBS to Kix translation

I have not tried your code, and am certainly not a expert when it comes to HEX and bitwise code... but I think I see some things that may help... I'm sure others around here could verify this better than I.

No need for the quotes around the numbers:
Code:
  
$ADS_ACETYPE_ACCESS_ALLOWED = "0"
$ADS_ACETYPE_ACCESS_DENIED = "1"
$ADS_ACEFLAG_INHERIT_ACE = "2"
$ADS_ACEFLAG_SUB_NEW = "9"



If these are HEX values shouldn't they be like $hex=&H0000
Code:
 
$RIGHT_READ = +H80000000
$RIGHT_EXECUTE = +H20000000
$RIGHT_WRITE = +H40000000
$RIGHT_DELETE = +H10000
$RIGHT_FULL = +H10000000
$RIGHT_CHANGE_PERMS = +H40000
$RIGHT_TAKE_OWNERSHIP = +H80000



Shouldn't the code below be using "|" instead of OR
Code:
 
CASE ($case = "C")
$ace.accessmask = $RIGHT_READ OR $RIGHT_WRITE OR $RIGHT_EXECUTE OR $RIGHT_DELETE
CASE ($case = "R")
$ace.accessmask = $RIGHT_READ OR $RIGHT_EXECUTE



Hope this helps.


Arend_
(MM club member)
2005-01-19 10:55 AM
Re: VBS to Kix translation

ok I changed that part but still no dice, I have to put the hex values in quotation marks else I get error in expression stuff.
Code:

$RIGHT_READ = "&H80000000"
$RIGHT_EXECUTE = "&H20000000"
$RIGHT_WRITE = "&H40000000"
$RIGHT_DELETE = "&H10000"
$RIGHT_FULL = "&H10000000"
$RIGHT_CHANGE_PERMS = "&H40000"
$RIGHT_TAKE_OWNERSHIP = "&H80000"



Also changed the OR to |.


Richard H.Administrator
(KiX Supporter)
2005-01-19 11:03 AM
Re: VBS to Kix translation

Drop the 'H':
Code:
$RIGHT_READ = &80000000
$RIGHT_EXECUTE = &20000000
$RIGHT_WRITE = &40000000
$RIGHT_DELETE = &10000
$RIGHT_FULL = &10000000
$RIGHT_CHANGE_PERMS = &40000
$RIGHT_TAKE_OWNERSHIP = &80000



LonkeroAdministrator
(KiX Master Guru)
2005-01-19 11:58 AM
Re: VBS to Kix translation

hmm...

k, I had to place this here as said I remembered the discussion.
not so short time ago but relevant info, no?
http://www.kixtart.org/ubbthreads/showflat.php?Cat=&Board=UBB2&Number=58027


Arend_
(MM club member)
2005-01-19 01:34 PM
Re: VBS to Kix translation

Thats entirely relevant, because the code I am workin on is from Kent Dyer, his post in the link you pasted is the code I am trying to translate thouroughly to kix. The code he pasted is a VBS script converted to kix with VBS2KIX, I made the effort of trying to get it to work as it should in kix, still am...

Arend_
(MM club member)
2005-01-19 05:05 PM
Re: VBS to Kix translation

You are right about the "H" thing, the &80000 values are resolved ok to Hex values. Thanks for that

The script now works without errors, however it doesn't set the permissions still :/


jtokach
(Seasoned Scripter)
2005-01-19 05:32 PM
Re: VBS to Kix translation

I've been down this road before and gave up due to the complexity of this and time constraints . I opted to wrap SetACL. GL, and keep us posted. Here you go:

WMI Security Descriptor Objects


LonkeroAdministrator
(KiX Master Guru)
2005-01-19 06:08 PM
Re: VBS to Kix translation

about the rights masks, orring will not get you anywhere.
this:
Code:

CASE ($case = "F")
$ace.accessmask = $RIGHT_FULL
CASE ($case = "C")
$ace.accessmask = $RIGHT_READ OR $RIGHT_WRITE OR $RIGHT_EXECUTE OR $RIGHT_DELETE
CASE ($case = "R")
$ace.accessmask = $RIGHT_READ OR $RIGHT_EXECUTE
CASE ($case = "E")
$ace.accessmask = $RIGHT_EXECUTE



should most likely be:
Code:

CASE ($case = "F")
$ace.accessmask = $RIGHT_FULL
CASE ($case = "C")
$ace.accessmask = $RIGHT_READ + $RIGHT_WRITE + $RIGHT_EXECUTE + $RIGHT_DELETE
CASE ($case = "R")
$ace.accessmask = $RIGHT_READ + $RIGHT_EXECUTE
CASE ($case = "E")
$ace.accessmask = $RIGHT_EXECUTE



why?
I haven't checked the code nor tested nor read about anything but from old stuff know that security masks are "incrementals"

and to prove my point, doing or:
$ace = 1 or 1

will always give you 1 (or true)
doing:
$ace = 253254324 or 460943590843

will always give you 1.
that's the nature of it

so, no wonder if it does not set security if instead of huge number it gets 1, right?


Richard H.Administrator
(KiX Supporter)
2005-01-19 06:08 PM
Re: VBS to Kix translation

Well, I've added some debug statements and at this point in your ChangeACLS function:
Code:
  udfDEBUG("About to GetSecurityDescriptor")
$sd = $sec.GetSecurityDescriptor("FILE://" + $file)
If @ERROR "Failed to get DACL" Exit @ERROR EndIf
udfDEBUG("Past GetSecurityDescriptor")



I get the "About to GetSecurityDescriptor" message, but then nothing. KiXtart exits in the GetSecurityDescriptor call with no error message.


LonkeroAdministrator
(KiX Master Guru)
2005-01-19 06:09 PM
Re: VBS to Kix translation

oh, and for kixtart OR and | are exactly the same thing.

Richard H.Administrator
(KiX Supporter)
2005-01-19 06:30 PM
Re: VBS to Kix translation

Quote:

oh, and for kixtart OR and | are exactly the same thing.




No, they are very definately different. One is a logical operator, the other a bitwise operator.

Logical operators can only deal with true and false inputs.


LonkeroAdministrator
(KiX Master Guru)
2005-01-19 06:39 PM
Re: VBS to Kix translation

right.
how come I still make these stupid arguments without thinking a bit?


krabourn
(Hey THIS is FUN)
2005-01-19 07:32 PM
Re: VBS to Kix translation

Here is some test code that I have. It might help.Code:
BREAK ON
; The folder named "images" must exist on the C:\ drive.

$wmiFileSecSetting = GetObject("winmgmts:Win32_LogicalFileSecuritySetting.path='c:\\Temp'")
$objMethod = $wmiFileSecSetting.Methods_.Item("GetSecurityDescriptor")
$objRegOut = $wmiFileSecSetting.ExecMethod_($objMethod.Name)
IF @Error <> 0
? "GetSecurityDescriptor failed" + @CRLF + @Error + @CRLF + @SError
QUIT 1
ELSE
? "GetSecurityDescriptor succeeded"
ENDIF
$wmiSecurityDescriptor = $objRegOut.Descriptor

; Retrieve the DACL array of Win32_ACE objects.
$DACL = $wmiSecurityDescriptor.DACL
FOR EACH $wmiAce IN $DACL
? "Access Mask: " + $wmiAce.AccessMask
? "ACE Type: " + $wmiAce.AceType
; Get Win32_Trustee object from ACE
$Trustee = $wmiAce.Trustee
? "Trustee Domain: " + $Trustee.Domain
? "Trustee Name: " + $Trustee.Name
? "Trustee SID: " + $Trustee.SIDString
NEXT



Arend_
(MM club member)
2005-01-19 09:08 PM
Re: VBS to Kix translation

To Jooel:
Well the Orring got me for a sec too, so for testing puposes I removed the CASE stuff and set the $ace.AccessMask to &80000, just to be on the safe side that that should work. (&80000 being Full Owner)

To Richard H.
So far I debugged every variable I've set in this script the I can read the variables ok, I even get all the Ace's and their stuff returned, just add this piece of code:
Code:

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


Place the for loop there and you will get a nice view on who has access to the folder you are trying to set rights to. I am calling it quits for this evening so I will paste my current progress.

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)
;
; Initialize all of the new ACLs
;
; VBS methods of creating the ACL bins
;
$newdacl = CreateObject("AccessControlList")
$ImpDenyDacl = CreateObject("AccessControlList")
$InheritedDacl = CreateObject("AccessControlList")
$ImpAllowDacl = CreateObject("AccessControlList")
$InhAllowDacl = CreateObject("AccessControlList")
$ImpDenyObjectDacl = CreateObject("AccessControlList")
$ImpAllowObjectDacl = CreateObject("AccessControlList")
;
; Sift the DACL into 5 bins:
; Inherited Aces
; Implicit Deny Aces
; Implicit Deny Object Aces
; Implicit Allow Aces
; Implicit Allow object aces
;
For Each $ace In $dacl
;
; Sort the original ACEs into their appropriate
; ACLs
;
If (($ace.AceFlags AND $ADS_ACEFLAG_INHERITED_ACE) = $ADS_ACEFLAG_INHERITED_ACE)
;
; Don't really care about the order of inherited aces. Since we are
; adding them to the top of a new list, when they are added back
; to the Dacl for the object, they will be in the same order as
; they were originally. Just a positive side affect of adding items
; of a LIFO ( Last In First Out) type list.
;
$InheritedDacl.AddAce($ace)
Else
;
; We have an Implicit ACE, lets put it the proper pool
;
Select Case ace.AceType
Case $ADS_ACETYPE_ACCESS_ALLOWED
;
; We have an implicit allow ace
;
$ImpAllowDacl.AddAce($ace)
Case $ADS_ACETYPE_ACCESS_DENIED
;
; We have a implicit Deny ACE
;
$ImpDenyDacl.AddAce($ace)
Case $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
;
; We have an object allowed ace
; Does it apply to a property? or an Object?
;
$impAllowObjectDacl.AddAce($ace)
Case $ADS_ACETYPE_ACCESS_DENIED_OBJECT
;
; We have a object Deny ace
;
$ImpDenyObjectDacl.AddAce($ace)
EndSelect
EndIf
Next
;
; Combine the ACEs in the proper order
; Implicit Deny
; Implicit Deny Object
; Implicit Allow
; Implicit Allow Object
; Inherited aces
;
; Implicit Deny
;
For Each $ace In $ImpDenyDacl
$newdacl.AddAce($ace)
Next
;
; Implicit Deny Object
;
For Each $ace In $ImpDenyObjectDacl
$newdacl.AddAce($ace)
Next
;
; Implicit Allow
;
For Each $ace In $ImpAllowDacl
$newdacl.AddAce($ace)
Next
;
; Implicit Allow Object
;
For Each $ace In $impAllowObjectDacl
$newdacl.AddAce($ace)
Next
;
; Inherited Aces
;
For Each $ace In $InheritedDacl
$newdacl.AddAce($ace)
Next
;
; Clean up
;
$InheritedDacl = ""
$ImpAllowDacl = ""
$ImpDenyObjectDacl = ""
$ImpDenyDacl = ""
;
; Set the appropriate revision level
; for the DACL
;
$newdacl.AclRevision = $dacl.AclRevision
;
; Replace the Security Descriptor
;
$dacl = ""
$dacl = $newdacl
EndFunction

Arend_
(MM club member)
2005-01-19 09:20 PM
Re: VBS to Kix translation

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



Sealeopard
(KiX Master)
2005-01-20 01:09 AM
Re: VBS to Kix translation

According to http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/iadsaccesscontrollist_addace.asp and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ad/ad/example_code_for_creating_a_security_descriptor.asp your ACLs are not being comitted.

Arend_
(MM club member)
2005-01-20 06:28 PM
Re: VBS to Kix translation

Ladies and Gents, I am proud to announce that it is working!!! Perfectly too I might add. I wanna thank all of you who helped me trough this quest, I couln't have done it without you. It works like a f00kin charm. To show my grattitude I'll paste the working code:
Code:

;##################################################### Script #########################################################

$sec = CreateObject("ADsSecurity")
$textusr = "DOMAIN\testuser"
$userdir = "\\PC-DOMAIN-XP-4\d$\TEST"
$filenm = $userdir
$permspart = "add(" + $textusr + ":R)+add(Administrators:F)"

;-- Replace ACL on single file or folder-------
ChangeAcls($filenm, $permspart, "EDIT", "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

; cleanup
$dacl=""
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
; 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 + $ADS_RIGHT_GENERIC_WRITE + $ADS_RIGHT_GENERIC_EXECUTE + $ADS_RIGHT_DELETE
CASE ($case = "R")
$ace.AccessMask = $ADS_RIGHT_GENERIC_READ + $ADS_RIGHT_GENERIC_EXECUTE
CASE ($case = "E")
$ace.AccessMask = $ADS_RIGHT_GENERIC_EXECUTE
ENDSELECT
$ace.AceFlags = $aceflags
$dacl.AddAce($ace)
$sd.DiscretionaryAcl = $dacl
$sec.SetSecurityDescriptor($sd)
ENDFUNCTION



AllenAdministrator
(KiX Supporter)
2005-01-20 10:50 PM
Re: VBS to Kix translation

You've come this far... why not clean these up, add a header, and add these to the UDFs.

Arend_
(MM club member)
2005-01-21 12:22 PM
Re: VBS to Kix translation

I will, thanks for mentioning that. Will post it tonight or this weekend.

Sealeopard
(KiX Master)
2005-01-22 11:40 PM
Re: VBS to Kix translation

So, what was the problem? That the ACL wasn't committed to the object?

Arend_
(MM club member)
2005-01-25 02:33 PM
Re: VBS to Kix translation

Yup, that was the problem, I cleaned it up a bit and submitted the function (All Thank you's in place as well)

maciep
(Korg Regular)
2005-01-25 02:38 PM
Re: VBS to Kix translation

nicely done! but i just have to warn you that you'll probably get pulled over by the "code tag" police in the udf forum. So i would suggest you edit that post to add code tags.

too late


Richard H.Administrator
(KiX Supporter)
2005-01-25 02:39 PM
Re: VBS to Kix translation

Too late. The Code Tags division never sleeps.

Sealeopard
(KiX Master)
2005-01-25 03:34 PM
Re: VBS to Kix translation

And the follow-the-guidelines division also already reared it's ugly head.

AllenAdministrator
(KiX Supporter)
2005-01-25 03:45 PM
Re: VBS to Kix translation

Sorry apronk... I forgot to mention adding your UDFs would unleash the hounds

Arend_
(MM club member)
2005-01-26 09:35 AM
Re: VBS to Kix translation

argh... Allright, I'l change is and make is "kixtart.org compliant" as soon as I find some time this week. Thx for mentioning it

JochenAdministrator
(KiX Supporter)
2005-01-26 10:34 AM
Re: VBS to Kix translation

If you have anything unclear about the guidelines in udf forum leave me a pm and I'll try to explain ...

Arend_
(MM club member)
2005-02-08 08:50 AM
Re: VBS to Kix translation

Hi all, I am sorry I haven't replied in some time. the workload is a bit much the last few weeks. Anyway i'm not submitting the function just yet, I found out that it still misses one important thing, setting the owner. As soon as thats done I will submit it. If anyone has any suggestions I'd be glad to hear it.

Arend_
(MM club member)
2005-03-24 07:01 PM
Re: VBS to Kix translation

Sory it is taking so long to submit again, but I have found some problems that remain, first the Aces have to be "reordered" which present problem #1, also the owner of the main folder has to be set properly so the subfolders can inherit the rights properly which is problem #2. When I solved those 2 probs I will submit the Function but as it is at the moment the whole script consists of 3 functions. one of which isn't working yet, if anyone can shed some light on the owner or reorder problem please do so

I am working on the script most of my free time so although i takes a while once it is finished alot of ppl will benefit from this.