• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 8854
  • Last Modified:

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
0
jharrell2
Asked:
jharrell2
  • 6
  • 5
  • 2
  • +1
1 Solution
 
mrmarkfuryCommented:
Have you assigned a password in addition to making userAccountControl = 544?
0
 
jharrell2Author Commented:
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
0
 Email signature solution for Office 365

Easily set up a company-wide email signature in Office 365 that works with every email client. Add personalized email signatures to every email in your company. Let users preview their server-level signature in Outlook.

 
jharrell2Author Commented:
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.
0
 
FADVMSAdminCommented:
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.
0
 
FADVMSAdminCommented:
*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

0
 
jharrell2Author Commented:
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.
0
 
FADVMSAdminCommented:
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

0
 
jharrell2Author Commented:
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
0
 
FADVMSAdminCommented:
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?
0
 
jharrell2Author Commented:
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

0
 
FADVMSAdminCommented:
OK I understand now.

I just did some testing, and using the same code above (just modified to remove the if statement and the XORing of the two values, instead directly setting the value I want, I have no issues.
  i.e..    objUser.Put "userAccountControl", 512 (or 544, 546, 514, etc)

That is to say, by directly applying the value I wanted, the account ends up with the correct flags.  I can specify 512 for a normal account, 514 for a normal/disabled, 544 for a normal/password not required, 546 for normal/disabled/password not required, etc. and it takes correctly.

Ultimately if I set a value that corresponds to a user account's flags, the value takes without issue.  If your line of code above errors out when specifying these values, I'd have to say the issue lies somewhere within that process itself.  It's not the value itself causing the error as AD happily accepts them.

At this point I don't think there's anything I can do to help as this seems to go outside the realm of Active Directory itself and is isolated to your process.  Sorry!
0
 
jharrell2Author Commented:
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
0
 
JAaron AndersonProgramming Architect @ Widener UniversityCommented:
no where in this article is it clear what language is being written in... my guess is a vbs script running on localhost ActiveDirectory...
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 6
  • 5
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now