windows-server-manager-20050509
[openafs.git] / src / WINNT / afsapplib / al_creds.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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  */
9
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include <WINNT/afsapplib.h>
16 #include "al_dynlink.h"
17 #include <WINNT/TaAfsAdmSvrClient.h>
18
19
20 /*
21  * DEFINITIONS ________________________________________________________________
22  *
23  */
24
25
26 /*
27  * VARIABLES __________________________________________________________________
28  *
29  */
30
31
32 /*
33  * PROTOTYPES _________________________________________________________________
34  *
35  */
36
37 void OnExpiredCredentials (WPARAM wp, LPARAM lp);
38
39 BOOL CALLBACK OpenCell_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
40 void OpenCell_OnInitDialog (HWND hDlg, LPOPENCELLDLG_PARAMS lpp);
41 BOOL OpenCell_OnOK (HWND hDlg, LPOPENCELLDLG_PARAMS lpp);
42 void OpenCell_OnCell (HWND hDlg);
43 void OpenCell_Enable (HWND hDlg, BOOL fEnable);
44 void OpenCell_OnGotCreds (HWND hDlg, LPARAM lp);
45
46 BOOL CALLBACK NewCreds_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
47 void NewCreds_OnInitDialog (HWND hDlg, LPCREDENTIALSDLG_PARAMS lpp);
48 BOOL NewCreds_OnOK (HWND hDlg, LPCREDENTIALSDLG_PARAMS lpp);
49 void NewCreds_OnLogin (HWND hDlg);
50 void NewCreds_Enable (HWND hDlg, BOOL fEnable);
51 void NewCreds_GetOutParams (HWND hDlg, LPCREDENTIALSDLG_PARAMS lpp);
52
53 BOOL CALLBACK BadCreds_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
54
55
56 /*
57  * ROUTINES ___________________________________________________________________
58  *
59  */
60
61 BOOL AfsAppLib_CrackCredentials (PVOID hCreds, LPTSTR pszCell, LPTSTR pszUser, LPSYSTEMTIME pst, ULONG *pStatus)
62 {
63    BOOL rc = FALSE;
64    ULONG status = 0;
65
66    DWORD idClient;
67    if ((idClient = AfsAppLib_GetAdminServerClientID()) != 0)
68       {
69       rc = asc_CredentialsCrack (idClient, hCreds, pszCell, pszUser, pst, &status);
70       }
71    else 
72        if (OpenClientLibrary())
73       {
74       char szUserA[ cchRESOURCE ], szUser2A[ cchRESOURCE ];
75       char szCellA[ cchRESOURCE ];
76       unsigned long dateExpire;
77       int fHasKasToken;
78
79       if (afsclient_TokenQuery (hCreds, &dateExpire, szUserA, szUser2A, szCellA, &fHasKasToken, (afs_status_p)&status))
80          {
81          rc = TRUE;
82          CopyAnsiToString (pszUser, szUserA);
83          CopyAnsiToString (pszCell, szCellA);
84          AfsAppLib_UnixTimeToSystemTime (pst, dateExpire);
85          }
86
87       CloseClientLibrary();
88       }
89
90    if (!hCreds && pStatus)
91       *pStatus = status;
92    return rc;
93 }
94
95
96 PVOID AfsAppLib_GetCredentials (LPCTSTR pszCell, ULONG *pStatus)
97 {
98    PVOID hCreds = NULL;
99    ULONG status = 0;
100
101    DWORD idClient;
102    if ((idClient = AfsAppLib_GetAdminServerClientID()) != 0)
103       {
104       hCreds = asc_CredentialsGet (idClient, pszCell, &status);
105       }
106    else
107        if (OpenClientLibrary())
108       {
109       LPSTR pszCellA = StringToAnsi (pszCell);
110
111       afsclient_TokenGetExisting (pszCellA, &hCreds, (afs_status_p)&status);
112
113       FreeString (pszCellA, pszCell);
114       CloseClientLibrary();
115       }
116
117    if (!hCreds && pStatus)
118       *pStatus = status;
119    return hCreds;
120 }
121
122
123 PVOID AfsAppLib_SetCredentials (LPCTSTR pszCell, LPCTSTR pszUser, LPCTSTR pszPassword, ULONG *pStatus)
124 {
125    PVOID hCreds = NULL;
126    ULONG status = 0;
127
128    DWORD idClient;
129    if ((idClient = AfsAppLib_GetAdminServerClientID()) != 0)
130       {
131       hCreds = asc_CredentialsSet (idClient, pszCell, pszUser, pszPassword, &status);
132       }
133    else
134        if (OpenClientLibrary())
135       {
136       char szCellA[ cchRESOURCE ];
137       char szUserA[ cchRESOURCE ];
138       char szPasswordA[ cchRESOURCE ];
139       CopyStringToAnsi (szCellA, pszCell);
140       CopyStringToAnsi (szUserA, pszUser);
141       CopyStringToAnsi (szPasswordA, pszPassword);
142
143       afsclient_TokenGetNew (szCellA, szUserA, szPasswordA, &hCreds, (afs_status_p)&status);
144
145       CloseClientLibrary();
146       }
147
148    if (hCreds)
149       {
150       PostMessage (AfsAppLib_GetMainWindow(), WM_REFRESHED_CREDENTIALS, 0, (LPARAM)hCreds);
151       }
152
153    if (!hCreds && pStatus)
154       *pStatus = status;
155    return hCreds;
156 }
157
158
159 /*
160  * OPEN CELL DIALOG ___________________________________________________________
161  *
162  */
163
164 BOOL AfsAppLib_ShowOpenCellDialog (LPOPENCELLDLG_PARAMS lpp)
165 {
166    HINSTANCE hInst = APP_HINST;
167    if (lpp->idd == 0)
168       {
169       hInst = APPLIB_HINST;
170       lpp->idd = IDD_APPLIB_OPENCELL;
171       }
172    if (lpp->hCreds == 0)
173       {
174       if (lpp->szCell[0])
175          lpp->hCreds = AfsAppLib_GetCredentials (lpp->szCell);
176       else
177          lpp->hCreds = AfsAppLib_GetCredentials (NULL);
178       }
179
180    int rc = ModalDialogParam (lpp->idd, lpp->hParent, (DLGPROC)OpenCell_DlgProc, (LPARAM)lpp);
181
182    return (rc == IDOK) ? TRUE : FALSE;
183 }
184
185
186 BOOL CALLBACK OpenCell_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
187 {
188    LPOPENCELLDLG_PARAMS lpp;
189    if (msg == WM_INITDIALOG)
190       SetWindowLong (hDlg, DWL_USER, lp);
191
192    if ((lpp = (LPOPENCELLDLG_PARAMS)GetWindowLong (hDlg, DWL_USER)) != NULL)
193       {
194       if (lpp->hookproc)
195          {
196          if (CallWindowProc ((WNDPROC)lpp->hookproc, hDlg, msg, wp, lp))
197             return TRUE;
198          }
199       }
200
201    if (lpp != NULL)
202       {
203       if (AfsAppLib_HandleHelp (lpp->idd, hDlg, msg, wp, lp))
204          return TRUE;
205       }
206
207    switch (msg)
208       {
209       case WM_INITDIALOG:
210          OpenCell_OnInitDialog (hDlg, lpp);
211          break;
212
213       case WM_COMMAND:
214          switch (LOWORD(wp))
215             {
216             case IDCANCEL:
217                EndDialog (hDlg, IDCANCEL);
218                return TRUE;
219
220             case IDOK:
221                if (OpenCell_OnOK (hDlg, lpp))
222                   EndDialog (hDlg, IDOK);
223                return TRUE;
224
225             case IDC_OPENCELL_CELL:
226                switch (HIWORD(wp))
227                   {
228                   case CBN_SELCHANGE:
229                      TCHAR szCell[ cchNAME ];
230                      SendDlgItemMessage (hDlg, IDC_OPENCELL_CELL, CB_GETLBTEXT, CB_GetSelected(GetDlgItem (hDlg, IDC_OPENCELL_CELL)), (LPARAM)szCell);
231                      SetDlgItemText (hDlg, IDC_OPENCELL_CELL, szCell);
232                      OpenCell_OnCell (hDlg);
233                      break;
234
235                   case CBN_EDITCHANGE:
236                      OpenCell_OnCell (hDlg);
237                      break;
238                   }
239                break;
240             }
241          break;
242
243       case WM_REFRESHED_CREDENTIALS:
244          OpenCell_OnGotCreds (hDlg, lp);
245          break;
246       }
247
248    return FALSE;
249 }
250
251
252 void OpenCell_OnInitDialog (HWND hDlg, LPOPENCELLDLG_PARAMS lpp)
253 {
254    // Fix the title of the dialog (unless the caller has supplied a
255    // custom dialog template)
256    //
257    if (lpp && (lpp->idd == IDD_APPLIB_OPENCELL))
258       {
259       TCHAR szApplication[ cchNAME ];
260       AfsAppLib_GetAppName (szApplication);
261       if (szApplication[0] != TEXT('\0'))
262          {
263          TCHAR szTitle[ cchRESOURCE ];
264          GetWindowText (hDlg, szTitle, cchRESOURCE);
265          lstrcat (szTitle, TEXT(" - "));
266          lstrcat (szTitle, szApplication);
267          SetWindowText (hDlg, szTitle);
268          }
269       }
270
271    // Fill in the 'Cell:' combobox; we'll list the default cell, and any
272    // cell which the user has specified before.
273    //
274    CB_StartChange (GetDlgItem (hDlg, IDC_OPENCELL_CELL), TRUE);
275
276    if (!lpp->lpcl)
277       {
278       TCHAR szDefCell[ cchNAME ];
279       if (AfsAppLib_GetLocalCell (szDefCell) && *szDefCell)
280          {
281          CB_AddItem (GetDlgItem (hDlg, IDC_OPENCELL_CELL), szDefCell, 1);
282          }
283       }
284    else for (size_t ii = 0; ii < lpp->lpcl->nCells; ++ii)
285       {
286       CB_AddItem (GetDlgItem (hDlg, IDC_OPENCELL_CELL), lpp->lpcl->aCells[ii], 1+ii);
287       }
288
289    CB_EndChange (GetDlgItem (hDlg, IDC_OPENCELL_CELL), 1);
290
291    // Set up the "Credentials" box; if the user needs credentials to edit
292    // this default cell, jump the cursor to the appropriate field
293    //
294    SetDlgItemText (hDlg, IDC_OPENCELL_ID, TEXT("admin"));
295
296    OpenCell_OnCell (hDlg);
297 }
298
299
300 BOOL OpenCell_OnOK (HWND hDlg, LPOPENCELLDLG_PARAMS lpp)
301 {
302    BOOL rc = FALSE;
303    OpenCell_Enable (hDlg, FALSE);
304    StartHourGlass ();
305
306    // Remember what cell the user chose to edit
307    //
308    GetDlgItemText (hDlg, IDC_OPENCELL_CELL, lpp->szCell, cchNAME);
309
310    // Try to obtain the credentials specified by the user.
311    //
312    TCHAR szCell[ cchNAME ];
313    GetDlgItemText (hDlg, IDC_OPENCELL_CELL, szCell, cchNAME);
314
315    TCHAR szUser[ cchRESOURCE ];
316    GetDlgItemText (hDlg, IDC_OPENCELL_ID, szUser, cchNAME);
317
318    TCHAR szPassword[ cchRESOURCE ];
319    GetDlgItemText (hDlg, IDC_OPENCELL_PASSWORD, szPassword, cchNAME);
320
321    ULONG status;
322    if ((lpp->hCreds = AfsAppLib_SetCredentials (lpp->szCell, szUser, szPassword, &status)) == NULL)
323       {
324       ErrorDialog (status, IDS_ERROR_BAD_CREDENTIALS);
325       }
326    else
327       {
328       // See if those credentials are sufficient
329       //
330       CHECKCREDS_PARAMS pp;
331       memset (&pp, 0x00, sizeof(pp));
332       memcpy (&pp.bcdp, &lpp->bcdp, sizeof(BADCREDSDLG_PARAMS));
333       pp.bcdp.hParent = hDlg;
334       pp.hCreds = lpp->hCreds;
335       pp.fShowWarning = TRUE;
336
337       if ((rc = AfsAppLib_CheckCredentials (&pp)) == FALSE)
338          {
339          SetDlgItemText (hDlg, IDC_OPENCELL_ID, TEXT("admin"));
340          PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg,IDC_OPENCELL_PASSWORD), TRUE);
341          }
342       }
343
344    if (!rc)
345       OpenCell_Enable (hDlg, TRUE);
346    StopHourGlass ();
347    return rc;
348 }
349
350
351 typedef struct
352    {
353    HWND hDlg;
354    TCHAR szCell[ cchNAME ];
355    TCHAR szUser[ cchNAME ];
356    SYSTEMTIME stExpire;
357    BOOL fGotCreds;
358    BOOL fValidCreds;
359    } OPENCELL_ONCELL_PARAMS, *LPOPENCELL_ONCELL_PARAMS;
360
361 DWORD WINAPI OpenCell_OnCell_ThreadProc (PVOID lp)
362 {
363    LPOPENCELL_ONCELL_PARAMS lpp;
364    if ((lpp = (LPOPENCELL_ONCELL_PARAMS)lp) != NULL)
365       {
366       PVOID hCreds = AfsAppLib_GetCredentials (lpp->szCell);
367       lpp->fGotCreds = AfsAppLib_CrackCredentials (hCreds, lpp->szCell, lpp->szUser, &lpp->stExpire);
368       lpp->fValidCreds = FALSE;
369
370       if (lpp->fGotCreds && AfsAppLib_IsTimeInFuture (&lpp->stExpire))
371          {
372          CHECKCREDS_PARAMS pp;
373          memset (&pp, 0x00, sizeof(pp));
374          pp.hCreds = hCreds;
375          lpp->fValidCreds = AfsAppLib_CheckCredentials(&pp);
376          }
377
378       // Post our results; we'll return the same packet we got.
379       //
380       if (IsWindow (lpp->hDlg))
381          PostMessage (lpp->hDlg, WM_REFRESHED_CREDENTIALS, 0, (LPARAM)lpp);
382       else
383          Delete (lpp);
384       }
385
386    return 0;
387 }
388
389
390 void OpenCell_OnCell (HWND hDlg)
391 {
392    // Fire up a background thread to query our current credentials in the
393    // selected cell.
394    //
395    LPOPENCELL_ONCELL_PARAMS lpp = New (OPENCELL_ONCELL_PARAMS);
396    memset (lpp, 0x00, sizeof(lpp));
397    GetDlgItemText (hDlg, IDC_OPENCELL_CELL, lpp->szCell, cchNAME);
398    lpp->hDlg = hDlg;
399
400    DWORD dwThreadID;
401    CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)OpenCell_OnCell_ThreadProc, lpp, 0, &dwThreadID);
402 }
403
404
405 void OpenCell_OnGotCreds (HWND hDlg, LPARAM lp)
406 {
407    LPOPENCELL_ONCELL_PARAMS lpp;
408    if ((lpp = (LPOPENCELL_ONCELL_PARAMS)lp) != NULL)
409       {
410       // Don't do anything to the dialog if the user has chosen a different
411       // cell than that for which we just queried credentials.
412       //
413       TCHAR szCell[ cchNAME ];
414       GetDlgItemText (hDlg, IDC_OPENCELL_CELL, szCell, cchNAME);
415
416       if (!lstrcmpi (szCell, lpp->szCell))
417          {
418          TCHAR szPrevCreds[ cchRESOURCE ];
419          GetDlgItemText (hDlg, IDC_OPENCELL_OLDCREDS, szPrevCreds, cchRESOURCE);
420
421          if (!lpp->fGotCreds)
422             {
423             LPTSTR psz = FormatString (IDS_CREDS_NONE, TEXT("%s"), lpp->szCell);
424             SetDlgItemText (hDlg, IDC_OPENCELL_OLDCREDS, psz);
425             FreeString (psz);
426             }
427          else if (!AfsAppLib_IsTimeInFuture (&lpp->stExpire))
428             {
429             LPTSTR pszCreds = FormatString (IDS_CREDS_EXPIRED, TEXT("%s%s%t"), lpp->szCell, lpp->szUser, &lpp->stExpire);
430             SetDlgItemText (hDlg, IDC_OPENCELL_OLDCREDS, pszCreds);
431             FreeString (pszCreds);
432             }
433          else
434             {
435             LPTSTR pszCreds = FormatString (IDS_CREDS_VALID, TEXT("%s%s%t"), lpp->szCell, lpp->szUser, &lpp->stExpire);
436             SetDlgItemText (hDlg, IDC_OPENCELL_OLDCREDS, pszCreds);
437             FreeString (pszCreds);
438             }
439
440          SetDlgItemText (hDlg, IDC_OPENCELL_ID, (lpp->fGotCreds) ? lpp->szUser : TEXT("admin"));
441
442          if (!lpp->fValidCreds && !szPrevCreds[0])
443             PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg,IDC_OPENCELL_PASSWORD), TRUE);
444          }
445
446       Delete (lpp);
447       }
448 }
449
450
451 void OpenCell_Enable (HWND hDlg, BOOL fEnable)
452 {
453    EnableWindow (GetDlgItem (hDlg, IDOK), fEnable);
454    EnableWindow (GetDlgItem (hDlg, IDCANCEL), fEnable);
455    EnableWindow (GetDlgItem (hDlg, IDHELP), fEnable);
456    EnableWindow (GetDlgItem (hDlg, IDC_OPENCELL_CELL), fEnable);
457    EnableWindow (GetDlgItem (hDlg, IDC_OPENCELL_ID), fEnable);
458    EnableWindow (GetDlgItem (hDlg, IDC_OPENCELL_PASSWORD), fEnable);
459 }
460
461
462 /*
463  * NEW CREDENTIALS DIALOG _____________________________________________________
464  *
465  */
466
467 BOOL AfsAppLib_ShowCredentialsDialog (LPCREDENTIALSDLG_PARAMS lpp)
468 {
469    HINSTANCE hInst = APP_HINST;
470    if (lpp->idd == 0)
471       {
472       hInst = APPLIB_HINST;
473       lpp->idd = IDD_APPLIB_CREDENTIALS;
474       }
475    if (lpp->hCreds == 0)
476       {
477       if (lpp->szCell[0])
478          lpp->hCreds = AfsAppLib_GetCredentials (lpp->szCell);
479       else
480          lpp->hCreds = AfsAppLib_GetCredentials (NULL);
481       }
482
483    int rc = ModalDialogParam (lpp->idd, lpp->hParent, (DLGPROC)NewCreds_DlgProc, (LPARAM)lpp);
484
485    return (rc == IDOK) ? TRUE : FALSE;
486 }
487
488
489 BOOL CALLBACK NewCreds_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
490 {
491    LPCREDENTIALSDLG_PARAMS lpp;
492    if (msg == WM_INITDIALOG)
493       SetWindowLong (hDlg, DWL_USER, lp);
494
495    if ((lpp = (LPCREDENTIALSDLG_PARAMS)GetWindowLong (hDlg, DWL_USER)) != NULL)
496       {
497       if (lpp->hookproc)
498          {
499          if (CallWindowProc ((WNDPROC)lpp->hookproc, hDlg, msg, wp, lp))
500             return TRUE;
501          }
502       }
503
504    if (lpp != NULL)
505       {
506       if (AfsAppLib_HandleHelp (lpp->idd, hDlg, msg, wp, lp))
507          return TRUE;
508       }
509
510    switch (msg)
511       {
512       case WM_INITDIALOG:
513          NewCreds_OnInitDialog (hDlg, lpp);
514          break;
515
516       case WM_COMMAND:
517          switch (LOWORD(wp))
518             {
519             case IDCANCEL:
520                EndDialog (hDlg, IDCANCEL);
521                return TRUE;
522
523             case IDOK:
524                               if (NewCreds_OnOK (hDlg, lpp))
525                   EndDialog (hDlg, IDOK);
526                return TRUE;
527
528             case IDC_CREDS_LOGIN:
529                NewCreds_OnLogin (hDlg);
530                break;
531             }
532          break;
533       }
534
535    return FALSE;
536 }
537
538
539 void NewCreds_OnInitDialog (HWND hDlg, LPCREDENTIALSDLG_PARAMS lpp)
540 {
541    // Fix the title of the dialog (unless the caller has supplied a
542    // custom dialog template)
543    //
544    if (lpp && (lpp->idd == IDD_APPLIB_CREDENTIALS))
545       {
546       TCHAR szApplication[ cchNAME ];
547       AfsAppLib_GetAppName (szApplication);
548       if (szApplication[0] != TEXT('\0'))
549          {
550          TCHAR szTitle[ cchRESOURCE ];
551          GetWindowText (hDlg, szTitle, cchRESOURCE);
552          lstrcat (szTitle, TEXT(" - "));
553          lstrcat (szTitle, szApplication);
554          SetWindowText (hDlg, szTitle);
555          }
556       }
557
558    // Set up the "Credentials" boxes
559    //
560    TCHAR szUser[ cchRESOURCE ];
561    SYSTEMTIME st;
562
563    BOOL fValidCreds = TRUE;
564    BOOL fShowCreds = TRUE;
565    CHECKCREDS_PARAMS pp;
566    memset (&pp, 0x00, sizeof(pp));
567    pp.hCreds = lpp->hCreds;
568    pp.fShowWarning = FALSE;
569    memcpy (&pp.bcdp, &lpp->bcdp, sizeof(BADCREDSDLG_PARAMS));
570    pp.bcdp.hParent = hDlg;
571
572    if (!AfsAppLib_CrackCredentials (lpp->hCreds, lpp->szCell, szUser, &st))
573       {
574       fValidCreds = FALSE;
575       fShowCreds = FALSE;
576       }
577    if (!AfsAppLib_IsTimeInFuture (&st))
578       {
579       fValidCreds = FALSE;
580       fShowCreds = FALSE;
581       }
582    if (!AfsAppLib_CheckCredentials (&pp))
583       {
584       fValidCreds = FALSE;
585       }
586
587    CheckDlgButton (hDlg, IDC_CREDS_LOGIN, !fValidCreds);
588    if (!fValidCreds)
589       PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg,IDC_CREDS_PASSWORD), TRUE);
590
591    SetDlgItemText (hDlg, IDC_CREDS_CELL, lpp->szCell);
592
593    if (fShowCreds)
594       {
595       SetDlgItemText (hDlg, IDC_CREDS_CURRENTID, szUser);
596
597       LPTSTR pszDate = FormatString (TEXT("%1"), TEXT("%t"), &st);
598       SetDlgItemText (hDlg, IDC_CREDS_EXPDATE, pszDate);
599       FreeString (pszDate);
600       }
601
602    SetDlgItemText (hDlg, IDC_CREDS_ID, TEXT("admin"));
603
604    NewCreds_OnLogin (hDlg);
605 }
606
607
608 BOOL NewCreds_OnOK (HWND hDlg, LPCREDENTIALSDLG_PARAMS lpp)
609 {
610    NewCreds_GetOutParams (hDlg, lpp);
611    if (!IsDlgButtonChecked (hDlg, IDC_CREDS_LOGIN))
612       return TRUE;
613
614    BOOL rc = FALSE;
615    StartHourGlass ();
616    NewCreds_Enable (hDlg, FALSE);
617
618    // Try to obtain the credentials specified by the user.
619    //
620    TCHAR szUser[ cchRESOURCE ];
621    GetDlgItemText (hDlg, IDC_CREDS_ID, szUser, cchNAME);
622
623    TCHAR szPassword[ cchRESOURCE ];
624    GetDlgItemText (hDlg, IDC_CREDS_PASSWORD, szPassword, cchNAME);
625
626    ULONG status;
627    if ((lpp->hCreds = AfsAppLib_SetCredentials (lpp->szCell, szUser, szPassword, &status)) == NULL)
628       {
629       ErrorDialog (status, IDS_ERROR_BAD_CREDENTIALS);
630       }
631    else
632       {
633       // See if those credentials are sufficient
634       //
635       CHECKCREDS_PARAMS pp;
636       memset (&pp, 0x00, sizeof(pp));
637       memcpy (&pp.bcdp, &lpp->bcdp, sizeof(BADCREDSDLG_PARAMS));
638       pp.bcdp.hParent = hDlg;
639       pp.hCreds = lpp->hCreds;
640       pp.fShowWarning = TRUE;
641
642       if ((rc = AfsAppLib_CheckCredentials (&pp)) == FALSE)
643          {
644          SetDlgItemText (hDlg, IDC_CREDS_ID, TEXT("admin"));
645          PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg,IDC_CREDS_PASSWORD), TRUE);
646          }
647       }
648
649    if (!rc)
650       NewCreds_Enable (hDlg, TRUE);
651    StopHourGlass ();
652    return rc;
653 }
654
655
656 void NewCreds_OnLogin (HWND hDlg)
657 {
658    BOOL fEnable = IsDlgButtonChecked (hDlg, IDC_CREDS_LOGIN);
659
660    EnableWindow (GetDlgItem (hDlg, IDC_CREDS_ID),       fEnable);
661    EnableWindow (GetDlgItem (hDlg, IDC_CREDS_PASSWORD), fEnable);
662 }
663
664
665 void NewCreds_Enable (HWND hDlg, BOOL fEnable)
666 {
667    EnableWindow (GetDlgItem (hDlg, IDOK), fEnable);
668    EnableWindow (GetDlgItem (hDlg, IDCANCEL), fEnable);
669    EnableWindow (GetDlgItem (hDlg, IDHELP), fEnable);
670    EnableWindow (GetDlgItem (hDlg, IDC_CREDS_LOGIN), fEnable);
671
672    if (fEnable)
673       NewCreds_OnLogin (hDlg);
674    else
675       {
676       EnableWindow (GetDlgItem (hDlg, IDC_CREDS_ID),       fEnable);
677       EnableWindow (GetDlgItem (hDlg, IDC_CREDS_PASSWORD), fEnable);
678       }
679 }
680
681
682 void NewCreds_GetOutParams (HWND hDlg, LPCREDENTIALSDLG_PARAMS lpp)
683 {
684    if (!IsDlgButtonChecked (hDlg, IDC_CREDS_LOGIN))
685       {
686       lpp->szIdentity[0] = TEXT('\0');
687       lpp->szPassword[0] = TEXT('\0');
688       }
689    else
690       {
691       GetDlgItemText (hDlg, IDC_CREDS_ID, lpp->szIdentity, cchNAME);
692       GetDlgItemText (hDlg, IDC_CREDS_PASSWORD, lpp->szPassword, cchNAME);
693       }
694 }
695
696
697 /*
698  * TEST CREDENTIALS ___________________________________________________________
699  *
700  */
701
702 typedef struct
703    {
704    BADCREDSDLG_PARAMS bcdp;
705    LPTSTR pszFullText;
706    PVOID hCreds;
707    } REALBADCREDSDLG_PARAMS, *LPREALBADCREDSDLG_PARAMS;
708
709 BOOL AfsAppLib_CheckCredentials (LPCHECKCREDS_PARAMS lpp)
710 {
711    BOOL fCredsOK = TRUE;
712    int idsWarning = IDS_BADCREDS_DESC_GENERAL;
713
714    TCHAR szCell[ cchNAME ];
715    TCHAR szUser[ cchNAME ];
716    SYSTEMTIME stExpire;
717
718    if (!AfsAppLib_CrackCredentials (lpp->hCreds, szCell, szUser, &stExpire))
719       {
720       fCredsOK = FALSE;
721       }
722    else if (!AfsAppLib_IsUserAdmin (lpp->hCreds, szUser))
723       {
724       fCredsOK = FALSE;
725       idsWarning = IDS_BADCREDS_DESC_BADCHOICE;
726       }
727    else if (!AfsAppLib_IsTimeInFuture (&stExpire))
728       {
729       fCredsOK = FALSE;
730       idsWarning = IDS_BADCREDS_DESC_EXPIRED;
731       }
732
733    if (!fCredsOK && lpp->fShowWarning)
734       {
735       if (lpp->bcdp.pfShowWarningEver && !(*lpp->bcdp.pfShowWarningEver))
736          {
737          fCredsOK = TRUE; // user says always ignore bad credentials.
738          }
739       else
740          {
741          if (!szCell[0])
742             AfsAppLib_GetLocalCell (szCell);
743
744          int idsDesc = (lpp->bcdp.idsDesc) ? lpp->bcdp.idsDesc : IDS_BADCREDS_DESC2;
745          LPTSTR pszDesc = FormatString (idsDesc, TEXT("%s"), szCell);
746          LPTSTR pszFullText = FormatString (idsWarning, TEXT("%s%s%m"), szCell, pszDesc, IDS_BADCREDS_DESC3);
747          FreeString (pszDesc);
748
749          REALBADCREDSDLG_PARAMS pp;
750          memset (&pp, 0x00, sizeof(pp));
751          pp.pszFullText = pszFullText;
752          memcpy (&pp.bcdp, &lpp->bcdp, sizeof(BADCREDSDLG_PARAMS));
753
754          HINSTANCE hInst = APP_HINST;
755          if (pp.bcdp.idd == 0)
756             {
757             hInst = APPLIB_HINST;
758             pp.bcdp.idd = IDD_APPLIB_BADCREDS;
759             }
760
761          int rc = ModalDialogParam (pp.bcdp.idd, pp.bcdp.hParent, (DLGPROC)BadCreds_DlgProc, (LPARAM)&pp);
762          if (rc == IDCANCEL)
763             {
764             fCredsOK = TRUE; // user says ignore bad credentials this time.
765             }
766
767          FreeString (pszFullText);
768          }
769       }
770
771    return fCredsOK;
772 }
773
774
775 BOOL CALLBACK BadCreds_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
776 {
777    LPREALBADCREDSDLG_PARAMS lpp;
778    if (msg == WM_INITDIALOG)
779       SetWindowLong (hDlg, DWL_USER, lp);
780    if ((lpp = (LPREALBADCREDSDLG_PARAMS)GetWindowLong (hDlg, DWL_USER)) != NULL) 
781       {
782       if (lpp->bcdp.hookproc)
783          {
784          if (CallWindowProc ((WNDPROC)lpp->bcdp.hookproc, hDlg, msg, wp, lp))
785             return TRUE;
786          }
787       if (AfsAppLib_HandleHelp (lpp->bcdp.idd, hDlg, msg, wp, lp))
788          return TRUE;
789       }
790
791    switch (msg)
792       {
793       case WM_INITDIALOG:
794          TCHAR szApplication[ cchNAME ];
795          AfsAppLib_GetAppName (szApplication);
796          if (szApplication[0] != TEXT('\0'))
797             {
798             TCHAR szTitle[ cchRESOURCE ];
799             GetWindowText (hDlg, szTitle, cchRESOURCE);
800             lstrcat (szTitle, TEXT(" - "));
801             lstrcat (szTitle, szApplication);
802             SetWindowText (hDlg, szTitle);
803             }
804          if (!lpp || !lpp->bcdp.pfShowWarningEver)
805             DestroyWindow (GetWindow (hDlg, IDC_BADCREDS_SHUTUP));
806
807          SetDlgItemText (hDlg, IDC_BADCREDS_DESC, lpp->pszFullText);
808          break;
809
810       case WM_COMMAND:
811          switch (LOWORD(wp))
812             {
813             case IDOK:
814             case IDCANCEL:
815                if (lpp && lpp->bcdp.pfShowWarningEver)
816                   *lpp->bcdp.pfShowWarningEver = !IsDlgButtonChecked (hDlg, IDC_BADCREDS_SHUTUP);
817                EndDialog (hDlg, LOWORD(wp));
818                break;
819             }
820          break;
821       }
822
823    return FALSE;
824 }
825
826
827 /*
828  * EXPIRED CREDENTIALS ________________________________________________________
829  *
830  */
831
832 void AfsAppLib_CheckForExpiredCredentials (LPCREDENTIALSDLG_PARAMS lpp)
833 {
834    static PVOID hCredsPrevious = NULL;
835    static BOOL fHadGoodCredentials;
836
837    TCHAR szCell[ cchNAME ];
838    TCHAR szUser[ cchNAME ];
839    SYSTEMTIME stExpire;
840
841    BOOL fHaveCredentials;
842    fHaveCredentials = AfsAppLib_CrackCredentials (lpp->hCreds, szCell, szUser, &stExpire);
843
844    if (hCredsPrevious && (hCredsPrevious != lpp->hCreds))
845       {
846       if (!fHaveCredentials)
847          fHadGoodCredentials = FALSE;
848       else if (!AfsAppLib_IsTimeInFuture (&stExpire))
849          fHadGoodCredentials = FALSE;
850       else
851          fHadGoodCredentials = TRUE;
852       hCredsPrevious = lpp->hCreds;
853       }
854    else if (fHaveCredentials && AfsAppLib_IsTimeInFuture (&stExpire))
855       {
856       fHadGoodCredentials = TRUE;
857       }
858    else if (fHadGoodCredentials) // used to have good credentials, but now don't
859       {
860       fHadGoodCredentials = FALSE;
861
862       LPCREDENTIALSDLG_PARAMS lppCopy = New (CREDENTIALSDLG_PARAMS);
863       memcpy (lppCopy, lpp, sizeof(CREDENTIALSDLG_PARAMS));
864
865       if (!AfsAppLib_GetMainWindow())
866          OnExpiredCredentials ((WPARAM)(!AfsAppLib_IsTimeInFuture(&stExpire)), (LPARAM)lppCopy);
867       else
868          PostMessage (AfsAppLib_GetMainWindow(), WM_EXPIRED_CREDENTIALS, (WPARAM)(!AfsAppLib_IsTimeInFuture(&stExpire)), (LPARAM)lppCopy);
869       }
870 }
871
872
873 void OnExpiredCredentials (WPARAM wp, LPARAM lp)
874 {
875    BOOL fExpired = (BOOL)wp;
876    LPCREDENTIALSDLG_PARAMS lpp = (LPCREDENTIALSDLG_PARAMS)lp;
877
878    if (lpp && lpp->bcdp.pfShowWarningEver && *(lpp->bcdp.pfShowWarningEver))
879       {
880       int idsWarning = (wp) ? IDS_BADCREDS_DESC_EXPIRED : IDS_BADCREDS_DESC_DESTROYED;
881
882       int idsDesc = (lpp->bcdp.idsDesc) ? lpp->bcdp.idsDesc : IDS_BADCREDS_DESC2;
883       LPTSTR pszDesc = FormatString (idsDesc, TEXT("%s"), lpp->szCell);
884       LPTSTR pszFullText = FormatString (idsWarning, TEXT("%s%s%m"), lpp->szCell, pszDesc, IDS_BADCREDS_DESC3);
885       FreeString (pszDesc);
886
887       REALBADCREDSDLG_PARAMS pp;
888       memset (&pp, 0x00, sizeof(pp));
889       pp.pszFullText = pszFullText;
890       memcpy (&pp.bcdp, &lpp->bcdp, sizeof(BADCREDSDLG_PARAMS));
891
892       if (ModalDialogParam (IDD_APPLIB_BADCREDS, NULL, (DLGPROC)BadCreds_DlgProc, (LPARAM)&pp) != IDCANCEL)
893          {
894          AfsAppLib_ShowCredentialsDialog (lpp);
895          }
896
897       FreeString (pszFullText);
898       }
899
900    if (lpp)
901       {
902       Delete (lpp);
903       }
904 }
905
906
907 BOOL AfsAppLib_IsUserAdmin (PVOID hCreds, LPTSTR pszUser)
908 {
909 #ifndef USE_KASERVER
910     return TRUE;
911 #else
912    BOOL rc = FALSE;
913    afs_status_t status;
914
915    DWORD idClient;
916    if ((idClient = AfsAppLib_GetAdminServerClientID()) != 0)
917       {
918       TCHAR szCell[ cchRESOURCE ];
919       TCHAR szUser[ cchRESOURCE ];
920       SYSTEMTIME stExpire;
921       if (asc_CredentialsCrack (idClient, hCreds, szCell, szUser, &stExpire, (ULONG*)&status))
922          {
923          ASID idCell;
924          if (asc_CellOpen (idClient, hCreds, szCell, AFSADMSVR_SCOPE_USERS, &idCell, (ULONG*)&status))
925             {
926             ASID idUser;
927             if (asc_ObjectFind (idClient, idCell, TYPE_USER, pszUser, &idUser, (ULONG*)&status))
928                {
929                ASOBJPROP Info;
930                if (asc_ObjectPropertiesGet (idClient, GET_ALL_DATA, idCell, idUser, &Info, (ULONG*)&status))
931                   {
932                   if (Info.u.UserProperties.fHaveKasInfo)
933                      {
934                      rc = Info.u.UserProperties.KASINFO.fIsAdmin;
935                      }
936                   }
937                }
938             asc_CellClose (idClient, idCell, (ULONG*)&status);
939             }
940          }
941       }
942    else if (OpenClientLibrary())
943       {
944       if (OpenKasLibrary())
945          {
946          char szUserA[ cchRESOURCE ], szUser2A[ cchRESOURCE ];
947          char szCellA[ cchRESOURCE ];
948          unsigned long dateExpire;
949          int fHasKasToken;
950
951          if (afsclient_TokenQuery (hCreds, &dateExpire, szUserA, szUser2A, szCellA, &fHasKasToken, (afs_status_p)&status))
952             {
953             PVOID hCell;
954             if (afsclient_CellOpen (szCellA, hCreds, &hCell, &status))
955                {
956                kas_identity_t Identity;
957                memset (&Identity, 0x00, sizeof(Identity));
958                CopyStringToAnsi (Identity.principal, pszUser);
959
960                kas_principalEntry_t Entry;
961                if (kas_PrincipalGet (hCell, NULL, &Identity, &Entry, &status))
962                   {
963                   if (Entry.adminSetting == KAS_ADMIN)
964                      rc = TRUE;
965                   }
966
967                afsclient_CellClose (hCell, (afs_status_p)&status);
968                }
969             }
970
971          CloseKasLibrary();
972          }
973
974       CloseClientLibrary();
975       }
976
977    return rc;
978 #endif /* USE_KASERVER */
979 }
980