A couple of related puzzles:



The first script almost works.

I'm trying to create a number of users (in a separate script for this
purpose) and enable their account and set their passwords not to expire.



The create-account script (not shown) works fine. This part, whether
integral to the create-account script or stand-alone, manages to do the
second if statement, but not the first. If I swap the if statements it still
does the second, but not the first.



What would cause it to do that? Is it the case that you can only do one
operation at a time? Only the last one takes?



++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



Const ADS_UF_ACCOUNTDISABLE = 2

Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000



Set objUser = GetObject
("LDAP://cn=Atest,ou=PsyUsers,dc=xxx,dc=uuuu,dc=edu")



intUAC = objUser.Get("userAccountControl")



If intUAC AND ADS_UF_ACCOUNTDISABLE Then

objUser.Put "userAccountControl", intUAC XOR ADS_UF_ACCOUNTDISABLE

objUser.SetInfo

End If



If not intUAC AND ADS_UF_DONT_EXPIRE_PASSWD Then

objUser.Put "userAccountControl", intUAC XOR ADS_UF_DONT_EXPIRE_PASSWD

objUser.SetInfo

End If



+++++++++++++++++++++++++++++++++++++++++++++++



And. I can't make this work at all. It says something in the book that the
can't change password property is in "userAccountControl" , but then says
something about it being an "nTSecurityDescriptor". I am not at all clear on
the syntax, I've swapped both values in every permutation, but not got it to
do anything. I've also played with "if" and "if not", doesn't seem to help.



+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Const ADS_UF_PASSWD_CANT_CHANGE = &h00400



Set objUser = GetObject
("LDAP://cn=Atest,ou=PsyUsers,dc=xxx,dc=uuuu,dc=edu")



intUAC = objUser.Get("userAccountControl")



if not intNSD AND ADS_UF_PASSWD_CANT_CHANGE Then

objUser.Put "nTSecurityDescriptor", intUAC XOR ADS_UF_PASSWD_CANT_CHANGE

objUser.SetInfo

End If



+++++++++++++++++++++++++++++++++++++++++++++++



Thanks,

Jerry

Re: User password properties by Richard

Richard
Tue Jul 15 21:25:13 CDT 2003

Hi,

Very interesting. In your first example, you retrieve the userAccountControl
attribute and assign the value to the variable intUAC. Then, you Xor this
value with a mask and save the result as the new value of
userAccountControl. After the the first SetInfo is invoked, note that the
userAccountControl attribute has a new value, but not the variable intUAC.
It still has the original value. Next, you Xor intUAC with another mask and
save the result as a new value of userAccountControl, overwritting the
previous value. The solution would be do all operations on intUAC and not
write the final value to userAccountControl until the end. For example:

blnModified = False
If intUAC And ADS_UF_ACCOUNTDISABLE Then
intUAC = intUAC Xor ADS_UF_ACCOUNTDISABLE
blnModified = True
End If

If intUAC And ADS_UF_DONT_EXPIRE_PASSWORD Then
intUAC = intUAC Xor ADS_UF_DONT_EXPIRE_PASSWORD
blnModified = True
End If

If blnModified = True Then
objUser.Put "userAccountControl", intUAC
objUser.SetInfo
End If

Next, the value for ADS_UF_PASSWD_CANT_CHANGE is actually &h40, not &h400.
However, it doesn't matter. userAccountControl is not used for this, but
rather the ntSecurityDescriptor for the user object. Two ACE's (Access
Control Entries) are added to the DACL (Descretionary Access Control List)
in the security descriptor for the user object to deny permission to change
the password. To grant permission to change the password, these two ACE's
are removed from the DACL. See Microsoft KB articles 301287 and 269159. An
example program to deny permission for a user to change their own password
is at this link:

http://www.rlmueller.net/Cannot%20Change%20PW.htm

The companion program to grant permission for a user the change their own
password is:

http://www.rlmueller.net/Can%20Change%20PW.htm

Both programs require ADsSecurity.dll be registered on the client. Any
computer with W2k or above has this. The programs also refer to the trustees
"Everyone" and "NT Authority\Self". If the client language is other than
English, the trustee names will be different and the programs won't work. I
haven't yet worked out the code to refer to these trustees by their
well-known Sids, to make the programs language independent. Someone from the
Netherlands complained.

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--

