【问题标题】:How to create directory with all rights granted to everyone如何创建授予所有人所有权限的目录
【发布时间】:2010-10-16 00:03:06
【问题描述】:

我需要以编程方式创建一个目录,将“完全控制”授予“所有人”组。如果我使用

CreateDirectory(path, NULL);

根据 Win32 SDK documentation,这将创建一个从其父目录继承的目录。我不想继承父目录的访问权限,我需要确保“每个人”都可以完全控制该目录。

显然,这需要使用适当的安全描述符设置SECURITY_ATTRIBUTES 结构。我该怎么做?

【问题讨论】:

  • 我认为您的意思是:“授予所有权利”
  • 是的,感谢 dmckee 进行编辑!

标签: windows security winapi directory directory-security


【解决方案1】:

这是一种似乎有效的技术:

SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
PSID everyone_sid = NULL;
AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 
   0, 0, 0, 0, 0, 0, 0, &everyone_sid);

EXPLICIT_ACCESS ea;
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
ea.grfAccessMode = SET_ACCESS;
ea.grfInheritance = NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea.Trustee.ptstrName  = (LPWSTR)everyone_sid;

PACL acl = NULL;
SetEntriesInAcl(1, &ea, NULL, &acl);

PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, 
                                   SECURITY_DESCRIPTOR_MIN_LENGTH);
InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE);

SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = sd;
sa.bInheritHandle = FALSE;

CreateDirectory(path, &sa);

FreeSid(everyone_sid);
LocalFree(sd);
LocalFree(acl);

请注意,此示例代码绝对没有错误检查——您必须自己提供。

【讨论】:

  • 老兄,非常感谢这段代码。我一直试图弄清楚为什么在用户特定的应用程序数据文件夹中创建目录时我的游戏不断崩溃。您的代码救了我 - 不再崩溃。
【解决方案2】:

我更喜欢下面的代码 sn-p 因为它创建了一个继承默认权限的文件夹 - 这似乎是正确的做法 - 其他软件/用户可能出于正当原因在目录上设置了特定的可继承权限 - 然后添加完全控制内置“用户”组的显式访问条目。

BOOL CreateDirectoryWithUserFullControlACL(LPCTSTR lpPath)
{
  if(!CreateDirectory(lpPath,NULL))
    return FALSE;

  HANDLE hDir = CreateFile(lpPath,READ_CONTROL|WRITE_DAC,0,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
  if(hDir == INVALID_HANDLE_VALUE)
    return FALSE; 

  ACL* pOldDACL;
  SECURITY_DESCRIPTOR* pSD = NULL;
  GetSecurityInfo(hDir, SE_FILE_OBJECT , DACL_SECURITY_INFORMATION,NULL, NULL, &pOldDACL, NULL, (void**)&pSD);

  PSID pSid = NULL;
  SID_IDENTIFIER_AUTHORITY authNt = SECURITY_NT_AUTHORITY;
  AllocateAndInitializeSid(&authNt,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_USERS,0,0,0,0,0,0,&pSid);

  EXPLICIT_ACCESS ea={0};
  ea.grfAccessMode = GRANT_ACCESS;
  ea.grfAccessPermissions = GENERIC_ALL;
  ea.grfInheritance = CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE;
  ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
  ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  ea.Trustee.ptstrName = (LPTSTR)pSid;

  ACL* pNewDACL = 0;
  DWORD err = SetEntriesInAcl(1,&ea,pOldDACL,&pNewDACL);

  if(pNewDACL)
    SetSecurityInfo(hDir,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL, NULL, pNewDACL, NULL);

  FreeSid(pSid);
  LocalFree(pNewDACL);
  LocalFree(pSD);
  LocalFree(pOldDACL);
  CloseHandle(hDir);

  return TRUE;
}

【讨论】:

    【解决方案3】:

    看看能不能用SetSecurityInfo()

    在可选pDacl参数的描述中:

    ...如果 SecurityInfo 参数的值包括 DACL-SECURITY-INFORMATION 标志并且此参数的值设置为 NULL,则授予所有人对该对象的完全访问权限。

    【讨论】:

    • 我正在寻找一种解决方案,该解决方案使用非 null 且通过 CreateDirectory() 调用正确初始化 SECURITY_ATTRIBUTE。
    • 我的代码意外设置了 NULL DACL,并且在打开 UAC 的情况下,最终结果并不等于所有用户完全控制。
    猜你喜欢
    • 2016-07-17
    • 2021-04-20
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多