Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1 lines
14 KiB

// =========================================================================== // UAMDialogs.c © 1997 Microsoft Corp. All rights reserved. // =========================================================================== // General dialog utilities used by the Microsoft User Authentication Method. // // =========================================================================== #include <macstrsafe.h> #include "UAMDebug.h" #include "UAMDialogs.h" #include "UAMUtils.h" #include "UAMNetwork.h" #include "UAMDLOGUtils.h" #include "UAMKeychain.h" #include "UAMPswdField.h" #include "UAMPrefs.h" #ifndef UAM_TARGET_CARBON extern ModalFilterUPP gDialogFilter; #endif extern Str32 gServerName; extern UserItemUPP gLineItem; extern long gSupportedUAMs; extern UAM_PREFERENCES gUAMPreferences; SInt16 gNumPasswordEntryErrors = 0; // --------------------------------------------------------------------------- // ¥ UAM_ReportError() // --------------------------------------------------------------------------- // Reports an error to the user by displaying an alert box. // void UAM_ReportError(OSStatus inError) { UAM_StandardAlert(uamErr_ErrorMessageString, inError, NULL); } // --------------------------------------------------------------------------- // ¥ UAM_StandardAlert() // --------------------------------------------------------------------------- // Puts up a standard alert box for reporting errors and other items to the // user. // // The routine looks for resources of type 'STR ' to get the strings // associated with the message and explanations. // void UAM_StandardAlert(SInt16 inMessageID, SInt32 inExplanation, SInt16* outSelectedItem) { StringHandle theMessage = NULL; StringHandle theExplanation = NULL; SInt16 theSelectedItem; #ifdef UAM_TARGET_CARBON AlertStdAlertParamRec theAlertRec; SysBeep(1); theAlertRec.movable = TRUE; theAlertRec.helpButton = FALSE; theAlertRec.filterProc = NULL; theAlertRec.defaultText = (UInt8*)kAlertDefaultOKText; theAlertRec.cancelText = NULL; theAlertRec.otherText = NULL; theAlertRec.defaultButton = kAlertStdAlertOKButton; theAlertRec.position = kWindowAlertPositionMainScreen; // //If the caller is looking for the button the user selected, then we //assume that the user wants a cancel button. // if (outSelectedItem != NULL) { theAlertRec.cancelButton = kAlertStdAlertCancelButton; } else { theAlertRec.cancelButton = 0; } #endif //UAM_TARGET_CARBON InitCursor(); if (outSelectedItem != NULL) { *outSelectedItem = 0; } theMessage = GetString(inMessageID); if (theMessage != NULL) { HLock((Handle)theMessage); theExplanation = GetString(inExplanation); if (theExplanation == NULL) { // //We didn't find an error string corresponding to this error, so //put up a general error message. // theExplanation = GetString(uamErr_DefaultExplanation); } if (theExplanation != NULL) { HLock((Handle)theExplanation); #ifdef UAM_TARGET_CARBON StandardAlert( kAlertStopAlert, *theMessage, *theExplanation, &theAlertRec, &theSelectedItem ); #else ParamText(NULL, NULL, *theMessage, *theExplanation); theSelectedItem = StopAlert((outSelectedItem == NULL) ? ALRT_Error : ALRT_Error2, NULL); #endif if (outSelectedItem != NULL) { *outSelectedItem = theSelectedItem; } HUnlock((Handle)theExplanation); ReleaseResource((Handle)theExplanation); } HUnlock((Handle)theMessage); ReleaseResource((Handle)theMessage); } } // --------------------------------------------------------------------------- // ¥ UAM_ChangePwdDialogFilter() // --------------------------------------------------------------------------- // Dialog filter for the change password dialog. // pascal Boolean UAM_ChangePwdDialogFilter(DialogRef inDialog, EventRecord *inEvent, SInt16 *inItem) { Boolean theResult = FALSE; SInt16 theCode; if ((inEvent->what == keyDown) || (inEvent->what == autoKey)) { theCode = (inEvent->message & charCodeMask); if ((inEvent->modifiers & cmdKey) && (inEvent->what != autoKey)) { switch(theCode) { // //Don't allow users to cut/copy or paste their passwords. // case 'c': case 'C': case 'v': case 'V': case 'x': case 'X': theResult = TRUE; break; default: break; } } else if ((inEvent->modifiers & optionKey) || (inEvent->modifiers & controlKey)) { // //We do not allow the use of extended or control characters. This is because //there is no way to map them over to the windows code page. // // //If the user tried to use extended chars more than once, we //put up a dialog telling them they are not allowed. // gNumPasswordEntryErrors++; if (gNumPasswordEntryErrors >= MAX_PASSWORD_ENTRY_ERRORS) { UAM_StandardAlert( uamErr_PasswordMessage, uamErr_ExtendedCharsNotAllowed, NULL ); gNumPasswordEntryErrors = 0; } else { SysBeep(1); } theResult = TRUE; } else { switch(theCode) { case UAMKey_Escape: *inItem = DITEM_Cancel; theResult = TRUE; break; case UAMKey_Enter: case UAMKey_Return: *inItem = DITEM_OK; theResult = TRUE; break; default: break; } } } #ifdef UAM_TARGET_CARBON if (theResult == FALSE) { theResult = StdFilterProc(inDialog , inEvent, inItem); } #endif return(theResult); } // --------------------------------------------------------------------------- // ¥ 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; Str255 theNewPwd, theVerPwd; CursHandle theCursor; OSStatus theError = noErr; DialogRef theDialog = NULL; Boolean theDoLoop = true; KCItemRef theKCItemRef = NULL; ModalFilterUPP theFilter = NULL; Assert_(gLineItem != NULL); theFilter = NewModalFilterUPP(&UAM_ChangePwdDialogFilter); if (theFilter == NULL) { // //Bad problems if we couldn't allocate a little ol upp! // return(-108); } GetPort(&theSavePort); ParamText(inUAMArgs->Opt.pwDlg.userName, gServerName, NULL, NULL); #ifdef UAM_TARGET_CARBON theDialog = GetNewDialog(DLOG_ChangePwd, NULL, (WindowPtr)-1); #else theDialog = UAM_NewDialog(DLOG_ChangePwd, true); #endif if (theDialog == NULL) { UAM_ReportError(resNotFound); return(resNotFound); } // //Set up the line at the top of the dialog. // UAM_SetupDialogUserItem(theDialog, DITEM_LineItem, gLineItem, userItem); // //Initialize the 3 password edit fields. // UAM_InitializeDialogPasswordItem(theDialog, DITEM_OldPassword); UAM_InitializeDialogPasswordItem(theDialog, DITEM_NewPassword); UAM_InitializeDialogPasswordItem(theDialog, DITEM_VerifyPwd); if (inUAMArgs->Opt.pwDlg.password[0] != 0) { UAM_SetPasswordText( theDialog, DITEM_OldPassword, inUAMArgs->Opt.pwDlg.password ); UAM_MakePasswordItemFocusItem(theDialog, DITEM_NewPassword); } else { UAM_MakePasswordItemFocusItem(theDialog, DITEM_OldPassword); } #ifdef UAM_TARGET_CARBON SetPortDialogPort(theDialog); ShowWindow(GetDialogWindow(theDialog)); BringToFront(GetDialogWindow(theDialog)); #else UAM_SetCustomFilterProc(theDialog, theFilter); #endif // //Tell the password key filter the maximum password length to allow. // UAM_SetMaximumPasswordLength(true); do { ModalDialog( #ifdef UAM_TARGET_CARBON theFilter, #else gDialogFilter, #endif &theItem); switch(theItem) { case 1: UAM_GetPasswordText(theDialog, DITEM_NewPassword, theNewPwd); UAM_GetPasswordText(theDialog, DITEM_VerifyPwd, theVerPwd); UAM_GetPasswordText(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_SetPasswordText(theDialog, DITEM_NewPassword, "\p"); UAM_SetPasswordText(theDialog, DITEM_VerifyPwd, "\p"); UAM_MakePasswordItemFocusItem(theDialog, DITEM_NewPassword); break; } // //Let the user know they may wait a while for the operation to //complete. // theCursor = GetCursor(watchCursor); if (theCursor) { SetCursor(*theCursor); } // //Make sure the user is not trying to enter in a blank or null //password for the old or new password. // if ((PSTR_LENGTH(inUAMArgs->Opt.auth.password) == 0) || (PSTR_LENGTH(theNewPwd) == 0)) { UAM_StandardAlert( uamErr_PasswordMessage, uamErr_NoBlankPasswordsAllowed, NULL ); break; } // //Determine which change password method we're using. We use v1 for //NT4.0 and older servers and v2 for Windows2000 and v3 for .NET. // if (gSupportedUAMs & kMSUAM_V3_Supported) { DbgPrint_((DBGBUFF, "CHANGE PSWD: using UAM_ChangePasswordV3()")); theError = UAM_ChangePasswordForMS30(inUAMArgs, theNewPwd); } else if (gSupportedUAMs & kMSUAM_V2_Supported) { DbgPrint_((DBGBUFF, "CHANGE PSWD: using UAM_ChangePasswordV2()")); theError = UAM_ChangePasswordForMS20(inUAMArgs, theNewPwd); } else { // //Check and see if the user wants to allow this weak authentication //to take place. // if (gUAMPreferences.flags & UAM_PREFS_REQUIRE_STRONG_ENCRYPTION) { // //Nope, the auth strength is too weak for the user to //stomach. Exit gracefully. // UAM_StandardAlert( uamErr_AuthenticationMessage, uamErr_AuthTooWeak, NULL ); return(userCanceledErr); } DbgPrint_((DBGBUFF, "CHANGE PSWD: using UAM_ChangePasswordV1()")); theError = UAM_ChangePasswordForMS10(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)", (int)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); DisposeDialog(theDialog); SetPort(theSavePort); DisposeRoutineDescriptor(theFilter); // //Reset the maximum password length for non-password changing ops. // UAM_SetMaximumPasswordLength(false); return(theError); } // --------------------------------------------------------------------------- // ¥ UAM_ChangePasswordNotificationDlg() // --------------------------------------------------------------------------- // Put up an about dialog. void UAM_ChangePasswordNotificationDlg(Int16 inDaysTillExpiration) { Str255 theDaysStr; NumToString(inDaysTillExpiration, theDaysStr); ParamText(theDaysStr, NULL, NULL, NULL); UAM_StandardAlert(uamErr_PasswordExpirationMessage, uamErr_PasswordExpirationExplanation, NULL); }