4

I have a Windows service which requires on-demand access to a remote CIFS share. Whenever it needs to access the share, it first tries to 'mount' it with provided credentials,

NET USE \\host\share password /USER:user

uses the share's contents, and then removes the share.

NET USE \\host\share /DELETE

Currently, the service only works the first time the share is used. On subsequent attempts, it doesn't work and I get the following error:

NET failed with exit code 2

However, this same logic all works perfectly fine when run manually from the command line; it only fails in the context of the service.

My question is: is there a better, more correct way to handle network shares in a Windows service? According to this article, NET USE is not recommended for use in services, even without the use of drive letters. Is there some alternative to NET USE I should be using, or does the service just need to run as a user other than the default LocalSystem user?

Ideally, the share should only be accessible when directly needed; so I'd like to keep the logic where the share gets deleted every time if possible.

TipsyTopsy
  • 43
  • 1
  • 1
  • 3
  • Have you tried specifying a drive letter and then deleting the drive letter? e.g. `NET USE t: \\host\share password /USER:user` and then `NET USE t: /d /y`. You're not exactly mounting or deleting the *share*, you're *mapping* to the share and then deleting the *mapping*. The share is on another server and it persists when you're done with it. – Todd Wilcox Oct 31 '17 at 21:10
  • Is there a reason you need to map a drive letter, rather than just access the UNC path directly? – Charles Burge Oct 31 '17 at 21:13
  • @CharlesBurge That's how it's being done now, just using the UNC path directly. It used to be done with drive letters, but in light of the linked article and other problems, we moved to trying just the UNC path. – TipsyTopsy Oct 31 '17 at 21:18
  • 1
    The article pretty much answers your question. The better, more correct way is to use a UNC path. You stated it "all works perfectly fine when run manually from the command line; it only fails in the context of the service." the reason is, as stated in the article "Drive letters are not global to the system. Each logon session receives its own set of drive letters from A to Z. Therefore, redirected drives cannot be shared between processes running under different user accounts". In short, don't use mapped drives for automated processes. – Charles Burge Oct 31 '17 at 21:27
  • 1
    @CharlesBurge Yes, but a service can mount it's own mapped drives if the script is doing the mapping first. Though I agree it's bad practice, there are still things out there that don't like UNC paths. Anyway, it doesn't even seem like the OP's script is using drive letters? – Dan Oct 31 '17 at 21:31
  • Correct, this is **not** using drive letters, just the UNC path. I'm aware that drive letter mappings aren't shared between different users/login sessions, so even when drive letters were used that wasn't the problem since we only had the one process accessing the share. – TipsyTopsy Oct 31 '17 at 22:45

1 Answers1

4

You should be running the service as a specific user account, and that user account should have permissions to access the share.

Putting a username and password in like that is a pretty awful way of working. Not only for security, but also for portability and management.

Dan
  • 15,280
  • 1
  • 35
  • 67
  • This +1000. And the service should reference the UNC paths directly rather than trying to map a drive. – Ryan Bolger Oct 31 '17 at 22:18
  • @RyanBolger this isn't using drive letters, just the path. Also the username/password aren't hardcoded into the source, they come from a configuration. – TipsyTopsy Oct 31 '17 at 22:48
  • 1
    The point is that the service should be running in the context of the user who has access to the share (or any network resource) so there's no need to mess with credentials at all in the code or the app config. – Ryan Bolger Nov 01 '17 at 04:30