|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
修复过程包含最多4个阶段,在下面描述。在你开始前,你应该cd到数据库目录和检查表文件的权限,确保他们可被运行mysqld的Unix用户读取(和你,因为你需要存取你正在检查的文件)。如果它拒绝你修改文件,他们也必须是可被你写入的。<pstyle="TEXT-INDENT:2em">1、SQLCLR权限集级别<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 当你利用CREATEASSEMBLY语句把一个程序集加载到一个数据库中时,SQLServer供应了三种权限集级别:SAFE,EXTERNAL_ACCESS和UNSAFE。这些权限集构成如和(均请参考第二篇)所示的AppDomain战略级别。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 上面是一个典范的语句,它完成安装位于FileLoader.dll文件内的一个程序集,而且付与它EXTERNAL_ACCESS权限集。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">CREATEASSEMBLYFileAccess<pstyle="TEXT-INDENT:2em">FROME:FileLoader.dll<pstyle="TEXT-INDENT:2em">WITHPERMISSION_SET=EXTERNAL_ACCESS<pstyle="TEXT-INDENT:2em">GO<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 在代码实行时,每种权限集级别都授与该代码一组分歧的CAS允许权集。上面让我们入手下手会商在每级上授与的特定允许权。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> (1)SAFE<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> SAFE是默许的权限集。它仅授与充足的允许权来实行代码,完成不请求存取内部资本的外部盘算和存取在宿主SQLServer实例中的数据和工具。注重,SAFE代码不克不及存取内部的资本,因而它不克不及读取或写磁盘文件,不克不及存取任何别的SQLServer实例,或读取或写注册表。并且,该代码也必需被查验为范例平安的,这将有助于制止各类包含缓冲区溢出在内的打击。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> SAFE代码是更牢靠和平安的SQLCLR代码。它可以完成用T-SQL誊写的代码在数据库和服务器实例内所能完成的几近一样的功效。它可以授与如表格1所枚举的CAS允许权。从表格1中可见,该代码可以运转和读取宿主SQLServer实例中的工具和数据-借助于一种特定情势的ADO.NET毗连串,大概是"contextconnection=true"大概是"contextconnection=yes"来完成。任何别的毗连串都大概会招致某种平安非常。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 表格1:授与给SAFE程序集的权限集。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">权限范例限定<pstyle="TEXT-INDENT:2em">SecurityPermission受限定实行<pstyle="TEXT-INDENT:2em">SqlClientPermission受限定不克不及是空口令,只能利用高低文毗连串<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 授与给一个程序集的了局权限集是枚举于表格1中的允许权权限集与来自企业、呆板和用户权限集的交集。由于这些级别默许会具有一切的允许权,以是程序集仅承受枚举于表格1中的权限。注重,请确保你必定要了解这些权限。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> (2)EXTERNAL_ACCESS<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 与SAFE比拟,EXTERNAL_ACCESS权限集同意无限制地存取存在于SQLServer实破例部的资本-包含磁盘文件,在别的SQLServer实例中的数据和工具,情况变量和注册表的一些部分。存取这些别的资本一般是在SQLServer服务帐户的平安高低文中举行的,可是,该代码可以摹拟别的用户举行存取。这个级别授与枚举于表格2中的允许权。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 表格2:授与给EXTERNAL_ACCESS程序集的权限集。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">权限范例限定<pstyle="TEXT-INDENT:2em">EnviromentPermission不受限定-<pstyle="TEXT-INDENT:2em">FileIOPermission不受限定-<pstyle="TEXT-INDENT:2em">RegistryPermission受限定仅能以读体例存取HKEY_CLASSES_ROOT,HKEY_LOCAL_MACHINE,HKEY_CURRENT_USER,HKEY_CURRENT_CONFIG和HKEY_USER<pstyle="TEXT-INDENT:2em">SecurityPermission受限定Assertion,Execution,SerializationFormatter,ControlPrincipal<pstyle="TEXT-INDENT:2em">KeyContainerPermission不受限定-<pstyle="TEXT-INDENT:2em">SqlClientPermission不受限定-<pstyle="TEXT-INDENT:2em">EventLogPermission受限定仅限于当地主机且仅限于体系办理员<pstyle="TEXT-INDENT:2em">DnsPermission不受限定-<pstyle="TEXT-INDENT:2em">SocketPermission受限定仅限于IP地点<pstyle="TEXT-INDENT:2em">WebPermission受限定仅能经由过程HTTP存取当地主机<pstyle="TEXT-INDENT:2em">SmtpPermission受限定仅能举行毗连存取<pstyle="TEXT-INDENT:2em">DistributedTransactionPermission不受限定-<pstyle="TEXT-INDENT:2em">NetworkInformationPermission受限定仅能经由过程Ping体例存取<pstyle="TEXT-INDENT:2em">StorePermission不受限定-<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 下面不受限定的FileIOPermission大概看起来有点使人忧虑,由于,它意味着,从CLR的角度来看,代码能存取磁盘上的任何地位。可是牢记,该代码仍旧运转于当地服务帐户的操纵体系平安限定下。因而假如该帐户不克不及存取一个文件的话,那末SQLCLR代码也不克不及存取。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 典范地,当地服务帐户是一种具有极强权限的帐户,因而存在滥用的大概性。为此,我们一样平常把对这些程序集的存取权限仅授与那些具有服务帐户信托度的登录而且不利用当地体系帐户作为SQLServer的服务帐户。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 值得注重的是,借助于EXTERNAL_ACCESS权限集,你可使用一个更传统型的ADO.NET毗连串来毗连到在统一个SQLServer实例(SQLCLR代码在个中运转)中的一个数据库。这必要SqlClientPermission以便你可以利用一个除"高低文毗连"串之外的毗连-用以读取以后实例中的数据,指定一般的服务器定名,凭据,等等。但是,我也没法找到为何你要如许做的来由,可是既然我们能够举行选择,也是一件功德,对吗?<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> (3)UNSAFE<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 这个UNSAFE权限集是付与一切权限的SQLCLR等价物,在这类情形下,CLR挂起一切的允许权反省。它承受单个的不受限定的SecurityPermission权限,这是CLR的授与一切权限的体例。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 潜伏地,一个UNSAFE程序集可以完成各类"伤害性"的举措,由于它属于内涵地被信托的代码。比方,它能挪用非托管代码,比方COM组件和原始Win32API。它还受限于服务帐户的操纵体系允许权,可是CLR不会限定它存取任何资本的才能。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 由于UNSAFE是云云的不平安,以是,只要一个sysadmin可以创立这类范例的程序集。 <pstyle="TEXT-INDENT:2em">2、会见内部资本<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 由于会见内部资本必要与操纵体系举行交互,以是,今世码实验存取内部的资本时,存在多种要恪守的划定规矩。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 关于SAFE代码来讲,这类划定规矩是复杂的:假如它试图存取一个内部的资本,那末存取将被否定而且它激发一个非常。就是这些。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 关于EXTERNAL_ACCESS和UNSAFE的情形,则庞大些:<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> ・划定规矩1:假如代码在一个SQLServer登录的平安高低文下实行(也就是说,还没有被映照到一个Windows用户或组),那末存取将被克制而且激发一个非常。一个SQL登录其实不具有SQLServer外的任何允许权,因而这是很主要的。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> ・划定规矩2:假如代码在一个被映照到一个Windows登录的登录下实行,那末举行内部存取的实行高低文就是该登录的实行高低文。假如该用户可以存取Windows中的资本,那末该代码乐成。假如不是,存取被否定而且激发一个非常。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> ・划定规矩3:假如挪用者不是原始的挪用者(已举行了一个实行高低文切换),那末存取被否定而且激发一个非常。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 一入手下手,这些划定规矩也使我有点懵懂,可是,当我今后渐渐地愈来愈多地利用它们时,它们入手下手变得很主要了。关于划定规矩1来讲,由于一个SQL登录仅仅存在于SQLServer天下中,以是,假如它能存取操纵体系资本的话,这将是一个伟大的平安毛病。划定规矩2也很主要,而且它同意摹拟。划定规矩3仿佛有点严厉,可是我嫌疑SQLServer小组有点守旧,由于高低文切换大概会是一场"办理噩梦",而且他们仍旧确信不会发生平安毛病成绩。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 内部的存取划定规矩乃至更庞大些。假定运转代码的登录已乐成"超出"下面枚举的"重重封闭",可是,为了存取内部的资本-正如你大概企望的(而且大概但愿),SQLServer其实不主动地摹拟以后实行高低文。代之的是,它利用SQLServer实例的服务帐户来存取资本。大概,你也能够显式地摹拟高低文登录来存取资本。如许做必要利用SqlContext工具的WindowsIdentity属性来挪用WindowsIdentity来完成实践的摹拟。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 列表1:在SQLCLR代码中利用摹拟<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">try<pstyle="TEXT-INDENT:2em">{<pstyle="TEXT-INDENT:2em"> //摹拟以后SQL平安高低文<pstyle="TEXT-INDENT:2em"> WindowsIdentityCallerIdentity=SqlContext.WindowsIdentity;<pstyle="TEXT-INDENT:2em"> if(CallerIdentity!=null)<pstyle="TEXT-INDENT:2em"> {<pstyle="TEXT-INDENT:2em"> OriginalContext=CallerIdentity.Impersonate();<pstyle="TEXT-INDENT:2em"> //做一些回护操纵<pstyle="TEXT-INDENT:2em"> }<pstyle="TEXT-INDENT:2em">}<pstyle="TEXT-INDENT:2em">catch<pstyle="TEXT-INDENT:2em">{<pstyle="TEXT-INDENT:2em"> //从存取成绩中恢复<pstyle="TEXT-INDENT:2em">}<pstyle="TEXT-INDENT:2em">finally<pstyle="TEXT-INDENT:2em">{<pstyle="TEXT-INDENT:2em"> if(OriginalContext!=null)<pstyle="TEXT-INDENT:2em"> OriginalContext.Undo();<pstyle="TEXT-INDENT:2em">}<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 列表1向你展现怎样在SQLCLR代码中利用摹拟。WindowsImpersonationContext工具属于System.Security.Principal定名空间的一部分而且形貌了在你摹拟前的Windows用户平安高低文。SqlContext工具属于和SQLServer一同安装的Microsoft.SQLServer.Server定名空间的一部分而且供应在SQLServer主机和SQLCLR代码之间的一个钩子。在这类情形中,它利用WindowsIdentity属性来失掉以后平安身份的一个令牌。这是Windows登录的平安高低文-该代码在这一登录下运转。该代码测试是不是了局CallerIdentity为null,假如该代码在一种SQL登录下运转时它将为null。最初,它挪用WindowsIdentity摹拟来完成实践的摹拟,并保留原始的高低文以用于当请求恢复到该高低文时。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 必需了解,仅当实行必要回护的操纵(比方翻开一文件)时摹拟才起感化。一旦它被翻开,该代码就不再必要摹拟。因而,一旦你完成回护的操纵,即恢复归去。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 最初,经由过程挪用OriginalContext的Undo办法,代码块卖力恢复到原始高低文。假如你在函数停止之前不举行恢复,那末SQLServer将激发一个非常。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 关于摹拟也存在一些限定。当该摹拟起感化时,你就没法再利用SQLServer实例存取数据或工具。在你再次存取当地数据之前,你必需恢复摹拟。这也意味着,历程内数据存取老是产生在会话确当前平安高低文中。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 风趣的是,一个异步实行的UNSAFE程序集(也就是说,它可以创立线程而且异步地运转代码)永久不会同意历程内数据存取。实在,这并非一个平安成绩而明显是一个牢靠性的成绩。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 3、可托赖的数据库<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 在SAFE程序集和别的权限设置级别之间的别的一个区分是在SQLServer2005测试期增加的。如今,你必需满意两个请求之一来创立EXTERNAL_ACCESS或UNSAFE程序集:<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> ・数据库一切者(dbo)必需具有EXTERNALACCESSASSEMBLY权限而且数据库必需具有TRUSTWORTHY属性集。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 大概:<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> ・程序集的利用体例必需是,经由过程一个具有EXTERNALACCESSASSEMBLY权限的登录并且要利用一个证书或一个非对称密钥。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> EXTERNALACCESSASSEMBLY权限是另外一种新的粒度允许权-同意一位卖力人创立这类程序集。默许情形下,体系办理员具有它而且可以把它赋给别的登录。可是如许做时要稳重,这固然由于大概潜伏地同意伤害代码安装到服务器中。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 一个数据库的TRUSTWORTHY属性请求设置办理员权限而且是在数据库中安装非SAFE程序集的条件。基于EXTERNALACCESSASSEMBLY权限,一个DBA可以把持是不是存在潜伏伤害性的程序集可以被安装就任何数据库中,和谁可以把它们放到那边。这很有但愿会使DBA放心而不用再忧虑他们的服务器会传染.NET代码!<pstyle="TEXT-INDENT:2em">4、总结<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 表格3包括可用于SQLCLR程序集的三种权限集的总结,和SQLServer为每种权限集供应的回护范例。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> ・代码存取平安是在代码内CLR托管的允许权集。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> ・编程模子限定是指宿主回护属性,和是不是代码可以利用静态手艺。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> ・请求确认指指,当你利用CREATEASSEMBLY语句安装它时是不是SQLServer考证代码存在绝对的平安性。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> ・挪用本机代码唆使,是不是代码可以挪用Win32API或对内部组件作一种平台挪用。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 表格3:权限设置总结。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 权限集<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em">回护范例SAFEEXTERNAL_ACCESSUNSAFE<pstyle="TEXT-INDENT:2em">代码存取平安仅实行实行和受限存取内部资本不受限定<pstyle="TEXT-INDENT:2em">编程模子限定(主机回护属性)是是无<pstyle="TEXT-INDENT:2em">请求确认是是否<pstyle="TEXT-INDENT:2em">挪用本机代码否否是<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 如你所见,只需你把你的代码限定为SAFE或EXTERNAL_ACCESS,SQLServer就可以够供应一种对回护数据平安和服务器不乱性的SQLCLR代码的优秀包装。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 上面是一个考查你关于SQLCLR平安的了解的测试:<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> ・可使用一个惯例的ADO.NET毗连串来存取另外一种数据库(大概是一个Oracle大概是一个Access数据库)吗?<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> ・假定你如今已懂得会见内部资本,存取一个Oracle数据库的程序集必要具有甚么样的SQLCLR权限集级别?<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 在持续浏览之前,请仔细地思索一下这两个成绩吧。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 提醒.NET框架中所包括的独一的托管数据库供应者是System.Data.SqlClient。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 注重,这个程序集必需被安装为UNSAFE。为何呢?由于该代码必需利用System.Data.OleDb工具。由于这些是基于COM的工具(这意味着长短托管代码),以是程序集必要被安装为UNSAFE-由于这是可以存取非托管代码的独一的级别。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 你大概以为这是微软的与Oracle交互的体例。实在,谜底是,关于会见一个微软Access数据库也是一样的,由于它也是基于OLEDB和响应的非托管代码。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 我将在此大胆说一句:UNSAFE代码永久不该该用在一个临盆服务器中。除非它是可以被完整察看的代码和经由严厉校验以考证它不会伤害服务器;不然,你没法用统统举措来足已包管它是平安的。只管我不扫除存在关于UNSAFE代码的正当利用,可是我仍是要深图远虑究竟是甚么样的代码值得如许一冒险。我一般感应,关于利用扩大的存储历程也存在不异的成绩,这一样存在冒险性且必需以庞大的C++代码来编写。<pstyle="TEXT-INDENT:2em"><pstyle="TEXT-INDENT:2em"> 至此,我能够说,任何同意UNSAFE代码被安装到一个临盆服务器的DBA一样平常都应当是一个DBA妙手而不是一个一般的DBA。并且,我以为,作为一位常常与DBA交换的开辟职员,他们中的年夜多半都是妙手!<pstyle="TEXT-INDENT:2em"> 可是,SAFE代码不会比一个T-SQL存储历程带来更年夜的伤害性,并且,当你必要存取内部资本时,EXTERNAL_ACCESS是一种公道的让步。因而,你能够不用思索关于未知内容的害怕,而只需让SAFE代码到场到你的数据库中好了。然后,当它关于数据库、使用程序及用户来讲是主要的情形下,再思索EXTERNAL_ACCESS代码成绩。总之,在使得这一类代码平安和牢靠方面,微软切实其实做了一件功德情。
在JOIN操作中(需要从多个数据表提取数据时),MySQL只有在主键和外键的数据类型相同时才能使用索引。 |
|