Nt/2000 xp平台下的存储控制模型如何?

Nt/2000 xp平台下的存储控制模型如何?

Nt/2000/xp平台下的存储控制模型(Access Control Model

By 李智勇 2003-7-18 16:28

 

()

 

在涉及其他之前,我们先来看一段可能会出问题的程序。

if(ERROR_SUCCESS !=RegCreateKeyExW(HKEY_LOCAL_MACHINE,L"Software//007h",0,NULL,

REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hkey,NULL))

{return FALSE;}

if(ERROR_SUCCESS !=RegSetValueEx(hkey,lpItem,0,REG_SZ,(LPBYTE)”90”,2))

{

RegCloseKey(hkey); return FALSE;

}

RegCloseKey(hkey);

(程序1

这段程序很简单,就是打开注册表,并写值。在98或者管理员权限下基本上不会出现什么问题。但存在什么样的潜在问题呢?我们做这样的假设,这段代码运行在用户态的打印机驱动程序的某个DDI接口中,比如DrvEnablePDEV。这样当不同用户进行打印时这段代码都需要被调用。于是问题出现了,在其他用户权限下,有可能打开或者设置值失败。GetLastError()返回5Access denied)。原因是当你建立相关子键"Software//007h”时使用了NULL做为安全权限(lpSecurityAttributes)地参数。使用NULL意味着从父键直接继承DACL,而在这个DACL中一旦不包含对你所使用的帐户赋予权限的ACE,你对注册表的相关操作必然失败。(枚举"Software”的各个ACE的代码见后,但读懂ACE字符串有点难度,简单来说就是Built-in users只有对"Software”进行读的权利,所以Users组和Guest组的用户将无法写你所建立的子键007h”,因为用上述方式建立的子键的DACL继承自"Software”)。为避免这种情况,建立注册表键时要明确制定安全权限。代码如下(from msdn 有更改)

这段代码建立一个管理员可以进行任何操作,任何用户都可以读写的子键,程序和相关结构的说明将在下节进行。

SECURITY_ATTRIBUTES uSecurityAttributes;

PSID pEveryoneSID = NULL, pAdminSID = NULL;

PACL pACL = NULL;

PSECURITY_DESCRIPTOR pSD = NULL;

EXPLICIT_ACCESS ea[2];

SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;

SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;

SECURITY_ATTRIBUTES sa;

LONG lRes;

HKEY hkSub = NULL;

// Create a well-known SID for the Everyone group.

BOOL bResult=AllocateAndInitializeSid(&SIDAuthWorld, 1,

SECURITY_WORLD_RID,

0, 0, 0, 0, 0, 0, 0,

&pEveryoneSID);

// Initialize an EXPLICIT_ACCESS structure for an ACE.

// The ACE will allow Everyone read access to the key.

ZeroMemory(&ea, 2*sizeof(EXPLICIT_ACCESS));

ea[0].grfAccessPermissions = KEY_READ|KEY_WRITE ;

ea[0].grfAccessMode = SET_ACCESS;

ea[0].grfInheritance= NO_INHERITANCE;

ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;

ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;

ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID;

AllocateAndInitializeSid(&SIDAuthNT, 2,

SECURITY_BUILTIN_DOMAIN_RID,

DOMAIN_ALIAS_RID_ADMINS,

0, 0, 0, 0, 0, 0,

&pAdminSID);

// Initialize an EXPLICIT_ACCESS structure for an ACE.

// The ACE will allow the Administrators group full access to the key.

ea[1].grfAccessPermissions = KEY_ALL_ACCESS;

ea[1].grfAccessMode = SET_ACCESS;

ea[1].grfInheritance= NO_INHERITANCE;

ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;

ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;

ea[1].Trustee.ptstrName = (LPTSTR) pAdminSID;

// Create a new ACL that contains the new ACEs.

dwRes = SetEntriesInAcl(2, ea, NULL, &pACL);

// Initialize a security descriptor.

pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,

SECURITY_DESCRIPTOR_MIN_LENGTH);

InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);

SetSecurityDescriptorDacl(pSD,

TRUE, // bDaclPresent flag

pACL,

FALSE);

// Initialize a security attributes structure.

sa.nLength = sizeof (SECURITY_ATTRIBUTES);

sa.lpSecurityDescriptor = pSD;

sa.bInheritHandle = FALSE;

if ((dwErr=RegCreateKeyExW(HKEY_LOCAL_MACHINE,L"Software//800",0,NULL,

REG_OPTION_NON_VOLATILE,KEY_READ|KEY_WRITE,&sa,&hkey,NULL))!=ERROR_SUCCESS)

{ return ; }

else if ((dwErr=RegSetValueEx(hkey,lpItem,0,REG_SZ,(LPBYTE)lpVer90,2))

!=ERROR_SUCCESS)

{ RegCloseKey(hkey);return; }

RegCloseKey(hkey);

if(pAdminSID)

FreeSid(pAdminSID);

if (pEveryoneSID)

FreeSid(pEveryoneSID);

if (pACL)

LocalFree(pACL);

if (pSD)

LocalFree(pSD);

(程序2

下面为读取当前注册表键安全信息并把它转为字符串的程序,转化后的字符串的解析,参见msdn.

DWORD dwRes;

PACL pOldDACL = NULL;

PSECURITY_DESCRIPTOR pSD = NULL;

PSID pprimarysid=NULL,pownersid=NULL;

LPSTR pstring;

HKEY hObject;

if(ERROR_SUCCESS!=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software//800",0,KEY_READ,&hObject))

return 0;

// Get a pointer to the existing DACL.

dwRes = GetSecurityInfo((HANDLE)hObject, SE_REGISTRY_KEY ,

DACL_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION

|OWNER_SECURITY_INFORMATION,

&pownersid, &pprimarysid, &pOldDACL, NULL, &pSD);

ConvertSecurityDescriptorToStringSecurityDescriptor(pSD,SDDL_REVISION_1,

DACL_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION

|OWNER_SECURITY_INFORMATION,

&pstring,NULL);

if(pSD != NULL)

LocalFree((HLOCAL) pSD);

if(pstring!=NULL)

LocalFree((HLOCAL)pstring);

RegCloseKey(hObject);

(程序 3)