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

📄 nabhandling.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 3 页
字号:
/*______________________________________________________________________________
	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 + -