9. 亲信成员的保管


那个缓冲器应该要丰盛大,以富有传回的值;它们的大小会经由指向DWOSportageD变数的目的来传递,pcbName提出经由它所指向的缓冲器长度,而
pcbReferencedDomainName则指出经由它指向的缓冲器长度。如果你不传递充裕大小的缓冲器以从系统接受那一个名称的话,系统会在那七个变数中传来所需的缓冲器大小。

typedef struct _LOCALGROUP_MEMBERS_INFO_0 {
    PSID   lgrmi0_sid;
}LOCALGROUP_MEMBERS_INFO_0;

typedef struct _LOCALGROUP_MEMBERS_INFO_3 {

    PWSTR   lgrmi3_domainandname;
}LOCALGROUP_MEMBERS_INFO_3;


为止本章前,我想要谈论一些信任成员帐户的意见。我们曾经研商过怎么建立及摧毁使用者及群组帐户以及哪些指派权限给那些帐户的内容。别的,也浏览了平安识
别项或SIDs的要害主旨。但是,您或许还想知道您的服务器软件必须建立信任成员帐户的原因,简单来讲,那是因为众多服务器应用程序从不确立信任成员帐户
以及从现存的信任成员帐户指派或废除权限。

BOOL SetUserPassword(PWSTR pszSystem, PWSTR pszName, PWSTR pszPassword){ 
    USER_INFO_1003 userInfo = {0};
    userInfo.usri1003_password = pszPassword;
    NET_API_STATUS netStatus =
        NetUserSetInfo(pszSystem, pszName, 1003, (PBYTE) &userInfo, NULL);
    return (netStatus == NERR_Success);
}

BOOL GetUserComment(PWSTR pszSystem, PWSTR pszName, PWSTR pszComment,
    int nBufLen){
    USER_INFO_10 *puserInfo;
    BOOL fSuccess = FALSE;
    NET_API_STATUS netStatus =
        NetUserGetInfo(pszSystem, pszName, 10, (PBYTE*) &puserInfo);
    if (netStatus == NERR_Success){
        if (nBufLen > lstrlen(puserInfo->usri10_comment)) {
            lstrcpy(pszComment, puserInfo->usri10_comment);
            fSuccess = TRUE;
        }
        NetApiBufferFree(puserInfo);
    }
    return(fSuccess);
}
意义
FILTER_NORMAL_ACCOUNT 传回系统上的通用使用者帐户资料
FILTER_TEMP_DUPLICATE_ACCOUNT 传回网域控制站上的本机使用者帐户资料
FILTER_INTER网域_TRUST_ACCOUNT 传回网域控制站上的网域信任帐户资料
FILTER_WORKSTATION_TRUST_ 传回网域控制站上的成员服务器或工作站帐 ACCOUNT 户资料
FILTER_SERVER_TRUST_ACCOUNT 传回网域控制站上的网域控制站帐户资料


储存SID名称到持久的储存器中,例如系统登录,或是在使用者介面中代表多个SID时,文字SIDs会是十一分有救助的。您可以用来转换文字SIDs的函
数,分别是ConvertSidToStringSid及ConvertStringSidToSid。以下是它们的函数原型:

即使LookupAccountName取得了微机名称作为参数,它的搜索并不限于所内定的机械。搜寻应该依照指示机器的意见来实施。这么说,以下的清单即体现出信任成员的查找顺序:

 表9-5 可以传递给NetUserEnum的filter参数的筛选条件值
NTSTATUS LsaEnumerateAccountsWithUserRight(
    LSA_HANDLE  hPolicy,
    PLSA_UNICODE_STRING plsastrUserRight,
    PVOID*  ppvEnumerationBuffer,
    PULONG  CountReturned);


统经由信任成员帐户授予有个别文件的存取或拥有权。当系统推行有个别特许的权能函数时,因为信任成员帐户已予以这些权力,所以它是被允许的。当使用者被系统识
别时,是被他(他)的倚重成员帐户及群组的亲信成员帐户识别,而且使用者是那几个帐户的分子。如您所见,信任成员是Windows安全性的主要性部分。


系统实际会分别权限和它的近亲,即帐户义务,他们被同一地指派及吊销。如表9-10所示,权限定义在WinNT.h中,而帐户权利则在NTSecAPI.h中定义。

甭管它看起来像什么,用NetUserAdd来树立新使用者帐户之最低编写程序须要条件实际上是丰富合情的。以下的程序代码表达了最简易的实例:

 表9-1 管理信任成员的结构集

PlsastrSystemName是指向LSA_UNICODE_ST奥德赛ING结构的目的,定义如下:

最后1个传递给NetLocalGroupAdd的参数是pdwParmErr,是个DWO景逸SUVD的目的。对于不得当的参数,系统传回四个提出在
pdwParmErr参考的变数中,不相宜的参数值。唯有NetLocalGroupAdd的传回值等于E智跑RO揽胜极光_INVALID_PARAMETEXC60时,传回pdwParmErr的值才使得。表9-2列出这几个或许的值。假设你不想要收到这么些音讯,可以传递NULL给pdwParmErr。

以下的程序代码显示开启几个在网路上,系统名称为「杰森sComputer」之LSA原则物件的适宜措施:

LSA函数
 

LSA_ENUMERATION_INFOKoleosMATION结构真的拾分简单,而且只含有单一的分子-即2个SID目的:


其余有效的函数
 

设定使用者及群组资讯
 

权力的差使与移除
 

LookupAccountName的函数原型如下:

如您所见,那是个极度琐碎的程序代码,用来在给定的种类上与给定的称号及密码建立1人使用者。使用以下的办法呼叫此范例函数将会在本机系统上建立贰个名字为「MrMan」,密码为「HowDoYouDo」的使用者:

信任成员具有的权杖
 



你平日会为鲜明的亲信成员建立SIDs,例如伊夫ryone群组。您会经过查询授权单位及信任成员的值来为商讨中的信任成员建立3个SID,并且将它们传递给AllocateAndInitializeSid函数:


 表9-8 众所周知的SIDs及用法
BOOL LookupAccountSid(
    PCTSTR  pszSystemName,
    PSID    pSid,
    PTSTR   pszName,
    PDWORD  pcbName,
    PTSTR   pszReferencedDomainName,
    PDWORD  pcbReferencedDomainName,
    PSID_NAME_USE   peUse);

历数权限
 

那几个函数请求一个LSA原则物件的handle,与LsaEnumerateAccountRights很接近。但是,它代表了
LSA_UNICODE_STENCOREING结构的相信成员名称,您应该传递八个附带权限或帐户任务的布置性名称的LSA_UNICODE_STRING结构指
标。


您所见,这几个函数与大家谈谈过的NetLocalGroupEnum及NetUserEnum函数看起来很类似。事实上,主要的例外处在于这一个函数使用了
LOCALGROUP_USERS_INFO_*
结构集(LOCALGROUP_USERS_INFO_0于今仍存在)。

那里有个例子:倘若你使用NetLocalGroupAdd函数(稍后将详细地切磋)来确立本机群组,您可以采用输入及传递2个LOCALGROUP_INFO_0构造的实例,只含有群组名称,或是可让您内定群组名称及声明字串的LOCALGROUP_INFO_1布局。那取决于
您,而路过1个誉为level参数的传递,Net函数可让您采取要动用的社团。在大家的例证中,LOCALGROUP_INFO_0为level
0结构,而LOCALGROUP_INFO_1则是level 1结构。

本条简单选取的函数不难地获取你的缓冲器长度(以位元组)、四个针对目的SID的目的及3个针对最初SID的目的。

因为系统现已了派出三个表示你的缓冲器,所以当您成就它时,必须释放这些缓冲器。传递3个目的到LsaFreeMemory函数的缓冲器中:

摧毁使用者及群组帐户
 

  • Net API 「Net」函数可让您建立及保管任何Windows
    三千系统上的使用者帐户,包罗工作站以及服务器系统,不管系统是还是不是为网域控制站。
     
  • Active Directory Services
    Interface(ADSI) ADSI是一组COM物件,可让您在Windows
    2000上管理Active Directory。Active Directory是Windows
    3000网域上独具使用者及群组帐户(在成千上万其余的物件中)的器皿,对Windows来说是个至关主要的附加部分。您的软件能够利用ADSI物件来确立、
    删除及管制网域控制站之Active Directory上的使用者及群组物件。
     

如您所见,NetUserGetInfo及NetUserSetInfo函数拥有大概跟NetUserAdd一样的参数清单。事实上,唯一额外的参数是pstrUsername,它提议被拿走或设定资讯的使用者名称。

纵然那或者是当真,可是你会发觉Windows
2000的安全性具有非常大的弹性。您可以自行创建信任成员,不需与特定的使用者直接沟通在联名,也无须总是被已登入系统的使用者利用。举例来
说,Windows
3000可让您把使用者帐户的存取限制为与它的原本权限以及由软件决定的亲信成员权限相结合,它是一种 建立Restricted
Token 
的技能(Restricted
Token在第八一章有详实的座谈)。如此一来,您的软件就可以建立体系管事人不可以(或需要)手动建立的帐户。

说明

 

说明


众多序列函数会流传SIDs,同时有很多与安全性相关的函数会期待您建立涵盖SIDs或针对SIDs目标的结构。那不是题材,除了SID结构在长短上是可变的以外,系统设计者须要大家将社团作为是不透明的。幸运的是,系统提供了一个用来复制SID的函数:

表9-7展现一些眼看的奥迪Q3IDs。(完整的清单请参阅《Platform
SDK》文件中的WinNT.h。)和在此从前列出之授权单位差其他是,这些PRADOIDs并不完全是唯一的,因为它们是绝无仅有与授权单位相关的,就其本人来说,不受授权单位的主宰是尚未意思的。

如果您使用名称为「JClark」建立二个信任成员,然后再用那个帐户登入并确立三个文本,系统会主张本身是以此物件的主人。不过,假若您摧毁了本人的使用者
帐户,然后再以名称「JClark」重新建立3个新的使用者帐户,此时系统会指派分化的SID值,因而新的帐户不会被视为旧文件物件的主人。

void PrintLocalGroups() {
    ULONG_PTR lResume = 0;
    ULONG lTotal = 0;
    ULONG lReturned = 0;
    ULONG lIndex = 0;
    NET_API_STATUS netStatus;
    LOCALGROUP_INFO_0* pinfoGroup;

    do {
        netStatus = NetLocalGroupEnum(NULL, 0, (PBYTE*) &pinfoGroup,
            MAX_PREFERRED_LENGTH, &lReturned, &lTotal, &lResume);
        if ((netStatus == ERROR_MORE_DATA) ||
            (netStatus == NERR_Success)) {
            for (lIndex = 0; lIndex < lReturned; lIndex++) {
                wprintf(L"%s/n", pinfoGroup[lIndex].lgrpi0_name);
            }
            NetApiBufferFree(pinfoGroup);
        }
    }while (netStatus == ERROR_MORE_DATA);
}

建立使用者帐户与建立群组帐户的主意类似;不过,您可以提供更加多使用者帐户的信息给系统。您可以采取NetUserAdd函数在Windows
三千系统上建立新的使用者。

