Windows service install doesn't have correct privileges - c#

I have a service that I have created for Windows. The service works fine. The problem I am having is a permission issue. My service accesses a .mdf SQL Server database file that is created when the service is installed (using Installshield VS 2012).
The service itself is running as user. When I install I input my credentials and I can successfully start the service. The service starts fine. However, when I get to the part in my code where I have to open the .mdf I get an error because the database log file does not exists and the service does not have permissions to create it.
The only way I can fix it is by adding my username or authenticated users for example to the security section of my program files folder. This allows the SQL Server .log file to be created and my service continues running.
What is the best solution to getting around this? Basically I want to be able to run the service and local system and it have the privileges to install and create the .mdf.
Thank you for the help.

You should create the database log file during the installation. You can run custom code during the installation to do that (the code may be similar to what triggers creation of the log file in your regular code). That will use the user with elevated permissions so it will work well and is correct from the security point of view (all administrative tasks should be done during the installation in this case).
It's better not to add permissions for a normal user to SQL Server data folder as that will lower security.

Related

Flat File Destination Failed the pre-execute phase. Cannot open the datafile

I am executing a SSIS Package from a C# WinForm project. It executes and runs about halfway when it tries to create/write a file (An Expression in the Flat File Manager).
When I check the SSISDB Catalog on the SQL Server, I see the following errors for the package:
Flat File Destination failed the pre-execute phase and returned error
code 0xC020200E.
PO Header:Error: Cannot open the datafile "\Server\path\Admin Shared
Folders\Information
Systems\Projects\projectPath\filepath\636943168325507712-1070-15175.txt".
Based on the path and filename, the expression resolved fine. When I run the SSIS package directly it runs fine, so it appears to be a permission issue.
I am using Integration Services (MS SQL Server 2014) and right now I am using windows authentication in my connect string:
Integrated Security=SSPI;
However, the group who will be using the app will not have full permissions, so a specific user account will be created in SQL Server that I will use to connect. That said, assuming that this is a permission issue, how does the SQL Server account need to be created / what permissions and considerations need to be applied? What other permission issues/considerations need to be taken into account?
ie, we have no idea how to create the account to make this work and need help!
I think you are ask for run with SQL agent and hit permission issue, you can do this, in Windows service there are a service name call SQL Server Agent, and Log on with a special account, likely you create a individual account, and give this account to your folder permission.
Make sure that SQL service account can access to this path and has needed permissions:
Configure File System Permissions for Database Engine Access

C# Internal Server Error

I wrote a C# WCF server and I am trying to get it up in IIS but everything I try to go to my endpoint I get this error:
I checked the Permissions on the site and I have Authenticated Users others:
so I am not sure what to do now...
I imagine that the root of the problem is that you are trying to create an application on the server that points to files on your own computer using a Remote Desktop Connection drive share. The \\?\UNC\tsclient\C\... path is a dead giveaway.
This is a definite no. You cannot run a web service this way. The tsclient path is specific to your individual connection and will not work from any other context. Any other user account - including the service account that the IIS instance is running from - will not be able to access those files.
To resolve this issue you need to copy the files from your machine to a location on the server and recreate the IIS application entry, referencing the location on the server. You might still need to monkey with the security on the server-local folder.

C# exe file executed hourly as windows task - needs to connect to SQL Server

I have inherited a C# project (exe file) that needs to run once per hour. It ran on an old server just fine, but I don't have access to that server to view the settings. I have it setup to run as a windows task. The task runs but I'm getting the error:
System.Data.Entity exception the underlying provider failed on open - Login failed for user
SQL Server is setup for windows authentication. Websites that are running on the server which use Entity Framework connect just fine. The config file for this project is setup to authenticate the same (same setup as old server only thing I changed was the Data Source):
connection string="Data Source=WIN-FM8VFGOQQKN;
Initial Catalog=DatabaseNameHere;Integrated Security=True;
MultipleActiveResultSets=True""
providerName="System.Data.EntityClient
The Windows task is setup to run as a Windows login account that has access to this database. I am guessing simply setting up the Windows task to run the program as a Windows login account is not enough to authenticate?
EDIT to add info: When I run the exe file from the command line logged in as the same user who is the author of the scheduled task, it runs perfectly. It only throws a .NET exception when trying to logon to SQL Server when executed as a scheduled task.
I have searched around but all I can find are solutions related to web applications. This program is not running under IIS.
Env: SQL Server 2012, asp.net 4.0, C#, Windows Server 2012 r2
I wanted to go ahead and answer my own question as I couldn't find any other way around this issue. I had to change SQL Server to mixed mode authentication, create a database user, then change my connection string from windows authentication to SQL Server authentication. After that the task ran just fine. It's hard for me to believe there isn't a way around this, but I couldn't find anything. All other posts I found on the interwebs also stated they had to change to mixed mode authentication. What a waste of time!
Check if "run with highest privileges" in the scheduled task properties is set.
I am guessing simply setting up the Windows task to run the program as a Windows login account is not enough to authenticate?
A common problem of scheduled tasks are that the user account does not have "logon as batch" privilegs. It seems that this is not the problem here, since in the case of missing this privilege the task does not run at all.
But be aware that this privilege may be set via a GPO (group policy) from Active Directory, and this means that setting this privilege locally will be overwritten by the next GPO refresh.
And check the event log, normally problems with login / privileges missing will be logged.

