Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to run .NET 5.0 service as a different user #51269

Closed
BrettGFleischer opened this issue Apr 13, 2021 · 13 comments
Closed

Unable to run .NET 5.0 service as a different user #51269

BrettGFleischer opened this issue Apr 13, 2021 · 13 comments
Labels
area-Extensions-Hosting help wanted [up-for-grabs] Good issue for external contributors
Milestone

Comments

@BrettGFleischer
Copy link

Description

I am trying to get an ASP.NET 5.0 service to run as a different user (by using shift+right click and selecting Run as different user) because of a DCOM requirement, but I am unable to do so and simply receive an error (seen within Other information section below).

I am aware that this is a very general error about a process exiting, therefore, I generated a small sample to reproduce the bug locally (see code below).

public static void Main(string[] args)
  {
      //This is here so that one can attach to the process
      Console.WriteLine("Press any key to continue...");  
      Console.ReadLine();

      try
      {
          CreateHostBuilder(args).Build().Run();
      }
      catch (Exception e)
      {
          Console.WriteLine(e);
      }
  }
  public static IHostBuilder CreateHostBuilder(string[] args)
  {
      IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args);

      hostBuilder.ConfigureServices(services =>
      {
      });
      try
      {
          hostBuilder.UseWindowsService();//Line where error occurs
      }
      catch (Exception e)
      {
          Console.WriteLine(e);
      }
      return hostBuilder;
  }

Steps to reproduce the bug:

  1. Create a new local user account in windows

  2. Give the created user account full control of the containing debug folder (right click > properties > security > edit > add new user > assign "Full Control" > save)

  3. Give the created user account "Logon As Service" rights (Control Panel > Administrative Tools > Local Security Policy > Dropdown "Local Policies" > Double Click "User Rights Assignment" > Double Click "Logon as a service" > Add your created user account > OK)

  4. Shift + Right Click > Run as different user on the test.exe console app (see code below)

  5. Enter local user name and password and run

  6. Attach to the process from Visual Studio (Console.ReadLine(); gives you time to attach to process)

  7. Step through code and see error on "Line where error occurs"

Expected behavior:

Since I am using UseWindowsService(), I expect the app to start up with the provided user credentials.

Configuration

  • Running version: .NET 5.0
  • OS: Windows 10 Enterprise/Pro (locally/development), Windows Server 2016 (remotely/deployment)
  • Architecture: x64/x86
  • Configuration specific: Unsure
  • Using Blazor: Not using Blazor

Regression?

I don't know.

Other information

