Windows API StartService ... localized service name - c++

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);

Related

Reset a Managed Chrome Device with SDK using Google Apps Script

I'm attempting to create a dashboard for admins to allow them to reset a chrome device managed by GoogleAdmin using google apps script.
I don't see any way to perform a reset using Admin SDK API. Can this be done?
If you want to deprovision and/or disable a ChromeOS device
The supported actions when using the Directory API, according to the documentation here are:
deprovision: Remove a device from management that is no longer active, being resold, or is being submitted for return / repair, use the deprovision action to dissociate it from management.
disable: If you believe a device in your organization has been lost or stolen, you can disable the device so that no one else can use it. When a device is disabled, all the user can see when turning on the Chrome device is a screen telling them that it’s been disabled, and your desired contact information of where to return the device.
Taking this into account, this is how the request would look like:
POST https://admin.googleapis.com/admin/directory/v1/customer/{customerId}/devices/chromeos/{resourceId}/action
If you want to reboot and/or remote powerwash a ChromeOS device
However, if you simply plan on doing a powerwash or a reboot, you can make use of the below information:
REBOOT: Reboot the device. Can only be issued to Kiosk and managed guest session devices.
REMOTE_POWERWASH: Wipes the device by performing a power wash. Executing this command in the device will remove all data including user policies, device policies and enrollment policies.
Warning: This will revert the device back to a factory state with no enrollment unless the device is subject to forced or auto enrollment. Use with caution, as this is an irreversible action!
Taking this into account, this is how the request would look like:
POST https://admin.googleapis.com/admin/directory/v1/customer/{customerId}/devices/chromeos/{deviceId}:issueCommand
Apps Script
As for applying any of these in Apps Script, you will have to add the Admin SDK API advanced service and choose the directory _v1 version and simulate any of the above requests.
Code
Assuming you want to remote powerwash a device, you will have to write something similar to this:
let resource = {
YOUR_RESOURCE_HERE;
"commandType": "REMOTE_POWERWASH"
};
let customerId = 'CUSTOMER_ID';
let deviceId = 'DEVICE_ID';
AdminDirectory.Customer.Devices.Chromeos.issueCommand(resource, customerId, deviceId);
Not what you are looking for?
You can simply create a feature request on Google's Issue Tracker and provide the details with regards to your task by filling in the form here.
Reference
Directory API Manage ChromeOS Devices.

Restricting a Service using Windows Firewall APIs not finding service shortname

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.

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.

GetUserNameExA function cannot give user Details at system startup time(GINA)?

i am using c++ win32 API.
i tried to get user details using GetUserNameExA();
i have use this function into system logondialog source(GINA).
in my logfile,it gives
CN=ComputerName,CN=Computers,DC=JEGAN,DC=COM".
But it's used after logon on to system,at that time it gives user details like "CN=sanju,CN=USERS,DC=JEGAN,DC=COM" in my other solution.
i want user details only,but it gives system details at the logon time,how can i achieve user details at logontime?
note: i have already tried ADSI,LDAP functions & directoryservices cant able to use.so suggest any other system functions.
David is correct - the GINA DLL is loaded by the WinLogon.exe process. Check Task Manager and you'll see that WinLogon.exe runs as Local System. The GetUserName and GetUserNameEx functions provide information about the identity for the current thread:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724435.aspx
From a 20,000 foot view, after a user's credentials have been validated, the GINA notifies all Network Providers of the successful login. After this, it loads the user's profile and creates the user's shell (Explorer.exe) which is then displayed.
You might try using a Network Provider instead. They are fully supported up through Windows 8 and multiple NPs can be defined for the system so you won't run into the 'chaining' issues that GINAs have.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa378775.aspx
The NPLogonNotify function will receive the user's cleartext name, domain and password (sometimes you'll receive a UPN as username in which case the domain is blank). You can use this information as is, perform LDAP-based lookups to AD or use LogonUser & ImpersonateLoggedOnUser before calling GetUserNameEx. Be extremely careful with this last approach since network providers run as Local system within the WinLogon.exe process. Always call RevertToSelf and CloseHandle to undo/clean up the previous calls.
The only (quite quirky) workaround for what you are trying to do is to log on some other user account on the side which has access to the domain and can thus query user details (don't remember the permissions needed in detail, though). Otherwise I'd suggest you go with Gregg's answer.
With a thread impersonated as such user you should then be able to query the information for the user that you are going to log on (how do you even know by that time?) via NetUserGetInfo() and friends. Choose the USER_INFO_* struct that best suits your needs and simply ask the domain server for the information. This should also work on earlier and later systems (the functionality, not the GINA itself).

Exchange Web Services, try to use ExchangeImpersonationType

I am trying to use EWS, first time trying to use the ExchangeServiceBinding. The code I am using is below:
_service = new ExchangeServiceBinding();
//_service.Credentials = new NetworkCredential(userName, userPassword, this.Domain);
_service.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
_service.Url = this.ServiceURL;
ExchangeImpersonationType ei = new ExchangeImpersonationType();
ConnectingSIDType sid = new ConnectingSIDType();
sid.PrimarySmtpAddress = this.ExchangeAccount;
ei.ConnectingSID = sid;
_service.ExchangeImpersonation = ei;
The application is an aspnet 3.5 trying to create a task using EWS. I have tried to use impersonation because I will not know the logon user's domain password, so I thought impersonation would be the best fit. Any thoughts on how I can utilize impersonation? Am I setting this correctly, I get an error while trying to run my application. I also tried without impersonation just to try to see if I can create a task, no luck either. Any help would be appreciated. Thanks.
Without broader context of your code snip, I can't tell for sure what's wrong, but here are a few things you might find useful...
You mention you had trouble connecting without impersonation.
I'm assuming you are using Exchange Server 2007 SP1, yes?
Do you have a mailbox for which you do know the username and password? If so, consider trying to connect to that mailbox, just to see if you can send an email or query for inbox count. That will help verify your connection at least.
As to exchange impersonation,
have the permissions been set on the Client Access Server (CAS) to enable impersonation?
Have the permissions been set on either the mailbox or mailbox database (containing the mailbox you are attempting to access)?
are you in a cross-forest scenario that requires additional trust relationships?
If not, that might explain why you cannot connect.
Some links you might find useful
Configuring (http://msdn.microsoft.com/en-us/library/bb204095.aspx)
Using Exchange impersonation (http://msdn.microsoft.com/en-us/library/bb204088.aspx)
Access multiple resource mailboxes (http://msexchangeteam.com/archive/2007/12/13/447731.aspx)