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