DBDataPermission.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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. //------------------------------------------------------------------------------
  8. namespace System.Data.Common {
  9. using System.Collections;
  10. using System.Data.Common;
  11. using System.Diagnostics;
  12. using System.Globalization;
  13. using System.Runtime.Serialization;
  14. using System.Security;
  15. using System.Security.Permissions;
  16. using System.Text;
  17. [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, ControlEvidence=true, ControlPolicy=true)]
  18. [Serializable]
  19. public abstract class DBDataPermission : CodeAccessPermission, IUnrestrictedPermission {
  20. private bool _isUnrestricted;// = false;
  21. private bool _allowBlankPassword;// = false;
  22. private NameValuePermission _keyvaluetree = NameValuePermission.Default;
  23. private /*DBConnectionString[]*/ArrayList _keyvalues; // = null;
  24. [ Obsolete("DBDataPermission() has been deprecated. Use the DBDataPermission(PermissionState.None) constructor. http://go.microsoft.com/fwlink/?linkid=14202", true) ] // V1.2.3300, MDAC 86034
  25. protected DBDataPermission() : this(PermissionState.None) { // V1.0.3300
  26. }
  27. protected DBDataPermission(PermissionState state) { // V1.0.3300
  28. if (state == PermissionState.Unrestricted) {
  29. _isUnrestricted = true;
  30. }
  31. else if (state == PermissionState.None) {
  32. _isUnrestricted = false;
  33. }
  34. else {
  35. throw ADP.InvalidPermissionState(state);
  36. }
  37. }
  38. [ 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
  39. protected DBDataPermission(PermissionState state, bool allowBlankPassword) : this(state) { // V1.0.3300, MDAC 84281
  40. AllowBlankPassword = allowBlankPassword;
  41. }
  42. protected DBDataPermission(DBDataPermission permission) { // V1.0.5000, for Copy
  43. if (null == permission) {
  44. throw ADP.ArgumentNull("permissionAttribute");
  45. }
  46. CopyFrom(permission);
  47. }
  48. protected DBDataPermission(DBDataPermissionAttribute permissionAttribute) { // V1.0.5000, for CreatePermission
  49. if (null == permissionAttribute) {
  50. throw ADP.ArgumentNull("permissionAttribute");
  51. }
  52. _isUnrestricted = permissionAttribute.Unrestricted;
  53. if (!_isUnrestricted) {
  54. _allowBlankPassword = permissionAttribute.AllowBlankPassword;
  55. if (permissionAttribute.ShouldSerializeConnectionString() || permissionAttribute.ShouldSerializeKeyRestrictions()) { // MDAC 86773
  56. Add(permissionAttribute.ConnectionString, permissionAttribute.KeyRestrictions, permissionAttribute.KeyRestrictionBehavior);
  57. }
  58. }
  59. }
  60. // how connectionString security is used
  61. // parsetable (all string) is shared with connection
  62. internal DBDataPermission(DbConnectionOptions connectionOptions) { // v2.0
  63. if (null != connectionOptions) {
  64. _allowBlankPassword = connectionOptions.HasBlankPassword; // MDAC 84563
  65. AddPermissionEntry(new DBConnectionString(connectionOptions));
  66. }
  67. }
  68. public bool AllowBlankPassword { // V1.0.3300
  69. get {
  70. return _allowBlankPassword;
  71. }
  72. set { // MDAC 61263
  73. // for behavioral backward compatability with V1.1
  74. // set_AllowBlankPassword does not _isUnrestricted=false
  75. _allowBlankPassword = value;
  76. }
  77. }
  78. public virtual void Add(string connectionString, string restrictions, KeyRestrictionBehavior behavior) { // V1.0.5000
  79. DBConnectionString constr = new DBConnectionString(connectionString, restrictions, behavior, null, false);
  80. AddPermissionEntry(constr);
  81. }
  82. internal void AddPermissionEntry(DBConnectionString entry) {
  83. if (null == _keyvaluetree) {
  84. _keyvaluetree = new NameValuePermission();
  85. }
  86. if (null == _keyvalues) {
  87. _keyvalues = new ArrayList();
  88. }
  89. NameValuePermission.AddEntry(_keyvaluetree, _keyvalues, entry);
  90. _isUnrestricted = false; // MDAC 84639
  91. }
  92. protected void Clear() { // V1.2.3300, MDAC 83105
  93. _keyvaluetree = null;
  94. _keyvalues = null;
  95. }
  96. // IPermission interface methods
  97. // [ObsoleteAttribute("override Copy instead of using default implementation")] // not inherited
  98. override public IPermission Copy() {
  99. DBDataPermission copy = CreateInstance();
  100. copy.CopyFrom(this);
  101. return copy;
  102. }
  103. private void CopyFrom(DBDataPermission permission) {
  104. _isUnrestricted = permission.IsUnrestricted();
  105. if (!_isUnrestricted) {
  106. _allowBlankPassword = permission.AllowBlankPassword;
  107. if (null != permission._keyvalues) {
  108. _keyvalues = (ArrayList) permission._keyvalues.Clone();
  109. if (null != permission._keyvaluetree) {
  110. _keyvaluetree = permission._keyvaluetree.CopyNameValue();
  111. }
  112. }
  113. }
  114. }
  115. // [ Obsolete("use DBDataPermission(DBDataPermission) ctor") ]
  116. [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")] // V1.0.5000, MDAC 82936
  117. virtual protected DBDataPermission CreateInstance() {
  118. // derived class should override with a different implementation avoiding reflection to allow semi-trusted scenarios
  119. return (Activator.CreateInstance(GetType(), System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Instance, null, null, CultureInfo.InvariantCulture, null) as DBDataPermission);
  120. }
  121. override public IPermission Intersect(IPermission target) { // used during Deny actions
  122. if (null == target) {
  123. return null;
  124. }
  125. if (target.GetType() != this.GetType()) {
  126. throw ADP.PermissionTypeMismatch();
  127. }
  128. if (this.IsUnrestricted()) { // MDAC 84803, NDPWhidbey 29121
  129. return target.Copy();
  130. }
  131. DBDataPermission operand = (DBDataPermission) target;
  132. if (operand.IsUnrestricted()) { // NDPWhidbey 29121
  133. return this.Copy();
  134. }
  135. DBDataPermission newPermission = (DBDataPermission) operand.Copy();
  136. newPermission._allowBlankPassword &= AllowBlankPassword;
  137. if ((null != _keyvalues) && (null != newPermission._keyvalues)) {
  138. newPermission._keyvalues.Clear();
  139. newPermission._keyvaluetree.Intersect(newPermission._keyvalues, _keyvaluetree);
  140. }
  141. else {
  142. // either target.Add or this.Add have not been called
  143. // return a non-null object so IsSubset calls will fail
  144. newPermission._keyvalues = null;
  145. newPermission._keyvaluetree = null;
  146. }
  147. if (newPermission.IsEmpty()) { // no intersection, MDAC 86773
  148. newPermission = null;
  149. }
  150. return newPermission;
  151. }
  152. private bool IsEmpty() { // MDAC 84804
  153. ArrayList keyvalues = _keyvalues;
  154. bool flag = (!IsUnrestricted() && !AllowBlankPassword && ((null == keyvalues) || (0 == keyvalues.Count)));
  155. return flag;
  156. }
  157. override public bool IsSubsetOf(IPermission target) {
  158. if (null == target) {
  159. return IsEmpty();
  160. }
  161. if (target.GetType() != this.GetType()) {
  162. throw ADP.PermissionTypeMismatch();
  163. }
  164. DBDataPermission superset = (target as DBDataPermission);
  165. bool subset = superset.IsUnrestricted();
  166. if (!subset) {
  167. if (!IsUnrestricted() &&
  168. (!AllowBlankPassword || superset.AllowBlankPassword) &&
  169. ((null == _keyvalues) || (null != superset._keyvaluetree))) {
  170. subset = true;
  171. if (null != _keyvalues) {
  172. foreach(DBConnectionString kventry in _keyvalues) {
  173. if(!superset._keyvaluetree.CheckValueForKeyPermit(kventry)) {
  174. subset = false;
  175. break;
  176. }
  177. }
  178. }
  179. }
  180. }
  181. return subset;
  182. }
  183. // IUnrestrictedPermission interface methods
  184. public bool IsUnrestricted() {
  185. return _isUnrestricted;
  186. }
  187. override public IPermission Union(IPermission target) {
  188. if (null == target) {
  189. return this.Copy();
  190. }
  191. if (target.GetType() != this.GetType()) {
  192. throw ADP.PermissionTypeMismatch();
  193. }
  194. if (IsUnrestricted()) { // MDAC 84803
  195. return this.Copy();
  196. }
  197. DBDataPermission newPermission = (DBDataPermission) target.Copy();
  198. if (!newPermission.IsUnrestricted()) {
  199. newPermission._allowBlankPassword |= AllowBlankPassword;
  200. if (null != _keyvalues) {
  201. foreach(DBConnectionString entry in _keyvalues) {
  202. newPermission.AddPermissionEntry(entry);
  203. }
  204. }
  205. }
  206. return (newPermission.IsEmpty() ? null : newPermission);
  207. }
  208. private string DecodeXmlValue(string value) {
  209. if ((null != value) && (0 < value.Length)) {
  210. value = value.Replace("&quot;", "\"");
  211. value = value.Replace("&apos;", "\'");
  212. value = value.Replace("&lt;", "<");
  213. value = value.Replace("&gt;", ">");
  214. value = value.Replace("&amp;", "&");
  215. }
  216. return value;
  217. }
  218. private string EncodeXmlValue(string value) {
  219. if ((null != value) && (0 < value.Length)) {
  220. value = value.Replace('\0', ' '); // assumption that '\0' will only be at end of string
  221. value = value.Trim();
  222. value = value.Replace("&", "&amp;");
  223. value = value.Replace(">", "&gt;");
  224. value = value.Replace("<", "&lt;");
  225. value = value.Replace("\'", "&apos;");
  226. value = value.Replace("\"", "&quot;");
  227. }
  228. return value;
  229. }
  230. // <IPermission class="...Permission" version="1" AllowBlankPassword=false>
  231. // <add ConnectionString="provider=x;data source=y;" KeyRestrictions="address=;server=" KeyRestrictionBehavior=PreventUsage/>
  232. // </IPermission>
  233. override public void FromXml(SecurityElement securityElement) {
  234. // code derived from CodeAccessPermission.ValidateElement
  235. if (null == securityElement) {
  236. throw ADP.ArgumentNull("securityElement");
  237. }
  238. string tag = securityElement.Tag;
  239. if (!tag.Equals(XmlStr._Permission) && !tag.Equals(XmlStr._IPermission)) {
  240. throw ADP.NotAPermissionElement();
  241. }
  242. String version = securityElement.Attribute(XmlStr._Version);
  243. if ((null != version) && !version.Equals(XmlStr._VersionNumber)) {
  244. throw ADP.InvalidXMLBadVersion();
  245. }
  246. string unrestrictedValue = securityElement.Attribute(XmlStr._Unrestricted);
  247. _isUnrestricted = (null != unrestrictedValue) && Boolean.Parse(unrestrictedValue);
  248. Clear(); // MDAC 83105
  249. if (!_isUnrestricted) {
  250. string allowNull = securityElement.Attribute(XmlStr._AllowBlankPassword);
  251. _allowBlankPassword = (null != allowNull) && Boolean.Parse(allowNull);
  252. ArrayList children = securityElement.Children;
  253. if (null != children) {
  254. foreach(SecurityElement keyElement in children) {
  255. tag = keyElement.Tag;
  256. if ((XmlStr._add == tag) || ((null != tag) && (XmlStr._add == tag.ToLower(CultureInfo.InvariantCulture)))) {
  257. string constr = keyElement.Attribute(XmlStr._ConnectionString);
  258. string restrt = keyElement.Attribute(XmlStr._KeyRestrictions);
  259. string behavr = keyElement.Attribute(XmlStr._KeyRestrictionBehavior);
  260. KeyRestrictionBehavior behavior = KeyRestrictionBehavior.AllowOnly;
  261. if (null != behavr) {
  262. behavior = (KeyRestrictionBehavior) Enum.Parse(typeof(KeyRestrictionBehavior), behavr, true);
  263. }
  264. constr = DecodeXmlValue(constr);
  265. restrt = DecodeXmlValue(restrt);
  266. Add(constr, restrt, behavior);
  267. }
  268. }
  269. }
  270. }
  271. else {
  272. _allowBlankPassword = false;
  273. }
  274. }
  275. // <IPermission class="...Permission" version="1" AllowBlankPassword=false>
  276. // <add ConnectionString="provider=x;data source=y;"/>
  277. // <add ConnectionString="provider=x;data source=y;" KeyRestrictions="user id=;password=;" KeyRestrictionBehavior=AllowOnly/>
  278. // <add ConnectionString="provider=x;data source=y;" KeyRestrictions="address=;server=" KeyRestrictionBehavior=PreventUsage/>
  279. // </IPermission>
  280. override public SecurityElement ToXml() {
  281. Type type = this.GetType();
  282. SecurityElement root = new SecurityElement(XmlStr._IPermission);
  283. root.AddAttribute(XmlStr._class, type.AssemblyQualifiedName.Replace('\"', '\''));
  284. root.AddAttribute(XmlStr._Version, XmlStr._VersionNumber);
  285. if (IsUnrestricted()) {
  286. root.AddAttribute(XmlStr._Unrestricted, XmlStr._true);
  287. }
  288. else {
  289. root.AddAttribute(XmlStr._AllowBlankPassword, _allowBlankPassword.ToString(CultureInfo.InvariantCulture));
  290. if (null != _keyvalues) {
  291. foreach(DBConnectionString value in _keyvalues) {
  292. SecurityElement valueElement = new SecurityElement(XmlStr._add);
  293. string tmp;
  294. tmp = value.ConnectionString; // WebData 97375
  295. tmp = EncodeXmlValue(tmp);
  296. if (!ADP.IsEmpty(tmp)) {
  297. valueElement.AddAttribute(XmlStr._ConnectionString, tmp);
  298. }
  299. tmp = value.Restrictions;
  300. tmp = EncodeXmlValue(tmp);
  301. if (null == tmp) { tmp = ADP.StrEmpty; }
  302. valueElement.AddAttribute(XmlStr._KeyRestrictions, tmp);
  303. tmp = value.Behavior.ToString();
  304. valueElement.AddAttribute(XmlStr._KeyRestrictionBehavior, tmp);
  305. root.AddChild(valueElement);
  306. }
  307. }
  308. }
  309. return root;
  310. }
  311. private static class XmlStr {
  312. internal const string _class = "class";
  313. internal const string _IPermission = "IPermission";
  314. internal const string _Permission = "Permission";
  315. internal const string _Unrestricted = "Unrestricted";
  316. internal const string _AllowBlankPassword = "AllowBlankPassword";
  317. internal const string _true = "true";
  318. internal const string _Version = "version";
  319. internal const string _VersionNumber = "1";
  320. internal const string _add = "add";
  321. internal const string _ConnectionString = "ConnectionString";
  322. internal const string _KeyRestrictions = "KeyRestrictions";
  323. internal const string _KeyRestrictionBehavior = "KeyRestrictionBehavior";
  324. }
  325. }
  326. }