VgwSecurityCheckDocsFnc


Use the VgwSecurityCheckDocsFnc function to specify whether a user should be allowed access to documents returned as part of a search. The Verity engine calls your VgwSecurityCheckDocsFnc function while filtering a list of search results.


Syntax

VdkError VgwSecurityCheckDocsFnc(
   VgwAppSession        vgwSession,
   VdkUser              vdkUser,
   VgwSecCheckDocsArg   vgwCheckArg)

Arguments

 


vgwSession

VgwAppSession   The session handle that contains session-related data, which was set in your driver’s VgwSessionNewFnc function.

vdkUser

VdkUser   A handle that identifies the user requesting access to this repository’s documents.

vgwCheckArg

VgwSecCheckDocsArg   A handle to a VgwSecCheckDocsArgRec structure that identifies the documents for which access must be determined. On return, this structure will identify whether or not access is allowed for each document.


Member Descriptions

 

Table 6-7    VgwSecCheckDocsArgRec Members


Member

Type/Description

idCount

VdkUint4   The number of IDs in the idArray array.

idArray

VdkDocId*   A pointer to an array of document IDs.

accessArray

VdkUint1*   A pointer to an array whose bits specify whether access to a document is allowed.

docSet

VdkDocSet   A VDK docset handle provided to give access to fields stored in collections or docsources.

maxNumDocs

VdkUint4   The maximum number of documents for which to allow access.

flags

VdkUint4   Reserved for future use.



Returns

This function must return one of the following error codes:

VdkSuccess for success

 

VdkError_* for a standard Verity Developer Kit API error as described in the Verity Developer’s Kit Programming Reference

 

VdkFail for a non-specific error

 


Discussion

Your VgwSecurityCheckDocsFnc function must determine whether the documents listed in the idArray member of the vgwCheckArg argument (VgwSecCheckDocsArgRec structure) should be made available to the user specified by the vdkUser argument.

Determining access should be as fast as possible; for example, you could

store access information, such as an access control list (ACL), in the repository’s collection and retrieve it from the collection whenever the Verity engine calls your VgwSecurityCheckDocsFnc function.

 

store user access rights, groups, or roles in the user’s certificate

 

keep the ACL and certificate information in your driver’s global memory. For more information, see Performance Improvement Techniques.

 

Your VgwSecurityCheckDocsFnc function iterates over the document IDs specified in idArray member of the VgwSecCheckDocsArgRec structure. If the access information associated with the document matches the rights associated with a user, your function should set the document’s corresponding access bit in the accessArray member using VgwBitOn; otherwise, it should be set using VgwBitOff. Each bit in the accessArray member corresponds to the document ID at the same position in the idArray member; thus, bit 0 of the accessArray member specifies whether access is allowed for the first document (array position 0) identified in the accessArray member, and so on.

If the documents’ access information is stored in the collection, you can retrieve the information by calling VdkDocSetRead and release it by calling VdkDocSetReadFree when the information is no longer needed.

If the value of the maxNumDocs member is zero, your VgwSecurityCheckDocsFnc function must check access to all documents specified by the idArray member; otherwise, your function should stop checking when the number of documents that “passes” the check exceeds the value of maxNumDocs; for example, if the value of maxNumDocs is 100, your function should stop checking and return as soon as the user is allowed to access 100 documents identified in the idArray member.

Your VgwSecurityCheckDocsFnc function can implement any scheme to check security and keep any kind of access information for documents in your repository; for example, you can copy this information into a collection

by including a copy field with the access information in your gateway’s field style file and populating it in your gateway’s configuration style file. For more information, see Type Parameter File.

 

by creating a field token during a stream operation. For more information, see Bypassing Auto-Recognition.

 

You can compare access information against any criteria; for example, you can check any of the following items against the document’s access information:

data in a certificate associated with the user, such as the “group”

 

the kind of certificate, such as an administrator’s certificate

 

the certificate’s state, such as whether or not the certificate is valid

 

specific values in an access control list, such as a constant assigned to specific users or groups

 

Multiple criteria can be used.

Your driver’s session handle can specify whether or not to use security; for more information, see the example under VgwSessionNewFnc in Session Interface. If NULL is specified for a security module, security is not enabled for your repository; in which case, you can set each bit of the accessArray member using VgwBitOn to allow access for all documents.

