1 line
8.7 KiB
C
1 line
8.7 KiB
C
// ===========================================================================
|
|
// UAMDialogs.c © 1997 Microsoft Corp. All rights reserved.
|
|
// ===========================================================================
|
|
// General dialog utilities used by the Microsoft User Authentication Method.
|
|
//
|
|
// ===========================================================================
|
|
|
|
#include <Sound.h>
|
|
|
|
#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);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|