Unhandled exception. System.InvalidOperationException: Process has exited, so the requested information is not available.
   at System.Diagnostics.Process.EnsureState(State state)
   at System.Diagnostics.Process.get_SessionId()
   at Microsoft.Extensions.Hosting.WindowsServices.WindowsServiceHelpers.IsWindowsService()
   at Microsoft.Extensions.Hosting.WindowsServiceLifetimeHostBuilderExtensions.UseWindowsService(IHostBuilder hostBuilder, Action`1 configure)
   at Microsoft.Extensions.Hosting.WindowsServiceLifetimeHostBuilderExtensions.UseWindowsService(IHostBuilder hostBuilder)
   at Historian.Service.Program.CreateHostBuilder(String[] args) in ..\Program.cs:line 31
   at Historian.Service.Program.Main(String[] args) in ..\Program.cs:line 27

I believe the error lies within the hostBuilder.UseWindowsService();//Line where error occurs line, seen in the Description section above.

Do you know of any workarounds?:

I know that I can install the service then go to the properties of that service and set the logon credentials as the specified user, as a workaround. The service then starts up and is seen as running, however, the expected output from the service is not received. Therefore, I suspect that the running status is a false positive and the service is actually in an errored state or the service is still not using the logon credentials correctly.

@mairaw mairaw transferred this issue from dotnet/core Apr 13, 2021
@BrennanConroy BrennanConroy transferred this issue from dotnet/aspnetcore Apr 14, 2021
@dotnet-issue-labeler dotnet-issue-labeler bot added area-Extensions-Hosting untriaged New issue has not been triaged by the area owner labels Apr 14, 2021
@ghost
Copy link

ghost commented Apr 14, 2021

Tagging subscribers to this area: @eerhardt, @maryamariyan
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

I am trying to get an ASP.NET 5.0 service to run as a different user (by using shift+right click and selecting Run as different user) because of a DCOM requirement, but I am unable to do so and simply receive an error (seen within Other information section below).

I am aware that this is a very general error about a process exiting, therefore, I generated a small sample to reproduce the bug locally (see code below).

public static void Main(string[] args)
  {
      //This is here so that one can attach to the process
      Console.WriteLine("Press any key to continue...");  
      Console.ReadLine();

      try
      {
          CreateHostBuilder(args).Build().Run();
      }
      catch (Exception e)
      {
          Console.WriteLine(e);
      }
  }
  public static IHostBuilder CreateHostBuilder(string[] args)
  {
      IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args);

      hostBuilder.ConfigureServices(services =>
      {
      });
      try
      {
          hostBuilder.UseWindowsService();//Line where error occurs
      }
      catch (Exception e)
      {
          Console.WriteLine(e);
      }
      return hostBuilder;
  }

Steps to reproduce the bug:

  1. Create a new local user account in windows

  2. Give the created user account full control of the containing debug folder (right click > properties > security > edit > add new user > assign "Full Control" > save)

  3. Give the created user account "Logon As Service" rights (Control Panel > Administrative Tools > Local Security Policy > Dropdown "Local Policies" > Double Click "User Rights Assignment" > Double Click "Logon as a service" > Add your created user account > OK)

  4. Shift + Right Click > Run as different user on the test.exe console app (see code below)

  5. Enter local user name and password and run

  6. Attach to the process from Visual Studio (Console.ReadLine(); gives you time to attach to process)

  7. Step through code and see error on "Line where error occurs"

Expected behavior:

Since I am using UseWindowsService(), I expect the app to start up with the provided user credentials.

Configuration

  • Running version: .NET 5.0
  • OS: Windows 10 Enterprise/Pro (locally/development), Windows Server 2016 (remotely/deployment)
  • Architecture: x64/x86
  • Configuration specific: Unsure
  • Using Blazor: Not using Blazor

Regression?

I don't know.

Other information

Unhandled exception. System.InvalidOperationException: Process has exited, so the requested information is not available.
   at System.Diagnostics.Process.EnsureState(State state)
   at System.Diagnostics.Process.get_SessionId()
   at Microsoft.Extensions.Hosting.WindowsServices.WindowsServiceHelpers.IsWindowsService()
   at Microsoft.Extensions.Hosting.WindowsServiceLifetimeHostBuilderExtensions.UseWindowsService(IHostBuilder hostBuilder, Action`1 configure)
   at Microsoft.Extensions.Hosting.WindowsServiceLifetimeHostBuilderExtensions.UseWindowsService(IHostBuilder hostBuilder)
   at Historian.Service.Program.CreateHostBuilder(String[] args) in ..\Program.cs:line 31
   at Historian.Service.Program.Main(String[] args) in ..\Program.cs:line 27

I believe the error lies within the hostBuilder.UseWindowsService();//Line where error occurs line, seen in the Description section above.

Do you know of any workarounds?:

I know that I can install the service then go to the properties of that service and set the logon credentials as the specified user, as a workaround. The service then starts up and is seen as running, however, the expected output from the service is not received. Therefore, I suspect that the running status is a false positive and the service is actually in an errored state or the service is still not using the logon credentials correctly.

Author: BrettGFleischer
Assignees: -
Labels:

area-Extensions-Hosting, untriaged

Milestone: -

@maryamariyan maryamariyan removed the untriaged New issue has not been triaged by the area owner label Apr 23, 2021
@maryamariyan maryamariyan added this to the 6.0.0 milestone Apr 23, 2021
@ceilingfish
Copy link

I found I was able to work around this issue with

dotnet /path/to/Historian.dll

So maybe something to do with the apphost.exe?

@eerhardt eerhardt modified the milestones: 6.0.0, 7.0.0 Jul 22, 2021
@eerhardt
Copy link
Member

