error 5 when starting a service - c++

i created a windows service in c++ and when i try start the service i get the message error 5: access denied.
my user account is set to admin and i even tried using the default admin account on the computer and it still doesn't work.
i can install/uninstall the service through the cmd without problems but i can't start the service
the code isn't the problem here its the user account. any suggestions on how to fix this?

"Running a service" is not simply "starting a program on my desktop". It does not necessarily run as "you".
The service is detached from any desktops and it actually ignores your user account. The service will have its own account/password configuration stored in the OS and when you run it, you only order it to start up. It will startup on its own user account. If you have put your .exe/.dll files in some protected folder, and if you have not configured neither the accessrights to that files nor user-pass for the service, then there's great odds that the service tries to run at default service user account like 'LocalService' or 'NetworkService' and that it simply cannot touch the files.
If you installed the service properly, go to ControlPanel - AdministrativeTools - Services, find your service and check the (if I remember well) second tab and verify that the username presented here has access to the files that are tried to be loaded and run. If the username is wrong, correct it. If you don't care about the username, then just peek that name and set accessrights on the folder and/or files such that at least both "read directry contents" and "read" and "execute" are available for that-username-the-service-tries-to-run-as.

Related

Windows agents implementation

One creates a Windows agent by calling CreateService with one of the following two parameters: SERVICE_USER_OWN_PROCESS or SERVICE_USER_SHARE_PROCESS. When SERVICE_USER_OWN_PROCESS is used, the agent will start with the next login and it will have a name like < service_name>_< some session ID>. Example of Windows 10 Microsoft agents: MessagingService_ba3d3c, PrintWorkflowUserSvc_ba3d3c or DevicesFlowUserSvc_ba3d3c (call sc query type=userservice to see the active ones) - in this case, the is 0xba3d3c, while the Logon Session is 0xba1a53 (close, but not enough) (seen with Process explorer).
My questions are:
Can I start the agent immediately after installation without logout? It would help with the installer that asks for reboot now.
What is this mysterious "session ID" ? It would help with the testing, to avoid enumeration and guessing.

Azure VM, your credentials did not work on remote desktop

I've just had a bit of fun trying to connect to a new VM I'd created, I've found loads of posts from people with the same problem, the answer details the points I've found
(1) For me it worked with
<VMName>\Username
Password
e.g.
Windows8VM\MyUserName
SomePassword#1
(2) Some people have just needed to use a leading '\', i.e.
\Username
Password
Your credentials did not work Azure VM
(3) You can now reset the username/password from the app portal. There are powershell scripts which will also allow you to do this but that shouldn't be necessary anymore.
(4) You can also try redeploying the VM, you can do this from the app portal
(5) This blog says that "Password cannot contain the username or part of username", but that must be out of date as I tried that once I got it working and it worked fine
https://blogs.msdn.microsoft.com/narahari/2011/08/29/your-credentials-did-not-work-error-when-connecting-to-windows-azure-vms/
(6) You may find links such as the below which mention Get-AzureVM, that seems to be for classic VMs, there seem to be equivalents for the resource manager VMs such as Get-AzureRMVM
https://blogs.msdn.microsoft.com/mast/2014/03/06/enable-rdp-or-reset-password-with-the-vm-agent/
For complete novices to powershell, if you do want to go down that road here's the basics you may need. In the end I don't believe I needed this, just point 1
unInstall-Module AzureRM
Install-Module AzureRM -allowclobber
Import-Module AzureRM
Login-AzureRmAccount (this will open a window which takes you through the usual logon process)
Add-AzureAccount (not sure why you need both, but I couldn’t log on without this)
Select-AzureSubscription -SubscriptionId <the guid for your subscription>
Set-AzureRmVMAccessExtension -ResourceGroupName "<your RG name>" -VMName "Windows8VM" -Name "myVMAccess" -Location "northeurope" -username <username> -password <password>
(7) You can connect to a VM in a scale set as by default the Load Balancer will have Nat Rules mapping from port onwards 50000, i.e. just remote desktop to the IP address:port. You can also do it from a VM that isn't in the scale set. Go to the scale set's overview, click on the "virtual network/subnet", that'll give you the internal IP address. Remote desktop from the other one
Ran into similar issues. It seems to need domain by default. Here is what worked for me:
localhost\username
Other option can be vmname\username
Some more guides to help:
https://learn.microsoft.com/en-us/azure/virtual-machines/windows/quick-create-portal#connect-to-virtual-machine
https://learn.microsoft.com/en-us/azure/virtual-machines/windows/connect-logon
In April 2022 "Password cannot contain the username or part of username" was the issue.
During the creation of VM in Azure, everything was alright but wasn't able to connect via RDP.
Same in Nov 2022, you will be allowed to create a password that contains the user name but during login it will display the credential error. Removing the user name from the password fixed it.

