PolGetPolicyExistingFile callback function

A Policy DLL's PolGetPolicyExistingFile callback function determines whether a specific open instance of an existing encrypted file should receive encrypted or non-encrypted (raw, cleartext) access.

Syntax

POL_GET_POLICY_EXISTING_FILE PolGetPolicyExistingFile;

 

FE_POLICY_RESULT

PolGetPolicyExistingFile(

    _In_  FE_POLICY_PATH_INFORMATION *PolicyPathInfo,

    _In_  DWORD ThreadId,

    _In_  PVOID PolHeaderData,

    _In_  DWORD PolHeaderDataSize,

    _In_  DWORD GrantedAccess,

    _In_  DWORD CreateAction

)

Parameters

PolicyPathInfo [in]

A pointer to an FESF allocated FE_POLICY_PATH_INFORMATION structure describing the file being opened.  See Remarks, below.

ThreadId [in]

The identifier of the thread opening the file.

PolHeaderData [in]

A pointer to an FESF allocated storage area containing the Policy DLL's Header Data that FESF retrieved from the file.  This data was previously provided to FESF by the Policy DLL as output from a successful call to PolGetKeyNewFile.

PolHeaderDataSize [in]

The size, in bytes, of the header data provided in the buffer pointed to by PolHeaderData.

GrantedAccess [in]

A bitmask representing the File Access Rights that the thread opening the file has been granted.  File Access Rights are represented by standard Windows-defined constants.  See the description of the GrantedAccess parameter on the PolGetPolicyNewFile call for a list of these constants.

CreateAction [in]

A value indicating the action taken as a result of the thread's CreateFile call.  See the description of the CreateAction parameter on the PolGetPolicyNewFile call for a list of these constants.

Return value

The Policy DLL's PolGetPolicyExistingFile callback function returns an enumeration value of the type FE_POLICY_RESULT that determines FESF's action on subsequent read or write operations via the opened file handle.

If PolGetPolicyExistingFile returns FE_POLICY_ENCRYPT_DECRYPT, data read from the file will be transparently decrypted by FESF before it is returned to the reader, and data written to the file will be transparently encrypted by FESF before it is stored in the file.

If PolGetPolicyExistingFile returns FE_POLICY_RAW, read and write operations on the file will be performed on the data as provided.  That is, no transparent encryption or decryption of data will be take place.

If PolGetPolicyExistingFile cannot specify an encryption policy for the file being opened, for example due to an error in processing, PolGetPolicyExistingFile returns the enumeration value FE_POLICY_FAIL.  This will cause the thread's CreateFile operation to fail with an error.  See the Remarks section for more information on the consequences of returning FE_POLICY_FAIL.

Remarks

All Policy DLLs must implement this callback function.

FESF calls a Policy DLL's PolGetPolicyExistingFile callback function whenever a thread successfully opens an existing file that contains FESF encrypted data.  There are two exceptions:

      When FESF Policy Caching is enabled and policy information has already been cached for the combination of file, process, and access being processed. 

      When the open being processed is a Transacted Open (such as the result of a thread calling CreateFileTransacted).  Transacted Open operations typically result in raw access being granted.  See the discussion of Transacted Open operations at the section for the PolApproveTransactedOpen callback.

Note that PolGetPolicyExistingFile is never called when a file containing non-encrypted data is opened.

FESF calls a Policy DLL's PolGetPolicyExistingFile callback function to determine the policy for a specific CreateFile request on an existing encrypted file.  The policy specifies whether a given open request is granted raw or encrypt/decrypt access to the data in the file.  The policy decision can be based on the parameters passed into this function as well as any additional information PolGetPolicyExistingFile acquires on its own.

Given the ThreadID provided in this callback, PolGetPolicyExistingFile can call FESF-provided helper functions to retrieve additional information about the calling thread, including the directory and file name of the executing program and identity and security information of the user account under which the thread is running.

If the FE_POLICY_PATH_FILE_DEHYDRATED flag is set in the PolicyFlags field of the provided PolicyPathInfo structure, the file being accessed is locally “dehydrated” and encrypted.  In this context, “dehydrated” means that the file’s data is located in the cloud and only a placeholder representing the file is stored locally on disk. 

Each cloud driver behaves differently, and you will need to understand the precise behavior and the consequences of recalling dehydrated files. However, in general, if your Solution intends to handle files that are “unencrypted in the cloud” you should never return raw to opens that have the FE_POLICY_PATH_FILE_DEHYDRATED flag set.

If FESF Policy Caching is enabled, FESF will remember the policy decision returned by PolGetPolicyExistingFile.  In this case, if the process owning the ThreadID opens this file in the future with the same access described by GrantedAccess, FESF will automatically apply the same policy. This helps reduce system overhead by potentially avoiding a call to PolGetPolicyExistingFile. The duration of this caching behavior lasts as long as the Windows file cache for this file persists, which in turn depends on numerous factors that cannot be directly controlled.  The FESF Policy Cache can be flushed at any time by the Policy DLL.  For more information, see FESF Policy Caching.

PolGetPolicyExistingFile is called as part of Windows' processing a system service call (such as CreateFile) made by the thread indicated by ThreadID for the file described by PolicyPathInfo.  The call to PolGetPolicyExistingFile occurs after the system service call has succeeded but before the final result is returned to the thread.  Because the PolGetPolicyExistingFile callback is blocking the system service call from completing, processing in this function must be prompt.

Because of the asynchronous nature of Windows, in some unusual cases the values provided for CreateAction can be unexpected.  For example, PolGetPolicyNewFile is called when an existing zero length file is encountered (including a file that is superseded as part of being opened).  However, if two threads open the same file at the same time, and agree to share write access to that file, it is possible for PolGetPolicyExisitingFile to be called with CreateAction set to POL_CREATE_ACTION_SUPERSEDED, and there to be no user data in the file.  The file will, however, include Policy DLL Header Data and FESF control information.  While it is rare for two threads to share write access to the same file, for one of those threads to supersede its contents, and for the two threads to attempt to open this shared file at almost exactly the same time, this is possible.  Policy DLLs should therefore not rely on CreateAction always being POL_CREATE_ACTION_OPENED when PolGetPolicyExistingFile is called.

Also note that there is an inherent risk in providing mixed responses to this call.  If a given file is opened for shared write access and one open is granted FE_POLCY_ENCRYPT_DECRYPT and the other open is granted FE_POLCY_RAW, there is no way for FESF to ensure that the resulting file, with its potential mixture of encrypted and decrypted data, contains usable data.  In fact, this can even lead to Client Header Data or FESF metadata being corrupted.  This can lead to a situation in which FESF will identify the file as being inconsistent.  See the description of the PolReportFileInconsistent callback for more details.

Policy DLLs should return FE_POLICY_FAIL from their PolGetPolicyExistingFile callback only when absolutely necessary.  Because PolGetPolicyExistingFile is called after Windows CreateFile processing has completed, returning FE_POLICY_FAIL can result in a previously existing file being superseded or overwritten with a new zero length file.  The specific action taken as a result of CreateFile is indicated by CreateAction.  For more information, see Returning Failure from Policy DLL Callbacks.

Examples

 

See Also

The FESF Sample Solution contains an example implementation of this callback function.  This example is part of the provided UM_Sample Visual Studio Solution, the SampPolicy project, and is located in the file SampPolicy.cpp.

Requirements

Software version

FESF V1 (or later)

Library

FESFPolicy.lib

Header

PolDllApi.h