NET_API_STATUS NetLocalGroupAdd(
    PCWSTR  pstrServername,
    DWORD   dwLevel,
    PBYTE   pbBuf,
    PDWORD  pdwParmErr);

确立信任成员帐户
 

认识Net函数
 

末段八个LsaOpenPolicy的参数需求你传递LSA_HANDLE类型变数的位址。执行成功后,系统会将此handle放置到此变数中开放的LSA原则物件。一旦你做到了这几个原则物件,即应当传递此handle到LsaClose函数:

即便AllocateAndInitializeSid传回FALSE,表示你很有只怕传递了二个过量8的附带授权单位数据。因为这几个函数会指派内存给你,
所以另二个失利的缘故只怕是暴发内存不足的意况。若是AllocateAndInitilizeSid执行成功,PSID变数将会蕴藏三个针对性新SID的
目的。当您成就SID后,应该把它传递给FreeSid,以使系统可以释放SID所选拔的内存:

 表9-10 中具备可传回的权杖清单内容。表9-9 。TrusteeMan范例应用程序 。表9-1 中所商量的LOCALGROUP_INFO_*
结构集。您能够传递0或然1以作为此函数的level值。那七个结构的概念如下:

使用者帐户及群组帐户是一个系统的亲信成员。 信任成员 
在Windows中可以拒绝或同意存取的实业。有个别相信成员隐含在系统中(例如伊夫ryone之内建群组),另一些则由系统动态地树立(例如在第⑩及十
一章会更详实谈论的登入SID),还有其余因为已创建帐户而留存的信任成员。使用者、群组及电脑都以与看重成员帐户有关的Windows信任成员。全部的
信任成员分享遍及系统的共用函数,尤其是在拍卖存取控制时(在下一章商量)。



以此函数会取得服务器名称及本机群组名称以作为它的首先个参数。常见的dwLevel参数指出您想要经由ppbBuf参数传回的LOCALGROUP_MEMBERS_INFO_*
结构集level。


使用者及群组帐户在系统中控制存取安全物件的剧中人物,以及系统权限的功能来说是看似的。系统可让您交替地指派以及否决使用者和群组帐户的权能。可是,使用者
可以接纳使用者帐户登入系统,反之,群组帐户却力不从心以那种方式利用。那种与使用者结合的气象,使得系统必须为使用者帐户维护多量的情报。


应该在内存中传递三个针对丰盛为pSid参数所需之SID缓冲器目标,以及一个DWO奥迪Q7D位址,包罗作为pcbSid参数的缓冲器大小。即便你的缓冲器太
小,系统将盛传战败,而且GetLastError函数会传回E途锐RO奥迪Q7_INSUFFICIENT_
BUFFELX570。LookupAccountName也将通过pcbSid参数以缓冲器应有的高低填满您提供的DWO中华VD变数。

结构集 用法及函数
GROUP_INFO_* 这些结构为通用或网域群组取得资讯以及设定通用群组资讯,在建立群组及对现存的群组操作时会使用到。

 函数: 

NetGroupAdd、NetGroupEnum、NetGroupGetInfo、NetGroupSetInfo

GROUP_USERS_INFO_* 在管理通用或网域群组中的使用者成员时会使用到这些结构,可用来为群组设定或取得使用者资讯。

 函数: 

NetGroupGetUsers、NetGroupSetUsers、NetUserGetGroups、NetUserSetGroups

LOCALGROUP_INFO_* 用来为本机群组取得以及设定资讯,不但会被现存的群组使用,在建立新的本机群组时也会用到。

 函数: 

NetLocalGroupAdd、NetLocalGroupEnum、NetLocalGroupGetInfo、NetLocalGroupSetInfo

LOCALGROUP_MEMBERS_INFO_* 用来为本机群组设定及取得成员清单。

 函数: 

NetLocalGroupAddMembers、NetLocalGroupDelMembers、NetLocalGroupGetMembers、NetLocalGroupSetMembers

LOCALGROUP_USERS_INFO_* 此组结构只包含一个称为LOCALGROUP_ USERS_INFO_0的结构,呼叫NetUserGet-Local Groups以取得本机群组成员之所有使用者帐户清单时使用。

 函数: 

NetUserGetLocalGroups

USER_INFO_* 由于Windows 2000使用者帐户联系的大量资讯,此组结构显然包含了最大的结构数量。建立使用者以及为现存使用者帐户取得和设定资讯时会使用到这些结构。

函数:

NetUserAdd、NetUserEnum、NetUserSetInfo、NetUserGetInfo

和事先的罗列函数不一样,它从不重新呼叫NetUserGetLocalGroups继续列举的艺术。您不太大概汇合临列举多于几十二个群组的景色,而列举使用者只怕会传播数千个帐户项目。


NET_API_STATUS NetApiBufferFree(PVOID pvBuffer);

SID格式

使
用者帐户维持一组与使用者相关的情报,例如,名字、密码(或身分证件)、注释及地方。有三个必备项目与使用者帐户一起储存,即是使用者在系统上的权限清单
以及数位身份鉴别-被称呼安全识别项或是SID(读为「sid」)-当在保证物件及私人资料的平安时,系统会接纳它们来确认帐户。SID是用来认可相信任成
员帐户的可变长度二进制结构(权限和SID在稍后将有详尽的座谈)。第1个与使用者帐户同样相当主要的信息是使用者成员的群组清单。

持有成功呼叫的NetUserGetInfo必须呼叫NetApiBufferFree,以释放NetUserGetInfo传回的缓冲器。NetApiBufferFree函数被定义为取得二个参数,它是被保释的缓冲器目的。

NTSTATUS LsaFreeMemory(PVOID pvBuffer);
LSA_OBJECT_ATTRIBUTES  lsaOA = {0};
LSA_UNICODE_STRING  lsastrComputer = {0};
LSA_HANDLE  hPolicy = NULL;

// 电脑名称
WCHAR* pstrName = L"JasonsComputer";

// 设定LSA_OBJECT_ATTRIBUTES结构的大小
lsaOA.Length = sizeof(lsaOA);

// 填入LSA_UNICODE_STRING结构的成员
lsastrComputer.Length = (USHORT) (lstrlen(pstrName) * sizeof(WCHAR));
lsastrComputer.MaximumLength = lsastrComputer.Length + sizeof(WCHAR);
lsastrComputer.Buffer = pstrName;

// 撷取原则的handle
NTSTATUS ntStatus = LsaOpenPolicy(&lsastrComputer, &lsaOA,
    POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES |
    POLICY_CREATE_ACCOUNT, &hPolicy);
ULONG lErr = LsaNtStatusToWinError(ntStatus);
if (lErr != ERROR_SUCCESS){
    // 处理错误
}

拍卖信任成员时,理解很多安全性函数所需的SID值是很要紧的。再者,就SIDs来说,本机群组成员的操作函数可让您撷取信任成员项目。


域或通用群组帐户在很多观念及软件上皆与本机群组帐户一样。就算自个儿从此间起首将探讨本机群组的保管细节,不过在规划地保管通用群组时,许多价值观照旧适用
的。有关Net API通用群组功效的全部商量,请参阅《Platform
SDK》文件中字首为「NetGroup」的函数组。

呼唤NetUserAdd时,表9-4中此外一种标志的三结合都足以被派遣给USELacrosse_INFO_1的usri1_flags成员,其余的标记则可用来钦定额外的性状。有关这么些其余标志的新闻,请参阅《Platform
SDK》文件。



的软件必须为使用者或群组大概会有和处理器或网域相同的名号负责。处理那些状态的最好点子是无人不晓地指出电脑名称给帐户,以作为帐户名称的一部份。举例来说,
假设电脑和使用者都取名为「JClark」,而「JClark」帐户已存在「JClark」电脑上,以下的程序代码将盛传SID给使用者帐户:

BOOL LookupAccountName(
    PCTSTR  pszSystemName,
    PCTSTR  pszAccountName,
    PSID    pSid,
    PDWORD  pcbSid,
    PTSTR   pszReferencedDomainName,
    PDWORD  pcbReferencedDomainName,
    PSID_NAME_USE   peUse);

FallRights
可让您从信任成员中移除全部的权位,而不用建立信任成员具有的权限清单。若是你传递TRUE给此参数,则plsastrUserRights及
lCountOfRights参数应该分别为NULL和0。倘诺您传递FALSE给fAllRights参数,则
LsRemoveAccountRights与LsaAddAccountRights的行使方式一样。

现行你明白撷取及设定全数本机群组之信任成员的方法,还有四个有效的函数,可让您从明日成员的群组中,只新增及删除特定的信任成员清单。那五个函数分别是NetLocalGroupAddMembers及NetLocalGroupDelMembers:

说明

LookupPrivilegeDisplayName不会为帐户义务传回显示名称。它只为权限工作。大家在此地的座谈并不区分那三种帐户权利的品类,这几个宗意在第拾一章会有更完整切磋。您可以参考 表9-10 来决定帐户义务是不是为权力。假诺所谈论的权利在WinNT.h标头档中被定义,则它是个权力。如若它被定义在NTSecAPI.h标头档中,则它只是个帐户职分,并非实际的权柄。

 

NTSTATUS LsaAddAccountRights(
    LSA_HANDLE  hPolicy,
    PSID        psidTrustee,
    PLSA_UNICODE_STRING plsastrUserRights,
ULONG           lCountOfRights);

先是个参数是你想建立之群组帐户的系统名称。传递NULL给pstrServername表示您愿意在本机系统上树立多少个群组。dwLevel参数指出您将传递给pbBuf参数作为参考的结构类型。NetLocalGroupAdd使用 

TrusteeMan
范例应用程序(「09
TrusteeMan.exe」)示范Net函数的利用及用来树立和管制使用者及群组帐户,与选派及吊销系统权限的LSA函数。这些应用程序的原始码及文
件,存放在随书光碟中的09-TrusteeMan目录下。图9-2显示了TrusteeMan范例应用程序的使用者介面。

认识权力与帐户权利
 

撷取信任成员的二进制SID
 

说明

以下的程序代码表达了如何利用NetLocalGroupEnum列举本机系统上的群组,并出示在主控台视窗:


设定信任成员资讯时,Net函数可能会咬定软件并没有正确地设定结构成员。在那几个场地下,「Set」函数(如NetUserSetInfo)会回传
E奥德赛ROTiguan_INVALID_PARAMETEKuga。为了鲜明错误的来由,您可以采纳函数的谬误参数,那个参数会被填入二个先期定义的值,以提议首先个导致
错误的布局成员。假设你对那么些音信不感兴趣,可以传递NULL给「Set」函数。


跟Net函数一样,LSA函数只处理Unicode格式的字串。不过,和Net函数不一致的是,LSA函数须求以LSA_UNICODE_STKugaING结构管理全部的字串,此布局包罗字串长度、缓冲器长度以及针对缓冲器的目标。


说明

分享到:

LOCALGROUP_MEMBERS_INFO_0中使用的PSID类型提议3个针对SID结构的目的。这个协会的其余3个都可依照你软件的要求而与NetLocalGroupGetMembers一起使用。

