今日看了看关于windows本身安全机制的一些文章,所以将自己掌握到的一些东西供大家探讨一下。
1. Access Token
windows访问令牌记录着某用户的SID、组ID、Session、及权限等信息,要获取这些信息,可以通过GetTokenInformation API获得。以下是一些代码样例
#define GETATTRI(desc, attri, check) \
if (attri & check)\
{\
if (desc!=_T(""))\
{\
desc += _T(" | ");\
}\
desc+=_T(#check);\
}
#define MAKESIDDESC(type) {type, _T(#type)}
struct SIDNameDesc
{
SID_NAME_USE type;
TCHAR* desc;
};
SIDNameDesc gvSidUseType[]=
{
MAKESIDDESC(SidTypeUser),
MAKESIDDESC(SidTypeGroup),
MAKESIDDESC(SidTypeDomain),
MAKESIDDESC(SidTypeAlias),
MAKESIDDESC(SidTypeWellKnownGroup),
MAKESIDDESC(SidTypeDeletedAccount),
MAKESIDDESC(SidTypeInvalid),
MAKESIDDESC(SidTypeUnknown),
MAKESIDDESC(SidTypeComputer),
MAKESIDDESC(SidTypeLabel),
};
TCHAR* GetSidNameUseDescription(SID_NAME_USE type)
{
TCHAR* pDesc=NULL;
int count = sizeof(gvSidUseType) / sizeof(SIDNameDesc);
for (int i=0;i<count;i++)
{
if (gvSidUseType[i].type==type)
{
pDesc=gvSidUseType[i].desc;
break;
}
}
return pDesc;
}
CString GetAttribute(DWORD attribute)
{
CString strAttri;
GETATTRI(strAttri,attribute,SE_GROUP_ENABLED);
GETATTRI(strAttri,attribute,SE_GROUP_ENABLED_BY_DEFAULT);
GETATTRI(strAttri,attribute,SE_GROUP_LOGON_ID);
GETATTRI(strAttri,attribute,SE_GROUP_MANDATORY);
GETATTRI(strAttri,attribute,SE_GROUP_OWNER);
GETATTRI(strAttri,attribute,SE_GROUP_RESOURCE);
GETATTRI(strAttri,attribute,SE_GROUP_USE_FOR_DENY_ONLY);
return strAttri;
}
void dump(PSID pSid)
{
USES_CONVERSION;
LPTSTR strSid;
ConvertSidToStringSid(pSid,&strSid);
cout<<"SID : "<<T2A(strSid)<<endl;
TCHAR name[MAX_PATH];
TCHAR domainName[MAX_PATH];
DWORD dwNamelen=MAX_PATH;
DWORD dwDomainNamelen=MAX_PATH;
SID_NAME_USE nameUse;
if(!LookupAccountSid(NULL,pSid,name,&dwNamelen,domainName,&dwDomainNamelen,&nameUse))
{
cout<<"LookupAccountSid failed with "<<GetLastError()<<endl;
return;
}
StrCat(domainName,_T("\\"));
StrCat(domainName, name);
cout<<"Account : "<<T2A(domainName)<<endl;
cout<<" Type : "<<T2A(GetSidNameUseDescription(nameUse))<<endl;
}
void dump(DWORD attribute)
{
USES_CONVERSION;
CString strAttri = GetAttribute(attribute);
cout<<"Attribute : "<<T2A(strAttri)<<endl;
}
void GetTokenUser(HANDLE hToken)
{
DWORD dwReturnedLen=0;
GetTokenInformation(hToken, TokenUser, NULL, NULL, &dwReturnedLen);
if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
LPVOID p=LocalAlloc(LPTR, dwReturnedLen);
if (p==NULL)
{
cout<<"LocalAlloc failed with "<<GetLastError()<<endl;
}
if(!GetTokenInformation(hToken, TokenUser, p, dwReturnedLen, &dwReturnedLen))
{
if (GetLastError()!=ERROR_SUCCESS)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
}
TOKEN_USER* pUser = (TOKEN_USER*)p;
dump(pUser->User.Sid);
dump(pUser->User.Attributes);
}
void GetTokenGroup(HANDLE hToken)
{
DWORD dwReturnedLen=0;
GetTokenInformation(hToken, TokenGroups, NULL, NULL, &dwReturnedLen);
if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
LPVOID p=LocalAlloc(LPTR, dwReturnedLen);
if (p==NULL)
{
cout<<"LocalAlloc failed with "<<GetLastError()<<endl;
}
if(!GetTokenInformation(hToken, TokenGroups, p, dwReturnedLen, &dwReturnedLen))
{
if (GetLastError()!=ERROR_SUCCESS)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
}
TOKEN_GROUPS* pGroup = (TOKEN_GROUPS*)p;
for (int i=0;i<pGroup->GroupCount;i++)
{
dump(pGroup->Groups[i].Sid);
dump(pGroup->Groups[i].Attributes);
cout<<endl;
}
}
void dump(LUID_AND_ATTRIBUTES privilege)
{
USES_CONVERSION;
TCHAR buffer[MAX_PATH];
DWORD dwLength=MAX_PATH;
if(!LookupPrivilegeName(NULL,&privilege.Luid,buffer,&dwLength))
{
cout<<"LookupPrivilegeName failed with "<<GetLastError()<<endl;
return;
}
CString strAttribute;
GETATTRI(strAttribute,privilege.Attributes,SE_PRIVILEGE_ENABLED);
GETATTRI(strAttribute,privilege.Attributes,SE_PRIVILEGE_ENABLED_BY_DEFAULT);
GETATTRI(strAttribute,privilege.Attributes,SE_PRIVILEGE_REMOVED);
GETATTRI(strAttribute,privilege.Attributes,SE_PRIVILEGE_USED_FOR_ACCESS);
CString strDump = buffer;
strDump += _T(" : ");
strDump += strAttribute;
cout<<T2A(strDump)<<endl;
}
void GetPrivileges(HANDLE hToken)
{
DWORD dwReturnedLen=0;
GetTokenInformation(hToken, TokenPrivileges, NULL, NULL, &dwReturnedLen);
if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
LPVOID p=LocalAlloc(LPTR, dwReturnedLen);
if (p==NULL)
{
cout<<"LocalAlloc failed with "<<GetLastError()<<endl;
}
if(!GetTokenInformation(hToken, TokenPrivileges, p, dwReturnedLen, &dwReturnedLen))
{
if (GetLastError()!=ERROR_SUCCESS)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
}
TOKEN_PRIVILEGES* pPrivileges = (TOKEN_PRIVILEGES*)p;
for (int i=0;i<pPrivileges->PrivilegeCount;i++)
{
dump(pPrivileges->Privileges[i]);
}
}
void GetOwnerInfo(HANDLE hToken)
{
DWORD dwReturnedLen=0;
GetTokenInformation(hToken, TokenOwner, NULL, NULL, &dwReturnedLen);
if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
LPVOID p=LocalAlloc(LPTR, dwReturnedLen);
if (p==NULL)
{
cout<<"LocalAlloc failed with "<<GetLastError()<<endl;
}
if(!GetTokenInformation(hToken, TokenOwner, p, dwReturnedLen, &dwReturnedLen))
{
if (GetLastError()!=ERROR_SUCCESS)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
}
TOKEN_OWNER* pOwner = (TOKEN_OWNER*)p;
dump(pOwner->Owner);
}
void GetPrimaryGroup(HANDLE hToken)
{
DWORD dwReturnedLen=0;
GetTokenInformation(hToken, TokenPrimaryGroup, NULL, NULL, &dwReturnedLen);
if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
LPVOID p=LocalAlloc(LPTR, dwReturnedLen);
if (p==NULL)
{
cout<<"LocalAlloc failed with "<<GetLastError()<<endl;
}
if(!GetTokenInformation(hToken, TokenPrimaryGroup, p, dwReturnedLen, &dwReturnedLen))
{
if (GetLastError()!=ERROR_SUCCESS)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
}
TOKEN_PRIMARY_GROUP* pPrimaryGroup = (TOKEN_PRIMARY_GROUP*)p;
dump(pPrimaryGroup->PrimaryGroup);
}
void Print(LPCSTR desc, LUID luid)
{
LARGE_INTEGER* pli = (LARGE_INTEGER*)&luid;
cout<<desc<<" : "<<pli->QuadPart<<endl;
}
void dump(TOKEN_STATISTICS* pStatistics)
{
Print("TokenID", pStatistics->TokenId);
Print("AuthenticationId", pStatistics->AuthenticationId);
if (pStatistics->TokenType == TokenPrimary)
{
cout<<"Primary Token"<<endl;
}
else
{
cout<<"Impersonation Token"<<endl;
}
}
void GetTokenStatistics(HANDLE hToken)
{
DWORD dwReturnedLen=0;
GetTokenInformation(hToken, TokenStatistics, NULL, NULL, &dwReturnedLen);
if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
LPVOID p=LocalAlloc(LPTR, dwReturnedLen);
if (p==NULL)
{
cout<<"LocalAlloc failed with "<<GetLastError()<<endl;
}
if(!GetTokenInformation(hToken, TokenStatistics, p, dwReturnedLen, &dwReturnedLen))
{
if (GetLastError()!=ERROR_SUCCESS)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
}
TOKEN_STATISTICS* pTokenStatistics = (TOKEN_STATISTICS*)p;
dump(pTokenStatistics);
}
void GetTokenSource(HANDLE hToken)
{
DWORD dwReturnedLen=0;
GetTokenInformation(hToken, TokenSource, NULL, NULL, &dwReturnedLen);
if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
LPVOID p=LocalAlloc(LPTR, dwReturnedLen);
if (p==NULL)
{
cout<<"LocalAlloc failed with "<<GetLastError()<<endl;
}
if(!GetTokenInformation(hToken, TokenSource, p, dwReturnedLen, &dwReturnedLen))
{
if (GetLastError()!=ERROR_SUCCESS)
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
}
TOKEN_SOURCE* pSource = (TOKEN_SOURCE*)p;
cout<<"Source Name : "<<pSource->SourceName<<endl;
Print("Source ID : ", pSource->SourceIdentifier);
}
void GetTokenSessionID(HANDLE hToken)
{
DWORD dwReturnedLen=0;
DWORD sessionID;
if(!GetTokenInformation(hToken, TokenSessionId, &sessionID, sizeof(DWORD), &dwReturnedLen))
{
cout<<"GetTokenInformation failed with "<<GetLastError()<<endl;
}
cout<<"Session ID : "<<sessionID<<endl;
}
大家知道在Win7上管理员登录后会关联两个Access Token,一个是有管理员权限的Access Token,另外一个是被限制权限的Access Token,其中Restricted Access Token中Administrators组的属性为SE_GROUP_USE_FOR_DENY_ONLY,说明系统在访问检查时,只会检查给这个组应用了拒绝访问的那些ACE项,而允许访问的ACE项被忽略。而CheckTokenMembership在判断一个Token是否属于某个组时,这个组必须存在并且组属性包含SE_GROUP_ENABLED,才会认为这个Token属于这个组。所以一个权限未提升的进程的令牌是不会认为属于Administrators组的。
2. 安全描述符
安全描述符是windows安全对象管理的一种数据结构,用来描述允许什么用户使用某种权限访问它,拒绝什么用户使用某种权限访问它。(另外还有一些审计操作,不讨论了)。获取ACE信息,见一些代码
void ParseAce(PACE_HEADER pAceHdr);
#define GETATTRI(mask, check) \
if (mask & check)\
{\
cout<<#check<<endl;\
}
#define MAKESIDDESC(type) {type, _T(#type)}
struct SIDNameDesc
{
SID_NAME_USE type;
TCHAR* desc;
};
SIDNameDesc gvSidUseType[]=
{
MAKESIDDESC(SidTypeUser),
MAKESIDDESC(SidTypeGroup),
MAKESIDDESC(SidTypeDomain),
MAKESIDDESC(SidTypeAlias),
MAKESIDDESC(SidTypeWellKnownGroup),
MAKESIDDESC(SidTypeDeletedAccount),
MAKESIDDESC(SidTypeInvalid),
MAKESIDDESC(SidTypeUnknown),
MAKESIDDESC(SidTypeComputer),
MAKESIDDESC(SidTypeLabel),
};
TCHAR* GetSidNameUseDescription(SID_NAME_USE type)
{
TCHAR* pDesc=NULL;
int count = sizeof(gvSidUseType) / sizeof(SIDNameDesc);
for (int i=0;i<count;i++)
{
if (gvSidUseType[i].type==type)
{
pDesc=gvSidUseType[i].desc;
break;
}
}
return pDesc;
}
void dump(PSID pSid)
{
USES_CONVERSION;
LPTSTR strSid;
ConvertSidToStringSid(pSid,&strSid);
cout<<"SID : "<<T2A(strSid)<<endl;
TCHAR name[MAX_PATH];
TCHAR domainName[MAX_PATH];
DWORD dwNamelen=MAX_PATH;
DWORD dwDomainNamelen=MAX_PATH;
SID_NAME_USE nameUse;
if(!LookupAccountSid(NULL,pSid,name,&dwNamelen,domainName,&dwDomainNamelen,&nameUse))
{
cout<<"LookupAccountSid failed with "<<GetLastError()<<endl;
return;
}
StrCat(domainName,_T("\\"));
StrCat(domainName, name);
cout<<"Account : "<<T2A(domainName)<<endl;
cout<<" Type : "<<T2A(GetSidNameUseDescription(nameUse))<<endl;
}
void dumpAccessMask(ACCESS_MASK mask)
{
GETATTRI(mask, DELETE);
GETATTRI(mask, READ_CONTROL);
GETATTRI(mask, WRITE_DAC);
GETATTRI(mask, WRITE_OWNER);
GETATTRI(mask, SYNCHRONIZE);
}
#define MAKESDCDESC(sdc) {sdc, _T(#sdc)}
struct SdcDesc
{
DWORD sdc;
TCHAR* desc;
};
SdcDesc gvSdcDesc[]=
{
MAKESDCDESC(SE_DACL_AUTO_INHERIT_REQ),
MAKESDCDESC(SE_DACL_AUTO_INHERITED),
MAKESDCDESC(SE_DACL_DEFAULTED),
MAKESDCDESC(SE_DACL_PRESENT),
MAKESDCDESC(SE_DACL_PROTECTED),
MAKESDCDESC(SE_GROUP_DEFAULTED),
MAKESDCDESC(SE_OWNER_DEFAULTED),
MAKESDCDESC(SE_RM_CONTROL_VALID),
MAKESDCDESC(SE_SACL_AUTO_INHERIT_REQ),
MAKESDCDESC(SE_SACL_AUTO_INHERITED),
MAKESDCDESC(SE_SACL_DEFAULTED),
MAKESDCDESC(SE_SACL_PRESENT),
MAKESDCDESC(SE_SACL_PROTECTED),
MAKESDCDESC(SE_SELF_RELATIVE)
};
void dumpSdc(SECURITY_DESCRIPTOR_CONTROL controlBit)
{
USES_CONVERSION;
CString strDesc;
int count = sizeof(gvSdcDesc)/sizeof(SdcDesc);
for (int i=0;i<count;i++)
{
if (controlBit & gvSdcDesc[i].sdc)
{
if (strDesc!=_T(""))
{
strDesc += _T(" | ");
}
strDesc+=gvSdcDesc[i].desc;
}
}
cout<<"Security Description Control"<<endl;
cout<<T2A(strDesc)<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR* file = _T("F:\\bixy\\topdesk.ini");
PSID pSidOwner;
PSID pSidGroup;
PACL pDacl;
PSECURITY_DESCRIPTOR pSD;
DWORD dwRet = GetNamedSecurityInfo(file,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION,
&pSidOwner,&pSidGroup,&pDacl,NULL,&pSD);
if (dwRet==ERROR_SUCCESS)
{
cout<<"-------------------Owner--------------------"<<endl;
dump(pSidOwner);
cout<<endl;
cout<<"-------------------Group--------------------"<<endl;
dump(pSidGroup);
}
else
{
cout<<"GetNamedSecurityInfo failed with "<<dwRet<<endl;
return 0;
}
SECURITY_DESCRIPTOR_CONTROL controlBit;
DWORD dwRevision;
if(!GetSecurityDescriptorControl(pSD,&controlBit,&dwRevision))
{
cout<<"GetSecurityDescriptorControl failed with "<<GetLastError()<<endl;
return 0;
}
dumpSdc(controlBit);
ULONG countofExplicitEntries;
PEXPLICIT_ACCESS pExplicitAcess;
dwRet = GetExplicitEntriesFromAcl(pDacl,&countofExplicitEntries,&pExplicitAcess);
if (dwRet==ERROR_SUCCESS)
{
for (int i=0;i<countofExplicitEntries;i++)
{
cout<<endl<<"----------------------------------------"<<endl;
cout<<"Explicit Access "<<i+1<<endl;
cout<<"Access Mask:"<<endl;
dumpAccessMask(pExplicitAcess[i].grfAccessPermissions);
cout<<endl;
cout<<"Access Mode"<<endl;
switch(pExplicitAcess[i].grfAccessMode)
{
case NOT_USED_ACCESS:
cout<<"NOT_USED_ACCESS"<<endl;
break;
case GRANT_ACCESS:
cout<<"GRANT_ACCESS"<<endl;
break;
case SET_ACCESS:
cout<<"SET_ACCESS"<<endl;
break;
case DENY_ACCESS:
cout<<"DENY_ACCESS"<<endl;
break;
case REVOKE_ACCESS:
cout<<"REVOKE_ACCESS"<<endl;
break;
case SET_AUDIT_SUCCESS:
cout<<"SET_AUDIT_SUCCESS"<<endl;
break;
case SET_AUDIT_FAILURE:
cout<<"SET_AUDIT_FAILURE"<<endl;
break;
}
if (pExplicitAcess[i].Trustee.TrusteeForm==TRUSTEE_IS_SID)
{
dump((PSID)pExplicitAcess[i].Trustee.ptstrName);
}
cout<<endl<<"--------------------------------"<<endl<<endl;
}
}
else
{
cout<<"GetExplicitEntriesFromAcl failed with "<<GetLastError()<<endl;
}
TRUSTEE Trustee;
ZeroMemory(&Trustee,sizeof(TRUSTEE));
Trustee.pMultipleTrustee=NULL;
Trustee.MultipleTrusteeOperation=NO_MULTIPLE_TRUSTEE;
Trustee.TrusteeForm=TRUSTEE_IS_SID;
Trustee.TrusteeType=TRUSTEE_IS_USER;
Trustee.ptstrName=(LPTSTR)pSidOwner;
ACCESS_MASK mask=0;
dwRet = GetEffectiveRightsFromAcl(pDacl,&Trustee,&mask);
if (dwRet==ERROR_SUCCESS)
{
cout<<endl;
cout<<"Access Mask:"<<endl;
dumpAccessMask(mask);
}
else
{
cout<<"GetEffectiveRightsFromAcl failed with "<<GetLastError()<<endl;
}
cout<<endl<<"--------------------------------"<<endl<<endl;
ACL_SIZE_INFORMATION asi;
if(!GetAclInformation(pDacl,&asi,sizeof(ACL_SIZE_INFORMATION),AclSizeInformation))
{
cout<<"GetAclInformation failed with "<<GetLastError()<<endl;
}
for (int i=0;i<asi.AceCount;i++)
{
LPVOID pAce;
if (!GetAce(pDacl,i,&pAce))
{
cout<<"GetAce failed with "<<GetLastError()<<endl;
break;
}
PACE_HEADER pAceHeader = (PACE_HEADER)pAce;
ParseAce(pAceHeader);
}
//LocalFree(pDacl);
cout<<endl;
return 0;
}
void dumpAceFlags(BYTE flag)
{
CString strDesc;
GETATTRI(flag,CONTAINER_INHERIT_ACE);
GETATTRI(flag,FAILED_ACCESS_ACE_FLAG);
GETATTRI(flag,INHERIT_ONLY_ACE);
GETATTRI(flag,INHERITED_ACE);
GETATTRI(flag,NO_PROPAGATE_INHERIT_ACE);
GETATTRI(flag,OBJECT_INHERIT_ACE);
GETATTRI(flag,SUCCESSFUL_ACCESS_ACE_FLAG);
}
void ParseAce(PACCESS_ALLOWED_ACE pAllowedAce)
{
dumpAccessMask(pAllowedAce->Mask);
dump((PSID)&pAllowedAce->SidStart);
}
void ParseAce(PACCESS_DENIED_ACE pAllowedAce)
{
dumpAccessMask(pAllowedAce->Mask);
dump((PSID)&pAllowedAce->SidStart);
}
void ParseAce(PSYSTEM_ALARM_OBJECT_ACE pAllowedAce)
{
}
void ParseAce(PSYSTEM_ALARM_ACE pAllowedAce)
{
}
void ParseAce(PSYSTEM_ALARM_CALLBACK_ACE pAllowedAce)
{
}
void ParseAce(PSYSTEM_ALARM_CALLBACK_OBJECT_ACE pAllowedAce)
{
}
void ParseAce(PSYSTEM_AUDIT_ACE pAllowedAce)
{
}
void ParseAce(PSYSTEM_MANDATORY_LABEL_ACE pAllowedAce)
{
}
void ParseAce(PACE_HEADER pAceHdr)
{
cout<<"-------------------------------------"<<endl;
cout<<"-------------------------------------"<<endl;
cout<<"-------------------------------------"<<endl;
dumpAceFlags(pAceHdr->AceFlags);
cout<<endl;
if (pAceHdr->AceType == ACCESS_ALLOWED_ACE_TYPE)
{
cout<<"ACCESS_ALLOWED_ACE_TYPE"<<endl;
ParseAce((PACCESS_ALLOWED_ACE)pAceHdr);
}
else if (pAceHdr->AceType == ACCESS_DENIED_ACE_TYPE)
{
cout<<"ACCESS_DENIED_ACE_TYPE"<<endl;
ParseAce((PACCESS_DENIED_ACE)pAceHdr);
}
else if(pAceHdr->AceType == SYSTEM_ALARM_OBJECT_ACE_TYPE)
{
cout<<"SYSTEM_ALARM_OBJECT_ACE_TYPE"<<endl;
ParseAce((PSYSTEM_ALARM_OBJECT_ACE)pAceHdr);
}
else if (pAceHdr->AceType == SYSTEM_ALARM_ACE_TYPE)
{
cout<<"SYSTEM_ALARM_ACE_TYPE"<<endl;
ParseAce((PSYSTEM_ALARM_ACE)pAceHdr);
}
else if (pAceHdr->AceType == SYSTEM_ALARM_CALLBACK_ACE_TYPE)
{
cout<<"SYSTEM_ALARM_CALLBACK_ACE_TYPE"<<endl;
ParseAce((PSYSTEM_ALARM_CALLBACK_ACE)pAceHdr);
}
else if (pAceHdr->AceType == SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE)
{
cout<<"SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE"<<endl;
ParseAce((PSYSTEM_ALARM_CALLBACK_OBJECT_ACE)pAceHdr);
}
else if (pAceHdr->AceType == SYSTEM_AUDIT_ACE_TYPE)
{
cout<<"SYSTEM_AUDIT_ACE_TYPE"<<endl;
ParseAce((PSYSTEM_ALARM_ACE)pAceHdr);
}
else if (pAceHdr->AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
{
cout<<"SYSTEM_MANDATORY_LABEL_ACE_TYPE"<<endl;
ParseAce((PSYSTEM_MANDATORY_LABEL_ACE)pAceHdr);
}
cout<<endl;
}
3. 为新建对象使用安全描述符(或更改描述符)
#define MAKESDCDESC(sdc) {sdc, _T(#sdc)}
struct SdcDesc
{
DWORD sdc;
TCHAR* desc;
};
SdcDesc gvSdcDesc[]=
{
MAKESDCDESC(SE_DACL_AUTO_INHERIT_REQ),
MAKESDCDESC(SE_DACL_AUTO_INHERITED),
MAKESDCDESC(SE_DACL_DEFAULTED),
MAKESDCDESC(SE_DACL_PRESENT),
MAKESDCDESC(SE_DACL_PROTECTED),
MAKESDCDESC(SE_GROUP_DEFAULTED),
MAKESDCDESC(SE_OWNER_DEFAULTED),
MAKESDCDESC(SE_RM_CONTROL_VALID),
MAKESDCDESC(SE_SACL_AUTO_INHERIT_REQ),
MAKESDCDESC(SE_SACL_AUTO_INHERITED),
MAKESDCDESC(SE_SACL_DEFAULTED),
MAKESDCDESC(SE_SACL_PRESENT),
MAKESDCDESC(SE_SACL_PROTECTED),
MAKESDCDESC(SE_SELF_RELATIVE)
};
void dumpSdc(SECURITY_DESCRIPTOR_CONTROL controlBit)
{
USES_CONVERSION;
CString strDesc;
int count = sizeof(gvSdcDesc)/sizeof(SdcDesc);
for (int i=0;i<count;i++)
{
if (controlBit & gvSdcDesc[i].sdc)
{
if (strDesc!=_T(""))
{
strDesc += _T(" | ");
}
strDesc+=gvSdcDesc[i].desc;
}
}
cout<<"Security Description Control"<<endl;
cout<<T2A(strDesc)<<endl;
}
void CreateDACL()
{
TCHAR* filename = _T("F:\\bixy\\topdesk.ini");
SECURITY_DESCRIPTOR sd;
PACL pAcl;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
EXPLICIT_ACCESS explicitAccess;
ZeroMemory(&explicitAccess,sizeof(EXPLICIT_ACCESS));
BuildExplicitAccessWithName(&explicitAccess, _T("Everyone"), GENERIC_READ|GENERIC_WRITE, GRANT_ACCESS, NO_INHERITANCE);
DWORD dwRet = SetEntriesInAcl(1, &explicitAccess, NULL, &pAcl);
if (ERROR_SUCCESS != dwRet)
{
cout<<"SetEntriesInAcl failed with "<<GetLastError()<<endl;
return;
}
EXPLICIT_ACCESS explicitAccess2;
ZeroMemory(&explicitAccess2,sizeof(EXPLICIT_ACCESS));
BuildExplicitAccessWithName(&explicitAccess2, _T("Administrators"), GENERIC_READ|GENERIC_WRITE, DENY_ACCESS, CONTAINER_INHERIT_ACE);
dwRet = SetEntriesInAcl(1, &explicitAccess2, pAcl, &pAcl);
if (ERROR_SUCCESS != dwRet)
{
cout<<"SetEntriesInAcl failed with "<<GetLastError()<<endl;
return;
}
//PSID Sid;
//DWORD SidSize;
//SidSize = SECURITY_MAX_SID_SIZE;
Allocate enough memory for the largest possible SID.
//if(!(Sid = LocalAlloc(LMEM_FIXED, SidSize)))
//{
// cout<<"LocalAlloc failed with "<<GetLastError()<<endl;
// return;
//}
//if(!CreateWellKnownSid(WinBuiltinAdministratorsSid ,NULL,Sid,&SidSize))
//{
// cout<<"CreateWellKnownSid failed with "<<GetLastError()<<endl;
// return;
//}
//if(!AddAccessDeniedAce(pAcl,ACL_REVISION,GENERIC_READ|GENERIC_WRITE,Sid))
//{
// cout<<"AddAccessDeniedAce failed with "<<GetLastError()<<endl;
// return;
//}
SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE);
SECURITY_DESCRIPTOR_CONTROL controlBit;
DWORD dwRevision;
if(!GetSecurityDescriptorControl(&sd,&controlBit,&dwRevision))
{
cout<<"GetSecurityDescriptorControl failed with "<<GetLastError()<<endl;
return;
}
dumpSdc(controlBit);
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle=FALSE;
sa.lpSecurityDescriptor=&sd;
HANDLE hFile = CreateFile(filename,GENERIC_READ|GENERIC_WRITE, NULL, &sa, CREATE_ALWAYS, NULL,NULL);
CloseHandle(hFile);
}
ps:判断当前用户是否域登录,可以先查询用户所属的组,再用LookupAccountSid查询组Sid的SID_NAME_USE