Link to home
Start Free TrialLog in
Avatar of jharrell2
jharrell2

asked on

Setting userAccountControl

I have an application that will create a user for me with a specified UAC.  In short I want a normal user (512) + add the property 'user must change password at next logon".  I've tried 544, but the user isnt prompted to change their pw.  I thought UAC #'s 8389120, 8389152, but i'm not getting that property set.  Any help would be appreciated.

Thanks
Avatar of mrmarkfury
mrmarkfury
Flag of United States of America image

Have you assigned a password in addition to making userAccountControl = 544?
Avatar of jharrell2
jharrell2

ASKER

yes, i am sending a password.  I did send pwdlastSet = 0x0 and ad rejected it.  I'll try just 0 with uac 544.  I'll post back in a few
ok,  i'm sending a '0' but it looks like AD just has the vaule of the time the account was created. (not 0).  The software developers recommend i look at msDS-User-Account-Control-Computed attribute.  My finding have been that UAC is backward compatable on server 2003.
Why are you trying to set the UAC to 544?  All you should need is 512.  The additional '32' you are adding is for the UAC flag for PASSWD_NOTREQD.  You don't want that.

After creating the account with UAC of 512, set the pwdLastSet attribute to 0.  That should be all that's needed.  

Keep in mind, you may have to take into account AD replication, depending on how your environment is set up and how your script is written.  If your application/script uses the Windows APIs to auto-locate a DC during run, there's a chance it'll get a DC different from the one the user is currently authenticating to.  You can force your script to use a specific server if needed.
*additional info*
Here is a listing of the userAccountControl flags:  http://support.microsoft.com/kb/305144

Per the article above, the PASSWORD_EXPIRED flag has been deprecated along with another one.  ms-DS-User-Account-Control-Computed is now used in lieu of those.  I'm not 100% certain but since attribute seems to be a 'computed' value, hence it's name.  Computed values are typically 'read-only', so I'm not sure this will do you any good.

See below for a code example that should be able to expire the PW as you intend.  Note, this code assumes the user is already created, in order to be pulled/set to the objUser object.  If you require code to set this option during user account creation, this will need tweaked/adapted into your existing code.
' Bind to the user object.
Set objUser = GetObject("LDAP://cn=myuser,cn=users,dc=MyDomain,dc=com")
 
' Expire the password.
objUser.pwdLastSet = 0
 
' Save changes.
objUser.SetInfo

Open in new window

Ok, I guess I should have mentioned that earlier..  I am unable to pass 512.

What i'm working with here is a student information system.  The software will create AD accounts but places them into a 'disabled' state.  So, i pass a UAC after creation (internal to the SIS).  But for whatever reason I receive an (very generic) error if I pass 512 (could it possibly be a security policy).  544 works, but i was using that just for troubleshooting purposes.   I can work with their tech-support more, but they want to charge me consulting fees, foofs.

I'll try passing 512 again, but i'm sure it'll fail.  We're doing DB maintenance tonight so it'll be tomorrow before i'll be able to make the changes.
Can you gather some more information?  I'd like to know the following:

1) the existing value of userAccountControl after it is created (before you do anything with it)
2) the code you're using to pass the value.  

It's very possible the account already has the 512, as that signifies it's a normal user account and should be set automatically when the account is created.  Depending on how you're trying to apply it, it can fail.  Typically you set userAccountControl flags using AND or XOR operations vs setting the value directly.

With that said, if you are just trying to enable the account, you should only have to take the existing userAccountControl value and XOR it to the value for the disabled flag.  For example:


Const ADS_UF_ACCOUNTDISABLE = 2
 
' Bind to the user object.
Set objUser = GetObject("LDAP://cn=myuser,cn=users,dc=MyDomain,dc=com")
 
' Expire the password.
objUser.Put "pwdLastSet", 0  
 
' get userAccountControl flags
intUAC = objUser.Get("userAccountControl")
 
' If account is disabled
If intUAC And ADS_UF_ACCOUNTDISABLE Then  
     ' Renable it
     objUser.Put "userAccountControl", intUAC Xor ADS_UF_ACCOUNTDISABLE 
End If
 
' Save changes.
objUser.SetInfo

Open in new window

I dont have access to see the code behind this.  I'm assuming its java based code.  If I  do not pass a value the account is created "546" disabled.  I can change the UAC with an external script after the fact, but this is not an option.  I guess my question is:  Does AD restrict passing 512 at the point of account creation via scripting?  Where might i find this to disable it?

I'm working with their support, they have a way to run a  2nd process after the account is created, this may be our solution.
Step 1) Account created in disabled state
Step 2) Display name, Cn passed, UAC passed, PwdlastSet passed
I must admit, I'm at a loss for what you are asking for.  I don't understand the process that you have in place.  Can you clarify this?  This is what I've gathered so far.

1) you have an automated process that provisions accounts.  This is out of your control entirely.
2) you don't want to use an external script to modify the userAccountControl flags.

How exactly are you trying to pass the userAccountControl value that you are trying to pass if you have no access to the code behind and aren't using an external script?  Does this application provide you some sort of parameter list that you can modify, with userAccountControl being one of them?

I'm also still confused by why this program is passing 546 as the default value.  This value is a culmination of 3 flags:
1) normal user account: 512
2) account is disabled: 2
3) password not required: 32

So this process is making a normal user account that is disabled and has no password set?
haha, trust me you are not the only one confused!

Ok, this student info system will create AD accounts once they've been classified as 'student'.  In a subroutine i have determines which DC to be sent to along with the UAC.  Honestly i cant explain the mechanics of how this works.  The only part I have control of is the subroutine, which is a code base i've never seen before.

But yes, if i dont set userAccountControl by default is 546.  But a password is sent, the flag states that password is not required, which by my understanding that a student could set their password to blank if they wish. (it overrides security policies)

I'll attach the line in this subroutine so it may clarify.  As you can see, i'm just setting a variable in the SIS, In another location i'm actually mapping this equal to AD's userAccountControl attribute.
AL.LDAP.ATTRIBUTES<1,-1> = "E06.ACCT.CTRL=544"

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of FADVMSAdmin
FADVMSAdmin

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yea, i've assumed it was a problem with the SIS provisioning the account.  I thought I'd ask if anyone knew of something i could be doing wrong.

thanks for the help
no where in this article is it clear what language is being written in... my guess is a vbs script running on localhost ActiveDirectory...