Windows 创建只允许所有者访问文件的文件访问 (Win32)
Windows Create File Access that only allows Owner to access the file (Win32)
我正在尝试修改 Windows 对文件的访问权限,使其只有所有者(甚至其他管理员)才能访问该文件。有点相当于 unix chmod 700 文件。
我试过拒绝一般组(EVERYONE、ADMINISTRATORS)的权限并将它们授予当前用户,但当前用户总是也会失去这些权限。
我尝试更改顺序 (eas[0], eas[1]) 等,但没有成功。
有人有想法吗?
EXPLICIT_ACCESSA ea= { 0, }, eas[5]= { { 0, }, };
PACL pacl= 0;
ea.grfAccessPermissions = GENERIC_ALL;
ea.grfAccessMode = DENY_ACCESS ;
ea.grfInheritance = NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea.Trustee.ptstrName = "EVERYONE";
eas[0]= ea;
ea.grfAccessPermissions = GENERIC_ALL;
ea.grfAccessMode = GRANT_ACCESS ;
ea.grfInheritance = NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
ea.Trustee.ptstrName = "CURRENT_USER";
eas[1]= ea;
rc= SetEntriesInAcl(2, &eas[0], NULL, &pacl);
rc= SetNamedSecurityInfoA((LPSTR)filename, SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION,
NULL, NULL, pacl, NULL);
虽然在技术上是可行的,但它不会在保护对象方面给您带来太多好处。给定具有适当条目的 DACL,本地管理员可能无法立即访问文件,但他们始终可以获得系统中任何对象的所有权。这授予他们对该对象的完全控制权,并且他们可以操纵其 DACL 和 SACL。
正式你需要下一个代码
DWORD demo(PCWSTR filename)
{
EXPLICIT_ACCESS ea= {
GENERIC_ALL,
GRANT_ACCESS,
NO_INHERITANCE,
{ 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, TRUSTEE_IS_USER, L"CURRENT_USER"}
};
PACL pacl;
DWORD err = SetEntriesInAcl(1, &ea, NULL, &pacl);
if (!err)
{
err = ERROR_GEN_FAILURE;
if (pacl->AceCount == 1)
{
union {
PVOID pvAce;
PACE_HEADER Header;
PACCESS_ALLOWED_ACE pAce;
};
if (GetAce(pacl, 0, &pvAce) && Header->AceType == ACCESS_ALLOWED_ACE_TYPE)
{
HANDLE hFile = CreateFile(filename, WRITE_DAC|WRITE_OWNER, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE);
SetSecurityDescriptorOwner(&sd, &pAce->SidStart, FALSE);
SetSecurityDescriptorControl(&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED);
err = SetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION, &sd)
? NOERROR : GetLastError();
CloseHandle(hFile);
}
else
{
err = GetLastError();
}
}
}
LocalFree(pacl);
}
return err;
}
注释行
SetSecurityDescriptorControl(&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED);
使用此代码 DACL
的文件将只有一个条目 - 当前用户的 GENERIC_ALL
。以及 DACL 中明确不允许的所有内容 - 被拒绝。但当然,如果用户拥有 SE_TAKE_OWNERSHIP_PRIVILEGE
权限 - 您可以使用 WRITE_OWNER
访问权限打开文件并将自己设置为所有者。在此之后你可以用 WRITE_DAC
打开文件并更改 DACL
如前所述@Harry Johnston 如果使用 SetNamedSecurityInfo
,代码可以更短
DWORD demo(PCWSTR filename)
{
EXPLICIT_ACCESS ea= {
GENERIC_ALL,
GRANT_ACCESS,
NO_INHERITANCE,
{ 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, TRUSTEE_IS_USER, L"CURRENT_USER"}
};
PACL pacl;
DWORD err = SetEntriesInAcl(1, &ea, NULL, &pacl);
if (!err)
{
err = ERROR_GEN_FAILURE;
if (pacl->AceCount == 1)
{
union {
PVOID pvAce;
PACE_HEADER Header;
PACCESS_ALLOWED_ACE pAce;
};
if (GetAce(pacl, 0, &pvAce) && Header->AceType == ACCESS_ALLOWED_ACE_TYPE)
{
err = SetNamedSecurityInfo((PWSTR)filename, SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION |PROTECTED_DACL_SECURITY_INFORMATION,
&pAce->SidStart, NULL, pacl, NULL);
}
}
LocalFree(pacl);
}
return err;
}
在大多数情况下,拒绝条目优先于允许条目。由于默认情况下拒绝访问,因此您不需要拒绝条目,但是您需要禁用继承的权限。您可以使用 PROTECTED_DACL_SECURITY_INFORMATION
标志来执行此操作。
#include <Windows.h>
#include <Aclapi.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
EXPLICIT_ACCESS eas[1];
PACL pacl = 0;
DWORD rc;
eas[0].grfAccessPermissions = GENERIC_ALL;
eas[0].grfAccessMode = GRANT_ACCESS;
eas[0].grfInheritance = NO_INHERITANCE;
eas[0].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
eas[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
eas[0].Trustee.ptstrName = L"CURRENT_USER";
rc = SetEntriesInAcl(1, &eas[0], NULL, &pacl);
if (rc != ERROR_SUCCESS)
{
printf("SetEntriesInAcl: %u\n", rc);
return 1;
}
rc = SetNamedSecurityInfo(L"C:\working\test.txt", SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
NULL, NULL, pacl, NULL);
if (rc != ERROR_SUCCESS)
{
printf("SetNamedSecurityInfo: %u\n", rc);
return 1;
}
printf("OK!\n");
return 0;
}
请注意,管理员可以随时重置权限以获得对文件的访问权限。如果您确实需要保护数据免受其他管理员的侵害,则必须对其进行加密。 (希望没有人安装键盘记录器来窃取您的加密密码。)
我正在尝试修改 Windows 对文件的访问权限,使其只有所有者(甚至其他管理员)才能访问该文件。有点相当于 unix chmod 700 文件。
我试过拒绝一般组(EVERYONE、ADMINISTRATORS)的权限并将它们授予当前用户,但当前用户总是也会失去这些权限。
我尝试更改顺序 (eas[0], eas[1]) 等,但没有成功。
有人有想法吗?
EXPLICIT_ACCESSA ea= { 0, }, eas[5]= { { 0, }, };
PACL pacl= 0;
ea.grfAccessPermissions = GENERIC_ALL;
ea.grfAccessMode = DENY_ACCESS ;
ea.grfInheritance = NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea.Trustee.ptstrName = "EVERYONE";
eas[0]= ea;
ea.grfAccessPermissions = GENERIC_ALL;
ea.grfAccessMode = GRANT_ACCESS ;
ea.grfInheritance = NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
ea.Trustee.ptstrName = "CURRENT_USER";
eas[1]= ea;
rc= SetEntriesInAcl(2, &eas[0], NULL, &pacl);
rc= SetNamedSecurityInfoA((LPSTR)filename, SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION,
NULL, NULL, pacl, NULL);
虽然在技术上是可行的,但它不会在保护对象方面给您带来太多好处。给定具有适当条目的 DACL,本地管理员可能无法立即访问文件,但他们始终可以获得系统中任何对象的所有权。这授予他们对该对象的完全控制权,并且他们可以操纵其 DACL 和 SACL。
正式你需要下一个代码
DWORD demo(PCWSTR filename)
{
EXPLICIT_ACCESS ea= {
GENERIC_ALL,
GRANT_ACCESS,
NO_INHERITANCE,
{ 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, TRUSTEE_IS_USER, L"CURRENT_USER"}
};
PACL pacl;
DWORD err = SetEntriesInAcl(1, &ea, NULL, &pacl);
if (!err)
{
err = ERROR_GEN_FAILURE;
if (pacl->AceCount == 1)
{
union {
PVOID pvAce;
PACE_HEADER Header;
PACCESS_ALLOWED_ACE pAce;
};
if (GetAce(pacl, 0, &pvAce) && Header->AceType == ACCESS_ALLOWED_ACE_TYPE)
{
HANDLE hFile = CreateFile(filename, WRITE_DAC|WRITE_OWNER, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE);
SetSecurityDescriptorOwner(&sd, &pAce->SidStart, FALSE);
SetSecurityDescriptorControl(&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED);
err = SetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION, &sd)
? NOERROR : GetLastError();
CloseHandle(hFile);
}
else
{
err = GetLastError();
}
}
}
LocalFree(pacl);
}
return err;
}
注释行
SetSecurityDescriptorControl(&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED);
使用此代码 DACL
的文件将只有一个条目 - 当前用户的 GENERIC_ALL
。以及 DACL 中明确不允许的所有内容 - 被拒绝。但当然,如果用户拥有 SE_TAKE_OWNERSHIP_PRIVILEGE
权限 - 您可以使用 WRITE_OWNER
访问权限打开文件并将自己设置为所有者。在此之后你可以用 WRITE_DAC
打开文件并更改 DACL
如前所述@Harry Johnston 如果使用 SetNamedSecurityInfo
DWORD demo(PCWSTR filename)
{
EXPLICIT_ACCESS ea= {
GENERIC_ALL,
GRANT_ACCESS,
NO_INHERITANCE,
{ 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, TRUSTEE_IS_USER, L"CURRENT_USER"}
};
PACL pacl;
DWORD err = SetEntriesInAcl(1, &ea, NULL, &pacl);
if (!err)
{
err = ERROR_GEN_FAILURE;
if (pacl->AceCount == 1)
{
union {
PVOID pvAce;
PACE_HEADER Header;
PACCESS_ALLOWED_ACE pAce;
};
if (GetAce(pacl, 0, &pvAce) && Header->AceType == ACCESS_ALLOWED_ACE_TYPE)
{
err = SetNamedSecurityInfo((PWSTR)filename, SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION |PROTECTED_DACL_SECURITY_INFORMATION,
&pAce->SidStart, NULL, pacl, NULL);
}
}
LocalFree(pacl);
}
return err;
}
在大多数情况下,拒绝条目优先于允许条目。由于默认情况下拒绝访问,因此您不需要拒绝条目,但是您需要禁用继承的权限。您可以使用 PROTECTED_DACL_SECURITY_INFORMATION
标志来执行此操作。
#include <Windows.h>
#include <Aclapi.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
EXPLICIT_ACCESS eas[1];
PACL pacl = 0;
DWORD rc;
eas[0].grfAccessPermissions = GENERIC_ALL;
eas[0].grfAccessMode = GRANT_ACCESS;
eas[0].grfInheritance = NO_INHERITANCE;
eas[0].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
eas[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
eas[0].Trustee.ptstrName = L"CURRENT_USER";
rc = SetEntriesInAcl(1, &eas[0], NULL, &pacl);
if (rc != ERROR_SUCCESS)
{
printf("SetEntriesInAcl: %u\n", rc);
return 1;
}
rc = SetNamedSecurityInfo(L"C:\working\test.txt", SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
NULL, NULL, pacl, NULL);
if (rc != ERROR_SUCCESS)
{
printf("SetNamedSecurityInfo: %u\n", rc);
return 1;
}
printf("OK!\n");
return 0;
}
请注意,管理员可以随时重置权限以获得对文件的访问权限。如果您确实需要保护数据免受其他管理员的侵害,则必须对其进行加密。 (希望没有人安装键盘记录器来窃取您的加密密码。)