Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / client_creds / creds.cpp
bloba385054b59beb201ee7a03d2b278b2c331b7f71d
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
10 #include <winsock2.h>
11 #include <ws2tcpip.h>
13 extern "C" {
14 #include <afs\stds.h>
15 #include <afs\param.h>
16 #include <afs\auth.h>
17 #include <afs\kautils.h>
18 #include <rx\rxkad.h>
19 #include <afs\cm_config.h>
20 #include <afs\afskfw.h>
21 #include "ipaddrchg.h"
24 #include "afscreds.h"
25 #include <WINNT\afsreg.h>
28 * DEFINITIONS ________________________________________________________________
32 #define cREALLOC_CREDS 4
34 #define cszLIBTOKENS TEXT("afsauthent.dll")
35 #define cszLIBCONF TEXT("libafsconf.dll")
39 * DYNAMIC LINKING ____________________________________________________________
43 extern "C" {
44 typedef unsigned int (*initAFSDirPath_t)(void);
45 typedef int (*ka_Init_t)(int flags);
46 typedef int (*rx_Init_t)(int port);
47 typedef int (*ktc_GetToken_t)(struct ktc_principal *server, struct ktc_token *token, int tokenLen, struct ktc_principal *client);
48 typedef int (*ktc_ListTokens_t)(int cellNum, int *cellNumP, struct ktc_principal *serverName);
49 typedef int (*ktc_ForgetToken_t)(struct ktc_principal *server);
50 typedef int (*ka_UserAuthenticateGeneral_t)(int flags, char *name, char *instance, char *realm, char *password, int lifetime, int *password_expiresP, int spare, char **reasonP);
51 typedef long (*cm_GetRootCellName_t)(char *namep);
52 typedef int (*ka_ParseLoginName_t)(char *login, char *name, char *inst, char *cell);
55 static struct l
57 HINSTANCE hInstLibTokens;
58 HINSTANCE hInstLibConf;
60 initAFSDirPath_t initAFSDirPathP;
61 ka_Init_t ka_InitP;
62 rx_Init_t rx_InitP;
63 ktc_GetToken_t ktc_GetTokenP;
64 ktc_ListTokens_t ktc_ListTokensP;
65 ktc_ForgetToken_t ktc_ForgetTokenP;
66 ka_UserAuthenticateGeneral_t ka_UserAuthenticateGeneralP;
67 ka_ParseLoginName_t ka_ParseLoginNameP;
68 cm_GetRootCellName_t cm_GetRootCellNameP;
69 } l;
71 #define initAFSDirPath (*l.initAFSDirPathP)
72 #define ka_Init (*l.ka_InitP)
73 #define rx_Init (*l.rx_InitP)
74 #define ktc_GetToken (*l.ktc_GetTokenP)
75 #define ktc_ListTokens (*l.ktc_ListTokensP)
76 #define ktc_ForgetToken (*l.ktc_ForgetTokenP)
77 #define ka_UserAuthenticateGeneral (*l.ka_UserAuthenticateGeneralP)
78 #define cm_GetRootCellName (*l.cm_GetRootCellNameP)
81 BOOL Creds_OpenLibraries (void)
83 if (!l.hInstLibTokens)
85 if ((l.hInstLibTokens = LoadLibrary (cszLIBTOKENS)) != NULL)
87 l.initAFSDirPathP = (initAFSDirPath_t)GetProcAddress (l.hInstLibTokens, "initAFSDirPath");
88 l.ka_InitP = (ka_Init_t)GetProcAddress (l.hInstLibTokens, "ka_Init");
89 l.rx_InitP = (rx_Init_t)GetProcAddress (l.hInstLibTokens, "rx_Init");
90 l.ktc_GetTokenP = (ktc_GetToken_t)GetProcAddress (l.hInstLibTokens, "ktc_GetToken");
91 l.ktc_ListTokensP = (ktc_ListTokens_t)GetProcAddress (l.hInstLibTokens, "ktc_ListTokens");
92 l.ktc_ForgetTokenP = (ktc_ForgetToken_t)GetProcAddress (l.hInstLibTokens, "ktc_ForgetToken");
93 l.ka_ParseLoginNameP = (ka_ParseLoginName_t)GetProcAddress (l.hInstLibTokens, "ka_ParseLoginName");
94 l.ka_UserAuthenticateGeneralP = (ka_UserAuthenticateGeneral_t)GetProcAddress (l.hInstLibTokens, "ka_UserAuthenticateGeneral");
96 if (!l.initAFSDirPathP ||
97 !l.ka_InitP ||
98 !l.rx_InitP ||
99 !l.ktc_GetTokenP ||
100 !l.ktc_ListTokensP ||
101 !l.ktc_ForgetTokenP ||
102 !l.ka_ParseLoginNameP ||
103 !l.ka_UserAuthenticateGeneralP)
105 FreeLibrary (l.hInstLibTokens);
106 l.hInstLibTokens = NULL;
108 else
110 rx_Init(0);
111 initAFSDirPath();
112 ka_Init(0);
117 if (!l.hInstLibConf)
119 if ((l.hInstLibConf = LoadLibrary (cszLIBCONF)) != NULL)
121 l.cm_GetRootCellNameP = (cm_GetRootCellName_t)GetProcAddress (l.hInstLibConf, "cm_GetRootCellName");
123 if (!l.cm_GetRootCellNameP)
125 FreeLibrary (l.hInstLibConf);
126 l.hInstLibConf = NULL;
131 return l.hInstLibTokens && l.hInstLibConf;
135 void Creds_CloseLibraries (void)
137 if (l.hInstLibTokens)
139 FreeLibrary (l.hInstLibTokens);
140 l.hInstLibTokens = NULL;
143 if (l.hInstLibConf)
145 FreeLibrary (l.hInstLibConf);
146 l.hInstLibConf = NULL;
153 * ROUTINES ___________________________________________________________________
157 void GetGatewayName (LPTSTR pszGateway)
159 *pszGateway = TEXT('\0');
160 HKEY hk;
161 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, TEXT(AFSREG_CLT_SVC_PARAM_SUBKEY), 0,
162 (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &hk) == 0)
164 DWORD dwSize = MAX_PATH;
165 DWORD dwType = REG_SZ;
167 if (RegQueryValueEx (hk, TEXT("Gateway"), NULL, &dwType, (PBYTE)pszGateway, &dwSize) != 0)
168 *pszGateway = TEXT('\0');
170 RegCloseKey (hk);
175 BOOL IsServiceRunning (void)
177 if (g.fIsWinNT)
179 SERVICE_STATUS Status;
180 memset (&Status, 0x00, sizeof(Status));
181 Status.dwCurrentState = SERVICE_STOPPED;
183 SC_HANDLE hManager;
184 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
186 SC_HANDLE hService;
187 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
189 QueryServiceStatus (hService, &Status);
190 CloseServiceHandle (hService);
191 } else if ( IsDebuggerPresent() )
192 OutputDebugString("Unable to open Transarc AFS Daemon Service\n");
194 CloseServiceHandle (hManager);
195 } else if ( IsDebuggerPresent() )
196 OutputDebugString("Unable to open SC Manager\n");
198 return (Status.dwCurrentState == SERVICE_RUNNING);
201 TCHAR szGateway[ MAX_PATH ];
202 GetGatewayName (szGateway);
203 return (szGateway[0]) ? TRUE : FALSE;
207 BOOL IsServicePersistent (void)
209 struct {
210 QUERY_SERVICE_CONFIG Config;
211 BYTE buf[1024];
212 } Config;
213 memset (&Config, 0x00, sizeof(Config));
214 Config.Config.dwStartType = SERVICE_AUTO_START;
216 SC_HANDLE hManager;
217 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
219 SC_HANDLE hService;
220 if ((hService = OpenService (hManager, TEXT(AFSREG_CLT_SVC_NAME), GENERIC_READ)) != NULL)
222 DWORD dwSize = sizeof(Config);
223 QueryServiceConfig (hService, (QUERY_SERVICE_CONFIG*)&Config, sizeof(Config), &dwSize);
225 CloseServiceHandle (hService);
228 CloseServiceHandle (hManager);
231 return (Config.Config.dwStartType == SERVICE_AUTO_START) ? TRUE : FALSE;
235 BOOL IsServiceConfigured (void)
237 BOOL rc = FALSE;
238 HKEY hk;
240 if (!g.fIsWinNT)
242 rc = TRUE;
244 else if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, TEXT(AFSREG_CLT_SVC_PARAM_SUBKEY), 0,
245 (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &hk) == 0)
247 TCHAR szCell[ MAX_PATH ];
248 DWORD dwSize = sizeof(szCell);
249 DWORD dwType = REG_SZ;
251 if (RegQueryValueEx (hk, TEXT("Cell"), NULL, &dwType, (PBYTE)szCell, &dwSize) == 0)
253 if (szCell[0] != TEXT('\0'))
254 rc = TRUE;
257 RegCloseKey (hk);
260 return rc;
264 int GetCurrentCredentials (void)
266 int rc = KTC_NOCM;
268 lock_ObtainMutex(&g.credsLock);
270 // Free any knowledge we currently have about the user's credentials
272 if (g.aCreds)
273 Free (g.aCreds);
274 g.aCreds = NULL;
275 g.cCreds = 0;
276 g.tickLastRetest = GetTickCount();
278 // Start enumerating tokens.
280 if (!Creds_OpenLibraries())
282 rc = ERROR_DLL_INIT_FAILED;
284 else if (IsServiceRunning())
286 for (int iCell = 0; ; )
288 struct ktc_principal Principal;
289 if ((rc = ktc_ListTokens (iCell, &iCell, &Principal)) != 0)
290 break;
292 struct ktc_token Token;
293 struct ktc_principal ClientName;
294 if ((rc = ktc_GetToken (&Principal, &Token, sizeof(Token), &ClientName)) != 0)
295 break;
297 // Translate what we found about the user's creds in this particular
298 // cell into something readable.
300 TCHAR szCell[ 256 ];
301 CopyAnsiToString (szCell, Principal.cell);
302 if (!szCell[0])
303 continue;
305 TCHAR szUser[ 256 ];
306 CopyAnsiToString (szUser, ClientName.name);
307 if (ClientName.instance[0])
309 lstrcat (szUser, TEXT("."));
310 CopyAnsiToString (&szUser[ lstrlen(szUser) ], ClientName.instance);
313 SYSTEMTIME stExpires;
314 TimeToSystemTime (&stExpires, Token.endTime);
316 // We've found out that the user has--or perhaps recently had--
317 // credentials within a certain cell under the certain name.
318 // Stick that knowledge in our g.aCreds array.
320 size_t iCreds;
321 for (iCreds = 0; iCreds < g.cCreds; ++iCreds)
323 if (!lstrcmpi (g.aCreds[ iCreds ].szCell, szCell))
324 break;
326 if (iCreds == g.cCreds)
328 for (iCreds = 0; iCreds < g.cCreds; ++iCreds)
330 if (!g.aCreds[ iCreds ].szCell[0])
331 break;
333 if (!REALLOC (g.aCreds, g.cCreds, 1+iCreds, cREALLOC_CREDS))
334 break;
337 lstrcpy (g.aCreds[ iCreds ].szCell, szCell);
338 lstrcpy (g.aCreds[ iCreds ].szUser, szUser);
339 memcpy (&g.aCreds[ iCreds ].stExpires, &stExpires, sizeof(SYSTEMTIME));
340 LoadRemind (iCreds);
344 lock_ReleaseMutex(&g.credsLock);
346 // We've finished updating g.aCreds. Update the tray icon to reflect
347 // whether the user currently has any credentials at all, and
348 // re-enable the Remind timer.
350 ChangeTrayIcon (NIM_MODIFY);
351 return rc;
355 int DestroyCurrentCredentials (LPCTSTR pszCell)
357 int rc = KTC_NOCM;
359 if (!Creds_OpenLibraries())
361 rc = ERROR_DLL_INIT_FAILED;
363 else if (IsServiceRunning())
365 struct ktc_principal Principal;
366 memset (&Principal, 0x00, sizeof(Principal));
367 CopyStringToAnsi (Principal.cell, pszCell);
368 CopyStringToAnsi (Principal.name, TEXT("afs"));
369 rc = ktc_ForgetToken (&Principal);
370 if ( KFW_is_available() )
371 KFW_AFS_destroy_tickets_for_cell(Principal.cell);
374 if (rc != 0)
376 int idsTitle = (g.fIsWinNT) ? IDS_ERROR_TITLE : IDS_ERROR_TITLE_95;
377 int idsDesc = (!g.fIsWinNT) ? IDS_ERROR_DESTROY_95 : (rc == KTC_NOCM) ? IDS_ERROR_DESTROY_NOCM : IDS_ERROR_DESTROY_UNKNOWN;
378 Message (MB_ICONHAND | MB_OK, idsTitle, idsDesc, TEXT("%s%ld"), pszCell, rc);
381 return rc;
385 int ObtainNewCredentials (LPCTSTR pszCell, LPCTSTR pszUser, LPCTSTR pszPassword, BOOL Silent)
387 int rc = KTC_NOCM;
388 char *Result = NULL;
390 if (!Creds_OpenLibraries())
392 rc = ERROR_DLL_INIT_FAILED;
394 else if (IsServiceRunning())
396 char szCellA[ 256 ];
397 CopyStringToAnsi (szCellA, pszCell);
399 char szNameA[ 256 ];
400 CopyStringToAnsi (szNameA, pszUser);
402 char szPasswordA[ 256 ];
403 CopyStringToAnsi (szPasswordA, pszPassword);
405 char szSmbNameA[ MAXRANDOMNAMELEN ];
406 CopyStringToAnsi (szSmbNameA, g.SmbName);
408 int Expiration = 0;
410 if ( KFW_is_available() ) {
411 // KFW_AFS_get_cred() parses the szNameA field as complete princial including potentially
412 // a different realm then the specified cell name.
413 rc = KFW_AFS_get_cred(szNameA, szCellA, szPasswordA, 0, szSmbNameA[0] ? szSmbNameA : NULL, &Result);
414 } else {
415 char name[sizeof(szNameA)];
416 char instance[sizeof(szNameA)];
417 char cell[sizeof(szNameA)];
419 name[0] = '\0';
420 instance[0] = '\0';
421 cell[0] = '\0';
422 ka_ParseLoginName(szNameA, name, instance, cell);
424 if ( szSmbNameA[0] ) {
425 rc = ka_UserAuthenticateGeneral2(KA_USERAUTH_VERSION+KA_USERAUTH_AUTHENT_LOGON,
426 name, instance, szCellA, szPasswordA, szSmbNameA, 0, &Expiration, 0, &Result);
427 } else {
428 rc = ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION, name, instance, szCellA, szPasswordA, 0, &Expiration, 0, &Result);
433 if (!Silent && rc != 0)
435 int idsTitle = (g.fIsWinNT) ? IDS_ERROR_TITLE : IDS_ERROR_TITLE_95;
436 int idsDesc = (g.fIsWinNT) ? IDS_ERROR_OBTAIN : IDS_ERROR_OBTAIN_95;
437 Message (MB_ICONHAND | MB_OK, idsTitle, idsDesc, TEXT("%s%s%s%ld"), pszCell, pszUser, (Result) ? Result : TEXT(""), rc);
440 return rc;
444 int GetDefaultCell (LPTSTR pszCell)
446 int rc = KTC_NOCM;
447 *pszCell = TEXT('\0');
449 if (!Creds_OpenLibraries())
451 rc = ERROR_DLL_INIT_FAILED;
453 else if (IsServiceRunning())
455 char szCellA[ cchRESOURCE ] = "";
456 int rc;
457 HKEY hk;
459 if (RegOpenKeyEx (HKEY_CURRENT_USER, TEXT(AFSREG_USER_OPENAFS_SUBKEY), 0,
460 (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &hk) == 0)
462 DWORD dwSize = sizeof(szCellA);
463 DWORD dwType = REG_SZ;
464 RegQueryValueEx (hk, TEXT("Authentication Cell"), NULL, &dwType, (PBYTE)szCellA, &dwSize);
465 RegCloseKey (hk);
468 if (szCellA[0] == '\0') {
469 rc = cm_GetRootCellName (szCellA);
470 } else {
471 rc = 0;
473 if (rc == 0)
474 CopyAnsiToString(pszCell, szCellA);
476 return rc;