We have an application that we have instrumented with WMI, and have added a WMI method which is a ManagementTask. When we try to invoke this management task from another application the method is getting called just fine, however within that thread of execution we are trying to write to a file, send a command to the SCM, and perform debug logging. None of these three items will execute because they seem to be running into permissions problems.
When we try to write to a file we get the error
Either a required impersonation level was not provided, or the provided impersonation level is invalid.
How do we resolve this?
Al, I feel your pain. Any attempt to write to a file using native WMI methods will fail since WMI is not capable of doing it. However, there is a workaround created by Frank White using C#, which was fleshed out in VBS. Here's the line he created that does the magic:
InputParameters("CommandLine") = "cmd /c echo myFTPCommands > c:\ftpscript.txt"
Please refer to the VBS method for full description, and post back here if you have questions about it. And yes, you will need to set impersonationLevel, as shown in the VBS page.
For sending a command to the SCM, that shouldn't be a problem, so try it separately to ensure there's no issues. For debug logging, if you're writing a file to the remote system, then you'll have to use the workaround mentioned above.
Related
I have a Custom Action that runs an executable within an msi installer package. The exe is compiled as a console application and stdouts necessary info.
I want that output redirected to the MSI log file.
I don't want the console to be shown during the installation.
For number 2 I suppose I can use windows as a subsystem, which will not open a console at all. But no output will be shown even if I run the exe from a terminal (PowerShell/CMD).
For number 1 I thought of running an executable as a subprocess called within a Custom Action DLL, but it is not possible since the exe is stored in a binary table and won't be generated when I need it. Moreover, it will have a random name.
The Custom Action's logic MUST be run as a separate process.
EDIT: Some colleagues wrote a free guide on installation testing. Maybe it will be useful in the future, to avoid such costly mistakes.
I don't think you can do it if you want to run the custom action as a separate process. I might be wrong. But I never tried this and it doesn't seem/sound possible.
Basically, the MSIEXEC process will own the handle of the log file created by the installation and I don't think you can share it with a separate process.
Why do you need to use a separate custom action process?
As a test - you could try to create an additional DLL custom action, that runs asynchronously. The purpose of this custom action is simply to communicate with your EXE process and write inside the log file any information you want to pass from the EXE custom action. I never tried this approach, but if you have time to kill and really need the main logic to remain in the EXE custom action, you could give it a try.
I have been dabbling with working nicely with UAC for a while and I found about a few things:
With UAC enabled, a program in the Startup folder, that requires to be run as admin (say by an embedded manifest), cannot be run according to this Stack Overflow thread.
Another method of running a program at startup is by creating a key containing the path to that application in: HKLM or HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run or HKLM or HKCU\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run in 64 bit machines.
Yet another method is using the task scheduler setting the Run with highest privileges option. This is the only method that bypasses the problem stated in point 1.
Coming from a Linux background, I had no clue about all these admin rights related problems. If someone can list out scenarios which absolutely need administrator privileges, it would be of great help!
I'm asking this because when I'm developing some application, I keep encountering several problems during implementation mostly because my application required admin rights when it shouldn't.
If I know, at design time, all possible scenarios that require admin rights, I could possibly design a common service for all my applications that takes care of all the administrator tasks (I think services are the Windows way of doing things like this).
There really isn't a list of scenarios or API function calls that require elevation. Your best option will probably be to focus on what API calls require elevation. The reason for this is that it may be required only if certain values are passed to the function. For instance CreateFile can create a file in your home directory without elevation but requires it for creating a file in C:\Windows. If the directory is provided through user input the only way you can know if elevation is required is to check the error code when the call fails. If elevation is required the function will set the error status to ERROR_ACCESS_DENIED and return a value indicating failure.
I have a C++ windows service that sometimes crashes when I call the system() function to shell out a command. I've run the exact text of the command in the windows command-line, and it runs just fine, but for some reason it fails when system() is run.
To make matters worse, I can't seem to get any information as to why system() is failing. There doesn't seem to be an exception raised, because I'm doing a catch(...) and nothing's getting caught. My service just stops running. I know that it's the call to system() that is failing because I've put logging information before and after the call, and anything after just doesn't log anything.
So, is there a different way that I can shell out my command? At the very least, something that will give me some information if things go wrong, or at least let me handle an exception or something.
I belive system() is technically part of the C standard library, and therefore wouldn't throw exceptions. You should be able to check the return code or the ERRNO variable to get some information about what happened. This MSDN link has some information about the possible return codes on Windows.
I've also seen system() fail for other external reasons, such as virus scanners, so you might investigate that as well.
I don't know of a better way to run shell commands, but I could be wrong.
EDIT: If it still just seems to crash for no reason, you might try using process monitor to see what is going on at a lower level. Since the output from process monitor can be kind of overwhelming, a trick I like to use is to add a statement right before the call to system() to your program to open a nonexistent file like "C:\MARKER.TXT" or something, then you can search the process monitor output for the name of the file and look at the entries right afterward that may have something to do with the problem.
Ordinary catch() will not catch fatal exceptions (e.g. segmentation fault). You have to use structured exception handling. Better yet, enable post-mortem debugging; this article explains how you can enable post-mortem debugging of services.
You could use fork/exec, but I think that is what the system is doing.
I think your problem could be the user account associated on your service.
Either there's an environment problem (missing entry in path) or the account the service is using to run doesn't have the rights to exec whatever you're trying to run.
Run services.msc and look at the properties for your service.
On the logon page, as a test, change the setup so it uses your account to run the service. If it succeeds, you know what the problem is.
Another thing to look at is the path while inside the service. Use getenv( "PATH" ) and see if a path you might be reliant on is missing.
Hope this helps...
I ended up using CreateProcess. It's been working out so far.
I'm building a custom authentication subpackage for MSV1_0 for Windows 7. I've used the msvsubauth sample in from the Windows SDK and I have 2 questions regarding some problems I'm facing with that:
When I'm trying just to make sure that the routine get's invoked and set the Auth0 property in the registry to my package and add a simple code at the end of the Msv1_0SubAuthenticationRoutine that creates a file:
//
// Cleanup up before returning.
//
Cleanup:
hTestFile = CreateFile(
TEXT("C:\\lsa\\lsa.txt"),
GENERIC_READ|GENERIC_WRITE, 0,
NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if(hTestFile != INVALID_HANDLE_VALUE) {
CloseHandle(hTestFile);
}
return Status;
} // Msv1_0SubAuthenticationRoutine
Apparently the package gets invoked because when I enter my password I get an error message from windows "the parameter is incorrect" which is a good sign. But why I'm getting that error? when the exactly same code is executed from a separate .exe file it runs perfectly and creates the test text file. I've checked the permissions and set "full control" for "everyone". Any ideas? the SDK doesn't exactly mention what kind of isolation LSA is creating for code within auth packages.
The second problem is testing the AP. Currently with every change I rebuild the library, copy it to a test VM and then to the System32 folder and reboot it. Is there an easier way to do that?
Thank in advance!
Debugging in Winlogon and LSASS makes for the most time consuming debugging.
To ease your debugging, you could write a proxy AP that exports the same functions. When loaded, you proxy_ap would
Copy the real AP from a known location to a temp locationand.
LoadLibrary that DLL, GetProcAddress of everything, and forward any calls it receives to that newly loaded DLL.
Watch for changes in the directory where the original AP was copied from
When a change occurs (and if your AP changed) FreeLibrary and goto step 2
But you need to keep a tight grip on what happens on your development target, because handling the dll switch while dealing with requests comming from many threads can become a worse nightmare that what you are trying to solve.
LogonUI.exe starts a new instance every time, but LSASS.exe is long lived.
+Have a look at CVSNT source code (http://cvsnt.sourcearchive.com/). They have a pretty nice AP that implements su. Run the sample in the local system account with psexec -s (from Microsoft/SysInternals pstools suite)
Perhaps your problem is Everyone only includes Authenticated users? This is just a guess.
I suggest you use Process Monitor to monitor for Access Denied messages or for your path. It is fantastic for debugging permission/path problems of all kinds.
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
If you experience the issue at the "Unlock Workstation" or "change Password" screens, and it doesn't prevent you logging in, this should be easy to do - set it running, reproduce the problem, log back in and hey presto.
Otherwise you might have to resort to tricks like executing that code path only for certain user accounts, on the Nth try, etc.
Writing a program in c++ and I want to issue a system command from the system() function but I don't want the user to see the command (because the command includes a pwd) in the executable window. I need to copy a file from the user's directory onto the server without allowing user access to the server or displaying the pwd. Figured having a .exe that does this is the easiest way.
Ex:
system("FILETRANSFER_SW.exe -pw helloWORLD11!# C:/temp.txt F:/tempfolder/")
But the executable window is showing this command, hence defeating the purpose of trying to hide the password.
I tried issuing
system("#echo OFF")
at the beginning of the program but that does not suppress the following commands, they still show up in the executable window.
Any suggestions?
Thanks...
The command line of running processes is considered public information in most operating systems.
Therefore it is a very bad idea to pass passwords on the command line.
There are two common workarounds to this problem, both of which require the support of the executable being called:
instead of passing the username/password on the command line, pass the name of a file containing the username/password
re-set the command line of the running process from within the called executable.
The first solution is easy and universally possible, the second one has a race condition and is harder to implement, because there's no cross-platform way to do it (on some OSes, changing argv will help).
I'm assuming from your command line that you're using Windows. If it doesn't need to be portable I would suggest you use the CreateProcess() API instead of calling system().
The CreateProcess() API can take a command-line and you can set up the STARTUP_INFORMATION parameter to hide the new process window (wShowWindow = SW_HIDE).
The command line will be hidden from the casual user, but as others have pointed out, it's not that hard to retrieve. Since you are creating a new process, I would suggest writing the sensitive data to that process' standard input. That way the process can just read it and proceed normally.
Using CreateProcess() API will hide the sensitive data from a user, but a power user can easily get the command line associated with the process using a free utilty, e.g. Process Explorer
Another solution is to send the password between your programs, encrypted with something like 3DES, or AES.
You could use a pipe to comunicate between both programs, and don't use the command line at all.
But any of this schemes is not really secure they can be circumvent rather easily. If you want more security you should use some kind of challenge-response protocol with the server.