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);
95 protected DBDataPermission (DbConnectionOptions connectionOptions)
96 : this (PermissionState.None)
98 // ignore null (i.e. no ArgumentNullException)
99 if (connectionOptions != null) {
100 throw new NotImplementedException ();
105 protected DBDataPermission (PermissionState state)
107 this.state = PermissionHelper.CheckPermissionState (state, true);
108 _connections = new Hashtable ();
112 [Obsolete ("use DBDataPermission (PermissionState.None)", true)]
114 public DBDataPermission (PermissionState state, bool allowBlankPassword)
117 this.allowBlankPassword = allowBlankPassword;
120 #endregion // Constructors
124 public bool AllowBlankPassword {
125 get { return allowBlankPassword; }
126 set { allowBlankPassword = value; }
129 #endregion // Properties
134 public virtual void Add (string connectionString, string restrictions, KeyRestrictionBehavior behavior)
136 state = PermissionState.None;
137 AddConnectionString (connectionString, restrictions, behavior, null, false);
140 [MonoTODO ("synonyms and useFirstKeyValue aren't supported")]
141 protected virtual void AddConnectionString (string connectionString, string restrictions,
142 KeyRestrictionBehavior behavior, Hashtable synonyms, bool useFirstKeyValue)
144 _connections [connectionString] = new object [2] { restrictions, behavior };
147 public virtual void Add (string connectionString, string restrictions, KeyRestrictionBehavior behavior)
149 state = PermissionState.None;
150 _connections [connectionString] = new object [2] { restrictions, behavior };
154 protected void Clear ()
156 _connections.Clear ();
159 public override IPermission Copy ()
161 DBDataPermission dbdp = CreateInstance ();
162 dbdp.allowBlankPassword = this.allowBlankPassword;
163 dbdp._connections = (Hashtable) this._connections.Clone ();
167 protected virtual DBDataPermission CreateInstance ()
169 return (DBDataPermission) Activator.CreateInstance (this.GetType (), new object [1] { PermissionState.None });
172 public override void FromXml (SecurityElement securityElement)
174 PermissionHelper.CheckSecurityElement (securityElement, "securityElement", version, version);
175 // Note: we do not (yet) care about the return value
176 // as we only accept version 1 (min/max values)
178 state = (PermissionHelper.IsUnrestricted (securityElement) ?
179 PermissionState.Unrestricted : PermissionState.None);
181 allowBlankPassword = false;
182 string blank = securityElement.Attribute ("AllowBlankPassword");
185 // avoid possible exceptions with Fx 2.0
186 if (!Boolean.TryParse (blank, out allowBlankPassword))
187 allowBlankPassword = false;
190 allowBlankPassword = Boolean.Parse (blank);
193 allowBlankPassword = false;
198 if (securityElement.Children != null) {
199 foreach (SecurityElement child in securityElement.Children) {
200 string connect = child.Attribute ("ConnectionString");
201 string restricts = child.Attribute ("KeyRestrictions");
202 KeyRestrictionBehavior behavior = (KeyRestrictionBehavior) Enum.Parse (
203 typeof (KeyRestrictionBehavior), child.Attribute ("KeyRestrictionBehavior"));
205 if ((connect != null) && (connect.Length > 0))
206 Add (connect, restricts, behavior);
211 [MonoTODO ("restrictions not completely implemented - nor documented")]
212 public override IPermission Intersect (IPermission target)
214 DBDataPermission dbdp = Cast (target);
217 if (IsUnrestricted ()) {
218 if (dbdp.IsUnrestricted ()) {
219 DBDataPermission u = CreateInstance ();
220 u.state = PermissionState.Unrestricted;
225 if (dbdp.IsUnrestricted ())
227 if (IsEmpty () || dbdp.IsEmpty ())
230 DBDataPermission p = CreateInstance ();
231 p.allowBlankPassword = (allowBlankPassword && dbdp.allowBlankPassword);
232 foreach (DictionaryEntry de in _connections) {
233 object o = dbdp._connections [de.Key];
235 p._connections.Add (de.Key, de.Value);
237 return (p._connections.Count > 0) ? p : null;
240 [MonoTODO ("restrictions not completely implemented - nor documented")]
241 public override bool IsSubsetOf (IPermission target)
243 DBDataPermission dbdp = Cast (target);
246 if (dbdp.IsUnrestricted ())
248 if (IsUnrestricted ())
249 return dbdp.IsUnrestricted ();
251 if (allowBlankPassword && !dbdp.allowBlankPassword)
253 if (_connections.Count > dbdp._connections.Count)
256 foreach (DictionaryEntry de in _connections) {
257 object o = dbdp._connections [de.Key];
260 // FIXME: this is a subset of what is required
261 // it seems that we must process both the connect string
262 // and the restrictions - but this has other effects :-/
267 public bool IsUnrestricted ()
269 return (state == PermissionState.Unrestricted);
273 [MonoTODO ("DO NOT IMPLEMENT - will be removed")]
274 [Obsolete ("DO NOT IMPLEMENT - will be removed")]
275 protected void SetConnectionString (DbConnectionOptions constr)
277 throw new NotImplementedException ();
280 [MonoTODO ("DO NOT IMPLEMENT - will be removed")]
281 [Obsolete ("DO NOT IMPLEMENT - will be removed")]
282 public virtual void SetRestriction (string connectionString, string restrictions, KeyRestrictionBehavior behavior)
284 throw new NotImplementedException ();
288 public override SecurityElement ToXml ()
290 SecurityElement se = PermissionHelper.Element (this.GetType (), version);
291 if (IsUnrestricted ()) {
292 se.AddAttribute ("Unrestricted", "true");
295 // attribute is present for both True and False
296 se.AddAttribute ("AllowBlankPassword", allowBlankPassword.ToString ());
297 foreach (DictionaryEntry de in _connections) {
298 SecurityElement child = new SecurityElement ("add");
299 child.AddAttribute ("ConnectionString", (string) de.Key);
300 object[] restrictionsInfo = (object[]) de.Value;
301 child.AddAttribute ("KeyRestrictions", (string) restrictionsInfo [0]);
302 KeyRestrictionBehavior krb = (KeyRestrictionBehavior) restrictionsInfo [1];
303 child.AddAttribute ("KeyRestrictionBehavior", krb.ToString ());
310 [MonoTODO ("restrictions not completely implemented - nor documented")]
311 public override IPermission Union (IPermission target)
313 DBDataPermission dbdp = Cast (target);
316 if (IsEmpty () && dbdp.IsEmpty ())
319 DBDataPermission p = CreateInstance ();
320 if (IsUnrestricted () || dbdp.IsUnrestricted ()) {
321 p.state = PermissionState.Unrestricted;
324 p.allowBlankPassword = (allowBlankPassword || dbdp.allowBlankPassword);
325 p._connections = new Hashtable (_connections.Count + dbdp._connections.Count);
326 foreach (DictionaryEntry de in _connections)
327 p._connections.Add (de.Key, de.Value);
329 foreach (DictionaryEntry de in dbdp._connections)
330 p._connections [de.Key] = de.Value;
337 private bool IsEmpty ()
339 return ((state != PermissionState.Unrestricted) && (_connections.Count == 0));
342 private DBDataPermission Cast (IPermission target)
347 DBDataPermission dbdp = (target as DBDataPermission);
349 PermissionHelper.ThrowInvalidPermission (target, this.GetType ());
355 #endregion // Methods