The stack trace above is coming from WindowsServiceHelpers.IsWindowsService() calling into parent.SessionId. In looking at #52416 (comment), I don't believe the logic in IsWindowsService() is correct and should be changed as illustrated in that issue.

I wonder if that change would fix this issue as well.

Moving to 7.0 and marking as "up for grabs".

@eerhardt eerhardt added the help wanted [up-for-grabs] Good issue for external contributors label Jul 22, 2021
@zryogi
Copy link

zryogi commented Nov 17, 2021

After doing a little bit of testing it appears that the cause of the issue is not the failed validation of parent.SessionId == 0 but rather, at this point var parent = Internal.Win32.GetParentProcess(); has already exited so the fields of parent are no longer available. So if we remove the SessionId validation, it will still fail at parent.ProcessName:

ProcessValidation

At this point a work around to avoid the exception when directly executing the .exe would be to doing so from the command line:

runas /user:UserName .\path\to\exe\service.exe

In this case parent would be null, the exe would not execute as windows service (because we are doing it directly) but the exception will be avoided.

So, the deletion of the check may be to enough to solve the issue.

@KieranFoot
Copy link

Does this issue still remain after closing #52416 ?
If so, I'd like to have a crack at it.

@maryamariyan
Copy link
Member

@KieranFoot sure since it is up for grabs, it would be good to investigate and propose a fix if this is still a problem after the lastest changes

@deeprobin
Copy link
Contributor

Is this .NET 5.0 (EOL) specific or does this bug also occur on .NET 6/7?

@maryamariyan
Copy link
Member

Is this .NET 5.0 (EOL) specific or does this bug also occur on .NET 6/7?

we think it is fixed in 7.0 @deeprobin or @KieranFoot would you be able to test if this with the latest to confirm repro?

@BrettGFleischer
Copy link
Author

Hi there,

Just to give a bit of an update to the original bug.

Do you know of any workarounds?:

I know that I can install the service then go to the properties of that service and set the logon credentials as the specified user, as a workaround. The service then starts up and is seen as running, however, the expected output from the service is not received. Therefore, I suspect that the running status is a false positive and the service is actually in an errored state or the service is still not using the logon credentials correctly.

Our current workaround is still the same as the original code sample attached:

public static void Main(string[] args)
  {
      //This is here so that one can attach to the process
      Console.WriteLine("Press any key to continue...");  
      Console.ReadLine();

      try
      {
          CreateHostBuilder(args).Build().Run();
      }
      catch (Exception e)
      {
          Console.WriteLine(e);
      }
  }
  public static IHostBuilder CreateHostBuilder(string[] args)
  {
      IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args);

      hostBuilder.ConfigureServices(services =>
      {
      });
      try
      {
          hostBuilder.UseWindowsService();//Line where error occurs
      }
      catch (Exception e)
      {
          Console.WriteLine(e);
      }
      return hostBuilder;
  }

We are still using this workaround in .NET 6. When we have the capacity to test if the desired workflow works on our deployment machines we will and then reply on this thread. We ideally would like this to be resolved in .NET 6.

Thanks everybody for the feedback and input.

@eerhardt
Copy link
Member

I believe this issue has been fixed in .NET 7. We are no longer calling "Process.get_SessionId()" which is in the callstack in the original issue.

Please re-open if this issue still reproduces using the latest 7.0 build.

@mloskot
Copy link

mloskot commented Aug 18, 2022

This bug was discussed in #52416 and fixed in #62452, but it looks like the fix made it only to .NET 7. Correct?

Is there any chance to get it fixed in .NET 6, so it becomes available on containers with e.g. ASP.NET Core Runtime 6.0?

@eerhardt
Copy link
Member

@mloskot - #70751 is open tracking backporting that fix to 6.0. I've opened #74188 to backport the change. Once it is approved, it will be in the next servicing release.

@mloskot
Copy link

mloskot commented Aug 24, 2022

Thank you @eerhardt

@ghost ghost locked as resolved and limited conversation to collaborators Sep 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Extensions-Hosting help wanted [up-for-grabs] Good issue for external contributors
Projects
None yet
Development

No branches or pull requests

8 participants