NamedPipeClientStream throws UnauthorizedAccessException: Access to the path is denied - c#

I have reviewed lots of similar questions but none seems to cover this case. So please check the details before assuming it is a duplicate.
Scenario:
I have a client and server application written in c# targeting .NET Framework 4.7.2 that communicates using NamedPipeClientStream and NamedPipeServerStream respectively.
The server is running as the local administrator account and creates the NamedPipeServerStream like this:
PipeSecurity ps = new PipeSecurity();
ps.AddAccessRule(new PipeAccessRule(WindowsIdentity.GetCurrent().Owner, PipeAccessRights.FullControl, AccessControlType.Allow));
ps.AddAccessRule(new PipeAccessRule(new SecurityIdentifier("S-1-5-32-544"), PipeAccessRights.ReadWrite, AccessControlType.Allow));
NamedPipeServerStream mypipe = new NamedPipeServerStream("mypipe", PipeDirection.Out, 1, 0, PipeOptions.WriteThrough, 0, 0, ps);
mypipe.WaitForConnection();
On the server I have created a local account called "testuser" that is a member of the local administrators group. This account is used for authentication on the client when connecting to the Named Pipes over the network.
The client program is running as a local user on a different machine connected via network and creates the connection like this:
NamedPipeClientStream mypipe = new NamedPipeClientStream("<ip of server>", "mypipe", PipeDirection.In, PipeOptions.None);
mypipe.Connect();
When running the server software on Windows Server 2012 this works fine. But on Windows Server 2016 and Windows Server 2019 I get the UnauthorizedAccessException. If instead of my local user "testuser" I authenticate with the built-in Administrator account over the network, it works fine on all three version of windows server.
If I change the pipe security to use a SID of for example S-1-5-11 to allow "authenticated users" it also works on all three versions but the requirement is to only allow members of the local administrators group from connecting to the server over the network. Ideally it should not matter if the account is a local or domain account, but I have only tested with local accounts.
I have done some debugging using Event Viewer on the server and I can see Event 5145 (Detailed File Share) with Audit success for my testuser when accessing the pipe, but the client still reports UnauthorizedAccessException.
Is there any way to restrict access for only members of the local administrators group on windows server 2016 and 2019?

If anyone else runs into this problem I found the cause.
The problem was "UAC remote restrictions". More information can be found in Microsoft's KB 951016
If a local account is a member of the Builtin\Administrators group and authenticates over the network for instance to an SMB share such as \\remotecomputer\C$ or a named pipe, the account will not authenticate as a "full" administrator and thus not have access to administrative resources. Such accounts will have to be elevated from a interactive logon such as RDP to gain full administrative privileges. As such, my scenario with builtin accounts does not work because of this security feature.
There seems to be three ways to handle this problem.
Disable this security measure in the registry (probably not recommended).
Use a domain account and add that as a local administrator. This security restriction appears to only affect SAM (local) accounts.
Only use the builtin Administrator account as this is also not affected by the security restriction.
Note that if the registry is edited incorrectly there might be serious consequences. So backup the registry before performing any changes. The following instructions are based on Microsoft's article on the subject:
To disable the restriction in the registry:
Open the registry using regedit and select the following key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
Create the following key (type DWORD) if it does not exist, otherwise just edit it to have a value of 1: LocalAccountTokenFilterPolicy.

Related

C# Process.Start cannot connect to server

