Reputation: 25711
I have 2 DLLs signed in Visual Studio (VS) 2015. A former employee created an asymmetric key and login and I ran one of the assemblies in UNSAFE
mode correctly.
I get the following error with the second one:
Msg 10327, Level 14, State 1, Line 27
CREATE ASSEMBLY for assembly 'TableFile' failed because assembly 'TableFile' is not authorized for PERMISSION_SET = UNSAFE. The assembly is authorized when either of the following is true: the database owner (DBO) has UNSAFE ASSEMBLY permission and the database has the TRUSTWORTHY database property on; or the assembly is signed with a certificate or an asymmetric key that has a corresponding login with UNSAFE ASSEMBLY permission.
I can't ask the former employee so how do I find out how to get this to run? I tried this too:
USE master;
GO
CREATE ASYMMETRIC KEY AProjectKey FROM EXECUTABLE FILE = 'E:\sqldlls\TableFile.dll'
CREATE LOGIN AProjectLogin FROM ASYMMETRIC KEY AProjectKey ;
GRANT UNSAFE ASSEMBLY TO AProjectLogin ;
GO
This gives the following errors:
Msg 15396, Level 16, State 1, Line 9
An asymmetric key with name 'AProjectKey' already exists or this asymmetric key already has been added to the database.Msg 15151, Level 16, State 1, Line 10
Cannot find the asymmetric key 'AProjectKey', because it does not exist or you do not have permission.Msg 15151, Level 16, State 1, Line 11
Cannot find the login 'AProjectLogin', because it does not exist or you do not have permission.
How do I get both these assemblies running in unsafe mode? Thanks in advance.
Upvotes: 2
Views: 2159
Reputation: 48826
Regarding those 3 error messages:
The first could be due to the Asymmetric Key already existing, but under a different name. Keys and Certificates need to be unique in terms of their public key, not just the name (though that obviously needs to be unique as well). Each Key and Certificate has a hash of the public key which is referred to as the "thumbprint". The thumbprints of existing Keys / Certificates are checked when creating a new one and will prevent the creation, even of a differently named Key / Certificate, if the thumbprint already exists. That is what the error message means by "or this asymmetric key already has been added to the database".
OR:
It could mean that a different Asymmetric Key (i.e. different "thumbprint") exists in master
, but with the name AProjectKey
CREATE ASYMMETRIC KEY
statement failed).Error # 2 helps narrow down the issue. If Error # 1 was caused by an existing Asymmetric Key having the same name but different "thumbprint", then you either would have been able to create the Login (if it did not already exist), or you would have gotten an error stating that the Login (i.e. "server principal") already exists. But the error is that an Asymmetric Key by that name cannot be found. This should mean that the Asymmetric Key itself does already exist, but under a different name. You can see what Asymmetric Keys have been created by executing the following:
SELECT * FROM sys.asymmetric_keys;
But that doesn't tell you which one came from that Assembly (or an Assembly signed with the same Strong Name Key used to sign this one). For that you need to know the "thumbprint", and for that you need to open a Command Prompt (preferably a "Developer Command Prompt" which Visual Studio sets up when installed, as it has the correct path set up upon opening it). Then, run the following:
CD /D E:\sqldlls\
sn -T TableFile.dll
You should see:
Public key token is XXXXXXXXXXXXXXXX
Copy and paste that XXXXX "token" (i.e. thumbprint) into the following query:
SELECT ak.[name], ak.[sid]
FROM sys.asymmetric_keys ak
WHERE ak.[thumbprint] = 0x{XXXXXXXXXXXXXXXX}; -- remove the { and }
Assuming that you get a row returned, we need to see if the Login exists. Simply trying to create a Login from the Asymmetric Key won't get us the Login's name if it does exist since you can only have 1 Login created per Key / Certificate, and the error message only reports back the name you are trying to create as the one that already exists, even though it can be a different name for the same Key. So, take the SID from the returned row and paste it in the following query:
SELECT sp.*
FROM sys.server_principals sp
WHERE sp.[sid] = 0x{SID_from_sys_asymmetric_keys}; -- remove the { and }
If no row is returned then you should create a Login from that Asymmetric Key.
At this point a Login should exist, so grant it the UNSAFE ASSEMBLY
permission.
Now try creating the Assembly again.
Upvotes: 1