#87472 - 2002-08-25 07:23 PM
Scripting "User cannot change password" option
|
Glen D.
Lurker
Registered: 2002-08-25
Posts: 4
Loc: State College, Pennsylvania, U...
|
I'm having some difficulty with a routine I'm working on to update the "User cannot change password" option. It's not a simple flag, but rather an access control entry on the discretionary access control list of security discriptor of the user object. I've modified the code I've found on the MS scriptcenter for KIX, but I'm getting a "member not found error" when I attempt to reassign the security descriptor. If I comment out all the code between where I retrieve the DACL and then try to reassign it so that the code would flow as follows:
$objDACL=$objSD.DiscretionaryAcl $objSD.DiscretionaryAcl = $objDACL
I still get the error on the assign. Any thoughts?
Here's the code I have.
$ADS_ACETYPE_ACCESS_DENIED_OBJECT=&6 $ADS_ACEFLAG_OBJECT_TYPE_PRESENT=&1 $CHANGE_PASSWORD_GUID = "{AB721A53-1E2F-11D0-9819-00AA0040529B}" $ADS_RIGHT_DS_CONTROL_ACCESS =&100
$objUser=GetObject("LDAP://CN=TestStudent, OU=test, DC=test, DC=local") $test=$objUser.Get("SN") ? "User:"+ $test $objSD=$objUser.Get("ntSecurityDescriptor") $objDACL=$objSD.DiscretionaryAcl
; This is test code to see if the ACE can be read (this works) For Each $Ace In $objDACL ?$ACE.ObjectType+" --> "+$Ace.Acetype If (($Ace.AceType = $ADS_ACETYPE_ACCESS_DENIED_OBJECT) AND (LCase($Ace.ObjectType) = $CHANGE_PASSWORD_GUID)) $blnACEPresent = True EndIf Next If $blnACEPresent ? "ADS_UF_PASSWD_CANT_CHANGE is enabled" Else ? "ADS_UF_PASSWD_CANT_CHANGE is disabled" ENDIF
; Set up the new ACE entries $aryTrustees = "nt authority\self" , "EVERYONE" FOR EACH $strTrustee IN $aryTrustees $objACE = CreateObject("AccessControlEntry") $objACE.Trustee=$strTrustee $objACEFlags=0 $objACE.AceType= $ADS_ACETYPE_ACCESS_DENIED_OBJECT $objACE.Flags = $ADS_ACEFLAG_OBJECT_TYPE_PRESENT $objACE.ObjectType= $CHANGE_PASSWORD_GUID $objACE.AccessMask = $ADS_RIGHT_DS_CONTROL_ACCESS $objDACL.AddAce($objACE) NEXT $objSD.DiscretionaryAcl = $objDACL ? "1:"+@error+" "+@serror $objUser.Put("ntSecurityDescriptor", $objSD) ? "2:"+@error+" "+@serror $objUser.SetInfo ? "3:"+@error+" "+@serror
|
Top
|
|
|
|
#87474 - 2002-08-25 08:04 PM
Re: Scripting "User cannot change password" option
|
Glen D.
Lurker
Registered: 2002-08-25
Posts: 4
Loc: State College, Pennsylvania, U...
|
I had hoped that would be the case. Unfortunately for the Cannot Change Password option, this can only be read from the Userflags property--it can't be set(regardless if it's the LDAP or WINNT interface)
To quote the MS Site ADSI reference http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netdir/adsi/adsi_reference.asp
To determine if the user has been granted permission to change his or her password, read the ADS_UF_PASSWD_CANT_CHANGE (0x0040) bit on the userFlags attribute of the user object. This flag is defined in the ADS_USER_FLAG_ENUM enumeration. This flag cannot be set directly.
To prevent a user from changing the password, set two ACEs in the security descriptor DACL of the user object. One ACE denies the permission to the user and another ACE denies the permission to the Everyone group. Both ACEs are object-specific deny ACEs that specify the GUID of the extended permission for changing passwords.
|
Top
|
|
|
|
#87475 - 2002-08-25 09:32 PM
Re: Scripting "User cannot change password" option
|
Howard Bullock
KiX Supporter
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
I just set the UF_PASSWD_CANT_CHANGE flag on NT4 using Perl by performing a Bitwise OR of UserFlags and ($UF_PASSWD_CANT_CHANGE = 0x0040;). I will check KiXtart shortly.
{edit}
This also worked on a W2K AD DC. [ 25. August 2002, 21:38: Message edited by: Howard Bullock ]
|
Top
|
|
|
|
#87476 - 2002-08-26 12:08 AM
Re: Scripting "User cannot change password" option
|
Glen D.
Lurker
Registered: 2002-08-25
Posts: 4
Loc: State College, Pennsylvania, U...
|
While I can set other flags (for example the ADS_UF_DONT_EXPIRE_PASSWD &10000) using the method you specify, I can't set the ADS_UF_PASSWD_CANT_CHANGE.
If I try to set an ADS_UF_PASSWD_CANT_CHANGE(&40), the script will "work" insofar as it won't report any errors; however, checking the user account will show that the flag is not set. Rerunning the script and just displaying the flag will also show that the value is not "saved" after the put.
Since I forgot to post it in the original message, I am using an AD under win2k and kixtart 4.10.
Here's the script I used to test that out on an account with no flags enabled:
$Ouser=GetObject("LDAP://CN=Test, OU=Test, DC=TASD, DC=LOCAL") if @error<>0 ? @error+" "+@serror endif
If $oUser ; Print Base $Flags = $oUser.Get("UserAccountControl") ? "Base: "+$Flags
? "ADS_UF_DONT_EXPIRE_PASSWD" $Flags = $oUser.Get("UserAccountControl") $Flags = $Flags | &10000 ? " Before Put:"+$Flags $oUser.Put("UserAccountControl",$Flags) if @error<>0 ? @error+" "+@serror endif $oUser.SetInfo if @error<>0 ? @error+" "+@serror endif
;Check the value again $Flags = $oUser.Get("UserAccountControl") ?" After Put: "+$Flags
?"ADS_UF_PASSWD_CANT_CHANGE" $Flags = $oUser.Get("UserAccountControl") $Flags = $Flags | &40 ? " Before Put:"+$Flags $oUser.Put("UserAccountControl",$Flags) if @error<>0 ? @error+" "+@serror endif $oUser.SetInfo if @error<>0 ? @error+" "+@serror endif
;Check the value again $Flags = $oUser.Get("UserAccountControl") ?" After Put: "+$Flags
Else ? "User not found" EndIf $oUser=0
And here's the output:
Base: 544 ADS_UF_DONT_EXPIRE_PASSWD Before Put:66080 After Put: 66080 ADS_UF_PASSWD_CANT_CHANGE Before Put:66144 After Put: 66080
This seems to jive with what the Microsoft docs say.
Thanks -Glen
|
Top
|
|
|
|
#87477 - 2002-08-26 01:31 AM
Re: Scripting "User cannot change password" option
|
Howard Bullock
KiX Supporter
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
This code works. I have yet to test the LDAP:// provider.
Notice the difference of my use of "&40". I believe that you need to use the "VAL" function. Test and let me know.
code:
$Domain = "us-tyco-e" $Account = "habtest1"
? "WinNT://$Domain/$Account,user" $oAccount=getobject("WinNT://$Domain/$Account,user") ? @serror + " " +vartypename($oAccount)
$val=$oAccount.UserFlags ? @serror ? $Val
$Val = $val | val("&40") ? $Val
$oAccount.Put ("UserFlags", $Val ) ? "setinfo " +@serror
$oAccount.SetInfo ? "setinfo " +@serror
? "WinNT://$Domain/$Account,user" $oAccount=getobject("WinNT://$Domain/$Account,user")
$val=$oAccount.UserFlags ? @serror ? $Val
[ 26. August 2002, 01:33: Message edited by: Howard Bullock ]
|
Top
|
|
|
|
#87478 - 2002-08-26 01:50 AM
Re: Scripting "User cannot change password" option
|
Howard Bullock
KiX Supporter
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
My statement about the VAL function was incorrect. I spoke before I tested. code:
$Val = $val | &40
worked too. [ 26. August 2002, 01:51: Message edited by: Howard Bullock ]
|
Top
|
|
|
|
#87479 - 2002-08-26 02:56 AM
Re: Scripting "User cannot change password" option
|
Glen D.
Lurker
Registered: 2002-08-25
Posts: 4
Loc: State College, Pennsylvania, U...
|
Thanks! It does seem to work properly under the WINNT provider. I was working primarily under the LDAP provider since this was part of a user creation script and I was using LDAP to get the users into the correct OUs. I guess next time I should just try it before reading the documentation from MS
Thanks again. (Heck, I'll even buy AMP connectors next time I put in an order )
|
Top
|
|
|
|
#87480 - 2002-09-12 08:53 PM
Re: Scripting "User cannot change password" option
|
Bonji
Starting to like KiXtart
Registered: 2001-09-28
Posts: 169
Loc: Virginia
|
I've got the hard part of this issue done, the only problem is that my OR operation is returning the same value. I quickly wrote up a test script to make sure I was doing it properly. Here it is...
code:
BREAK ON $VAR1 = 577 $VAR1 = $VAR1 | &40 ? $VAR1
$VAR1 is returning 577. If I'm not mistaken the operation should look something like this...
code:
10-01000001 (577) | (OR) 00-01000000 (64) RESULT (Equals) 10-00000001 (513)
Can someone shed some light on this for me?
Thanks, Ben [ 12. September 2002, 20:58: Message edited by: Ben Dulaney ]
|
Top
|
|
|
|
#87486 - 2002-09-13 02:47 PM
Re: Scripting "User cannot change password" option
|
Howard Bullock
KiX Supporter
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
|
Does code:
$VAR1 = $Var1 - ($VAR1 & &40)
get you where you need to go? [ 13. September 2002, 14:48: Message edited by: Howard Bullock ]
|
Top
|
|
|
|
#87487 - 2002-09-13 02:58 PM
Re: Scripting "User cannot change password" option
|
Bonji
Starting to like KiXtart
Registered: 2001-09-28
Posts: 169
Loc: Virginia
|
That works when it is set to 577. However if I wanted to go from 513 back to 577 (turn the bit back on) that would not work. I need an operation that can flip-flop and flop-flip a bit in a binary number.
Thanks, Ben [ 13. September 2002, 14:59: Message edited by: Ben Dulaney ]
|
Top
|
|
|
|
#87488 - 2002-09-13 03:04 PM
Re: Scripting "User cannot change password" option
|
Bonji
Starting to like KiXtart
Registered: 2001-09-28
Posts: 169
Loc: Virginia
|
After a little creative thinking I think this may do the trick...
code:
BREAK ON $VAR1=577 ? $VAR1 $VAR2=$VAR1 - ($VAR1 & &40) IF $VAR1 = $VAR2 ;The bit was off $VAR1 = $VAR1 + &40 ELSE ;The bit was on $VAR1 = $VAR1 - &40 ENDIF ? $VAR1
Thanks for your input Howard. It put me on the road to binary bliss.
This could be setup as a UDF
code:
Function XOR($BinaryVal,$Bit) ;&BinaryVal = Value of binary number // $Bit = Value of bit to swap Dim $TstBit $TstBit = $Bit WHILE $TstBit MOD 2 = 0 AND $TstBit <> 1 $TstBit = $TstBit / 2 LOOP IF $TstBit <> 1 ? "The bit is not a power of 2!" RETURN ENDIF Dim $TmpVar $TmpVar=$BinaryVal - ($BinaryVal & $Bit) IF $TmpVar = $BinaryVal ;The bit was off $XOR = $BinaryVal + $Bit ELSE ;The bit was on $XOR = $BinaryVal - $Bit ENDIF EndFunction
Some method of checking $Bit to be sure it's a power of 2 would be good also. *UPDATE* I went ahead and decided to be proactive and added a routine to check the $Bit value. It's inlcuded in the above UDF.
Thanks, Ben [ 13. September 2002, 15:49: Message edited by: Ben Dulaney ]
|
Top
|
|
|
|
Moderator: Shawn, ShaneEP, Ruud van Velsen, Arend_, Jochen, Radimus, Glenn Barnas, Allen, Mart
|
0 registered
and 128 anonymous users online.
|
|
|