getipaddrlist-20040318
[openafs.git] / src / WINNT / client_creds / afskfw.c
index 30f8188..bedb85f 100644 (file)
@@ -397,34 +397,50 @@ void
 KFW_initialize(void)
 {
     static int inited = 0;
+
     if ( !inited ) {
-        inited = 1;
-        LoadFuncs(KRB5_DLL, k5_fi, &hKrb5, 0, 1, 0, 0);
-        LoadFuncs(KRB4_DLL, k4_fi, &hKrb5, 0, 1, 0, 0);
-        LoadFuncs(COMERR_DLL, ce_fi, &hComErr, 0, 0, 1, 0);
-        LoadFuncs(SERVICE_DLL, service_fi, &hService, 0, 1, 0, 0);
+        char mutexName[MAX_PATH];
+        HANDLE hMutex = NULL;
+
+        sprintf(mutexName, "AFS KFW Init pid=%d", getpid());
+        
+        hMutex = CreateMutex( NULL, TRUE, mutexName );
+        if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
+            if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) {
+                return;
+            }
+        }
+        if ( !inited ) {
+            inited = 1;
+            LoadFuncs(KRB5_DLL, k5_fi, &hKrb5, 0, 1, 0, 0);
+            LoadFuncs(KRB4_DLL, k4_fi, &hKrb4, 0, 1, 0, 0);
+            LoadFuncs(COMERR_DLL, ce_fi, &hComErr, 0, 0, 1, 0);
+            LoadFuncs(SERVICE_DLL, service_fi, &hService, 0, 1, 0, 0);
 #ifdef USE_MS2MIT
-        LoadFuncs(SECUR32_DLL, lsa_fi, &hSecur32, 0, 1, 1, 1);
+            LoadFuncs(SECUR32_DLL, lsa_fi, &hSecur32, 0, 1, 1, 1);
 #endif /* USE_MS2MIT */
-        LoadFuncs(KRB524_DLL, k524_fi, &hKrb524, 0, 1, 1, 1);
-        LoadFuncs(PROFILE_DLL, profile_fi, &hProfile, 0, 1, 0, 0);
-        LoadFuncs(AFSTOKENS_DLL, afst_fi, &hAfsTokens, 0, 1, 0, 0);
-        LoadFuncs(AFSCONF_DLL, afsc_fi, &hAfsConf, 0, 1, 0, 0);
-        LoadFuncs(LEASH_DLL, leash_fi, &hLeash, 0, 1, 0, 0);
-        LoadFuncs(CCAPI_DLL, ccapi_fi, &hCCAPI, 0, 1, 0, 0);
-
-        if ( KFW_is_available() ) {
-            char rootcell[MAXCELLCHARS+1];
+            LoadFuncs(KRB524_DLL, k524_fi, &hKrb524, 0, 1, 1, 1);
+            LoadFuncs(PROFILE_DLL, profile_fi, &hProfile, 0, 1, 0, 0);
+            LoadFuncs(AFSTOKENS_DLL, afst_fi, &hAfsTokens, 0, 1, 0, 0);
+            LoadFuncs(AFSCONF_DLL, afsc_fi, &hAfsConf, 0, 1, 0, 0);
+            LoadFuncs(LEASH_DLL, leash_fi, &hLeash, 0, 1, 0, 0);
+            LoadFuncs(CCAPI_DLL, ccapi_fi, &hCCAPI, 0, 1, 0, 0);
+
+            if ( KFW_is_available() ) {
+                char rootcell[MAXCELLCHARS+1];
 #ifdef USE_MS2MIT
-            KFW_import_windows_lsa();
+                KFW_import_windows_lsa();
 #endif /* USE_MS2MIT */
-            KFW_import_ccache_data();
-                   KFW_AFS_renew_expiring_tokens();
+                KFW_import_ccache_data();
+                KFW_AFS_renew_expiring_tokens();
 
-            /* WIN32 NOTE: no way to get max chars */
-            if (!pcm_GetRootCellName(rootcell))
-                KFW_AFS_renew_token_for_cell(rootcell);
+                /* WIN32 NOTE: no way to get max chars */
+                if (!pcm_GetRootCellName(rootcell))
+                    KFW_AFS_renew_token_for_cell(rootcell);
+            }
         }
+        ReleaseMutex(hMutex);
+        CloseHandle(hMutex);
     }
 }
 
@@ -490,7 +506,7 @@ KFW_is_available(void)
          hSecur32 && 
 #endif /* USE_MS2MIT */
          hKrb524 &&
-         hProfile && hAfsTokens && hAfsConf )
+         hProfile && hAfsTokens && hAfsConf && hLeash && hCCAPI )
         return TRUE;
     return FALSE;
 }
@@ -832,6 +848,9 @@ KFW_get_ccache(krb5_context alt_ctx, krb5_principal principal, krb5_ccache * cc)
     char * ccname = 0;
     krb5_error_code code;
 
