<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>SQL Programmability &amp; API Development Team Blog : SQL CLR Hosting</title><link>http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+CLR+Hosting/default.aspx</link><description>Tags: SQL CLR Hosting</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Exception handling in SQLCLR</title><link>http://blogs.msdn.com/sqlprogrammability/archive/2006/04/17/578613.aspx</link><pubDate>Tue, 18 Apr 2006 00:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:578613</guid><dc:creator>xiaoweij</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/sqlprogrammability/comments/578613.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqlprogrammability/commentrss.aspx?PostID=578613</wfw:commentRss><description>&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;Naveen covered the TSQL exception handling in his posts. How does the TSQL exception handling mechanism interacts with SQLCLR exception handling mechanism? We will&amp;nbsp;cover this topic in this post.&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;When&amp;nbsp;SQL server execute a user function/procedure/trigger implemented in CLR (i.e., managed code), we will install a managed exception handler around the user code. So if the user code leaked&amp;nbsp;a exception, the server will catch it and throw a TSQL exception wrapping the user exception. Here is an example:&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;FONT size=2&gt;Msg 6522, Level 16, State 1, Procedure UDP_OpenFile, Line 0&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face="Courier New" size=2&gt;&lt;FONT size=1&gt;&lt;FONT size=2&gt;A .NET Framework error occurred during execution of user defined routine or aggregate 'UDP_OpenFile': &lt;BR&gt;System.IO.FileNotFoundException: Could not find file 'C:\nonexisiting'.&lt;BR&gt;System.IO.FileNotFoundException: &lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp; at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURI&lt;/FONT&gt;&amp;nbsp;&lt;/FONT&gt; &lt;BR&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;Now, what happens if your CLR function/procedure calls back into SQL server again through InProc data access and caused a TSQL exception? For example, if a stored procedure is implemented in CLR like the following:&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT face="Courier New"&gt;public static void AddNewBook()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;using(SqlConnection cnn = new SqlConnection(someConnectionString))&lt;BR&gt;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;conn.Open();&lt;BR&gt;&amp;nbsp;&amp;nbsp;using(SqlCommand cmd = conn.CreateCommand())&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmd.CommandText = "insert t_Books (title, author) values('title', 'author')";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmd.ExecuteNonQuery();&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face=Arial&gt;What if the INSERT statement failed due to a duplicated key violation? &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Arial size=2&gt;SQL server will translate &lt;/FONT&gt;&lt;FONT face=Arial size=2&gt;such normal TSQL exceptions into&amp;nbsp;a CLR SqlException object. When this happens, the TSQL exception is considered as been handled. The system no longer has any pending TSQL exceptions at all, instead a managed SqlException will be thrown.&amp;nbsp;Your code will&amp;nbsp;see a SqlException. You can catch it through your CLR exception handler. This mechanism allows to catch TSQL exceptions in your CLR function/procedure. &lt;/FONT&gt;&lt;/P&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;However, if your CLR code doesn't catch the SqlException,&amp;nbsp;SQL server&amp;nbsp;will see that you leaked an unhandled CLR exception. Currently, the infrastructure doesn't treat SqlException differently from any other CLR exception (e.g. FileNotFoundException), so we will give an error 6522 with the exception message and stack.&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;Simply speaking, normal TSQL exceptions doesn't pass through CLR frames on the stack. It will get translated into appropriate SqlException. This SqlException can be handled by user code. If not, SQL server will treat it the same way as any other unhandled CLR exception.&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;I used the world "normal" TSQL exceptions in the above explaination, which suggests that there are "unusal" TSQL exceptions that behaves differently. That is indeed the case. Those are server TSQL exceptions that will either stop the execution of the batch or terminate the connection. Such TSQL exceptions are server enough to warrant special treatment. They will be translated into System.Threading.ThreadAbortException. Since ThreadAbortException can't be handled (well, it can be caught, but it will be rethrow immediately after catch block unless you explicitly reset it, which&amp;nbsp;will be&amp;nbsp;considered as bug in user code), the CLR frame will unwind and when the control goes back to TSQL, the original server TSQL exception will be thrown. &lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;If this sounds a little complicated, you are right. Exception handling is tricky. &lt;/FONT&gt;&lt;FONT face=Arial size=2&gt;We are looking into ways to make the mechanism more intuitive and friendly. Your experience anc comments about the current mechanism will help us to understand how to make things easier for you in the future. &lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV dir=ltr&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=578613" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+CLR+Hosting/default.aspx">SQL CLR Hosting</category><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category></item><item><title>Strong named assemblies and AllowPartiallyTrustedCallers </title><link>http://blogs.msdn.com/sqlprogrammability/archive/2006/04/08/572258.aspx</link><pubDate>Sat, 08 Apr 2006 20:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:572258</guid><dc:creator>RaviR</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/sqlprogrammability/comments/572258.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqlprogrammability/commentrss.aspx?PostID=572258</wfw:commentRss><description>&lt;font face="Arial" size="2"&gt;
&lt;p&gt;Very often, you may wish to factor out your code into separate assemblies in your application. For example, you separate your type in one assembly because it gets used by multiple areas in your application. And you save your proc that uses that type in another assembly.&lt;/p&gt;&lt;/font&gt;&lt;font face="Arial" size="2"&gt;
&lt;/font&gt;&lt;p&gt;&lt;font face="Arial" size="2"&gt;So Let's say you have two CLR assemblies. Assembly A contains a UDT. Assembly B has functions which use the UDT in their function signatures and/or in code inside the function. Assembly B references A.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial" size="2"&gt;A problem occurs when they are strong-named. When a function in B is called this error is thrown:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;Msg 6522, Level 16, State 1, Line 1&lt;br&gt;A .NET Framework error occurred during execution of user defined routine or aggregate 'MyProc': &lt;br&gt;System.Security.SecurityException: That assembly does not allow partially trusted callers.&lt;br&gt;System.Security.SecurityException: &lt;br&gt;at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(Assembly asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandle rmh, SecurityAction action, Object demand, IPermission permThatFailed)&lt;/font&gt;&lt;/p&gt;&lt;font face="Arial" size="2"&gt;
&lt;p&gt;What's going on ?&lt;/p&gt;
&lt;p&gt;You tried writing your own executable with the same callers that use the UDT in A and it works! but it doesn't within the server and you are wondering whether its a bug in the server ?&lt;/p&gt;
&lt;p&gt;Well this is actually a CLR design. MSDN says that Types in strong-named assemblies can be called by partially trusted code only when the assemblies have been marked with the AllowPartiallyTrustedCallers attribute (APTCA). It adds that this attribute essentially removes the implicit LinkDemand for the FullTrust permission set that is otherwise automatically placed on each publicly accessible method in each type. Please note the word "FullTrust" in CLR refers to unrestricted access or 'unsafe' permission set by sqlclr definition.&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;font face="Arial"&gt;So,&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;When assembly B calls strong-named assembly A,&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;Either A must have AllowPartiallyTrustedCallers attribute Or B must have unsafe (FullTrust) permission set.&lt;/font&gt;&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;font face="Arial"&gt;What does this mean ?&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;It means that CLR enforces the callers of a strong named assembly to be fully trusted unless that assembly has the APTCA attribute. If you add another assembly C that calls the functions in B, then B should have APTCA attribute or C should be unsafe. We recommend that if your assemblies in the database are SAFE/EXTERNAL_ACCESS (not FullTrust / partial trust / restricted), you need to mark them with APTCA to support cross assembly calls. &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;The reason your executable worked is, by default every assembly on you local drive gets FullTrust. If you copy your assemblies to a network share and try to run it from your local machine, you will see the same error, because default CLR policy will not give FullTrust to assemblies on remote shares.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;Here's the history on this requirement for sqlclr assemblies. CLR introduced the APTCA model for providing protection for the assemblies that are shared across multiple applications. Typically such assemblies were put in the GAC by applications. Assemblies that are NOT shared are usually in the Application Path. Any application that did not have unrestricted access(FullTrust/unsafe) could only load only those assemblies that are in GAC or those found by probing in the location specified by the AppDomain's APPBASE property (ApplicationPath / Database).CLR loader guaranteed that and provided protection against restricted assemblies from loading arbitrary assemblies. In the case of SQL Server, the hosting hooks guaranteed similar control on what gets loaded in its appdomain. But there was no corresponding mechanism for protecting shared assemblies ( such as in the GAC ) from being called by arbitrary assemblies. APTCA enforced that by either requiring the caller to have unrestricted access or requiring that those shared assemblies opt to allow arbitrary caller. Using the attribute implied that the shared assembly would be audited / reviewed and then deemed to be safe for use from any calleer.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;The problem with APTCA is that CLR checks for it in *every* assembly instead of restricting the check to shared assemblies. Further, CLR could have skipped checking this attribute for assemblies in the ApplicationPath / Database which can be considered as NOT shared. For example, this relaxation makes perfect sense for SAFE assemblies since have only execute permissions. They could have been considered implicitly APTCA and they could have been allowed to call each other. CLR allows the host to dictate permissions for the assemblies but does not allow the host to control APTCA behaviour. &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;The workaround we suggest therefore is to mark your SAFE/EXTERNAL_ACCESS assemblies with APTCA attribute in order to allow them to talk to each other. Please note that specifying this attribute in sqlclr assemblies does not require any audit/review and can be considered the norm to allow cross assembly calls. So we recommend that. We are not changing the rules here but specifying its relevance in SQLCLR. The directive for audit / review continues to remain valid for assemblies in the GAC that are shared between multiple other applications. In addition, we would not recommend granting unrestricted access to the callers of sqlclr assemblies. That will be an extreme measure.&lt;/font&gt;&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=572258" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+CLR+Hosting/default.aspx">SQL CLR Hosting</category><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category></item><item><title>Host Policy level Permission Sets and their permissions</title><link>http://blogs.msdn.com/sqlprogrammability/archive/2006/03/30/565126.aspx</link><pubDate>Thu, 30 Mar 2006 12:41:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:565126</guid><dc:creator>RaviR</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/sqlprogrammability/comments/565126.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqlprogrammability/commentrss.aspx?PostID=565126</wfw:commentRss><description>&lt;P&gt;While there is guidance on how to use the various permission sets - SAFE, EXTERNAL_ACCESS, UNSAFE ,&amp;nbsp;a list of the various permissions granted in these three helps clear their definitions.&lt;/P&gt;
&lt;P&gt;SAFE:&lt;BR&gt;Code that has this permission set is only allowed to execute and use context connections. &lt;/P&gt;
&lt;P&gt;EXTERNAL_ACCESS: &lt;BR&gt;Code that has been granted external_access can access system resources and go over the wire. Code can do distributed transactions, ping,&amp;nbsp;make connections,&amp;nbsp;request DNS information, read internet resources, read&amp;nbsp;and write&amp;nbsp;key containers and certificates, read&amp;nbsp;and write environment variables, files, folders and&amp;nbsp;registry keys and register and respond to events. Code is not only allowed to execute but also assert&amp;nbsp;for callers to bear adequate permissions and&amp;nbsp;impersonate.&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;UNSAFE:&lt;BR&gt;In addition to all of the above, it allows&amp;nbsp;calling unmanaged code.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=565126" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+CLR+Hosting/default.aspx">SQL CLR Hosting</category><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category></item></channel></rss>