/// <summary> /// Evaluates whether the DACL fulfills the given AdRoleAssertion and returns the list of unsatisfied AceAssertions /// (if any). /// If the assertor was constructed with {@code searchGroups = true} and the roleAssertion specifies a user, /// then /// all group SIDs contained in the roleAssertion will be tested for potential matches in the DACL if any /// rights are /// not directly granted to the user. Also, the 'Everyone' AD group will also be scanned. /// Denied rights are now detected and included in the resulting list. /// @param roleAssertion /// the AdRoleAssertion to test /// @return List of unsatisfied AceAssertions (if any). Empty if none. /// </summary> private List <AceAssertion> FindUnsatisfiedAssertions(AdRoleAssertion roleAssertion) { var acesBySIDMap = new Dictionary <string, List <Ace> >(); for (var i = 0; i < this.dacl.GetAceCount(); i++) { Ace ace = this.dacl.GetAce(i); if (ace.GetSid() != null) { if (!acesBySIDMap.ContainsKey(ace.GetSid().ToString())) { acesBySIDMap.Add(ace.GetSid().ToString(), new List <Ace>()); } acesBySIDMap[ace.GetSid().ToString()].Add(ace); } } // Find any roleAssertion ACEs not matched in the DACL. // Not using Java 8 or other libs for this to keep dependencies of ADSDDL as is. // ------------------------------ var unsatisfiedAssertions = new List <AceAssertion>(roleAssertion.GetAssertions()); var deniedAssertions = new List <AceAssertion>(); SID principal = roleAssertion.GetPrincipal(); if (acesBySIDMap.ContainsKey(principal.ToString())) { this.FindUnmatchedAssertions(acesBySIDMap[principal.ToString()], unsatisfiedAssertions, deniedAssertions, roleAssertion.GetAssertions()); } // There may be denials on groups even if we resolved all assertions - search groups if specified if (this.searchGroups) { if (roleAssertion.IsGroup()) { this.DoEveryoneGroupScan(acesBySIDMap, unsatisfiedAssertions, deniedAssertions, roleAssertion.GetAssertions()); this.MergeDenials(unsatisfiedAssertions, deniedAssertions); return(unsatisfiedAssertions); } List <SID> tokenGroupSiDs = roleAssertion.GetTokenGroups(); if (tokenGroupSiDs == null) { this.DoEveryoneGroupScan(acesBySIDMap, unsatisfiedAssertions, deniedAssertions, roleAssertion.GetAssertions()); this.MergeDenials(unsatisfiedAssertions, deniedAssertions); return(unsatisfiedAssertions); } foreach (SID grpSID in tokenGroupSiDs.Where(grpSID => acesBySIDMap.ContainsKey(grpSID.ToString()))) { this.FindUnmatchedAssertions(acesBySIDMap[grpSID.ToString()], unsatisfiedAssertions, deniedAssertions, roleAssertion.GetAssertions()); } this.DoEveryoneGroupScan(acesBySIDMap, unsatisfiedAssertions, deniedAssertions, roleAssertion.GetAssertions()); } this.MergeDenials(unsatisfiedAssertions, deniedAssertions); return(unsatisfiedAssertions); }
/// <summary> /// Check if user canot change password. /// @param sddl SSDL. /// @return <tt>true</tt> if user cannot change password: <tt>false</tt> otherwise. /// </summary> public static bool IsUserCannotChangePassword(Sddl sddl) { var res = false; List <Ace> aces = sddl.GetDacl().GetAces(); for (var i = 0; !res && i < aces.Count; i++) { Ace ace = aces[i]; if (ace.GetAceType() == AceType.AccessDeniedObjectAceType && ace.GetObjectFlags().GetFlags().Contains(AceObjectFlags.Flag.AceObjectTypePresent)) { if (ace.GetObjectType() == ucpObjectGuid) { SID sid = ace.GetSid(); if (sid.GetSubAuthorities().Count == 1) { if (sid.GetIdentifierAuthority().SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }) && sid.GetSubAuthorities().First().SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x00 }) || sid.GetIdentifierAuthority().SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x05 }) && sid.GetSubAuthorities().First().SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x0a })) { res = true; } } } } } return(res); }
/// <summary> /// Set "User Cannot Change Password ACL". /// @param sddl SDDL. /// @param cannot <tt>true</tt> to set the ACL; <tt>false</tt> to unset. /// @return updated SDDL. /// </summary> public static Sddl UserCannotChangePassword(Sddl sddl, bool cannot) { AceType type = cannot ? AceType.AccessDeniedObjectAceType : AceType.AccessAllowedObjectAceType; Ace self = null; Ace all = null; List <Ace> aces = sddl.GetDacl().GetAces(); for (var i = 0; (all == null || self == null) && i < aces.Count; i++) { Ace ace = aces[i]; if ((ace.GetAceType() == AceType.AccessAllowedObjectAceType || ace.GetAceType() == AceType.AccessDeniedObjectAceType) && ace.GetObjectFlags().GetFlags().Contains(AceObjectFlags.Flag.AceObjectTypePresent)) { if (ace.GetObjectType() == ucpObjectGuid) { SID sid = ace.GetSid(); if (sid.GetSubAuthorities().Count == 1) { if (self == null && sid.GetIdentifierAuthority().SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }) && sid.GetSubAuthorities().First().SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x00 })) { self = ace; self.SetType(type); } else if (all == null && sid.GetIdentifierAuthority().SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x05 }) && sid.GetSubAuthorities().First().SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x0a })) { all = ace; all.SetType(type); } } } } } if (self == null) { // prepare aces self = Ace.NewInstance(type); self.SetObjectFlags(new AceObjectFlags(AceObjectFlags.Flag.AceObjectTypePresent)); self.SetObjectType(ucpObjectGuid); self.SetRights(new AceRights().AddOjectRight(AceRights.ObjectRight.Cr)); SID sid = SID.NewInstance(NumberFacility.GetBytes(0x000000000001, 6)); sid.AddSubAuthority(NumberFacility.GetBytes(0)); self.SetSid(sid); sddl.GetDacl().GetAces().Add(self); } if (all == null) { all = Ace.NewInstance(type); all.SetObjectFlags(new AceObjectFlags(AceObjectFlags.Flag.AceObjectTypePresent)); all.SetObjectType(ucpObjectGuid); all.SetRights(new AceRights().AddOjectRight(AceRights.ObjectRight.Cr)); SID sid = SID.NewInstance(NumberFacility.GetBytes(0x000000000005, 6)); sid.AddSubAuthority(NumberFacility.GetBytes(0x0A)); all.SetSid(sid); sddl.GetDacl().GetAces().Add(all); } return(sddl); }