I have a server with a bunch of installers on it. However my program stops when I attempt to initiate connection to the server.
Process.Start(#"\\{Server ip}\Software_Depot\Installers_Master\Snagit\v2019\snagit.exe");
What I'm trying to do here is initiate the installation of snagit.exe from our server.
Check the permissions of the elevated user that’s being used. If it’s a local admin account, it might not have permissions to the network share.
You could either add a “net use .... domain-user password” or use a domain account to launch your .net app.

Remote debugging C# application in VS2010

I try to remote debug C# application (remote PC under WinXP (32bit), VS runs under Win7 (64bit) i got an error message:
Error while trying to run project: Unable to start debugging.
Logon failure: unknown user name or bad password. See help for more information.
On both machines i set-up user accounts with same name/password, and both machines locates on same work group in LAN.
When I enabled login audit on WinXP I see strange record on event log, common sense of this is: login forbidden for user SYSTEM, but i run VS and remote debug moniton by another user name.
Can somebody explain me how to beat this strange error?
Upd: I tryed to run VS2010 as remote user with command:
runas /user:pc_name\user_name path_to_vs_ide
then pass password. IDE was started succesfully, but when i choose "Attach to process..." and wrote pc_name in qualifier field, i got same error as above:
Logon failure: unknown user name or bad password.
So my question is still yet actual. How to remotely debug C# applications?
Upd2: Problem solved after install new pure copy of WinXP.
Assume you have two computers, C1 and C2. You create a user Alex on both, and each copy of Alex has the same password. Same user, right?
These are not the same user login. Each has a different unique identifier (UID).
If you try to log in to C1 from C2 using "Alex" as the user name, the user you are using is the Alex from C2, not the Alex from C1, which is the principal the remote system will use to authenticate. But the remote system doesn't know who Alex from C2 is.
Try changing your remote credentials to your equivalent of "C1\Alex": the remote computer name, a \, and the user name.
You can see more info here on how to set up remote tools: http://msdn.microsoft.com/en-us/library/bt727f1t.aspx Gregg's blog is very useful for account requirements: http://blogs.msdn.com/b/greggm/archive/2008/05/15/visual-studio-remote-debugger-service-user-account-requirements.aspx
You really want two local user accounts, one on host and remote host, with the same username and password (to have Visual Studio authenticate using a local account that matches a remote account (username and password) that has been given permissions to debug in msvsmon.exe)
Windows cached credentials - if you accessed a resource and checked “remember me”, Windows cached credentials to that resource. If you ever attempted to Attach To Process using the current user logged into the local machine, Visual Studio will pick up these cached credentials and attempt to use this as authentication for remote debugging. So you’ll need to clear these credentials (control userpasswords2, Advanced tab, Manage Passwords, Delete the credentials for that remote host)
Now you can either attempt to access the resource (like a share) using a different credential and store it, or you can run Visual Studio as that user you want to debug with that corresponds to the user on the remote side.
Alex, you may need to change the Local Security Policy setting on the Windows XP machine, here are more details: http://msdn.microsoft.com/en-us/library/ek2256kk(v=vs.100).aspx

what Windows account should a service run under to access network sql servers

I am considering creating a windows service that would run periodically and query networked databases and store the information on the local machine (please don’t ask why!).
I would like this service to run when there is no one logged on to the computer locally. What account should the service run under Localservice, Localsystem or Network.
A username and password would be provided to all networked databases including the local.
I'd probably create a specific domain account and grant that rights to both SQL server and whatever local store you are going to use. If you want to use SQL credentials to connect to the DB, then it could be a local account (with access to the local resources) or a higher privileged user (like LocalSystem).
To guarantee that you can actually connect to the databases, I would suggest that you create a services account (something like /User - and apply a password that doesn't expire).
This way you can set up the user in SQL Server and use integrated security while connecting.
For example:
Domain: stackoverflow
Service: SearchDB
I would create a user stackoverflow\SearchDBUser
Basically you don't have to stick to the pre-defined users when setting up the windows service.
I hope this helps.
Wagner.
This might actually be better asked on ServerFault, but I've always seen it as 'Network' or 'Local System' depending on specific usage.

How can I send user credentials for use on a remote machine using WCF?

I have two machines, we'll call them machine A and machine B. Machine B is running a Windows service written in C#.net, as the Local System account. Machine A tells machine B's service (using WCF) to open a file located on the network. Since local system is not a network user, it does not have access to network files, and is unable to open the file. Currently, I am reading files from machine A and serializing them as strings to machine B, and then writing them locally on B. I've considered making a generic network account for machine B, so it can have access to the network, however this is undesirable. Is there any way I can make machine B open files using the user account of machine A? I've taken a look at the system security principal's identity classes, would this be a case to use them?
MSDN - How to: Impersonate a Client on a Service
Impersonating a client on a Windows
Communication Foundation (WCF) service
enables the service to perform actions
on behalf of the client. For actions
subject to access control list (ACL)
checks, such as access to directories
and files on a machine or access to a
SQL Server database, the ACL check is
against the client user account
Also don't forget to configure your service to use Windows Authentication and use a supported binding.

Access the remote control/Terminal Services properties of a windows user via c#

I'm writing a C# program that adds Users on a Server 2003 box.
I user the .NET 3.5 namespace System.DirectoryServices.AccountManagement, which is OK.
However, I'd like to prevent the added users to use Remote Control or Terminal Server log on rights.
Do you know how to do that in C#? I failed so far to find anything about this.
The ability to remote desktop to a machine depends on the security policy of that machine. By default members of the Administrators group and the Remote Desktop Users group (on the local machine) have the ability to remote desktop.

Categories

Resources