Beispiel #1
0
size_t Main_FindExpiredCreds (void)
{
   size_t retval = (size_t) -1;
   static bool expirationCheck = false;
   lock_ObtainMutex(&g.expirationCheckLock);
   if (expirationCheck) {
       lock_ReleaseMutex(&g.expirationCheckLock);
       return -1;
   }
   expirationCheck = true;
   lock_ReleaseMutex(&g.expirationCheckLock);

   if ( KFW_is_available() )
       KFW_AFS_renew_expiring_tokens();
   
   lock_ObtainMutex(&g.credsLock);
   for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
      {
      if (!g.aCreds[ iCreds ].szCell[0])
         continue;
      if (!g.aCreds[ iCreds ].fRemind)
         continue;

      SYSTEMTIME stNow;
      GetLocalTime (&stNow);

      FILETIME ftNow;
      SystemTimeToFileTime (&stNow, &ftNow);

      FILETIME ftExpires;
      SystemTimeToFileTime (&g.aCreds[ iCreds ].stExpires, &ftExpires);

      LONGLONG llNow = (((LONGLONG)ftNow.dwHighDateTime) << 32) + (LONGLONG)(ftNow.dwLowDateTime);
      LONGLONG llExpires = (((LONGLONG)ftExpires.dwHighDateTime) << 32) + (LONGLONG)(ftExpires.dwLowDateTime);

      llNow /= c100ns1SECOND;
      llExpires /= c100ns1SECOND;

      if (llExpires <= (llNow + (LONGLONG)cminREMIND_WARN * csec1MINUTE))
         {
         if ( KFW_is_available() &&
              KFW_AFS_renew_token_for_cell(g.aCreds[ iCreds ].szCell) )
             continue;
         retval = (size_t) iCreds;
         break;
         }
      }
   
   lock_ReleaseMutex(&g.credsLock);

   lock_ObtainMutex(&g.expirationCheckLock);
   expirationCheck = false;
   lock_ReleaseMutex(&g.expirationCheckLock);

   return retval;
}
Beispiel #2
0
void AfsLogonInit(void)
{
    if ( bInit == FALSE ) {
        if ( WaitForSingleObject( hInitMutex, INFINITE ) == WAIT_OBJECT_0 ) {
	    /* initAFSDirPath() initializes an array and sets a 
	     * flag so that the initialization can only occur
	     * once.  No cleanup will be done when the DLL is 
	     * unloaded so the initialization will not be 
	     * performed again on a subsequent reload
	     */
	    initAFSDirPath();

	    /* ka_Init initializes a number of error tables.
	     * and then calls ka_CellConfig() which grabs 
	     * an afsconf_dir structure via afsconf_Open().
	     * Upon a second attempt to call ka_CellConfig()
	     * the structure will be released with afsconf_Close()
	     * and then re-opened.  Could this corrupt memory?
	     * 
	     * We only need this if we are not using KFW.
	     */
	    if (!KFW_is_available())
		ka_Init(0);
	    bInit = TRUE;
	}
	ReleaseMutex(hInitMutex);
    }
}
Beispiel #3
0
DWORD APIENTRY NPLogonNotify(
	PLUID lpLogonId,
	LPCWSTR lpAuthentInfoType,
	LPVOID lpAuthentInfo,
	LPCWSTR lpPreviousAuthentInfoType,
	LPVOID lpPreviousAuthentInfo,
	LPWSTR lpStationName,
	LPVOID StationHandle,
	LPWSTR *lpLogonScript)
{
    char uname[MAX_USERNAME_LENGTH+1]="";
    char password[MAX_PASSWORD_LENGTH+1]="";
    char logonDomain[MAX_DOMAIN_LENGTH+1]="";

    MSV1_0_INTERACTIVE_LOGON *IL;

    DWORD code = 0;

    char *reason;
    char *ctemp;

    BOOLEAN interactive = TRUE;
    HWND hwndOwner = (HWND)StationHandle;
    BOOLEAN lowercased_name = TRUE;

    /* Can we load KFW binaries? */
    if ( !KFW_is_available() )
        return 0;

    DebugEvent0("NPLogonNotify start");

    /* Remote Desktop / Terminal Server connections to existing sessions 
     * are interactive logons.  Unfortunately, because the session already
     * exists the logon script does not get executed and this prevents 
     * us from being able to execute the rundll32 entrypoint 
     * LogonEventHandlerA which would process the credential cache this
     * routine will produce.  Therefore, we must cleanup orphaned cache
     * files from this routine.  We will take care of it before doing
     * anything else.
     */
    KFW_cleanup_orphaned_caches();

    /* Are we interactive? */
    if (lpStationName)
        interactive = (wcsicmp(lpStationName, L"WinSta0") == 0);

    if ( !interactive ) {
	char station[64]="station";
        DWORD rv;

        SetLastError(0);
	rv = WideCharToMultiByte(CP_UTF8, 0, lpStationName, -1, 
			    station, sizeof(station), NULL, NULL);
        DebugEvent("Skipping NPLogonNotify- LoginId(%d,%d) - Interactive(%d:%s) - gle %d", 
                    lpLogonId->HighPart, lpLogonId->LowPart, interactive, rv != 0 ? station : "failure", GetLastError());
        return 0;
    } else
        DebugEvent("NPLogonNotify - LoginId(%d,%d)", lpLogonId->HighPart, lpLogonId->LowPart);

    /* Initialize Logon Script to none */
    *lpLogonScript=NULL;
    
    /* MSV1_0_INTERACTIVE_LOGON and KERB_INTERACTIVE_LOGON are equivalent for
     * our purposes */

    if ( wcsicmp(lpAuthentInfoType,L"MSV1_0:Interactive") && 
         wcsicmp(lpAuthentInfoType,L"Kerberos:Interactive") )
    {
	char msg[64];
	WideCharToMultiByte(CP_ACP, 0, lpAuthentInfoType, -1, 
			    msg, sizeof(msg), NULL, NULL);
	msg[sizeof(msg)-1]='\0';
        DebugEvent("NPLogonNotify - Unsupported Authentication Info Type: %s", msg);
        return 0;
    }

    IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo;

    /* Convert from Unicode to ANSI */

    /*TODO: Use SecureZeroMemory to erase passwords */
    if (!UnicodeStringToANSI(IL->UserName, uname, MAX_USERNAME_LENGTH) ||
	!UnicodeStringToANSI(IL->Password, password, MAX_PASSWORD_LENGTH) ||
	!UnicodeStringToANSI(IL->LogonDomainName, logonDomain, MAX_DOMAIN_LENGTH))
	return 0;

    /* Make sure AD-DOMAINS sent from login that is sent to us is stripped */
    ctemp = strchr(uname, '@');
    if (ctemp) *ctemp = 0;

    /* is the name all lowercase? */
    for ( ctemp = uname; *ctemp ; ctemp++) {
        if ( !islower(*ctemp) ) {
            lowercased_name = FALSE;
            break;
        }
    }

    code = KFW_get_cred(uname, password, 0, &reason);
    DebugEvent("NPLogonNotify - KFW_get_cred  uname=[%s] code=[%d]",uname, code);
    
    /* remove any kerberos 5 tickets currently held by the SYSTEM account
     * for this user 
     */
    if (!code) {
	char filename[MAX_PATH+1] = "";
	char acctname[MAX_USERNAME_LENGTH+MAX_DOMAIN_LENGTH+3]="";
	PSID pUserSid = NULL;
	LPTSTR pReferencedDomainName = NULL;
	DWORD dwSidLen = 0, dwDomainLen = 0, count;
	SID_NAME_USE eUse;

	if (_snprintf(acctname, sizeof(acctname), "%s\\%s", logonDomain, uname) < 0) {
	    code = -1;
	    goto cleanup;
	}

	count = GetTempPath(sizeof(filename), filename);
        if (count == 0 || count > (sizeof(filename)-1)) {
            code = -1;
            goto cleanup;
        }

	if (_snprintf(filename, sizeof(filename), "%s\\kfwlogon-%x.%x",
		       filename, lpLogonId->HighPart, lpLogonId->LowPart) < 0) 
	{
	    code = -1;
	    goto cleanup;
	}

	KFW_copy_cache_to_system_file(uname, filename);

	/* Need to determine the SID */

	/* First get the size of the required buffers */
	LookupAccountName (NULL,
			   acctname,
			   pUserSid,
			   &dwSidLen,
			   pReferencedDomainName,
			   &dwDomainLen,
			   &eUse);
	if(dwSidLen){
	    pUserSid = (PSID) malloc (dwSidLen);
	    memset(pUserSid,0,dwSidLen);
	}

	if(dwDomainLen){
	    pReferencedDomainName = (LPTSTR) malloc (dwDomainLen * sizeof(TCHAR));
	    memset(pReferencedDomainName,0,dwDomainLen * sizeof(TCHAR));
	}
 
	//Now get the SID and the domain name
	if (pUserSid && LookupAccountName( NULL,
					   acctname,
					   pUserSid,
					   &dwSidLen,
					   pReferencedDomainName,
					   &dwDomainLen,
					   &eUse)) 
	{
	    DebugEvent("LookupAccountName obtained user %s sid in domain %s", acctname, pReferencedDomainName);
	    code = KFW_set_ccache_dacl_with_user_sid(filename, pUserSid);

#ifdef USE_WINLOGON_EVENT
	    /* If we are on Vista, setup a LogonScript 
	     * that will execute the LogonEventHandler entry point via rundll32.exe 
	     */
	    if (is_windows_vista()) {
		ConfigureLogonScript(lpLogonScript, filename);
		if (*lpLogonScript)
		    DebugEvent0("LogonScript assigned");
		else
		    DebugEvent0("No Logon Script");
	    }
#else
	    ConfigureLogonScript(lpLogonScript, filename);
	    if (*lpLogonScript)
		    DebugEvent0("LogonScript assigned");
	    else	
		    DebugEvent0("No Logon Script");
#endif
	} else {
	    DebugEvent0("LookupAccountName failed");
	    DeleteFile(filename);
	    code = -1;
	}

      cleanup:
	if (pUserSid)
	    free(pUserSid);
	if (pReferencedDomainName)
	    free(pReferencedDomainName);
    }

    KFW_destroy_tickets_for_principal(uname);

    if (code) {
        char msg[128];
        HANDLE h;
        char *ptbuf[1];

        StringCbPrintf(msg, sizeof(msg), "Kerberos ticket acquisition failed: %s", reason);

        h = RegisterEventSource(NULL, KFW_LOGON_EVENT_NAME);
        ptbuf[0] = msg;
        ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1008, NULL, 1, 0, ptbuf, NULL);
        DeregisterEventSource(h);
        SetLastError(code);
    }

    if (code)
	DebugEvent0("NPLogonNotify failure");
    else
	DebugEvent0("NPLogonNotify success");

    return code;
}       
Beispiel #4
0
BOOL CALLBACK Main_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
{
   static UINT msgCheckTerminate = 0;
   if (msgCheckTerminate == 0)
      msgCheckTerminate = RegisterWindowMessage (TEXT("AfsCredsCheckTerminate"));

   if (msg == msgCheckTerminate)
      {
      Main_OnCheckTerminate();
      }
   else switch (msg)
      {
      case WM_INITDIALOG:
         g.hMain = hDlg;
         Main_OnInitDialog (hDlg);
         break;

      case WM_DESTROY:
         Creds_CloseLibraries();
         ChangeTrayIcon (NIM_DELETE);
         break;

      case WM_ACTIVATEAPP:
         if (wp)
            {
            Main_RepopulateTabs (FALSE);
            }
         break;

      case WM_COMMAND:
         switch (LOWORD(wp))
            {
            case IDOK:
            case IDCANCEL:
               Main_Show (FALSE);
               break;

            case M_ACTIVATE:
               if (g.fIsWinNT || IsServiceRunning())
                  {
                  if (!lp) // Got here from "/show" parameter? switch tabs.
                     {
                     HWND hTab = GetDlgItem (g.hMain, IDC_TABS);
                     TabCtrl_SetCurSel (hTab, 0);
                     Main_OnSelectTab();
                     }
                  Main_Show (TRUE);
                  }
               else
                  {
                  Message (MB_ICONHAND, IDS_UNCONFIG_TITLE_95, IDS_UNCONFIG_DESC_95);
                  }
               break;

            case M_TERMINATE:
#ifndef UAC_COMPATIBLE
               if (g.fIsWinNT && IsServiceRunning())
                  ModalDialog (IDD_TERMINATE, NULL, (DLGPROC)Terminate_DlgProc);
               else
#endif
               if (g.fIsWinNT)
                  ModalDialog (IDD_TERMINATE_SMALL, NULL, (DLGPROC)Terminate_DlgProc);
               else // (!g.fIsWinNT)
                  ModalDialog (IDD_TERMINATE_SMALL_95, NULL, (DLGPROC)Terminate_DlgProc);
               break;

            case M_TERMINATE_NOW:
               Quit();
               break;

            case M_REMIND:
               Main_OnCheckMenuRemind();
               break;
            }
         break;

      case WM_TIMER:
         Main_OnRemindTimer();
         break;

      case WM_NOTIFY:
         switch (((NMHDR*)lp)->code)
            {
            case TCN_SELCHANGE:
               Main_OnSelectTab();
               break;
            }
         break;

      case WM_TRAYICON:
         switch (lp)
            {
            case WM_LBUTTONDOWN:
               if (IsServiceRunning() || !IsServiceConfigured())
                  Main_Show (TRUE);
               else if (!g.fIsWinNT)
                  Message (MB_ICONHAND, IDS_UNCONFIG_TITLE_95, IDS_UNCONFIG_DESC_95);
               else
                  ShowStartupWizard();
               break;

            case WM_RBUTTONDOWN:
               HMENU hm;
               if ((hm = TaLocale_LoadMenu (MENU_TRAYICON)) != 0)
                  {
                  POINT pt;
                  GetCursorPos(&pt);

                  HMENU hmDummy = CreateMenu();
                  InsertMenu (hmDummy, 0, MF_POPUP, (UINT)hm, NULL);

                  BOOL fRemind = FALSE;
                  lock_ObtainMutex(&g.credsLock);
                  for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
                     {
                     if (g.aCreds[ iCreds ].fRemind)
                        fRemind = TRUE;
                     }
                  lock_ReleaseMutex(&g.credsLock);
                  CheckMenuItem (hm, M_REMIND, MF_BYCOMMAND | ((fRemind) ? MF_CHECKED : MF_UNCHECKED));
		  SetForegroundWindow(hDlg);
                  TrackPopupMenu (GetSubMenu (hmDummy, 0),
                                  TPM_RIGHTALIGN | TPM_RIGHTBUTTON,
                                  pt.x, pt.y, NULL, hDlg, NULL);
		  PostMessage(hDlg, WM_NULL, 0, 0);
                  DestroyMenu (hmDummy);
                  }
               break;

            case WM_MOUSEMOVE:
               Main_OnMouseOver();
               break;
            }
         break;
      case WM_OBTAIN_TOKENS:
          if ( InterlockedIncrement (&g.fShowingMessage) != 1 )
              InterlockedDecrement (&g.fShowingMessage);
          else
              ShowObtainCreds (wp, (char *)lp);
          GlobalFree((void *)lp);
          break;

      case WM_START_SERVICE:
          {
              SC_HANDLE hManager;
              if ((hManager = OpenSCManager ( NULL, NULL, 
                                              SC_MANAGER_CONNECT |
                                              SC_MANAGER_ENUMERATE_SERVICE |
                                              SC_MANAGER_QUERY_LOCK_STATUS)) != NULL)
              {
                  SC_HANDLE hService;
                  if ((hService = OpenService ( hManager, TEXT("TransarcAFSDaemon"), 
                                                SERVICE_QUERY_STATUS | SERVICE_START)) != NULL)
                  {
                      if (StartService (hService, 0, 0))
                          TestAndDoMapShare(SERVICE_START_PENDING);
		      if ( KFW_is_available() && KFW_AFS_wait_for_service_start() ) {
#ifdef USE_MS2MIT
			  KFW_import_windows_lsa();
#endif /* USE_MS2MIT */
			  KFW_AFS_renew_tokens_for_all_cells();
		      }

                      CloseServiceHandle (hService);
                  }

                  CloseServiceHandle (hManager);
              }
              if (KFW_AFS_wait_for_service_start())
		  ObtainTokensFromUserIfNeeded(g.hMain);
          }
          break;
      }

   return FALSE;
}
Beispiel #5
0
void Main_OnRemindTimer (void)
{
   Main_RepopulateTabs (TRUE);

   // See if anything is close to expiring; if so, display a warning
   // dialog. Make sure we never display a warning more than once.
   //
   size_t iExpired;
   if ((iExpired = Main_FindExpiredCreds()) != -1) {
       if (InterlockedIncrement (&g.fShowingMessage) != 1) {
           InterlockedDecrement (&g.fShowingMessage);
       } else { 
           char * rootcell = NULL;
           char   password[PROBE_PASSWORD_LEN+1];
           struct afsconf_cell cellconfig;
           BOOL   serverReachable = FALSE;
           DWORD  code;

           rootcell = (char *)GlobalAlloc(GPTR,MAXCELLCHARS+1);
           if (!rootcell) 
               goto cleanup;

           code = KFW_AFS_get_cellconfig(g.aCreds[ iExpired ].szCell, 
                                         (afsconf_cell*)&cellconfig, rootcell);
           if (code) 
               goto cleanup;

           if (KFW_is_available()) {
               // 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
               serverReachable = KFW_probe_kdc(&cellconfig);
           } else {
               int i;

               for ( i=0 ; i<PROBE_PASSWORD_LEN ; i++ )
                   password[i] = 'x';

               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;
               }
           }
         cleanup:
           if (rootcell)
               GlobalFree(rootcell);

           if (serverReachable)
               ShowObtainCreds (TRUE, g.aCreds[ iExpired ].szCell);
           else
               InterlockedDecrement (&g.fShowingMessage);
       }
   }
}
Beispiel #6
0
DWORD APIENTRY NPLogonNotify(
	PLUID lpLogonId,
	LPCWSTR lpAuthentInfoType,
	LPVOID lpAuthentInfo,
	LPCWSTR lpPreviousAuthentInfoType,
	LPVOID lpPreviousAuthentInfo,
	LPWSTR lpStationName,
	LPVOID StationHandle,
	LPWSTR *lpLogonScript)
{
    char uname[MAX_USERNAME_LENGTH]="";
    char password[MAX_PASSWORD_LENGTH]="";
    char logonDomain[MAX_DOMAIN_LENGTH]="";
    char cell[256]="<non-integrated logon>";
    char homePath[MAX_PATH]="";
    char szLogonId[128] = "";

    MSV1_0_INTERACTIVE_LOGON *IL;

    DWORD code = 0, code2;

    int pw_exp;
    char *reason;
    char *ctemp;

    BOOLEAN interactive;
    BOOLEAN flag;
    DWORD LSPtype, LSPsize;
    HKEY NPKey;

    HWND hwndOwner = (HWND)StationHandle;

    BOOLEAN afsWillAutoStart;

    BOOLEAN lowercased_name = TRUE;

    LogonOptions_t opt; /* domain specific logon options */
    int retryInterval;
    int sleepInterval;

    /* Are we interactive? */
    interactive = (wcsicmp(lpStationName, L"WinSta0") == 0);

#ifdef DISABLE_NON_INTERACTIVE
    /* Do not do anything if the logon session is not interactive. */
    if (!interactive)
	return 0;
#endif

    (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;
    
    /* MSV1_0_INTERACTIVE_LOGON and KERB_INTERACTIVE_LOGON are equivalent for
     * our purposes */

    if ( wcsicmp(lpAuthentInfoType,L"MSV1_0:Interactive") && 
         wcsicmp(lpAuthentInfoType,L"Kerberos:Interactive") )
    {
        DebugEvent("Unsupported Authentication Info Type: %S",
                   lpAuthentInfoType);
        return 0;
    }

    IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo;

    /* Convert from Unicode to ANSI */

    /*TODO: Use SecureZeroMemory to erase passwords */
    if (!UnicodeStringToANSI(IL->UserName, uname, MAX_USERNAME_LENGTH) ||
	 !UnicodeStringToANSI(IL->Password, password, MAX_PASSWORD_LENGTH) ||
	 !UnicodeStringToANSI(IL->LogonDomainName, logonDomain, MAX_DOMAIN_LENGTH))
 	return 0;

    /* Make sure AD-DOMANS sent from login that is sent to us is striped */
    ctemp = strchr(uname, '@');
    if (ctemp) *ctemp = 0;

    /* is the name all lowercase? */
    for ( ctemp = uname; *ctemp ; ctemp++) {
        if ( !islower(*ctemp) ) {
            lowercased_name = FALSE;
            break;
        }
    }

    /*
     * Get Logon options
     */

    GetDomainLogonOptions( lpLogonId, uname, logonDomain, &opt );
    retryInterval = opt.retryInterval;
    sleepInterval = opt.sleepInterval;
    *lpLogonScript = opt.logonScript;

    if (retryInterval < sleepInterval)
        sleepInterval = retryInterval;

    DebugEvent("Got logon script: %S",opt.logonScript);

    afsWillAutoStart = AFSWillAutoStart();

    DebugEvent("LogonOption[%x], Service AutoStart[%d]",
                opt.LogonOption,afsWillAutoStart);
    
    /* Check for zero length password if integrated logon*/
    if ( ISLOGONINTEGRATED(opt.LogonOption) )  {
        if ( password[0] == 0 ) {
            DebugEvent0("Password is the empty string");
            code = GT_PW_NULL;
            reason = "zero length password is illegal";
            code=0;
        }

        /* Get cell name if doing integrated logon.  
           We might overwrite this if we are logging into an AD realm and we find out that
           the user's home dir is in some other cell. */
        DebugEvent("About to call cm_GetRootCellName(%s)",cell);
        code = cm_GetRootCellName(cell);
        if (code < 0) { 
            DebugEvent0("Unable to obtain Root Cell");
            code = KTC_NOCELL;
            reason = "unknown cell";
            code=0;
        } else {
            DebugEvent("Cell is %s",cell);
        }       

        /* We get the user's home directory path, if applicable, though we can't lookup the
           cell right away because the client service may not have started yet. This call
           also sets the AD_REALM flag in opt.flags if applicable. */
        if (ISREMOTE(opt.flags)) {
            DebugEvent0("Is Remote");
            GetAdHomePath(homePath,MAX_PATH,lpLogonId,&opt);
        }
    }

    /* loop until AFS is started. */
    if (afsWillAutoStart) {
	while (IsServiceRunning() || IsServiceStartPending()) {
	    DebugEvent("while(autostart) LogonOption[%x], Service AutoStart[%d]",
			opt.LogonOption,afsWillAutoStart);

	    if (ISADREALM(opt.flags)) {
		code = GetFileCellName(homePath,cell,256);
		if (!code) {
		    DebugEvent("profile path [%s] is in cell [%s]",homePath,cell);
		}
		/* Don't bail out if GetFileCellName failed.
		 * The home dir may not be in AFS after all. 
		 */
	    } else
		code=0;
		
	    /* if Integrated Logon  */
	    if (ISLOGONINTEGRATED(opt.LogonOption))
	    {			
		if ( KFW_is_available() ) {
		    SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, "");
                    if (opt.realm) {
			char * principal, *p;
			size_t len, tlen;

			StringCchLength(opt.realm, MAX_DOMAIN_LENGTH, &tlen);
			len = tlen;
			StringCchLength(uname, MAX_USERNAME_LENGTH, &tlen);
			len += tlen + 2;

			/* tlen is now the length of uname in characters */
			principal = (char *)malloc(len * sizeof(char));
			if ( principal ) {
			    StringCchCopy(principal, len, uname);
			    p = principal + tlen;
			    *p++ = '@';
                            StringCchCopy(p, len - tlen -1, opt.realm);
                            code = KFW_AFS_get_cred(principal, cell, password, 0, opt.smbName, &reason);
                            DebugEvent("KFW_AFS_get_cred  uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
					    principal,opt.smbName,cell,code);
			    free(principal);
			}
                    } else {
                        code = KFW_AFS_get_cred(uname, cell, password, 0, opt.smbName, &reason);
                        DebugEvent("KFW_AFS_get_cred  uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
                                    uname,opt.smbName,cell,code);
                    }
		    SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, NULL);
		    if (code == 0 && opt.theseCells) { 
			char * principal, *p;
			size_t len, tlen;

			StringCchLength(opt.realm ? opt.realm : cell, MAX_DOMAIN_LENGTH, &tlen);
			len = tlen;
			StringCchLength(uname, MAX_USERNAME_LENGTH, &tlen);
			len += tlen + 2;

			/* tlen is now the length of uname in characters */
			principal = (char *)malloc(len * sizeof(char));
			if ( principal ) {
			    StringCchCopy(principal, len, uname);
			    p = principal + tlen;
			    *p++ = '@';
                            if (opt.realm) {
                                StringCchCopy(p, len - tlen -1, opt.realm);
                            } else {
                                StringCchCopy(p, len - tlen - 1, cell);
                                for ( ;*p; p++) {
                                    *p = toupper(*p);
                                }
                            }
			    p = opt.theseCells;
			    while ( *p ) {
                                if ( cm_stricmp_utf8(p, cell) ) {
                                    SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, "");
                                    code2 = KFW_AFS_get_cred(principal, p, 0, 0, opt.smbName, &reason);
                                    SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, NULL);
                                    DebugEvent("KFW_AFS_get_cred  uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
                                               principal,opt.smbName,p,code2);
                                }
				p += strlen(p) + 1;
			    }
			    free(principal);
			}
		    }
		} else {
		    code = ka_UserAuthenticateGeneral2(KA_USERAUTH_VERSION+KA_USERAUTH_AUTHENT_LOGON,
							uname, "", cell, password, opt.smbName, 0, &pw_exp, 0,
							&reason);
		    DebugEvent("AFS AfsLogon - (INTEGRATED only)ka_UserAuthenticateGeneral2 Code[%x] uname[%s] smbname=[%s] Cell[%s] PwExp=[%d] Reason=[%s]",
				code,uname,opt.smbName,cell,pw_exp,reason?reason:"");
		}       
		if ( code && code != KTC_NOCM && code != KTC_NOCMRPC && !lowercased_name ) {
		    for ( ctemp = uname; *ctemp ; ctemp++) {
			*ctemp = tolower(*ctemp);
		    }
		    lowercased_name = TRUE;
		    goto sleeping;
		}

		/* is service started yet?*/

		/* If we've failed because the client isn't running yet and the
		 * client is set to autostart (and therefore it makes sense for
		 * us to wait for it to start) then sleep a while and try again. 
		 * If the error was something else, then give up. */
		if (code != KTC_NOCM && code != KTC_NOCMRPC)
		    break;
	    }
	    else {  
		/*JUST check to see if its running*/
		if (IsServiceRunning())
		    break;
		if (!IsServiceStartPending()) {
		    code = KTC_NOCMRPC;
		    reason = "AFS Service start failed";
		    break;
		}
	    }

	    /* If the retry interval has expired and we still aren't
	     * logged in, then just give up if we are not in interactive
	     * mode or the failSilently flag is set, otherwise let the
	     * user know we failed and give them a chance to try again. */
	    if (retryInterval <= 0) {
		reason = "AFS not running";
		if (!interactive || opt.failSilently)
		    break;
		flag = MessageBox(hwndOwner,
				   "AFS is still starting.  Retry?",
				   "AFS Logon",
				   MB_ICONQUESTION | MB_RETRYCANCEL);
		if (flag == IDCANCEL)
		    break;

		/* Wait just a little while and try again */
		retryInterval = opt.retryInterval;
	    }

	  sleeping:
	    Sleep(sleepInterval * 1000);
	    retryInterval -= sleepInterval;
	}
    }
    DebugEvent0("while loop exited");

    /* remove any kerberos 5 tickets currently held by the SYSTEM account
     * for this user 
     */

    if (ISLOGONINTEGRATED(opt.LogonOption) && KFW_is_available()) {
#ifdef KFW_LOGON
	sprintf(szLogonId,"%d.%d",lpLogonId->HighPart, lpLogonId->LowPart);
	KFW_AFS_copy_cache_to_system_file(uname, szLogonId);
#endif
	KFW_AFS_destroy_tickets_for_principal(uname);
    }

    if (code) {
	char msg[128];
	HANDLE h;
	char *ptbuf[1];

	StringCbPrintf(msg, sizeof(msg), "Integrated login failed: %s", reason);

	if (ISLOGONINTEGRATED(opt.LogonOption) && interactive && !opt.failSilently)
	    MessageBox(hwndOwner, msg, "AFS Logon", MB_OK);

	h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
	ptbuf[0] = msg;
	ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1008, NULL,
		     1, 0, ptbuf, NULL);
	DeregisterEventSource(h);
	    
        code = MapAuthError(code);
        SetLastError(code);

        if (ISLOGONINTEGRATED(opt.LogonOption) && (code!=0))
        {
            if (*lpLogonScript)
                LocalFree(*lpLogonScript);
            *lpLogonScript = NULL;
            if (!afsWillAutoStart)	// its not running, so if not autostart or integrated logon then just skip
                code = 0;
        }
    }

    if (opt.theseCells) free(opt.theseCells);
    if (opt.smbName) free(opt.smbName);
    if (opt.realm) free(opt.realm);

    DebugEvent("AFS AfsLogon - Exit","Return Code[%x]",code);
    return code;
}       
Beispiel #7
0
void
ObtainTokensFromUserIfNeeded(HWND hWnd)
{
    char * rootcell = NULL;
    char   cell[MAXCELLCHARS+1] = "";
    char   password[PROBE_PASSWORD_LEN+1];
    struct afsconf_cell cellconfig;
    struct ktc_principal    aserver;
    struct ktc_principal    aclient;
    struct ktc_token	atoken;
    krb5_timestamp now = 0;
    BOOL serverReachable = 0;
    int rc;
    DWORD       CurrentState, code;
    char        HostName[64];
    int         use_kfw = KFW_is_available();

    SYSTEMTIME stNow;
    FILETIME ftNow;
    LONGLONG llNow;
    FILETIME ftExpires;
    LONGLONG llExpires;
    SYSTEMTIME stExpires;

    CurrentState = 0;
    memset(HostName, '\0', sizeof(HostName));
    gethostname(HostName, sizeof(HostName));
    if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR)
        return;
    if (CurrentState != SERVICE_RUNNING) {
        SendMessage(hWnd, WM_START_SERVICE, FALSE, 0L);
        return;
    }

    rootcell = (char *)GlobalAlloc(GPTR,MAXCELLCHARS+1);
    if (!rootcell) 
        goto cleanup;

    code = KFW_AFS_get_cellconfig(cell, (void*)&cellconfig, rootcell);
    if (code) 
        goto cleanup;

    memset(&aserver, '\0', sizeof(aserver));
    strcpy(aserver.name, "afs");
    strcpy(aserver.cell, rootcell);

    GetLocalTime (&stNow);
    SystemTimeToFileTime (&stNow, &ftNow);
    llNow = (((LONGLONG)ftNow.dwHighDateTime) << 32) + (LONGLONG)(ftNow.dwLowDateTime);
    llNow /= c100ns1SECOND;

    rc = ktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient);
    if ( rc == 0 ) {
        TimeToSystemTime (&stExpires, atoken.endTime);
        SystemTimeToFileTime (&stExpires, &ftExpires);
        llExpires = (((LONGLONG)ftExpires.dwHighDateTime) << 32) + (LONGLONG)(ftExpires.dwLowDateTime);
        llExpires /= c100ns1SECOND;

        if (llNow < llExpires)
            goto cleanup;

        if ( IsDebuggerPresent() ) {
            char message[256];
            sprintf(message,"ObtainTokensFromUserIfNeeded: %d  now = %ul  endTime = %ul\n",
                     rc, llNow, llExpires);
            OutputDebugString(message);
        }
    }

#ifdef USE_FSPROBE
    serverReachable = cellPing(NULL);
#else
    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
        serverReachable = KFW_probe_kdc(&cellconfig);
    } else {
        int i;

        for ( i=0 ; i<PROBE_PASSWORD_LEN ; i++ )
            password[i] = 'x';

        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 ) {
        if ( IsDebuggerPresent() )
            OutputDebugString("Server Unreachable\n");
        goto cleanup;
    }

    if ( IsDebuggerPresent() )
        OutputDebugString("Server Reachable\n");

    if ( use_kfw ) {
#ifdef USE_MS2MIT
        KFW_import_windows_lsa();
#endif /* USE_MS2MIT */
        KFW_AFS_renew_expiring_tokens();
        KFW_AFS_renew_token_for_cell(rootcell);

        rc = ktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient);
        if ( rc == 0 ) {
            TimeToSystemTime (&stExpires, atoken.endTime);
            SystemTimeToFileTime (&stExpires, &ftExpires);
            llExpires = (((LONGLONG)ftExpires.dwHighDateTime) << 32) + (LONGLONG)(ftExpires.dwLowDateTime);
            llExpires /= c100ns1SECOND;
        
            if (llNow < llExpires)
                goto cleanup;
        }
    }

    SendMessage(hWnd, WM_OBTAIN_TOKENS, FALSE, (long)rootcell);
    rootcell = NULL;    // rootcell freed by message receiver

  cleanup:
    if (rootcell)
        GlobalFree(rootcell);

    return;
}