叙述
LOCALGROUP_NAME_PARMNUM 这个值表示您指定了一个无效的群组名称给新的群组。
LOCALGROUP_COMMENT_PARMNUM 这个值表示呼叫NetLocalGroupAdd中的注解值是无效的。
  • 限定或管理财富的存取。那就是你的服务器软件怎么样利用信任成员管理的部份。
     
  • 为使用者建立帐户,以作为登入识其他使用或为管理现存的使用者而树立群组帐户。即便那是起家信任成员帐户常见的案由,但服务器软件并非如此。MMC或任何管理的工具常常会管理那几个函数。
     

您能够运用那几个函数传回的值指派3个缓冲器给您的新SID。

协理授权单位是绝无仅有的三十五个人元值,与授权单位的SID相关。下叁个附带授权单位是绝无仅有的,与原先的附带授权单位及最后授权单位的SID相关。次要授权单位即大家所知道的索罗德IDs。

PszReferenced网域Name及pcbReferenced网域Name分别为缓冲器接收与帐户相关的网域名称,以及一个针对性包蕴大小的DWO凯雷德D变数目标。就算是不要求与看重成员相关的网域名称,也无法传递NULL给其余2个值。

此外,若是你正在编写可以直接支援建立帐户的服务器软件,例如Internet
gaming群体(Internet gaming community)或是前端(Front
End)连线银行,您的劳动必须能够统筹的创造及管理信任成员帐户。Windows
3000提供两组可让您那般做的函数:


您所见,当您在确立使用者时,能够采纳传递多量的音讯给系统。有关USE奥德赛_INFO_2及USER_INFO_3布局中各种成员的详细讲述,请参阅
《Platform
SDK》文件。此处的座谈只需叙述在USEOdyssey_INFO_1协会中冒出的积极分子,那一个成员会在表9-3中列出。

接下去的多个参数为您新的SID指出次要授权单位。小编常想了然为啥Microsoft的开发人士不选用将那么些参数合并成为DWO奥迪Q5D阵列的单一目标。无论怎么样,您应该传递给次要授权单位的值和你必要的相同多,并且传递0给剩馀的参数。

要记得Length(提醒字串的尺寸)及马克西姆umLength(指示缓冲器的尺寸)成员是以位元组的点子储存,而非字元。

你可以行使NetLocalGroupAdd函数来树立本机群组帐户,其原型如下:

即便系统领会它正在复制的SID长度,它依旧需求显然不会被写入当先缓冲器的尺寸。那就是为何CopySid须求您传递3个长短以作为第1个参数的由来。
更关键的是,您将会必要领悟被选派的缓冲器有多大。可以接纳GetLengthSid函数找出以位元组计算的SID长度:

尽管你可以应用LookupAccountName找出肯定的SIDs,您依旧应该时时采取AllocateAndInitializeSid来一贯建立尽人皆知的SIDs。



应该传递LSA_UNICODE_ST奥迪Q5ING型态的变数位址给LsaEnumerateAccountRights的
pplsastrUserRights参数。系统会发生LSA_UNICODE_ST卡宴ING结构的阵列,并选派多个缓冲器包蕴此阵列,然后在
pplsastrUserRights参数指向的变数中放置2个针对缓冲器的目标。系统会传回plCountOfRights指向的ULONG阵列变数中
的权柄号码。

以下的范例函数显示怎么列出信任成员具有的权柄清单。它拿走LSA原则handle及PSID以作为它的参数。

作者在这一章谈论到的布局集将以星号(*)代替level标记,以便归结资讯而不用详细表达逐个可用的构造。举例来说,在上一段所涉嫌的七个布局都在
LOCALGROUP_INFO_*
结构集中。小编将会解释一些不时使用的构造以及带有较少结构成员的一部分大结构。全体结构的详实表达皆可在《Platform
SDK》文件中找到。

这么些布局的各种成员将来对你来说应该是领会的。ANYSIZE_ALX570RAY定义为1,首假设意味着结构不肯定仅以十足的DWO奥迪Q5D代表一个辅助授权单位以作为
结尾。即使SID结构的本人极度驾驭,它是个「不透明的」资料结构,而且应该只使用提供的体系函数来操作。这些不透明天性给予Microsoft开发人员在以往改成SID内部结构的私行。您的软件应该跟随这一个规则。


应该传递2个目标到采纳的结构类型阵列给pbBuf参数,以及阵列中项目的多少为dwTotalEntries参数的始末。借使函数执行成功,被
pbBuf以阵列传递之表示深信成员清单将是其一群组的新成员清单。记住信任成员清单将会代表任三个现行的群组成员。倘使函数执行成功,将传回
NE翼虎LX570_Success。


您所看到的,信任成员的称号空间在使用者、群组、电脑及网域之间被分享。即使系统差异意你使用与另贰个使用者或群组相同的名称建立壹位使用者或群组,但系
统允许使用者或群组拥有与总括机或网域相同的名号。那暴发了神秘的题材,因为LookupAccountName会在SID被回传给使用者以前即传给电脑。

Net
API有好多的风味且富含众多使管理信任成员帐户更为简单的函数及协会。Net函数可让您管理使用者帐户、本机群组帐户(只与单一机器相关联)及存在于网
域控制站和整个网域函数的网域或通用群组帐户。那几个函数以稳住且适合逻辑的章程设计,我们能够经过对有的规则的问询而读书到很多。

dwPref马克斯Len、
pdwEntriesRead、pdwTotalEntries及pdwResumeHandle参数是惯用缓冲器大小、读取的档次、剩下的系列以及连续列举型别的值。这几个参数和曾经探讨过的NetUserEnum及NetLocalGroupEnum函数中同样名称的参数一样,以完全相同的措施运营。事
实上,为了与NetLocalGroupGetMembers一起使用,NetLocalGroupEnum的一部分范例函数
PrintLocalGroups,可以不难地修改如下:

列举使用者及群组
 

SID 常见名称 用法
S-1-0-0 Null SID 指出一个空的或为NULL的群组。它被定义为唯一没有使用者的群组,通常用来指示没有人。
S-1-1-0 Everyone 指出一个所有信任成员皆为暗示性成员的群组。这是一个非常重要的SID,对于在系统中建立安全物件的存取清单是有帮助的。它也就是World SID或World群组。
S-1-2-0 Local SID 指出一个包括所有本地或实际登入系统的使用者群组。
S-1-3-0 Creator Owner SID 为某个物件的建立者充当替代符号(Placeholder)。它与可继承的存取控制清单一起使用。您将在第十章找到更多有关此SID的资讯。
S-1-3-1 Creator Group SID 为某个物件的主要群组建立者充当替代符号。它与可继承的存取控制清单一起使用。您将在第十章找到更多有关此SID的资讯。
S-1-5-1 Dialup 指出当使用者帐户经由拨接登入Windows 2000系统时,所有使用者帐户自动成为成员的群组。
S-1-5-2 Network 指出当使用者帐户经由网路登入Windows 2000系统时,所有使用者帐户自动成为成员的群组。
S-1-5-3 Batch 指出当使用者帐户经由批次登入的方式登入Windows 2000系统时,所有使用者帐户自动成为成员的群组。
S-1-5-4 Interactive 指出当使用者帐户经由互动式登入Windows 2000系统时,所有使用者帐户自动成为成员的群组。
S-1-5-6 Service 指出当使用者帐户以服务的身分登入Windows 2000系统时,所有使用者帐户自动成为成员的群组。
S-1-5-7 AnonymousLogon 与无效的会议登入结合。
S-1-5-9 ServerLogon 与网域控制站帐户结合。
S-1-5-10 Self(或Principal Self) 充当替代符号,并且只适用于存取群组或使用者帐户的清单。当它出现时,指出存取清单申请的信任成员帐户。
S-1-5-11 Authenticated User 使用者指出一个所有目前被认证的使用者帐户是暗示性成员的群组。
S-1-5-13 Terminal Server 与登入终端服务器的使用者关联。
S-1-5-18 LocalSystem 这个有许多服务皆在其下执行的特别帐户,存在于所有的Windows 2000系统中。有关更多的资讯,请参阅 第十一章 。

表9-1列出为信任成员管理所定义的社团集以及可同台利用的函数。

 表9-2 pdwParamErr参数中可能被传回的值
RID 有关的授权单位 定义
SECURITY_NULL_RID NULL 定义为0,这是NULL群组的个别次要授权单位。
SECURITY_WORLD_RID WORLD 定义为0,这是Everyone群组的个别次要授权单位。
SECURITY_CREATOR_ OWNER_RID CREATOR 定义为0,这是使用者Creator Owner的个别次要授权单位。
SECURITY_CREATOR_ GROUP_RID CREATOR 定义为1,这是使用者Creator Group的个别次要授权单位。
SECURITY_CREATOR_ OWNER_SERVER_RID CREATOR 定义为2,这是使用者Creator Owner Server的个别次要授权单位。
SECURITY_CREATOR_ GROUP_SERVER_RID CREATOR 定义为3,这是使用者Creator Group Server的个别次要授权单位。

以此函数只需求某个修改就足以拔取NetUserEnum来列举系统上的使用者。

ULONG LsaNtStatusToWinError(NTSTATUS Status);

使用AllocateAndInitializeSid,您不仅可以创立赫赫有名的SIDs,也得以建立2个使你的软件能分辨授权单位及扶助授权单位数值的动态SIDs。以下的范例展现了哪些采纳此函数建立多少个意味着伊芙ryone群组的SID:

ADSI
套件也足以用来确立群组帐户。Active
Directory被协会成层级物件,可以在此外的器皿物件中树立群组物件。您可以采用IADsContainer介面的Create方法创制一个群组物
件。一旦创造物件后,您可以应用QueryInterface方法得到IADsGroup介面的目标,它可以用来更进一步地管理新的群组物件。要收获更加多的细节,请参阅《Platform SDK》文件。

PobjectAttributes参数指向LSA_OBJECT_ATTRubiconIBUTES结构的实例,在那时候还未使用,由此要将它的各种成员开始化为0。

说明


其一范例也为编制信任成员清单实作二个可重覆使用的通用对话方块。此范例使用那么些对话方块来管理群组帐户及特定权限的持有者。系统尚未为此提供内建的介面,所以在范例中富含2个。

在大家进去安顿性的管制使用者及群组帐户的议论以前,让咱们先看一下管理连串信任成员的使用者介面。


请记得群组成员资讯也与群组帐户一起储存,就算名称及评释看起来恐怕是与群组帐户结合的最少资讯。由于它与SID主旨精心相关,所以这些主旨将延到本章的末段有的,在稍后的〈认识SIDs〉一节少校讨论SIDs内容。


 I 是个48I位元的数字,提示授权单位。

借使LsaEnumerateAccountRights执行成功了,那么转变的事态程序代码将是E途睿欧ROSportage_SUCCESS;假若帐户没有被指派权限,则转变的失实程序代码将会是EXC60RO奥迪Q5_FILE_NOT_FOUND。

 R 是SID的校正阶段,以贰个数字代表(一般是1)。

 S 如字面所写的「S」,指示那些序号是SID。

NetUserGetLocalGroups函数的原型如下:

LOCALGROUP_MEMBERS_INFO_*
结构允许你处理信任成员名称及网域名称,或是它们的SIDs,下一节将作详细地证实。以下是LOCALGROUP_MEMBERS_
INFO_0 及 LOCALGROUP_MEMBERS_INFO_3 结构的定义:


