WCF local only NamedPipe - wcf

Here's a simple example of my problem. I'm writing an application that self hosts a WCF service for communication only within the user's session. When multiple users run this application concurrently on a terminal services machine, all the users are happy as long as they don't have local admin rights. The problem begins if two or more users are admins, the 1st user creates the service, a 2nd user because the service has been created Globally...
Simple Win32 implementation, without WCF, would be create a named pipe with the "Local\" prefix. WCF appears to first attempt to create a global shared memory mapping, after that fails, then creates a local mapping.
Has anybody found a way to self host a WCF service that is local to the current user's session, even if the user is a local admin?

The easy way is just have each instance use a different service URL (deriving it from some characteristic of the user session to make it unique - e.g. session logon ID).
There's no way to stop the WCF binding publishing its endpoint details (aka the real pipe name) in the Global namespace if it's running with sufficient privileges to do so. But maybe you could adjust the process token privileges to disable the SeCreateGlobalPrivilege before opening the service host, if your service finds it is running as admin with elevated privileges.

Related

Hosting a continuosly running Console application

Azure VM, Cloud service or Web job?
I have a configurable console application which runs continuosly. Currently it is running on a VM and consumes lot of memory (it is basically doing data mining).
The current requirement is to have multiple instances of this application with different set of configuration which can be changed by specific users.
So where should I host this application such that the configuration can be modified using some front end which provides access managements(like Sharepoint),ability to stop it/restart (like WCF service) without logging on the VM?
I am open to any suggestions/ideas. Thanks
I don't think there's any sold answer to this question as there is the preference variable but for what it's worth, if it were up to me I would deploy it against individual azure VM's for each specific set of users. That way if the server resources went up because of config changes the user group made it is isolated to that group, and with azure, will scale automatically to meet the resource demand. Then just build a little .net web app to allow user to authenticate and change configuration settings.
You could expose an "admin" endpoint for your service (obviously you need authentication here!) that:
1. can return the current configuration
2. accept new configuration
3. restart the service (if needed). Stopping the service will be harder, since that leaves the question on how to start it again.
Then you need to write your own (or use a 3-party (like sharepoint or a CMS)) application that will handle your users and under the hood consume your "admin" endpoint.
Edit: The hosting part: If I understand you correctly your app is just an console application today, and you don't know how to host it? Well, there are many answers to that question. If you have a operations department go talk to them, if you are on your own play around and see what fits you and your environment best!
My tip: go for a http/https protocol/interface - just because there are many web host out there, and you can easy find tools for that protocol. if you are on the .NET platform check out Web.API or OWASP
Azure now has Machine learning to process data mining.
You should check if it's suit to you.
Otherwise, you can use Webjob:
Allow you to have multiple instances of your long time running job (Webjon scaling out).
AppSettings can be change from the Azure Portal or using the Azure Management API

WCF security problems with named pipes

