How to grant the database owner (DBO) the EXTERNAL ACCESS ASSEMBLY permission? - sql

When I try to create assembly in SQL 2008 from .Net assembly (.Net 3.5) I am getting the below error, error says that I have to set either of the below properties as true, how can I do that?
The database owner (DBO) has EXTERNAL ACCESS ASSEMBLY permission as
TRUE
The database has the TRUSTWORTHY database property on
The assembly is signed with a certificate or an asymmetric key that
has a corresponding login with EXTERNAL ACCESS ASSEMBLY permission.
The complete error is below,
CREATE ASSEMBLY for assembly 'SQLLogger' failed because assembly 'SQLLogger' is not authorized for PERMISSION_SET = EXTERNAL_ACCESS. The assembly is authorized when either of the following is true: the database owner (DBO) has EXTERNAL ACCESS 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 EXTERNAL ACCESS ASSEMBLY permission.

This worked for me:
EXEC sp_changedbowner 'sa'
ALTER DATABASE [dbase] SET trustworthy ON
and I also did this:
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO
sp_configure 'show advanced options', 0;
GO
RECONFIGURE;
GO

⚠ ‼ Please do not set TRUSTWORTHY ON ... ⚠
...unless absolutely necessary‼ And, it should pretty much never be "necessary", even when loading an Assembly that you did not build (you can always add another certificate, or worst-case: sign after loading into SQL Server), or when loading .NET Framework libraries that aren't "supported" and hence aren't already in SQL Server's CLR host (you can use the certificate they are signed with, or worst-case: sign after loading into SQL Server). Setting the database to TRUSTWORTHY ON opens up a security hole, and for more info on that, please see:
PLEASE, Please, please Stop Using Impersonation, TRUSTWORTHY, and Cross-DB Ownership Chaining
Instead,
it is much better to do the following:
USE [master];
CREATE ASYMMETRIC KEY [SomeKey]
AUTHORIZATION [dbo]
FROM EXECUTABLE FILE = 'C:\path\to\Some.dll';
CREATE LOGIN [SomeLogin]
FROM ASYMMETRIC KEY [SomeKey];
GRANT EXTERNAL ACCESS ASSEMBLY TO [SomeLogin]; -- or "UNSAFE" instead of "EXTERNAL ACCESS"
The above only needs to be done once per Instance, per key. So if you use the same snk / pfx file for all of your assemblies, then the steps shown above only need to be done once per SQL Server Instance; the number of Assemblies and databases containing those Assemblies does not matter. Or, if signing with a Certificate, then just replace ASYMMETRIC KEY with CERTIFICATE in the example code shown above.
This approach allows you to keep better security on the database (by keeping TRUSTWORTHY set to OFF) and allows for more granular control of which assemblies are even allowed to be set to EXTERNAL_ACCESS and/or UNSAFE (since you can separate by using different keys for signing and Logins based on those different keys).
However, if you must use the TRUSTWORTHY ON method, then the database owner does not need to be sa. The requirement is merely that the Login registered as the database owner has been granted either EXTERNAL ACCESS ASSEMBLY or UNSAFE ASSEMBLY (same two permissions shown above for the Asymmetric Key-based Login). Meaning:
USE [master];
GRANT UNSAFE ASSEMBLY TO [{Login-that-is-dbo-for-DB-containing-Assembly}];
For a more detailed walk-through of the security options, please see the following article that I wrote on SQL Server Central: Stairway to SQLCLR Level 4: Security (EXTERNAL and UNSAFE Assemblies).
For a detailed walk-through of how to automate this via Visual Studio / SSDT, please see the following 3 articles (a 3-part series), also on SQL Server Central:
Stairway to SQLCLR Level 6: Development Tools Intro
Stairway to SQLCLR Level 7: Development and Security
Stairway to SQLCLR Level 8: Using Visual Studio to work around SSDT
Also, since writing those 3 articles, I have come up with an easier method using T4 templates but have not had time to write that up yet. When I do, I will update this answer with a link to that article.
UPDATE
SQL Server 2017 introduced a new complication in the form of a server-level configuration option named "CLR strict security". It is enabled by default and requires that ALL Assemblies, even those marked as SAFE, be signed with a Certificate or Asymmetric Key, have the associated Login, and that the Login has the UNSAFE ASSEMBLY permission granted (not good enough to grant EXTERNAL ACCESS ASSEMBLY). Please see my answer to the following S.O. question for more details on this new "feature":
CLR Strict Security on SQL Server 2017

