windows Access Token 、ACL、ACE学习笔记

今日看了看关于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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值