no-getcellconfig-error-20040323
[openafs.git] / src / WINNT / client_creds / afskfw.c
index 0e2e03e..376ce09 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));
@@ -2551,7 +2596,7 @@ KFW_AFS_klog(
     // NULL or empty cell returns information on local cell
     if (rc = get_cellconfig(Dmycell, &ak_cellconfig, local_cell))
     {
-               KFW_AFS_error(rc, "get_cellconfig()");
+        // KFW_AFS_error(rc, "get_cellconfig()");
         return(rc);
     }
 
@@ -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);
@@ -2917,7 +2965,7 @@ KFW_AFS_error(LONG rc, LPCSTR FailedFunctionName)
     else
       errText = "Unknown error!";
 
-    sprintf(message, "%s\n(%s failed)", errText, FailedFunctionName);
+    sprintf(message, "%s (0x%x)\n(%s failed)", errText, rc, FailedFunctionName);
 
     if ( IsDebuggerPresent() ) {
         OutputDebugString(message);
@@ -3217,6 +3265,9 @@ ObtainTokensFromUserIfNeeded(HWND hWnd)
         return;
     }
 
+    if (!pkrb5_init_context)
+        return;
+
     if ( use_kfw ) {
         code = pkrb5_init_context(&ctx);
         if ( code ) goto cleanup;
@@ -3303,7 +3354,7 @@ ObtainTokensFromUserIfNeeded(HWND hWnd)
         code = pkrb5_c_random_make_octets(ctx, &pwdata);
         if (code) {
             int i;
-            for ( i=0 ; i<PROBE_PASSWORD_LEN ; i )
+            for ( i=0 ; i<PROBE_PASSWORD_LEN ; i++ )
                 password[i] = 'x';
         }
         password[PROBE_PASSWORD_LEN] = '\0';
@@ -3331,11 +3382,21 @@ ObtainTokensFromUserIfNeeded(HWND hWnd)
         }
     } else {
         int i;
-        for ( i=0 ; i<PROBE_PASSWORD_LEN ; i )
+
+        for ( i=0 ; i<PROBE_PASSWORD_LEN ; i++ )
             password[i] = 'x';
 
-        code = ObtainNewCredentials(rootcell, PROBE_USERNAME, password);
-        serverReachable = 1;
+        code = ObtainNewCredentials(rootcell, PROBE_USERNAME, password, TRUE);
+        switch ( code ) {
+        case INTK_BADPW:
+        case KERB_ERR_PRINCIPAL_UNKNOWN:
+        case KERB_ERR_SERVICE_EXP:
+        case RD_AP_TIME:
+            serverReachable = TRUE;
+            break;
+        default:
+            serverReachable = FALSE;
+        }
     }
 #endif
     if ( !serverReachable ) {
@@ -3398,9 +3459,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);
     }
@@ -3411,12 +3474,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;
@@ -3428,33 +3492,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);
@@ -3469,11 +3548,6 @@ IpAddrChangeMonitor(void * hWnd)
         }
         prevNumOfAddrs = NumOfAddrs;
     }
-
-#ifdef USE_OVERLAPPED
-    if (Handle != INVALID_HANDLE_VALUE)
-        CloseHandle(Handle);
-#endif 
 }