2 // System.Data.Common.DbDataPermission.cs
5 // Rodrigo Moya (rodrigo@ximian.com)
6 // Tim Coleman (tim@timcoleman.com)
7 // Sebastien Pouliot <sebastien@ximian.com>
10 // Copyright (C) Tim Coleman, 2002-2003
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Collections;
34 using System.Security;
35 using System.Security.Permissions;
37 namespace System.Data.Common {
40 public abstract class DBDataPermission : CodeAccessPermission, IUnrestrictedPermission {
44 private const int version = 1;
46 private bool allowBlankPassword;
47 private PermissionState state;
48 private Hashtable _connections;
55 [Obsolete ("use DBDataPermission (PermissionState.None)", true)]
57 protected DBDataPermission ()
58 : this (PermissionState.None)
62 protected DBDataPermission (DBDataPermission permission)
64 if (permission == null)
65 throw new ArgumentNullException ("permission");
67 state = permission.state;
68 if (state != PermissionState.Unrestricted) {
69 allowBlankPassword = permission.allowBlankPassword;
70 _connections = (Hashtable) permission._connections.Clone ();
74 protected DBDataPermission (DBDataPermissionAttribute permissionAttribute)
76 if (permissionAttribute == null)
77 throw new ArgumentNullException ("permissionAttribute");
79 _connections = new Hashtable ();
80 if (permissionAttribute.Unrestricted) {
81 state = PermissionState.Unrestricted;
84 state = PermissionState.None;
85 allowBlankPassword = permissionAttribute.AllowBlankPassword;
86 if (permissionAttribute.ConnectionString.Length > 0) {
87 Add (permissionAttribute.ConnectionString, permissionAttribute.KeyRestrictions,
88 permissionAttribute.KeyRestrictionBehavior);
93 protected DBDataPermission (PermissionState state)
95 this.state = PermissionHelper.CheckPermissionState (state, true);
96 _connections = new Hashtable ();
100 [Obsolete ("use DBDataPermission (PermissionState.None)", true)]
105 DBDataPermission (PermissionState state, bool allowBlankPassword)
108 this.allowBlankPassword = allowBlankPassword;
111 #endregion // Constructors
115 public bool AllowBlankPassword {
116 get { return allowBlankPassword; }
117 set { allowBlankPassword = value; }
120 #endregion // Properties
124 public virtual void Add (string connectionString, string restrictions, KeyRestrictionBehavior behavior)
126 state = PermissionState.None;
127 _connections [connectionString] = new object [2] { restrictions, behavior };
130 protected void Clear ()
132 _connections.Clear ();
135 public override IPermission Copy ()
137 DBDataPermission dbdp = CreateInstance ();
138 dbdp.allowBlankPassword = this.allowBlankPassword;
139 dbdp._connections = (Hashtable) this._connections.Clone ();
143 protected virtual DBDataPermission CreateInstance ()
145 return (DBDataPermission) Activator.CreateInstance (this.GetType (), new object [1] { PermissionState.None });
148 public override void FromXml (SecurityElement securityElement)
150 PermissionHelper.CheckSecurityElement (securityElement, "securityElement", version, version);
151 // Note: we do not (yet) care about the return value
152 // as we only accept version 1 (min/max values)
154 state = (PermissionHelper.IsUnrestricted (securityElement) ?
155 PermissionState.Unrestricted : PermissionState.None);
157 allowBlankPassword = false;
158 string blank = securityElement.Attribute ("AllowBlankPassword");
161 // avoid possible exceptions with Fx 2.0
162 if (!Boolean.TryParse (blank, out allowBlankPassword))
163 allowBlankPassword = false;
166 allowBlankPassword = Boolean.Parse (blank);
169 allowBlankPassword = false;
174 if (securityElement.Children != null) {
175 foreach (SecurityElement child in securityElement.Children) {
176 string connect = child.Attribute ("ConnectionString");
177 string restricts = child.Attribute ("KeyRestrictions");
178 KeyRestrictionBehavior behavior = (KeyRestrictionBehavior) Enum.Parse (
179 typeof (KeyRestrictionBehavior), child.Attribute ("KeyRestrictionBehavior"));
181 if ((connect != null) && (connect.Length > 0))
182 Add (connect, restricts, behavior);
187 [MonoTODO ("restrictions not completely implemented - nor documented")]
188 public override IPermission Intersect (IPermission target)
190 DBDataPermission dbdp = Cast (target);
193 if (IsUnrestricted ()) {
194 if (dbdp.IsUnrestricted ()) {
195 DBDataPermission u = CreateInstance ();
196 u.state = PermissionState.Unrestricted;
201 if (dbdp.IsUnrestricted ())
203 if (IsEmpty () || dbdp.IsEmpty ())
206 DBDataPermission p = CreateInstance ();
207 p.allowBlankPassword = (allowBlankPassword && dbdp.allowBlankPassword);
208 foreach (DictionaryEntry de in _connections) {
209 object o = dbdp._connections [de.Key];
211 p._connections.Add (de.Key, de.Value);
213 return (p._connections.Count > 0) ? p : null;
216 [MonoTODO ("restrictions not completely implemented - nor documented")]
217 public override bool IsSubsetOf (IPermission target)
219 DBDataPermission dbdp = Cast (target);
222 if (dbdp.IsUnrestricted ())
224 if (IsUnrestricted ())
225 return dbdp.IsUnrestricted ();
227 if (allowBlankPassword && !dbdp.allowBlankPassword)
229 if (_connections.Count > dbdp._connections.Count)
232 foreach (DictionaryEntry de in _connections) {
233 object o = dbdp._connections [de.Key];
236 // FIXME: this is a subset of what is required
237 // it seems that we must process both the connect string
238 // and the restrictions - but this has other effects :-/
243 public bool IsUnrestricted ()
245 return (state == PermissionState.Unrestricted);
248 public override SecurityElement ToXml ()
250 SecurityElement se = PermissionHelper.Element (this.GetType (), version);
251 if (IsUnrestricted ()) {
252 se.AddAttribute ("Unrestricted", "true");
255 // attribute is present for both True and False
256 se.AddAttribute ("AllowBlankPassword", allowBlankPassword.ToString ());
257 foreach (DictionaryEntry de in _connections) {
258 SecurityElement child = new SecurityElement ("add");
259 child.AddAttribute ("ConnectionString", (string) de.Key);
260 object[] restrictionsInfo = (object[]) de.Value;
261 child.AddAttribute ("KeyRestrictions", (string) restrictionsInfo [0]);
262 KeyRestrictionBehavior krb = (KeyRestrictionBehavior) restrictionsInfo [1];
263 child.AddAttribute ("KeyRestrictionBehavior", krb.ToString ());
270 [MonoTODO ("restrictions not completely implemented - nor documented")]
271 public override IPermission Union (IPermission target)
273 DBDataPermission dbdp = Cast (target);
276 if (IsEmpty () && dbdp.IsEmpty ())
279 DBDataPermission p = CreateInstance ();
280 if (IsUnrestricted () || dbdp.IsUnrestricted ()) {
281 p.state = PermissionState.Unrestricted;
284 p.allowBlankPassword = (allowBlankPassword || dbdp.allowBlankPassword);
285 p._connections = new Hashtable (_connections.Count + dbdp._connections.Count);
286 foreach (DictionaryEntry de in _connections)
287 p._connections.Add (de.Key, de.Value);
289 foreach (DictionaryEntry de in dbdp._connections)
290 p._connections [de.Key] = de.Value;
297 private bool IsEmpty ()
299 return ((state != PermissionState.Unrestricted) && (_connections.Count == 0));
302 private DBDataPermission Cast (IPermission target)
307 DBDataPermission dbdp = (target as DBDataPermission);
309 PermissionHelper.ThrowInvalidPermission (target, this.GetType ());
315 #endregion // Methods