⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 9.2.3 信任成员的管理.htm

📁 Windows2000后台服务程序开发手册
💻 HTM
📖 第 1 页 / 共 3 页
字号:
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">NTSTATUS LsaOpenPolicy(&nbsp;&nbsp;<BR> PLSA_UNICODE_STRING plsastrSystemName,&nbsp;&nbsp;<BR> PLSA_OBJECT_ATTRIBUTES pObjectAttributes,&nbsp;&nbsp;<BR> ACCESS_MASK DesiredAccess,&nbsp;&nbsp;<BR> PLSA_HANDLE pPolicyHandle);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>这个函数起先看起来可能有点奇怪,因为这些资料型态在其他的Win32函数中不常被使用,所以让我们一个一个地检查。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>PlsastrSystemName是指向LSA_UNICODE_STRING结构的指标,定义如下:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">typedef struct _LSA_UNICODE_STRING {&nbsp;&nbsp;<BR> USHORT Length;&nbsp;&nbsp;<BR> USHORT MaximumLength;&nbsp;&nbsp;<BR> PWSTR&nbsp;&nbsp;Buffer;&nbsp;&nbsp;<BR>}LSA_UNICODE_STRING</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>跟Net函数一样,LSA函数只处理Unicode格式的字串。然而,和Net函数不同的是,LSA函数要求以LSA_UNICODE_STRING结构管理所有的字串,此结构包括字串长度、缓冲器长度以及指向缓冲器的指标。</FONT></P>
            <HR style="LINE-HEIGHT: 25px">

            <P><FONT style="LINE-HEIGHT: 25px" face=Arial color=#3e77d7 size=3 
            Black><B style="LINE-HEIGHT: 25px">说明</B></FONT> </P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>要记得Length(指示字串的长度)及MaximumLength(指示缓冲器的长度)成员是以位元组的方式储存,而非字元。</FONT></P>
            <HR style="LINE-HEIGHT: 25px">

            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>经由LSA_UNICODE_STRING结构之Buffer成员指向的字串没有明确地定义以0作结束。您可以选择用0来结束字串,但必须确定在字串长度的计算中没有包括无效的结尾。请记住当系统传回LSA_UNICODE_STRING给软件时,它不能指望经由Buffer成员指向的字串以0结束。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>处理LSA_UNICODE_STRING类型可能会有点不熟练,因为它是以长度分隔而不是以0作为分隔。正因如此,LSA_UNICODE_STRING实际上是被包含在C++ 
            类别中。我建立了一个称为CLSAStr的类别,在本章稍后叙述的TrusteeMan范例应用程序中会大量地使用到它。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>要呼叫LsaOpenPolicy,必须初始化LSA_UNICODE_STRING结构的实例并将它指向一个包含想操作之权限的Unicode字串系统名称。传递NULL以作为plsastrSystemName参数值,表示为本地机器。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>PobjectAttributes参数指向LSA_OBJECT_ATTRIBUTES结构的实例,在此时还未使用,因此要将它的每个成员初始化为0。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>DesiredAccess参数被宣告为ACCESS_MASK类型,对应到32位元无号整数。假如您要在系统上查看权限的资讯,则须结合此讨论后之范例中的POLICY_VIEW_LOCAL_INFORMATION及POLICY_LOOKUP_NAMES。假如您要设定权限资讯,应该要结合POLICY_CREATE_ACCOUNT存取标记。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>最后一个LsaOpenPolicy的参数要求您传递LSA_HANDLE类型变数的位址。执行成功后,系统会将此handle放置到此变数中开放的LSA原则物件。一旦您完成了这个原则物件,即应该传递此handle到LsaClose函数:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">NTSTATUS LsaClose(LSA_HANDLE hObjectHandle);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>所有的LSA函数皆传回NTSTATUS类型的值,您应该将这个值传递到LsaNtStatusToWinError中:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">ULONG LsaNtStatusToWinError(NTSTATUS Status);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>LsaNtStatusToWinError函数将NT状态程序代码转变成熟悉的Win32错误程序代码,就像从GetLastError传回的一样。在转变后,成功的呼叫LsaOpenPolicy,以传回一个ERROR_SUCCESS值。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>以下的程序代码显示开启一个在网路上,系统名称为「JasonsComputer」之LSA原则物件的适当方法:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">LSA_OBJECT_ATTRIBUTES lsaOA = {0};&nbsp;&nbsp;<BR>LSA_UNICODE_STRING lsastrComputer = {0};&nbsp;&nbsp;<BR>LSA_HANDLE hPolicy = NULL;&nbsp;&nbsp;<BR>// 电脑名称&nbsp;&nbsp;<BR>WCHAR* pstrName = L"JasonsComputer";&nbsp;&nbsp;<BR>// 设定LSA_OBJECT_ATTRIBUTES结构的大小&nbsp;&nbsp;<BR>lsaOA.Length = sizeof(lsaOA);&nbsp;&nbsp;<BR>// 填入LSA_UNICODE_STRING结构的成员&nbsp;&nbsp;<BR>lsastrComputer.Length = (USHORT) (lstrlen(pstrName) * sizeof(WCHAR));&nbsp;&nbsp;<BR>lsastrComputer.MaximumLength = lsastrComputer.Length + sizeof(WCHAR);&nbsp;&nbsp;<BR>lsastrComputer.Buffer = pstrName;&nbsp;&nbsp;<BR>// 撷取原则的handle&nbsp;&nbsp;<BR>NTSTATUS ntStatus = LsaOpenPolicy(&amp;lsastrComputer, &amp;lsaOA,&nbsp;&nbsp;<BR> POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES |&nbsp;&nbsp;<BR> POLICY_CREATE_ACCOUNT, &amp;hPolicy);&nbsp;&nbsp;<BR>ULONG lErr = LsaNtStatusToWinError(ntStatus);&nbsp;&nbsp;<BR>if (lErr != ERROR_SUCCESS){&nbsp;&nbsp;<BR> // 处理错误&nbsp;&nbsp;<BR>}</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>现在您已经知道如何取得LSA原则物件开启的handle,所以您已准备好开始管理系统上的权限。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e72d7 
            size=4><B style="LINE-HEIGHT: 25px">列举权限<BR 
            style="LINE-HEIGHT: 25px"> </B></FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>列举系统权限的方法有两种:获得特定信任成员所持有的权限清单,或者请求持有特定权限的信任成员清单。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e74d7 
            size=3><B style="LINE-HEIGHT: 25px">信任成员持有的权限<BR 
            style="LINE-HEIGHT: 25px"> </B></FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>让我们开始讨论如何获得系统特定的信任成员持有的权限清单。使用LsaEnumerateAccountRights函数来列举权限:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">NTSTATUS LsaEnumerateAccountRights(&nbsp;&nbsp;<BR> LSA_HANDLE hPolicy,&nbsp;&nbsp;<BR> PSID&nbsp;&nbsp;psidTrustee,&nbsp;&nbsp;<BR> PLSA_UNICODE_STRING* pplsastrUserRights,&nbsp;&nbsp;<BR> PULONG plCountOfRights);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>您必须传递一个与POLICY_LOOKUP_NAMES存取一起建立的开放原则物件,以作为LSAEnumerateAccountRights的hPolicy参数。PsidTrustee参数是个指向您想要列举权限之信任成员SID的指标。您可以使用LookupAccountName(在先前的〈认识SIDs〉一节中有讨论)从信任成员的帐户名称获得一个SID。这个信任成员可以是使用者帐户、群组帐户或者电脑帐户。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>您应该传递LSA_UNICODE_STRING型态的变数位址给LsaEnumerateAccountRights的pplsastrUserRights参数。系统会产生LSA_UNICODE_STRING结构的阵列,并指派一个缓冲器包含此阵列,然后在pplsastrUserRights参数指向的变数中放置一个指向缓冲器的指标。系统会传回plCountOfRights指向的ULONG阵列变数中的权限号码。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>因为系统已经了指派一个代表您的缓冲器,所以当您完成它时,必须释放这个缓冲器。传递一个指标到LsaFreeMemory函数的缓冲器中:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">NTSTATUS LsaFreeMemory(PVOID pvBuffer);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>假如LsaEnumerateAccountRights执行成功了,那么转变的状态程序代码将是ERROR_SUCCESS;假如帐户没有被指派权限,则转变的错误程序代码将会是ERROR_FILE_NOT_FOUND。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>经由LsaEnumerateAccountRights传回的阵列元素是LSA_UNICODE_STRING(在先前的〈LSA函数〉一节中定义)。每个元素会指向一个包含代表帐户权利的Unicode字串缓冲器,包括SeDebugPrivilege及SeEnableDelegationPrivilege等值。您可以参考先前的&nbsp;</FONT><FONT 
            style="LINE-HEIGHT: 25px" face=arial color=#000000 size=2><A 
            style="LINE-HEIGHT: 25px" 
            href="http://www.acejoy.com/doc/serverside/9.htm#440_1" 
            target=_new>表9-10</A>&nbsp;中所有可传回的权限清单内容。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>虽然LookupPrivilegeDisplayName函数和列举权限并无直接的关系,但是在此仍应该提到它。这个函数将计划性的权限名称,例如SeTcbPrivilege,译成易记的显示名称,在这个实例中则被译为「扮演作业系统的一部份」。</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL LookupPrivilegeDisplayName(&nbsp;&nbsp;<BR> PCTSTR pszSystemName,&nbsp;&nbsp;<BR> PCTSTR pszName,&nbsp;&nbsp;<BR> PTSTR&nbsp;&nbsp;pszDisplayName,&nbsp;&nbsp;<BR> PDWORD cbDisplayName,&nbsp;&nbsp;<BR> PDWORD pLanguageId);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>这个函数为权限取得系统名称及计划性名称,然后再将易记的名称传到您提供的缓冲器中。</FONT></P>
            <HR style="LINE-HEIGHT: 25px">

            <P><FONT style="LINE-HEIGHT: 25px" face=Arial color=#3e77d7 size=3 
            Black><B style="LINE-HEIGHT: 25px">说明</B></FONT> </P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>LookupPrivilegeDisplayName不会为帐户权利传回显示名称。它只为权限工作。我们在此处的讨论并不区分这两种帐户权利的类型,这个主题在第十一章会有更完整讨论。您可以参考&nbsp;<A 
            style="LINE-HEIGHT: 25px" 
            href="http://www.acejoy.com/doc/serverside/9.htm#440_1" 
            target=_new>表9-10</A>&nbsp;来决定帐户权利是否为权限。假如所讨论的权利在WinNT.h标头档中被定义,则它是个权限。如果它被定义在NTSecAPI.h标头档中,则它只是个帐户权利,并非实际的权限。</FONT></P>
            <HR style="LINE-HEIGHT: 25px">

            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>以下的范例函数显示如何列出信任成员持有的权限清单。它取得LSA原则handle及PSID以作为它的参数。</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL PrintTrusteePrivs(LSA_HANDLE hPolicy, PSID psid) {&nbsp;&nbsp;<BR> BOOL fSuccess = FALSE;&nbsp;&nbsp;<BR> WCHAR szTempPrivBuf[256];&nbsp;&nbsp;<BR> WCHAR szPrivDispBuf[1024];&nbsp;&nbsp;<BR> PLSA_UNICODE_STRING plsastrPrivs = NULL;&nbsp;&nbsp;<BR> __try {&nbsp;&nbsp;<BR>&nbsp;&nbsp;// 撷取SID的权限阵列&nbsp;&nbsp;<BR>&nbsp;&nbsp;ULONG lCoun, t = 0;&nbsp;&nbsp;<BR>&nbsp;&nbsp;NTSTATUS ntStatus = LsaEnumerateAccountRights(hPolicy, psid,&nbsp;&nbsp;<BR>&nbsp;&nbsp; &amp;plsastrPrivs, &amp;lCount);&nbsp;&nbsp;<BR>&nbsp;&nbsp;ULONG lErr = LsaNtStatusToWinError(ntStatus);&nbsp;&nbsp;<BR>&nbsp;&nbsp;if (lErr != ERROR_SUCCESS) {&nbsp;&nbsp;<BR>&nbsp;&nbsp; plsastrPrivs = NULL;&nbsp;&nbsp;<BR>&nbsp;&nbsp; __leave;&nbsp;&nbsp;<BR>&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;ULONG lDispLen = 0;&nbsp;&nbsp;<BR>&nbsp;&nbsp;ULONG lDispLang = 0;&nbsp;&nbsp;<BR>&nbsp;&nbsp;for (ULONG lIndex = 0;lIndex &lt; lCount; lIndex++) {&nbsp;&nbsp;<BR>&nbsp;&nbsp; // 确保0的结束&nbsp;&nbsp;<BR>&nbsp;&nbsp; lstrcpyn(szTempPrivBuf,&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;plsastrPrivs[lIndex].Buffer, plsastrPrivs[lIndex].Length);&nbsp;&nbsp;<BR>&nbsp;&nbsp; szTempPrivBuf[plsastrPrivs[lIndex].Length] == 0;&nbsp;&nbsp;<BR>&nbsp;&nbsp; wprintf(L"Programmatic Name: %s\n", szTempPrivBuf);&nbsp;&nbsp;<BR>&nbsp;&nbsp; // 转译成显示的名称&nbsp;&nbsp;<BR>&nbsp;&nbsp; lDispLen = 1024; // Size of static Display buffer&nbsp;&nbsp;<BR>&nbsp;&nbsp; if (LookupPrivilegeDisplayName(NULL, szTempPrivBuf,&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;szPrivDispBuf, &amp;lDispLen, &amp;lDispLang))&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;wprintf(L"Display Name: %s\n\n", szPrivDispBuf);&nbsp;&nbsp;<BR>&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;fSuccess = TRUE;&nbsp;&nbsp;<BR> }&nbsp;&nbsp;<BR> __finally {&nbsp;&nbsp;<BR>&nbsp;&nbsp;if (plsastrPrivs) LsaFreeMemory(plsastrPrivs);&nbsp;&nbsp;<BR> }&nbsp;&nbsp;<BR> return(fSuccess);&nbsp;&nbsp;<BR>}</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e74d7 
            size=3><B style="LINE-HEIGHT: 25px">持有特定权限的信任成员<BR 
            style="LINE-HEIGHT: 25px"> </B></FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>第二种撷取Windows 2000系统权限资讯的方式为:经由对LsaEnumerate 
            AccountsWithUserRight的呼叫请求持有特定权限的信任成员清单。</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">NTSTATUS LsaEnumerateAccountsWithUserRight(&nbsp;&nbsp;<BR> LSA_HANDLE hPolicy,&nbsp;&nbsp;<BR> PLSA_UNICODE_STRING plsastrUserRight,&nbsp;&nbsp;<BR> PVOID* ppvEnumerationBuffer,&nbsp;&nbsp;<BR> PULONG CountReturned);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>这个函数请求一个LSA原则物件的handle,与LsaEnumerateAccountRights很类似。然而,它取代了LSA_UNICODE_STRING结构的信任成员名称,您应该传递一个附带权限或帐户权利的计划性名称的LSA_UNICODE_STRING结构指标。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>系统经由被分派的缓冲器传回信任成员资讯到您的软件中,以及透过ppvEnumerationBuffer参数传回它的指标。尽管这个参数被定义成PVOID指标,您还是应该传递指标的位址给PLSA_ENUMERATION_INFORMATION类型之变数,因为系统将以LSA_ENUMERATION_INFORMATION结构阵列的方式传回资讯。假如Windows开发人员定义了LsaEnumerateAccountsWithUserRight取得正确类型的指标的话,情况将会更好,但是他们选择要求一个PVOID指标作为替代,所以您必须自行将这个参数转型。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>LSA_ENUMERATION_INFORMATION结构真的非常简单,而且只包含单一的成员-即一个SID指标:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">typedef struct _LSA_ENUMERATION_INFORMATION {&nbsp;&nbsp;<BR> PSID Sid;&nbsp;&nbsp;<BR>} LSA_ENUMERATION_INFORMATION;</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>阵列中元素的数量被传回到CountReturned指向的变数中,为LsaEnumerateAccountsWithUserRight的最后一个参数。在传回阵列中的SIDs,经由传递SID到LookupAccountSid中,可被用来产生信任成员名称。当您完成LsaEnumerateAccountsWithUserRight传回的缓冲器后,应该要将它的指标传递给LsaFreeMemory。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e72d7 
            size=4><B style="LINE-HEIGHT: 25px">权限的指派与移除<BR 
            style="LINE-HEIGHT: 25px"> </B></FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>建立单独的软件来列举权限给信任成员帐户的情形是罕见的。然而,几乎任何一个建立信任成员帐户的软件皆必须从帐户中指派(或移除)权利。幸运的是,LSA提供了两个简单的函数来执行这些任务。首先,LsaAddAccountRights用来将权限授予信任成员:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">NTSTATUS LsaAddAccountRights(&nbsp;&nbsp;<BR> LSA_HANDLE hPolicy,&nbsp;&nbsp;<BR> PSID&nbsp;&nbsp;psidTrustee,&nbsp;&nbsp;<BR> PLSA_UNICODE_STRING plsastrUserRights,&nbsp;&nbsp;<BR>ULONG&nbsp;&nbsp; lCountOfRights);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>这个函数很容易使用。您必须传递开启LSA原则物件的handle,以及指向您要修改权限之信任成员SID指标(本章先前的讨论中曾提到,您可以经由呼叫LookupAccountName而获得使用者或群组帐户的SID)。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>然而,在呼叫LsaAddAccountRights之前,您应该建立一个LSA_UNICODE_ 
            STRING结构的阵列,并加上您想要信任成员持有的权限名称。传递这个阵列的指标作为LsaAddAccountRights的plsastrUserRights参数值。最后,传递阵列中元素的数量给最后一个lCountOfRights参数。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>LsaAddAccountRights函数忽略已信任成员持有的任何帐户权利或权限。然而,若阵列中的任何一个权利对系统来说为无效的名称,则会失去作用。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>以下的程序代码提供了一个如何指派SeInteractiveLogonRight帐户权利及SeTcbPrivilege权限给经由变数psid指出SID的信任成员。</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">LSA_UNICODE_STRING lsastrPrivs[2] = { 0 };&nbsp;&nbsp;<BR>lsastrPrivs[0].Buffer = SE_INTERACTIVE_LOGON_NAME;&nbsp;&nbsp;<BR>lsastrPrivs[0].Length =&nbsp;&nbsp;<BR> lstrlen(lsastrPrivs[0].Buffer) * sizeof(WCHAR);&nbsp;&nbsp;<BR>lsastrPrivs[0].MaximumLength = lsastrPrivs[0].Length + sizeof(WCHAR);&nbsp;&nbsp;<BR>lsastrPrivs[1].Buffer = SE_TCB_NAME;&nbsp;&nbsp;<BR>lsastrPrivs[1].Length =&nbsp;&nbsp;<BR> lstrlen(lsastrPrivs[1].Buffer) * sizeof(WCHAR);&nbsp;&nbsp;<BR>lsastrPrivs[1].MaximumLength = lsastrPrivs[1].Length + sizeof(WCHAR);&nbsp;&nbsp;<BR>NTSTATUS ntStatus = LsaAddAccountRights(hPolicy, psid,&nbsp;&nbsp;<BR> lsastrPrivs, 2);&nbsp;&nbsp;<BR>ULONG lErr = LsaNtStatusToWinError(ntStatus);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>这个用来从信任成员帐户中移除权限的函数与LsaAddAccountRights非常相似,称LsaRemoveAccountRights,其函数原型如下:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">NTSTATUS LsaRemoveAccountRights(&nbsp;&nbsp;<BR> LSA_HANDLE hPolicy,&nbsp;&nbsp;<BR> PSID&nbsp;&nbsp;psidTrustee,&nbsp;&nbsp;<BR> BOOLEAN fAllRights,&nbsp;&nbsp;<BR> PLSA_UNICODE_STRING plsastrUserRights,&nbsp;&nbsp;<BR> ULONG&nbsp;&nbsp;lCountOfRights);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>它除了从psidTrustee指示的信任成员中移除权利清单以及拥有一个附加参数BooleanfAllRights外,此函数与LsaAddAccountRights一样。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>FallRights可让您从信任成员中移除所有的权限,而不用建立信任成员持有的权限清单。假如您传递TRUE给此参数,则plsastrUserRights及lCountOfRights参数应该分别为NULL和0。如果您传递FALSE给fAllRights参数,则LsRemoveAccountRights与LsaAddAccountRights的使用方式相同。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>在结束LsaRemoveAccountRights的讨论前,我应该指出从帐户中移除所有权利的相关细节。《Platform 
            SDK》文件中说明如果您传递TRUE给fAllRights参数的话,系统将会从帐户中移除所有的权限,然后再从系统中删除这个帐户;然而,这只有从某个观点来说才是正确的。每个执行Windows 
            2000的系统必须维持一个帐户权限项目的本机资料库(内部实作技术如同本机帐户),即使信任成员依*在另一台机器上,例如网域控制站。LsaRemoveAccountRights函数不会从主帐户的系统中删除信任成员帐户(即使是本地帐户);它只从它的本机资料库中删除帐户权限项目。</FONT></P><A 
            style="LINE-HEIGHT: 25px" name=209006>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e70d7 
            size=5><B style="LINE-HEIGHT: 25px">建立信任成员的理由<BR 
            style="LINE-HEIGHT: 25px"> </B></FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>在结束本章前,我想要谈论一些信任成员帐户的观点。我们已经讨论过如何建立及摧毁使用者及群组帐户以及如何指派权限给这些帐户的内容。此外,也浏览了安全识别项或SIDs的关键主题。然而,您可能还想知道您的服务器软件必须建立信任成员帐户的原因,简单来说,这是因为许多服务器应用程序从不建立信任成员帐户以及从现存的信任成员帐户指派或撤销权限。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>这里有几个原因:</FONT></P><FONT style="LINE-HEIGHT: 25px" face=arial 
            color=#000000 size=2>
            <UL style="LINE-HEIGHT: 25px">
              <LI 
              style="LINE-HEIGHT: 25px">限制或管理资源的存取。这就是您的服务器软件如何利用信任成员管理的部份。<BR 
              style="LINE-HEIGHT: 25px">  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -