views:

97

answers:

1

Hi guys,

with help from two people on stackoverflow I've figured out how to set the "user cannot change password" using the code below. I'm now trying to figure out how to remove the property. I thought setting the denied flag to "allow" would work but it seems to do nothing. I would like the code to be using DirectoryEntry and not PrincipalContext if possible as I'm not sure if my app will be using .NET 3.5 on all the servers. Any help on this would be greatly appreciated.

            string PASSWORD_GUID = "{ab721a53-1e2f-11d0-9819-00aa0040529b}";
            string [] trustees = {"NT AUTHORITY\\SELF", "EVERYONE"};

            ActiveDs.IADsSecurityDescriptor sd = (ActiveDs.IADsSecurityDescriptor)User.Properties["ntSecurityDescriptor"].Value;
            ActiveDs.IADsAccessControlList acl = (ActiveDs.IADsAccessControlList) sd.DiscretionaryAcl;
            ActiveDs.AccessControlEntry ace = new ActiveDs.AccessControlEntry();        


            double denied = (double)ActiveDs.ADS_ACETYPE_ENUM.ADS_ACETYPE_ACCESS_DENIED_OBJECT;
            double objectType = (double)ActiveDs.ADS_FLAGTYPE_ENUM.ADS_FLAG_OBJECT_TYPE_PRESENT;
            double dsControl = (double)ActiveDs.ADS_RIGHTS_ENUM.ADS_RIGHT_DS_CONTROL_ACCESS;

            foreach (string trustee in trustees) {
                ace.Trustee = trustee;
                ace.AceFlags = 0;                
                ace.AceType = Convert.ToInt32(Math.Floor(denied));
                ace.Flags = Convert.ToInt32(Math.Floor(objectType));
                ace.ObjectType = PASSWORD_GUID;
                ace.AccessMask = Convert.ToInt32(Math.Floor(dsControl));

                acl.AddAce(ace);
            }
            sd.DiscretionaryAcl = acl;
            User.Properties["ntSecurityDescriptor"].Value
= sd;
            User.CommitChanges();
+1  A: 

I much prefer using the System.DirectoryServices.AccountManagement namespace for this kind of thing (requires .Net 3.5 or higher, I think). Your call becomes much simpler with those objects:

using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "Domain"))
{
    UserPrincipal up = UserPrincipal.FindByIdentity(pc, "Domain\\User");
    up.UserCannotChangePassword = false;
    up.Save();
}
Jacob Proffitt
It requires .NET 3.5 and up, actually
marc_s
You're right. Just noticed that and was headed to correct when I saw your comment :).
Jacob Proffitt
That looks like a much better way though I would like a solution the way I've been doing things as well if any body knows how. I'm not 100% sure if this will be on all servers with 3.5.
Luke