理LSA_UNICODE_STENVISIONING类型大概会有点不熟稔,因为它是以长度分隔而不是以0作为分隔。正因如此,LSA_UNICODE_ST本田CR-VING
实际上是被含有在C++
种类中。作者建立了三个号称CLSAStr的门类,在本章稍后叙述的TrusteeMan范例应用程序中会大量地运用到它。

让大家伊始商量什么获取系统特定的深信成员具有的权杖清单。使用LsaEnumerateAccountRights函数来列举权限:


组成员资讯能以多少个格局修改,可是大家首先须要学习几个撷取群组成员资讯的不二法门。第二个办法应用NetUserGetLocalGroups函数撷取为群
组成员之使用者清单;第3个主意应用NetLocalGroupGetMembers函数撷取与个别群组关联的成员组。

NET_API_STATUS NetLocalGroupGetMembers(
    PCWSTR  pszServerName,
    PCWSTR  pszLocalGroupName,
    DWORD       dwLevel,
    PBYTE*  ppbBuf,
    DWORD       dwPrefMaxLen,
    PDWORD  pdwEntriesRead,
    PDWORD  pdwTotalEntries,
    PDWORD_PTR  pdwResumeHandle);

认识SIDs
 

dwLevel
参数提出在呼唤NetUserGetInfo或NetUserSetInfo中,将会使用到的USE本田UR-V_INFO_*
结构level。这几个函数接受USE大切诺基_INFO_1或USER_INFO_3,似乎前边所定义的,以及NetUserAdd不支援的其余多少个USEPAJERO_INFO_* 结构。有关这么些社团的一体化叙述,请参见《Platform
SDK》文件。

以下的程序代码提供了八个怎么样指派SeInteractiveLogonRight帐户权利及SeTcbPrivilege权限给经由变数psid指出SID的相信成员。

系统传回读取pdwEntriesRead参数所指的变数项目数目。其馀可用的门类(包涵那些被传回的项目)总数会储存在pdwTotalEntries参数所指的变数中。

NET_API_STATUS NetLocalGroupAddMembers(
    PCWSTR  pszServerName,
    PCWSTR  pszGroupName,
    DWORD       dwLevel,
    PBYTE       pbBuf,
    DWORD       dwTotalEntries);

NET_API_STATUS NetLocalGroupDelMembers(
    PCWSTR  pszServerName,
    PCWSTR  pszGroupName,
    DWORD       dwLevel,
    PBYTE       pbBuf,
    DWORD       dwTotalEntries);

NTSTATUS LsaOpenPolicy(
    PLSA_UNICODE_STRING plsastrSystemName,
    PLSA_OBJECT_ATTRIBUTES  pObjectAttributes,
    ACCESS_MASK DesiredAccess,
    PLSA_HANDLE pPolicyHandle);
程序名称 显示的名称 标头档
SeAssignPrimaryTokenPrivilege
SE_ASSIGNPRIMARYTOKEN_NAME
取代一个程序层级的 (处理程序等级的token) WinNT.h
SeAuditPrivilege
SE_AUDIT_NAME
产生安全性稽核 WinNT.h
SeBackupPrivilege
SE_BACKUP_NAME
备份文件及目录 WinNT.h
SeChangeNotifyPrivilege
SE_CHANGE_NOTIFY_NAME
略过往返检查 WinNT.h
SeCreatePagefilePrivilege
SE_CREATE_PAGEFILE_NAME
建立一个分页档 WinNT.h
SeCreatePermanentPrivilege
SE_CREATE_PERMANENT_NAME
建立永久分享的物件 WinNT.h
SeCreateTokenPrivilege
SE_CREATE_TOKEN_NAME
建立一个token物件 WinNT.h
SeDebugPrivilege
SE_DEBUG_NAME
除错程序 WinNT.h
SeEnableDelegationPrivilege
SE_ENABLE_DELEGATION_NAME
信任委派的电脑及使用者帐户 WinNT.h
SeIncreaseBasePriorityPrivilege
SE_INC_BASE_PRIORITY_NAME
增加优先权清单 WinNT.h
SeIncreaseQuotaPrivilege
SE_INCREASE_QUOTA_NAME
增加配额 WinNT.h
SeLoadDriverPrivilege
SE_LOAD_DRIVER_NAME
载入及卸载设备驱动程序 WinNT.h
SeLockMemoryPrivilege
SE_LOCK_MEMORY_NAME
锁住在内存中的页面 WinNT.h
SeMachineAccountPrivilege
SE_MACHINE_ACCOUNT_NAME
增加工作站到网域 WinNT.h
SeProfileSingleProcessPrivilege
SE_PROF_SINGLE_PROCESS_NAME
设定档个别的程序 WinNT.h
SeRemoteShutdownPrivilege
SE_REMOTE_SHUTDOWN_NAME
强迫从远端系统关机 WinNT.h
SeRestorePrivilege E
SE_RESTORE_NAM
回存文件及目录 WinNT.h
SeSecurityPrivilege
SE_SECURITY_NAME
管理稽核及安全性日志 WinNT.h
SeShutdownPrivilege
SE_SHUTDOWN_NAME
关闭系统 WinNT.h
SeSyncAgentPrivilege
SE_SYNC_AGENT_NAME
使目录服务资料同步 WinNT.h
SeSystemEnvironmentPrivilege
SE_SYSTEM_ENVIRONMENT_NAME
修改韧体环境值 WinNT.h
SeSystemProfilePrivilege
SE_SYSTEM_PROFILE_NAME
设定档系统效能 WinNT.h
SeSystemtimePrivilege
SE_SYSTEMTIME_NAME
改变系统时间 WinNT.h
SeTakeOwnershipPrivilege
SE_TAKE_OWNERSHIP_NAME
取得文件或其他物件的所有权 WinNT.h
SeTcbPrivilege
SE_TCB_NAME
扮演操作系统的一部份 WinNT.h
SeUndockPrivilege
SE_UNDOCK_NAME
从母机中移除电脑 WinNT.h
SeUnsolicitedInputPrivilege
SE_UNSOLICITED_INPUT_NAME
接收未经请求的设备输入 WinNT.h
SeBatchLogonRight
SE_BATCH_LOGON_NAME
以批次工作的身分登入 NTSecAPI.h
SeDenyBatchLogonRight
SE_DENY_BATCH_LOGON_NAME
拒绝批次工作的登入 NTSecAPI.h
SeDenyInteractiveLogonRight
SE_DENY_INTERACTIVE_LOGON_NAME
拒绝本机登入 NTSecAPI.h
SeDenyNetworkLogonRight
SE_DENY_NETWORK_LOGON_NAME
拒绝从网路存取这台电脑 NTSecAPI.h
SeDenyServiceLogonRight
SE_DENY_SERVICE_LOGON_NAME
拒绝以服务的身分登入 NTSecAPI.h
SeInteractiveLogonRight
SE_INTERACTIVE_LOGON_NAME
本机登入 NTSecAPI.h
SeNetworkLogonRight
SE_NETWORK_LOGON_NAME
从网路存取这台电脑 NTSecAPI.h
SeServiceLogonRight SE_
SERVICE_LOGON_NAME
以服务的身分登入 NTSecAPI.h

率先,您要有Windows
两千系统的管理权限(大概,就网域系统而言是帐户操小编的权位)。借使须求的话,安装2个以你为领导者的Windows
3000种类。

使用NetLocalGroupGetMembers函数
 

如您所观望的,那么些简单的函数只利用系统名称及使用者帐户的称谓作为参数。PszServerName参数可以为NULL,表示本机系统。如果这些函数执行成功,将会流传NE奥迪Q5卡宴_Success。


过1个称作群组原则的逻辑层来通晓Windows
三千中关于权限之MMC嵌入式管理单元介面是最首要的。群组原则是个复杂的宗旨,可以独自写成好几章。那一个委派权限的点子是从Windows
NT直接委派权限给信任成员的使用者管理员工具中分离出来的法门。透过呼叫系统函数,直接的权限操作照旧是大概的;可是,Windows
3000提供的使用者介面唯有用到群组原则。
使用MMC嵌入式管理单元,您可以体会委派使用者权限的历程。别的,委派使用者权限恐怕会被网域群组原则完全地遮盖。您可以行使直接管理权限的工具来拍卖
那些地下的难题。


PSID BuildEveryoneSid(){
    SID_IDENTIFIER_AUTHORITY auth = SECURITY_WORLD_SID_AUTHORITY;
    PSID pSID = NULL;
    BOOL fSuccess = AllocateAndInitializeSid(&auth, 1,
        SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSID);
    return(fSuccess ? pSID : NULL);
}

这几个函数先河看起来恐怕有点奇怪,因为那几个素材型态在此外的Win32函数中不常被使用,所以让大家2个贰个地检查。

最终,在进入安排性管理信任成员的议论以前,小编应当提到在本章稍后所描述的TrusteeMan范例应用程序,该范例程序能被用来确立及删除使用者和群组帐
户,并委派权限给信任成员帐户的工具。纵然这几个范例是个教学用的工具,但它也对Windows
两千所包含的MMC嵌入式管理单元提供二个简单易行的抉择。

 图9-2 TrusteeMan范例应用程序之使用者介面


深信不疑成员帐户名称及二进制SIDs之间的转移是您平日要求履行的实用工作,系统提供七个可以推行这几个干活儿的函数,这个函数有让人怀疑的名称,所以那是回忆哪个是哪位的特等方法:


典型的商号环境里,系统官员或帐户操作者可以在系统上确立使用者及群组帐户。在这种环境下执行的服务器软件可以和已启用的安全性感知以及使用者识别一起
运作,不用直接建立或管理信任成员帐户。那一个软件仅假定那么些帐户已经由另二个实体建立,那样的话,许多的劳务开发人员就如都不用布署性地创制信任成员帐
户。

说明


统经由被分派的缓冲器传回信任成员资讯到你的软件中,以及经过ppvEnumerationBuffer参数传回它的目标。即便那几个参数被定义成
PVOID目标,您照旧应该传递目的的位址给PLSA_ENUMERATION_INFO奇骏MATION类型之变数,因为系统将以
LSA_ENUMERATION_INFOEvoqueMATION结构阵列的不二法门传回资讯。假诺Windows开发人士定义了
LsaEnumerateAccountsWithUserRight取得正确类型的目标来说,景况将会更好,可是他们接纳须求二个PVOID目标作为替
代,所以您必须自行将那些参数转型。

现行您对系统信任成员帐户的二进制识别资料已有彻底的认识,所以你曾经颇具富有本章此前叙述之利用本机群组操作成员方法的必不可少资讯。让大家开头谈论指派及移除信任成员的权限。

若是你的软件须求为信任成员找出帐户名称,在它曾经具有二进制的SID时应当运用LookupAccountSid函数:

撷取信任成员的帐户名称
 

NET_API_STATUS NetLocalGroupDel(
    PCWSTR pszServerName,
    PCWSTR pszGroupname);