I have a slightly complicated setup that, of course, works fine in XP, but chokes on Windows 7. It may seem like madness, but it made sense at the time!
I have a WPF application that launches and then launches another application that communicates with an external device. After launching it establishes communications with the new process using WCF (hosted by the new process) via a named pipe (net.pipe). This seems to work fine on either OS.
I wanted to make some of the functionality of the WPF application externally available to a command line program, so I set up another WCF service, this time hosted by the WPF application and again exposed it via named pipes. Again, this seems to work.
Next, I wanted to make the functionality of the WPF application available via the web. Now, it's important that the WPF application be runnable from a regular user account, so I thought the best way to make this work on Windows 7 would be to create a windows service that would provide the web service part and have it communicate back to the WPF application via the same named pipe that works fine for the command line. I implemented this and it runs fine on XP, but it chokes on Windows 7. The problem seems to be with trying to establish the named pipe connection between the windows service and the WPF application.
If I run the WPF app as an administrator, it works fine. So it seems to be a problem with the account that the windows service is running in can't communicate with a regular user account that is hosting the WCF service via named pipes. Is there a way to make this work? It seems a WCF service running in a regular user account can communicate using named pipes to another app running in the same account, but it seems it can't do the same thing with a different account.
Oddly, the reverse seems to work. The windows service does, in fact, also expose a service with a named pipe binding (it's used as an activation function since the service is running all the time). I can connect from the WPF app to this service without any problems.
My knowledge of security is somewhat limited. Can anybody shine a light on what's going on?
This question has been asked several times previously on SO. For example, see Connecting via named pipe from windows service to desktop app
The problem is that your user session applications don't possess the SeCreateGlobalPrivilege security privilege necessary to allow them to create objects in the global kernel namespace visible to other sessions, but only in the local namespace which is only visible within the session. Services, on the other hand, which run with this privilege by default, can do so.
It is not the named pipe object itself which is constrained to the local namespace in this way, but another named kernel object, a shared memory section, on which the WCF named pipe binding relies in order to publish to its clients the actual name of the pipe, which is a GUID which changes each time the service is started.
You can get round this constraint by reversing the roles - make the windows service application the WCF Service, to which your user session apps connect. The windows service has no problem publishing its service to your session. And connecting things up this way round makes more sense because the windows service is always running, whereas your session and its apps comes and goes as you log in and out. You'll want to define the service with a duplex contract, so that once the connection is established, the essential flow of communication over the WCF service can still happen in the same direction you originally intended.
The applications (WPF/Console) are creating locally scoped named pipes (this happens by default when they are unable to create globally scoped pipes). My guess is that they can communicate with each other because they can see each others named pipes because they are running under the same account.
The windows service has higher privileges and can therefore create a globally scoped named pipe for the client applications to see.
You can check out a discussion on Christian Weyer's Blog.

ASPX Security settings complicated

Have an app on server ion. It calls a webservice on server2. Endpoint of that service is to write a pdf file on server3.
As a developer in dev on my laptop it works. As a deployed app it fails on the write.
IIS6, Windows 2003 servers as well as VS2008
AppPool Identity as network service will not write the file. If I use a "fake" user in AD the app pulls no data and fails to start up properly.
Any ideas?
TIA
My guess is that the credentials that are running the app on server2 does not have write permissions to server3 (assuming server2 uses a UNC path to write to the filesystem on server3).
The user account that runs the IIS Application Pool (or however credentials are assigned to your app(s)) on Server2 will need write access to the share/UNCpath on server3; generally this means you cant use NetworkService.
If you change the user account in IIS on server2, you'll need to take into account all the implied permissions that the existing user account (assuming NetworkService) has on server2.
Including Filesystem, Registry, Metabase, etc permissions; the list could be very long and complicated or short and irrelevant (depending on your implementation on servers1/server2/server3).
For all my implementations, we use AD User accounts that are designated as Service Accounts; with extremely limited permissions on the servers, each App would have its own Service Account, and any touch-points would require explicit permissions applied. Thus, an account would be setup for the app on Server2 and the explicit permissions would be configured on Server2 to run the app, and the UNC path/share and NTFS permissions on Server3 would be applied explicitly for the file transfer.
Hope this helps.

Does WCF always needs my host to have administrator privileges?

I'm following this tutorial and seems like to implement WCF in my application it would need to run with administrator privileges.
I want to use remoting only to communicate between processes in the same machine. Anyway, everyone seems to recommend WCF even when this is the case. But if this will require my application to run only with administrator privileges then I'd rather find another solution than WCF.
There seem to be a workaround that involves running the command line and using some tool that varies depending on the Windows OS version. Is this the only way? Would I have to tell my users to run the command line and all that stuff or can this be automated, considering that my application runs on XP, Vista and 7?.
Administrative privileges are only needed for the HTTP URL namespace reservations. If you are using named pipe communication (which would be the recommended way to go for inter-process communication), then you can run fine as a normal user.
It could well be that because you are registering the endpoint information programatically that you need the elevated permissions. WCF does not require them in most circumstances.
Services such as this one require permission to register HTTP
addresses on the machine for listening. Administrator accounts have
this permission, but non-administrator accounts must be granted
permission for HTTP namespaces

Can't open a network file in WCF Service

I have a WCF WSDualHttpBinding service. The service is contained in a WindowsService with account type LocalSystem.
The service is attempting to access a network file stored on another machine on the same network as the service, e.g. \\dataStoreMachine\\myshare\\fileToOpen.txt . If the service is running on dataStoreMachine (the same machine that stores the file), the file is opened succesfully. However, if the service is running on another machine in the network, the file is not found. Is this a permissions issue? I've given read permissions on the network share. Is there something that needs to be specified in the service bindings so it has the correct rights? The file can be browsed to from the machine running the service within win explorer, so I know the file is really at the location it's looking at it for.
Both machines on the network (a VMnet) are not on a specific domain, but have the same username, and blank passwords.
The LocalSystem account doesn't have any rights to network access. Assuming your servers are part of an ActiveDirectory domain, you should use the Network Service account to run the service. You'll need to give read permission for the share to the specific domain accounts assigned as the machine account of the servers. This is usually something like: YourDomain\MachineId123 where the MachineId123 is the actual machine name in the domain.
If you servers aren't in a domain, then you can use the synchronized passwords on identical local accounts technique. I would avoid this if at all possible because in the real world, it is very easily broken by a password change. Each server would have a local machine account named something like File123Shared and would have the same password as the same account on the other machines. You would run your service using that local account after configuring it to be able to run as a service and any other permissions it may need.