CoRegisterClassObject returns error (session 0?)

A customer is running one of our programs, usually run as a service, as an application. The customer is getting the following error on CoRegisterClassObject():
The class is configured to run as a security id different from the caller.
It looks like some type of session 0 error, but why should CoRegisterClassObject() care about session 0? COM should allow both services (session 0) and apps (session > 0) and not care what registers what, shouldn't it?
Also, I don't like the fact that it's not in the list of errors returnable by CoRegisterClassObject(), as per the Microsoft doc webpage.
The error code in question is CO_E_WRONG_SERVER_IDENTITY (0x80004015).
Per this page:
COM security frequently asked questions
Q6 Why does CoRegisterClassObject return CO_E_WRONG_SERVER_IDENTITY? When launching my ATL 1.1 server service as an .exe file, I receive CO_E_WRONG_SERVER_IDENTITY from CoRegisterClassObject. (The class is configured to run as a security ID different from the caller.) This seems to occur whether I skip the CoInitializeSecurity or not. It fails running as a service or as an .exe file.
A. Many services are debugged by running them as console applications in the interactive user identity. Because the service is already registered to run in a different identity (configurable by the Services control panel applet), OLE fails the CoRegisterClassObject and RunningObjectTable::Register(ROTFLAGS_ALLOWANYCLIENT) calls by returning CO_E_WRONG_SERVER_IDENTITY to enforce security and to prevent malicious servers from spoofing the server. To debug by running in the interactive user's identity, make the following changes in the server's registry entries to prevent these failures:
• To prevent CoRegisterClassObject failure, remove the following named value:
[HKEY_CLASSES_ROOT\APPID\{0bf52b15-8cab-11cf-8572-00aa00c006cf}]
"LocalService"="HelloOleServerService"
• To prevent a IRunningObjectTable::Register(ROTFLAGS_ALLOWANYCLIENT) failure, follow these steps:
Remove the following named value:
[HKEY_CLASSES_ROOT\APPID\{0bf52b15-8cab-11cf-8572-00aa00c006cf}]
"LocalService"="HelloOleServerService"
Then add the following named value:
[HKEY_CLASSES_ROOT\APPID\{0bf52b15-8cab-11cf-8572-00aa00c006cf}]
"RunAs"="Interactive User"
You muist restore the modified registry entries after debugging.
I am assuming you would have to replace {0bf52b15-8cab-11cf-8572-00aa00c006cf} with your COM object's actual CLSID instead.

How can an admin process open an application in the logged in user?

Overview
The Process
exe/dll compiled in C++ to be run
Scenario
Log in (win 7) to a standard user account (no admin)
run The Process as admin
The Process opens some app (exe) using ShellExecute
Problem
The app is opened in the scope of the admin user
Expecting
The app is opened in the scope of the standard user
Solutions
1. CreateProcessAsUser
Use CreateProcessAsUser (Assuming I managed to get hToken right that should have solved the issue).
However, I get the call failed with error code 1314 - ERROR_PRIVILEGE_NOT_HELD. Going back to the documentation tells me:
If this function fails with ERROR_PRIVILEGE_NOT_HELD (1314), use the
CreateProcessWithLogonW function instead
So I digged in and found this CreateProcessAsUser Error 1314 which wasn't very helpful.
2. ImpersonateLoggedOnUser
using ImpersonateLoggedOnUser generated the same error code: 1314 - ERROR_PRIVILEGE_NOT_HELD.
3. CreateProcessWithLogonW
CreateProcessWithLogonW requires lpPassword which naturally I don't have
The Question
How can an admin process open an application in the logged in user?
Have you tried using CreateProcessWithTokenW which is mentioned in the CreateProcessWithLogonW documentation? It seems to require a much weaker privilege than CreateProcessAsUser, one you should posses (SE_IMPERSONATE_NAME rather than SE_ASSIGNPRIMARYTOKEN_NAME).
You said you already have a token for the interactive user so I won't go into it.
(Note: Strange bugs have been reported with all of this, including CreateProcessWithTokenW. Don't give up on the first attempt. A bug and a fix for example: why is CreateProcessWithTokenW failing with ERROR_ACCESS_DENIED )
hToken is not a "right". It's a token. What the error says is that you lack a privilege.
Holding a privilege is not a fundamental right! Some privileges are given to certain users by default. Others need to be given through the Local Security Policy (in the "User Right Assignment" node in the MMC snap-in or with LsaAddAccountRights - all of which is documented in the page Assigning Privileges to an Account).
Besides that you sometimes have to enable privileges using AdjustTokenPrivileges. This is documented in the sibling page Changing Privileges in a Token.
Some APIs enable them if you hold them. Others don't and require you to do so yourself. The obvious way to go is to enable a privilege before calling and API that's documented to require it.
The MS Forum link may not have been but the error message is quite clear. MSDN says about the function:
Typically, the process that calls the CreateProcessAsUser
function must have the SE_INCREASE_QUOTA_NAME privilege
and may require the SE_ASSIGNPRIMARYTOKEN_NAME privilege
if the token is not assignable.
and the error is (from the page you linked to!):
ERROR_PRIVILEGE_NOT_HELD
  1314 (0x522)
  A required privilege is not held by the client.
This is actually a very tricky Task you want to accomplish. There are very strict security policies which make it very difficult.
As far as I know you can do it with psexec. It has a commandline Switch which enables user interaction but running the process as admin. I think your command should look like the following:
psexec \\target-computer -i -s [your command]
Another way to do it is using WMI. But for this you Need to Change the security Settings of the target machine (probably using GPO's). You Need to connect to the target machine using impersonation Level deletgate see here. Additionally as said before, you Need to Change the security Settings. See here

Unable to start a C++ Windows Service

I tried creating a Windows service in C++ using this code sample on MSDN. I opened the solution file in Visual Studio 2013 as admin. The build was successful. Then I installed the service, as per the description provided with the code sample, from a command prompt opened as administrator. The service is now shown in the Services tool in my system. However, when I try to start the service, I get error 5: Access is denied.
The output of sc qc CppWindowsService is as follows:
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: CppWindowsService
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 3 DEMAND_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Users\Aaa\Documents\CppWindowsService\C++\Debug\CppWindowsService.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : CppWindowsService Sample Service
DEPENDENCIES :
SERVICE_START_NAME : NT AUTHORITY\LocalService
Why does this happen, and how can I fix it?
Because the executable file is in your personal Documents folder, the local service account doesn't have access to it.
The easiest resolution would be to change the permissions on the Debug folder to give SERVICE read and execute access, with inheritance enabled. From the command line:
icacls Debug /grant SERVICE:(OI)(CI)(RX)
(Because Windows does not do traverse checking in the default configuration, you do not need to change the permissions for the parent folders.)
Another option is to copy the executable file to a public location (such as inside Program Files) and install it there, but you then have to remember to manually update the copy each time you recompile.
Edit: yet another option, as you suggest, is to change the account to local system so that the service is running with administrative privileges. Best practice is to run services with the least privilege necessary, but at this stage it doesn't matter much.
The comment provided by #Pumkko helped to solve the issue... The service account was specified as LocalService (#define SERVICE_ACCOUNT L"NTAUTHORITY\\LocalService"). From here:
The Local Service account didn't have permissions to the output .exe
file, and this was why the error was occuring.
I changed the account type to LocalSystem (#define SERVICE_ACCOUNT L"LocalSystem") and now my service can be started.
Thankyou #Pumkko and #Harry Johnston.