// =========================================================================== // UAMDialogs.c © 1997 Microsoft Corp. All rights reserved. // =========================================================================== // General dialog utilities used by the Microsoft User Authentication Method. // // =========================================================================== #include #include "UAMDebug.h" #include "UAMDialogs.h" #include "UAMUtils.h" #include "UAMMain.h" #include "UAMNetwork.h" #include "UAMDSNetwork.h" #include "UAMListBox.h" #include "UAMDLOGUtils.h" #include "UAMKeychain.h" extern Str32 gServerName; extern ModalFilterUPP gDialogFilter; extern UserItemUPP gLineItem; extern long gSupportedUAMs; // --------------------------------------------------------------------------- // ¥ UAM_ReportError() // --------------------------------------------------------------------------- // Reports an error to the user by displaying an alert box. This routine looks // in the resource file for a resource of type 'ESTR' with the same res ID as // the error code. If found, the message contained in the resource is displayed // to the user. // // Note that we go out our way here by putting up and maintaining our own error // alert box instead of using one of the Alert routines. This is because other // dialogs in the UAM use ParamText() to set string information. If we have // an error, then the strings will be replaced by the alert strings. Not a // good scenario... #define DITEM_MsgText 3 void UAM_ReportError(OSStatus inError) { Str255 theMsg; short theItem; StringHandle theString; DialogPtr theDialog = NULL; GrafPtr theSavePort = NULL; Assert_(gDialogFilter != NULL); if (inError != noErr) { GetPort(&theSavePort); InitCursor(); UAM_PStrCopy("\p", theMsg); theString = (StringHandle)Get1Resource('STR ', inError); if (theString) { HLock((Handle)theString); UAM_PStrCopy(*theString, theMsg); HUnlock((Handle)theString); ReleaseResource((Handle)theString); } theDialog = UAM_NewDialog(DLOG_GeneralError, true); Assert_(theDialog != NULL); if (theDialog != NULL) { SysBeep(1); UAM_SetText(theDialog, DITEM_MsgText, theMsg); do { ModalDialog(gDialogFilter, &theItem); }while(theItem != 1); UAM_DisposeDialog(theDialog); SetPort(theSavePort); } } } // --------------------------------------------------------------------------- // ¥ UAM_ChangePwd() // --------------------------------------------------------------------------- // Puts up and handles the change password dialog and calls the appropriate // routines to change the password. // // Unless there is an error, we'll usually return one of: // // #define CHNGPSWD_UPDATE_KEYCHAIN 1000 // #define CHNGPSWD_USER_CANCELED 1001 // #define CHNGPSWD_NOERR noErr #define DITEM_Icon 3 #define DITEM_OldPassword 6 #define DITEM_NewPassword 8 #define DITEM_VerifyPwd 10 #define DITEM_LineItem 11 OSStatus UAM_ChangePwd(UAMArgs *inUAMArgs) { GrafPtr theSavePort; short theItem; OSStatus theError; Str255 theNewPwd, theVerPwd; CursHandle theCursor; DialogPtr theDialog = NULL; Boolean theDoLoop = true; KCItemRef theKCItemRef = NULL; Assert_(gDialogFilter != NULL); Assert_(gLineItem != NULL); GetPort(&theSavePort); ParamText(inUAMArgs->Opt.pwDlg.userName, gServerName, NULL, NULL); theDialog = UAM_NewDialog(DLOG_ChangePwd, true); if (theDialog == NULL) { UAM_ReportError(resNotFound); return(resNotFound); } // //Set up the line at the top of the dialog. // UAM_SetUpUserItem(theDialog, DITEM_LineItem, gLineItem, userItem); // //All three fields in this dialog are bullet protected. // UAM_SetBulletItem(theDialog, DITEM_OldPassword, UAM_CLRTXTPWDLEN); UAM_SetBulletItem(theDialog, DITEM_NewPassword, UAM_CLRTXTPWDLEN); UAM_SetBulletItem(theDialog, DITEM_VerifyPwd, UAM_CLRTXTPWDLEN); if (inUAMArgs->Opt.pwDlg.password[0] != 0) { UAM_SetBulletText( theDialog, DITEM_OldPassword, inUAMArgs->Opt.pwDlg.password ); SelectDialogItemText(theDialog, DITEM_NewPassword, 0, 0); } else { SelectDialogItemText(theDialog, DITEM_OldPassword, 0, 0); } UAM_SupportCmdKeys(theDialog, false); do { ModalDialog(gDialogFilter, &theItem); switch(theItem) { case 1: UAM_GetBulletBuffer(theDialog, DITEM_NewPassword, theNewPwd); UAM_GetBulletBuffer(theDialog, DITEM_VerifyPwd, theVerPwd); UAM_GetBulletBuffer(theDialog, DITEM_OldPassword, inUAMArgs->Opt.pwDlg.password); // //Ensure the new and verified password are equal. If not, present an //error to the user and give 'em a chance to correct the problem. // if (!EqualString(theNewPwd, theVerPwd, true, true)) { UAM_ReportError(afpNTNewPasswordMismatchErr); UAM_ClearBulletText(theDialog, DITEM_NewPassword); UAM_ClearBulletText(theDialog, DITEM_VerifyPwd); SelectDialogItemText(theDialog, DITEM_NewPassword, 0, 0); break; } theCursor = GetCursor(watchCursor); if (theCursor) { SetCursor(*theCursor); } if (gSupportedUAMs & kMSUAM_V2_Supported) { // //If kMSUAM_V2_Supported, then we change the password a //different way. // theError = UAM_ChangePasswordV2(inUAMArgs, theNewPwd); } else { theError = UAM_ChangePassword(inUAMArgs, theNewPwd); } if (theError == noErr) { if (UAM_KCAvailable()) { // //See if a keychain existed for the user name. //If so, delete it. // if (UAM_KCFindAppleSharePassword( inUAMArgs->Opt.pwDlg.userName, inUAMArgs->Opt.pwDlg.password, gServerName, &theKCItemRef) == noErr) { theError = KCDeleteItem(theKCItemRef); if ((theError != noErr) && (theError != userCanceledErr)) { DbgPrint_((DBGBUFF, "KCDeleteItem() failed (%d)", theError)); UAM_ReportError(theError); } else if (theError == noErr) { // //This is how we tell the main login routine to //re-enter the password into the keychain. // theError = CHNGPSWD_UPDATE_KEYCHAIN; } KCReleaseItem(&theKCItemRef); } } // //If we changed the password successfully, then store the //new password in the arguments struct. // UAM_PStrCopy(theNewPwd, inUAMArgs->Opt.pwDlg.password); } theDoLoop = false; break; case 2: theError = CHNGPSWD_USER_CANCELED; theDoLoop = false; break; default: break; } }while(theDoLoop); UAM_DisposeDialog(theDialog); SetPort(theSavePort); return(theError); } // --------------------------------------------------------------------------- // ¥ UAM_ChangePasswordNotificationDlg() // --------------------------------------------------------------------------- // Put up an about dialog. void UAM_ChangePasswordNotificationDlg(Int16 inDaysTillExpiration) { const Int16 theLine = 4; const Int16 theTextBox = 5; GrafPtr theSavePort; DialogPtr theDialog = NULL; short theItem; Str255 theDaysStr; Assert_(gDialogFilter != NULL); Assert_(gLineItem != NULL); GetPort(&theSavePort); if (inDaysTillExpiration > 0) { NumToString(inDaysTillExpiration, theDaysStr); ParamText(theDaysStr, NULL, NULL, NULL); } theDialog = UAM_NewDialog(DLOG_ChangePwdNotification, true); Assert_(theDialog != NULL); if (theDialog == NULL) { // //We could not get our dialog from the resource, something real //bad has happened, try to exit gracefully. // return; } if (inDaysTillExpiration <= 0) { StringHandle theString = GetString(uamPasswordExpiresInOneDay); Assert_(theString != NULL); if (theString != NULL) { UAM_SetText(theDialog, theTextBox, *theString); } } UAM_SetUpUserItem(theDialog, theLine, gLineItem, userItem); do { ModalDialog(gDialogFilter, &theItem); }while(theItem != DITEM_OK); UAM_DisposeDialog(theDialog); SetPort(theSavePort); } // --------------------------------------------------------------------------- // ¥ UAM_AskQuestion() // --------------------------------------------------------------------------- // Asks a "yes" or "no" question. You supply the ID of the STR resource the // question resides in. // // Returns: 1 (ALRT_YES) for yes, 2 (ALRT_NO) for no. Int16 UAM_AskQuestion(Int16 inStrID) { Int16 theResponse = ALRT_NO; StringHandle theString = NULL; theString = GetString(inStrID); Assert_(theString != NULL); if (theString != NULL) { InitCursor(); ParamText(*theString, NULL, NULL, NULL); theResponse = Alert(ALRT_ReplaceKey, NULL); ReleaseResource((Handle)theString); } return(theResponse); }