I have a windows service written in C#. I want to set the service account to be LocalSystem. The service spawns a process which is a batch file in which Git Authentication is required. If I set the service account as User, it prompts for username and password while installation and the service runs perfectly. But when I register it as LocalSystem account, it fails to do so.
Event Viewer error log is:
Source: Git Credential Manager
Details: System.InvalidOperationException: Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application.
The reason I want to go with LocalSystem account is I want to avoid any credential pop-up. Any help on how I can install the service without any password pop-up and authenticate git as well as current logged in user?
If you want to avoid a prompt for credentials, you need to set up a credential helper properly. It's likely that you are indeed using one, in this case the Git Credential Manager for Windows, but in this case that requires a UI prompt.
You will first need to make sure the system Git installation does not use a credential helper by typing git config --system --unset credential.helper. Then, configure your service to use an appropriate credential.helper argument when you're invoking your push or fetch command, like so: git -c credential.helper=my-credential-helper push origin main.
You can either write your own credential helper by following the directions in the gitcredentials(7) manual page and specify that name or use a shell command to get it from the environment. For example, if you wanted to push code and read data from the USERNAME and PASSWORD environment variables, then you'd run this command:
$ git -c credential.helper='f() { echo username=$USERNAME; echo password=$PASSWORD; };f' \
push origin main
Related
I am hosting a WCF Service in my IIS, and I Encountered the error shown below:
Request Error
The server encountered an error processing the request. Please see the
service help page for constructing valid requests to the service. The
exception message is 'Login failed for user 'IIS APPPOOL\TEST'.'. See
server logs for more details
I call my method with this link: http://192.168.1.111/TruckService.svc/getAllCompA
from the browser I can access the TruckService.svc file, only the methods throws an error.
The methods is shown from the service help link: http://192.168.1.111/TruckService.svc/help Don't know if that would make a difference?
There isn't a lot of info to work with, I did Google the error but cannot seem to find a similar issue.
Any Ideas?
This part of the error message tells you quite a bit, actually:
"The exception message is 'Login failed for user 'IIS APPPOOL\TEST'.'"
You didn't give a whole lot of information in your question, but I'm willing to bet your service is using a SQL database (Login failed for user is a fairly common SQL error).
Assuming your connection string is correct, based on the error you're most likely using integrated security, which means that the service is trying to login to SQL with the credentials it's being run under, in this case IIS APPPOOL\TEST.
If you want to continue using integrated security, then you need to run the application under an account that has the proper permissions to login to the SQL server. Alternatively, you can update the connection string to use a user name and password. Personally, I prefer integrated security.
Finally, did you check server logs for more details as the error suggested?
Added
To see/change the account the application pool is running under, go to IIS Manager (either from the start menu or type inetmgr from a command prompt). In the left hand pane, expand the tree view so you see the Application Pools node, and then click on that.
Select the application pool (in your case, TEST), right click and select "Advanced Settings..." from the context menu.
This will open a new screen, and you can see what account is currently running that application pool:
Click on the ellipses (...) and this will bring up another window where you can set the account:
Click the button for Custom account and then click "Set..").
Finally, enter the account (you will probably need to enter the domain to, like MyCompany\UserName), enter the password, confirm the password and click OK.
Note that if the password ever changes, the application pool will not run until the password is updated via the steps above.
I want to get service name inside service. The rough idea is to get process id and compare the process id with services enumerated by WMI, ServiceCotroller or EnumServicesStatusEx() API.
The problem is that the service is running under a domain account (it isn't local administrator). When I want to enumerate the services inside the running service, the running service itself is missing from enumeration!
If I move the service account to local administrator, the running service is found. So it isn't code issue. (If code issue, the behavior should be same: service not found.)
If I extract the logic to a console application (or by powershell) and run application or powershell under service account, the service is found, too. So it isn't permission issue. (If permission issue, the behavior should be same: service not found.)
The service CANNOT be enumerated when the service account IS NOT administrator and INSIDE service. It is very wire issue.
I check documentation for EnumServicesStatusEx from MSDN and find local administrator has extra SC_MANAGER_LOCK than local authenticated user. Is it the reason? But I CANNOT link the lock with service enumeration.
Or somebody please indicate a way to query service name inside the service.
Thanks.
BTW, It is on Windows 2008 R2.
I found a related question: How to get name of windows service from inside the service itself.
the 1st answer is not acceptable for me. I want to provide a common library and has no control to installer.
the 2nd answer is same idea with me. I guess it should be same with my result.
It is a permission issue.
Run psservice from Sysinternals like:
psservice.exe security InstrumentationTestService
and I got the following result:
PsService v2.24 - Service information and configuration utility
Copyright (C) 2001-2010 Mark Russinovich
Sysinternals - www.sysinternals.com
SERVICE_NAME: InstrumentationTestService
DISPLAY_NAME: InstrumentationTestService
ACCOUNT: LocalSystem
SECURITY:
[ALLOW] NT AUTHORITY\SYSTEM
Query status
Query Config
Interrogate
Enumerate Dependents
Pause/Resume
Start
Stop
User-Defined Control
Read Permissions
[ALLOW] BUILTIN\Administrators
All
[ALLOW] NT AUTHORITY\INTERACTIVE
Query status
Query Config
Interrogate
Enumerate Dependents
User-Defined Control
Read Permissions
[ALLOW] NT AUTHORITY\SERVICE
Query status
Query Config
Interrogate
Enumerate Dependents
User-Defined Control
Read Permissions
It indicates that my service account has no permission to Query the service status.
If I use service account to run powershell/WMI/ServiceController, the service account will turn into a INTERACTIVE user. So it has the permission to query service status.
The solution is to grant the service account Query status permission.
This is not a pure PowerShell answer, but you've got a good tool as far as EXEs,DLLs and SERVICEs are concerned it's TASKLIST.EXE.
Have a look to /FI and /FO. In the following sample I get information for the search service.
tasklist /FI "SERVICES eq WSearch" /FO "CSV"
To integrate it with PowerShell youcan use :
tasklist /FI "SERVICES eq WSearch" /FO "CSV" | ConvertFrom-Csv
I'm signing executables through a Windows Service. This service creates a batch-file, in which the actual Sign command is:
cd D:\wmt_sign\Signer\Tools
signtool sign /f "D:\codesign\cert\Certificate.pfx" /p MyPass /t "http://timestamp.digicert.com" /d "zxz" /du "http://www.testurl.com" "D:\codesign\Sign\Request307\filetobesigned.exe">>"D:\codesign\log\signlog\Request\SignLogReport.txt"
When I execute the batch command from the machine directly, no problem, everything works fine
When I execute the Sign command direclty from commanline, no problem everything works
when I execute the batchfile in code (process.startinfo....etc ) the timestamp-url cannot be reached! (error is "The specified timestamp server could not be reached.")
The service runs under Local System Account, there is a firewall, but this one is open for outwards traffic.
I have no clue at all....
The LocalSystem account, by default, does not have any rights to access the network. You should use the Network Service acount instead. Even then, if any of the URLs you are trying to access require authentication, it may stil not work. It that case you may need to create a domain account for the service to run under or impersonate.
Our setup has an embedded manifest that triggers the UAC before the application starts. (The applications runs as an admin user). However, if the setup needs to install the .NET Framework, we have to continue the setup after a reboot. For this reason, we have to create a registry key in the current user's RunOnce.
Unfortunatly, HKEY_CURRENT_USER points to the Administrator's registry. We need to find out the user that is currently logged in and started the installation. (Th normal USER clicked the setup.exe, an ADMIN entered his details in the UAC prompt. We need to find out who the USER was)
I've tried all the usual methods (Environment.UserName, WindowsIdentity.GetCurrent())
Thanks!
You can use the LsaEnumerateLogonSessions function to retreive what you need. However, it is a winapi C function call. If you need a managed version of it, I belive you can look at the source code for Cassia, which uses this function in its terminal services API. The call should be the same. You can also look here.
Also you can use the NetWkstaUserEnum WINAPI function. You can find a managed wrapper for it here
With Cassia library this code works fine:
ITerminalServicesManager manager = new TerminalServicesManager();
ITerminalServicesSession session = manager.CurrentSession;
string userInfo = session.DomainName + "\\" + session.UserName;
NTAccount account = session.UserAccount;
Run your initial setup.exe as a small executable that puts up a splash screen while invoking your real setup program as a child process. The small EXE is not run as admin and can pass the logged in user name to the child process. The child process invokes UAC and runs in the admin context but already has the logged in username as a command line parameter.
It is not possible to retrieve the original user if your application is ran as Administrator:
If a user launches Setup by right-clicking its EXE file and selecting
"Run as administrator", then this flag, unfortunately, will have no
effect, because Setup has no opportunity to run any code with the
original user credentials. The same is true if Setup is launched from
an already-elevated process. Note, however, that this is not an Inno
Setup-specific limitation; Windows Installer-based installers cannot
return to the original user credentials either in such cases.
Source : InnoSetup Help
As said by Matthew in comments, you should not run your application as Administrator but only trigger UAC when needed in your code.
This returns the name of the logged in Windows User by stripping out the domain:
using System.Security.Principal; // here is the security namespace you need
...
string userName = WindowsIdentity.GetCurrent().Name.Replace("\\", "|");
string[] split = userName.Split(new Char[] { '|' });
lblDebug.Text = (split.Count() > 1) ? split[1] : userName;
I have the following C# code
using (RunspaceInvoke invoker = new RunspaceInvoke())
{
invoker.Invoke("Set-ExecutionPolicy Unrestricted");
// ...
}
which gives me the exception
Access to the registry key
'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell'
is denied.
According to this, the solution is to start PowerShell as an administrator.
Ordinarily, this can be accomplished by right-clicking PowerShell and selecting "Run as Administrator". Is there a way to do this programmatically?
I know this is an old post, but we ran into this same problem recently.
We had to scope the execution policy on the machine running the C# code by running the following from PowerShell...
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
When we had done this previously, without scoping, we were setting the execution policy for Administrator. Visual Studio \ C# was running as the current user, causing it to fail with insufficient permissions.
Check this out
You need to impersonate as an administrator to do it (you will of course need administrator credentials)
Check that article, that also comes with code ready to use (I've used it and it works great)
Basically, you need to do this:
using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
{
using (RunspaceInvoke invoker = new RunspaceInvoke())
{
invoker.Invoke("Set-ExecutionPolicy Unrestricted");
}
}
Administrative privileges are at the application level. The app that needs admin access in this case is yours. Creating runspaces in C# in a custom app does not invoke powershell the application - it just loads some assemblies into your application.
That said, you can elevate as the other poster said although embedding admin usernames and passwords into source code make me feel ill.
-Oisin
I think an alternative model would be to wrap the powershell executor into a simple asp.net webapi webservice.
The webservice could then be configured to run with the required permissions needed to do it's job. It can provide it's own security to determine which clients can call it.
To execute a script, you would just call webservice methods. You could make the method quite general - script name and params.
It's a bit more work, but a lot more secure (see x0n's thoughts).
Strictly for DEV environment
This is relatively very old post.
But I have found a new way to do this.
I am hosting the C# web api on IIS 8 having some powershell code that I want to run with administrator privileges.
So I provided the admin credentials in the Application pool identity setting.
Just set administrator account in app pool identity.
Hope this helps to anyone. :)