void PrintLocalGroupMembers(WCHAR *pszGroup) {
    ULONG_PTR lResume = 0;
    ULONG lTotal = 0;
    ULONG lReturned = 0;
    ULONG lIndex = 0;
    NET_API_STATUS netStatus;
    LOCALGROUP_MEMBERS_INFO_3* pinfoMembers;

    do {
        netStatus = NetLocalGroupGetMembers(NULL, pszGroup, 3,
            (PBYTE*) &pinfoMembers, MAX_PREFERRED_LENGTH,
            &lReturned, &lTotal, &lResume);
        if ((netStatus == ERROR_MORE_DATA) ||
            (netStatus == NERR_Success)) {
            for (lIndex = 0; lIndex < lReturned; lIndex++) {
                wprintf(L"%s/n",
                    pinfoMembers[lIndex].lgrmi3_domainandname);
            }
            NetApiBufferFree(pinfoMembers);
        }
    }while (netStatus == ERROR_MORE_DATA);
}


由LSA_UNICODE_STENVISIONING结构之Buffer成员指向的字串没有显明地定义以0作了结。您可以采纳用0来终止字串,但必须鲜明在字串长度的
计算中一向不包含无效的最后。请牢记当系统传回LSA_UNICODE_STENCOREING给软件时,它无法仰望经由Buffer成员指向的字串以0截止。

NTSTATUS LsaEnumerateAccountRights(
    LSA_HANDLE  hPolicy,
    PSID        psidTrustee,
    PLSA_UNICODE_STRING*    pplsastrUserRights,
    PULONG  plCountOfRights);
BOOL fRet = LookupAccountName(NULL, "JClark//JClark", 
    &sid, &dwSizeSid, szBuffer, &dwSizeBuf, &use);


列中成分的数量被传回到CountReturned指向的变数中,为LsaEnumerateAccountsWithUserRight的末尾3个参
数。在扩散阵列中的SIDs,经由传递SID到LookupAccountSid中,可被用来爆发信任成员名称。当你做到
LsaEnumerateAccountsWithUserRight传回的缓冲器后,应该要将它的目的传递给LsaFreeMemory。

NTSTATUS LsaRemoveAccountRights(
    LSA_HANDLE  hPolicy,
    PSID        psidTrustee,
    BOOLEAN fAllRights,
    PLSA_UNICODE_STRING plsastrUserRights,
    ULONG       lCountOfRights);

文字与二进制SID的更换
 

那就是说,您可以利用如下的函数来删除使用者帐户:

ADSI
套件也可被用来建立使用者帐户。就好像群组物件一般,可以在任何的容器物件中成立使用者物件。您可以利用IADsContainer介面的Create成员
建立3个使用者物件。一旦确立了那个物件,便得以运用QueryInterface方法,以拿到IADsUser介面的目的,它可被用来更是地保管您的
新使用者物件。有关这几个核心的底细,请参阅《Platform SDK》文件。


应该传递须要作为ppbBuf参数之结构类型目的变数的位址。根据NetUserEnum及NetLocalGroupEnum是或不是被应用的事态,系统将
指派二个缓冲器以具有USE奥迪Q7_INFO_* 或LOCALGROUP_INFO_*
结构的阵列,ppbBuf是三个缓冲器位址的目的。那几个缓冲器将是函数列举的帐户。记得如同NetUserGetInfo一样,必须呼叫
NetApiBufferFree来刑释解教系统指派给您的缓冲器。

建立SIDs
 

有二种你应该掌握的权能文字代表。这个文字代表即是Windows使用者介面中突显的易记名称以及软件使用的先后名称。各个程序名称都定义在SDK的标头档中。

 表9-3 USER_INFO_1的成员
 图9-1 显示在群组原则嵌入式管理单元中的权限画面
BOOL CopySid(
    DWORD   dwDestinationSidLength,
    PSID    pSidDestination,
    PSID    pSidSource);

你可以传递MAX_PREFERRED_LENGTH给dwPref马克斯Len参数,可是无论是拔取何种方法,您都必须注意经由pdwEntriesRead参数及pdwTotalEntries参数传回的值,以显然全体或者的项目皆被流传。

当Net函数将关于信任成员的新闻回传到软件时,它将选派四个缓冲器给你。如前所述,Net函数要求你传递目的位址到转型成PBYTE*
的适度结构类型中。当您用完系统传回的缓冲器后,应该将它传递到NetApiBufferFree,以释放缓冲器。那一个函数定义如下:

在那个时候谈到SID,是因为它确实与倚重成员帐户的解构某个关系。即使Net函数能让你处理信任成员帐户的称谓,而其馀的连串超过四分之二皆忽视与信任成员帐户关联的名称。取而代之的是系统会接纳与帐户关联的SID二进制值来辨别有些帐户。那与摧毁信任成员帐户有怎样关系啊?

您有时候才会看到那几个SIDs。熟知那么些连串内建的看重成员是好的,SID自身的材质结构定义如下:

为了实用地编写具有安全性的软件,精晓Windows
三千中什么保管安全性及谙习一些有扶持的工具是不可或缺的。

当你使用TrusteeMan建立使用者帐户时,应用程序会选择「Pass三千」作为你新帐户的密码。这一个密码简化了使用者介面并汇总在关键的宗旨上。如若你是系统的老总,您可以行使MMC嵌入式管理单元为使用者帐户手动地设定密码。

说明

BOOL AllocateAndInitializeSid(
    PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
    BYTE    nSubAuthorityCount,
    DWORD   dwSubAuthority0,
    DWORD   dwSubAuthority1,
    DWORD   dwSubAuthority2,
    DWORD   dwSubAuthority3,
    DWORD   dwSubAuthority4,
    DWORD   dwSubAuthority5,
    DWORD   dwSubAuthority6,
    DWORD   dwSubAuthority7,
    PSID*   ppSid);

TrusteeMan范例应用程序
 

你可以接纳跟NetLocalGroupSetMembers一样的法门接纳这么些函数。关于范例的部份,请参阅本章稍后叙述的 

说明

你也可以应用ADSI物件来列举及删除使用者及群组帐户,并获取以及设定使用者及群组资讯。有关IADsUser及IADsGroup介面和用来搜寻及列举IdirectorySearch介面的商讨部份,请参阅《Platform
SDK》文件。

在切换工具及商量识别信任成员帐户、SIDs的系统结构此前,小编想要谈论如何摧毁使用者及群组帐户的部份,以富含使用者及群组管理的座谈。



了有宏图地指派权限,您要求熟习一组称为LSA的函数。LSA代表Local Security
Authority,它处理地方机械上的使用者登入及表明。LSA函数可用来作一些与本章有关之权能指派工作。使用LSA函数的首先步是撷取原则物件的
handle。原则物件代表你将履行帐户管理函数的连串。为了获取原则物件的handle,您必须呼叫LsaOpenPolicy。



统也为了赢得及设定已被确立之使用者或群组帐户的音讯而提供Net函数。您可以看看那几个函数的呼叫格式与NetGroupAdd及NetUserAdd卓殊类似。要获取及设定使用者帐户资讯,可以应用NetUserGetInfo及NetUserSetInfo函数,其原型如下:

从Windows
NT
3.1至今,SID结构的纠正版本号码已经是1;然则,结构是唯恐会转移的,大家将来有那么一天会看到2的修改版本。授权单位「号码」指出SID在哪些授权单位之下发生-即什么「实体」拥有SID及管制它的帐户。表9-6提供今后有帮忙之授权单位清单。

  • Net函数使用Net+[深信不疑成员类型]+[施行的动作]格式为稳定的命名。例如:NetUserAdd、NetLocalGroupGetInfo以及NetUserSetGroups。
     
  • Net函数只支援Unicode字串。若是你的专案以ANSI建立以来,在传递字串到Net函数前必须为各种字串缓冲器制作Unicode副本。(当在编写Windows
    三千的服务器软件时,那是另三个平常利用Unicode的因由。)
     
  • Net函数经由系统及帐户名称来分辨信任成员帐户。如若你在远端机器上有所充裕的权能,便可以在远端系统上应用那么些函数管理信任成员。
     
  • Net函数实作了一组可用来向软件回报信任成员资讯或是被软件用来设定信任成员资讯的构造。因为牵涉到许多构造的部份,所以这些Net函数的特色大概会令人感觉到疑惑,可是询问后会卓殊合理且有用。
     

PszServerName
及pszGroupName参数提示您正在设定成员的系统名称及本机群组。DwLevel参数提议您想要使用的
LOCALGROUP_MEMBERS_INFO_*
结构集level。您可以传递0或3,以独家代表LOCALGROUP_MEMBERS_INFO_0或
LOCALGROUP_MEMBERS_INFO_3,两者在稍早都已定义过。那意味着你可以采取使用信任成员帐户名称字串或是SIDs来设定成员。

当你登入一台执行Windows的机械,常常会输入使用者名称及密码。使用者名称会向系统确认那个代表你的帐号。像这么的帐号日常被称呼 使用者帐户 

 表9-6 SID授权单位

只要您成就了此函数传回的SID后,必须将它的目的传递到FreeSid函数。您可以自由地修改这些函数,并经过改变auth变数的上马值,以及传递区其余大切诺基ID到AllocateAndInitializeSid,以树立另三个SID。

这一个函数很相近,但有一些差异值得注意。从LOCALGROUP_INFO_*
结构集中传回结构到NetLocalGroupEnum的同时,将会从USE凯雷德_INFO_*
结构集传回结构到NetUserEnum函数。其它,NetUserEnum可让您指定筛选标准,以调减使用者帐户清单传回的限制。传递0给
NetUserEnum的filter参数,表示从没筛选标准,所以任何的帐户类型都会被传出。您日常要传递FILTE兰德酷路泽_NORMAL_ACCOUNT
给filter参数;不过,您也能够传递表9-5中列出的其余二个值。

PszSystemName参数是系统名称,您想要在那些序列上询问pszAccountName参数中所钦命的名称。您可以传递NULL给pszSystemName参数,以指出本地机械。

BOOL PrintTrusteePrivs(LSA_HANDLE hPolicy, PSID psid) {
    BOOL fSuccess = FALSE;
    WCHAR szTempPrivBuf[256];
    WCHAR szPrivDispBuf[1024];
    PLSA_UNICODE_STRING plsastrPrivs = NULL;

    __try {
        // 撷取SID的权限阵列
        ULONG lCount = 0;
        NTSTATUS ntStatus = LsaEnumerateAccountRights(hPolicy, psid,
            &plsastrPrivs, &lCount);
        ULONG lErr = LsaNtStatusToWinError(ntStatus);
        if (lErr != ERROR_SUCCESS) {
            plsastrPrivs = NULL;
            __leave;
        }

        ULONG lDispLen = 0;
        ULONG lDispLang = 0;

        for (ULONG lIndex = 0;lIndex < lCount; lIndex++) {
            // 确保0的结束
            lstrcpyn(szTempPrivBuf,
                plsastrPrivs[lIndex].Buffer, plsastrPrivs[lIndex].Length);
            szTempPrivBuf[plsastrPrivs[lIndex].Length] == 0;
            wprintf(L"Programmatic Name: %s/n", szTempPrivBuf);
            // 转译成显示的名称

            lDispLen = 1024; // Size of static Display buffer
            if (LookupPrivilegeDisplayName(NULL, szTempPrivBuf,
                szPrivDispBuf, &lDispLen, &lDispLang))
                wprintf(L"Display Name: %s/n/n", szPrivDispBuf);
        }

        fSuccess = TRUE;
    }
    __finally {
        if (plsastrPrivs) LsaFreeMemory(plsastrPrivs);
    }
    return(fSuccess);
}
NET_API_STATUS NetLocalGroupGetInfo(
    PCWSTR pservername,
    PCWSTR groupname,
    DWORD dwLevel,
    PBYTE *ppbBuf);

NET_API_STATUS NetLocalGroupSetInfo(
    PCWSTR servername,
    PCWSTR groupname,
    DWORD dwLevel,
    PBYTE pbBuf,
    PDWORD pdwParmErr);

Net
API为除去群组实作了八个好像的函数,其定义如下:

说明

说明

typedef struct _LOCALGROUP_INFO_0 {
    PWSTR lgrpi0_name;
}LOCALGROUP_INFO_0;

typedef struct _LOCALGROUP_INFO_1 { 
PWSTR lgrpi0_name; 
PWSTR lgrpi0_comment;
}LOCALGROUP_INFO_1;
 表9-4 与USER_INFO_1有关的标记

全数一定权限的深信成员
 


说明

BOOL LookupPrivilegeDisplayName(
    PCTSTR  pszSystemName,
    PCTSTR  pszName,
    PTSTR       pszDisplayName,
    PDWORD  cbDisplayName,
    PDWORD  pLanguageId);


不过,在呼叫LsaAddAccountRights在此以前,您应该创建二个LSA_UNICODE_
STPAJEROING结构的阵列,并累加你想要信任成员具有的权能名称。传递那一个阵列的目的作为LsaAddAccountRights的
plsastrUserRights参数值。最终,传递阵列中成分的数码给最终叁个lCountOfRights参数。


下的多少个范例函数,表达了怎么采用NetUserSetInfo及NetUserGetInfo来设定和取得使用者帐户资讯的章程。第叁个函数呈现怎么为
使用者帐户设定密码;第三个函数则表达如何撷取使用者的注释栏位。这么些函数使用的尺度得以为使用者帐户取得或设定任何有效的音讯。


了回传filter参数及结构外,NetUserEnum及NetLocalGroupEnum的接纳是完全相同的。就如大家在此之前看看的函数一
样,pszServerName参数提出我们想要列举信任成员帐户的系统。dwLevel参数提出与ppbBuf参数相关的LOCALGROUP_
INFO_* 或USER_INFO_* 结构的本子。

Net函数的其中三个特点是以相同的主意表现。因为那一个原因,才可以在不涵盖API命名集的每一个单一函数的情事下,提供问询那个函数之通用规则的故事情节:

复制SIDs
 


应该认识这个参数的用途,值得一提的是,第②个PidentifierAuthority参数,该参数为你正在建立的SID识别授权单位的值。
PidentifierAuthority参数是SID_IDENTIFIER_AUTHOCR-VITY的品种,被定义为陆个位元组的阵列。那看起来某些棘
手,但值得庆幸的是《Platform
SDK》文件定义了这几个使得的SID授权单位。您应该传递表9-6中显示的其中叁个值,例如SECU翼虎ITY_NT_AUTHORITY。

治本群组成员
 

建立信任成员的说辞
 

SID的格式平常是:S-PRADO-I-S-S…


应该提示出呼叫函数所传回的缓冲器最大容积,以位元组来传递那一个尺寸以作为dwPref马克斯Len参数。假设你要系统尽大概指派更大的缓冲器,可以传递
MAX_PREFERRED_LENGTH。那样的话,系统常常会独家呼叫函数来成功列举型别(Enumeration)的动作。

以下有多少个您要精通的广泛工作:



typedef struct _USER_INFO_1 {
    PWSTR usri1_name;
    PWSTR usri1_password;
    DWORD usri1_password_age;
    DWORD usri1_priv;
    PWSTR usri1_home_dir;
    PWSTR usri1_comment;
    DWORD usri1_flags;
    PWSTR usri1_script_path;
}USER_INFO_1 ;
typedef struct _USER_INFO_3 {
    PWSTR usri3_name;
    PWSTR usri3_password;
    DWORD usri3_password_age;
    DWORD usri3_priv;
    PWSTR usri3_home_dir;
    PWSTR usri3_comment;
    DWORD usri3_flags;
    PWSTR usri3_script_path;
    DWORD usri3_auth_flags;
    PWSTR usri3_full_name;
    PWSTR usri3_usr_comment;
    PWSTR usri3_parms;
    PWSTR usri3_workstations;
    DWORD usri3_last_logon;
    DWORD usri3_last_logoff;
    DWORD usri3_acct_expires;
    DWORD usri3_max_storage;
    DWORD usri3_units_per_week;
    PBYTE usri3_logon_hours;
    DWORD usri3_bad_pw_count;
    DWORD usri3_num_logons;
    PWSTR usri3_logon_server;
    DWORD usri3_country_code;
    DWORD usri3_code_page;
    DWORD usri3_user_id;
    DWORD usri3_primary_group_id;
    PWSTR usri3_profile;
    PWSTR usri3_home_dir_drive;
    DWORD usri3_password_expired;
}USER_INFO_3 ;

设定使用者资讯时,您应该利用1个只含有您想设定的消息或接受NULL,就好像叁个成员值的布局level。举例来说,仅设定使用者帐户的密码可以运用USER_INFO_1003布局类型,因为它只为使用者的新密码包罗3个成员。



注意到NetUserAdd与NetLocalGroupAdd的参数清单完全相同,差距在于传递到pbBuf参数的构造类型。您可以传递目标到
level 壹 、2或3的USE宝马7系_INFO_*
结构,以创制新的使用者。那里是USECR-V_INFO_1(可以与NetUserAdd一起利用的最简易结构)及USEXC90_INFO_3(您可以拔取的最广
泛结构)的定义。

  • 将三个使用者或群组名称转换到SID。
     
  • 为信任成员将SID转换到文字名称。
     
  • 千帆竞发建立一个明显的SID。这几个SID存在全数的种类中,而且提议如Guest或伊芙rybody帐户。
     
  • 复制SID结构。
     
  • 最后,来回地更换代表SID的二进制数值及字串。
     

CreateUser(NULL, L"MrMan", L"HowDoYouDo");
成员 叙述 如果ERROR_INVALID_ PARAMETER,pdwParmErr 的传回值
usri1_name 指向一个包含建立使用者帐户的Unicode使用者名称缓冲器。此成员必须包含一个有效的指标,否则NetUserAdd将传回ERROR_INVALID_PARAMETER。 USER_NAME_PARMNUM
usri1_password 指向一个包含建立使用者帐户的Unicode密码缓冲器。密码限制为14个字元而且必须符合您正在新增使用者帐户之系统提出的规则。 USER_PASSWORD_PARMNUM
usri1_password_age NetUserAdd忽略此成员。 USER_PASSWORD_AGE_PARMNUM
usri1_priv 当您在建立使用者时,这个成员的值必须设定为USER_PRIV_USER。任何其他的值将会导致NetUserAdd传回ERROR_INVALID_PARAMETER。 USER_PRIV_PARMNUM
usri1_home_dir 使用者可以为其帐户定义主目录。假如您想要联合主目录与新的使用者,此成员应该要指向一个包含Unicode字串目录路径的缓冲器。您可以指派NULL给这个成员。 USER_HOME_DIR_PARMNUM
usri1_comment 这个成员指向一个包含新使用者的Unicode注解缓冲器。假如您不想要结合注解与新的使用者帐户,可以指派NULL给这个成员。 USER_COMMENT_PARMNUM
usri1_flags 这个成员可以结合指示新使用者帐户功能的标记(请见 表9-4 )。 USER_FLAGS_PARMNUM
usri1_script_path 当使用者登入系统时,系统将执行与您的使用者结合之 .exe、.cmd或.bat档。您可以使用此成员来设定登入指令档的路径。 USER_SCRIPT_PATH_PARMNUM
NET_API_STATUS NetLocalGroupEnum(
    PCWSTR pszServerName,
    DWORD dwLevel,
    PBYTE* ppbBuf,
    DWORD dwPrefMaxLen,
    PDWORD pdwEntriesRead,
    PDWORD pdwTotalEntries,
    PDWORD_PTR pdwResumeHandle);

NET_API_STATUS NetUserEnum(
    PCWSTR pszServerName,
    DWORD dwLevel,
    DWORD dwFilter,
    PBYTE* ppbBuf,
    DWORD dwPrefMaxLen,
    PDWORD pdwEntriesRead,
    PDWORD pdwTotalEntries,
    PDWORD_PTR pdwResumeHandle);
 表9-10 权限及帐户权利

治本信任成员帐户
 


 

倘使已经成功地扩散资料,但是有更多帐户被列举时,列举函数将传回E奇骏ROTucson_MORE_DATA。当最终的可用帐户被传播后,列举函数将回传NE昂科雷Tiggo_
Success。

BOOL ConvertSidToStringSid(
    PSID        pSid,
    PTSTR*  StringSid);

BOOL ConvertStringSidToSid(
    PCTSTR  StringSid,
    PSID*       ppSid);
NTSTATUS LsaClose(LSA_HANDLE hObjectHandle);

如你所见,呼叫那几个函数与呼叫取得及设定使用者帐户资讯的函数大致完全相同,差异在于你要拍卖的群组资讯及以前切磋的LOCALGROUP_INFO_*
结构。

说明

Windows开发人员实作了群组帐户,以管理复杂性的东西。 群组帐户 富含一组可以是使用者帐户或是通用群组帐户的积极分子。群组帐户维持着与使用者帐户相似的情报,例如系统权限及SID。只要经过将使用者帐户指派到群组帐户,可在二个地点管理一组使用者安全性而无需为各种使用者作调整。

权力是指派权利给科普系统分枝的相信成员(相对之下,指派给信任成员的存取权利则定义允许存取系统中的特定物件)。权限的事例包含登入本机的权利、备份文件与目录,以及关闭系统。

  1. 公共场合的SID名称
  2. 在地头机械上内建及定义的帐户
  3. 本条连串的根本网域
  4. 受看重的网域
  5. 在网域树系中的任三个网域

你应该传递SID_NAME_USE变数的位址给peUse,以从系统接到拔取的SID。有关SID_NAME_USE之列举型别类型的辨证,请参阅 

typedef struct _LSA_UNICODE_STRING {
    USHORT  Length;
    USHORT  MaximumLength;
    PWSTR       Buffer;
}LSA_UNICODE_STRING

说明

说明

您或者会问为何老是拔取范围「Net*Enum」传回的缓冲器大小,从而必须数十二回呼唤函数。那里有多少个原因:不保障少数的帐户,而恢宏的帐户只怕会压倒系统指派的最大缓冲器大小。其余,假诺罗列型别是个冗长的主次,您只怕会想要应用程序定期地打消对它的操纵。

  • 设若你有3个相信成员的帐户名称,不过却须要一个二进制的SID,此时你可以呼叫LookupAccountName。
     
  • 相反地,若是你有一个二进制的SID,然而却须要1个相信成员的帐户名称时,您可以呼叫LookupAccountSid。
     