+    if (!pkrb5_init_context)
+        return 0;
+
     if ( alt_ctx ) {
         ctx = alt_ctx;
     } else {
@@ -878,6 +897,9 @@ KFW_import_windows_lsa(void)
     char cell[128]="";
     int i;
          
+    if (!pkrb5_init_context)
+        return;
+
     if ( !MSLSA_IsKerberosLogon() )
         return;
 
@@ -1138,6 +1160,9 @@ KFW_AFS_get_cred(char * username,
     int  cell_count=0;
     afsconf_cell cellconfig;
 
+    if (!pkrb5_init_context)
+        return 0;
+
     if ( IsDebuggerPresent() ) {
         OutputDebugString("KFW_AFS_get_cred for token ");
         OutputDebugString(username);
@@ -1262,6 +1287,9 @@ KFW_AFS_destroy_tickets_for_cell(char * cell)
     int count;
     char ** principals = NULL;
 
+    if (!pkrb5_init_context)
+        return 0;
+
     if ( IsDebuggerPresent() ) {
         OutputDebugString("KFW_AFS_destroy_ticets_for_cell: ");
         OutputDebugString(cell);
@@ -1329,6 +1357,9 @@ KFW_AFS_renew_expiring_tokens(void)
     char local_cell[MAXCELLCHARS+1]="";
     afsconf_cell cellconfig;
 
+    if (!pkrb5_init_context)
+        return 0;
+
     if ( pcc_next == NULL ) // nothing to do
         return 0;
 
@@ -1422,6 +1453,9 @@ KFW_AFS_renew_token_for_cell(char * cell)
     int count;
     char ** principals = NULL;
 
+    if (!pkrb5_init_context)
+        return 0;
+
     if ( IsDebuggerPresent() ) {
         OutputDebugString("KFW_AFS_renew_token_for_cell:");
         OutputDebugString(cell);
@@ -1435,7 +1469,9 @@ KFW_AFS_renew_token_for_cell(char * cell)
     if ( count > 0 ) {
         krb5_principal      princ = 0;
         krb5_principal      service = 0;
+#ifdef COMMENT
         krb5_creds          mcreds, creds;
+#endif /* COMMENT */
         krb5_ccache                    cc  = 0;
         const char * realm = NULL;
         afsconf_cell cellconfig;
@@ -1554,6 +1590,9 @@ KFW_renew(krb5_context alt_ctx, krb5_ccache alt_cc)
     krb5_creds                         my_creds;
     krb5_data                   *realm = 0;
 
+    if (!pkrb5_init_context)
+        return 0;
+
        memset(&my_creds, 0, sizeof(krb5_creds));
 
     if ( alt_ctx ) {
@@ -1831,6 +1870,9 @@ KFW_kdestroy(krb5_context alt_ctx, krb5_ccache alt_cc)
     krb5_ccache                        cc;
     krb5_error_code            code;
 
+    if (!pkrb5_init_context)
+        return 0;
+
     if (alt_ctx)
     {
         ctx = alt_ctx;
@@ -2538,6 +2580,9 @@ KFW_AFS_klog(
         return(-2);
     }
 
+    if (!pkrb5_init_context)
+        return 0;
+
     memset(RealmName, '\0', sizeof(RealmName));
     memset(CellName, '\0', sizeof(CellName));
     memset(ServiceName, '\0', sizeof(ServiceName));
@@ -2818,6 +2863,9 @@ afs_realm_of_cell(afsconf_cell *cellconfig)
     if (!cellconfig)
         return 0;
 
+    if (!pkrb5_init_context)
+        return 0;
+
     r = pkrb5_init_context(&ctx); 
     if ( !r )
         r = pkrb5_get_host_realm(ctx, cellconfig->hostName[0], &realmlist);
@@ -3192,7 +3240,7 @@ ObtainTokensFromUserIfNeeded(HWND hWnd)
     struct ktc_principal    aserver;
     struct ktc_principal    aclient;
     struct ktc_token   atoken;
-    krb5_context ctx;
+    krb5_context ctx = 0;
     krb5_timestamp now = 0;
     krb5_error_code code;
     int serverReachable = 0;
@@ -3205,6 +3253,7 @@ ObtainTokensFromUserIfNeeded(HWND hWnd)
 #endif /* USE_FSPROBE */
     DWORD       CurrentState;
     char        HostName[64];
+    int         use_kfw = KFW_is_available();
 
     CurrentState = 0;
     memset(HostName, '\0', sizeof(HostName));
@@ -3216,7 +3265,10 @@ ObtainTokensFromUserIfNeeded(HWND hWnd)
         return;
     }
 
-    if ( KFW_is_available() ) {
+    if (!pkrb5_init_context)
+        return;
+
+    if ( use_kfw ) {
         code = pkrb5_init_context(&ctx);
         if ( code ) goto cleanup;
     }
@@ -3233,7 +3285,7 @@ ObtainTokensFromUserIfNeeded(HWND hWnd)
 
     rc = pktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient);
 
-    if ( KFW_is_available() ) {
+    if ( use_kfw ) {
         code = pkrb5_timeofday(ctx, &now);
         if ( code ) 
             now = 0;
@@ -3281,7 +3333,7 @@ ObtainTokensFromUserIfNeeded(HWND hWnd)
 #ifdef USE_FSPROBE
     serverReachable = cellPing(NULL);
 #else
-    if ( KFW_is_available() ) {
+    if ( use_kfw ) {
         // If we can't use the FSProbe interface we can attempt to forge
         // a kinit and if we can back an invalid user error we know the
         // kdc is at least reachable
@@ -3346,7 +3398,7 @@ ObtainTokensFromUserIfNeeded(HWND hWnd)
     if ( IsDebuggerPresent() )
         OutputDebugString("Server Reachable\n");
 
-    if ( KFW_is_available() ) {
+    if ( use_kfw ) {
 #ifdef USE_MS2MIT
         KFW_import_windows_lsa();
 #endif /* USE_MS2MIT */
@@ -3366,6 +3418,7 @@ ObtainTokensFromUserIfNeeded(HWND hWnd)
         GlobalFree(rootcell);
 
 #ifndef USE_FSPROBE
+       if (KFW_is_available()) {
     if ( pname )
         pkrb5_free_unparsed_name(ctx,pname);
     if ( principal )
@@ -3375,6 +3428,7 @@ ObtainTokensFromUserIfNeeded(HWND hWnd)
 #endif /* USE_FSPROBE */
     if (ctx)
         pkrb5_free_context(ctx);
+       }
     return;
 }
 
@@ -3395,9 +3449,11 @@ GetNumOfIpAddrs(void)
     if (code == ERROR_INSUFFICIENT_BUFFER) {
         pIpAddrTable = malloc(dwSize);
         code = GetIpAddrTable(pIpAddrTable, &dwSize, 0);
-        for ( index=0; index < pIpAddrTable->dwNumEntries; index++ ) {
-            if (pIpAddrTable->table[index].dwAddr != 0)
-                validAddrs++;
+        if ( code == NO_ERROR ) {
+            for ( index=0; index < pIpAddrTable->dwNumEntries; index++ ) {
+                if (pIpAddrTable->table[index].dwAddr != 0)
+                    validAddrs++;
+            }
         }
         free(pIpAddrTable);
     }
@@ -3408,12 +3464,13 @@ void
 IpAddrChangeMonitor(void * hWnd)
 {
 #ifdef USE_OVERLAPPED
-    HANDLE Handle = INVALID_HANDLE_VALUE;
+    HANDLE Handle = INVALID_HANDLE_VALUE;   /* Do Not Close This Handle */
     OVERLAPPED Ovlap;
 #endif /* USE_OVERLAPPED */
     DWORD Result;
     DWORD prevNumOfAddrs = GetNumOfIpAddrs();
     DWORD NumOfAddrs;
+    char message[256];
 
     if ( !hWnd )
         return;
@@ -3425,33 +3482,48 @@ IpAddrChangeMonitor(void * hWnd)
         Result = NotifyAddrChange(&Handle,&Ovlap);
         if (Result != ERROR_IO_PENDING)
         {        
-            printf("NotifyAddrChange() failed with error %d \n", Result);
+            if ( IsDebuggerPresent() ) {
+                sprintf(message, "NotifyAddrChange() failed with error %d \n", Result);
+                OutputDebugString(message);
+            }
             break;
         }
 
-        if ((Result = WaitForSingleObject(Handle,INFINITE)) == WAIT_FAILED)
+        if ((Result = WaitForSingleObject(Handle,INFINITE)) != WAIT_OBJECT_0)
         {
-            printf("WaitForSingleObject() failed with error %d\n",
-                    GetLastError());
+            if ( IsDebuggerPresent() ) {
+                sprintf(message, "WaitForSingleObject() failed with error %d\n",
+                        GetLastError());
+                OutputDebugString(message);
+            }
             continue;
         }
 
         if (GetOverlappedResult(Handle, &Ovlap,
                                  &DataTransfered, TRUE) == 0)
         {
-            printf("GetOverlapped result failed %d \n",
-                    GetLastError());
+            if ( IsDebuggerPresent() ) {
+                sprintf(message, "GetOverlapped result failed %d \n",
+                        GetLastError());
+                OutputDebugString(message);
+            }
             break;
         }
-
 #else
         Result = NotifyAddrChange(NULL,NULL);
+        if (Result != NO_ERROR)
+        {        
+            if ( IsDebuggerPresent() ) {
+                sprintf(message, "NotifyAddrChange() failed with error %d \n", Result);
+                OutputDebugString(message);
+            }
+            break;
+        }
 #endif
         
         NumOfAddrs = GetNumOfIpAddrs();
 
         if ( IsDebuggerPresent() ) {
-            char message[256];
             sprintf(message,"IPAddrChangeMonitor() NumOfAddrs: now %d was %d\n",
                     NumOfAddrs, prevNumOfAddrs);
             OutputDebugString(message);
@@ -3466,11 +3538,6 @@ IpAddrChangeMonitor(void * hWnd)
         }
         prevNumOfAddrs = NumOfAddrs;
     }
-
-#ifdef USE_OVERLAPPED
-    if (Handle != INVALID_HANDLE_VALUE)
-        CloseHandle(Handle);
-#endif 
 }