private DBConnectionString(DBConnectionString connectionString, string[] restrictionValues, KeyRestrictionBehavior behavior) { // used by intersect for two equal connection strings with different restrictions _encryptedUsersConnectionString = connectionString._encryptedUsersConnectionString; _parsetable = connectionString._parsetable; _keychain = connectionString._keychain; _hasPassword = connectionString._hasPassword; _restrictionValues = restrictionValues; _restrictions = null; _behavior = behavior; Verify(restrictionValues); }
private NameValuePermission(NameValuePermission permit) // deep-copy { _value = permit._value; _entry = permit._entry; _tree = permit._tree; if (null != _tree) { NameValuePermission[] tree = (_tree.Clone() as NameValuePermission[]); for (int i = 0; i < tree.Length; ++i) { if (null != tree[i]) // WebData 98488 { tree[i] = tree[i].CopyNameValue(); // deep copy } } _tree = tree; } }
internal bool IsSupersetOf(DBConnectionString entry) { Debug.Assert(!_hasPassword || ContainsKey(KEY.Password) || ContainsKey(KEY.Pwd), "OnDeserialized password mismatch this"); Debug.Assert(!entry._hasPassword || entry.ContainsKey(KEY.Password) || entry.ContainsKey(KEY.Pwd), "OnDeserialized password mismatch entry"); switch (_behavior) { case KeyRestrictionBehavior.AllowOnly: // every key must either be in the resticted connection string or in the allowed keywords // keychain may contain duplicates, but it is better than GetEnumerator on _parsetable.Keys for (NameValuePair current = entry.KeyChain; null != current; current = current.Next) { if (!ContainsKey(current.Name) && IsRestrictedKeyword(current.Name)) { return(false); } } break; case KeyRestrictionBehavior.PreventUsage: // every key can not be in the restricted keywords (even if in the restricted connection string) if (null != _restrictionValues) { foreach (string restriction in _restrictionValues) { if (entry.ContainsKey(restriction)) { return(false); } } } break; default: Debug.Assert(false, "invalid KeyRestrictionBehavior"); throw ADP.InvalidKeyRestrictionBehavior(_behavior); } return(true); }
internal DBConnectionString Intersect(DBConnectionString entry) { KeyRestrictionBehavior behavior = _behavior; string[] restrictionValues = null; if (null == entry) { //Debug.WriteLine("0 entry AllowNothing"); behavior = KeyRestrictionBehavior.AllowOnly; } else if (this._behavior != entry._behavior) // subset of the AllowOnly array { behavior = KeyRestrictionBehavior.AllowOnly; if (KeyRestrictionBehavior.AllowOnly == entry._behavior) // this PreventUsage and entry AllowOnly { if (!ADP.IsEmptyArray(_restrictionValues)) { if (!ADP.IsEmptyArray(entry._restrictionValues)) { //Debug.WriteLine("1 this PreventUsage with restrictions and entry AllowOnly with restrictions"); restrictionValues = NewRestrictionAllowOnly(entry._restrictionValues, _restrictionValues); } else { //Debug.WriteLine("2 this PreventUsage with restrictions and entry AllowOnly with no restrictions"); } } else { //Debug.WriteLine("3/4 this PreventUsage with no restrictions and entry AllowOnly"); restrictionValues = entry._restrictionValues; } } else if (!ADP.IsEmptyArray(_restrictionValues)) // this AllowOnly and entry PreventUsage { if (!ADP.IsEmptyArray(entry._restrictionValues)) { //Debug.WriteLine("5 this AllowOnly with restrictions and entry PreventUsage with restrictions"); restrictionValues = NewRestrictionAllowOnly(_restrictionValues, entry._restrictionValues); } else { //Debug.WriteLine("6 this AllowOnly and entry PreventUsage with no restrictions"); restrictionValues = _restrictionValues; } } else { //Debug.WriteLine("7/8 this AllowOnly with no restrictions and entry PreventUsage"); } } else if (KeyRestrictionBehavior.PreventUsage == this._behavior) // both PreventUsage { if (ADP.IsEmptyArray(_restrictionValues)) { //Debug.WriteLine("9/10 both PreventUsage and this with no restrictions"); restrictionValues = entry._restrictionValues; } else if (ADP.IsEmptyArray(entry._restrictionValues)) { //Debug.WriteLine("11 both PreventUsage and entry with no restrictions"); restrictionValues = _restrictionValues; } else { //Debug.WriteLine("12 both PreventUsage with restrictions"); restrictionValues = NoDuplicateUnion(_restrictionValues, entry._restrictionValues); } } else if (!ADP.IsEmptyArray(_restrictionValues) && !ADP.IsEmptyArray(entry._restrictionValues)) // both AllowOnly with restrictions { if (this._restrictionValues.Length <= entry._restrictionValues.Length) { //Debug.WriteLine("13a this AllowOnly with restrictions and entry AllowOnly with restrictions"); restrictionValues = NewRestrictionIntersect(_restrictionValues, entry._restrictionValues); } else { //Debug.WriteLine("13b this AllowOnly with restrictions and entry AllowOnly with restrictions"); restrictionValues = NewRestrictionIntersect(entry._restrictionValues, _restrictionValues); } } else // both AllowOnly //Debug.WriteLine("14/15/16 this AllowOnly and entry AllowOnly but no restrictions"); { } // verify _hasPassword & _parsetable are in sync between Everett/Whidbey Debug.Assert(!_hasPassword || ContainsKey(KEY.Password) || ContainsKey(KEY.Pwd), "OnDeserialized password mismatch this"); Debug.Assert(null == entry || !entry._hasPassword || entry.ContainsKey(KEY.Password) || entry.ContainsKey(KEY.Pwd), "OnDeserialized password mismatch entry"); DBConnectionString value = new DBConnectionString(this, restrictionValues, behavior); ValidateCombinedSet(this, value); ValidateCombinedSet(entry, value); return(value); }
static internal void AddEntry(NameValuePermission kvtree, ArrayList entries, DBConnectionString entry) { Debug.Assert(null != entry, "null DBConnectionString"); if (null != entry.KeyChain) { for (NameValuePair keychain = entry.KeyChain; null != keychain; keychain = keychain.Next) { NameValuePermission kv; kv = kvtree.CheckKeyForValue(keychain.Name); if (null == kv) { kv = new NameValuePermission(keychain.Name); kvtree.Add(kv); // add directly into live tree } kvtree = kv; kv = kvtree.CheckKeyForValue(keychain.Value); if (null == kv) { DBConnectionString insertValue = ((null != keychain.Next) ? null : entry); kv = new NameValuePermission(keychain.Value, insertValue); kvtree.Add(kv); // add directly into live tree if (null != insertValue) { entries.Add(insertValue); } } else if (null == keychain.Next) // shorter chain potential { if (null != kv._entry) { Debug.Assert(entries.Contains(kv._entry), "entries doesn't contain entry"); entries.Remove(kv._entry); kv._entry = kv._entry.Intersect(entry); // union new restrictions into existing tree } else { kv._entry = entry; } entries.Add(kv._entry); } kvtree = kv; } } else // global restrictions, MDAC 84443 { DBConnectionString kentry = kvtree._entry; if (null != kentry) { Debug.Assert(entries.Contains(kentry), "entries doesn't contain entry"); entries.Remove(kentry); kvtree._entry = kentry.Intersect(entry); } else { kvtree._entry = entry; } entries.Add(kvtree._entry); } }
private NameValuePermission(string value, DBConnectionString entry) { _value = value; _entry = entry; }
internal bool CheckValueForKeyPermit(DBConnectionString parsetable) { if (null == parsetable) { return(false); } bool hasMatch = false; NameValuePermission[] keytree = _tree; // _tree won't mutate but Add will replace it if (null != keytree) { hasMatch = parsetable.IsEmpty; // MDAC 86773 if (!hasMatch) { // which key do we follow the key-value chain on for (int i = 0; i < keytree.Length; ++i) { NameValuePermission permitKey = keytree[i]; if (null != permitKey) { string keyword = permitKey._value; #if DEBUG Debug.Assert(null == permitKey._entry, "key member has no restrictions"); #endif if (parsetable.ContainsKey(keyword)) { string valueInQuestion = (string)parsetable[keyword]; // keyword is restricted to certain values NameValuePermission permitValue = permitKey.CheckKeyForValue(valueInQuestion); if (null != permitValue) { //value does match - continue the chain down that branch if (permitValue.CheckValueForKeyPermit(parsetable)) { hasMatch = true; // adding a break statement is tempting, but wrong // user can safetly extend their restrictions for current rule to include missing keyword // i.e. Add("provider=sqloledb;integrated security=sspi", "data provider=", KeyRestrictionBehavior.AllowOnly); // i.e. Add("data provider=msdatashape;provider=sqloledb;integrated security=sspi", "", KeyRestrictionBehavior.AllowOnly); } else // failed branch checking { return(false); } } else // value doesn't match to expected values - fail here { return(false); } } } // else try next keyword } } // partial chain match, either leaf-node by shorter chain or fail mid-chain if (null == _restrictions) } DBConnectionString entry = _entry; if (null != entry) { // also checking !hasMatch is tempting, but wrong // user can safetly extend their restrictions for current rule to include missing keyword // i.e. Add("provider=sqloledb;integrated security=sspi", "data provider=", KeyRestrictionBehavior.AllowOnly); // i.e. Add("provider=sqloledb;", "integrated security=;", KeyRestrictionBehavior.AllowOnly); hasMatch = entry.IsSupersetOf(parsetable); } return(hasMatch); // mid-chain failure }