[Pvfs2-cvs] commit by sampson in pvfs2/src/client/windows/client-service: dokan-interface.c

CVS commit program cvs at parl.clemson.edu
Fri Apr 1 17:02:11 EST 2011


Update of /projects/cvsroot/pvfs2/src/client/windows/client-service
In directory parlweb1:/tmp/cvs-serv30302/src/client/windows/client-service

Modified Files:
      Tag: windows-client
	dokan-interface.c 
Log Message:
Coding Windows security


Index: dokan-interface.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/client/windows/client-service/Attic/dokan-interface.c,v
diff -p -u -r1.1.2.24 -r1.1.2.25
--- dokan-interface.c	24 Mar 2011 21:32:57 -0000	1.1.2.24
+++ dokan-interface.c	1 Apr 2011 22:02:11 -0000	1.1.2.25
@@ -1,4 +1,4 @@
-/* TODO: Copyright (C) Omnibond, LLC 2010 */
+/* TODO: Copyright (C) Omnibond, LLC 2011 */
 
 #include <Windows.h>
 #include <AccCtrl.h>
@@ -6,17 +6,28 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "dokan.h"
-/* TODO: needed? #include <fileinfo.h> */
 
 #include "pvfs2.h"
 #include "str-utils.h"
 #include "client-service.h"
 #include "fs.h"
+#include "quickhash.h"
 
 FILE *g_DebugFile = NULL;
 BOOL g_UseStdErr;
 BOOL g_DebugMode;
 
+extern struct qlist_head user_list;
+
+struct cred_entry
+{
+    struct qhash_head hash_link;
+    ULONG64 context;
+    PVFS_credentials credentials;
+};
+
+struct qhash_table *cred_cache;
+
 #define DEBUG_FLAG(val, flag) if (val&flag) { DbgPrint("   "#flag"\n"); }
 
 /* TODO */
