1 //------------------------------------------------------------------------------
2 // <copyright file="DBDataPermission.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
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
;
20 [SecurityPermissionAttribute(SecurityAction
.InheritanceDemand
, ControlEvidence
=true, ControlPolicy
=true)]
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;
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");
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
81 return _allowBlankPassword
;
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;
111 // IPermission interface methods
112 // [ObsoleteAttribute("override Copy instead of using default implementation")] // not inherited
113 override public IPermission
Copy() {
114 DBDataPermission copy
= CreateInstance();
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
) {
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
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
);
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
)));
184 override public bool IsSubsetOf(IPermission target
) {
185 if (null == target
) {
188 if (target
.GetType() != this.GetType()) {
189 throw ADP
.PermissionTypeMismatch();
192 DBDataPermission superset
= (target
as DBDataPermission
);
194 bool subset
= superset
.IsUnrestricted();
196 if (!IsUnrestricted() &&
197 (!AllowBlankPassword
|| superset
.AllowBlankPassword
) &&
198 ((null == _keyvalues
) || (null != superset
._keyvaluetree
))) {
201 if (null != _keyvalues
) {
202 foreach(DBConnectionString kventry
in _keyvalues
) {
203 if(!superset
._keyvaluetree
.CheckValueForKeyPermit(kventry
)) {
214 // IUnrestrictedPermission interface methods
215 public bool IsUnrestricted() {
216 return _isUnrestricted
;
219 override public IPermission
Union(IPermission target
) {
220 if (null == target
) {
223 if (target
.GetType() != this.GetType()) {
224 throw ADP
.PermissionTypeMismatch();
226 if (IsUnrestricted()) { // MDAC 84803
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(""", "\"");
246 value = value.Replace("'", "\'");
247 value = value.Replace("<", "<");
248 value = value.Replace(">", ">");
249 value = value.Replace("&", "&");
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("&", "&");
259 value = value.Replace(">", ">");
260 value = value.Replace("<", "<");
261 value = value.Replace("\'", "'");
262 value = value.Replace("\"", """);
267 // <IPermission class="...Permission" version="1" AllowBlankPassword=false>
268 // <add ConnectionString="provider=x;data source=y;" KeyRestrictions="address=;server=" KeyRestrictionBehavior=PreventUsage/>
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
);
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/>
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
);
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
);
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
);
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";