/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ #include #include extern "C" { #include #include #include #include #include #include #include #include #include #include "ipaddrchg.h" } #include "afscreds.h" #include /* * DEFINITIONS ________________________________________________________________ * */ #define cREALLOC_CREDS 4 #define cszLIBTOKENS TEXT("afsauthent.dll") #define cszLIBCONF TEXT("libafsconf.dll") /* * DYNAMIC LINKING ____________________________________________________________ * */ extern "C" { typedef unsigned int (*initAFSDirPath_t)(void); typedef int (*ka_Init_t)(int flags); typedef int (*rx_Init_t)(int port); typedef int (*ktc_GetToken_t)(struct ktc_principal *server, struct ktc_token *token, int tokenLen, struct ktc_principal *client); typedef int (*ktc_ListTokens_t)(int cellNum, int *cellNumP, struct ktc_principal *serverName); typedef int (*ktc_ForgetToken_t)(struct ktc_principal *server); typedef int (*ka_UserAuthenticateGeneral_t)(int flags, char *name, char *instance, char *realm, char *password, int lifetime, int *password_expiresP, int spare, char **reasonP); typedef long (*cm_GetRootCellName_t)(char *namep); typedef int (*ka_ParseLoginName_t)(char *login, char *name, char *inst, char *cell); } static struct l { HINSTANCE hInstLibTokens; HINSTANCE hInstLibConf; initAFSDirPath_t initAFSDirPathP; ka_Init_t ka_InitP; rx_Init_t rx_InitP; ktc_GetToken_t ktc_GetTokenP; ktc_ListTokens_t ktc_ListTokensP; ktc_ForgetToken_t ktc_ForgetTokenP; ka_UserAuthenticateGeneral_t ka_UserAuthenticateGeneralP; ka_ParseLoginName_t ka_ParseLoginNameP; cm_GetRootCellName_t cm_GetRootCellNameP; } l; #define initAFSDirPath (*l.initAFSDirPathP) #define ka_Init (*l.ka_InitP) #define rx_Init (*l.rx_InitP) #define ktc_GetToken (*l.ktc_GetTokenP) #define ktc_ListTokens (*l.ktc_ListTokensP) #define ktc_ForgetToken (*l.ktc_ForgetTokenP) #define ka_UserAuthenticateGeneral (*l.ka_UserAuthenticateGeneralP) #define cm_GetRootCellName (*l.cm_GetRootCellNameP) BOOL Creds_OpenLibraries (void) { if (!l.hInstLibTokens) { if ((l.hInstLibTokens = LoadLibrary (cszLIBTOKENS)) != NULL) { l.initAFSDirPathP = (initAFSDirPath_t)GetProcAddress (l.hInstLibTokens, "initAFSDirPath"); l.ka_InitP = (ka_Init_t)GetProcAddress (l.hInstLibTokens, "ka_Init"); l.rx_InitP = (rx_Init_t)GetProcAddress (l.hInstLibTokens, "rx_Init"); l.ktc_GetTokenP = (ktc_GetToken_t)GetProcAddress (l.hInstLibTokens, "ktc_GetToken"); l.ktc_ListTokensP = (ktc_ListTokens_t)GetProcAddress (l.hInstLibTokens, "ktc_ListTokens"); l.ktc_ForgetTokenP = (ktc_ForgetToken_t)GetProcAddress (l.hInstLibTokens, "ktc_ForgetToken"); l.ka_ParseLoginNameP = (ka_ParseLoginName_t)GetProcAddress (l.hInstLibTokens, "ka_ParseLoginName"); l.ka_UserAuthenticateGeneralP = (ka_UserAuthenticateGeneral_t)GetProcAddress (l.hInstLibTokens, "ka_UserAuthenticateGeneral"); if (!l.initAFSDirPathP || !l.ka_InitP || !l.rx_InitP || !l.ktc_GetTokenP || !l.ktc_ListTokensP || !l.ktc_ForgetTokenP || !l.ka_ParseLoginNameP || !l.ka_UserAuthenticateGeneralP) { FreeLibrary (l.hInstLibTokens); l.hInstLibTokens = NULL; } else { rx_Init(0); initAFSDirPath(); ka_Init(0); } } } if (!l.hInstLibConf) { if ((l.hInstLibConf = LoadLibrary (cszLIBCONF)) != NULL) { l.cm_GetRootCellNameP = (cm_GetRootCellName_t)GetProcAddress (l.hInstLibConf, "cm_GetRootCellName"); if (!l.cm_GetRootCellNameP) { FreeLibrary (l.hInstLibConf); l.hInstLibConf = NULL; } } } return l.hInstLibTokens && l.hInstLibConf; } void Creds_CloseLibraries (void) { if (l.hInstLibTokens) { FreeLibrary (l.hInstLibTokens); l.hInstLibTokens = NULL; } if (l.hInstLibConf) { FreeLibrary (l.hInstLibConf); l.hInstLibConf = NULL; } } /* * ROUTINES ___________________________________________________________________ * */ void GetGatewayName (LPTSTR pszGateway) { *pszGateway = TEXT('\0'); HKEY hk; if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, TEXT(AFSREG_CLT_SVC_PARAM_SUBKEY), 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &hk) == 0) { DWORD dwSize = MAX_PATH; DWORD dwType = REG_SZ; if (RegQueryValueEx (hk, TEXT("Gateway"), NULL, &dwType, (PBYTE)pszGateway, &dwSize) != 0) *pszGateway = TEXT('\0'); RegCloseKey (hk); } } BOOL IsServiceRunning (void) { if (g.fIsWinNT) { SERVICE_STATUS Status; memset (&Status, 0x00, sizeof(Status)); Status.dwCurrentState = SERVICE_STOPPED; SC_HANDLE hManager; if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL) { SC_HANDLE hService; if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL) { QueryServiceStatus (hService, &Status); CloseServiceHandle (hService); } else if ( IsDebuggerPresent() ) OutputDebugString("Unable to open Transarc AFS Daemon Service\n"); CloseServiceHandle (hManager); } else if ( IsDebuggerPresent() ) OutputDebugString("Unable to open SC Manager\n"); return (Status.dwCurrentState == SERVICE_RUNNING); } TCHAR szGateway[ MAX_PATH ]; GetGatewayName (szGateway); return (szGateway[0]) ? TRUE : FALSE; } BOOL IsServicePersistent (void) { struct { QUERY_SERVICE_CONFIG Config; BYTE buf[1024]; } Config; memset (&Config, 0x00, sizeof(Config)); Config.Config.dwStartType = SERVICE_AUTO_START; SC_HANDLE hManager; if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL) { SC_HANDLE hService; if ((hService = OpenService (hManager, TEXT(AFSREG_CLT_SVC_NAME), GENERIC_READ)) != NULL) { DWORD dwSize = sizeof(Config); QueryServiceConfig (hService, (QUERY_SERVICE_CONFIG*)&Config, sizeof(Config), &dwSize); CloseServiceHandle (hService); } CloseServiceHandle (hManager); } return (Config.Config.dwStartType == SERVICE_AUTO_START) ? TRUE : FALSE; } BOOL IsServiceConfigured (void) { BOOL rc = FALSE; HKEY hk; if (!g.fIsWinNT) { rc = TRUE; } else if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, TEXT(AFSREG_CLT_SVC_PARAM_SUBKEY), 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &hk) == 0) { TCHAR szCell[ MAX_PATH ]; DWORD dwSize = sizeof(szCell); DWORD dwType = REG_SZ; if (RegQueryValueEx (hk, TEXT("Cell"), NULL, &dwType, (PBYTE)szCell, &dwSize) == 0) { if (szCell[0] != TEXT('\0')) rc = TRUE; } RegCloseKey (hk); } return rc; } int GetCurrentCredentials (void) { int rc = KTC_NOCM; lock_ObtainMutex(&g.credsLock); // Free any knowledge we currently have about the user's credentials // if (g.aCreds) Free (g.aCreds); g.aCreds = NULL; g.cCreds = 0; g.tickLastRetest = GetTickCount(); // Start enumerating tokens. // if (!Creds_OpenLibraries()) { rc = ERROR_DLL_INIT_FAILED; } else if (IsServiceRunning()) { for (int iCell = 0; ; ) { struct ktc_principal Principal; if ((rc = ktc_ListTokens (iCell, &iCell, &Principal)) != 0) break; struct ktc_token Token; struct ktc_principal ClientName; if ((rc = ktc_GetToken (&Principal, &Token, sizeof(Token), &ClientName)) != 0) break; // Translate what we found about the user's creds in this particular // cell into something readable. // TCHAR szCell[ 256 ]; CopyAnsiToString (szCell, Principal.cell); if (!szCell[0]) continue; TCHAR szUser[ 256 ]; CopyAnsiToString (szUser, ClientName.name); if (ClientName.instance[0]) { lstrcat (szUser, TEXT(".")); CopyAnsiToString (&szUser[ lstrlen(szUser) ], ClientName.instance); } SYSTEMTIME stExpires; TimeToSystemTime (&stExpires, Token.endTime); // We've found out that the user has--or perhaps recently had-- // credentials within a certain cell under the certain name. // Stick that knowledge in our g.aCreds array. // size_t iCreds; for (iCreds = 0; iCreds < g.cCreds; ++iCreds) { if (!lstrcmpi (g.aCreds[ iCreds ].szCell, szCell)) break; } if (iCreds == g.cCreds) { for (iCreds = 0; iCreds < g.cCreds; ++iCreds) { if (!g.aCreds[ iCreds ].szCell[0]) break; } if (!REALLOC (g.aCreds, g.cCreds, 1+iCreds, cREALLOC_CREDS)) break; } lstrcpy (g.aCreds[ iCreds ].szCell, szCell); lstrcpy (g.aCreds[ iCreds ].szUser, szUser); memcpy (&g.aCreds[ iCreds ].stExpires, &stExpires, sizeof(SYSTEMTIME)); LoadRemind (iCreds); } } lock_ReleaseMutex(&g.credsLock); // We've finished updating g.aCreds. Update the tray icon to reflect // whether the user currently has any credentials at all, and // re-enable the Remind timer. // ChangeTrayIcon (NIM_MODIFY); return rc; } int DestroyCurrentCredentials (LPCTSTR pszCell) { int rc = KTC_NOCM; if (!Creds_OpenLibraries()) { rc = ERROR_DLL_INIT_FAILED; } else if (IsServiceRunning()) { struct ktc_principal Principal; memset (&Principal, 0x00, sizeof(Principal)); CopyStringToAnsi (Principal.cell, pszCell); CopyStringToAnsi (Principal.name, TEXT("afs")); rc = ktc_ForgetToken (&Principal); if ( KFW_is_available() ) KFW_AFS_destroy_tickets_for_cell(Principal.cell); } if (rc != 0) { int idsTitle = (g.fIsWinNT) ? IDS_ERROR_TITLE : IDS_ERROR_TITLE_95; int idsDesc = (!g.fIsWinNT) ? IDS_ERROR_DESTROY_95 : (rc == KTC_NOCM) ? IDS_ERROR_DESTROY_NOCM : IDS_ERROR_DESTROY_UNKNOWN; Message (MB_ICONHAND | MB_OK, idsTitle, idsDesc, TEXT("%s%ld"), pszCell, rc); } return rc; } int ObtainNewCredentials (LPCTSTR pszCell, LPCTSTR pszUser, LPCTSTR pszPassword, BOOL Silent) { int rc = KTC_NOCM; char *Result = NULL; if (!Creds_OpenLibraries()) { rc = ERROR_DLL_INIT_FAILED; } else if (IsServiceRunning()) { char szCellA[ 256 ]; CopyStringToAnsi (szCellA, pszCell); char szNameA[ 256 ]; CopyStringToAnsi (szNameA, pszUser); char szPasswordA[ 256 ]; CopyStringToAnsi (szPasswordA, pszPassword); char szSmbNameA[ MAXRANDOMNAMELEN ]; CopyStringToAnsi (szSmbNameA, g.SmbName); int Expiration = 0; if ( KFW_is_available() ) { // KFW_AFS_get_cred() parses the szNameA field as complete princial including potentially // a different realm then the specified cell name. rc = KFW_AFS_get_cred(szNameA, szCellA, szPasswordA, 0, szSmbNameA[0] ? szSmbNameA : NULL, &Result); } else { char name[sizeof(szNameA)]; char instance[sizeof(szNameA)]; char cell[sizeof(szNameA)]; name[0] = '\0'; instance[0] = '\0'; cell[0] = '\0'; ka_ParseLoginName(szNameA, name, instance, cell); if ( szSmbNameA[0] ) { rc = ka_UserAuthenticateGeneral2(KA_USERAUTH_VERSION+KA_USERAUTH_AUTHENT_LOGON, name, instance, szCellA, szPasswordA, szSmbNameA, 0, &Expiration, 0, &Result); } else { rc = ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION, name, instance, szCellA, szPasswordA, 0, &Expiration, 0, &Result); } } } if (!Silent && rc != 0) { int idsTitle = (g.fIsWinNT) ? IDS_ERROR_TITLE : IDS_ERROR_TITLE_95; int idsDesc = (g.fIsWinNT) ? IDS_ERROR_OBTAIN : IDS_ERROR_OBTAIN_95; Message (MB_ICONHAND | MB_OK, idsTitle, idsDesc, TEXT("%s%s%s%ld"), pszCell, pszUser, (Result) ? Result : TEXT(""), rc); } return rc; } int GetDefaultCell (LPTSTR pszCell) { int rc = KTC_NOCM; *pszCell = TEXT('\0'); if (!Creds_OpenLibraries()) { rc = ERROR_DLL_INIT_FAILED; } else if (IsServiceRunning()) { char szCellA[ cchRESOURCE ] = ""; int rc; HKEY hk; if (RegOpenKeyEx (HKEY_CURRENT_USER, TEXT(AFSREG_USER_OPENAFS_SUBKEY), 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &hk) == 0) { DWORD dwSize = sizeof(szCellA); DWORD dwType = REG_SZ; RegQueryValueEx (hk, TEXT("Authentication Cell"), NULL, &dwType, (PBYTE)szCellA, &dwSize); RegCloseKey (hk); } if (szCellA[0] == '\0') { rc = cm_GetRootCellName (szCellA); } else { rc = 0; } if (rc == 0) CopyAnsiToString(pszCell, szCellA); } return rc; }