What is the default security descriptor?


All these functions have an optional LPSECURITY_ATTRIBUTES parameter, for which everybody just passes NULL, thereby obtaining the default security descriptor. But what is the default security descriptor?

Of course, the place to start is MSDN, in the section titled Security Descriptors for New Objects.

It says that the default DACL comes from inheritable ACEs (if the object belongs to a hierarchy, like the filesystem or the registry); otherwise, the default DACL comes from the primary or impersonation token of the creator.

But what is the default primary token?

Gosh, I don't know either. So let's write a program to find out.

#include <windows.h>
#include <sddl.h> // ConvertSecurityDescriptorToStringSecurityDescriptor

int WINAPI
WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
 HANDLE Token;
 if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token)) {
 DWORD RequiredSize = 0;
 GetTokenInformation(Token, TokenDefaultDacl, NULL, 0, &RequiredSize);
 TOKEN_DEFAULT_DACL* DefaultDacl =
     reinterpret_cast<TOKEN_DEFAULT_DACL*>(LocalAlloc(LPTR, RequiredSize));
 if (DefaultDacl) {
  SECURITY_DESCRIPTOR Sd;
  LPTSTR StringSd;
  if (GetTokenInformation(Token, TokenDefaultDacl, DefaultDacl,
                          RequiredSize, &RequiredSize) &&
      InitializeSecurityDescriptor(&Sd, SECURITY_DESCRIPTOR_REVISION) &&
      SetSecurityDescriptorDacl(&Sd, TRUE,
          DefaultDacl->DefaultDacl, FALSE) &&
      ConvertSecurityDescriptorToStringSecurityDescriptor(&Sd,
          SDDL_REVISION_1, DACL_SECURITY_INFORMATION, &StringSd, NULL)) {
   MessageBox(NULL, StringSd, TEXT("Result"), MB_OK);
   LocalFree(StringSd);
  }
  LocalFree(DefaultDacl);
 }
 CloseHandle(Token);
 }
 return 0;
}

Okay, I admit it, the whole purpose of this entry is just so I can call the function ConvertSecurityDescriptorToStringSecurityDescriptor, quite possibly the longest function name in the Win32 API. And just for fun, I used the NT variable naming convention instead of Hungarian.

If you run this program you'll get something like this:

D:(A;;GA;;;S-1-5-21-1935655697-839522115-854245398-1003)(A;;GA;;;SY)

Pull out our handy reference to the Security Descriptor String Format to decode this.

  • "D:" - This introduces the DACL.

  • "(A;;GA;;;S-...)" - "Allow" "Generic All" access to "S-...", which happens to be me. Every user by default has full access to their own process.

  • "(A;;GA;;;SY)" - "Allow" "Generic All" access to "Local System".

Next time, I'll teach you how to decode that S-... thing.

Comments (19)
  1. Anonymous says:

    How about AccessCheckWithTypedResultListAuditAlarm?

    Thats my personel favorite,

  2. Anonymous says:

    Raymond,

    Can you go into more detail about what the "Generic All" permissions to "Local System" means and its ramifications? Even with the documentation you linked, it’s a little ambiguous, and I’m rather certain there are serious security ramifications when one holds a generic allow to local system.

    I also assume that you’re an administrator on your machine and that you wouldn’t have this generic allow to local system if you weren’t. (I’d test it but I don’t have a comiler handy and I’m being lazy.)

    I think many of us would find a followup narrative on this topic to be quite informative.

  3. Anonymous says:

    Amen to Matt’s comment. We could definitely need more information on this subject.

  4. Anonymous says:

    A;GA;;;SY means what it says: The Local System account has full access to your process and the things it creates. You typically want to grant SY access to your stuff so services can do things like content-index it or repair a broken shortcut.

    And no, I am not local administrator.

  5. Anonymous says:

    Doh. I was thinking backward. I was thinking that it mean that my object had full access to local system. (Particularly, I was thinking my process/thread had full access to localsystem.)

    Your clarification makes a lot more sense. Thanks!

  6. Anonymous says:

    Objects don’t access things; users do. So users have access to objects, not the other way around.

    I can write a little more but I’m not an expert on how this all works, so what I write will not really go as deeply in-depth as some of my other stuff.

  7. Anonymous says:

    I know what Hungarian notation is but what is:

    NT variable naming convention

    Regards,

    Dave

  8. Anonymous says:

    It’s the naming conventions laid out in the NT OS/2 Design Workbook :)

  9. Anonymous says:

    I appreciate the non-Hungarian approach for this entry. It makes the code much cleaner to my eyes.

    Thanks,

    PeterM

  10. Anonymous says:

    I always liked ImpersonateSelf. ;)

    You tell me who You are and I will check if I want to trust you.

    Gotta love the reflexive nature of security.

  11. Anonymous says:

    Don’t forget the COM APIs CoMarshallInterThreadInterfaceInStream() and CoGetInterfaceAndReleaseStream(). :-)

  12. Anonymous says:

    Whilst on the subject of naming conventions, is there an interesting story behind the name of the "mouse_event" function?

  13. Anonymous says:

    mouse_event: Not really. It was the function used by the old mouse driver to inform USER that there was input back in Windows 1.0. It has long since been deprecated in favor of SendInput.

  14. Anonymous says:

    Speaking of naming conventions, how did one api get structures named PROCESS_INFORMATION and STARTUPINFO?

    Is this some kind of cruel joke?

  15. Anonymous says:

    > I think many of us would find a followup narrative on this topic to be quite informative

    Read Programming Windows Security (http://www.develop.com/books/pws).

  16. Anonymous says:

    > Objects don’t access things; users do. So users have access to objects, not the other way around. <

    In Windows security, which is based on principals. In the CLR, or IE, or other environments with code access security, objects access objects and can have fewer permissions than the user running the code (but never more permissions!).

    Kind of OT for a non-.NET blog, I know :-)

  17. Anonymous says:

    This works as long as you don’t allow arbitrary code to run. Once you allow that, you lose code access security because you can never be sure who your caller is.

    http://weblogs.asp.net/oldnewthing/archive/2004/01/01/47042.aspx

  18. Anonymous says:

    Well yeah… you *can* have fewer permissions than the user, but that doesn’t necessarily mean you actually *do* :-). Native / FullTrust code has whatever you have including the ability to completely mess up the stack or other important memory structures.

  19. Anonymous says:

    Ping Back来自:www.donews.net

Comments are closed.