windows-stuff-20050529
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 30 May 2005 04:55:47 +0000 (04:55 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 30 May 2005 04:55:47 +0000 (04:55 +0000)
(1) Replace all calls to getenv() with GetEnvironment().  getenv() does
not read from the real environment but instead from a copy created by
the C RTL.

(2) Add support for preserving Kerberos 5 tickets during the Integrated
Logon process.   Now when Integrated Logon is used, the tickets will
be stored into the default ccache within the user session.

(3) Stress testing at MIT uncovered two code paths that could leave
threads in a permanent sleep state under heavy load.   Calls to
cm_SyncOpDone were added to plug this hole.

====================
This delta was composed from multiple commits as part of the CVS->Git migration.
The checkin message with each commit was inconsistent.
The following are the additional commit messages.
====================

Install afscpcc.exe and register the KFWLogon WinLogon Event Handler

14 files changed:
src/WINNT/afsd/NTMakefile
src/WINNT/afsd/afscpcc.c [new file with mode: 0644]
src/WINNT/afsd/afscpcc.rc [new file with mode: 0644]
src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/afskfw.c
src/WINNT/afsd/afskfw.h
src/WINNT/afsd/afslogon.c
src/WINNT/afsd/afslogon.def
src/WINNT/afsd/cm_buf.c
src/WINNT/afsd/cm_config.c
src/WINNT/afsd/cm_dcache.c
src/WINNT/afsd/cm_ioctl.c
src/WINNT/install/NSIS/OpenAFS.nsi
src/WINNT/install/wix/files.wxi

index 7194e87..8361c51 100644 (file)
@@ -282,7 +282,7 @@ install: install_headers install_objs $(CONF_DLLFILE) \
         $(EXEDIR)\afsdacl.exe \
        $(LOGON_DLLFILE) \
        $(EXEDIR)\afsshare.exe \
-       $(DESTDIR)\bin\kpasswd.exe $(EXEDIR)\cmdebug.exe
+       $(DESTDIR)\bin\kpasswd.exe $(EXEDIR)\cmdebug.exe $(EXEDIR)\afscpcc.exe
 
 install9X: install_headers $(CONF_DLLFILE) \
        $(EXEDIR)\klog.exe \
@@ -354,6 +354,12 @@ $(EXEDIR)\unlog.exe: $(OUT)\cunlog.obj $(OUT)\unlog.res $(EXELIBS)
        $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib
        $(EXEPREP)
 
+# afscpcc.exe
+$(EXEDIR)\afscpcc.exe: $(OUT)\afscpcc.obj $(OUT)\afscpcc.res $(LOGON_DLLLIBS)
+       $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib
+       $(EXEPREP)
+
+
 # afsd.exe
 AFSD_EXEFILE = $(EXEDIR)\afsd.exe
 
@@ -472,6 +478,8 @@ $(OUT)\tokens.res: tokens.rc AFS_component_version_number.h
 
 $(OUT)\unlog.res: unlog.rc AFS_component_version_number.h
 
+$(OUT)\afscpcc.res: afscpcc.rc AFS_component_version_number.h
+
 afsd_eventmessages.rc: afsd_eventmessages.h
 
 $(OUT)\afsd_service.res: afsd_service.rc afsd_eventmessages.rc AFS_component_version_number.h
diff --git a/src/WINNT/afsd/afscpcc.c b/src/WINNT/afsd/afscpcc.c
new file mode 100644 (file)
index 0000000..342ab6f
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2005, Secure Endpoints Inc.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the MIT License.  
+ */
+
+#include <windows.h>
+#include <afskfw.h>
+
+int main(int argc, char *argv[])
+{
+    if ( argc != 2 )
+        return 1;
+
+    KFW_initialize();
+
+    return KFW_AFS_copy_system_file_to_default_cache(argv[1]);
+}
+
+
diff --git a/src/WINNT/afsd/afscpcc.rc b/src/WINNT/afsd/afscpcc.rc
new file mode 100644 (file)
index 0000000..0315e83
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2005, Secure Endpoints Inc.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the MIT License.  
+ */
+
+/* Define VERSIONINFO resource */
+
+#define  AFS_VERINFO_FILE_DESCRIPTION "AFS Logon Copy Credentials Command"
+#define AFS_VERINFO_NAME "afscpcc"
+#define AFS_VERINFO_FILENAME "afscpcc.exe"
+
+#include "AFS_component_version_number.h"
+#include "..\..\config\NTVersioninfo.rc"
index bf5eebb..37189ec 100644 (file)
@@ -146,11 +146,8 @@ afsi_start()
     DWORD maxLogSize = 100 * 1024;
 
     afsi_file = INVALID_HANDLE_VALUE;
-    if (getenv("TEMP"))
-    {
-        StringCbCopyA(wd, sizeof(wd), getenv("TEMP"));
-    }
-    else
+    code = GetEnvironmentVariable("TEMP", wd, sizeof(wd));
+    if ( code == 0 || code > sizeof(wd) )
     {
         code = GetWindowsDirectory(wd, sizeof(wd));
         if (code == 0) 
@@ -186,10 +183,13 @@ afsi_start()
     WriteFile(afsi_file, t, strlen(t), &zilch, NULL);
     WriteFile(afsi_file, u, strlen(u), &zilch, NULL);
     p = "PATH=";
-    path = getenv("PATH");
+    code = GetEnvironmentVariable("PATH", NULL, 0);
+    path = malloc(code);
+    code = GetEnvironmentVariable("PATH", path, code);
     WriteFile(afsi_file, p, strlen(p), &zilch, NULL);
     WriteFile(afsi_file, path, strlen(path), &zilch, NULL);
     WriteFile(afsi_file, "\n", 1, &zilch, NULL);
+    free(path);
 
     /* Initialize C RTL Code Page conversion functions */
     /* All of the path info obtained from the SMB client is in the OEM code page */
@@ -1399,12 +1399,10 @@ static HANDLE
 OpenDumpFile(void)
 {
     char wd[256];
+    DWORD code;
 
-    if (getenv("TEMP"))
-    {
-        StringCbCopyA(wd, sizeof(wd), getenv("TEMP"));
-    }
-    else
+    code = GetEnvironmentVariable("TEMP", wd, sizeof(wd));
+    if ( code == 0 || code > sizeof(wd) )
     {
         if (!GetWindowsDirectory(wd, sizeof(wd)))
             return NULL;
index adc8587..771a511 100644 (file)
@@ -1080,7 +1080,7 @@ KFW_import_ccache_data(void)
                     code = pkrb5_cc_close(ctx,cc);
                     cc = 0;
                     code = pkrb5_cc_close(ctx,oldcc);
-                    cc = 0;
+                    oldcc = 0;
                     KRB5_error(code, "krb5_cc_copy_creds", 0, NULL, NULL);
                     continue;
                 }
@@ -1370,7 +1370,7 @@ KFW_AFS_destroy_tickets_for_cell(char * cell)
         return 0;
 
     if ( IsDebuggerPresent() ) {
-        OutputDebugString("KFW_AFS_destroy_ticets_for_cell: ");
+        OutputDebugString("KFW_AFS_destroy_tickets_for_cell: ");
         OutputDebugString(cell);
         OutputDebugString("\n");
     }
@@ -1422,6 +1422,60 @@ KFW_AFS_destroy_tickets_for_cell(char * cell)
     return 0;
 }
 
+int 
+KFW_AFS_destroy_tickets_for_principal(char * user)
+{
+    krb5_context               ctx = 0;
+    krb5_error_code            code;
+    int count;
+    char ** cells = NULL;
+    krb5_principal      princ = 0;
+    krb5_ccache                        cc  = 0;
+
+    if (!pkrb5_init_context)
+        return 0;
+
+    if ( IsDebuggerPresent() ) {
+        OutputDebugString("KFW_AFS_destroy_tickets_for_user: ");
+        OutputDebugString(user);
+        OutputDebugString("\n");
+    }
+
+    code = pkrb5_init_context(&ctx);
+    if (code) ctx = 0;
+
+    code = pkrb5_parse_name(ctx, user, &princ);
+    if (code) goto loop_cleanup;
+
+    code = KFW_get_ccache(ctx, princ, &cc);
+    if (code) goto loop_cleanup;
+
+    code = pkrb5_cc_destroy(ctx, cc);
+    if (!code) cc = 0;
+
+  loop_cleanup:
+    if ( cc ) {
+        pkrb5_cc_close(ctx, cc);
+        cc = 0;
+    }
+    if ( princ ) {
+        pkrb5_free_principal(ctx, princ);
+        princ = 0;
+    }
+
+    count = KFW_AFS_find_cells_for_princ(ctx, user, &cells, TRUE);
+    if ( count >= 1 ) {
+        while ( count-- ) {
+            KFW_AFS_update_cell_princ_map(ctx, cells[count], user, FALSE);
+            free(cells[count]);
+        }
+        free(cells);
+    }
+
+    pkrb5_free_context(ctx);
+    return 0;
+}
+
 int
 KFW_AFS_renew_expiring_tokens(void)
 {
@@ -3454,4 +3508,171 @@ KFW_AFS_get_lsa_principal(char * szUser, DWORD *dwSize)
     if (ctx)
         pkrb5_free_context(ctx);
     return success;
-}
\ No newline at end of file
+}
+
+#define AFS_LOGON_EVENT_NAME TEXT("AFS Logon")
+
+static void DebugEvent0(char *a) 
+{
+    HANDLE h; char *ptbuf[1];
+    h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
+    ptbuf[0] = a;
+    ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
+    DeregisterEventSource(h);
+}
+
+#define MAXBUF_ 512
+static void DebugEvent(char *b,...) 
+{
+    HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
+    va_list marker;
+    h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
+    va_start(marker,b);
+    vsprintf(buf, b, marker);
+    buf[MAXBUF_] = '\0';
+    ptbuf[0] = buf;
+    ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
+    DeregisterEventSource(h);
+    va_end(marker);
+}
+
+
+void
+KFW_AFS_copy_cache_to_system_file(char * user, char * szLogonId)
+{
+    char filename[256];
+    DWORD count;
+    char cachename[264] = "FILE:";
+    krb5_context               ctx = 0;
+    krb5_error_code            code;
+    krb5_principal              princ = 0;
+    krb5_ccache                        cc  = 0;
+    krb5_ccache                 ncc = 0;
+
+    if (!pkrb5_init_context)
+        return;
+
+    count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));
+    if ( count > sizeof(filename) || count == 0 ) {
+        GetWindowsDirectory(filename, sizeof(filename));
+    }
+
+    if ( strlen(filename) + strlen(szLogonId) + 2 > sizeof(filename) )
+        return;
+
+    strcat(filename, "\\");
+    strcat(filename, szLogonId);    
+
+    strcat(cachename, filename);
+
+    DebugEvent("Copy2File %s", filename);
+
+    DeleteFile(filename);
+
+    code = pkrb5_init_context(&ctx);
+    if (code) ctx = 0;
+
+    code = pkrb5_parse_name(ctx, user, &princ);
+    if (code) goto cleanup;
+
+    code = KFW_get_ccache(ctx, princ, &cc);
+    if (code) goto cleanup;
+
+    code = pkrb5_cc_resolve(ctx, cachename, &ncc);
+    if (code) goto cleanup;
+
+    code = pkrb5_cc_initialize(ctx, ncc, princ);
+    if (code) goto cleanup;
+
+    DebugEvent0("Copy2File copying");
+
+    code = pkrb5_cc_copy_creds(ctx,cc,ncc);
+
+    DebugEvent("Copy2File copy_creds=%d", code);
+
+  cleanup:
+    if ( cc ) {
+        pkrb5_cc_close(ctx, cc);
+        cc = 0;
+    }
+    if ( ncc ) {
+        pkrb5_cc_close(ctx, ncc);
+        ncc = 0;
+    }
+    if ( princ ) {
+        pkrb5_free_principal(ctx, princ);
+        princ = 0;
+    }
+
+    if (ctx)
+        pkrb5_free_context(ctx);
+}
+
+int
+KFW_AFS_copy_system_file_to_default_cache(char * filename)
+{
+    DWORD count;
+    char cachename[264] = "FILE:";
+    HANDLE hFile;
+    krb5_context               ctx = 0;
+    krb5_error_code            code;
+    krb5_principal              princ = 0;
+    krb5_ccache                        cc  = 0;
+    krb5_ccache                 ncc = 0;
+    int retval = 1;
+
+    if (!pkrb5_init_context)
+        return 1;
+
+    if ( strlen(filename) + 6 > sizeof(cachename) )
+        return 1;
+
+    strcat(cachename, filename);
+
+    DebugEvent("Copy2Cache %s", cachename);
+
+    code = pkrb5_init_context(&ctx);
+    if (code) ctx = 0;
+
+    code = pkrb5_cc_resolve(ctx, cachename, &cc);
+    if (code) goto cleanup;
+    
+    DebugEvent("Copy2Cache resolve=%d", code);
+
+    code = pkrb5_cc_get_principal(ctx, cc, &princ);
+
+    code = pkrb5_cc_default(ctx, &ncc);
+    DebugEvent("Copy2Cache default=%d", code);
+
+    if (!code) {
+        code = pkrb5_cc_initialize(ctx, ncc, princ);
+        DebugEvent("Copy2Cache initialize=%d", code);
+
+        code = pkrb5_cc_copy_creds(ctx,cc,ncc);
+        DebugEvent("Copy2Cache copy_creds=%d", code);
+    }
+    if ( ncc ) {
+        pkrb5_cc_close(ctx, ncc);
+        ncc = 0;
+    }
+
+    retval=0;   /* success */
+
+  cleanup:
+    if ( cc ) {
+        pkrb5_cc_close(ctx, cc);
+        cc = 0;
+    }
+
+    DeleteFile(filename);
+
+    if ( princ ) {
+        pkrb5_free_principal(ctx, princ);
+        princ = 0;
+    }
+
+    if (ctx)
+        pkrb5_free_context(ctx);
+
+    return 0;
+}
index 352e059..7c744e7 100644 (file)
@@ -47,6 +47,7 @@ void KFW_initialize(void);
 void KFW_cleanup(void);
 int  KFW_is_available(void);
 int  KFW_AFS_destroy_tickets_for_cell(char *);
+int  KFW_AFS_destroy_tickets_for_principal(char *);
 int  KFW_AFS_renew_expiring_tokens(void);
 int  KFW_AFS_get_cred( char * username, 
                         char * cell,
@@ -62,6 +63,10 @@ int  KFW_AFS_get_cellconfig(char *, struct afsconf_cell *, char *);
 void KFW_import_windows_lsa(void);
 BOOL KFW_AFS_get_lsa_principal(char *, DWORD *);
 
+/* These functions are only to be used in the afslogon.dll */
+void KFW_AFS_copy_cache_to_system_file(char *, char *);
+int  KFW_AFS_copy_system_file_to_default_cache(char *);
+
 /* From afs/krb_prot.h */
 /* values for kerb error codes */
 #define         KERB_ERR_OK                              0
index 34833aa..85ac65a 100644 (file)
@@ -41,8 +41,10 @@ WSADATA WSAjunk;
 void DebugEvent0(char *a) 
 {
     HANDLE h; char *ptbuf[1];
+    
     if (!ISLOGONTRACE(TraceOption))
         return;
+    
     h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
     ptbuf[0] = a;
     ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
@@ -651,6 +653,7 @@ DWORD APIENTRY NPLogonNotify(
     char logonDomain[MAX_DOMAIN_LENGTH]="";
     char cell[256]="<non-integrated logon>";
     char homePath[MAX_PATH]="";
+    char szLogonId[128] = "";
 
     MSV1_0_INTERACTIVE_LOGON *IL;
 
@@ -675,15 +678,33 @@ DWORD APIENTRY NPLogonNotify(
     int retryInterval;
     int sleepInterval;
 
+    (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
+                         0, KEY_QUERY_VALUE, &NPKey);
+    LSPsize=sizeof(TraceOption);
+    RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
+                     &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
+
+    RegCloseKey (NPKey);
+
+    DebugEvent("NPLogonNotify - LoginId(%d,%d)", lpLogonId->HighPart, lpLogonId->LowPart);
+
     /* Make sure the AFS Libraries are initialized */
     AfsLogonInit();
 
     /* Initialize Logon Script to none */
     *lpLogonScript=NULL;
     
-    /* TODO: We should check the value of lpAuthentInfoType before assuming that it is
-       MSV1_0_INTERACTIVE_LOGON though for our purposes KERB_INTERACTIVE_LOGON is
-       co-incidentally equivalent. */
+    /* MSV1_0_INTERACTIVE_LOGON and KERB_INTERACTIVE_LOGON are equivalent for
+     * our purposes */
+
+    if ( wcscmp(lpAuthentInfoType,L"MSV1_0:Interactive") && 
+         wcscmp(lpAuthentInfoType,L"Kerberos:Interactive") )
+    {
+        DebugEvent("Unsupported Authentication Info Type: %S",
+                   lpAuthentInfoType);
+        return 0;
+    }
+
     IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo;
 
     /* Are we interactive? */
@@ -708,14 +729,6 @@ DWORD APIENTRY NPLogonNotify(
         }
     }
 
-    (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
-                         0, KEY_QUERY_VALUE, &NPKey);
-    LSPsize=sizeof(TraceOption);
-    RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
-                     &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
-
-    RegCloseKey (NPKey);
-
     /*
      * Get Logon options
      */
@@ -873,9 +886,15 @@ DWORD APIENTRY NPLogonNotify(
     }
 
     DebugEvent("while loop exited");
-    /* remove any kerberos 5 tickets currently held by the SYSTEM account */
-    if ( KFW_is_available() )
-        KFW_AFS_destroy_tickets_for_cell(cell);
+    /* remove any kerberos 5 tickets currently held by the SYSTEM account
+     * for this user 
+     */
+    if ( KFW_is_available() ) {
+        sprintf(szLogonId,"%d.%d",lpLogonId->HighPart, lpLogonId->LowPart);
+        KFW_AFS_copy_cache_to_system_file(uname, szLogonId);
+
+        KFW_AFS_destroy_tickets_for_principal(uname);
+    }
 
     if (code) {
         char msg[128];
@@ -1040,20 +1059,16 @@ VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo )
 
 VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
 {
-    DWORD code;
     TCHAR profileDir[1024] = TEXT("");
     DWORD  len = 1024;
     PTOKEN_USER  tokenUser = NULL;
     DWORD  retLen;
-    HANDLE hToken;
-
     WCHAR szUserW[128] = L"";
     char  szUserA[128] = "";
     char  szClient[MAX_PATH];
     char szPath[MAX_PATH] = "";
     NETRESOURCE nr;
     DWORD res;
-    DWORD gle;
     DWORD dwSize;
 
     /* Make sure the AFS Libraries are initialized */
@@ -1061,6 +1076,8 @@ VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
 
     DebugEvent0("AFS_Logon_Event - Start");
 
+    DebugEvent("AFS_Logon_Event Process ID: %d",GetCurrentProcessId());
+
     if (!GetTokenInformation(pInfo->hToken, TokenUser, NULL, 0, &retLen))
     {
         if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
@@ -1123,3 +1140,117 @@ VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
     DebugEvent0("AFS_Logon_Event - End");
 }
 
+static BOOL
+GetSecurityLogonSessionData(HANDLE hToken, PSECURITY_LOGON_SESSION_DATA * ppSessionData)
+{
+    NTSTATUS Status = 0;
+    HANDLE  TokenHandle;
+    TOKEN_STATISTICS Stats;
+    DWORD   ReqLen;
+    BOOL    Success;
+
+    if (!ppSessionData)
+        return FALSE;
+    *ppSessionData = NULL;
+
+#if 0
+    Success = OpenProcessToken( HANDLE GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
+    if ( !Success )
+        return FALSE;
+#endif
+
+    Success = GetTokenInformation( hToken, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen );
+#if 0
+    CloseHandle( TokenHandle );
+#endif
+    if ( !Success )
+        return FALSE;
+
+    Status = LsaGetLogonSessionData( &Stats.AuthenticationId, ppSessionData );
+    if ( FAILED(Status) || !ppSessionData )
+        return FALSE;
+
+    return TRUE;
+}
+
+VOID KFW_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
+{
+    DWORD code;
+
+    WCHAR szUserW[128] = L"";
+    char  szUserA[128] = "";
+    char  szClient[MAX_PATH];
+    char szPath[MAX_PATH] = "";
+    char szLogonId[128] = "";
+    NETRESOURCE nr;
+    DWORD res;
+    DWORD gle;
+    DWORD dwSize;
+    DWORD dwDisp;
+    DWORD dwType;
+    DWORD count;
+    VOID * ticketData;
+    char filename[256];
+    char commandline[512];
+    STARTUPINFO startupinfo;
+    PROCESS_INFORMATION procinfo;
+
+    LUID LogonId = {0, 0};
+    PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL;
+
+    HKEY hKey1 = NULL, hKey2 = NULL;
+
+    /* Make sure the KFW Libraries are initialized */
+    AfsLogonInit();
+
+    DebugEvent0("KFW_Logon_Event - Start");
+
+    GetSecurityLogonSessionData( pInfo->hToken, &pLogonSessionData );
+
+    if ( pLogonSessionData ) {
+        LogonId = pLogonSessionData->LogonId;
+        DebugEvent("KFW_Logon_Event - LogonId(%d,%d)", LogonId.HighPart, LogonId.LowPart);
+
+        sprintf(szLogonId,"%d.%d",LogonId.HighPart, LogonId.LowPart);
+        LsaFreeReturnBuffer( pLogonSessionData );
+    } else {
+        DebugEvent0("KFW_Logon_Event - Unable to determine LogonId");
+        return;
+    }
+
+    count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));
+    if ( count > sizeof(filename) || count == 0 ) {
+        GetWindowsDirectory(filename, sizeof(filename));
+    }
+
+    if ( strlen(filename) + strlen(szLogonId) + 2 <= sizeof(filename) ) {
+        strcat(filename, "\\");
+        strcat(filename, szLogonId);    
+
+        sprintf(commandline, "afscpcc.exe \"%s\"", filename);
+
+        GetStartupInfo(&startupinfo);
+        if (CreateProcessAsUser( pInfo->hToken,
+                             "afscpcc.exe",
+                             commandline,
+                             NULL,
+                             NULL,
+                             FALSE,
+                             CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS,
+                             NULL,
+                             NULL,
+                             &startupinfo,
+                             &procinfo)) 
+        {
+            WaitForSingleObject(procinfo.hProcess, 30000);
+
+            CloseHandle(procinfo.hThread);
+            CloseHandle(procinfo.hProcess);
+        }
+    }
+
+    DeleteFile(filename);
+
+    DebugEvent0("KFW_Logon_Event - End");
+}
+
index fa8dacc..77a9368 100644 (file)
@@ -11,5 +11,7 @@ EXPORTS
     AFS_Startup_Event
     AFS_Logoff_Event
     AFS_Logon_Event
+    KFW_Logon_Event
+
 
 
index 151bccc..641d450 100644 (file)
@@ -592,7 +592,7 @@ void buf_Recycle(cm_buf_t *bp)
         }
 
         /* we better find it */
-        osi_assertx(tbp != NULL, "buf_GetNewLocked: hash table screwup");
+        osi_assertx(tbp != NULL, "buf_Recycle: hash table screwup");
 
         *lbpp = bp->hashp;     /* hash out */
 
@@ -806,9 +806,7 @@ long buf_GetNew(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp)
     pageOffset.HighPart = offsetp->HighPart;
     pageOffset.LowPart = offsetp->LowPart & ~(cm_data.buf_blockSize-1);
     while (1) {
-        lock_ObtainWrite(&buf_globalLock);
-        bp = buf_LockedFind(scp, &pageOffset);
-        lock_ReleaseWrite(&buf_globalLock);
+        bp = buf_Find(scp, &pageOffset);
         if (bp) {
             /* lock it and break out */
             lock_ObtainMutex(&bp->mx);
@@ -848,6 +846,7 @@ long buf_GetNew(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp)
 }
 
 /* get a page, returning it held but unlocked.  Make sure it is complete */
+/* The scp must be unlocked when passed to this function */
 long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp)
 {
     cm_buf_t *bp;
@@ -869,9 +868,7 @@ long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp)
         buf_ValidateBufQueues();
 #endif /* TESTING */
 
-        lock_ObtainWrite(&buf_globalLock);
-        bp = buf_LockedFind(scp, &pageOffset);
-        lock_ReleaseWrite(&buf_globalLock);
+        bp = buf_Find(scp, &pageOffset);
         if (bp) {
             /* lock it and break out */
             lock_ObtainMutex(&bp->mx);
index 25672c5..3d71d37 100644 (file)
@@ -201,6 +201,7 @@ long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
        int tracking = 1, partial = 0;
 #if defined(DJGPP) || defined(AFS_WIN95_ENV)
     char *afsconf_path;
+    DWORD dwSize;
 #endif
 
     cm_GetCellServDB(wdir);
@@ -212,11 +213,15 @@ long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
         /* If we are in Win95 here, we are linking with klog etc. and are
         using DJGPP client even though DJGPP is not defined.  So we still
         need to check AFSCONF for location. */
-        afsconf_path = getenv("AFSCONF");
+        dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
+        afsconf_path = malloc(dwSize);
+        dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
         if (!afsconf_path)
             strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
-        else
+        else {
             strcpy(wdir, afsconf_path);
+            free(afsconf_path);
+        }
         strcat(wdir, "/");
         strcat(wdir, AFS_CELLSERVDB);
         /*fprintf(stderr, "opening cellservdb file %s\n", wdir);*/
@@ -485,17 +490,22 @@ long cm_GetRootCellName(char *cellNamep)
         FILE *thisCell;
         char thisCellPath[256];
         char *newline;
+        DWORD dwSize;
 
 #ifdef DJGPP
         strcpy(thisCellPath, cm_confDir);
 #else
         /* Win 95 */
         char *afsconf_path;
-        afsconf_path = getenv("AFSCONF");
+        dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
+        afsconf_path = malloc(dwSize);
+        dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
         if (!afsconf_path)
           strcpy(thisCellPath, AFSDIR_CLIENT_ETC_DIRPATH);
-        else
+        else {
           strcpy(thisCellPath, afsconf_path);
+          free(afsconf_path);
+        }
 #endif
         strcat(thisCellPath,"/");
 
@@ -532,11 +542,19 @@ cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
 #ifdef DJGPP
         strcpy(wdir,cm_confDir);
 #else
-        char *afsconf_path = getenv("AFSCONF");
+        DWORD dwSize;
+        char *afsconf_path;
+    
+        dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
+        afsconf_path = malloc(dwSize);
+        dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
+
         if (!afsconf_path)
-          strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
-        else
-          strcpy(wdir, afsconf_path);
+            strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
+        else {
+            strcpy(wdir, afsconf_path);
+            free(afsconf_path);
+        }
 #endif /* !DJGPP */
         strcat(wdir,"/");
 #endif /* DJGPP || WIN95 */
@@ -682,13 +700,14 @@ long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep)
 
 long cm_CloseCellFile(cm_configFile_t *filep)
 {
-       char wdir[256];
+    char wdir[256];
     char sdir[256];
     long code;
     long closeCode;
     int tlen;
 #ifdef AFS_WIN95_ENV
     char *afsconf_path;
+    DWORD dwSize;
 #endif
        closeCode = fclose((FILE *)filep);
 
@@ -702,11 +721,15 @@ long cm_CloseCellFile(cm_configFile_t *filep)
 #ifdef DJGPP
     strcpy(wdir,cm_confDir);
 #else
-    afsconf_path = getenv("AFSCONF");
+    dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
+    afsconf_path = malloc(dwSize);
+    dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
     if (!afsconf_path)
         strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
-    else
+    else {
         strcpy(wdir, afsconf_path);
+        free(afsconf_path);
+    }
 #endif /* !DJGPP */
     strcat(wdir,"/");
 #endif /* DJGPP || WIN95 */
@@ -739,6 +762,7 @@ void cm_GetConfigDir(char *dir)
     int tlen;
 #ifdef AFS_WIN95_ENV
     char *afsconf_path;
+    DWORD dwSize;
 #endif
 
 #if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
@@ -751,11 +775,15 @@ void cm_GetConfigDir(char *dir)
 #ifdef DJGPP
     strcpy(wdir,cm_confDir);
 #else
-    afsconf_path = getenv("AFSCONF");
+    dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0);
+    afsconf_path = malloc(dwSize);
+    dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize);
     if (!afsconf_path)
         strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
-    else
+    else {
         strcpy(wdir, afsconf_path);
+        free(afsconf_path);
+    }
 #endif /* !DJGPP */
     strcat(wdir,"\\");
 #endif /* DJGPP || WIN95 */
index 8d347f6..d5d7c70 100644 (file)
@@ -727,7 +727,9 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize,
             break;
 
         /* try to lock it, and quit if we can't (simplifies locking) */
+        lock_ReleaseMutex(&scp->mx);
         code = lock_TryMutex(&bufp->mx);
+        lock_ObtainMutex(&scp->mx);
         if (code == 0) {
             buf_Release(bufp);
             break;
@@ -781,7 +783,9 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize,
             break;
 
         /* try to lock it, and quit if we can't (simplifies locking) */
+        lock_ReleaseMutex(&scp->mx);
         code = lock_TryMutex(&bufp->mx);
+        lock_ObtainMutex(&scp->mx);
         if (code == 0) {
             buf_Release(bufp);
             break;
@@ -890,27 +894,27 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp,
      * sequence at a time.
      */
 
+    // lock_ObtainMutex(&cm_bufGetMutex);
     /* first hold all buffers, since we can't hold any locks in buf_Get */
     while (1) {
         /* stop at chunk boundary */
-        if (collected >= cm_chunkSize) break;
+        if (collected >= cm_chunkSize) 
+            break;
                 
         /* see if the next page would be past EOF */
-        if (LargeIntegerGreaterThanOrEqualTo(pageBase, fileSize)) break;
-
-        lock_ObtainMutex(&cm_bufGetMutex);
+        if (LargeIntegerGreaterThanOrEqualTo(pageBase, fileSize)) 
+            break;
 
         code = buf_Get(scp, &pageBase, &tbp);
         if (code) {
             lock_ReleaseMutex(&cm_bufGetMutex);
             lock_ObtainMutex(&scp->mx);
+            cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
             return code;
         }
                 
         buf_Release(tbp);
 
-        lock_ReleaseMutex(&cm_bufGetMutex);
-
         toffset.HighPart = 0;
         toffset.LowPart = cm_data.buf_blockSize;
         pageBase = LargeIntegerAdd(toffset, pageBase);
@@ -920,6 +924,8 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp,
     /* reserve a chunk's worth of buffers if possible */
     reserving = buf_TryReserveBuffers(cm_chunkSize / cm_data.buf_blockSize);
 
+    // lock_ReleaseMutex(&cm_bufGetMutex);
+
     pageBase = *offsetp;
     collected = pageBase.LowPart & (cm_chunkSize - 1);
 
@@ -1376,6 +1382,9 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up,
     code = cm_MapRPCError(code, reqp);
 
     lock_ObtainMutex(&scp->mx);
+    
+    cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_FETCHSTATUS);
+
     /* we know that no one else has changed the buffer, since we still have
      * the fetching flag on the buffers, and we have the scp locked again.
      * Copy in the version # into the buffer if we got code 0 back from the
index 47a7094..d4e5ca5 100644 (file)
@@ -2317,6 +2317,7 @@ long cm_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp)
     HANDLE hLogFile;
     char logfileName[MAX_PATH+1];
     char *cookie;
+    DWORD dwSize;
   
 #ifdef _DEBUG  
     static _CrtMemState memstate;
@@ -2325,12 +2326,8 @@ long cm_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cm_SkipIoctlPath(ioctlp);
     memcpy(&inValue, ioctlp->inDatap, sizeof(long));
   
-    if (getenv("TEMP"))
-    {
-        strncpy(logfileName, getenv("TEMP"), MAX_PATH);
-        logfileName[MAX_PATH] = '\0';
-    }
-    else
+    dwSize = GetEnvironmentVariable("TEMP", logfileName, sizeof(logfileName));
+    if ( dwSize == 0 || dwSize > sizeof(logfileName) )
     {
         GetWindowsDirectory(logfileName, sizeof(logfileName));
     }
index f979241..e7577b2 100644 (file)
@@ -546,6 +546,7 @@ Section "AFS Client" secClient
   
   SetOutPath "$SYSDIR"
   !insertmacro ReplaceDLL "${AFS_CLIENT_BUILDDIR}\afslogon.dll" "$SYSDIR\afslogon.dll" "$INSTDIR"
+  File "${AFS_CLIENT_BUILDDIR}\afscpcc.exe"
    
    Call AFSLangFiles
 
@@ -726,6 +727,11 @@ skipremove:
   WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" "Logoff" "AFS_Logoff_Event"
   WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" "Startup" "AFS_Startup_Event"
 
+  WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" "Asynchronous" 0
+  WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" "Impersonate"  0
+  WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" "DLLName" "afslogon.dll"
+  WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" "Logon" "KFW_Logon_Event"
+
   SetRebootFlag true
   
   WriteUninstaller "$INSTDIR\Uninstall.exe"
@@ -1800,10 +1806,12 @@ StartRemove:
   Delete /REBOOTOK "$SYSDIR\afsserver.cpl"
   Delete /REBOOTOK "$SYSDIR\afs_cpa.cpl"
   Delete /REBOOTOK "$SYSDIR\afslogon.dll"
+  Delete /REBOOTOK "$SYSDIR\afscpcc.exe"
 
   Delete /REBOOTOK "$SYSDIR\afsserver.pdb"
   Delete /REBOOTOK "$SYSDIR\afs_cpa.pdb"
   Delete /REBOOTOK "$SYSDIR\afslogon.pdb"
+  Delete /REBOOTOK "$SYSDIR\afscpcc.pdb"
 
   RMDir /r "$INSTDIR\Documentation\html\CmdRef"
   RMDir /r "$INSTDIR\Documentation\html\InstallGd"
index cf18477..de2f811 100644 (file)
@@ -3,6 +3,7 @@
     <Directory Id="SystemFolder" SourceName="System">
         <Component Id="cmf_afslogon_DLL" Guid="123197FE-4F53-4035-8D51-FCFB6B50A777">
             <File Id="fileafslogon_DLL" Name="afslogon.dll" LongName="afslogon.dll" KeyPath="yes" DiskId="1" src="$(var.ClientDir)afslogon.dll" />
+            <File Id="fileafscpcc_EXE"  Name="afscpcc.exe"  LongName="afscpcc.exe"  DiskId="1" src="$(var.ClientDir)afscpcc.exe" />
             <Registry Id="reg_afslogon01" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" Action="createKeyAndRemoveKeyOnUninstall" />
             <Registry Id="reg_afslogon02" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" />
             <Registry Id="reg_afslogon03" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" Name="Asynchronous" Type="integer" Value="0" />
             <Registry Id="reg_afslogon06" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" Name="Logoff" Type="string" Value="AFS_Logoff_Event" />
             <Registry Id="reg_afslogon07" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" Name="Logon" Type="string" Value="AFS_Logon_Event" />
             <Registry Id="reg_afslogon08" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" Name="Startup" Type="string" Value="AFS_Startup_Event" />
+            <Registry Id="reg_afslogon09" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" Name="Asynchronous" Type="integer" Value="0" />
+            <Registry Id="reg_afslogon10" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" Name="Impersonate" Type="integer" Value="0" />
+            <Registry Id="reg_afslogon11" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" Name="DLLName" Type="string" Value="[#fileafslogon_DLL]" />
+            <Registry Id="reg_afslogon13" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" Name="Logon" Type="string" Value="KFW_Logon_Event" />
         </Component>
     <?ifdef DebugSyms?>
         <Component Id="cmp_ClientSystemDebug" Guid="DD34DA09-D9DA-4A5A-9521-87B7738A7D53">
                        <File Id="fileafslogon_PDB" Name="afslogon.pdb" LongName="afslogon.pdb" KeyPath="yes" DiskId="1" src="$(var.ClientDir)afslogon.pdb" />
+                       <File Id="fileafscpcc_PDB" Name="afscpcc.pdb" LongName="afscpcc.pdb" DiskId="1" src="$(var.ClientDir)afscpcc.pdb" />
         </Component>
     <?endif?>
     </Directory>