Your VgwSecurityCheckDocsFnc function is responsible for releasing memory and other resources before returning.

 

 
Note   Because this function is only called for search result filtering, a stale cache might allow the user to know about a document for which he or she does not have access; regardless, your gateway driver should not allow the user to view the document.
 

 


Example

#define False 0
#define True 1

static VdkError
VDK_CALLBACK VgwSecurityCheckDocs(VgwAppSession pSession,
VdkUser pUser, VgwSecCheckDocsArg pCheckArg)
{
VdkError error = VdkSuccess;
VdkBool bCert = False;
VdkInt4 i;
VSecCertificate pCert = NULL;
VdkDocSetReadOut pDocsetOut = NULL;
VdkDocSetReadArgRec docsetArg;
VdkUserFindArgRec findArg;
VdkCString columnArray[2];

if( !pSession || !pCheckArg || !pCheckArg->docSet )
return VdkError_InvalidArgs;

if (!pCheckArg->idCount)
return VdkSuccess;

/****************************************************
* with no security module, set everything to on,
* which means result list filtering does not happen
****************************************************/

if (!pSession->securityModuleId) {

for( i=0; i<(VdkInt4)pCheckArg->idCount; i++ )
VgwBitOn(pCheckArg->accessArray, i);

return VdkSuccess;
}

/********************************************************
* read the VdkVgwKey and _VgwAccessValue out of the DDD
* for all of the candidate documents
********************************************************/

VdkStructInit(&docsetArg);
docsetArg.docset = pCheckArg->docSet;
docsetArg.startRow = 0;
docsetArg.numRows = (VdkInt4)pCheckArg->idCount;
docsetArg.columnCount = 2;
docsetArg.columnArray = columnArray;
docsetArg.columnArray[0] = (VdkCString)"VdkVgwKey";
docsetArg.columnArray[1] = (VdkCString)"_VgwSampAccessCache";
docsetArg.user = pUser;

  if (VdkSuccess != (error =
                     VdkDocSetRead(&docsetArg, &pDocsetOut)))
return error;

if (!pDocsetOut)
return VdkError_HandleNotFound;

/**********************************************************
* check access based on whether document is public or not
**********************************************************/

if (!pUser) {

/********************************************
* assume all documents are secure and valid
********************************************/

for( i=0; i<pDocsetOut->numRows; i++ )
VgwBitOff(pCheckArg->accessArray, i);

VdkDocSetReadFree(pDocsetOut);
return VdkSuccess;
}

/*******************************************************
* check access based on matched VDK certificate object
*******************************************************/

for( i=0; i<pDocsetOut->numRows; i++ ){

if( !pDocsetOut->values[i*2] ||
!strlen(pDocsetOut->values[i*2])) {
VgwBitOff(pCheckArg->accessArray, i);
continue;
}

/*******************************************************
* assumes all documents come from one repository 'abc'
* and are all valid
*******************************************************/

VdkStructInit(&findArg);
findArg.secId = pSession->securityModuleId;
findArg.repId = (VdkUint4)VGWR_ONEID;

/ ***************************************************************
* check all matching VDK certificates in the VdkUser object
* for possible access to the document that VdkDocKey specifies
***************************************************************/

bCert = False;
VgwBitOff(pCheckArg->accessArray, i);

while (VdkSuccess == (error =
VdkUserFindCertificate(pUser, &findArg, &pCert))) {
bCert = True;

/******************************************************
* check access based on user's VDK certificate object
* and document's cached acl or VdkVgwKey field value
******************************************************/

if (!pCert)
continue;

/***********************************************
* check stored made up uid in prData and
* give only 'abc' user access to all documents
***********************************************/

if( (pCert->prState & TicketInvalid) ||
!(pCert->prState & TicketValid) )
continue;

if (!pCert->prData)
continue;

if (pDocsetOut->values[i*2+1]) {

if (pCert->prData ==
(VdkVoidp)atoi((const char*)pDocsetOut->values[i*2+1])) {
VgwBitOn(pCheckArg->accessArray, i);
break;
}
      }
}

if (VdkError_HandleNotFound == error) {

/**********************************************************
* check access based on whether document is public or not
**********************************************************/

if (!bCert) {

/********************************************
* assume all documents are secure and valid
********************************************/

VgwBitOff(pCheckArg->accessArray, i);
}
}
}

VdkDocSetReadFree(pDocsetOut);
return VdkSuccess;
}