Restricting a Service using Windows Firewall APIs not finding service shortname - c++

I am using the example to restrict all except one port for a specific windows service. I took the example from msdn and tried it for OpenVPN windows service. Basically I just edited these two lines:
BSTR bstrServiceName = SysAllocString(L"OpenVPNServiceInteractive");
BSTR bstrAppName = SysAllocString(L"C:\\Program Files\\OpenVPN\\bin\\openvpnserv.exe");
As it needs the shortname and not the display name, I did sc query in my console and found for OpenVPNServiceInteractive, but when I run it doesn't find the service shortname (it fails the handle and says: RestrictService failed: Make sure you specified a valid service shortname)
So it basically can't find the service shortname which I specified. Does it prints (sc query) the real shortname of a service? Why doesn't it finds it?

It failed to restrict the service because I lacked administrator privileges. Ran it as administrator and worked.

Related

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.

error 5 when starting a service

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.

Verify Active Directory domain trust relationship of the local machine

I have to find out if the local machine is still joined to a domain, or if another computer has used the computer account or, if the computer account has been reset.
In other words, i need to verify the trust relationship between the local machine and the domain
NLTest /SC_VERIFY:{Domain} does the job pretty well.
Are there any API functions that i can use to detect whether the local machine has lost the trust relationship to a domain? I don't like to call external executables from my program.
What i tried so far:
NetGetJoinInformation(): It doesn't realize it.
DsBind*(): It doesn't realize it. Also tried to call it under the local system account.
Any ideas?
Okay. After a lot of digging, i finally found a solution: I_NetLogonControl2
NETLOGON_INFO_2* buffer=NULL;
LPBYTE domainName = (LPBYTE) L"eng";
int ret = I_NetLogonControl2(NULL, NETLOGON_CONTROL_TC_VERIFY, 2, (LPBYTE) &domainName, (LPBYTE*)&buffer);
wprintf( L"I_NetLogonControl2() returned %i\n", ret);
if (ret==0)
{
wprintf( L"PdcConenctionStatus: %i\n", buffer->netlog2_pdc_connection_status);
if (buffer->netlog2_pdc_connection_status==0)
wprintf(L"Trust relationship verified.\n");
else
wprintf(L"Trust relationship FAILED.\n");
wprintf( L"TcConenctionStatus: %i\n", buffer->netlog2_tc_connection_status);
wprintf( L"Flags: %i\n", buffer->netlog2_flags);
}
return 0;
So the magic thing is hidden in NETLOGON_INFO_2::netlog2_pdc_connection_status.If this value is 86 (ERROR_INVALID_PASSWORD) or 5 (ERROR_ACCESS_DENIED) the computer account has been changed (or reset).
If the computer account has been deleted, the value is 1787 (ERROR_NO_TRUST_SAM_ACCOUNT)
Hope this helps others!
Unfortunately, the MSDN documentation is not precise. When you are specifying "NETLOGON_CONTROL_TC_VERIFY", the data argument (LPBYTE) must point to (LPWSTR*)!
you can try LogonUser function to perform network login (LOGON32_LOGON_NETWORK).
If workstation has broken trust with domain, it will not be able to verify your credentials.
You will need some domain credentials which can perform network logon of course, not local.
Your other option is to use local account which has granted network service logon and try to access other domain workstation resource.You can receive access denied error or trust relation failed depends on which resource on which server.
Finally, you can still search system event log for event ID signaling trust failure.
but we don't have any well known accounts that we can use for this
You can not check for workstation account status on domain site (in AD) until you authenticate somehow, just local status.
NetLogon_Control2 is for BDC to PDC communications; does not work for my tests in Win 7
Microsoft page --
Remarks
This function can be used to request that a BDC ensure that its copy of the SAM database is brought up-to-date. It can also be used to determine if a BDC currently has a secure channel open to the PDC.

Windows API StartService ... localized service name

I want to start the Volume Shadow Copy service with a C++ program. This involves getting a handle to the service control manager (OpenSCManager), using this to obtain a service handle (OpenService) and then starting the service (StartService).
However, I have to pass the service name as a string to the OpenService function. The VSS service is called Volumeschattenkopie on my German Windows Vista. Is there a way to start the correct service in any language? I haven't used resource strings before but are service names obtainable with FindStringResourceEx or something like that?
Are you absolutely sure that Volumeschattenkopie is the service name on German Vista? It is definitely the service display name, but OpenService is looking for the name that was used during CreateService, which may not be localized. To locate the original service name, go into the services control panel, bring up the properties for the service you are interested in. It says the name right at the top. On my english win7 box, Volume Shadow Copy's service name is VSS.
I had the same problem with getting localized names for built-in Windows accounts like 'NT AUTHORITY\NETWORK SERVICE' or 'NT AUTHORITY\SYSTEM'.
Only difference is that I use C# in this case. However I think this should not be a problem to transfer to C++ (using unmanaged or managed C++?)
Here is how I get localized 'NT AUTHORITY\NETWORK SERVICE' on local computer:
SecurityIdentifier userIdentifer = new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null);
string accountName = userIdentifer.Translate(typeof(NTAccount)).Value;
And if I need 'NT AUTHORITY\SYSTEM' then I just use different Sid:
SecurityIdentifier userIdentifer = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);