#110404 - 2003-12-17 03:49 AM
Re: Using WMI to set ownership
|
Howard Bullock
KiX Supporter
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
I see an opportunity...but it won't be WMI
|
Top
|
|
|
|
#110406 - 2003-12-17 04:17 AM
Re: Using WMI to set ownership
|
Howard Bullock
KiX Supporter
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
Well I can already set owner via Perl EXE. I can see if it can be added to HABobjects.dll. It won't be WMI but it may be KiXtart COM. I have been exploring a new Perl Module not yet public that handles most Win32 security including a definable recursor routine.
I always wanted to provide COM access to DACL, ACLs, ACE'a etc. If I get some additional time I may be able to provide something to test in a week or two.
|
Top
|
|
|
|
#110408 - 2003-12-17 04:23 AM
Re: Using WMI to set ownership
|
Howard Bullock
KiX Supporter
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
Do I ever make things overly complited?
|
Top
|
|
|
|
#110409 - 2003-12-17 05:11 PM
Re: Using WMI to set ownership
|
jtokach
Seasoned Scripter
Registered: 2001-11-15
Posts: 513
Loc: PA, USA
|
Shawn, here's the ASP code where it's written using get:
Code:
'*** Get Win32_SecurityDescriptor class and create an instance of it ***
Set oClass = oConnectCIMv2.Get("Win32_SecurityDescriptor")
Set oSecDescriptor = oclass.SpawnInstance_()
'*** End Get Win32_SecurityDescriptor class and create an instance of it ***
'*** Prepare the security descriptor ***
'A set the control flags property of the security descriptor
'this value designates a set of control bits that qualify the
'meaning of a security descriptor or its individual members.
'a value of 4 (SE_DACL_PRESENT) indicates a security descriptor
'containing a DACL.
oSecDescriptor.Properties_.Item("ControlFlags") = SE_DACL_PRESENT
Set oClass = Nothing
'*** End Prepare the security descriptor ***
'*** Add a new ACE to the DACL ***
Set ACE = SetACE(oConnectCIMv2, sPermission, _
CUSTCON_ACE_INHERIT, _
ACETYPE_ACCESS_ALLOWED, _
SetTrustee(oConnectCIMv2, _
sDomain, _
sAccountName, _
sidval))
'build the array containing all ACEs. In this case, one ACE is being
'added to the security descriptor.
oSecDescriptor.Properties_.Item("DACL") = Array(ACE)
'clean up
Set ACE = Nothing
'*** End Add a new ACE to the DACL ***
'*** Modify the security descriptor ***
Set oDir = oConnectCIMv2.Get("Win32_Directory='" & sHomePath & "'")
Set oInParam = oDir.Methods_("ChangeSecurityPermissions"). _
InParameters.SpawnInstance_()
oInParam.Properties_.Item("Option") = CHANGE_DACL_SECURITY_INFORMATION
oInParam.Properties_.Item("SecurityDescriptor") = oSecDescriptor
oSecDescriptor.Properties_.Item("ControlFlags") = CUSTCON_ALLOW_INHERIT
'*** End Modify the security descriptor ***
'*** Execute the method ***
Set oOut = oDir.ExecMethod_("ChangeSecurityPermissions", oInParam)
If not oOut is nothing then
Response.Write "<li>The folder permissions were " & _
"successfully updated."
Else
Response.Write "<li class = warning>The folder permissions were " & _
"not successfully applied to the directory. "
End If
Regarding complication, I found an opensource tool that's miles ahead of subinacl and doesn't suffer the dreaded "ACL reodering". SetACL It, like subinacl, is not exactly user friendly. They developed a front end to write command lines. They're developing an ActiveX dll, so again we're SOL. Anyway, point is, the architecture of the SD is insane. Simplifying it is not possible. Sounds like a challenge Howard! =)
_________________________
-Jim
...the sort of general malaise that only the genius possess and the insane lament.
|
Top
|
|
|
|
#110410 - 2003-12-17 05:17 PM
Re: Using WMI to set ownership
|
Howard Bullock
KiX Supporter
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
Just to clear the air about subinacl. Only some older versions of this tool have the ACL order issue. The newest version that I have no longer supports NT4.
I use version 2.6.0.1397 for NT4 and version 4.0.3.1615 for W2K and XP.
I will tried to put some time in on the security COM objects. What specifically do you want to do first?
|
Top
|
|
|
|
#110412 - 2003-12-17 05:28 PM
Re: Using WMI to set ownership
|
Howard Bullock
KiX Supporter
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
|
Top
|
|
|
|
#110414 - 2003-12-17 05:36 PM
Re: Using WMI to set ownership
|
jtokach
Seasoned Scripter
Registered: 2001-11-15
Posts: 513
Loc: PA, USA
|
Shawn, here's the code. Howard's follow up explains all though.
Code:
<%@ Language=VBScript %>
<% Option Explicit On Error Resume Next %> <HTML> <HEAD> <META NAME="GENERATOR" Content="by Ethan Wilansky"> <LINK REL="STYLESHEET" HREF="stylesheet.css" TYPE="text/css"> </HEAD> <BODY>
<%
' ------------------------- CONSTANT DEFINITIONS ------------------------------
'*** Security related constants used in the script ***
'ACE flags Const OBJECT_INHERIT_ACE = 1 Const CONTAINER_INHERIT_ACE = 2 Const CUSTCON_ACE_INHERIT = 3
'ACE types Const ACETYPE_ACCESS_ALLOWED = 0 Const ACETYPE_ACCESS_DENIED = 1 'Const
'Access masks Const CUSTCON_FULL_CONTROL = 2032127 Const CUSTCON_CHANGE = 1245631 Const CUSTCON_READ = 1179785
'Security descriptor control flag Const SE_DACL_PRESENT = 4 Const SE_DACL_AUTO_INHERITED = 1024 Const SE_SELF_RELATIVE = 32768 Const CUSTCON_ALLOW_INHERIT = 33796
'This constant is for the ChangeSecurityPermission method. 'An option value of 4 in this method means change DACL information. 'The values in the current version of the WMI sdk are wrong. 'The legal values are 0, 2, 4 and 8. Const CHANGE_DACL_SECURITY_INFORMATION = 4
' --- END CONSTANT DEFINITIONS ---
' --------------------------- GLOBAL VARIABLES --------------------------------
Dim sFileServer, sDomainController, sNameSpacePath, Sidval, CheckVarType Dim oFso, bFol, bParentPath, sParentPath, sDirectoryName, iLength, sHomePath Dim oConnectLDAP, oConnectCIMv2 Dim sPath, sAccountName, sDomain, sPermission Dim oClass, oSecDescriptor, ACE Dim oDir, oInParam, oOut Dim iRetVal, oMethod, oDescriptor, oSecuritySettings
' --- END GLOBAL VARIABLES ---
' ----------------------------- PROCEDURES ------------------------------------ 'Check for the parent folder Sub CheckForFolder() 'local variables Dim sDriveLetter, iPruneLength, sRemainingPath
'Initialize sDriveLetter to the drive letter in sPath sDriveLetter = Left(sPath,1)
'Initialize sRemainingPath to sPath less the first two characters that 'represent the drive letter designation iPruneLength = iLength - 2 sRemainingPath = Right(sPath, iPruneLength)
'Check to see if the pathspec exists before continuing sParentPath = "\\" & sFileServer & "\" & sDriveLetter & "drive$" & _ sRemainingPath bParentPath = oFso.FolderExists(sParentPath) End Sub
'Check for or create the home folder Sub CheckOrCreateHomeFolder() Dim oCreateFolder, sDriveLetter, sRemainingPath
'Create a UNC and assign it to the sDirectoryName variable. sDirectoryName = sParentPath & "\" & sAccountName 'Check to see if the folder exists bFol = oFso.FolderExists(sDirectoryName)
If bFol = False Then
set oCreateFolder = oFso.CreateFolder(sDirectoryName)
End If 'clean up Set oCreateFolder = Nothing End Sub
'Adjust the path if the operator entered a backslash at the end of the path Sub AdjustPathSpec()
iLength = Len(sPath)
If Right(sPath,1) = "\" Then iLength = iLength - 1 sPath=Left(sPath,iLength)
End If End Sub
'Create an entry form Sub Form %>
<h3>Create Home Folders and Set Permissions</h3> <p>Use this form to create and set permissions for home directories using the FileSystemObject and WMI.</p> <FORM ACTION="HomeFolderPerms.asp" METHOD=post name=FeedBackForm> <table border=0 width=520px> <tr> <td nowrap> User account domain: </td> <td align=left> <!--Replace the options here with the names of your domains--> <SELECT ID=SelectList1 name=DomainName> <OPTION selected>DOMAIN01</OPTION> <OPTION>DOMAIN02</OPTION> </SELECT> </td> <td width=100px> </td> </tr> <tr> <td> Local domain controller: </td> <td align=left> <!--Replace the name value for this field with the name of a local domain controller--> <INPUT type="text" id=Text1 name=DomainController value=SERVER1> </td> <td width=100px> </td> </tr> <tr> <td class = definition colspan=3>The name of a local domain controller containing the user account. </td> </tr> <tr> <td> User account name: </td> <td align=left> <INPUT type="text" id=textinput2 name=UserAccountName> </td> <td width=100px> </td> </tr> <tr> <td> Server name: </td> <td align=left> <!--Replace the options here with the names of your home directory servers--> <SELECT ID=SelectList2 name=ServerName> <OPTION selected>SERVER1</OPTION> <OPTION>SERVER2</OPTION> </SELECT> </td> <td width=100px> </td> </tr> <tr> <td class=definition colspan=3> This is the server that will contain the user's home directory. </td> </tr> <tr> <td nowrap> Path to parent directory: </td> <td align=left> <INPUT type="text" id=textinput3 name=PathSpec value=e:\home> </td> <td width=100px> </td> </tr> <tr> <td class = definition colspan=3> This is the full physical path on the server, including the drive letter. </td> </tr> </table> <b>Permissions:</b> <INPUT ID=RADIO type="radio" id=radio1 name=permission value=Read> Read <INPUT type="radio" checked id=Radio2 name=permission value=Change> Change <INPUT type="radio" id=Radio3 name=permission value=FullControl> Full Control <p class = definition>Select the permission to assign the user account for the directory.</p> <p><INPUT type="checkbox" checked name="inherit" ID=Checkbox1> Allow inheritable permissions from parent to propagate to this directory.</p> <INPUT type="submit" value="Submit" id=submit name=submit> <INPUT type="reset" value="Reset" id=reset name=reset> </FORM> <% End Sub
' --- END PROCEDURES ---
' ------------------------ SERVER-SIDE FUNCTIONS ------------------------------
'Determine the SID of a user in the Active Directory Function QuerySid(sAccountName) 'Local variables Dim ServiceSet, Item Set ServiceSet = oConnectLDAP.ExecQuery _ ("SELECT DS_objectSID FROM ds_user " & _ " WHERE ds_samaccountname ='" & sAccountName & "'") For Each Item In ServiceSet QuerySid = (Item.DS_objectSID.value) Next 'Clean up Set ServiceSet = Nothing
End Function
'Prepare the trustee information for the ACE
Function SetTrustee(oConnectCIMv2, sDomain, sAccountName, SID) 'Declare any local variables Dim oTrustee
Set oTrustee = oConnectCIMv2.Get("Win32_Trustee").SpawnInstance_
oTrustee.Domain = sDomain
oTrustee.Name = sAccountName
oTrustee.Properties_.Item("SID") = SID
Set SetTrustee = oTrustee 'clean up Set oTrustee = Nothing
End Function
'Prepare the ACE for the DACL
Function SetACE(oConnectCIMv2, AccessMask, AceFlags, AceType, oTrustee)
'Declare any local variables Dim oAce
Set oAce = oConnectCIMv2.Get("Win32_Ace").SpawnInstance_
oAce.Properties_.Item("AccessMask") = AccessMask
oAce.Properties_.Item("AceFlags") = AceFlags
oAce.Properties_.Item("AceType") = AceType
oAce.Properties_.Item("Trustee") = oTrustee
Set SetACE = oAce 'clean up Set oAce = Nothing
End Function
' --- END SERVER-SIDE FUNCTIONS ---
%> <!-----------------------------CLIENT-SIDE FUNCTIONS-------------------------->
<SCRIPT LANGUAGE="VBScript"> <!-- Function FeedbackForm_OnSubmit() Dim iNumeric, sType 'Disallow submit until the form fields have been validated. FeedbackForm_OnSubmit = False
'Get a reference to the form. Set theForm = Document.FeedbackForm
'First, check for the domain controller name value. If Trim(theForm.DomainController.Value) = "" Then MsgBox "Enter the name of a domain controller.", vbCritical, "Input Required" theForm.DomainController.Focus Else 'Next, check for the user account name value. If Trim(theForm.UserAccountName.Value) = "" Then MsgBox "Enter a user account name.", vbCritical, "Input Required" theForm.UserAccountName.Focus Else 'Next, check for the path value. If Trim(theForm.PathSpec.Value) = "" Then MsgBox "Enter the parent directory path.", vbCritical, "Input Required" theForm.PathSpec.Focus Else 'Next, check that the path spec. value is in the correct format. GetValue = theForm.PathSpec.Value If Mid(GetValue,2,2) <> ":\" Then MsgBox "The form of this input is: drive_letter:\path", _ vbCritical, "Invalid Path Specification" theForm.PathSpec.Focus Else 'Continue with submission. FeedbackForm_OnSubmit = True End If End If End If
End If
End Function --> </SCRIPT>
<!--- END CLIENT-SIDE FUNCTIONS --->
<% ' ---------------------------- MAIN SCRIPT BODY -------------------------------
'Determine whether to load the blank form or validate the form, create the home 'directory if it isn't already there and set permissions on the directory. Response.Write "<BODY>"
'*** Form call logic ***
If Request.Form("UserAccountName") = "" _ or Request.Form("DomainController") = "" _ or Request.Form("PathSpec") = "" Then Call Form
'*** Data initialization ***
Else 'initialize the variables required in the script. sDomain=Request.Form("DomainName") sAccountName=Request.Form("UserAccountName") sFileServer=Request.Form("ServerName") sDomainController=Request.Form("DomainController") sPath=Request.Form("PathSpec") 'Adjust the pathspec so that if the operator adds 'a backslash at the end of the pathspec, remove it Call AdjustPathSpec() 'initialize the path to the home folder sHomePath=sPath & "\" & sAccountName 'initialize the permission to grant Select Case Request.Form("Permission") Case "Read" sPermission = CUSTCON_READ Case "Change" sPermission = CUSTCON_CHANGE Case Else sPermission = CUSTCON_FULL_CONTROL End Select '*** End Data intialization *** '*** WMI Connection Strings ***
'connect to the CIMv2 namespace on the appropriate remote server sNameSpacePath = "\root\cimv2"
Set oConnectCIMv2 = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}" _ & "!\\" & sFileServer & sNameSpacePath)
'connect to the LDAP namespace on a local domain controller sNameSpacePath = "\root\directory\LDAP" Set oConnectLDAP = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}" _ & "!\\" & sDomainController & sNameSpacePath) '*** End WMI Connection Strings *** '*** Get the SID if the user account exists *** 'initialize the variables used here. SidVal = QuerySid(sAccountName) CheckVarType = varType(SidVal) 'Clean up Set oConnectLDAP = Nothing 'A value of vbEmpty or 0 indicates that the SidVal variable is uninitialized 'and therefore, the user account was not found. If CheckVarType = vbEmpty Then Response.Write "<p>The user account you entered, <b>" & sAccountName & _ "</b>, cannot be found on <b>" & sDomainController & "</b>." & _ "You might not have the necessary permission to check the directory." & _ " <br>If you do have enough permissions, Press the <b>Back</b> button" & _ " and specify an existing user account on<b> " & _ sDomainController & "<b>.</p>" Response.End End If '*** End Get the SID if the user account exists ***
'*** File system operations ***
'Create an instance of the file system object and save 'a reference to it in the oFSO variable set oFso = CreateObject("Scripting.FileSystemObject")
bParentPath = "False" 'Call the sub procedure to see if the parent folder exists Call CheckForFolder() If bParentPath = False Then Response.Write "<p>The parent folder, <b>" & sPath & _ "</b>, cannot be found on <b>" & sFileServer & "</b>." & _ "You might not have the necessary permission to access the directory." & _ " <br>If you do have enough permission, press the <b>Back</b> button " & _ "and specify an existing parent folder on<b> " & _ sFileServer & "<b>.</p>" Response.End End If bFol = "False" 'Call the sub procedure to check for the home directory and create 'it if necessary. Call CheckOrCreateHomeFolder() If bFol = True Then Response.Write "<li>The home folder, " & sDirectoryName & _ ", already exists." Else Response.Write "<li>The folder, " & sDirectoryName & ", was created" End If 'clean up Set oFSO = Nothing '*** End file system operations ***
'*** Get Win32_SecurityDescriptor class and create an instance of it ***
Set oClass = oConnectCIMv2.Get("Win32_SecurityDescriptor")
Set oSecDescriptor = oclass.SpawnInstance_() '*** End Get Win32_SecurityDescriptor class and create an instance of it ***
'*** Prepare the security descriptor ***
'A set the control flags property of the security descriptor 'this value designates a set of control bits that qualify the 'meaning of a security descriptor or its individual members. 'a value of 4 (SE_DACL_PRESENT) indicates a security descriptor 'containing a DACL. oSecDescriptor.Properties_.Item("ControlFlags") = SE_DACL_PRESENT Set oClass = Nothing '*** End Prepare the security descriptor ***
'*** Add a new ACE to the DACL *** Set ACE = SetACE(oConnectCIMv2, sPermission, _ CUSTCON_ACE_INHERIT, _ ACETYPE_ACCESS_ALLOWED, _ SetTrustee(oConnectCIMv2, _ sDomain, _ sAccountName, _ sidval))
'build the array containing all ACEs. In this case, one ACE is being 'added to the security descriptor. oSecDescriptor.Properties_.Item("DACL") = Array(ACE) 'clean up Set ACE = Nothing '*** End Add a new ACE to the DACL *** '*** Modify the security descriptor *** Set oDir = oConnectCIMv2.Get("Win32_Directory='" & sHomePath & "'")
Set oInParam = oDir.Methods_("ChangeSecurityPermissions"). _ InParameters.SpawnInstance_()
oInParam.Properties_.Item("Option") = CHANGE_DACL_SECURITY_INFORMATION
oInParam.Properties_.Item("SecurityDescriptor") = oSecDescriptor
oSecDescriptor.Properties_.Item("ControlFlags") = CUSTCON_ALLOW_INHERIT '*** End Modify the security descriptor ***
'*** Execute the method ***
Set oOut = oDir.ExecMethod_("ChangeSecurityPermissions", oInParam)
If not oOut is nothing then
Response.Write "<li>The folder permissions were " & _ "successfully updated."
Else
Response.Write "<li class = warning>The folder permissions were " & _ "not successfully applied to the directory. " End If 'Clean up Set oDir = Nothing Set oInParam = Nothing Set oOut = Nothing
'*** End Execute the method *** '*** Reset the DACL to allow inheritance *** If Request.Form("inherit") = "on" Then 'Get the existing security descriptor and store it. Set oSecuritySettings = oConnectCIMv2. _ Get("Win32_LogicalFileSecuritySetting='" & sHomePath & "'")
'Clean up Set oConnectCIMv2 = Nothing If oSecuritySettings Is Nothing Then Response.Write "<li class = warning>Unable to retrieve the " & _ "Win32_LogicalFileSecurity Setting of " & sHomePath Else 'retrieve the descriptor and store it in oDescriptor iRetval = oSecuritySettings.getsecuritydescriptor(oDescriptor) If iRetval = 0 And Err.Number = 0 Then oSecDescriptor.ControlFlags = CUSTCON_ALLOW_INHERIT Set oMethod = oSecuritySettings.Methods_("SetSecurityDescriptor") Set oInParam = oMethod.inParameters.SpawnInstance_()
oInParam.Properties_.item("Descriptor") = oSecDescriptor
'Execute the method to reassign the security descriptor Set iRetVal = oSecuritySettings. _ ExecMethod_("SetSecurityDescriptor", oInParam)
With Response .Write "<li>" & sDomain & "\" & sAccountName & " has been granted " & _ Request.Form("Permission") & " permission to " & _ sHomePath & " on " & sFileServer & _ ".<li>Permissions from the parent folder are" & _ " inherited by this directory.<br>" .Write "<br><A HREF=HomeFolderPerms.asp>Return to the form.</a>" End With Else Response.Write "<li class = warning>Error# " & Err.Number & ": " _ & Err.Description & _ " occurred when retrieving the security descriptor" End If End If '*** End Reset the DACL to allow inheritance *** Else With Response .Write "<li>" & sDomain & "\" & sAccountName & " has been granted " & _ Request.Form("Permission") & " permission to " & _ sHomePath & " on " & sFileServer & "." & _ "<li>Permissions from the parent folder are NOT " & _ " inherited by this directory.<br>" .Write "<br><A HREF=HomeFolderPerms.asp>Return to the form</a>" End With End If 'Clean up Set oSecDescriptor = Nothing Set oSecuritySettings = Nothing Set oMethod = Nothing Set oInParam = Nothing Set iRetVal = Nothing End If
'*** End Form call logic ***
%> </BODY> </HTML>
_________________________
-Jim
...the sort of general malaise that only the genius possess and the insane lament.
|
Top
|
|
|
|
#110415 - 2003-12-17 05:38 PM
Re: Using WMI to set ownership
|
Howard Bullock
KiX Supporter
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
I don't know what MS support knows - just sent a email to Premier to ask them what versions that have available. I get mine direct from the developer of SubInACL. Several of the current functions and ablilites like using an offline sam file were added per my request.
Use the "/help" switch on the command line.
C:\Data>\\bullpup\Integrate\SubInAcl\4.0.3.1615\subinacl /help
Code:
SubInAcl version 4, 0, 3, 1615
USAGE
-----
Usage :
SubInAcl [/option...] /object_type object_name [[/action[=parameter]...]
/options :
/outputlog=FileName /errorlog=FileName
/noverbose /verbose (default)
/notestmode (default=/notestmode) /testmode
/alternatesamserver=SamServer /offlinesam=FileName
/stringreplaceonoutput=string1=string2
/expandenvironmentsymbols (default) /noexpandenvironmentsymbols
/statistic (default) /nostatistic
/dumpcachedsids=FileName /separator=character
/applyonly=[dacl,sacl,owner,group]
/object_type :
/service /keyreg /subkeyreg
/file /subdirectories[=directoriesonly|filesonly]
/clustershare /kernelobject /metabase
/printer /onlyfile /process
/share /samobject
/action :
/display[=dacl|sacl|owner|primarygroup|sdsize|sddl] (default)
/setowner=owner
/replace=[DomainName\]OldAccount=[DomainName\]New_Account
/accountmigration=[DomainName\]OldAccount=[DomainName\]New_Account
/changedomain=OldDomainName=NewDomainName[=MappingFile[=Both]]
/migratetodomain=SourceDomain=DestDomain=[MappingFile[=Both]]
/findsid=[DomainName\]Account[=stop|continue]
/suppresssid=[DomainName\]Account
/confirm
/ifchangecontinue
/cleandeletedsidsfrom=DomainName[=dacl|sacl|owner|primarygroup|all]
/testmode
/accesscheck=[DomainName\]Username
/setprimarygroup=[DomainName\]Group
/grant=[DomainName\]Username[=Access]
/deny=[DomainName\]Username[=Access]
/sgrant=[DomainName\]Username[=Access]
/sdeny=[DomainName\]Username[=Access]
/revoke=[DomainName\]Username
/perm
/audit
/compactsecuritydescriptor
/pathexclude=pattern
/objectexclude=pattern
/sddl=sddl_string
|
Top
|
|
|
|
Moderator: Shawn, ShaneEP, Ruud van Velsen, Arend_, Jochen, Radimus, Glenn Barnas, Allen, Mart
|
0 registered
and 557 anonymous users online.
|
|
|