贝贝花花包包店,精品555皮具,钱夹,皮夹

字体: | 推荐给好友 上一篇 | 下一篇

Windows2000 服务器端应用程序开发设计指南-存取控制(3)

发布: 2008-5-01 20:46 | 作者: Jeffrey Richter Jaso | 来源: 网络转载 | 查看: 205次

BOOL AllowAccessToDesktop( PSID psidTrustee, HDESK hDesk ){  

BOOL fReturn = FALSE;
PSECURITY_DESCRIPTOR psdDesk = NULL;
PACE_UNION pACENew = NULL;
try{{
// 取得桌面的DACL
PACL pDACLDesk;
if(GetSecurityInfo(hDesk, SE_WINDOW_OBJECT,
DACL_SECURITY_INFORMATION, NULL, NULL, &pDACLDesk,
NULL, &psdDesk) != ERROR_SUCCESS)
goto leave;
// 分派新的ACE
// 这个存取授予互动地登录的使用者
PACE_UNION pACENew = AllocateACE(ACCESS_ALLOWED_ACE_TYPE, 0,
DELETE|WRITE_OWNER|WRITE_DAC|READ_CONTROL|
DESKTOP_READOBJECTS|DESKTOP_CREATEWINDOW|
DESKTOP_CREATEMENU|DESKTOP_HOOKCONTROL|
DESKTOP_JOURNALRECORD|DESKTOP_JOURNALPLAYBACK|
DESKTOP_ENUMERATE|DESKTOP_WRITEOBJECTS|DESKTOP_SWITCHDESKTOP,
psidTrustee);
// ACE是否已经在DACL中?
if (FindACEInACL(pDACLDesk, pACENew) == -1){
// 假如没有,计算新的DACL大小
ULONG lNewACL = CalculateACLSize(pDACLDesk, NULL, 0,
&pACENew, 1 );
// 分配内存给新的DACL
PACL pNewDACL = (PACL)_alloca(lNewACL);
if (pNewDACL == NULL)
goto leave;
// 初始ACL
if (!InitializeAcl(pNewDACL, lNewACL, ACL_REVISION))
goto leave;
// 复制ACL
if (!CopyACL(pNewDACL, pDACLDesk))
goto leave;
// 取得新ACE的位置
ULONG lIndex = GetACEInsertionIndex(pNewDACL, pACENew);
// 增加新的ACE
if (!AddAce(pNewDACL, ACL_REVISION, lIndex,
pACENew, pACENew->aceHeader.AceSize))
goto leave;
// 设定DACL回到桌面
if (SetSecurityInfo(hDesk, SE_WINDOW_OBJECT,
DACL_SECURITY_INFORMATION, NULL, NULL,
pNewDACL, NULL)!=ERROR_SUCCESS)
goto leave;
}
fReturn = TRUE;
}leave:;
}catch(...){
}
// 清除
if(pACENew != NULL)
LocalFree(pACENew);
if(psdDesk != NULL)
LocalFree(psdDesk);
return (fReturn);
}

以下的程序片段显示如何使用这些函数的范例。此程序代码为内建的Everyone群组建立了一个SID,并将它传递到AllowAccessToWinSta及AllowAccessToDesktop函数中:

PSID psidEveryone;  

// 为内建的「Everyone」群组建立一个SID
SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_WORLD_SID_AUTHORITY;
if (!AllocateAndInitializeSid(&sidAuth, 1, SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0, &psidEveryone )){
// 错误
}
HWINSTA hWinSta = GetProcessWindowStation();
if (hWinSta == NULL){
// 错误
}
AllowAccessToWinSta(psidEveryone, hWinSta);
HDESK hDesk = GetThreadDesktop(GetCurrentThreadId());
if (hDesk == NULL){
// 错误
}
AllowAccessToDesktop(psidEveryone, hDesk);

说明

这里有个秘诀。AllowAccessToWinSta及AllowAccessToDesktop函数使用了标头文件Malloc.h中的C执行时期(Run-Time)程序库定义的_alloca函数,_alloca函数会在线程的堆叠上分配一块内存。此函数的优点是非常快速,不需内部的线程同步化及传回不必由应用程序释放的内存。当您跳出被呼叫的函数时,系统就会释放内存。 对于必须重复小型配置的安全性程序设计师而言,这样的函数会是个救命的工具,它将会加快程序代码的速度并帮助您避免内存缺乏的情形。


在此强烈地建议您找出时间察看AllowAccessToWinSta及AllowAccessToDesktop函数的内容,直到您了解它们的运作方式并有自信使用它们所采用的技巧为止。这些范例函数所执行的任务大约和您在存取控制程序设计中看到的一样复杂,假如您对它们感到自在,则实作符合您所需的存取控制大概就不会有困难。

实作存取控制的选择
 

Microsoft及其他厂商试图经由建立更高阶的函数来封装我们曾讨论过的低阶函数,以减轻存取控制程序设计师的重担。协力厂商也已经产生了减轻存取控制工作的解决方案。认识Windows之低阶存取控制的功能以及这些高阶函数的某些陷阱,应该能够让您做出满足程序代码需求的决定。

更高阶套件(Package)的实作器已经面临到这些挑战:

  • 简化非常有弹性的存取控制系统,不用限制弹性或在专案中可能需要的特色。
     
  • 建立健全且合用的程序代码。
     

63/6<123456>
 

评分:0

我来说两句

seccode