📄 nabhandling.c
字号:
/*______________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: NabHandling.c,v 1.6 2002/09/09 00:31:43 sdas Exp $
______________________________________________________________________________*/
/*::: MODULE OVERVIEW :::::::::::::
Reusable code associated with Notes name handling and the Domino Directory
(Notes Name & Address Book).
--- suggested enhancement ----
9/12/99 PR
change the GroupInfo and GroupNestInfo linked-list handling to use the
standard linked-list functionality provided through LibLinkList.h
--- revision history ---------
3/20/00 Version 1.1.1: Paul Ryan
+ documentation, formatting adjustment
9/12/99 Version 1.1: Paul Ryan
+ added name- & group-resolution functionality
+ signature change to eus_CreateTextListEntryCopy()
+ Notes name conversion procedure: canonicalized -> abbreviated
+ token renaming
+ doucmentation adjustment
1/10/99 Version 1.0: Paul Ryan
::::::::::::::::::::::::::::::::::::*/
#include "NabHandling.h"
#define mpc_TKN_COMMON_NM "CN="
static const char mpc_TKN_CANONICAL[] = mpc_TKN_COMMON_NM;
static const UINT mui_LEN_TKN_CANONICAL = sizeof( mpc_TKN_CANONICAL) - 1;
/** eus_CompileUsersAclGroupList( ***
Purpose is to construct a string list of all the groups to which a particular
user belongs. Procedure assumes that the first entry in the ListName item of
the group document is the name of the group; follow-on alias entries are
ignored.
--- parameters & return -----
RETURN: !eus_SUCCESS if invalid parameters were passed; eus_SUCCESS if no
error occured; the Notes API error code otherwise
--- suggested enhancement ---
9/12/99 PR: for the sake of comprehensiveness, extend procedure so that group
"aliases" are added to the returned string list
--- revision history --------
9/12/99 PR
+ token renaming
+ logic shortening
+ documentation adjustment
1/11/99 PR: created */
//DOC!!
STATUS eus_CompileUsersAclGroupList(
const char pc_USERNM[],
char pc_SERVERNM[],
StringNode * *const ppt_headMemberGroup) {
const WORD us_LOOKUP_VIEWS = 1, us_LOOKUP_ITEMS = 3,
us_GROUPNM = 0, us_TYPE = 1, us_MEMBERS = 2;
char pc_VIEWNM_GROUPS[] = "$VIMGroups", pc_ITMNM_GROUPNM[] = "ListName",
pc_ITMNM_TYPE[] = "GroupType", pc_ITMNM_MEMBERS[] = "Members";
char * pc, pc_ItmNms[ sizeof( pc_ITMNM_GROUPNM) +
sizeof( pc_ITMNM_TYPE) +
sizeof( pc_ITMNM_MEMBERS)];
HANDLE h = NULL;
void * pv_results, * pv = NULL, * pv_list = NULL;
WORD us, us_type, us_len, us_groups, us_entries, us_ixMatch = 0xFFFF;
BOOL f_okType, f_failure = FALSE, f_StartedEntries;
GroupInfoNode * pt_group = NULL, * pt_headGroup = NULL, * pt_grp;
BYTE * puc, * puc_members;
StringNode * pt_headMemberGroup = NULL, * pt_tailMember = NULL,
* pt_member, * pt;
GroupNestNode * pt_headNesting = NULL, * pt_tailNesting = NULL, * pt_nest;
GroupNestInfo * pt_nst;
STATUS us_err;
if (!( pc_USERNM && pc_SERVERNM && ppt_headMemberGroup))
return !eus_SUCCESS;
*ppt_headMemberGroup = NULL;
//lookup information about all the groups in the primary NAB
strcpy( pc = pc_ItmNms, pc_ITMNM_GROUPNM);
strcpy( pc += sizeof( pc_ITMNM_GROUPNM), pc_ITMNM_TYPE);
strcpy( pc + sizeof( pc_ITMNM_TYPE), pc_ITMNM_MEMBERS);
if (us_err = NAMELookup( pc_SERVERNM, NAME_LOOKUP_ALL |
NAME_LOOKUP_NOSEARCHING, us_LOOKUP_VIEWS,
pc_VIEWNM_GROUPS, 1, epc_NULL,
us_LOOKUP_ITEMS, pc_ItmNms, &h))
return us_err;
//if there aren't any groups in the NAB, short-circuit with success since
// there's nothing to compile
pv_results = OSLockObject( h);
pv_list = NAMELocateNextName( pv_results, NULL, &us_groups);
if (!( pv_list && us_groups))
goto errJump;
//construct a dedicated list of existing group names so we can look name
// matches up quickly
for ( us = 0; us < us_groups; us++) {
pv = NAMELocateNextMatch( pv_results, pv_list, pv);
//if the group can't be used with ACLs, loop for the next group name
if (us_err = eus_CreateNameMatchTextItemCopy( us_TYPE, pv, &pc))
goto errJump;
us_ixMatch++;
f_okType = !( *pc == i_MULTI_PURPOSE || *pc == i_ACL_ONLY);
free( pc);
if (!f_okType)
continue;
//add the group name to the dedicated list of existing group names
if (us_err = eus_CreateNameMatchTextItemCopy( us_GROUPNM, pv, &pc))
goto errJump;
if (!pc)
continue;
if (f_failure = !f_AddGroupInfoNodeFifo( pc, us_ixMatch, &pt_group)) {
free( pc);
goto errJump;
}
if (!pt_headGroup)
pt_headGroup = pt_group;
} //for ( us = 0; us < us_groups; us++)
//parse each group for user-membership and group-nesting information
pt_group = pt_headGroup;
us_ixMatch = 0;
pv = NULL;
while (pt_group) {
//scroll through to the information record about the next group
while (us_ixMatch <= pt_group->t.us_position) {
pv = NAMELocateNextMatch( pv_results, pv_list, pv);
us_ixMatch++;
}
//if the Members item isn't present (though it should be), iterate on
// to the next group
if (!( puc_members = NAMELocateItem( pv, us_MEMBERS, &us_type,
&us_len))) {
pt_group = pt_group->pt_next;
continue;
}
//determine the number of members in the list
if (us_type == TYPE_TEXT_LIST)
us_entries = ListGetNumEntries( puc_members, TRUE);
else if (us_type == TYPE_TEXT)
us_entries = 1;
else
us_entries = 0;
//process each name in the group as needed
f_StartedEntries = FALSE;
for (us = 0; us < us_entries; us++) {
//if the "name" is a null string, loop for the next entry
if (us_type == TYPE_TEXT_LIST) {
if (us_err = ListGetText( puc_members, TRUE, us, &puc,
&us_len))
goto errJump;
}else {
puc = puc_members + sizeof( WORD);
us_len -= sizeof( WORD);
}
if (!us_len)
continue;
//if the name matches the user name...
if (memcmp( puc, pc_USERNM, us_len) == ei_SAME && us_len ==
strlen( pc_USERNM)) {
//add the group name to the member-group list
if (f_failure = !ef_AddStringNodeFifo( pt_group->t.pc_name,
TRUE, &pt_tailMember))
goto errJump;
if (!pt_headMemberGroup)
pt_headMemberGroup = pt_tailMember;
//there's no need to continue processing the group if it
// contains the user, so break out this loop so we can move
// on to the next group
break;
} //if (puc && memcmp( puc, pc_USERNM
//if the name is canonicalized, loop for the next name
if (memcmp( puc, mpc_TKN_CANONICAL, mui_LEN_TKN_CANONICAL) ==
ei_SAME)
continue;
//We now assume that the name is a group name. If the name is not
// in the list of _pertinent_ groups, loop for the next name in
// this group...
pt_grp = pt_headGroup;
while (pt_grp) {
if (memcmp( puc, pt_grp->t.pc_name, us_len) == ei_SAME &&
us_len == strlen( pt_grp->t.pc_name))
break;
pt_grp = pt_grp->pt_next;
} //while (pt_grp)
if (!pt_grp)
continue;
//if nesting tracking has begun but no entries have been logged
// for _this_ group name...
if (pt_headNesting && !f_StartedEntries) {
//add a node onto the list to contain the new entry
if (f_failure = !(pt_tailNesting = pt_tailNesting->pt_next =
calloc( 1, sizeof( GroupNestNode))))
goto errJump;
//else if nesting tracking hasn't begun, start it off
}else if (!pt_headNesting)
if (f_failure = !(pt_headNesting = pt_tailNesting = calloc( 1,
sizeof( GroupNestNode))))
goto errJump;
//if nesting entries have been logged for this group name, string
// on room for another entry
pt = (pt_nst = &pt_tailNesting->t)->pt_headMember;
if (pt) {
while (pt->pt_next)
pt = pt->pt_next;
if (f_failure = !(pt = pt->pt_next = calloc( 1,
sizeof( StringNode))))
goto errJump;
//else start off the nesting entries list for this group name
}else {
if (f_failure = !(pt = pt_nst->pt_headMember = calloc( 1,
sizeof( StringNode))))
goto errJump;
f_StartedEntries = TRUE;
} //if (pt)
//populate the new nesting entry
if (f_failure = !(pt->pc = malloc( us_len + 1)))
goto errJump;
memcpy( pt->pc, puc, us_len);
pt->pc[ us_len] = NULL;
if (pt == pt_nst->pt_headMember)
pt_nst->pc_container = pt_group->t.pc_name;
} //for (us = 0; us < us_entries
pt_group = pt_group->pt_next;
} //while (pt_group)
//if applicable, add the names of any higher-order groups containing the
// "first-order" groups just discovered
if (pt_headNesting && (pt_member = pt_headMemberGroup)) {
StringNode * pt_headGreaterGroup = NULL,
* pt_tailGreaterGroup = NULL;
do
if (f_failure = !f_TackOnNestings( pt_member->pc, pt_headNesting,
&pt_tailGreaterGroup,
&pt_headGreaterGroup))
goto errJump;
while (pt_member = pt_member->pt_next);
pt_member = pt_headMemberGroup;
while (pt_member->pt_next)
pt_member = pt_member->pt_next;
pt_member->pt_next = pt_headGreaterGroup;
} //if (pt_headNesting && (pt_member
*ppt_headMemberGroup = pt_headMemberGroup;
errJump:
//if an error occurred and some member-group entries were logged, free
// the resources allocated for those entries
if ((us_err || f_failure) && (pt = pt_headMemberGroup)) {
StringNode * pt_next;
do {
pt_next = pt->pt_next;
free( pt->pc);
free( pt);
} while (pt = pt_next);
} //if ((us_err || f_failure) &&
//If applicable, free all resources still allocated to the nesting-groups
// table. The container string is owned by the dedicated list of
// existing group names, not by the nesting-groups table.
if (pt_nest = pt_headNesting) {
GroupNestNode * pt_next;
do {
pt_next = pt_nest->pt_next;
if (pt_nest->t.pt_headMember)
e_FreeList( &pt_nest->t.pt_headMember, TRUE);
free( pt_nest);
} while (pt_nest = pt_next);
} //if (pt_nest = pt_headNesting)
//if applicable, free the dedicated list of existing group names
if (pt_grp = pt_headGroup) {
GroupInfoNode * pt_next;
do {
pt_next = pt_grp->pt_next;
free( pt_grp->t.pc_name);
free( pt_grp);
} while (pt_grp = pt_next);
} //if (pt_grp = pt_headGroup)
//if applicable, free the buffer returned by NAMELookup(), if any
if (h) {
OSUnlockObject( h);
OSMemFree( h);
}
return us_err + f_failure;
} //eus_CompileUsersAclGroupList(
/** f_TackOnNestings( ***
--- parameters & return ----
--- revision history -------
9/12/99 PR: logic shortening
1/11/98 PR: created */
//DOC!!
static BOOL f_TackOnNestings( const char pc_GROUPNM[],
GroupNestNode *const pt_headNest,
StringNode * *const ppt_tailMember,
StringNode * *const ppt_headMember) {
GroupNestNode * pt_nest;
StringNode * pt_headMember = NULL;
BOOL f_SetHeadMemberNode = ppt_headMember ? !*ppt_tailMember : FALSE;
_ASSERTE( pc_GROUPNM && pt_headNest && ppt_tailMember);
if (ppt_headMember)
*ppt_headMember = NULL;
pt_nest = pt_headNest;
while (pt_nest) {
if (ef_ListContainsString( pc_GROUPNM, pt_nest->t.pt_headMember,
FALSE)) {
//copy the container group name to a new node in the member list
if (!ef_AddStringNodeFifo( pt_nest->t.pc_container, TRUE,
ppt_tailMember))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -