Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Data / System / Data / Common / DBDataPermission.cs
blobed6140309e9665e30e20dfadecf75aec1b338a9a
1 //------------------------------------------------------------------------------
2 // <copyright file="DBDataPermission.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 //------------------------------------------------------------------------------
9 namespace System.Data.Common {
11 using System.Collections;
12 using System.Data.Common;
13 using System.Diagnostics;
14 using System.Globalization;
15 using System.Runtime.Serialization;
16 using System.Security;
17 using System.Security.Permissions;
18 using System.Text;
20 [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, ControlEvidence=true, ControlPolicy=true)]
21 [Serializable]
22 public abstract class DBDataPermission : CodeAccessPermission, IUnrestrictedPermission {
24 private bool _isUnrestricted;// = false;
25 private bool _allowBlankPassword;// = false;
26 private NameValuePermission _keyvaluetree = NameValuePermission.Default;
27 private /*DBConnectionString[]*/ArrayList _keyvalues; // = null;
29 [ Obsolete("DBDataPermission() has been deprecated. Use the DBDataPermission(PermissionState.None) constructor. http://go.microsoft.com/fwlink/?linkid=14202", true) ] // V1.2.3300, MDAC 86034
30 protected DBDataPermission() : this(PermissionState.None) { // V1.0.3300
33 protected DBDataPermission(PermissionState state) { // V1.0.3300
34 if (state == PermissionState.Unrestricted) {
35 _isUnrestricted = true;
37 else if (state == PermissionState.None) {
38 _isUnrestricted = false;
40 else {
41 throw ADP.InvalidPermissionState(state);
45 [ Obsolete("DBDataPermission(PermissionState state,Boolean allowBlankPassword) has been deprecated. Use the DBDataPermission(PermissionState.None) constructor. http://go.microsoft.com/fwlink/?linkid=14202", true) ] // V1.2.3300, MDAC 86034
46 protected DBDataPermission(PermissionState state, bool allowBlankPassword) : this(state) { // V1.0.3300, MDAC 84281
47 AllowBlankPassword = allowBlankPassword;
50 protected DBDataPermission(DBDataPermission permission) { // V1.0.5000, for Copy
51 if (null == permission) {
52 throw ADP.ArgumentNull("permissionAttribute");
54 CopyFrom(permission);
57 protected DBDataPermission(DBDataPermissionAttribute permissionAttribute) { // V1.0.5000, for CreatePermission
58 if (null == permissionAttribute) {
59 throw ADP.ArgumentNull("permissionAttribute");
61 _isUnrestricted = permissionAttribute.Unrestricted;
62 if (!_isUnrestricted) {
63 _allowBlankPassword = permissionAttribute.AllowBlankPassword;
64 if (permissionAttribute.ShouldSerializeConnectionString() || permissionAttribute.ShouldSerializeKeyRestrictions()) { // MDAC 86773
65 Add(permissionAttribute.ConnectionString, permissionAttribute.KeyRestrictions, permissionAttribute.KeyRestrictionBehavior);
70 // how connectionString security is used
71 // parsetable (all string) is shared with connection
72 internal DBDataPermission(DbConnectionOptions connectionOptions) { // v2.0
73 if (null != connectionOptions) {
74 _allowBlankPassword = connectionOptions.HasBlankPassword; // MDAC 84563
75 AddPermissionEntry(new DBConnectionString(connectionOptions));
79 public bool AllowBlankPassword { // V1.0.3300
80 get {
81 return _allowBlankPassword;
83 set { // MDAC 61263
84 // for behavioral backward compatability with V1.1
85 // set_AllowBlankPassword does not _isUnrestricted=false
86 _allowBlankPassword = value;
90 public virtual void Add(string connectionString, string restrictions, KeyRestrictionBehavior behavior) { // V1.0.5000
91 DBConnectionString constr = new DBConnectionString(connectionString, restrictions, behavior, null, false);
92 AddPermissionEntry(constr);
95 internal void AddPermissionEntry(DBConnectionString entry) {
96 if (null == _keyvaluetree) {
97 _keyvaluetree = new NameValuePermission();
99 if (null == _keyvalues) {
100 _keyvalues = new ArrayList();
102 NameValuePermission.AddEntry(_keyvaluetree, _keyvalues, entry);
103 _isUnrestricted = false; // MDAC 84639
106 protected void Clear() { // V1.2.3300, MDAC 83105
107 _keyvaluetree = null;
108 _keyvalues = null;
111 // IPermission interface methods
112 // [ObsoleteAttribute("override Copy instead of using default implementation")] // not inherited
113 override public IPermission Copy() {
114 DBDataPermission copy = CreateInstance();
115 copy.CopyFrom(this);
116 return copy;
119 private void CopyFrom(DBDataPermission permission) {
120 _isUnrestricted = permission.IsUnrestricted();
121 if (!_isUnrestricted) {
122 _allowBlankPassword = permission.AllowBlankPassword;
124 if (null != permission._keyvalues) {
125 _keyvalues = (ArrayList) permission._keyvalues.Clone();
127 if (null != permission._keyvaluetree) {
128 _keyvaluetree = permission._keyvaluetree.CopyNameValue();
134 // [ Obsolete("use DBDataPermission(DBDataPermission) ctor") ]
135 [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")] // V1.0.5000, MDAC 82936
136 virtual protected DBDataPermission CreateInstance() {
137 // derived class should override with a different implementation avoiding reflection to allow semi-trusted scenarios
138 return (Activator.CreateInstance(GetType(), System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Instance, null, null, CultureInfo.InvariantCulture, null) as DBDataPermission);
141 override public IPermission Intersect(IPermission target) { // used during Deny actions
142 if (null == target) {
143 return null;
145 if (target.GetType() != this.GetType()) {
146 throw ADP.PermissionTypeMismatch();
148 if (this.IsUnrestricted()) { // MDAC 84803, NDPWhidbey 29121
149 return target.Copy();
152 DBDataPermission operand = (DBDataPermission) target;
153 if (operand.IsUnrestricted()) { // NDPWhidbey 29121
154 return this.Copy();
157 DBDataPermission newPermission = (DBDataPermission) operand.Copy();
158 newPermission._allowBlankPassword &= AllowBlankPassword;
160 if ((null != _keyvalues) && (null != newPermission._keyvalues)) {
161 newPermission._keyvalues.Clear();
163 newPermission._keyvaluetree.Intersect(newPermission._keyvalues, _keyvaluetree);
165 else {
166 // either target.Add or this.Add have not been called
167 // return a non-null object so IsSubset calls will fail
168 newPermission._keyvalues = null;
169 newPermission._keyvaluetree = null;
172 if (newPermission.IsEmpty()) { // no intersection, MDAC 86773
173 newPermission = null;
175 return newPermission;
178 private bool IsEmpty() { // MDAC 84804
179 ArrayList keyvalues = _keyvalues;
180 bool flag = (!IsUnrestricted() && !AllowBlankPassword && ((null == keyvalues) || (0 == keyvalues.Count)));
181 return flag;
184 override public bool IsSubsetOf(IPermission target) {
185 if (null == target) {
186 return IsEmpty();
188 if (target.GetType() != this.GetType()) {
189 throw ADP.PermissionTypeMismatch();
192 DBDataPermission superset = (target as DBDataPermission);
194 bool subset = superset.IsUnrestricted();
195 if (!subset) {
196 if (!IsUnrestricted() &&
197 (!AllowBlankPassword || superset.AllowBlankPassword) &&
198 ((null == _keyvalues) || (null != superset._keyvaluetree))) {
200 subset = true;
201 if (null != _keyvalues) {
202 foreach(DBConnectionString kventry in _keyvalues) {
203 if(!superset._keyvaluetree.CheckValueForKeyPermit(kventry)) {
204 subset = false;
205 break;
211 return subset;
214 // IUnrestrictedPermission interface methods
215 public bool IsUnrestricted() {
216 return _isUnrestricted;
219 override public IPermission Union(IPermission target) {
220 if (null == target) {
221 return this.Copy();
223 if (target.GetType() != this.GetType()) {
224 throw ADP.PermissionTypeMismatch();
226 if (IsUnrestricted()) { // MDAC 84803
227 return this.Copy();
230 DBDataPermission newPermission = (DBDataPermission) target.Copy();
231 if (!newPermission.IsUnrestricted()) {
232 newPermission._allowBlankPassword |= AllowBlankPassword;
234 if (null != _keyvalues) {
235 foreach(DBConnectionString entry in _keyvalues) {
236 newPermission.AddPermissionEntry(entry);
240 return (newPermission.IsEmpty() ? null : newPermission);
243 private string DecodeXmlValue(string value) {
244 if ((null != value) && (0 < value.Length)) {
245 value = value.Replace("&quot;", "\"");
246 value = value.Replace("&apos;", "\'");
247 value = value.Replace("&lt;", "<");
248 value = value.Replace("&gt;", ">");
249 value = value.Replace("&amp;", "&");
251 return value;
254 private string EncodeXmlValue(string value) {
255 if ((null != value) && (0 < value.Length)) {
256 value = value.Replace('\0', ' '); // assumption that '\0' will only be at end of string
257 value = value.Trim();
258 value = value.Replace("&", "&amp;");
259 value = value.Replace(">", "&gt;");
260 value = value.Replace("<", "&lt;");
261 value = value.Replace("\'", "&apos;");
262 value = value.Replace("\"", "&quot;");
264 return value;
267 // <IPermission class="...Permission" version="1" AllowBlankPassword=false>
268 // <add ConnectionString="provider=x;data source=y;" KeyRestrictions="address=;server=" KeyRestrictionBehavior=PreventUsage/>
269 // </IPermission>
270 override public void FromXml(SecurityElement securityElement) {
271 // code derived from CodeAccessPermission.ValidateElement
272 if (null == securityElement) {
273 throw ADP.ArgumentNull("securityElement");
275 string tag = securityElement.Tag;
276 if (!tag.Equals(XmlStr._Permission) && !tag.Equals(XmlStr._IPermission)) {
277 throw ADP.NotAPermissionElement();
279 String version = securityElement.Attribute(XmlStr._Version);
280 if ((null != version) && !version.Equals(XmlStr._VersionNumber)) {
281 throw ADP.InvalidXMLBadVersion();
284 string unrestrictedValue = securityElement.Attribute(XmlStr._Unrestricted);
285 _isUnrestricted = (null != unrestrictedValue) && Boolean.Parse(unrestrictedValue);
287 Clear(); // MDAC 83105
288 if (!_isUnrestricted) {
289 string allowNull = securityElement.Attribute(XmlStr._AllowBlankPassword);
290 _allowBlankPassword = (null != allowNull) && Boolean.Parse(allowNull);
292 ArrayList children = securityElement.Children;
293 if (null != children) {
294 foreach(SecurityElement keyElement in children) {
295 tag = keyElement.Tag;
296 if ((XmlStr._add == tag) || ((null != tag) && (XmlStr._add == tag.ToLower(CultureInfo.InvariantCulture)))) {
297 string constr = keyElement.Attribute(XmlStr._ConnectionString);
298 string restrt = keyElement.Attribute(XmlStr._KeyRestrictions);
299 string behavr = keyElement.Attribute(XmlStr._KeyRestrictionBehavior);
301 KeyRestrictionBehavior behavior = KeyRestrictionBehavior.AllowOnly;
302 if (null != behavr) {
303 behavior = (KeyRestrictionBehavior) Enum.Parse(typeof(KeyRestrictionBehavior), behavr, true);
305 constr = DecodeXmlValue(constr);
306 restrt = DecodeXmlValue(restrt);
307 Add(constr, restrt, behavior);
312 else {
313 _allowBlankPassword = false;
317 // <IPermission class="...Permission" version="1" AllowBlankPassword=false>
318 // <add ConnectionString="provider=x;data source=y;"/>
319 // <add ConnectionString="provider=x;data source=y;" KeyRestrictions="user id=;password=;" KeyRestrictionBehavior=AllowOnly/>
320 // <add ConnectionString="provider=x;data source=y;" KeyRestrictions="address=;server=" KeyRestrictionBehavior=PreventUsage/>
321 // </IPermission>
322 override public SecurityElement ToXml() {
323 Type type = this.GetType();
324 SecurityElement root = new SecurityElement(XmlStr._IPermission);
325 root.AddAttribute(XmlStr._class, type.AssemblyQualifiedName.Replace('\"', '\''));
326 root.AddAttribute(XmlStr._Version, XmlStr._VersionNumber);
328 if (IsUnrestricted()) {
329 root.AddAttribute(XmlStr._Unrestricted, XmlStr._true);
331 else {
332 root.AddAttribute(XmlStr._AllowBlankPassword, _allowBlankPassword.ToString(CultureInfo.InvariantCulture));
334 if (null != _keyvalues) {
335 foreach(DBConnectionString value in _keyvalues) {
336 SecurityElement valueElement = new SecurityElement(XmlStr._add);
337 string tmp;
339 tmp = value.ConnectionString; // WebData 97375
340 tmp = EncodeXmlValue(tmp);
341 if (!ADP.IsEmpty(tmp)) {
342 valueElement.AddAttribute(XmlStr._ConnectionString, tmp);
344 tmp = value.Restrictions;
345 tmp = EncodeXmlValue(tmp);
346 if (null == tmp) { tmp = ADP.StrEmpty; }
347 valueElement.AddAttribute(XmlStr._KeyRestrictions, tmp);
349 tmp = value.Behavior.ToString();
350 valueElement.AddAttribute(XmlStr._KeyRestrictionBehavior, tmp);
352 root.AddChild(valueElement);
356 return root;
359 private static class XmlStr {
360 internal const string _class = "class";
361 internal const string _IPermission = "IPermission";
362 internal const string _Permission = "Permission";
363 internal const string _Unrestricted = "Unrestricted";
364 internal const string _AllowBlankPassword = "AllowBlankPassword";
365 internal const string _true = "true";
366 internal const string _Version = "version";
367 internal const string _VersionNumber = "1";
369 internal const string _add = "add";
371 internal const string _ConnectionString = "ConnectionString";
372 internal const string _KeyRestrictions = "KeyRestrictions";
373 internal const string _KeyRestrictionBehavior = "KeyRestrictionBehavior";