|
|||||||
SecureUserI am not unique in wishing to provide my users with a secure operating environment with reasonable levels of password protection AND the ability to add new users at differing levels. For example assuming a three level hierarchy of management, the Supervisors (S) should be allowed to add Middle Management (MM) and Humble Minions (HM) but the MMs should only be allowed to add HMs. Similarly when checking audit violations, Ss should be able to see all audit violations, but MMs should only be allowed to see violations carried out by their own HMs. This was originally implemented by adding an option to LOGTO SYSPROG on the Security menu, and having a custom menu run on reaching SYSPROG to control addition of new users by feeding data statements into SECUREUSER. This worked, except of course that when I logged to SYSPROG, @PRIVILEGE was set to "" so the user security level could not be checked. To circumvent this all that was required was an XLATE to SYSTEM to retrieve the security level. Well and good - until the user logged back to the home account and their @PRIVILEGE was not reset but stayed at "". They were now free to do anything! What was required was a way of adding new users from the home account. The initial problem of actually using the SECUREUSER window in a different account was solved by editing COMMANDS SECUREUSER and removed the account restriction from the template. Unfortunately, the program hooked to SECUREUSER (SEC) checks the account to be SYSPROG and aborts program execution if it isn't. SEC appeared to be the key to the problem. What follows represents the distillation of a few days investigation into SEC. SEC is the system subroutine responsible for most things to do with security, password encryption, account and user checking, options etc. It takes one of a dozen or so parameters ranging from 1 to 12. For the full range of parameters see the list at the end of this article. SEC normally takes its data from @ANS and returns the result of any calculation in @ANS. Every USER record in the SYSTEM file has an encrypted version of both the password (in filed 7) AND the USER record (in field 9). This ensures that unauthorised attempts to modify ANY aspect of the USER record via the editor or DOS results in failure as the USER record becomes invalidated. Any attempts to add new users/change existing users must be cognizant of this fact or their attempts will fail. The calls to SEC required are 6 (to encrypt the password) and 9 (to encrypt the record). Being a routine designed for use from a collector window, any program wishing to call SEC must have WINDOW_COMMON% inserted, even if its a dummy version with WC_W% dimmed to 1 not WC_W_CNT%. As SEC expects to be called from a collector window, parameters must be passed to it via @RECORD and @ANS. Further the structure of @RECORD passed must not be that of the USER record in SYSTEM, rather it should be that of the @RECORD in the collector window SECUREUSER. To add a user it is necessary to prompt for the user name and other details (environment, video etc) then prompt for the password, encrypt the password then finally encrypt the record. (See example code listing below for details of this). The only problem with this relatively simple scenario, is that as pointed out before, SEC can only run from SYSPROG. To get around this we need to modify the object code for SEC. I cannot stress enough how dangerous this sort of procedure is. Not only does it require a good understanding of what you are doing but it leaves you open to problems created by upgrading at a later date and to software compatibility. BEFORE TRYING THIS ENSURE THAT YOU HAVE MADE A BACKUP OF YOUR SYSTEM. Having mentioned these caveats - to work. Firstly we need to copy $SEC into a new record, say $SECURITY so that $SEC still works. As the object code is going to be modded to be specific to a single account we might as well copy the code into the BP for that account and catalog it there. : COPY VERBS $SEC TO : (BP $SECURITY : CATALOG BP SECURITY Now to the difficult bit, modding the object code so that it no longer looks for SYSPROG but loks instaed for our account. THE ACCOUNT NAME WE USE MUST BE NO LONGER THAN 7 (SEVEN) CHARACTERS. At TCL type : EDIT BP $SECURITY and then ^F to find SYSPROG. Note that there is only one occurrence of SYSPROG in the symbol table and it is preceded by a small character which is an ASCII 7. Following the G of SYSPROG is an apparently blank space. This is in fact an ASCII 0, the 'C' end of string delimiter. The ASCII 7 is a pointer indicating the length of te literal and the ASCII 0 delimits the end of the literal. We cannot just type in our own account name without adjusting these parameters very carefully. We must ensure that whatever we do we do not throw out the offsets in the symbol table or strange results could follow. It is necessary to replace the word SYSPROG CHAR(0) with the name of our account CHAR(0) AND THEN AS MANY SPACES AS ARE REQUIRED TO PAD THE ACCOUNTNAME UP TO SEVEN> The ASCII length pointer byte at the beginning of the account name must then be changed from 7 to the length or our account name. Thus if our account name was SECURE we would replace CHAR(7)SYSPROGCHAR(0) with CHAR(6)SECURECHAR(0)CHAR(32) where the characters in bold are the actual ASCII characters entered from the Ctrl-S ASCII Popup. Once we have done this we can file the program and use it in our account. Once this is in place the routine can then be utilised to add users to the user file. Use the following example code to achieve this. Note that in the code we do not explicitly write the user record to the SYSTEM file. As this routine is normally called from a collector window, a call to SEC passing 9 automatically writes this to file. This is interesting as it works from whatever account you are in. This seems to indicate that somewhere in memory is a set of QFILES for at least the major system files such as SYSTEM. I do not know how to gain access to these, it doubtless requires the ubiquitous System Compiler. 0001 ANS = "" ; PW = "" 0002 @RECORD = "" 0003 CALL MSG ("User name","RC",ANS,"") 0004 IF ANS THEN 0005 CALL MSG("Password","RC",PW,"") 0006 @ANS = PW 0007 * 0008 * Encrypt password 0009 * 0010 CALL SECURITY 0011 @RECORD<7> = @ANS 0012 @RECORD<1> = ANS ; * User name 0013 @RECORD<2> = ACCOUNT.NAME$ 0014 @RECORD<3> = LOGON.VERB$ 0015 @RECORD<4> = PRIVILEGE.LEVEL$ 0016 @RECORD<5> = ENVIRONMENT$ 0017 @RECORD<6> = VIDEO$ 0018 @RECORD<8> = RESTART.CODE$ 0019 @RECORD<9> = RESTART.COMMAND$ 0020 CALL SECURITY(9) 0021 END Note further that the structure of the record passed to SEC is not identical to that of the record in the system file. In the system record, the restart code and command are found on the same field as multivalues. To make prompting easier, the collector prompts for these values separately and then SEC combines them. Using the above we now have a routine that can add users from any account and be used as the basis for a comprehensive security system. It would be nice were this sort of messing around to be unnecessary, perhaps by creating a new category of SYSPROG which operates from any account if the privilege level is high enough. This should just be a case of modding the security programs to check @PRIVILEGE rather than @ACCOUNT, perhaps alternating between the two as the result of a setup parameter. To conclude I list below the valid codes to pass to SEC and their action. Code Action 1 Abort window if not SYSPROG 2 Provide popup of valid usernames 3 Provide popup of valid accountnames 4 Provide opoup of valid environments 5 Provide popup of valid video sets 6 Encrypt @ANS 7 Display <encrypted> message (for OCONV) 8 Seems to load some details into current record 9 Documented above 10 Used by SECUREACCOUNT screen on load 11 Check account to be valid 12 Used by SECUREACCOUNT as presave(Volume 1, Issue 6, Pages 9-11) |
|||||||
| |||||||