"Jerry Parlee" <parlee@psy.utexas.edu> wrote in message
news:uH6vtnySDHA.2008@TK2MSFTNGP11.phx.gbl...
> A couple of related puzzles:
>
>
>
> The first script almost works.
>
> I'm trying to create a number of users (in a separate script for this
> purpose) and enable their account and set their passwords not to expire.
>
>
>
> The create-account script (not shown) works fine. This part, whether
> integral to the create-account script or stand-alone, manages to do the
> second if statement, but not the first. If I swap the if statements it
still
> does the second, but not the first.
>
>
>
> What would cause it to do that? Is it the case that you can only do one
> operation at a time? Only the last one takes?
>
>
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
>
>
> Const ADS_UF_ACCOUNTDISABLE = 2
>
> Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000
>
>
>
> Set objUser = GetObject
> ("LDAP://cn=Atest,ou=PsyUsers,dc=xxx,dc=uuuu,dc=edu")
>
>
>
> intUAC = objUser.Get("userAccountControl")
>
>
>
> If intUAC AND ADS_UF_ACCOUNTDISABLE Then
>
> objUser.Put "userAccountControl", intUAC XOR ADS_UF_ACCOUNTDISABLE
>
> objUser.SetInfo
>
> End If
>
>
>
> If not intUAC AND ADS_UF_DONT_EXPIRE_PASSWD Then
>
> objUser.Put "userAccountControl", intUAC XOR ADS_UF_DONT_EXPIRE_PASSWD
>
> objUser.SetInfo
>
> End If
>
>
>
> +++++++++++++++++++++++++++++++++++++++++++++++
>
>
>
> And. I can't make this work at all. It says something in the book that
the
> can't change password property is in "userAccountControl" , but then says
> something about it being an "nTSecurityDescriptor". I am not at all clear
on
> the syntax, I've swapped both values in every permutation, but not got it
to
> do anything. I've also played with "if" and "if not", doesn't seem to
help.
>
>
>
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> Const ADS_UF_PASSWD_CANT_CHANGE = &h00400
>
>
>
> Set objUser = GetObject
> ("LDAP://cn=Atest,ou=PsyUsers,dc=xxx,dc=uuuu,dc=edu")
>
>
>
> intUAC = objUser.Get("userAccountControl")
>
>
>
> if not intNSD AND ADS_UF_PASSWD_CANT_CHANGE Then
>
> objUser.Put "nTSecurityDescriptor", intUAC XOR ADS_UF_PASSWD_CANT_CHANGE
>
> objUser.SetInfo
>
> End If
>
>
>
> +++++++++++++++++++++++++++++++++++++++++++++++
>
>
>
> Thanks,
>
> Jerry
>
>



Re: User password properties by Richard

Richard
Tue Jul 15 21:42:09 CDT 2003

Hi,

An interesting program from the TechNet Script Center to determine if
ADS_UF_CANT_CHANGE is set by reading the ntSecurityDescriptor rather than
userAccountControl:

