/* File usertab.c Implementation of the users dialog tab for the dialup server ui. Paul Mayfield, 9/29/97 */ #include "rassrv.h" #include "usertab.h" #include #define USERTAB_PASSWORD_BUFFER_SIZE (PWLEN+1) static const WCHAR pszDummyPassword[] = L"XXXXXXXXXXXXXXX"; // Help maps static const DWORD phmUserTab[] = { CID_UserTab_LV_Users, IDH_UserTab_LV_Users, CID_UserTab_PB_New, IDH_UserTab_PB_New, CID_UserTab_PB_Delete, IDH_UserTab_PB_Delete, CID_UserTab_PB_Properties, IDH_UserTab_PB_Properties, CID_UserTab_PB_SwitchToMMC, IDH_UserTab_PB_SwitchToMMC, CID_UserTab_CB_BypassDcc, IDH_UserTab_CB_BypassDcc, 0, 0 }; static const DWORD phmCallback[] = { CID_UserTab_Callback_RB_Caller, IDH_UserTab_Callback_RB_Caller, CID_UserTab_Callback_RB_Admin, IDH_UserTab_Callback_RB_Admin, CID_UserTab_Callback_EB_Number, IDH_UserTab_Callback_EB_Number, CID_UserTab_Callback_RB_No, IDH_UserTab_Callback_RB_No, 0, 0 }; static const DWORD phmNewUser[] = { CID_UserTab_New_EB_Username, IDH_UserTab_New_EB_Username, CID_UserTab_New_EB_Fullname, IDH_UserTab_New_EB_Fullname, CID_UserTab_New_EB_Password1, IDH_UserTab_New_EB_Password1, CID_UserTab_New_EB_Password2, IDH_UserTab_New_EB_Password2, 0, 0 }; // Parameters to track net users // typedef struct _RASSRV_USER_PARAMS { BOOL bCanceled; // Set by property sheets when cancel pressed BOOL bNewUser; // for .Net 691639, the password change warning dialog won't pop up when creating new users. gangz // General properties //For whistler bug 210032 to allow username be 20 characters long WCHAR pszLogonName[IC_USERNAME]; WCHAR pszFullName [IC_USERFULLNAME+1]; // For whistler bug 39081 gangz WCHAR pszPassword1[USERTAB_PASSWORD_BUFFER_SIZE]; WCHAR pszPassword2[USERTAB_PASSWORD_BUFFER_SIZE]; DWORD dwErrorCode; // Callback properties HANDLE hUser; BOOL bNone; BOOL bCaller; BOOL bAdmin; WCHAR pszNumber[MAX_PHONE_NUMBER_LEN]; } RASSRV_USER_PARAMS; // Fills in the property sheet structure with the information // required to display the user database tab. // DWORD UserTabGetPropertyPage( IN LPPROPSHEETPAGE ppage, IN LPARAM lpUserData) { // Initialize ZeroMemory(ppage, sizeof(PROPSHEETPAGE)); // Fill in the values ppage->dwSize = sizeof(PROPSHEETPAGE); ppage->hInstance = Globals.hInstDll; ppage->pszTemplate = MAKEINTRESOURCE(PID_UserTab); ppage->pfnDlgProc = UserTabDialogProc; ppage->pfnCallback = RasSrvInitDestroyPropSheetCb; ppage->dwFlags = PSP_USECALLBACK; ppage->lParam = lpUserData; return NO_ERROR; } // // Error reporting // VOID UserTabDisplayError( IN HWND hwnd, IN DWORD err) { ErrDisplayError( hwnd, err, ERR_USERTAB_CATAGORY, ERR_USERDB_SUBCAT, Globals.dwErrorData); } // Fills in the user list view with the names of the users stored in the // user database provide. Also, initializes the checked/unchecked status // of each user. DWORD UserTabFillUserList( IN HWND hwndLV, IN HANDLE hUserDatabase) { LV_ITEM lvi; DWORD dwCount, i, dwErr, dwSize; HANDLE hUser; WCHAR pszName[IC_USERFULLNAME+IC_USERNAME+3]; // char pszAName[512]; HIMAGELIST checks; BOOL bDialinEnabled; // Get the count of all the users if ((dwErr = usrGetUserCount(hUserDatabase, &dwCount)) != NO_ERROR) { UserTabDisplayError(hwndLV, ERR_USER_DATABASE_CORRUPT); return dwErr; } ListView_SetUserImageList(hwndLV, Globals.hInstDll); // Initialize the list item ZeroMemory(&lvi, sizeof(LV_ITEM)); lvi.mask = LVIF_TEXT | LVIF_IMAGE; // Looop through all of the users adding their names as we go for (i=0; iusrmod0_min_passwd_len; NetApiBufferFree((LPBYTE)pModInfo); } // Load the parameters hwndControl = GetDlgItem(hwndDlg, CID_UserTab_New_EB_Username); if (hwndControl) { GetWindowTextW( hwndControl, pNuParams->pszLogonName, (sizeof(pNuParams->pszLogonName)/sizeof(WCHAR)) - 1); } hwndControl = GetDlgItem(hwndDlg, CID_UserTab_New_EB_Fullname); if (hwndControl) { GetWindowTextW( hwndControl, pNuParams->pszFullName, (sizeof(pNuParams->pszFullName)/sizeof(WCHAR)) - 1); } hwndControl = GetDlgItem(hwndDlg, CID_UserTab_New_EB_Password1); //gangz //For secure password bug .Net 754400 SafeWipePasswordBuf(pNuParams->pszPassword1 ); SafeWipePasswordBuf(pNuParams->pszPassword2 ); if (hwndControl) { GetWindowTextW( hwndControl, pNuParams->pszPassword1, (sizeof(pNuParams->pszPassword1)/sizeof(WCHAR)) - 1); } hwndControl = GetDlgItem(hwndDlg, CID_UserTab_New_EB_Password2); if (hwndControl) { GetWindowTextW( hwndControl, pNuParams->pszPassword2, (sizeof(pNuParams->pszPassword2)/sizeof(WCHAR)) - 1); } do { bOk = TRUE; // Verify that we have a login name dwLength = wcslen(pNuParams->pszLogonName); if (dwLength < 1) { pNuParams->dwErrorCode = ERR_LOGON_NAME_TOO_SMALL; bOk = FALSE; break; } // Verify the minimum password length dwLength = wcslen(pNuParams->pszPassword1); if (dwLength < dwMinPasswordLength) { pNuParams->dwErrorCode = ERR_PASSWORD_TOO_SMALL; bOk = FALSE; break; } // Verify the passwords was entered correctly if (wcscmp(pNuParams->pszPassword1, pNuParams->pszPassword2)) { pNuParams->dwErrorCode = ERR_PASSWORD_MISMATCH; bOk = FALSE; break; } // For .Net 660285 // Give warning if the password has been changed // for .Net 691639, the password change warning dialog won't pop up when creating new users. gangz // if ( !pNuParams->bNewUser && wcscmp(pszDummyPassword, pNuParams->pszPassword1) ) { BOOL fChange = FALSE; DWORD dwErr = NO_ERROR; dwErr = WarnPasswordChange( &fChange ); if( NO_ERROR != dwErr ) { break; } bOk = fChange; if( !bOk ) { pNuParams->dwErrorCode = ERROR_CAN_NOT_COMPLETE; } } } while (FALSE); // Cleanup { if (!bOk) { //reset password buffer so that other know password is not set yet. // SafeWipePasswordBuf( pNuParams->pszPassword1); SafeWipePasswordBuf( pNuParams->pszPassword2); } } // Keep the password field in encrypted status to be logic safe // Even it is wiped out SafeEncodePasswordBuf( pNuParams->pszPassword1 ); SafeEncodePasswordBuf( pNuParams->pszPassword2 ); return bOk; } // // Initialize the callback properties of the given user // //Passwords are encrypted when passing in DWORD UserTabLoadUserProps ( IN RASSRV_USER_PARAMS * pParams) { PWCHAR pszName; DWORD dwErr, dwSize; PWCHAR pszNumber; if (!pParams) { return ERROR_INVALID_PARAMETER; } // If this is a new user, default to user specified callback // (convienience mode) if (!pParams->hUser) { SafeWipePasswordBuf( pParams->pszPassword1); SafeWipePasswordBuf( pParams->pszPassword2); ZeroMemory(pParams, sizeof(*pParams)); SafeEncodePasswordBuf( pParams->pszPassword1); SafeEncodePasswordBuf( pParams->pszPassword2); pParams->bNone = TRUE; pParams->bCaller = FALSE; pParams->bAdmin = FALSE; } // Otherwise, load the user parameters from the user database else { pParams->bCanceled = FALSE; dwSize = sizeof(pParams->pszFullName)/sizeof(pParams->pszFullName[0]); usrGetFullName (pParams->hUser, pParams->pszFullName, &dwSize); usrGetName(pParams->hUser, &pszName); lstrcpynW( pParams->pszLogonName, pszName, sizeof(pParams->pszLogonName) / sizeof(WCHAR)); SafeWipePasswordBuf( pParams->pszPassword1); SafeWipePasswordBuf( pParams->pszPassword2); lstrcpynW( pParams->pszPassword1, pszDummyPassword, sizeof(pParams->pszPassword1) / sizeof(WCHAR)); lstrcpynW( pParams->pszPassword2, pszDummyPassword, sizeof(pParams->pszPassword2) / sizeof(WCHAR)); SafeEncodePasswordBuf( pParams->pszPassword1); SafeEncodePasswordBuf( pParams->pszPassword2); dwErr = usrGetCallback( pParams->hUser, &pParams->bAdmin, &pParams->bCaller); if (dwErr != NO_ERROR) { return dwErr; } dwErr = usrGetCallbackNumber(pParams->hUser, &pszNumber); if (dwErr != NO_ERROR) { return dwErr; } lstrcpynW( pParams->pszNumber, pszNumber, sizeof(pParams->pszNumber) / sizeof(WCHAR)); } return NO_ERROR; } // // Commit the call back properties of the given user. // DWORD UserTabSaveCallbackProps ( IN RASSRV_USER_PARAMS * pParams) { if (!pParams) { return ERROR_INVALID_PARAMETER; } // If we have a valid handle to the user, set his/her // properties if (pParams->hUser) { pParams->bNone = (pParams->bCaller == FALSE && pParams->bAdmin == FALSE); // Set the enabling and number usrEnableCallback( pParams->hUser, pParams->bNone, pParams->bCaller, pParams->bAdmin); if (pParams->bAdmin) { usrSetCallbackNumber(pParams->hUser, pParams->pszNumber); } } return NO_ERROR; } // Commit the parameters of the given user. If pOrig is non-null, then all // fields of pParams will be compare against pOrig and only those that have changed // will be committed. (optimization) // //passwords in the input structure are encoded DWORD UserTabSaveUserProps ( IN RASSRV_USER_PARAMS * pParams, IN RASSRV_USER_PARAMS * pOrig, IN PBOOL pbChanged) { if (!pParams || !pOrig || !pbChanged) { return ERROR_INVALID_PARAMETER; } *pbChanged = FALSE; // Commit the full name if changed if (wcscmp(pParams->pszFullName, pOrig->pszFullName)) { usrSetFullName(pParams->hUser, pParams->pszFullName); *pbChanged = TRUE; } // Commit the password if changed SafeDecodePasswordBuf(pParams->pszPassword1); if (wcscmp(pParams->pszPassword1, pszDummyPassword)) { usrSetPassword(pParams->hUser, pParams->pszPassword1); } SafeEncodePasswordBuf(pParams->pszPassword1); UserTabSaveCallbackProps(pParams); return NO_ERROR; } DWORD UserTabCallbackApply( IN HWND hwndDlg) { RASSRV_USER_PARAMS * pParams = NULL; LONG dwResult = PSNRET_NOERROR; HWND hwndControl = NULL; pParams = (RASSRV_USER_PARAMS *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_RB_No); if (hwndControl) { pParams->bNone = (BOOL) SendMessage( hwndControl, BM_GETCHECK, 0, 0); } hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_RB_Caller); if (hwndControl) { pParams->bCaller = (BOOL) SendMessage( hwndControl, BM_GETCHECK, 0, 0); } hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_RB_Admin); if (hwndControl) { pParams->bAdmin = (BOOL) SendMessage( hwndControl, BM_GETCHECK, 0, 0); } if (pParams->bAdmin) { hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_EB_Number); if (hwndControl) { GetWindowTextW( hwndControl, pParams->pszNumber, MAX_PHONE_NUMBER_LEN); } // If admin callback was set, but no admin callback number was set, // then popup an error and don't to refuse the apply // if (wcslen(pParams->pszNumber) == 0) { UserTabDisplayError(hwndDlg, ERR_CALLBACK_NUM_REQUIRED); PropSheet_SetCurSel ( GetParent(hwndDlg), hwndDlg, 0 ); dwResult = PSNRET_INVALID; } } SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, dwResult); return TRUE; } // // Dialog procedure that implements getting callback properties // INT_PTR CALLBACK UserTabCallbackDialogProc( IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { PWCHAR lpzNumber, lpzName; HWND hwndControl = NULL; HWND hwCb = GetDlgItem(hwndDlg, CID_UserTab_Callback_EB_Number); RASSRV_USER_PARAMS * pu = (RASSRV_USER_PARAMS *)(((PROPSHEETPAGE*)lParam)->lParam); // Initialize if (hwCb) { SendMessage( hwCb, EM_SETLIMITTEXT, sizeof(pu->pszNumber)/2 - 1, 0); } SetWindowLongPtr( hwndDlg, GWLP_USERDATA, (LONG_PTR)pu); // Display the callback properties if (!pu->bAdmin && !pu->bCaller) { hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_RB_No); if (hwndControl) { SendMessage( hwndControl, BM_SETCHECK,BST_CHECKED, 0); SetFocus( hwndControl); } } else if (pu->bCaller) { hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_RB_Caller); if (hwndControl) { SendMessage( hwndControl, BM_SETCHECK,BST_CHECKED, 0); SetFocus( hwndControl); } } else { hwndControl = GetDlgItem(hwndDlg,CID_UserTab_Callback_RB_Admin); if (hwndControl) { SendMessage( hwndControl, BM_SETCHECK,BST_CHECKED, 0); SetFocus( hwndControl); } } SetWindowTextW(hwCb, pu->pszNumber); EnableWindow(hwCb, !!pu->bAdmin); } return TRUE; case WM_HELP: case WM_CONTEXTMENU: { RasSrvHelp (hwndDlg, uMsg, wParam, lParam, phmCallback); break; } case WM_DESTROY: SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); break; case WM_NOTIFY: { NMHDR* pNotifyData; NM_LISTVIEW* pLvNotifyData; pNotifyData = (NMHDR*)lParam; switch (pNotifyData->code) { // The property sheet apply button was pressed case PSN_APPLY: return UserTabCallbackApply(hwndDlg); break; // The property sheet cancel was pressed case PSN_RESET: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); break; } } break; case WM_COMMAND: switch (wParam) { case CID_UserTab_Callback_RB_No: case CID_UserTab_Callback_RB_Caller: case CID_UserTab_Callback_RB_Admin: { HWND hwndNumber = NULL; HWND hwndAdmin = NULL; hwndNumber = GetDlgItem(hwndDlg, CID_UserTab_Callback_EB_Number); hwndAdmin = GetDlgItem(hwndDlg, CID_UserTab_Callback_RB_Admin); if (hwndNumber && hwndAdmin) { EnableWindow( hwndNumber, (BOOL) SendMessage( hwndAdmin, BM_GETCHECK, 0, 0)); } } break; } break; } return FALSE; } // // Initializes the user properties dialog procedure. // // Return TRUE if focus is set, false otherwise. // BOOL UserTabInitUserPropsDlg( IN HWND hwndDlg, IN WPARAM wParam, IN LPARAM lParam) { HWND hwLogon, hwFull, hwPass1, hwPass2, hwOk, hwCancel; RASSRV_USER_PARAMS * pu = (RASSRV_USER_PARAMS *)(((PROPSHEETPAGE*)lParam)->lParam); hwLogon = GetDlgItem( hwndDlg, CID_UserTab_New_EB_Username); hwFull = GetDlgItem( hwndDlg, CID_UserTab_New_EB_Fullname); hwPass1 = GetDlgItem( hwndDlg, CID_UserTab_New_EB_Password1); hwPass2 = GetDlgItem( hwndDlg, CID_UserTab_New_EB_Password2); hwOk = GetDlgItem( hwndDlg, IDOK); hwCancel = GetDlgItem( hwndDlg, IDCANCEL); // Store the parameters with the window handle SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)pu); // Set limits to the text that can be entered if (hwLogon) { SendMessage( hwLogon, EM_SETLIMITTEXT, sizeof(pu->pszLogonName)/2 - 2, 0); SetWindowTextW(hwLogon, pu->pszLogonName); } if (hwFull) { SendMessage( hwFull, EM_SETLIMITTEXT, sizeof(pu->pszFullName)/2 - 2, 0); SetWindowTextW(hwFull, pu->pszFullName); } if (hwPass1) { SendMessage( hwPass1, EM_SETLIMITTEXT, sizeof(pu->pszPassword1)/2 - 2 , 0); SafeDecodePasswordBuf(pu->pszPassword1); SetWindowTextW(hwPass1, pu->pszPassword1); SafeEncodePasswordBuf(pu->pszPassword1); } if (hwPass2) { SendMessage( hwPass2, EM_SETLIMITTEXT, sizeof(pu->pszPassword2)/2 - 2, 0); SafeDecodePasswordBuf(pu->pszPassword2); SetWindowTextW(hwPass2, pu->pszPassword2); SafeEncodePasswordBuf(pu->pszPassword2); } // Don't allow editing of the logon name if user already exists // Also, don't show the ok and cancel buttons if the user already // exits (because it's a property sheet with its own buttons) if (pu->hUser) { if (hwLogon) { EnableWindow(hwLogon, FALSE); } if (hwOk) { ShowWindow(hwOk, SW_HIDE); } if (hwCancel) { ShowWindow(hwCancel, SW_HIDE); } } // Otherwise, we are creating a new user. Change the window // title to other than "General". Also disable the ok button // since it will be enabled when a user name is typed in. else { PWCHAR pszTitle; pszTitle = (PWCHAR) PszLoadString ( Globals.hInstDll, SID_NEWUSER); SetWindowTextW (hwndDlg, pszTitle); EnableWindow(hwOk, FALSE); } return FALSE; } // Dialog procedure that implements the new user INT_PTR CALLBACK UserTabGenUserPropsDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: return UserTabInitUserPropsDlg(hwndDlg, wParam, lParam); break; case WM_HELP: case WM_CONTEXTMENU: { RasSrvHelp (hwndDlg, uMsg, wParam, lParam, phmNewUser); break; } case WM_DESTROY: // Cleanup the work done at WM_INITDIALOG SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); break; case WM_NOTIFY: { NMHDR* pNotifyData; NM_LISTVIEW* pLvNotifyData; pNotifyData = (NMHDR*)lParam; switch (pNotifyData->code) { // The property sheet apply button was pressed case PSN_APPLY: { RASSRV_USER_PARAMS * pParams; pParams = (RASSRV_USER_PARAMS *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); if (UserTabNewUserParamsOk(hwndDlg, pParams)) { SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); } else { if( ERROR_CAN_NOT_COMPLETE != pParams->dwErrorCode ) { ErrDisplayError( hwndDlg, pParams->dwErrorCode, ERR_USERTAB_CATAGORY,ERR_USERDB_SUBCAT, 0); } SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); } } return TRUE; // The property sheet cancel was pressed case PSN_RESET: { RASSRV_USER_PARAMS * pParams; pParams = (RASSRV_USER_PARAMS *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); pParams->bCanceled = TRUE; SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); break; } } } break; case WM_COMMAND: // Handle ok being pressed // if (wParam == IDOK) { RASSRV_USER_PARAMS * pParams; pParams = (RASSRV_USER_PARAMS *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); if (UserTabNewUserParamsOk(hwndDlg, pParams)) { EndDialog(hwndDlg, 1); } else { if( ERROR_CAN_NOT_COMPLETE != pParams->dwErrorCode ) { ErrDisplayError( hwndDlg, pParams->dwErrorCode, ERR_USERTAB_CATAGORY,ERR_USERDB_SUBCAT, 0); } } } // And cancel being pressed else if (wParam == IDCANCEL) { EndDialog(hwndDlg, 0); } // Notice whether the user name has been updated and // if so enable/disable the "Ok" button according to // whether a name has been entered. if (HIWORD(wParam) == EN_UPDATE) { WCHAR pszName[256]; HWND hwndName; BOOL bEnable = FALSE; if (CID_UserTab_New_EB_Username == LOWORD(wParam)) { // Get the current name hwndName = (HWND)lParam; pszName[0] = (WCHAR)0; GetWindowTextW( hwndName, pszName, sizeof(pszName)/sizeof(WCHAR)); // If the length is greater than 1, enable the // ok button. Otherwise, disable it. bEnable = pszName[0] != (WCHAR)0; EnableWindow(GetDlgItem(hwndDlg, IDOK), bEnable); } } break; } return FALSE; } // Brings up the new user/properties property sheet. // // If bNewUser is set, this is a new user, otherwise pUserParams // contains the pertanent user information. // // Returns: // NO_ERROR on success, pUserParams will be filled in // ERROR_CANCELLED if cancel was pressed // win32 error otherwise // // the password in pUserParams are assumed to be encoded DWORD UserTabRaiseProperties ( IN HWND hwndParent, IN RASSRV_USER_PARAMS * pUserParams) { PROPSHEETPAGE Pages[2]; PROPSHEETHEADER Header; INT_PTR ret; if (!pUserParams) return ERROR_INVALID_PARAMETER; // Initialize // For whistler 524777 ZeroMemory(Pages, sizeof(Pages)); ZeroMemory(&Header, sizeof(Header)); // Fill in the values for the general tab Pages[0].dwSize = sizeof(PROPSHEETPAGE); Pages[0].hInstance = Globals.hInstDll; Pages[0].pszTemplate = MAKEINTRESOURCE(DID_UserTab_New); Pages[0].pfnDlgProc = UserTabGenUserPropsDlgProc; Pages[0].pfnCallback = NULL; Pages[0].dwFlags = 0; Pages[0].lParam = (LPARAM)pUserParams; // Fill in the values for the callback tab Pages[1].dwSize = sizeof(PROPSHEETPAGE); Pages[1].hInstance = Globals.hInstDll; Pages[1].pszTemplate = MAKEINTRESOURCE(DID_UserTab_Callback); Pages[1].pfnDlgProc = UserTabCallbackDialogProc; Pages[1].pfnCallback = NULL; Pages[1].dwFlags = 0; Pages[1].lParam = (LPARAM)pUserParams; // Fill in the values for the header Header.dwSize = sizeof(Header); Header.dwFlags = PSH_DEFAULT | PSH_PROPSHEETPAGE | PSH_PROPTITLE | PSH_NOAPPLYNOW; Header.hwndParent = hwndParent; Header.hInstance = Globals.hInstDll; Header.pszCaption = (pUserParams->hUser) ? pUserParams->pszLogonName : pUserParams->pszFullName; Header.nPages = sizeof(Pages) / sizeof(Pages[0]); Header.ppsp = Pages; // Popup the dialog box if ((ret = PropertySheet(&Header)) == -1) { return GetLastError(); } if (pUserParams->bCanceled) { return ERROR_CANCELLED; } return NO_ERROR; } // // Raises the new user dialog // DWORD UserTabRaiseNewUserDialog( IN HWND hwndDlg, IN RASSRV_USER_PARAMS * pParams) { PROPSHEETPAGE Pages; INT_PTR iRet = 0; if (!pParams) { return ERROR_INVALID_PARAMETER; } // Initialize ZeroMemory(&Pages, sizeof(Pages)); Pages.lParam = (LPARAM)pParams; // Raise the dialog iRet = DialogBoxParam( Globals.hInstDll, MAKEINTRESOURCE(DID_UserTab_New), hwndDlg, UserTabGenUserPropsDlgProc, (LPARAM)&Pages); if (iRet == -1) { return GetLastError(); } if (iRet == 0) { return ERROR_CANCELLED; } return NO_ERROR; } // // Handles a request to add a new user // DWORD UserTabHandleNewUserRequest( IN HWND hwndDlg) { RASSRV_USER_PARAMS Params; DWORD dwErr = NO_ERROR, dwLength; HANDLE hUserDatabase = NULL; HWND hwndLV; //Encode the password area before leave the password buffer alone //and any future error return after this should goto directly to :done SafeEncodePasswordBuf(Params.pszPassword1); SafeEncodePasswordBuf(Params.pszPassword2); // Initializes the callback properties Params.hUser = NULL; //Password filds are encrypted when passing in and are encrypted when function return UserTabLoadUserProps (&Params); // Show the new user property sheet Params.bNewUser = TRUE; // For .Net 691639, won't raise password change warning dialog when creating new users dwErr = UserTabRaiseNewUserDialog(hwndDlg, &Params); if (dwErr != NO_ERROR) { goto done; } // Flush any changes to the local user database. These can be // rolled back later with usrRollbackLocalDatabase RasSrvGetDatabaseHandle(hwndDlg, ID_USER_DATABASE, &hUserDatabase); SafeDecodePasswordBuf(Params.pszPassword1); // Make sure you can add the user dwErr = RasSrvAddUser ( Params.pszLogonName, Params.pszFullName, Params.pszPassword1); SafeEncodePasswordBuf(Params.pszPassword1); // Figure out whether the user was added successfully if (dwErr != NO_ERROR) { switch (dwErr) { case ERROR_ACCESS_DENIED: UserTabDisplayError(hwndDlg, ERR_CANT_ADD_USER_ACCESS); break; case ERROR_USER_EXISTS: UserTabDisplayError(hwndDlg, ERR_CANT_ADD_USER_DUPLICATE); break; case ERROR_INVALID_PASSWORDNAME: UserTabDisplayError(hwndDlg, ERR_CANT_ADD_USER_PASSWORD); break; default: UserTabDisplayError(hwndDlg, ERR_CANT_ADD_USER_GENERIC); } goto done; } // Delete the user (since he/she will be added later when the database // is flushed RasSrvDeleteUser(Params.pszLogonName); // Add the user to the database dwErr = usrAddUser(hUserDatabase, Params.pszLogonName, &(Params.hUser)); if (dwErr == ERROR_ALREADY_EXISTS) { UserTabDisplayError(hwndDlg, ERR_CANT_ADD_USER_DUPLICATE); goto done; } if (dwErr != NO_ERROR) { UserTabDisplayError(hwndDlg, ERR_CANT_ADD_USER_GENERIC); goto done; } // Commit the parameters of this user if (wcslen(Params.pszFullName) > 0) { usrSetFullName (Params.hUser, Params.pszFullName); } SafeDecodePasswordBuf(Params.pszPassword1); dwLength = wcslen(Params.pszPassword1); if (dwLength > 0) { usrSetPassword (Params.hUser, Params.pszPassword1); } SafeEncodePasswordBuf(Params.pszPassword1); UserTabSaveCallbackProps (&Params); // Delete all of the old items from the list view hwndLV = GetDlgItem(hwndDlg, CID_UserTab_LV_Users); if (hwndLV) { if (!ListView_DeleteAllItems(hwndLV)) { UserTabDisplayError(hwndDlg, ERR_GENERIC_CODE); dwErr = ERR_GENERIC_CODE; goto done; } // Finally, restock the list view UserTabFillUserList(hwndLV, hUserDatabase); } done: SafeWipePasswordBuf(Params.pszPassword1); SafeWipePasswordBuf(Params.pszPassword2); return dwErr; } DWORD UserTabHandleProperties( IN HWND hwndDlg, IN DWORD dwIndex) { HANDLE hUser = NULL, hUserDatabase = NULL; RASSRV_USER_PARAMS Params, Orig; DWORD dwErr = NO_ERROR; BOOL bNameChanged; SafeEncodePasswordBuf(Params.pszPassword1); SafeEncodePasswordBuf(Params.pszPassword2); // Get a handle to the user in question RasSrvGetDatabaseHandle(hwndDlg, ID_USER_DATABASE, &hUserDatabase); dwErr = usrGetUserHandle (hUserDatabase, dwIndex, &hUser); if (dwErr != NO_ERROR) { UserTabDisplayError(hwndDlg, ERR_USER_DATABASE_CORRUPT); goto done; } // Initializes the callback properties Params.hUser = hUser; //UserTabLoadUserProps() assume the input password is encoded and will return // the password encoded. if ((dwErr = UserTabLoadUserProps (&Params)) != NO_ERROR) { goto done; } SafeDecodePasswordBuf(Params.pszPassword1); SafeDecodePasswordBuf(Params.pszPassword2); CopyMemory( &Orig, &Params, sizeof(Params) ); SafeEncodePasswordBuf(Params.pszPassword1); SafeEncodePasswordBuf(Params.pszPassword2); SafeEncodePasswordBuf(Orig.pszPassword1); SafeEncodePasswordBuf(Orig.pszPassword2); // Show the user property sheet Params.bNewUser = FALSE; // for .Net 691639 //Passwords in the Params are already encoded, functions inside //UserTabRaiseProperties will assume it that way if ((dwErr = UserTabRaiseProperties(hwndDlg, &Params)) != NO_ERROR) { goto done; } // Commit any changes needed // passwords in the input param structures are already encoded // and will remain encoded when return. UserTabSaveUserProps(&Params, &Orig, &bNameChanged); // If the name changed, update the list view if (bNameChanged) { LV_ITEM lvi; // the 3 is for the '(' ')' and ' ' // like foo (foo) // WCHAR pszDispName[IC_USERFULLNAME+IC_USERNAME+3]; DWORD dwSize = sizeof(pszDispName)/sizeof(pszDispName[0]); HWND hwndLV = GetDlgItem(hwndDlg, CID_UserTab_LV_Users); // Initialize the list item ZeroMemory(&lvi, sizeof(LV_ITEM)); lvi.mask = LVIF_TEXT; lvi.iItem = dwIndex; lvi.pszText = pszDispName; usrGetDisplayName(hUser, pszDispName, &dwSize); if (hwndLV) { ListView_SetItem(hwndLV, &lvi); ListView_RedrawItems(hwndLV, dwIndex, dwIndex); } } done: SafeWipePasswordBuf(Params.pszPassword1); SafeWipePasswordBuf(Params.pszPassword2); SafeWipePasswordBuf(Orig.pszPassword1); SafeWipePasswordBuf(Orig.pszPassword2); return NO_ERROR; } // // Handles the request to delete the user at index dwIndex // DWORD UserTabHandleDeleteUser( IN HWND hwndDlg, IN DWORD dwIndex) { WCHAR *pszCapString, pszCaption[512]; WCHAR *pszTitle, *pszName, pszFullName[IC_USERFULLNAME]; HANDLE hUserDatabase = NULL, hUser = NULL; DWORD dwErr= NO_ERROR, dwSize = sizeof(pszFullName)/sizeof(pszFullName[0]); HWND hwndLV = NULL; INT iRet; // Get a handle to the user in question RasSrvGetDatabaseHandle(hwndDlg, ID_USER_DATABASE, &hUserDatabase); dwErr = usrGetUserHandle (hUserDatabase, dwIndex, &hUser); if (dwErr != NO_ERROR) { UserTabDisplayError(hwndDlg, ERR_USER_DATABASE_CORRUPT); return dwErr; } if ((dwErr = usrGetName(hUser, &pszName)) != NO_ERROR) { return dwErr; } if ((dwErr = usrGetFullName(hUser, pszFullName, &dwSize)) != NO_ERROR) { return dwErr; } // Load resources pszCapString = (PWCHAR) PszLoadString (Globals.hInstDll, WRN_DELETE_USER_PERMANENT); pszTitle = (PWCHAR) PszLoadString (Globals.hInstDll, WRN_TITLE); // Format the caption if (wcslen(pszFullName)) wsprintfW(pszCaption, pszCapString, pszFullName); else wsprintfW(pszCaption, pszCapString, pszName); // Advertise the warning iRet = MessageBox( hwndDlg, pszCaption, pszTitle, MB_YESNO | MB_ICONWARNING); if (iRet == IDNO) { return NO_ERROR; } // Delete the user if ((dwErr = usrDeleteUser(hUserDatabase, dwIndex)) != NO_ERROR) { UserTabDisplayError(hwndDlg, ERR_CANT_DELETE_USER_GENERAL); return dwErr; } // Remove all items from the list view hwndLV = GetDlgItem(hwndDlg, CID_UserTab_LV_Users); if (hwndLV) { if (!ListView_DeleteAllItems(hwndLV)) { UserTabDisplayError(hwndDlg, ERR_GENERIC_CODE); return ERR_GENERIC_CODE; } // Finally, restock the list view UserTabFillUserList(hwndLV, hUserDatabase); } return NO_ERROR; } // // Saves the dcc bypass setting // DWORD UserTabSaveBypassDcc( IN HWND hwndDlg) { HANDLE hUserDatabase = NULL; BOOL bBypass = FALSE; HWND hwndCtrl; // Get reference to the misc database RasSrvGetDatabaseHandle( hwndDlg, ID_USER_DATABASE, &hUserDatabase); hwndCtrl = GetDlgItem(hwndDlg, CID_UserTab_CB_BypassDcc); if (hwndCtrl != NULL) { // Get the setting of the checkbox and commit it bBypass = SendMessage( hwndCtrl, BM_GETCHECK, 0, 0) == BST_CHECKED; usrSetDccBypass(hUserDatabase, bBypass); } return NO_ERROR; } // // Handles WM_COMMAND messages on the user tab. // DWORD UserTabCommand ( HWND hwndDlg, WPARAM wParam, LPARAM lParam) { DWORD dwIndex; dwIndex = ListView_GetSelectionMark( GetDlgItem(hwndDlg, CID_UserTab_LV_Users)); switch (wParam) { case CID_UserTab_PB_New: UserTabHandleNewUserRequest(hwndDlg); break; case CID_UserTab_PB_Properties: dwIndex = UserTabHandleProperties(hwndDlg, dwIndex); break; case CID_UserTab_PB_Delete: UserTabHandleDeleteUser(hwndDlg, dwIndex); break; case CID_UserTab_CB_BypassDcc: UserTabSaveBypassDcc (hwndDlg); break; case CID_UserTab_PB_SwitchToMMC: if (RassrvWarnMMCSwitch(hwndDlg)) { PropSheet_PressButton(GetParent(hwndDlg), PSBTN_OK); RassrvLaunchMMC(RASSRVUI_USERCONSOLE); } break; } return NO_ERROR; } // // This dialog procedure responds to messages sent to the // user tab. // INT_PTR CALLBACK UserTabDialogProc( IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam) { // Filter the customized list view messages if (ListView_OwnerHandler( hwndDlg, uMsg, wParam, lParam, LvDrawInfoCallback) ) { return TRUE; } // Filter the customized ras server ui page messages. // By filtering messages through here, we are able to // call RasSrvGetDatabaseHandle below if (RasSrvMessageFilter(hwndDlg, uMsg, wParam, lParam)) { return TRUE; } switch (uMsg) { case WM_INITDIALOG: return FALSE; case WM_HELP: case WM_CONTEXTMENU: { RasSrvHelp (hwndDlg, uMsg, wParam, lParam, phmUserTab); break; } case WM_NOTIFY: { NMHDR* pNotifyData; NM_LISTVIEW* pLvNotifyData; pNotifyData = (NMHDR*)lParam; switch (pNotifyData->code) { // // Note: PSN_APPLY and PSN_CANCEL are handled // by RasSrvMessageFilter // case PSN_SETACTIVE: PropSheet_SetWizButtons(GetParent(hwndDlg), 0); if (! GetWindowLongPtr(hwndDlg, GWLP_USERDATA)) { UserTabInitializeDialog( hwndDlg, wParam, lParam); SetWindowLongPtr( hwndDlg, GWLP_USERDATA, (LONG_PTR)1); } PropSheet_SetWizButtons( GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); break; // The check of an item is changing case LVXN_SETCHECK: pLvNotifyData = (NM_LISTVIEW*)lParam; UserTabHandleUserCheck( hwndDlg, (DWORD)pLvNotifyData->iItem); break; case LVXN_DBLCLK: pLvNotifyData = (NM_LISTVIEW*)lParam; UserTabHandleProperties( hwndDlg, pLvNotifyData->iItem); break; } } break; case WM_COMMAND: UserTabCommand (hwndDlg, wParam, lParam); break; // Cleanup the work done at WM_INITDIALOG case WM_DESTROY: UserTabCleanupDialog(hwndDlg, wParam, lParam); break; } return FALSE; }