NET_API_STATUS NetUserGetLocalGroups(
    PCWSTR  pszServerName,
    PCWSTR  pszUsername,
    DWORD   dwLevel,
    DWORD   dwFlags,
    PBYTE*  ppbBuf,
    DWORD   dwPrefMaxLen,
    PDWORD  pdwEntriesRead,
    PDWORD  pdwTotalEntries);

 范例: S-1-5-11

使用NetUserGetLocalGroups函数
 

typedef struct _SID {
    BYTE Revision;
    BYTE SubAuthorityCount;
    SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
    DWORD SubAuthority[ANYSIZE_ARRAY];
}SID;


用性是覆写TrusteeMan范例应用程序的靶子。因为以广大方面来说,必须深究与通晓安全性的故事情节,而二个可用的工具能支援你浏览系统的特色。这些范
例应用程序可让您尽情地确立使用者及群组帐户。也可让您修改群组的分子,并授予及否决权限给系统上的亲信成员帐户。您可以输入要利用的处理器名称且在富有足够义务的其余系统上管理信任成员。

DWORD GetLengthSid(PSID pSid);

Psid
是个指向你想撷取之与帐户名称一致的未来SID目标。那几个SID可以是你建立的,或是系统事先在token以及其余协会中传回的其余1个使得SID。
PszName及pszReferencedDomainName应该本着你提供用来从系统接受信任成员的名号及它的网域名称缓冲器。

在这里:

树立独立的软件来列举权限给信任成员帐户的意况是稀少的。可是,大致任何三个创设信任成员帐户的软件皆必须从帐户中打发(或移除)义务。幸运的是,LSA提供了八个大约的函数来实施那一个任务。首先,LsaAddAccountRights用来将权限授予信任成员:

因为安全性极度看重于使用者身份辨其余确立和治本,所以我们要起来商量Windows
三千之信任成员的运用。

SIDs
对Windows
2000安全性来说是不足缺失的。SIDs在本章已怀有提及,也继续的章节也将再一次出现,而方今正是详细认识SIDs的时候。到近来甘休,您了然SIDs
是高枕无忧识别项,它向系统识别信任成员的成色。逐个SID是三个意味着相信成员的绝无仅有二进制数值。

请小心NetUserGetInfo的部份,其pbBuf参数已经被改成缓冲器的目标位址。就像先前所指出的,那是因为系统实际上会指派被必要的构造给您,并经过ppbBuf参数在变数中传出三个针对新缓冲器的目的。

Microsoft
的开发者现已做到Microsoft Windows
3000安全性特色的规划工作,那一个安全性特色比一大半人所习惯的环境更复杂且更有弹性。事实上,若加上适量的治本和软件开发,Windows
2000是明天开始进且安全的操作环境之一。不过,由于那样复杂而暴发的大方细节以及错综复杂难懂之处,将使得对Windows安全性没经历的大多数开发者感
到气馁。就本书的读者和自作者而言,这一个安全性的宗旨即使表示一个挑战,但应付挑衅之后报偿将是拥有安全性的伺服端软件和实在的引以自豪。

使用者帐户及群组帐户是称呼 信任成员 的广阔系列成员。因为这一章重点是座谈使用者及群组帐户,所以唯有详细指明,否则 信任成员  信任成员帐户 那八个术语即表示使用者及群组帐户。

NET_API_STATUS NetLocalGroupSetMembers(
    PCWSTR  pszServerName,
    PCWSTR  pszGroupName,
    DWORD       dwLevel,
    PBYTE       pbBuf,
    DWORD       dwTotalEntries);

提出你花些时日看TrusteeMan范例应用程序,以纯熟Windows
3000的深信成员管理的运营方式。本书其馀的章节皆假定您会利用TrusteeMan、MMC嵌入式管理单元,或任何管理使用者帐户及派出权限的工具。


在继承探究前,先表达什么是所谓的「文字SID」。我不切磋代表相信成员帐户名称的字串;而谈论代表二进制SID结构的字串。


为止LsaRemoveAccountRights的座谈前,我应该指出从帐户中移除全数职责的相干细节。《Platform
SDK》文件中验证假若你传递TRUE给fAllRights参数的话,系统将会从帐户中移除全数的权杖,然后再从系统中删去这一个帐户;可是,那惟有从有些观点来说才是合情合理的。各个执行Windows
两千的连串必须保持三个帐户权限项目标本机资料库(内部实作技术就像是本机帐户),尽管信任成员依靠在另一台机械上,例如网域控制站。
LsaRemoveAccountRights函数不会从主帐户的体系中剔除信任成员帐户(即便是本土帐户);它只从它的本机资料库中去除帐户权限项目。

 S 是另一个附带授权单位。在SID中得以有任一的次要授权单位数量。


深信不疑成员名称及二进制的SID转换
 

LSA_UNICODE_STRING lsastrPrivs[2] = { 0 };
lsastrPrivs[0].Buffer = SE_INTERACTIVE_LOGON_NAME;
lsastrPrivs[0].Length =
    lstrlen(lsastrPrivs[0].Buffer) * sizeof(WCHAR);
lsastrPrivs[0].MaximumLength = lsastrPrivs[0].Length + sizeof(WCHAR);
lsastrPrivs[1].Buffer = SE_TCB_NAME;
lsastrPrivs[1].Length =
    lstrlen(lsastrPrivs[1].Buffer) * sizeof(WCHAR);
lsastrPrivs[1].MaximumLength = lsastrPrivs[1].Length + sizeof(WCHAR);
NTSTATUS ntStatus = LsaAddAccountRights(hPolicy, psid,
    lsastrPrivs, 2);
ULONG lErr = LsaNtStatusToWinError(ntStatus);

在「安全性」那个主旨下,Windows
两千有过多适宜的天性,大部份将在本书的这一篇谈论。本书将Windows安全性相关的风味区分为一或更三个如下所述的标题:

NET_API_STATUS NetUserAdd(
    PCWSTR pstrServername,
    DWORD dwLevel,
    PBYTE pbBuf,
    PDWORD pdwParmErr);

假诺还没准备好的话,以往也应有对Microsoft Management
Console(MMC)较为了然了。那几个应用程序会与系统同步安装,而且属于MMC.exe。MMC可让您执行管理的任务,从安装系统上的硬盘到监视事
件日志,包涵安全性管理皆是。实作MMC的每种函数如同被载入的嵌入式管理单元一般。有关使用MMC的更加多细节,请参阅Windows
2000 Help中的「使用Microsoft Management Console」核心。

具备的LSA函数皆传回NTSTATUS类型的值,您应该将以此值传递到LsaNtStatusToWinError中:

dwFlags
唯一有效的值即是LG_INCLUDE_INDIRECT,它提醒NetUserGetLocalGroups也应该传回为直接成员群组的使用者(由
pszUsername指出),可能是0,即指示函数应该只传回为直接成员群组的使用者。当pszUsername为通用群组或是网域群组的成员时-即本
机群组的成员,或然也会爆发直接成员的景观。

  •  身份鉴别及使用者内容 洋洋Windows安全性以使用者为根基,并且将它的力量使用在使用者识别以及保险「使用者内容」上。这一个力量可让系统控制使用者是还是不是被允许实施有个别动作。
     
  •  存取控制 存取控制与民用资料和文书及注册密钥等系列物件之安全性有关。Windows
    三千的存取控制特色应用在地方辨别和使用者内容上,其借助的水准在随后的五个章节中初露谈论时会更明亮。
     
  •  安全性连线 报道安全性是Windows
    2000的2个重中之重部份,包含资料加密和注明,两者皆确保您正在与叁个可相信的实业通信。
     

你应该时时检查NetLocalGroupAdd的传回值以保证系统已经不翼而飞NEPRADOHighlander_Success。否则表示系统在确立的新本机群组时举办破产。

那三个函数都会选派缓冲器给您,当您做到传回的素材时,释放缓冲器即是您的工作。可以行使LocalFree函数来刑满释放那一个函数传回的缓冲器。

typedef struct _LSA_ENUMERATION_INFORMATION {
    PSID Sid;
} LSA_ENUMERATION_INFORMATION;
用法
SidTypeUser 指示一个SID给使用者信任成员帐户
SidTypeGroup 指示一个SID给群组信任成员帐户
SidTypeDomain 指示一个代表网域物件的SID
SidTypeAlias 指示一个代表内建群组如管理者群组的SID
SidTypeWellKnownGroup 指示一个SID给众所周知的群组,例如Everyone群组
SidTypeDeletedAccount 指示一个SID给删除的帐户
SidTypeInvalid 指示一个无效的SID
SidTypeUnknown 指示一个未知的SID类型
SidTypeComputer 指示一个SID给网域上的电脑帐户

其一函数为权力取得系统名称及设计名称,然后再将易记的名目传到您提供的缓冲器中。

说明

另一个观看权限的章程是应用爱抚系统函数的辽源格局。举例来说,某个系统函数,例如LogonUser及InitiateSystemShutdown,须求呼叫的软件必须怀有十三分的权限,否则函数将会履行破产。

下一章我们将商量信任成员及康宁物件存取义务之间的涉及。第9一章将谈到您的服务器软件可用来代表客户端或任何随意接纳的亲信成员帐户行为的不二法门,您也将学会经由使用第③个信任成员帐户调整现存信任成员任务的方法。

BOOL CreateUser(PWSTR pszSystem, PWSTR pszName, PWSTR pszPassword){ 
    USER_INFO_1 userInfo ={0 };
    userInfo.usri1_name = pszName;
    userInfo.usri1_password = pszPassword;
    userInfo.usri1_priv = USER_PRIV_USER;

    NET_API_STATUS netStatus =
        NetUserAdd(pszSystem, 1, (PBYTE) &userInfo, NULL);
    return(netStatus == NERR_Success);
}
标记 叙述
UF_ACCOUNTDISABLE 建立一个无效的帐户。
UF_PASSWD_NOTREQD 建立一个不需要密码的帐户。对于要求所有帐户都需使用密码的系统或网域来说,可能是个适当的原则。
UF_PASSWD_CANT_CHANGE 建立一个使用者无法改变自己密码的帐户。系统管理者仍旧可以改变密码。
UF_DONT_EXPIRE_PASSWD 这个使用者的密码永不过期。
UF_NOT_DELEGATED 这个帐户不能被委派(有关委派的讨论,请参阅 第十一章 及 十二章 )。
UF_SMARTCARD_REQUIRED 要求使用者使用智慧卡登入这个新帐户。
UF_TRUSTED_FOR_DELEGATION 这个帐户可被委派(有关委派的讨论,请参阅 第十一章 及 十二章 )。

SID是个平安识别项以及向系统识别信任成员身分的结构。SID由四十九个位元值跟随二个三贰11人元之元件数字变数所构成。在文件中,SID经常会以S-LAND-I-S-S…格式表示(请参阅提要栏位)。

NET_API_STATUS NetUserDel(
    PCWSTR pszServerName,
    PCWSTR pszUsername);

LsaAddAccountRights函数忽略已信任成员具有的其他帐户义务或权限。不过,若阵列中的任何二个职分对系统来说为无用的称谓,则会错过意义。

以往您曾经通晓哪些获取LSA原则物件开启的handle,所以您已预加防范好起先管理连串上的权柄。

说到底几个参数是系统传回的值,在随着呼叫的罗列函数中得以被传送回系统,用来持续接收帐户资讯。在您最初呼叫列举函数时,应该将pdwResume
Handle参数所指的变数设定为0,并且不应有修改传回的值。