http://www.microsoft.com/technet/treeview/default.asp?url=/technet/scriptcen
ter/user/scrug33.asp

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Richard Mueller [MVP]" <rlmueller@ameritech.net> wrote in message
news:#gPZ6O0SDHA.3796@tk2msftngp13.phx.gbl...
> Hi,
>
> Very interesting. In your first example, you retrieve the
userAccountControl
> attribute and assign the value to the variable intUAC. Then, you Xor this
> value with a mask and save the result as the new value of
> userAccountControl. After the the first SetInfo is invoked, note that the
> userAccountControl attribute has a new value, but not the variable intUAC.
> It still has the original value. Next, you Xor intUAC with another mask
and
> save the result as a new value of userAccountControl, overwritting the
> previous value. The solution would be do all operations on intUAC and not
> write the final value to userAccountControl until the end. For example:
>
> blnModified = False
> If intUAC And ADS_UF_ACCOUNTDISABLE Then
> intUAC = intUAC Xor ADS_UF_ACCOUNTDISABLE
> blnModified = True
> End If
>
> If intUAC And ADS_UF_DONT_EXPIRE_PASSWORD Then
> intUAC = intUAC Xor ADS_UF_DONT_EXPIRE_PASSWORD
> blnModified = True
> End If
>
> If blnModified = True Then
> objUser.Put "userAccountControl", intUAC
> objUser.SetInfo
> End If
>
> Next, the value for ADS_UF_PASSWD_CANT_CHANGE is actually &h40, not &h400.
> However, it doesn't matter. userAccountControl is not used for this, but
> rather the ntSecurityDescriptor for the user object. Two ACE's (Access
> Control Entries) are added to the DACL (Descretionary Access Control List)
> in the security descriptor for the user object to deny permission to
change
> the password. To grant permission to change the password, these two ACE's
> are removed from the DACL. See Microsoft KB articles 301287 and 269159. An
> example program to deny permission for a user to change their own password
> is at this link:
>
> http://www.rlmueller.net/Cannot%20Change%20PW.htm
>
> The companion program to grant permission for a user the change their own
> password is:
>
> http://www.rlmueller.net/Can%20Change%20PW.htm
>
> Both programs require ADsSecurity.dll be registered on the client. Any
> computer with W2k or above has this. The programs also refer to the
trustees
> "Everyone" and "NT Authority\Self". If the client language is other than
> English, the trustee names will be different and the programs won't work.
I
> haven't yet worked out the code to refer to these trustees by their
> well-known Sids, to make the programs language independent. Someone from
the
> Netherlands complained.
>
> --
> Richard
> Microsoft MVP Scripting and ADSI
> HilltopLab web site - http://www.rlmueller.net
> --
>
> "Jerry Parlee" <parlee@psy.utexas.edu> wrote in message
> news:uH6vtnySDHA.2008@TK2MSFTNGP11.phx.gbl...
> > A couple of related puzzles:
> >
> >
> >
> > The first script almost works.
> >
> > I'm trying to create a number of users (in a separate script for this
> > purpose) and enable their account and set their passwords not to expire.
> >
> >
> >
> > The create-account script (not shown) works fine. This part, whether
> > integral to the create-account script or stand-alone, manages to do the
> > second if statement, but not the first. If I swap the if statements it
> still
> > does the second, but not the first.
> >
> >
> >
> > What would cause it to do that? Is it the case that you can only do one
> > operation at a time? Only the last one takes?
> >
> >
> >
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >
> >
> >
> > Const ADS_UF_ACCOUNTDISABLE = 2
> >
> > Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000
> >
> >
> >
> > Set objUser = GetObject
> > ("LDAP://cn=Atest,ou=PsyUsers,dc=xxx,dc=uuuu,dc=edu")
> >
> >
> >
> > intUAC = objUser.Get("userAccountControl")
> >
> >
> >
> > If intUAC AND ADS_UF_ACCOUNTDISABLE Then
> >
> > objUser.Put "userAccountControl", intUAC XOR ADS_UF_ACCOUNTDISABLE
> >
> > objUser.SetInfo
> >
> > End If
> >
> >
> >
> > If not intUAC AND ADS_UF_DONT_EXPIRE_PASSWD Then
> >
> > objUser.Put "userAccountControl", intUAC XOR ADS_UF_DONT_EXPIRE_PASSWD
> >
> > objUser.SetInfo
> >
> > End If
> >
> >
> >
> > +++++++++++++++++++++++++++++++++++++++++++++++
> >
> >
> >
> > And. I can't make this work at all. It says something in the book that
> the
> > can't change password property is in "userAccountControl" , but then
says
> > something about it being an "nTSecurityDescriptor". I am not at all
clear
> on
> > the syntax, I've swapped both values in every permutation, but not got
it
> to
> > do anything. I've also played with "if" and "if not", doesn't seem to
> help.
> >
> >
> >
> > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >
> > Const ADS_UF_PASSWD_CANT_CHANGE = &h00400
> >
> >
> >
> > Set objUser = GetObject
> > ("LDAP://cn=Atest,ou=PsyUsers,dc=xxx,dc=uuuu,dc=edu")
> >
> >
> >
> > intUAC = objUser.Get("userAccountControl")
> >
> >
> >
> > if not intNSD AND ADS_UF_PASSWD_CANT_CHANGE Then
> >
> > objUser.Put "nTSecurityDescriptor", intUAC XOR
ADS_UF_PASSWD_CANT_CHANGE
> >
> > objUser.SetInfo
> >
> > End If
> >
> >
> >
> > +++++++++++++++++++++++++++++++++++++++++++++++
> >
> >
> >
> > Thanks,
> >
> > Jerry
> >
> >
>
>



Re: User password properties by Jerry

Jerry
Wed Jul 16 10:32:56 CDT 2003

D'oh... That's what comes of a partial understanding...

Of course. As soon as I reinitialized intUAC it also works fine.

I'm playing with the "ADS_UF_PASSWD_CANT_CHANGE" bit now.
I wonder if it would be just as good to hide that property in a GPO.

Thanks,
Jerry

"Richard Mueller [MVP]" <rlmueller@ameritech.net> wrote in message
news:%23gPZ6O0SDHA.3796@tk2msftngp13.phx.gbl...
> Hi,
>
> Very interesting. In your first example, you retrieve the
userAccountControl
> attribute and assign the value to the variable intUAC. Then, you Xor this
> value with a mask and save the result as the new value of
> userAccountControl. After the the first SetInfo is invoked, note that the
> userAccountControl attribute has a new value, but not the variable intUAC.
> It still has the original value. Next, you Xor intUAC with another mask
and
> save the result as a new value of userAccountControl, overwritting the
> previous value. The solution would be do all operations on intUAC and not
> write the final value to userAccountControl until the end. For example:
>
> blnModified = False
> If intUAC And ADS_UF_ACCOUNTDISABLE Then
> intUAC = intUAC Xor ADS_UF_ACCOUNTDISABLE
> blnModified = True
> End If
>
> If intUAC And ADS_UF_DONT_EXPIRE_PASSWORD Then
> intUAC = intUAC Xor ADS_UF_DONT_EXPIRE_PASSWORD
> blnModified = True
> End If
>
> If blnModified = True Then
> objUser.Put "userAccountControl", intUAC
> objUser.SetInfo
> End If
>
> Next, the value for ADS_UF_PASSWD_CANT_CHANGE is actually &h40, not &h400.
> However, it doesn't matter. userAccountControl is not used for this, but
> rather the ntSecurityDescriptor for the user object. Two ACE's (Access
> Control Entries) are added to the DACL (Descretionary Access Control List)
> in the security descriptor for the user object to deny permission to
change
> the password. To grant permission to change the password, these two ACE's
> are removed from the DACL. See Microsoft KB articles 301287 and 269159. An
> example program to deny permission for a user to change their own password
> is at this link:
>
> http://www.rlmueller.net/Cannot%20Change%20PW.htm
>
> The companion program to grant permission for a user the change their own
> password is:
>
> http://www.rlmueller.net/Can%20Change%20PW.htm
>
> Both programs require ADsSecurity.dll be registered on the client. Any
> computer with W2k or above has this. The programs also refer to the
trustees
> "Everyone" and "NT Authority\Self". If the client language is other than
> English, the trustee names will be different and the programs won't work.
I
> haven't yet worked out the code to refer to these trustees by their
> well-known Sids, to make the programs language independent. Someone from
the
> Netherlands complained.
>
> --
> Richard
> Microsoft MVP Scripting and ADSI
> HilltopLab web site - http://www.rlmueller.net
> --
>
> "Jerry Parlee" <parlee@psy.utexas.edu> wrote in message
> news:uH6vtnySDHA.2008@TK2MSFTNGP11.phx.gbl...
> > A couple of related puzzles:
> >
> >
> >
> > The first script almost works.
> >
> > I'm trying to create a number of users (in a separate script for this
> > purpose) and enable their account and set their passwords not to expire.
> >
> >
> >
> > The create-account script (not shown) works fine. This part, whether
> > integral to the create-account script or stand-alone, manages to do the
> > second if statement, but not the first. If I swap the if statements it
> still
> > does the second, but not the first.
> >
> >
> >
> > What would cause it to do that? Is it the case that you can only do one
> > operation at a time? Only the last one takes?
> >
> >
> >
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >
> >
> >
> > Const ADS_UF_ACCOUNTDISABLE = 2
> >
> > Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000
> >
> >
> >
> > Set objUser = GetObject
> > ("LDAP://cn=Atest,ou=PsyUsers,dc=xxx,dc=uuuu,dc=edu")
> >
> >
> >
> > intUAC = objUser.Get("userAccountControl")
> >
> >
> >
> > If intUAC AND ADS_UF_ACCOUNTDISABLE Then
> >
> > objUser.Put "userAccountControl", intUAC XOR ADS_UF_ACCOUNTDISABLE
> >
> > objUser.SetInfo
> >
> > End If
> >
> >
> >
> > If not intUAC AND ADS_UF_DONT_EXPIRE_PASSWD Then
> >
> > objUser.Put "userAccountControl", intUAC XOR ADS_UF_DONT_EXPIRE_PASSWD
> >
> > objUser.SetInfo
> >
> > End If
> >
> >
> >
> > +++++++++++++++++++++++++++++++++++++++++++++++
> >
> >
> >
> > And. I can't make this work at all. It says something in the book that
> the
> > can't change password property is in "userAccountControl" , but then
says
> > something about it being an "nTSecurityDescriptor". I am not at all
clear
> on
> > the syntax, I've swapped both values in every permutation, but not got
it
> to
> > do anything. I've also played with "if" and "if not", doesn't seem to
> help.
> >
> >
> >
> > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >
> > Const ADS_UF_PASSWD_CANT_CHANGE = &h00400
> >
> >
> >
> > Set objUser = GetObject
> > ("LDAP://cn=Atest,ou=PsyUsers,dc=xxx,dc=uuuu,dc=edu")
> >
> >
> >
> > intUAC = objUser.Get("userAccountControl")
> >
> >
> >
> > if not intNSD AND ADS_UF_PASSWD_CANT_CHANGE Then
> >
> > objUser.Put "nTSecurityDescriptor", intUAC XOR
ADS_UF_PASSWD_CANT_CHANGE
> >
> > objUser.SetInfo
> >
> > End If
> >
> >
> >
> > +++++++++++++++++++++++++++++++++++++++++++++++
> >
> >
> >
> > Thanks,
> >
> > Jerry
> >
> >
>
>