807.TXT ===================================================================== Restricting Access to Applications ===================================================================== PRODUCT: R:BASE VERSION: 5.0 or Higher ===================================================================== CATALOG: Programming in R:BASE AREA : General Information ===================================================================== The Grant/Revoke access rights system lets you control access to the data in your database. You often need to also control access to the application or parts of the application. Even information on application menus can be sensitive information that you do not want everyone to see. Or, you might want to control access to data beyond the table level. For example, you might want users to see and edit only the data that they personally have entered. However, if someone is really determined to access information in your database you can't keep them out, but you can make it difficult for them. This article describes techniques you can use in addition to the Grant/Revoke access rights system to control access to data and applications. The techniques assume that you have already set up a Grant/Revoke access rights system restricting access to the database and tables. Use Programming to Control Access to an Application The first step in restricting access to data through an application is to make sure that the application does not allow the user access to the R> prompt or to the R:BASE main menu. Only allow users to access data through the application where you have control. Use the following techniques to ensure that users only have access to data from within the application: Always exit from the application to DOS Set ESCAPE off Disable the [F3] hot key Use startup files Always Exit from the Application to DOS Always exit the application to the operating system (DOS or Windows), not to R:BASE. When creating an application with Application Express, do not select the "Exit" action from the "Menu Actions" dialog box which exits back to R:BASE. Instead, select the "Custom" action and enter the command EXIT as the custom code. This action exits the user from R:BASE to the operating system when they choose to exit the application. Set ESCAPE Off Always have "Application break" (ESCAPE) set off to prevent users from aborting an application by pressing [Ctrl][Break]. Aborting an application exits users from the application to R:BASE. By making sure "Application break" (ESCAPE) is set to OFF, you keep users from accidentally or purposefully aborting an application and gaining access to the database outside the application. Disable the [F3] Hot Key Disable the [F3] hot key to prevent users from accessing the database structure (lists of tables, columns, views, forms, reports, and variables). Define a keymap setting the [F3] key to [Right][Left]. When users press [F3], nothing happens and the cursor remains in the same position. Save the keymap to the user's RBASE.CFG file or set it through the SET KEYMAP command in the startup file. For example: SET KEYMAP [F3] = [Right][Left] Use Startup Files Always use an RBASE.DAT or other startup file to initialize the application when R:BASE is started. The RBASE.DAT or startup file can be encrypted using CodeLock. For R:BASE 5.0, put the startup file in the working directory. To set the working directory, click on the R:BASE 5.0 icon and then choose File:Properties. The "Program Item Properties" dialog box opens and displays the working directory. Alternatively, enter the name of the startup file on the "Command Line" after RBG.EXE. For R:BASE 4.5++ or earlier, use DOS batch files or an external menuing system that will automatically place users in the appropriate directories to start R:BASE and the application. Keep Unauthorized Users Out of the Application By using the Grant/Revoke access rights system to protect all tables and views in a database, you can require a valid user identifier to be entered in order to connect and open the database. Using Grant/Revoke does not prevent users from opening the application menus however; it just prevents the actions that require database access from executing. The menus are displayed, but menu options are not executed. Using the R:BASE programming language, you can control access to the application using the following techniques: Require a password to run the application. Require a password to access menus in the application. Require a Password to Run the Application Add commands to the RBASE.DAT or startup file to require users to enter a password in order to gain access to the application. This password is not an R:BASE user identifier, but a password specified in the RBASE.DAT file itself. You can give users three tries to enter the correct password; if they don't, they are returned to the operating system and do not gain access to the application or to R:BASE. Here's an example of code you might use: USER NONE *(make sure Ctrl-Break will not abort to R>) SET ESCAPE OFF SET VAR vnum INTEGER = 1 WHILE vnum <= 3 THEN CLEAR VAR vpass, vget1, vdots SET VAR vnum = (.vnum + 1), vget1 TEXT, + vpass TEXT, vdots TEXT, vpos INTEGER = 49 CLS FROM 10,20 TO 12,61 BLACK CLS FROM 9,19 TO 11,60 CYAN WRITE 'Please enter your password: ' + at 10,22 BLACK ON CYAN LABEL getchar FILLIN vget1=0 USING '' AT 10,.vpos BLACK ON CYAN IF vget1 <> '[Enter]' THEN SET VAR vdots = (.vdots + '.'), + vpass = (.vpass + .vget1), + vpos = (.vpos + 1) WRITE .vdots AT 10,49 BLACK ON CYAN GOTO getchar ENDIF IF vpass = 'pword' THEN RUN application IN application.apx EXIT ELSE PAUSE 2 USING 'Invalid Password. Reenter it.' CLS FROM 10,48 TO 10,60 CYAN ENDIF ENDWHILE PAUSE 2 USING 'No valid password entered. + You cannot access system.' CLS EXIT Be sure to encrypt the RBASE.DAT or startup file with CodeLock so that the passwords you're checking are not readable by viewing the file. You can enhance this technique by using R:BASE tables to store the passwords. Assign each person a personal password. The personal password is stored in an R:BASE table along with the matching R:BASE user identifier created using the GRANT command. This allows you to restrict the number of different R:BASE user identifiers you need to assign, but each person can have their own log-on name. This system allows an application developer to grant a single user identifier for a department, but allow each user in the department to log-on to the application with their own name and password. In addition, you can have a log table that keeps track of who is using the system, and who has tried to gain access to the system. Following is an example of this technique. Create two tables: CREATE TABLE Secret + (UserName TEXT 20, PWord TEXT 18, SysPW TEXT 18) UserName_the name of the person. This can be the user's full name, just their first name, a network log-on name, or any name format you choose to use. The UserName should be unique for each person. PWord_ the personal log-on password for the user. The application developer can assign the password, or provide a menu choice in the application for the user to set this. SysPW_the user identifier for the Grant/Revoke access rights system. The user identifier is set by the database owner. One user identifier can apply to many different users. CREATE TABLE UserLog + (UserName TEXT 20, PWord TEXT 18, Time_In TIME, + Date_In DATE, Time_out TIME, Date_Out DATE, + PCheck TEXT 8) UserName_the name of the user. PWord_the user identifier for the Grant/Revoke access rights system. Time_In_the time the user started the application. Date_In_the date the user started the application. Time_Out_the time the user left the application. Date_Out_the date the user left the application. PCheck_contains either INVALID or VALID. The value indicates whether or not the user entered a correct user name and password combination. If the value is INVALID, the date and time stamp columns indicate the date and time the user attempted to gain entry to the application. The command file requires users to enter their name and their personal log-on password. The command file checks the Secret table for the combination of name and log-on password and gives three chances for the user to enter the correct log-on password for their name. Each try is logged into the UserLog table. The tables are protected by the Grant/Revoke access rights system. Again, the program code must be encrypted so that the passwords are not readable. When the correct password combination is entered, the application starts. If the correct combination is not entered, the user is returned to the operating system. SET MESSAGES OFF SET ERROR MESSAGES OFF USER NONE SET ESCAPE OFF SET ERROR VAR verr SET VAR vnum INTEGER = 1 CLS FROM 10,20 TO 12,61 BLACK CLS FROM 9,19 TO 11,60 CYAN WRITE 'Enter your name: ' at 10,22 BLACK ON CYAN FILLIN vusername=20 USING '' AT 10,39 BLACK ON CYAN IF vusername IS NULL THEN SET VAR vmsg = BREAK ENDIF CLS FROM 9,19 TO 11,60 CYAN WHILE vnum <= 3 THEN CLEAR VAR vpass, vget1, vdots SET VAR vnum = (.vnum + 1), vget1 TEXT, + vpass TEXT, vdots TEXT, vpos INTEGER = 49 CLS FROM 10,20 TO 12,61 BLACK CLS FROM 9,19 TO 11,60 CYAN WRITE 'Please enter your password: ' AT 10,22 + BLACK ON CYAN LABEL getchar FILLIN vget1=0 USING '' AT 10,.vpos BLACK ON CYAN IF vget1 <> '[Enter]' THEN SET VAR vdots = (.vdots + '.'), + vpass = (.vpass + .vget1), + vpos = (.vpos + 1) WRITE .vdots AT 10,49 BLACK ON CYAN GOTO getchar ENDIF *(set the select password for the SECRET table) SET USER junk CONN concomp SET VAR vpw = syspw IN secret WHERE pword = .vpass + AND username = .vusername SET V vhold = .verr IF vhold = 0 THEN *(set the insert password for the USERLOG table) SET USER junk INSERT INTO userlog + (username, pword, time_in, date_in, pcheck) + VALUES + (.vpass, .vusername, .#time, .#date, 'VALID') CLS SET USER .vpw RUN application IN application.apx *(set the update password for the USERLOG table) SET USER junk UPDATE userlog SET time_out = .#time, + date_out = .#date WHERE pword = .vpass AND + username = .vusername AND date_in = .#date EXIT ELSE *(set the insert password for the USERLOG table) SET USER junk INSERT INTO userlog + (username, pword, time_in, date_in, pcheck) + VALUES + (.vpass, .vusername, .#time, .#date, 'INVALID') DISC SET USER NONE PAUSE 2 using 'Invalid Password. Reenter it. CLS FROM 10,48 TO 10,60 CYAN ENDIF ENDWHILE PAUSE 2 using 'No valid password entered. + You cannot access system.' CLS EXIT Require a Password to Access Menus in the Application You can also control access to menu levels in an application. Use one of the following two techniques, depending on whether you want to continue modifying the application with Application Express. Option 1: Application Express modifiable Follow the following steps to insert password checking code as described above into an Application Express application. Using this option you can continue to modify the application using the Application Designer. 1.Create an ASCII file that has one command in it: RUN application IN application.APX. This file must remain as an ASCII file. 2.Modify the application and highlight the pulldown menu option to be restricted. 3.Click the right mouse button and choose Menu Item Settings from the pop-up menu. 4.Add a New Action, Custom Actions, and insert password checking code similar to the examples above. Edit the code to use the QUIT TO command instead of EXIT if users don't enter the correct password; QUIT TO the ASCII file created in step 1 that restarts the application. This action takes users to the main menu of the application, even if they are at a third level menu. 5.Click on the Add Before button to place the password checking code before the menu action to be restricted. When the new action has been added, there are two actions defined for the particular menu selection; the first action does password checking, and the second action displays the menu if the correct password is entered. To require a password to access the main menu of an application, place the password checking code in a startup file or in the Startup block of an Application Express application. Option 2: Not "Expressable" Use the following method if continuing to modify the application with Application Express is not an issue. This method requires editing of the .APP application file. 1.Modify the application using Application Express. Highlight the pulldown menu option to be restricted. 2.Click the right mouse button and choose Menu Item Settings from the pop-up menu. 3.Add a New Action, Custom Actions, and insert password checking code similar to the examples above. Edit the code to add the command SET VAR LEVEL3 = 0 instead of EXIT if users don't enter the correct password. LEVEL3 is the name of the variable Application Express uses to control third level menus. Use LEVEL2 as the variable name if you are checking a second level menu. 4.Click on the Add Before button to place the password checking code before the menu action to be restricted. 5.Save changes and close the Application Designer. 6.Use the text editor, RBEdit to edit the .APP application file. Application Express inserts a RUN command for the custom code immediately prior to a SET VAR command that controls the next menu level. The lines of code in the .APP file look like this: CASE 'Print reports' RUN pcheck IN application.apx SET VAR LEVEL3 INT = 1 WHILE LEVEL3 = 1 THEN Switch the two lines of code, RUN... and SET VAR LEVEL3..., so the code looks like this instead: CASE 'Print reports' SET VAR LEVEL3 INT = 1 RUN pcheck IN application.apx WHILE LEVEL3 = 1 THEN 7.Use CodeLock to create a new .APX file. Select Convert an ASCII Application File to a Binary Procedure File. The ASCII Application File is the .APP file, the Binary Procedure File is the .APX file. If the correct password is not entered, the WHILE condition fails (variable LEVEL3 = 0), the menu is not displayed, and the user returns to the previous menu (either the main menu of the application or the second level menu). Because you edited the .APP file, and used CodeLock to create a new .APX file to run, this application can no longer be modified using Application Express. Application Express won't know about the custom editing you have done to the .APP file. Control Data Access Using Forms R:BASE forms provide application developers with many techniques for limiting or restricting access to data. Such as: Locate specific fields only Use form passwords Use form, table, and field settings to restrict users from editing data Create the form using a view Disable [Shift]-[F3] pop-up menus Use read-only forms Locate Specific Fields Only The application developer limits the data that is located or displayed on the form. The developer chooses which columns the user can view and modify by placing or not placing those fields on the form. Choosing the fields to place on the form immediately and easily limits the data users can view or edit. Users cannot directly access other columns in the underlying table or view through the form. Use Form Passwords Forms have their own password system. Review the article "Protecting Your Data" in this issue of the Exchange for information about using the form password system. Use Form, Table and Field Settings to Restrict Editing Forms provide form, table ,and field level control on editing data. At the form level (choose Form Settings from the layout menu), a developer specifies that the form can be used to add new rows or to edit existing rows. The form menu can be customized or removed altogether. At the table level, choose Table Settings from the layout menu to specify whether users can add new rows, edit existing rows or delete rows from the table. Table settings are set individually for each table added to the form. At the field level, individual fields in tables can be made non-editable through the field settings. Select a field, then click the right mouse button. Choose Field Settings from the pop-up menu. Create the Form Using a View Forms can be built using views in addition to tables. A view can be created to retrieve specific columns or specific rows of data only. The form displays only the rows and columns from the view, not the table. Views are used to restrict editable data on a form to just the data a particular user entered. For example, create a view that retrieves data entered by a particular user. The view can be named using each user's network ID. Place the network ID into a variable using the CVAL function. Use the resulting variable as the view name. SET VAR vName = (CVAL('NAME')) CREATE VIEW &vName AS SELECT .... + WHERE EnteredBy = .vName Next, create a form using the view. The form can also be named using the user's network ID. The form only presents for editing the data retrieved by the view_data specifically entered by a user. Using the user's network ID and ampersand variables, just one command will open any user's form. SET VAR vName = (CVAL('NAME')) EDIT USING &vName Disable [Shift][F3] Pop-up Menus To make sure that users only have access to the data you want them to see, disable the default pop-up menus in forms, or define a specific pop-up menu for each field in a form. In 4.5 Plus! and higher, a new form is created without default pop-up menus on fields. You can turn default pop-up menus on or off through the Field Settings. When pop-up menus are turned off (the default), pressing [Shift][F3] does not display a pop-up menu of the current data in the table for the particular column. Read-only forms There are many application situations when people need to see data, but not edit data. R:BASE provides a number of ways to create read-only forms. 1. Use form passwords to create a read-only form. Specify a modify password through the Form Settings. If the current user identifier is not the same as the modify password, the form is displayed and data appears, but the "No editable data" message displays. Users can see the data but not edit the data. 2. Use Table and Field Settings combinations to create a read-only form. An individual table on a multi-table form can be specified as read-only by changing Table Settings and turning off the "Add New Rows" and "Replace Existing Rows" options, but you need to be careful when doing this. If any table on a multi-table form does not allow new rows to be added, the form cannot be used to add data. The only exception is if the table has a same-table lookup defined. If the "Replace Existing Rows" option is turned off, users can page up and page down through the data but they see the message "No editable data". The cursor does not land in any fields on the form and you cannot scroll through NOTE or TEXT fields. To scroll through NOTE or TEXT fields, define an expression to lookup the note or text data into a variable, locate the variable on the form, and make the field editable through the Field Settings. Because the data is placed into a variable, it won't matter if users inadvertently change the data, the changes won't be saved to the table. If you don't want your users to see the "No editable data" message, locate a dummy variable for each table on the form. Use Field Settings to make all fields but the dummy variable non-editable. The dummy variable gives the cursor a place to land. 3. Do not grant UPDATE permission to the tables the form is based on. Users without UPDATE permission are able to view the data, but cannot change it. They see the message "No editable data" and the cursor does not land in any fields on the form. 4. Create the form using a view and grant only SELECT permission to the view. Combining these programming techniques with the Grant/Revoke access rights system can provide a complete system of data security for your database and application.