Greetings!
When I try to use GetThreadContext() on a thread that I've started with CreateProcess(), I receive an error of 998: ERROR_NOACCESS
You can find a contrived but functional code example of this problem here: http://pastebin.com/tamDhYza
Based on the MSDN article regarding "Thread Security and Access Rights", my assumption is that I need to first pass the THREAD_GET_CONTEXT property into the lpThreadAttributes parameter of CreateProcess(). The type required by this argument is LPSECURITY_ATTRIBUTES, which appears to be a long pointer to the struct SECURITY_ATTRIBUTES. Unfortunately, I've not had much luck in figuring out how to add rights to this structure.
Could anyone help point me in the right direction?
I think you probably need to adjust the privileges of the calling code so that you can access the remote process. I suspect that you need to enable the SE_DEBUG_NAME privilege (see here) before you try and get the remote thread context. I'm not sure though as I usually use the debug API and call CreateProcess() with DEBUG_PROCESS which requires SE_DEBUG_NAME anyway...
If you do need to create a security descriptor then what you're doing is creating a DACL (discretionary access control list) which is a SECURITY_ATTRIBUTES structure that's populated with ACLs (access control lists) which allow or deny access to the resource by various principals (users, computers, etc). This used to be quite complex with lots of complicated API calls to make but now it's much easier, see http://msdn.microsoft.com/en-us/library/ms717798(VS.85).aspx for details.
Related
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 been tasked with writing entries to the Windows security log. The entire project is Win32 C++ code. I have already written (with help from various online resources) a logging class that handles registration, deregistration, and code for executing the ReportEvent() call. Also, I've done the mc.exe and rc.exe steps for my event logging, if that helps establish where I'm at in the project.
My question is a multi-parter:
I've noticed at Filling Windows XP Security Event Log that there are some who believe this is not allowed by Windows. Others ( How to write log to SECURITY event Log in C#? ) imply otherwise. Possible or not?
If it is possible, how to get it to write to the security log. Is it as simple as specifying "Security" as my source name when calling RegisterEventSource()?
As far as deregistration, when should that occur? When the app is uninstalled? When the app closes? When the log entry is written?
How do I look up my log entries? I look in the Windows Event Viewer, but I don't see the entries I add with my test app, despite all the appropriate return values from the system calls. Where would I look up the events that I specified with a source name of "yarp" when I made my call to RegisterEventSource()?
For the moment, I'll just deal with the first question, because the answer to that probably renders the rest irrelevant.
Only Local Security Authority (lsass.exe) can write to the security log. This isn't a matter that something else attempting to get the privilege will fail -- it's a matter of there not being a way for anything else to even request the privilege at all (and this is by design).
From there, about the only answer to your other questions is "Sorry!"
I am trying to set the owner of a file to another user programmatically in C++.
I have definitely enabled the SeRestorePrivilege for my process. I can confirm this using Process Explorer. I start the process, it is disabled, I run my code to enable it, ProcExp reports it as enabled, I go just up to the point where the owner is to be set, and it is still enabled (i.e. I am not accidentally disabling it).
What other caused can there be for this access is denied message? What have I not considered?
std::wstring fileSystemObject = L"C:\test.txt";
*status_code = SetNamedSecurityInfo((wchar_t*)fileSystemObject.c_str(), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, pSID, NULL, NULL, NULL);
if (*status_code == ERROR_SUCCESS)
{
Log(L"Successfully set owner for " + fileSystemObject);
return true;
}
else
{
Log(L"Failed to set owner for " + fileSystemObject + L". Error code: ", *status_code);
return false;
}
Thank you.
EDIT: Thank you very much for your continued assistance. It is greatly appreciated.
I used your code for all of the following tests. Basically, I am also getting Access Denied messages from your code, however, I have tracked it down a little more.
Firstly, "C:\test.txt" was not my real code, and unfortunately the missing backslash is not the cause of my problem. Thank you for your keen eyes though :)
Also, I am running an administrator account with UAC disabled, and my program has requireAdministrator set in the manifest.
However, I have noticed that both my code and yours work for simple files. After much testing, I have discovered that I only get AccessDenied messages in the following scenarios:
1: I am not the owner, and the "Take Ownership" permissions is set to Deny for e.g. Everyone.
2: I am the owner, and the "Take Ownership" permissions is set to Deny for e.g. Everyone. Curiously, in this second instance, despite the failure code, the ownership change does actually occur.
I don't see why this is happening. I, and you, have set SE_RESTORE_NAME in the process token. I should be allowed to arbitrarily set the owner SID. But it seems that I can't.
It seems that any Deny on TakeOwnership DACLs overrides my ability to take ownership. However, I can't change permissions until I can take ownership! sigh.
I might try setting SeTakeOwnershipPrivilege as you initially recommended, taking ownership to myself, changing permissions, setting ownership externally. What a pain. And I am not even very confident it will work.
I also found this: http://us.generation-nt.com/setnamedsecurityinfo-failing-rc-1307-help-59729462.html
He seems to be in a similar situation (I get 1307 if I don't set up the process token properly). But CreatePrivateObjectSecurityEx takes a whole lot more setting up.
Hmmmm. Thanks for your time.
The problem here is that security subsystem and model are defending the object from unreasonable ownership changes, and even having administrator permissions one needs to correctly overcome the obstacles.
There are two privileges involved in taking ownership of a file: SE_TAKE_OWNERSHIP_NAME and SE_RESTORE_NAME. The former allows taking someone's object and the latter allows setting owner who is not the setter himself.
It might look like SE_RESTORE_NAME is a more powerful privilege and is sufficient for the task, however it appears that it is not. Yes it allows to set someone's ownership, as MSDN states:
If the caller does not have the SeRestorePrivilege constant (see
Privilege Constants), this SID must be contained in the caller's
token, and must have the SE_GROUP_OWNER permission enabled. The
SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION
flag. To set the owner, the caller must have WRITE_OWNER access to the
object or have the SE_TAKE_OWNERSHIP_NAME privilege enabled.
However it does not let you overcome DACL item that explicitly prevents from ownership change. In this case you need that other privilege as well (that is, you need to enable both), which enables you to take ownership from someone before you decide whom you are going to give it then to.
I am copying the link to C++/ATL source code from comment above: SetFileOwner.cpp. When permissions/DACL has a Deny item, an exception takes place and enabling second privilege resolves the problem.
What I want to achieve:
I would like to count the instances of my application to a fixed number.
if more instances of the application are started, it should only work as a "Viewer"
Her is the code of the sample application
boost named_semaphore example
The problem:
it works fine if all processe are started from only one user
But I get a Security exception if I start the application with another user!!
(Access not allowed)
Somebody can point me in the right direction, the boost documentation is a little bit lacking on this topic ;-)
What permissions must be set to allow access from every other logged on user?
I found the solution
Looks like the docu for Boost isn't that bad :-/
http://www.boost.org/doc/libs/1_47_0/doc/html/boost/interprocess/permissions.html
Just have to pass the permission and set it to "unrestricted"
boost::interprocess::permissions permtest;
permtest.set_unrestricted();
_getch();
boost::interprocess::named_semaphore
the_semphore(boost::interprocess::open_or_create,"test_semaphore",3,permtest);
Unfortunately boost uses default security attributes for semaphore and there is no way to change it. Use ATL::CSemaphore or CSemaphore from MFC or even CreateSemaphore from WinApi and construct security descriptor which allows access for everyone.
I'm not exactly a Windows expert, so I can't tell you the answer by heart, but you need to know how named_semaphores are implemented (see "Some basic explanations" documentation of boost.interprocess) and then look up the permission policy for this resource to grant system-wide access. So, read the boost.named_semaphore code, and if they use a file, update that file's permissions, and if they use a system call, read the Windows API documentation for that system call.
I have some code that used to work, but recently stopped. It's in an Adobe Reader Plugin, and the latest Reader version has a "Protected Mode" which causes my problem.
My plugin can load some of my normal dlls, which load in-process:
MyNormalLib::IMyClassPtr foo;
HRESULT hr = foo.CreateInstance(__uuidof(MyNormalLib::MyClass));
But when I try to get a com pointer to my service (running on the same machine):
MyOtherLib::IMyServicePtr bar;
HRESULT hr = bar.CreateInstance(__uuidof(MyOtherLib::MyService));
I get E_ACCESSDENIED for my HRESULT.
This used to work fine, until Adobe Reader X came along. Without Protected Mode, Adobe runs normally and everything works. With Protected Mode, Adobe spawns another Reader process, with some restrictions on it. Looking at this with Process Explorer, I can see that the Security Tab for the parent Reader process has pretty much everything set to Mandatory; but the child Reader process has most groups set to "Deny, Mandatory", some "Mandatory, Restricted", some are just Mandatory. If this matters, I can provide more details.
All processes (my service and both Reader) are run as the same user -- me. I have admin rights, if that matters.
What can cause an AccessDenied error when trying to reach my own service? What security hoops do I have to jump through to get this to work?
The restricted process does not have admin rights. That's pretty much the point of the exercise - Reader X drops as many rights as it can from its token so that if it is pwned your computer is not.
(That's basically how UAC works too, you have to go to the Kernel to get permission to re-enable your Administrator group once you have disabled it).
Basically you need to look at the privs that Reader X has, and make sure your component can be used with those permissions. Process Monitor is your friend - just filter for DENIED and the problems will pop right out at you!