You must set these settings in the project file! When you right click on your project, click the Database Settings from the project configuration and select the miscellaneous tab. You should see something similar to what I have here:
This is the same question as: Error Running CLR Stored Proc

Following code worked for me for integrated security:
ALTER DATABASE dtabasename SET TRUSTWORTHY ON;
GO
ALTER AUTHORIZATION ON DATABASE::dtabasename TO [DOMAIN\UserName]
GO

This works for:
Visual Studio 2015 Update 2.
Visual Studio 2017.
Visual Studio 2017 and SQL Server 2019 (thanks #Ramkumar Sambandam).
In your project settings, select "External Access":
On publish, the error message says that it cannot accept "EXTERNAL_ACCESS" unless the assembly is set to "Trustworthy".
So, in the project settings, set the assembly to "Trustworthy":
This meant that I was able to run a sample user defined function that listed files on the local hard drive.
If the security is still too restrictive, add the attribute DataAccess = DataAccessKind.Read to your UDF, e.g.:
[Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "FindFiles", DataAccess = DataAccessKind.Read, TableDefinition = "FileName nvarchar(500), FileSize bigint, CreationTime datetime")]
Update 2017-07-02
On SQL Server 2016 + Visual Studio 2015, you might also have to do the following:
use master;grant unsafe assembly to [Domain\Username];
Run any programs (such as Visual Studio or any C# utilities) in Administrator mode to give them sufficient permissions to publish UNSAFE assemblies.
If nothing works, try connecting using username sa and your administrator password. This will always work, regardless of whether Visual Studio is run in Administrator mode or not.
Update 2020-01-17
Updated list of compatible VS + SQL Server combinations.

This is how I managed to make it work:
ALTER DATABASE databasename SET trustworthy ON
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO
sp_configure 'show advanced options', 0;
GO
RECONFIGURE;
GO
/
DROP ASSEMBLY assemblyname
GO
CREATE ASSEMBLY assemblyname
FROM 0x4D5A9000.....
WITH PERMISSION_SET = EXTERNAL_ACCESS

this single line solves the problem for me
use master;
grant external access assembly to [domain\username]

Related

SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the security conf

We have enabled 'XPCmdShellEnabled' on the database serve and we used command shell script in one of the SP which executes on daily job.
(Our Command shell script basically create the directory, create the file and dump the tem table data to csv file).
Issue: From past few days the daily job filing with the below error, before that it was working fine and nobody changed any configurations on server.
SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure. For more information about enabling 'xp_cmdshell' search for 'xp_cmdshell' in SQL Server Books Online.
(We have enabled 'XPCmdShellEnabled' = true on 'Surface Area Configuration'.
I have tried again by executing below query, and tried SP.
sp_configure 'show advanced options', '1'
RECONFIGURE
sp_configure 'xp_cmdshell', '1'
RECONFIGURE
But no luck..
Please let me know if anybody aware/faced of this similar type of issue and found solution.
Thanks.

Alter assembly permission set to Safe

Is there a way to alter the permission set for all the assemblies under a database at once?
I am seeing the error Assembly 'Logger' cannot be loaded because this edition of SQL Server only supports SAFE assemblies. So I want to change the permission from Unsafe to Safe for all the assemblies under a particular database.
Help appreciated!!

Using SQL LocalDB in a Windows Service

I have a very small test application in which I'm trying to install a Windows Service and create a LocalDB database during the install process, then connect to that LocalDB database when the Windows Service runs.
I am running into huge problems connecting to a LocalDB instance from my Windows Service.
My installation process is exactly like this:
Execute an installer .msi file which runs the msiexec process as the NT AUTHORITY\SYSTEM account.
Run a custom action to execute SqlLocalDB.exe with the following commands:
sqllocaldb.exe create MYINSTANCE
sqllocaldb.exe share MYINSTANCE MYINSTANCESHARE
sqllocaldb.exe start MYINSTANCE
Run a custom C# action using ADO.NET (System.Data.SqlConnection) to perform the following actions:
Connect to the following connection string, Data Source=(localdb)\MYINSTANCE; Integrated Security=true
CREATE DATABASE TestDB
USE TestDB
CREATE TABLE ...
Start the Windows Service before the installer finishes.
The Windows Service is installed to the LocalSystem account and so also runs as the NT AUTHORITY\SYSTEM user account.
The service attempts to connect using the same connection string used above.
I am consistently getting the following error when trying to open the connection to the above connection string from within the Windows Service:
System.Data.SqlClient.SqlException (0x80131904): A network-related or
instance-specific error occurred while establishing a connection to
SQL Server. The server was not found or was not accessible. Verify
that the instance name is correct and that SQL Server is configured to
allow remote connections. (provider: SQL Network Interfaces, error: 50
- Local Database Runtime error occurred. The specified LocalDB instance does not exist.
This is frustrating because both the msi installer custom action and the Windows Service are running under the same Windows user account (I checked, they're both NT AUTHORITY\System). So why the first works and the second does not is beyond me.
I have tried changing the connection strings used in the custom action and the Windows Service to use the share name (localdb)\.\MYINSTANCESHARE and I get the exact same error from the Windows Service.
I have tried changing the user account that the Windows Service logs on as to my Windows user account, which does work as long as I first run a command to add it to the SQL server logins for that instance.
I've also tried running a console application and connecting to the share name connection string and that works as well.
I've also tried connecting to the share name from SQL Server Management Studio and that works as well.
However none of these methods really solve my problem. I need a Windows Service because it starts up as soon as the computer starts up (even if no user logs on) and starts up no matter which user account is logged in.
How does a Windows Service connect to a LocalDB private instance?
I am using SQL Server 2014 Express LocalDB.
Picking up from the comments on the question, here are some areas to look at. Some of these have already been answered in those comments, but I am documenting here for others in case the info might be helpful.
Check here for a great source of info on SQL Server Express LocalDB:
SQL Server 2014 Express LocalDB
SqlClient Support for LocalDB
SqlLocalDB Utlity
Introducing LocalDB, an improved SQL Express (also look at the Q&A section at the end of the main post, just before the comments, as someone asked if LocalDB can be launched from a service, and the answer is:
LocalDB can be launched from a service, as long as the profile is loaded for the service account.
What version of .Net is being used? Here it is 4.5.1 (good) but earlier versions could not handle the preferred connection string (i.e. #"(localdb)\InstanceName"). The following quote is taken from the link noted above:
If your application uses a version of .NET before 4.0.2 you must connect directly to the named pipe of the LocalDB.
And according to the MSDN page for SqlConnection.ConnectionString:
Beginning in .NET Framework 4.5, you can also connect to a LocalDB database as follows:
server=(localdb)\\myInstance
Paths:
Instances: C:\Users{Windows Login}\AppData\Local\Microsoft\Microsoft SQL Server Local DB\Instances
Databases:
Created via SSMS or direct connection: C:\Users{Windows Login}\Documents or C:\Users{Windows Login}
Created via Visual Studio: C:\Users{Windows Login}\AppData\Local\Microsoft\VisualStudio\SSDT
Initial Problem
Symptoms:
Database files (.mdf and .ldf) created in the expected location:
C:\Windows\System32\config\systemprofile
Instance files created in an unexpected location:
C:\Users\{current user}\AppData\Local\Microsoft\Microsoft SQL Server Local DB\Instances
Cause (note taken from "SqlLocalDB Utility" MSDN page that is linked above; emphasis mine):
Operations other than start can only be performed on an instance belonging to currently logged in user.
Things to try:
Connection string that specifies the database (though maybe a long-shot if the error is regarding not being able to connect to the instance):
"Server=(LocalDB)\MYINSTANCE; Integrated Security=true ;AttachDbFileName=C:\Windows\System32\config\systemprofile\TestDB.mdf"
"Server=(LocalDB)\.\MYINSTANCESHARE; Integrated Security=true ;AttachDbFileName=C:\Windows\System32\config\systemprofile\TestDB.mdf"
Is the service running? Run the following from a Command Prompt:
TASKLIST /FI "IMAGENAME eq sqlservr.exe"
It should probably be listed under "Console" for the "Session Name" column
Run the following from a Command Prompt:
sqllocaldb.exe info MYINSTANCE
And verify that the value for "Owner" is correct. Is the value for "Shared name" what it should be? If not, the documentation states:
Only an administrator on the computer can create a shared instance of LocalDB
As part of the setup, add the NT AUTHORITY\System account as a Login to the system, which is required if this account is not showing as the "Owner" of the instance:
CREATE LOGIN [NT AUTHORITY\System] FROM WINDOWS;
ALTER SERVER ROLE [sysadmin] ADD MEMBER [NT AUTHORITY\System];
Check the following file for clues / details:
C:\Users{Windows Login}\AppData\Local\Microsoft\Microsoft SQL Server Local DB\Instances\MYINSTANCE\error.log
In the end you might need to create an actual account to create and own the Instance and Database, as well as run your service. LocalDB really is meant to be user-mode, and is there any downside to having your service have its own login? And you probably wouldn't need to share the instance at that point.
And in fact, as noted by Microsoft on the SQL Server YYYY Express LocalDB MSDN page:
An instance of LocalDB owned by the built-in accounts such as NT AUTHORITY\SYSTEM can have manageability issues due to windows file system redirection; Instead use a normal windows account as the owner.
UPDATE (2015-08-21)
Based on feedback from the O.P. that using a regular User account can be problematic in certain environments, AND keeping in mind the original issue of the LocalDB instance being created in the %LOCALAPPDATA% folder for the user running the installer (and not the %LOCALAPPDATA% folder for NT AUTHORITY\System ), I found a solution that seems to keep with the intent of easy installation (no user to create) and should not require needing extra code to load the SYSTEM profile.
Try using one of the two built-in accounts that is not the LocalSystem account (which does not maintain its own registry info. Use either:
NT AUTHORITY\LocalService
NT AUTHORITY\NetworkService
Both have their profile folders in: C:\Windows\ServiceProfiles
While I have not been able to test via an installer, I did test a service logging on as NT AUTHORITY\NetworkService by setting my SQL Server Express 2014 instance to log on as this account, and restarted the SQL Server service. I then ran the following:
EXEC xp_cmdshell 'sqllocaldb c MyTestInstance -s';
and it created the instance in: C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Microsoft\Microsoft SQL Server Local DB\Instances
I then ran the following:
EXEC xp_cmdshell N'SQLCMD -S (localdb)\MyTestInstance -E -Q "CREATE DATABASE [MyTestDB];"';
and it had created the database in: C:\Windows\ServiceProfiles\NetworkService
I was able to solve similar issue in our WiX installer recently. We have a Windows service, running under SYSTEM account, and an installer, where LocalDB-based storage is one of the options for database configuration. For some time (a couple of years actually) product upgrades and service worked quite fine, with no issues related to LocalDB. We are using default v11.0 instance, which is created in SYSTEM profile in C:\Windows\System32\config tree, and a database specified via AttachDbFileName, created in ALLUSERSPROFILE tree. DB provider is configured to use Windows authentication. We also have a custom action in installer, scheduled as deferred/non-impersonate, which runs DB schema updates.
All this worked fine until recently. After another bunch of DB updates, our new release started to fail after having upgraded over the former - service was unable to start, reporting infamous "A network-related or instance-specific error occurred while establishing a connection to SQL Server" (error 50) fault.
When investigating this issue, it became apparent that the problem is in a way WiX runs custom actions. Although non-impersonated CA-s run under SYSTEM account, the registry profile and environment remain that of current user (I suspect WiX loads these voluntary when attaching to user's session). This leads to incorrect path being expanded from the LOCALAPPDATA variable - the service receives SYSTEM profile one, but the schema update CA works with the user's one.
So here are two possible solutions. The first one is simple, but too intrusive to user's system - with cmd.exe started via psexec, recreate broken instance under the SYSTEM account. This was not an option for us as the user may have other databases created in v11.0 instance, which is public. The second option assumed lots of refactoring, but wouldn't hurt anything. Here is what to do to run DB schema updates properly with LocalDB in WiX CA:
Configure your CA as deferred/non-impersonate (should run under SYSTEM account);
Fix environment to point to SYSTEM profile paths:
var systemRoot = Environment.GetEnvironmentVariable("SystemRoot");
Environment.SetEnvironmentVariable("USERPROFILE", String.Format(#"{0}\System32\config\systemprofile", systemRoot));
Environment.SetEnvironmentVariable("APPDATA", String.Format(#"{0}\System32\config\systemprofile\AppData\Roaming", systemRoot));
Environment.SetEnvironmentVariable("LOCALAPPDATA", String.Format(#"{0}\System32\config\systemprofile\AppData\Local", systemRoot));
Environment.SetEnvironmentVariable("HOMEPATH", String.Empty);
Environment.SetEnvironmentVariable("USERNAME", Environment.UserName);
Load SYSTEM account profile. I used LogonUser/LoadUserProfile native API methods, as following:
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool LogonUser(
string lpszUserName,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[StructLayout(LayoutKind.Sequential)]
struct PROFILEINFO
{
public int dwSize;
public int dwFlags;
[MarshalAs(UnmanagedType.LPWStr)]
public String lpUserName;
[MarshalAs(UnmanagedType.LPWStr)]
public String lpProfilePath;
[MarshalAs(UnmanagedType.LPWStr)]
public String lpDefaultPath;
[MarshalAs(UnmanagedType.LPWStr)]
public String lpServerName;
[MarshalAs(UnmanagedType.LPWStr)]
public String lpPolicyPath;
public IntPtr hProfile;
}
[DllImport("userenv.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool LoadUserProfile(IntPtr hToken, ref PROFILEINFO lpProfileInfo);
var hToken = IntPtr.Zero;
var hProfile = IntPtr.Zero;
bool result = LogonUser("SYSTEM", "NT AUTHORITY", String.Empty, 3 /* LOGON32_LOGON_SERVICE */, 0 /* LOGON32_PROVIDER_DEFAULT */, ref token);
if (result)
{
var profileInfo = new PROFILEINFO();
profileInfo.dwSize = Marshal.SizeOf(profileInfo);
profileInfo.lpUserName = #"NT AUTHORITY\SYSTEM";
if (LoadUserProfile(token, ref profileInfo))
hProfile = profileInfo.hProfile;
}
Wrap this in an IDisposable class, and use with a using statement to build a context.
The most important - refactor your code to perform necessary DB updates in a child process. This could be a simple exe-wrapper over your installer DLL, or stand-alone utility, if your already have one.
P.S. All these difficulties could be avoided, if only Microsoft let uses choose where to create LocalDB instances, via command line option. Like Postgres' initdb/pg_ctl utilities have, for example.
I suggest using a different user account, and not using the System account, by doing the following:-
create a new account on the machine, and set that to be the account
under which the Windows Service runs. It's not good practice to use
the system account just to run an application, anyway, as the
permissions are excessive.
ensure that the permissions on the LocalDB files are set to allow the said user account to access the database (and thus continue to
use Integrated Security)
make sure it works by trying to connect to the DB (once installed) under the same user account by running sqlcmd or Management Studio
under the context of the said user, then connecting with Integrated
Security to ensure it works.
Some other things to try/consider:
have you checked the Windows Event log for any events that might be useful for diagnostic purposes?
Make sure that if you have any other versions of SQL Server (especially prior to 2012) that for the command-line tools, the %PATH% isn't set to find an older tools version first. Older tools don't support LocalDB.
It is possible also (as an alternative) to set up LocalDB to be shared with other users. This involves sharing the instance, and then granting access to other users. See the "Sharing Issues" section in this article: Troubleshoot SQL Server 2012 Express LocalDB.
There's also another SO article that may contain some more useful information there in the links within (change the language in the URL from Polish to English by changing pl-pl to en-us). His work-around is using SQL Server accounts, which might not be OK in your case.
This might also be useful, as it relates to security permissions being denied, and possible resolutions: https://dba.stackexchange.com/questions/30383/cannot-start-sqllocaldb-instance-with-my-windows-account
Trevor, the problem you have is with the MSI custom actions. You must configure them with "Impersonate=false" otherwise the custom actions will be executed under the current user context.
BTW what tool are you using to create the installer?
Depending on the tool you use, could you please provide screenshots or code snippets of your custom actions configuration?
The accepted answer from this post will give you some additional information about the different custom action execution alternatives:
Run ExeCommand in customAction as Administrator mode in Wix Installer
You will find additional information about impersonation here:
http://blogs.msdn.com/b/rflaming/archive/2006/09/23/768248.aspx
I wouldn't create the database under the system's localdb instance. I'd create it under the current user installing the product. This will make life much easier if you need to delete or manage the database. They can do this through sql management studio. Otherwise, you'll have to use psexc or something else to launch a process under the SYSTEM account to manage it.
Once the db is created, then use the share option you mentioned. The SYSTEM account can then access the database through the share name.
sqllocaldb share MSSqlLocalDb LOCAL_DB
When sharing, I've noticed you'll have to restart the the local db instance to actually access the db through the share name:
sqllocaldb stop MSSQLLocalDB
sqllocaldb start MSSQLLocalDB
Also, You may need to add the SYSTEM account as a db reader and writer to the database ...
EXEC sp_addrolemember db_datareader, 'NT AUTHORITY\SYSTEM'

FILESTREAM feature is disabled

I have a database set up with FILESTREAM enabled on it (if you go to Properties\Advanced on the instance, it shows that FILESTREAM is enabled). I also ran the sp_configure script on it after doing this to enable the access (to make sure it was enabled). But...as soon as I try to alter the database and add the filegroup to it, it says that the feature is disabled.
I have it enabled on other instances on the same computer, and those work fine. It is only this one that is not working. I have not been able to find any good suggestions as to why it is not working.
It is a SQL 2008 R2 instance.
I was unable to script this, (using the link provided by user1977061), as the MSSQLService requires a restart afterwards to apply the change. Even after doing this it didn't work, and instead I had to manually configure FILESTREAM usage via:
SqlServer Configuration Manager
Sql SQL Server Services
SQL Server(MSSQLSERVER) [Properties]
FILESTREAM tab - enable the first 2, and optionally 3rd check box.
Look at the SQLServer properties > Advanced > Running Values value for "Filestream Access Level" to ensure that the FILESTREAM is actually enabled if in doubt.
Was FILESTREAM enabled on the instance level, though?
In Microsoft Sql Server Management Studio, right-click the server and select Properties. Then on the Advanced page, ensure that FILESTREAM Access Level is not set to Disabled (Which I believe is default):
Changing the FILESTREAM settings through SQL Server Management Studio -> Properties -> Advanced had no effect for me, and SQL Server Configuration Manager kept giving me an error when I enabled FILESTREAM there:
There was an unknown error applying the FILESTREAM settings.
Check the parameters are valid. (0x80041008)
Digging around on the internet led me here as well as to this page: https://social.msdn.microsoft.com/forums/sqlserver/en-US/d8060fdd-4583-4bf7-bdcf-4fd053d5d2c0/unknown-error-applying-the-filestream-settings
Fortunately one of the suggestions there was the solution. Connect to the server with SQL Server Management Studio and run this script:
sp_configure 'filestream access level', 2
reconfigure with override
Note: This was for 64-bit SQL Server 2012
For me this worked out:
forget about Microsoft SQL Server Management Studio to solve this bug
find SQLServerManager**.msc in folder C:\Windows\SysWOW64 and open it
enable filestream as in the picture, by clicking on properties
Database import should work then!
I've done this a thousand times and always follow the steps as Mojo outlines above. However I found that on one computer I couldn't get this to work unless I changed SQL Server Service from running as NT Service to running under a local account. I even reinstalled SQL Server, no luck.
I did as follows:
Click start
Type 'compmgmt.msc'
Expand 'Services and Applications'
Sql Server Configuration
Right Click on 'SQL Server (MSSQLSERVER)' and choose 'Properties'
On the Log On tab, change the user to a local account
Maybe one day this will save someone from banging their head on their desk until their eyeballs pop-out.
If you still are having problems with this i suggest you checkout this link!
I had the same problem in which only one instance didn't activate filestream properly. The solution seems to be to use the SQL Server Configuration Manager and enable it from there.
In addition to the other answers: the account that is used by the sql server service must be a member of the Administrators group.
Symptom: the "Configured value" in the server properties does show "enabled", but the "Running value" stays at "disabled".
I got this working by enabling filestream not in SQL Management Studio but in SQL Configuration Manager. See https://learn.microsoft.com/en-us/sql/relational-databases/blob/enable-and-configure-filestream?view=sql-server-2017.
On the Start menu, point to All Programs, point to SQL Server, point to Configuration Tools, and then click SQL Server Configuration Manager.
In the list of services, right-click SQL Server Services, and then click Open.
In the SQL Server Configuration Manager snap-in, locate the instance of SQL Server on which you want to enable FILESTREAM.
Right-click the instance, and then click Properties.
In the SQL Server Properties dialog box, click the FILESTREAM tab.
Select the Enable FILESTREAM for Transact-SQL access check box.
If you want to read and write FILESTREAM data from Windows, click Enable FILESTREAM for file I/O streaming access. Enter the name of the Windows share in the Windows Share Name box.
If remote clients must access the FILESTREAM data that is stored on this share, select Allow remote clients to have streaming access to FILESTREAM data.
Click Apply.
In SQL Server Management Studio, click New Query to display the Query Editor.
In Query Editor, enter the following Transact-SQL code:
SQL
Copy
EXEC sp_configure filestream_access_level, 2
RECONFIGURE
Click Execute.
Restart the SQL Server service.
For me only the combination of SchmitzIT and Mojo suggestions made it work
I also stumbled into this problem and by trial and error i found out that the solution was to change the account under which Sql Server runs so from SS Configuration manager i located the sql server instante, right clicked "Properties" and on the "LOg On" tab i changed Logon as "This account" to "Bulil-in account", where i choose "Local system".
After a service restart all went fine.

sql server 2012: cannot alter the login sa

I'm trying to create a database on my local machine using SSMS version 11.0.2100.60. I've run the application as administrator, logged in using Windows authentication, and I've added MYDOMAIN\my-username to the Logins. However if I try to create a db with this login I get the message
CREATE DATABASE permission denied in database 'master'.
(Microsoft SQL Server, Error: 262)
If I try to add the privelage dbcreator to my user, I get the following error.
User does not have permission to perform this action.
(Microsoft SQL Server, Error: 15247)
I can't log in as sa as I don't know/remember the password (is there a preset default?), and if I try to change the password I get the message:
Cannot alter the login 'sa', because it does not exist or you do not have permission.
(Microsoft SQL Server, Error: 15151)
Finally I note that the account 'sa' is disabled, and if I try to enable it I get the same error as before. Is there any way around this or do I need to re-install?
Version info:
Microsoft SQL Server Management Studio 11.0.2100.60
Microsoft Analysis Services Client Tools 11.0.2100.60
Microsoft Data Access Components (MDAC) 6.2.9200.16384
Microsoft MSXML 3.0 4.0 6.0
Microsoft Internet Explorer 9.10.9200.16635
Microsoft .NET Framework 4.0.30319.18051
Operating System 6.2.9200
I found the answer here:
In order to start SQL Server in single-user mode, you can add the
parameter “-m” at the command line. You can also use the SQL Server
Configuration Manager tool, which provides proper controls for the
file access and other privileges. To use the Configuration Manager
tool to recover your system, use the following steps:
Open the Configuration Manager tool from the "SQL Server 2005| Configuration" menu
Stop the SQL Server Instance you need to recover
Navigate to the “Advanced” tab, and in the Properties text box add “;–m” to the end of the list in the “Startup parameters” option
Click the “OK” button and restart the SQL Server Instance
A little more specific :
Open Sql Configuration Manager.
Select SQL Server Services.
On the right hand side, select the instance.
Right click on it and open properties.
In the advanced tab attach ";-m" at the end of the Startup Parameters field.
Apply and restart the service.
Now you have privilege to enable "sa" user and modify its password.
once done, remove ";-m" and restart the service.
You are good to go.
I'd like to point out an alternative answer laid out on DBA SE. Download PSExec onto the box that is having the problem and follow the instructions laid out in this blog post to effortlessly change admin settings using the NT Authority\System account.
./psexec -s -i "C:\...\Ssms.exe"
Wanted to share this solution as it solved my problem!