@@ -337,7 +348,7 @@ static char *get_fs_path(const wchar_t *
     ret = fs_resolve_path(mb_path, fs_path, MAX_PATH);
     if (ret != 0)
     {
-        DbgPrint("   fs_resolve_path returned %d\n");
+        DbgPrint("   fs_resolve_path returned %d\n", ret);
         cleanup_string(mb_path);
         free(fs_path);
         return NULL;
@@ -350,9 +361,149 @@ static char *get_fs_path(const wchar_t *
     return fs_path;
 }
 
-static PVFS_credentials *get_credentials(ULONG64 context)
+int cred_compare(void *key, 
+                 struct qhash_head *link)
 {
+    struct cred_entry *entry = qhash_entry(link, struct cred_entry, hash_link);
+
+    return (entry->context == *((ULONG64 *) key));
+}
+
+static int get_requestor_credentials(PDOKAN_FILE_INFO file_info,
+                                     PVFS_credentials *credentials)
+{
+    HANDLE htoken;
+    PTOKEN_USER token_user;
+    char buffer[1024], user_name[256], domain_name[256];
+    DWORD user_len = 256, domain_len = 256, return_len, err;
+    SID_NAME_USE snu;
+    struct qlist_head *user_link;
+    PORANGEFS_USER puser, req_user;
+
+    /* get requesting user information */
+    htoken = DokanOpenRequestorToken(file_info);
+    if (htoken == INVALID_HANDLE_VALUE)
+    {
+        DbgPrint("   DokanOpenRequestorToken failed\n");
+        return -ERROR_INVALID_HANDLE;
+    }
+
+    if (!GetTokenInformation(htoken, TokenUser, buffer, sizeof(buffer), &return_len))
+    {
+        err = GetLastError();
+        DbgPrint("   GetTokenInformation failed: %d\n", err);
+        CloseHandle(htoken);
+        return err * -1;
+    }
+
+    CloseHandle(htoken);
+
+    token_user = (PTOKEN_USER) buffer;
+
+    if (!LookupAccountSid(NULL, token_user->User.Sid, user_name, &user_len,
+                          domain_name, &domain_len, &snu))
+    {
+        err = GetLastError();
+        DbgPrint("   LookupAccountSid failed: %u\n", err);
+    }
+
+    /* search user list for credentials */
+    req_user = NULL;
+    qlist_for_each(user_link, &user_list)
+    {
+        puser = qlist_entry(user_link, ORANGEFS_USER, list_link);
+        if (!stricmp(puser->user_name, user_name)) 
+        {
+            req_user = puser;
+            break;
+        }
+    }
     
+    if (req_user != NULL)
+    {
+        credentials->uid = req_user->uid;
+        credentials->gid = req_user->gid;
+
+        return 0;
+    }    
+
+    /* can't locate credentials for requesting user */
+    DbgPrint("   get_requestor_credentials:  user not found\n");
+    return -ERROR_USER_PROFILE_LOAD;
+}
+
+static int get_credentials(PDOKAN_FILE_INFO file_info, 
+                           PVFS_credentials *credentials)
+{
+    struct qhash_head *item;
+    struct cred_entry *entry;
+    int ret;
+
+    if (file_info == NULL || credentials == NULL)
+        return -ERROR_INVALID_PARAMETER;
+
+    DbgPrint("   get_credentials:  context: %llu\n", file_info->Context);
+
+    if (file_info->Context != 0)
+    {
+        /* check cache for existing credentials 
+           associated with the context */        
+        item = qhash_search(cred_cache, &file_info->Context);
+        if (item != NULL)
+        {
+            /* if cache hit -- return credentials */
+            entry = qhash_entry(item, struct cred_entry, hash_link);
+            credentials->uid = entry->credentials.uid;
+            credentials->gid = entry->credentials.gid;
+
+            DbgPrint("   get_credentials:  cache hit (%d:%d)\n", 
+                      credentials->uid, credentials->gid);
+            return 0;
+        }
+        else
+        {
+            /* else get requestor credentials and add to cache */
+            ret = get_requestor_credentials(file_info, credentials);
+            if (ret != 0)
+                return ret;
+            entry = (struct cred_entry *) calloc(1, sizeof(struct cred_entry));
+            if (entry == NULL)
+            {
+                DbgPrint("   get_credentials: out of memory\n");
+                return -ERROR_NOT_ENOUGH_MEMORY;
+            }
+            
+            entry->context = file_info->Context;
+            entry->credentials.uid = credentials->uid;
+            entry->credentials.gid = credentials->gid;
+            qhash_add(cred_cache, &file_info->Context, &entry->hash_link);
+        }
+    }
+    else
+    {
+        /* retrieve credentials for the requestor */
+        ret = get_requestor_credentials(file_info, credentials);
+        if (ret != 0)
+            return ret;
+    }
+
+    DbgPrint("   get_credentials:  requestor credentials (%d:%d)\n", 
+             credentials->uid, credentials->gid);
+    DbgPrint("   get_credentials:  exit\n");
+
+    return 0;
+}
+
+static void remove_credentials(ULONG64 context)
+{
+    struct qhash_head *link; 
+    
+    link = qhash_search_and_remove(cred_cache, &context);
+    if (link != NULL)
+    {
+        free(qhash_entry(link, struct cred_entry, hash_link));
+    }
+
 }
 
 static int __stdcall
@@ -368,7 +519,7 @@ PVFS_Dokan_create_file(
     int ret, found, err;
     PVFS_handle handle;
     PVFS_sys_attr attr;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
 
     DbgPrint("CreateFile: %S\n", FileName);
     
@@ -443,13 +594,18 @@ PVFS_Dokan_create_file(
 
     DokanFileInfo->Context = 0;
 
+    /* load credentials (of requestor) */
+    err = get_credentials(DokanFileInfo, &credentials);
+    if (err != 0)
+        return err;
+
     fs_path = get_fs_path(FileName);
     if (fs_path == NULL)
         return -1;
 
     /* look up the file */
     found = 0;
-    ret = fs_lookup(fs_path, &handle);    
+    ret = fs_lookup(fs_path, &credentials, &handle);    
 
     DbgPrint("   fs_lookup returns: %d\n", ret);
 
@@ -472,9 +628,9 @@ PVFS_Dokan_create_file(
     case CREATE_ALWAYS:
         if (found)
         {
-            fs_remove(fs_path, credentials);
+            fs_remove(fs_path, &credentials);
         }
-        ret = fs_create(fs_path, credentials, &handle);
+        ret = fs_create(fs_path, &credentials, &handle);
         break;
     case CREATE_NEW:
         if (found) 
@@ -485,14 +641,14 @@ PVFS_Dokan_create_file(
         else
         {
             /* create file */
-            ret = fs_create(fs_path, credentials, &handle);
+            ret = fs_create(fs_path, &credentials, &handle);
         }
         break;
     case OPEN_ALWAYS:
         if (!found)
         {    
             /* create file */
-            ret = fs_create(fs_path, credentials, &handle);
+            ret = fs_create(fs_path, &credentials, &handle);
         }
         break;
     case OPEN_EXISTING:
@@ -509,7 +665,7 @@ PVFS_Dokan_create_file(
         }
         else
         {   
-            ret = fs_truncate(fs_path, 0, credentials);
+            ret = fs_truncate(fs_path, 0, &credentials);
         }
     }
 
@@ -525,7 +681,7 @@ PVFS_Dokan_create_file(
         DbgPrint("   Context: %llx\n", DokanFileInfo->Context);
 
         /* determine whether this is a directory */
-        ret = fs_getattr(fs_path, credentials, &attr);
+        ret = fs_getattr(fs_path, &credentials, &attr);
         if (ret == 0)
         {
             DokanFileInfo->IsDirectory = attr.objtype & PVFS_TYPE_DIRECTORY;
@@ -534,14 +690,6 @@ PVFS_Dokan_create_file(
             /* TODO */ ;
     }
 
-    /* assign nonzero context on error so cleanup works */
-    /* TODO: use linked list to make sure context is not in use */
-    /* TODO: needed?
-    if (err != 0) {        
-        DokanFileInfo->Context = rand();
-    }
-    */
-
     free(fs_path);
 
     DbgPrint("CreateFile exit: %d (%d)\n", err, ret);
@@ -558,16 +706,23 @@ PVFS_Dokan_create_directory(
     char *fs_path;
     int ret, err;
     PVFS_handle handle;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
 
     DbgPrint("CreateDirectory: %S\n", FileName);
 
+    DokanFileInfo->Context = 0;
+
+    /* load credentials (of requestor) */
+    err = get_credentials(DokanFileInfo, &credentials);
+    if (err != 0)
+        return err;
+
     /* get file system path */
     fs_path = get_fs_path(FileName);
     if (fs_path == NULL)
         return -1;
 
-    ret = fs_mkdir(fs_path, credentials, &handle);
+    ret = fs_mkdir(fs_path, &credentials, &handle);
 
     DbgPrint("   fs_mkdir returns: %d\n", ret);
 
@@ -595,23 +750,30 @@ PVFS_Dokan_open_directory(
     int ret, err;
     PVFS_handle handle;
     PVFS_sys_attr attr;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
 
     DbgPrint("OpenDirectory: %S\n", FileName);
 
+    DokanFileInfo->Context = 0;
+
+    /* load credentials (of requestor) */
+    err = get_credentials(DokanFileInfo, &credentials);
+    if (err != 0)
+        return err;
+
     /* get file system path */
     fs_path = get_fs_path(FileName);
     if (fs_path == NULL)
         return -1;
 
     /* lookup the file */
-    ret = fs_lookup(fs_path, credentials, &handle);    
+    ret = fs_lookup(fs_path, &credentials, &handle);    
 
     DbgPrint("   fs_lookup returns: %d\n", ret);
 
     if (ret == 0)
     {
-        ret = fs_getattr(fs_path, credentials, &attr);
+        ret = fs_getattr(fs_path, &credentials, &attr);
         DbgPrint("   fs_getattr returns: %d\n", ret);
         if (ret == 0)
         {
@@ -644,7 +806,7 @@ PVFS_Dokan_close_file(
 {
     char *fs_path = NULL;
     int ret = 0, err;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
 
     DbgPrint("CloseFile: %S\n", FileName);
     DbgPrint("   Context: %llx\n", DokanFileInfo->Context);
@@ -652,18 +814,21 @@ PVFS_Dokan_close_file(
     /* delete the file/dir if DeleteOnClose specified */
     if (DokanFileInfo->DeleteOnClose)
     {
+        /* load credentials */
+        err = get_credentials(DokanFileInfo, &credentials);
+        if (err != 0)
+            return err;
+
         /* get file system path */
         fs_path = get_fs_path(FileName);
         if (fs_path == NULL)
             return -1;
 
         /* remove the file/dir */
-        ret = fs_remove(fs_path, credentials);
+        ret = fs_remove(fs_path, &credentials);
     }
 
-    /* PVFS doesn't have a close-file semantic.
-       Simply clear the handle. */
-    DokanFileInfo->Context = 0;
+    /* PVFS doesn't have a close-file semantic */ 
 
     if (fs_path != NULL)
         free(fs_path);
@@ -684,14 +849,9 @@ PVFS_Dokan_cleanup(
     DbgPrint("Cleanup: %S\n", FileName);
     DbgPrint("  Context: %llx\n", DokanFileInfo->Context);
 
-    /* needed?
-    if (DokanFileInfo->Context == 0) {
-    }
-    else {
-        DbgPrint("  Cleanup: invalid handle\n");
-        return -1;
-    }
-    */
+    /* remove context's entry from cache */
+    if (DokanFileInfo->Context != 0)
+        remove_credentials(DokanFileInfo->Context);
 
     DbgPrint("Cleanup exit: %d\n", 0);
 
@@ -710,7 +870,7 @@ PVFS_Dokan_read_file(
 {
     char *fs_path;
     PVFS_size len64;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
     int ret, err;
     
     DbgPrint("ReadFile: %S\n", FileName);
@@ -723,13 +883,18 @@ PVFS_Dokan_read_file(
         ReadLength == 0)
         return -1;
 
+    /* load credentials */
+    err = get_credentials(DokanFileInfo, &credentials);
+    if (err != 0)
+        return err;
+
     /* get file system path */
     fs_path = get_fs_path(FileName);
     if (fs_path == NULL)
         return -1;
     
     /* perform the read operation */
-    ret = fs_read(fs_path, Buffer, BufferLength, Offset, &len64, credentials);
+    ret = fs_read(fs_path, Buffer, BufferLength, Offset, &len64, &credentials);
     *ReadLength = (DWORD) len64;
 
     free(fs_path);    
@@ -753,22 +918,25 @@ PVFS_Dokan_write_file(
 {
     char *fs_path;
     PVFS_size len64;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
     int ret, err;
 
     DbgPrint("WriteFile: %S\n", FileName);
     DbgPrint("   Context: %llx\n", DokanFileInfo->Context);
 
+    /* load credentials */
+    err = get_credentials(DokanFileInfo, &credentials);
+    if (err != 0)
+        return err;
+
     /* get file system path */
     fs_path = get_fs_path(FileName);
     if (fs_path == NULL)
         return -1;
-
-    DEBUG_PATH(fs_path);
     
     /* perform the read operation */
     ret = fs_write(fs_path, (void *) Buffer, NumberOfBytesToWrite, Offset, 
-                   &len64, credentials);
+                   &len64, &credentials);
     *NumberOfBytesWritten = (DWORD) len64;
 
     free(fs_path);
@@ -788,18 +956,23 @@ PVFS_Dokan_flush_file_buffers(
 {
     char *fs_path;
     int ret, err;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
 
     DbgPrint("FlushFileBuffers: %S\n", FileName);
     DbgPrint("   Context: %llx\n", DokanFileInfo->Context);
 
+    /* load credentials */
+    err = get_credentials(DokanFileInfo, &credentials);
+    if (err != 0)
+        return err;
+
     /* get file system path */
     fs_path = get_fs_path(FileName);
     if (fs_path == NULL)
         return -1;
 
     /* flush the file */
-    ret = fs_flush(fs_path, credentials);
+    ret = fs_flush(fs_path, &credentials);
 
     err = error_map(ret);
 
@@ -820,18 +993,23 @@ PVFS_Dokan_get_file_information(
     char *fs_path, *filename;
     int ret, err;
     PVFS_sys_attr attr;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
 
     DbgPrint("GetFileInfo: %S\n", FileName);
     DbgPrint("   Context: %llx\n", DokanFileInfo->Context);
 
+    /* load credentials */
+    err = get_credentials(DokanFileInfo, &credentials);
+    if (err != 0)
+        return err;
+
     /* get file system path */
     fs_path = get_fs_path(FileName);
     if (fs_path == NULL)
         return -1;
 
     /* get file attributes */
-    ret = fs_getattr(fs_path, credentials, &attr);
+    ret = fs_getattr(fs_path, &credentials, &attr);
 
     if (ret == 0)
     {
@@ -890,18 +1068,21 @@ PVFS_Dokan_set_file_attributes(
     char *fs_path;
     int ret, err;
     PVFS_sys_attr attr;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
 
     DbgPrint("SetFileAttributes: %S\n", FileName);
     DbgPrint("   Context: %llx\n", DokanFileInfo->Context);
 
+    /* load credentials */
+    err = get_credentials(DokanFileInfo, &credentials);
+
     /* get file system path */
     fs_path = get_fs_path(FileName);
     if (fs_path == NULL)
         return -1;
 
     /* convert attributes to PVFS */
-    ret = fs_getattr(fs_path, credentials, &attr);
+    ret = fs_getattr(fs_path, &credentials, &attr);
 
     if (ret == 0)
     {
@@ -912,7 +1093,7 @@ PVFS_Dokan_set_file_attributes(
         if (FileAttributes & FILE_ATTRIBUTE_READONLY)
             /* TODO: permissions */ ;
 
-        ret = fs_setattr(fs_path, &attr, credentials);
+        ret = fs_setattr(fs_path, &attr, &credentials);
     }
 
     free(fs_path);
@@ -935,7 +1116,7 @@ PVFS_Dokan_find_files(
          filename[PVFS_NAME_MAX], *full_path;
     int ret, err, count = 0;
     PVFS_ds_position token;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
     WIN32_FIND_DATAW find_data;
     wchar_t *wpath, *wfilename;
     BY_HANDLE_FILE_INFORMATION hfile_info;
@@ -943,13 +1124,18 @@ PVFS_Dokan_find_files(
     DbgPrint("FindFiles: %S\n", FileName);
     DbgPrint("   Context: %llx\n", DokanFileInfo->Context);
 
+    /* load credentials (of requestor) */
+    err = get_credentials(DokanFileInfo, &credentials);
+    if (err != 0)
+        return err;
+
     /* get file system path */
     fs_path = get_fs_path(FileName);
     if (fs_path == NULL)
         return -1;
 
     /* find the first file */
-    ret = fs_find_first_file(fs_path, &token, credentials, filename, PVFS_NAME_MAX);
+    ret = fs_find_first_file(fs_path, &token, &credentials, filename, PVFS_NAME_MAX);
     if (ret != 0)
         goto find_files_exit;
 
@@ -999,7 +1185,7 @@ PVFS_Dokan_find_files(
         cleanup_string(wfilename);
 
         /* find next file */
-        ret = fs_find_next_file(fs_path, &token, credentials, filename, PVFS_NAME_MAX);
+        ret = fs_find_next_file(fs_path, &token, &credentials, filename, PVFS_NAME_MAX);
 
         if (ret != 0)
             goto find_files_exit;
@@ -1007,7 +1193,7 @@ PVFS_Dokan_find_files(
 
 find_files_exit:    
 
-    DbgPrint("   fs_find_xxx_file returns: %d\n", ret);
+    DbgPrint("   fs_find_xxxx_file returns: %d\n", ret);
 
     free(fs_path);
 
@@ -1026,12 +1212,15 @@ PVFS_Dokan_delete_file(
 {
     char *fs_path;         
     PVFS_handle handle;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
     int ret, err;
 
     DbgPrint("DeleteFile: %S\n", FileName);
     DbgPrint("   Context: %llx\n", DokanFileInfo->Context);
-    
+
+    /* load credentials */
+    err = get_credentials(DokanFileInfo, &credentials);
+
     /* get file system path */
     fs_path = get_fs_path(FileName);
     if (fs_path == NULL)
@@ -1040,7 +1229,7 @@ PVFS_Dokan_delete_file(
     /* Do not actually remove the file here, just return
        success if file is found. 
        The file/dir will be deleted in close_file(). */
-    ret = fs_lookup(fs_path, credentials, &handle);
+    ret = fs_lookup(fs_path, &credentials, &handle);
 
     free(fs_path);
 
@@ -1079,11 +1268,16 @@ PVFS_Dokan_move_file(
 {
     char *old_fs_path, *new_fs_path;
     int ret, err;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
 
     DbgPrint("MoveFile: %S -> %S\n", FileName, NewFileName);
     DbgPrint("   Context: %llx\n", DokanFileInfo->Context);
 
+    /* load credentials */
+    err = get_credentials(DokanFileInfo, &credentials);
+    if (err != 0)
+        return err;
+
     /* get file system path */
     old_fs_path = get_fs_path(FileName);
     if (old_fs_path == NULL)
@@ -1097,7 +1291,7 @@ PVFS_Dokan_move_file(
     }
 
     /* rename/move the file */
-    ret = fs_rename(old_fs_path, new_fs_path, credentials);
+    ret = fs_rename(old_fs_path, new_fs_path, &credentials);
 
     free(old_fs_path);
     free(new_fs_path);
@@ -1171,19 +1365,24 @@ PVFS_Dokan_set_file_time(
 {
     char *fs_path;
     int ret, err;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
     PVFS_sys_attr attr;
 
     DbgPrint("SetFileTime: %S\n", FileName);
     DbgPrint("   Context: %llx\n", DokanFileInfo->Context);
 
+    /* load credentials */
+    err = get_credentials(DokanFileInfo, &credentials);
+    if (err != 0)
+        return err;
+
     /* get file system path */
     fs_path = get_fs_path(FileName);
     if (fs_path == NULL)
         return -1;
 
     /* convert times to PVFS */
-    ret = fs_getattr(fs_path, credentials, &attr);
+    ret = fs_getattr(fs_path, &credentials, &attr);
 
     DbgPrint("   fs_getattr returns: %d\n", ret);
 
@@ -1193,7 +1392,7 @@ PVFS_Dokan_set_file_time(
         convert_filetime((LPFILETIME) LastAccessTime, &attr.atime);
         convert_filetime((LPFILETIME) LastWriteTime, &attr.mtime);
 
-        ret = fs_setattr(fs_path, &attr, credentials);        
+        ret = fs_setattr(fs_path, &attr, &credentials);        
 
         DbgPrint("   fs_setattr returns: %d\n", ret);
     }
@@ -1445,6 +1644,7 @@ PVFS_Dokan_unmount(
 {
     DbgPrint("Unmount\n");
     DbgPrint("   Context: %llx\n", DokanFileInfo->Context);
+
     DbgPrint("Unmount exit: %d\n", 0);
 
     return 0;
@@ -1459,12 +1659,15 @@ PVFS_Dokan_get_disk_free_space(
     PDOKAN_FILE_INFO DokanFileInfo)
 {
     int ret, err;
-    PVFS_credentials *credentials;
+    PVFS_credentials credentials;
 
     DbgPrint("GetDiskFreeSpace\n");
     DbgPrint("   Context: %llx\n", DokanFileInfo->Context);
 
-    ret = fs_get_diskfreespace(credentials,
+    /* load credentials (of requestor) */
+    err = get_credentials(DokanFileInfo, &credentials);
+
+    ret = fs_get_diskfreespace(&credentials,
                                (PVFS_size *) FreeBytesAvailable, 
                                (PVFS_size *) TotalNumberOfBytes);
 
@@ -1533,6 +1736,9 @@ int __cdecl dokan_loop(PORANGEFS_OPTIONS
     PDOKAN_OPTIONS dokanOptions =
             (PDOKAN_OPTIONS) malloc(sizeof(DOKAN_OPTIONS));
 
+    /* init credential cache */
+    cred_cache = qhash_init(cred_compare, quickhash_64bit_hash, 1023);
+
     g_DebugMode = g_UseStdErr = options->debug;
 
     ZeroMemory(dokanOptions, sizeof(DOKAN_OPTIONS));
@@ -1579,6 +1785,7 @@ int __cdecl dokan_loop(PORANGEFS_OPTIONS
     dokanOperations->SetFileSecurityA = PVFS_Dokan_set_file_security;
     dokanOperations->Unmount = PVFS_Dokan_unmount;
 
+
     DbgPrint("Entering DokanMain\n");
 
     /* dokan loops until termination */
@@ -1612,6 +1819,8 @@ int __cdecl dokan_loop(PORANGEFS_OPTIONS
             DbgPrint("Unknown error: %d\n", status);
             break;
     }
+
+    qhash_destroy_and_finalize(cred_cache, struct cred_entry, hash_link, free);
 
     free(dokanOptions);
     free(dokanOperations);



More information about the Pvfs2-cvs mailing list