如你所见,那几个函数的称呼就是您曾经持有的音讯。

说明

ADSI
物件可让您的软件管理非网域控制站系统上的使用者及群组,但是因为那种系统不会维护Active
Directory,所以ADSI物件可以只经过Net函数传递。同样地,假如Net函数被用来扩展、移除或管理网域控制站上的亲信成员,他们将会活动地
使用ADSI物件去修改机器上的Active Directory。

根据您的要求来控制使用哪一组APIs。Active
Directory是个公司管理工具,就其本人而言,假使你的软件正在店铺环境中创建使用者帐户的话,应该利用Active
Directory的ADSI介面。但是,假设你的服务软件正在大概不是网域控制站的纯净服务器中建立本机的亲信成员帐户时,您会发现Net函数的运用变
得更简短且更直接。

利用NetLocalGroupSetMembers函数来设定本机群组的分子:


着这么些核心的揭穿,您将学会运用Windows环境中可得的各类技术,并以更有成立性的主意来界定及加强对物件的存取,假使须求的话,使你的服务器软件拥
有树立信任成员帐户的权力是很要紧的。在接下去的几章中研商到那一个核心时,小编将提议经由您的服务器软件建立唯一信任成员的贴切案例。


机使用者及MMC的群组嵌入式管理单元不但可让您建立使用者及群组,也得以追加成员到群组中。嵌入式管理单元还足以让您改变使用者的密码及规定部分适用于
信任成员的规则。理想上,本书的范例应由管理群组成员的使用者执行(即便你将发现建立权力较小的使用者及群组,才能使您感受到权力较小的艺术更易于学习到
东西)。

要呼叫LsaOpenPolicy,必须开端化LSA_UNICODE_STOdysseyING结构的实例并将它指向三个含有想操作之权能的Unicode字串系统名称。传递NULL以作为plsastrSystemName参数值,表示为当地机械。

其次个列举成员资讯的情势是撷取与个别群组关联的成员组。您应该采用NetLocalGroupGetMembers函数那样做:

列举系统权限的法门有二种:拿到一定信任成员所兼有的权柄清单,可能请求持有一定权限的相信成员清单。

举例来说,「S-1-1-0」是三个意味SID的文字SID,它的信任成员帐户名称是伊芙ryone。

TrusteeMan范例应用程序除了是个有效的工具外,它的原始码也提供了无数关于信任成员管理的Net及LSA函数成效参考。那些范例应用程序使用Net函数执行应用程序的左窗格或亲信成员侧,而利用LSA函数实作应用程序的权利则在右窗格或权限侧。

授权单位 定义
SECURITY_NULL_SID_ AUTHORITY 定义为0,这个授权单位被用来建立一个指出无效群组或没有人的SID。
SECURITY_WORLD_SID_ AUTHORITY 定义为1,这个授权单位被用来建立Everybody群组帐户。
SECURITY_LOCAL_SID_ AUTHORITY 定义为2,这个授权单位被用来建立众所周知的LOCAL群组帐户。
SECURITY_CREATOR_SID_ AUTHORITY 定义为3,这个授权单位与Creator Owner SID一起使用。
SECURITY_NON_UNIQUE_ AUTHORITY 定义为4,这个授权单位被用来产生不是唯一的SIDs。 第一个次要授权单位总是设为SECURITY_NT_NON_UNIQUE,定义为0x15。
SECURITY_NT_AUTHORITY 定义为5,这个授权单位由Windows 2000系统建立的使用者及群组帐户所使用。

到了那些时候,您应该早就知晓什么样举行那些关于SIDs的平常需要工作部份。但是,大家对SIDs的商讨还不完整,除非本人告诉您怎么着将代表SID的文字转换到以二进制表示,反之亦然。

因为您不可以鲜明系统可以指派多少的内存,所以无论是还是不是接纳MAX_PREFERRED_LENGTH值为缓冲器的长度,您的程序代码都应该要能处理须要数拾贰次呼唤列举函数的景况。

如上三个社团都包蕴三个群组名称字串的目标,LOCALGROUP_INFO_1结构还富含一个申明字串的附加目标。当您在创立群组时,那七个社团都得以动用。

DesiredAccess
参数被发布为ACCESS_MASK类型,对应到叁十一个人元无号整数。如果你要在系统上查看权限的情报,则须结合此探究后之范例中的
POLICY_VIEW_LOCAL_INFORMATION及POLICY_LOOKUP_NAMES。假若你要设定权限资讯,应该要整合
POLICY_CREATE_ACCOUNT存取标记。

途经把显明的奇骏ID与各自的授权单位结合,可以暴发大家所纯熟的SID。家喻户晓的SIDs识别系统识别使用者及被系统定义且经过逐个网路上安装Windows
3000的群组身分。表9-8列出有个别大家所熟识的SIDs及用法。


由LsaEnumerateAccountRights传回的阵列成分是LSA_UNICODE_ST科雷傲ING(在原先的〈LSA函数〉一节中定义)。每一种因素会针对多个包罗代表帐户职务的Unicode字串缓冲器,包含SeDebugPrivilege及
SeEnableDelegationPrivilege等值。您可以参考先前的 

 S 是个叁十一个人元数字,提示次要的授权单位,亦即我们所知的相持识别项或是奥德赛ID。

您应该传递SID_NAME_USE变数的位址以作为peUse参数。LookupAccount
Name将盛传三个经过peUse指向变数中的值,它提出已经流传给您的SID类型。表9-9列出那些只怕的值。

其一用来从信任成员帐户中移除权限的函数与LsaAddAccountRights极度相像,称LsaRemoveAccountRights,其函数原型如下:

PVOID FreeSid(PSID pSid);


为3个单纯的函数可以赢得或回传八个以上的系统定义结构类型,Net函数定义的花色为PBYTE,并基于你所传递的信息而方便的转型。假若你传递八个结构
给函数,则您应该传递此特定社团的目标,并将它转型为PBYTE。假使Net函数回传3个协会给您,此时函数将会预期为二个PBYTE的目标,您可以在稍
后将它转型为适当的构造类型。

借使您正在编制多个恐怕呼叫Net函数的原本模组,您的原有模组及专案必须履行多少个步骤。跟半数以上Win
32中的API函数差距的是,Net函数不需在Windows.h的标头档中宣布。由此,您必须在模组的一发端就含入Lm.h标头档。同样地,您必须将
NetApi32.lib文件加到与专案连结的程序库文件清单中。


第三个值得注意的参数为nSubAuthorityCount,提议您为SID请求的协助授权单位数量。即使系统现已定义那些值
SID_MAX_SUB_AUTHO奔驰G级ITIE为15,AllocateAndInitializeSid将只会以8或更少的附带授权单位来建立
SIDs。


必须传递一个与POLICY_LOOKUP_NAMES存取一起成立的怒放条件物件,以作为LSAEnumerateAccountRights的
hPolicy参数。PsidTrustee参数是个指向您想要列举权限之信任成员SID的目标。您可以接纳LookupAccountName(在先前
的〈认识SIDs〉一节中有谈论)从信任成员的帐户名称拿到三个SID。这些信任成员可以是使用者帐户、群组帐户可能电脑帐户。

就算如此LookupPrivilegeDisplayName函数和列举权限并无直接的涉及,不过在此仍应该提到它。那一个函数将规划的权柄名称,例如SeTcbPrivilege,译成易记的展现名称,在这几个实例中则被译为「扮演作业系统的一部份」。

有了Net函数的常识,您将发现学习这么些细节是件毫不费劲的事。所以,让大家开始树立信任成员帐户吧!

名叫信任成员?
 

表9-10列出了在本书印刷时,Windows
2000中可用的保有权限。部分的清单在《Platform SDK》文件中。

其次种撷取Windows
两千种类权限资讯的章程为:经由对LsaEnumerate
AccountsWithUserRight的呼叫请求持有一定权限的信赖成员清单。

 表9-9 SID_NAME_US列举型别类型值

LsaNtStatusToWinError函数将NT状态程序代码转变成熟练的Win32指鹿为马程序代码,如同从GetLastError传回的相同。在变化后,成功的呼叫LsaOpenPolicy,以扩散3个E奥迪Q5ROLX570_SUCCESS值。

说明

那边有多少个原因:


近期您对此权力以及系统如何表示他们的不二法门应该已有微微的认识,让我们开头商量在系统上派遣及吊销权限的部份。

NET_API_STATUS NetUserGetInfo(
    PCWSTR pszServerName,
    PCWSTR pzUsername,
    DWORD dwLevel,
    PBYTE *ppbBuf);

NET_API_STATUS NetUserSetInfo(
    PCWSTR pszServerName,
    PCWSTR pszUsername,
    DWORD dwLevel,
    PBYTE pbBuf,
    PDWORD pdwParmErr);

Windows
3000的安全性工具
 


它除了从psidTrustee提示的深信成员中移除权利清单以及有着3个附加参数BooleanfAllRights外,此函数与LsaAddAccountRights一样。

经常会在给定的系列上收获现存使用者或群组的清单。再叁次地表明,Net
API提供五个类似的函数来施行那个义务。您可以动用NetLocalGroupEnum去获取系统上的群组清单;同样地,也得以使用
NetUserEnum取得系统上使用者帐户的清单。这个函数定义如下:

出于Net函数最常被运用,因而这一章会集中于那些片段。但是,可被用来施行类似职务的ADSI元件也会以注释的法门列举出来,以便你可以在《Platform
SDK》文件中寻找特定的大旨。


组原则嵌入式管理单元可让您调整委派给信任成员的权限。因为系统上有多量群组原则的作用,所以这几个嵌入式管理单元比本机使用者及群组嵌入式管理单元更复
杂。经由展开以下的门道可以平素到群组原则嵌入式管理单元的权柄作用:本机电脑原则/电脑配置/Windows设定/安全性设定/本机原则/使用者权限委
派。图9-1表明了应突显的镜头。

最终2个参数ppSid,值得额外的瞩目。它被定义为PSID*,是个针对SID目标的目标。和大多数Windows所提供的函数差距,AllocateAndInitializeSid会指派3个缓冲器给你,而非等待你提供三个缓冲器。被派出的内存位址则经过这一个参数传回。

 表9-7 一些众所周知的RIDs

PszSystemName参数是你执行搜寻所在的机械名称。当LookupAccountSid搜寻二个相信成员名称时,它会与LookupAccountName使用同一的搜索顺序及规则。

这么些函数很不难拔取。您必须传递开启LSA原则物件的handle,以及针对你要修改权限之信任成员SID目的(本章先前的探究中曾涉嫌,您能够经过呼叫LookupAccountName而得到使用者或群组帐户的SID)。

您恐怕曾经猜到,系统也提供了接近的函数,用来得到及设定群组信任成员帐户的资讯。要得到信任成员资讯,您能够呼叫NetLocalGroupGetInfo;而设定群组资讯则要呼叫NetLocalGroupSetInfo。这个函数定义如下:

不管AllocateAndInitializeSid的限制,依然应该把SIDs当成可为任意大小的场地(即幸免静态缓冲器)。

http://blog.csdn.net/showna/article/details/1543523

相关文章