Cannot programmatically access network path through VPN

I'm trying to use a network path (create directory, write and read files) from a Web Service in ASP.NET.
Everything works fine from my office where the network path is in the same LAN of my laptop, but when I try to connect to the network path through a VPN, the creation of a directory fails with "Access to path is denied" error.
The strange thing is that from Windows Explorer I can perfectly access such path, given my VPN credentials, that I stored in Windows Credentials Wallet.
I also tried to set my IIS App Pool Identity to 'Network Service' but no luck.
Can you help me please?
Thank you very much
EDIT:
When I try to execute a statement like
Directory.CreateDirectory(#"\\my\network\path");
from a simple console application project in my Visual Studio 2010 it works perfectly and the directory is created.
The problem is when I hit such a statement inside the business logic of my web service that is running under local IIS (and which I'm connected to via "Attach Process..." debug tool in VS2010)
I may not have all the details of what you're asking straight, but if you're running this service via Visual Studio and VPN, take a look at this great article, at CodeBetter.
runas /netonly /user:domain\username “C:\ProgramFiles\Path\to\your\visualstudio”
I don't have the computer I have this on in front of me, but I recall that I created a batch file and ran it to start VS and Sql Server Management Studio, and it works like a charm.
If I've misunderstood the issue, sorry for the noise.
Sounds like when you are running locally, your local domain account is the context under which everything is being ran. When running the console app, it is still running under your user context since you initiated the application. When running in IIS, you are correct in that the app-pool account is being used, and the networkservice account has some pretty low privileges.
Instead of using a highly privileged account (such as yours), would impersonation solve your issue? Any work that needs to be done over the VPN can "wrapped" in a context the appropriate permissions. Here is another SO article on using impersonation, which I have implemented for related things:
How do you do Impersonation in .NET?
See Matt Johnson's answer where he creates a custom Impersonation class. Use that in a using block, then do your network stuff. It uses the advapi32.dll with p/invoke to do this kind of user account voodoo. He put together a NuGet package as well which may save you some time:
https://www.nuget.org/packages/SimpleImpersonation

Access to a Sharepoint Remote Folder from C#

I have developed an ASP.NET MVC 3 which must access to a SharePoint Remote Folder.
To do that, during the development, before to run the Visual Studio Development Server, I try to access to the remote folder. Then, I must introduce the credentials of the user who has permission to see the remote resource. After this, using the following code:
string path = #"\\tests.sharepoint.es\folder1";
DirectoryInfo di = new DirectoryInfo(path);
DirectoryInfo[] dis = di.GetDirectories();
The access to the folder is successful. However, this fails when I executed my web application from the IIS, getting the next error:
Access to the path '\tests.sharepoint.es\folder1\' is denied.
Even if I set for the Application Pool the same user that runs the Visual Studio Development Server, it continues failing.
I have identified that the users who runs the World Wide Web Publish Service (W3SVC) is SYSTEM (an account who obviously doesn't have permission to access to the folder) but I can't change this and I am not sure if this causes the problem.
Also, I have read some posts about using SPSecurity.RunWithElevatedPrivileges but I can't use it because my IIS server doesn't have Sharepoint installed (it is in another machine) and therefore, I can't use Microsoft.Sharepoint.dll as far as I know.
UPDATE: When I try to access to the resource using my windows explorer, I have read that OS uses WebDav instead of NetBios. Can IIS use this protocol to access to the resource?
If you really need to access remote resource with Windows permissions from Windows web server (or any other server that impersonates remote client) than you must run such code under account directly signed in on the server box. This is caused by "NTLM one hop" policy - user's credentials can be used only on machine user directly signed in to or machine user directly communicates to (and not on third one that this second machine tries to connect to).
Safest approach is to run process under account that have access to remote resource and run code in that process. You can run IIS process under such account, but you may need to revert impersonation back to process if running code during requests.
You can also directly impersonate particular user but you'll need to have plain text login information. This is most likely against security policy for most companies.
Note: you very well may end up building anonymization proxy - be very careful to understand what it means to access remote resource under account different from actual user's account.
Fortunately, I have found how to resolve the access problem.
I have used the solution described in this post.
My code seems like this:
PinvokeWindowsNetworking.connectToRemote(#"\\tests.sharepoint.es\folder1", "domain\user", "password");
//manage files and folders of my remote resource
//...
PinvokeWindowsNetworking.disconnectRemote(#"\\tests.sharepoint.es\folder1");

Categories