10 ! ----- [LOMASKY.SYS]NUSER.BAS ----- ! ! ----- This program allows designated users to add or delete ----- ! ----- SYSUAF accounts, to change accounts between Restricted ----- ! ----- and non-Restricted, to Grant or Deny or Change database ----- ! ----- access to existing accounts, to change division-specific ----- ! ----- access for other accounts, to grant or deny specific ----- ! ----- other identifiers, to change a password back to the ----- ! ----- username, to change the password for a privileged user ----- ! ----- on all cluster nodes, and to change a user's account name ----- ! ----- (department number) on all cluster nodes ----- ! ! ----- This program will check all of the cluster-wide SYSUAF ----- ! ----- files when searching for possible username matches; If ----- ! ----- the username exactly matches another node's SYSUAF ----- ! ----- entry, the other node's SYSUAF information will be used, ----- ! ----- as appropriate, to store the username on the local node ----- ! ----- (after confirmation). If the username matches an account ----- ! ----- on more than one node, only the data from the first ----- ! ----- matching node will be used; the nodes are examined in ----- ! ----- the order that they appear in the TOOLS:SYSUAF_SPECS.DAT ----- ! ----- file. ----- ! ! ---------------------------------------------------------------------- ! ----- This program can also be called as a DCL foreign command, ----- ! ----- so as to provide some of its functions to DCL procedures. ----- ! ----- This is allowed if the user has SETPRV privilege. ----- ! ----- ----- ! ----- Returned values are stored in a DCL global symbol called: ----- ! ----- NUSER_RETURN ----- ! ----- ----- ! ----- Pass one of the following DCL parameter strings: ----- ! ----- DEFAULT username ----- ! ----- Returns username's default device/directory for ----- ! ----- the specified node (default of current node) ----- ! ----- DIVISION username ----- ! ----- Returns username's divisional 4-letter ----- ! ----- identifier for the specified node (default of ----- ! ----- current node) ----- ! ----- GRANT username identifier ----- ! ----- Grants the specified identifier to the specified ----- ! ----- username for the specified node (default of the ----- ! ----- current node) ----- ! ----- IDENTIFIER_NODES identifier ----- ! ----- Returns comma-separated list of all nodes where ----- ! ----- this identifier name exists ----- ! ----- MODIFY_DEVICE username dev: ----- ! ----- Modifies the specified username's device to the ----- ! ----- specified value for the specified node (default ----- ! ----- of the current node) ----- ! ----- MODIFY_UIC username [ggg,mmm] ----- ! ----- Modifies the specified username's UIC to the ----- ! ----- specified value on ALL cluster-wide nodes ----- ! ----- MODIFY_USERNAME username new-username new-owner ----- ! ----- (Note that all characters after the new-username ----- ! ----- will be interpreted as the new-owner name) ----- ! ----- For all cluster-wide nodes: ----- ! ----- 1) Copies the old user's acct to the new username ----- ! ----- 2) Delete the old username's account ----- ! ----- 3) Set password to new username ----- ! ----- 4) Set the pre-expired flag ----- ! ----- 5) Change the directory spec to [new-username] ----- ! ----- 6) Change the owner name to the new owner name ----- ! ----- 7) Change the name of the UIC identifier to the ----- ! ----- new name ----- ! ----- 8) Change the username in each SYSDB database ----- ! ----- which this user has access to, to the new ----- ! ----- username ----- ! ----- NEXT_AVAIL_UIC div ----- ! ----- Calculates the next available UIC (as [ggg,mmm]) ----- ! ----- for a specific 3-letter division code ----- ! ----- NODES username ----- ! ----- Returns comma-separated list of all nodes where ----- ! ----- this username has an account ----- ! ----- QUOTA ADD disk: [ggg,mmm] ----- ! ----- Adds a disk quota (if possible) for the specified ----- ! ----- UIC to the specified disk ----- ! ----- QUOTA DELETE disk: [ggg,mmm] ----- ! ----- Deletes a disk quota (if existing) for the ----- ! ----- specified UIC from the specified disk ----- ! ----- REVOKE username identifier ----- ! ----- Revokes the specified identifier from the ----- ! ----- specified username for the specified node (default ----- ! ----- of the current node) ----- ! ----- UIC username ----- ! ----- Returns username's UIC for the specified node ----- ! ----- (default of current node) ----- ! ---------------------------------------------------------------------- ! ! ----- When this program adds new identifiers, it will ensure ----- ! ----- that the cluster-wide RIGHTSLIST files will always match ----- ! ! ----- When adding a new account, this program will: ----- ! ----- 1) Create an appropriate SYSUAF.DAT record for the user ----- ! ----- 2) Assign an initial password matching the username ----- ! ----- 3) Create a UIC-format identifier for the user ----- ! ----- 4) Grant a divisional "divx" identifier to the user ----- ! ----- 5) Create an "infinite" disk quota entry on the user's ----- ! ----- default device ----- ! ----- 6) Create a root directory for the user (with the ----- ! ----- proper ownership and protection) ----- ! ----- 7) Allow Print Queue selection ----- ! ----- 8) If the user's division has a default ----- ! ----- database: Grants the _nnn identifier to ----- ! ----- the user and updates the security ----- ! ----- database for that user ----- ! ----- 9) Optionally grant and/or 4GL access to ----- ! ----- other databases ----- ! ----- 10) Optionally grant specific additional identifiers to ----- ! ----- the user (For Privileged users, allows the granting ----- ! ----- of any identifier) ----- ! ! ----- When deleting an existing account, this program will: ----- ! ----- 1) If the user holds any _nnn identifiers: ----- ! ----- Removes the user from the security ----- ! ----- database(s) ----- ! ----- 2) (Optionally) Delete the root directory for the user ----- ! ----- (in a highly-secure manner so as not to delete any ----- ! ----- system files which may have an alias for them) ----- ! ----- 3) Remove the disk quota entry (for the user's default ----- ! ----- device) for this user ----- ! ----- 4) Revoke all identifiers held by the user ----- ! ----- 5) Delete the UIC-format identifier for the user ----- ! ----- 6) Remove the user from the SYSUAF.DAT file ----- ! ! ----- When granting database access to an existing username, ----- ! ----- this program will: ----- ! ----- 1) Grant and/or 4GL access to other ----- ! ----- databases ----- ! ! ----- When denying database access from an existing username, ----- ! ----- this program will: ----- ! ----- 1) Deny and/or 4GL access to other ----- ! ----- databases ----- ! ! ----- When changing database access for an existing username, ----- ! ----- this program will: ----- ! ----- 1) Change the Security Database template ----- ! ----- for an existing user in one or more databases ----- ! ! ----- When modifying access to division-specific files, this ----- ! ----- program will: ----- ! ----- 1) Change the divisional "divx" identifier for a user ----- ! ! ----- When granting additional identifiers, this program will: ----- ! ----- 1) Grant additional identifier(s) to the user ----- ! ! ----- When denying specific identifiers, this program will: ----- ! ----- 1) Deny specific identifier(s) from the user ----- ! ! ----- When changing a password back to the username, this ----- ! ----- program will: ----- ! ----- 1) Change the password so as to match the username ----- ! ! ----- When changing a cluster-wide password, this program will: ----- ! ----- 1) Change the password of the running user to the ----- ! ----- entered string, on all of the SYSUAF files in the ----- ! ----- TOOLS:SYSUAF_SPECS.DAT file ----- ! ! ----- When changing a cluster-wide account name (department ----- ! ----- number), this program will: ----- ! ----- 1) Change the account name (department number) of the ----- ! ----- specified user to the entered string, on all of the ----- ! ----- SYSUAF files in the TOOLS:SYSUAF_SPECS.DAT file ----- ! ! ----- Restrictions: ----- ! ! ----- 1) TOOLS:RIGHTSLIST_SPECS.DAT and ----- ! ----- TOOLS:SYSUAF_SPECS.DAT must exist; They must ----- ! ----- contain the actual filespecs of the RIGHTSLIST ----- ! ----- and SYSUAF files on all cluster-wide nodes to ----- ! ----- be affected by this program. ----- ! ! ----- 2) TOOLS:NUSER.DAT must exist. It contains the ----- ! ----- list of allowable divisions, UIC groups for ----- ! ----- each division, and another number to be passed ----- ! ----- to the NUSER_OTHER subroutine (if and when ----- ! ----- called). Format of this file is: ----- ! ----- Columns 1 -> 3 contains the 3-char division ----- ! ----- Column 4 must contain a comma ----- ! ----- Columns 5 -> 7 contains the octal group UIC ----- ! ----- Column 8 must contain a comma ----- ! ----- Columns 9 -> 11 contain the numeric value ----- ! ----- passed to the NUSER_OTHER ----- ! ----- subroutine ----- ! ! ----- 3) This program must be installed with CMKRNL ----- ! ----- privilege ----- ! ! ----- 4) To add a new user, delete an existing user, ----- ! ----- change the Restricted status for a user, or ----- ! ----- change access to division-specific files, or ----- ! ----- change the password back to the username: ----- ! ----- The user must hold the matching MASTER_div ----- ! ----- identifier for the user's division (unless ----- ! ----- the user has SETPRV privilege) ----- ! ! ----- 5) To grant or deny a user access to a ----- ! ----- or 4GL database: ----- ! ----- The user must hold the matching MASTER_div ----- ! ----- identifier for the user's division or the ----- ! ----- MASTER_nnn identifier for the database ----- ! ----- (unless the user has SETPRV privilege) ----- ! ! ----- 6) To grant additional identifiers (other than ----- ! ----- the ones contained in ----- ! ----- TOOLS:NUSER_NONPRIV_IDENTIFIERS.DAT or divDOOR) ----- ! ----- grant a divisional identifier (divR, divW, ----- ! ----- divU) to a user which has no divisional ----- ! ----- identifier, or to change a cluster-wide ----- ! ----- password: ----- ! ----- The user must have the SETPRV privilege ----- ! ! ----- 7) A "DEFAULT" sysuaf entry must already exist ----- ! ! ----- 8) If SYS$NODE logical does not exist, ----- ! ----- Node-Specific sections of NUSER will not be ----- ! ----- performed (such as not automatically granting ----- ! ----- the ODOC identifier and defining a different ----- ! ----- base priority). Node-specific sections can be ----- ! ----- found by searching for ----- ! ----- "**** NODE-SPECIFIC ****" ----- ! ----- (currently only in NUSER.BAS and ----- ! ----- GET_OTHER_IDENTIFIER.FUN) ----- ! ! ----- 9) Requires BASIC V3.n ----- ! ! ----- 10) Allowed identifiers which can be granted by ----- ! ----- Non-privileged users are stored in ----- ! ----- TOOLS:NUSER_NONPRIV_IDENTIFIERS.DAT ----- ! ----- (The file need not exist if no identifiers are ----- ! ----- allowed to be granted by non-privileged users) ----- ! ! ----- 11) See any additional restrictions in NUSER_OTHER ----- ! ! ----- 12) The divR, divW, and divU identifiers must ----- ! ----- exist. Note that existing users which do not ----- ! ----- have a divR/divW/divU identifier granted to ----- ! ----- them, will be defaulted to a division of "OTH" ----- ! ----- and a division access of "U". ----- ! ! ----- Teradyne, Inc., 321 Harrison Avenue, M/S H22, Boston, MA 02118 ! ----- Brian Lomasky: (617) 422-2259 ! ! ----- Neither Brian Lomasky nor Teradyne, Inc. implicitly or ----- ! ----- explicitly implies this program is usable in any way. ----- ! ----- This program is released to the public domain in an ----- ! ----- "AS-IS" condition. ----- ! ! Compile, Link, and Install NUSER as follows: ! @NUSER.BLD ! ! ------------------------ Modification History ------------------------ ! ----- Date Version Description ----- ! ----- 04/08/94 2.07 Always change owner name cluster-wide ----- ! ----- 03/02/94 2.06 Change password back to username on all ----- ! ----- duplicate nodes ----- ! ----- 02/09/94 2.05 Add param to duplicate info between ----- ! ----- multiple nodes ----- ! ----- 09/23/93 2.04 Allow a different template database ----- ! ----- 08/19/93 2.03 Add UIC ident before creating SYSUAF rec----- ! ----- 08/17/93 2.02 Grant appropriate resource attribute ----- ! ----- 08/09/93 2.01 Allow optional SYS$NODE definition ----- ! ----- 07/22/93 2.00 Break up into separate functions ----- ! ----- 05/05/93 1.20 Always change department cluster-wide ----- ! ----- 04/22/93 1.19 Add new option to change department, ----- ! ----- Fix deny when checking other nodes ----- ! ----- 04/02/93 1.18 Add new option to add/delete identifier,----- ! ----- Add MODIFY_USERNAME and ----- ! ----- IDENTIFIER_NODES DCL options ----- ! ----- 03/31/93 1.17 Display last login dates if DELETE ----- ! ----- 03/30/93 1.16 Add foreign DCL support, Allow ----- ! ----- Cluster-wide Grant/Deny ----- ! ----- 03/17/93 1.15 Change wording on diff username prompt ----- ! ----- 01/22/93 1.14 Auto-grant ODOC identifier to ATW users ----- ! ----- 01/20/93 1.13 Fix bugs in calc of next avail ident ----- ! ----- and non-clear of invalid division flag ----- ! ----- 01/19/93 1.12 Ensure unique cluster-wide UIC/idents ----- ! ----- 01/18/93 1.11 Eliminate superfluous error message ----- ! ----- 01/14/93 1.10 If only cluster-wide password change ----- ! ----- allowed, prompt only for required input ----- ! ----- 01/13/93 1.9 Allow the user to grant, deny, or ----- ! ----- change the database access for any ----- ! ----- user, as long as the user holds the ----- ! ----- MASTER_div identifier which matches the ----- ! ----- DIV_nnn division for the database ----- ! ----- 12/18/92 1.8 Fix data from node being copied from ----- ! ----- 12/17/92 1.7 Copy username if matching another node ----- ! ----- 12/16/92 1.6 Change to warning status if identifier, ----- ! ----- divisional identifier, or database ----- ! ----- access exists for a new user ----- ! ----- 12/14/92 1.5 Fix for password change less than the ----- ! ----- minimum password length ----- ! ----- 12/01/92 1.4 Allow divDOOR identifier granting ----- ! ----- 11/30/92 1.3 Trap for invalid password errors and ----- ! ----- print illegal disk usage error info ----- ! ----- 11/24/92 1.2 Add user-friendly error messages, ----- ! ----- Add Cluster Set Password option ----- ! ----- Add Device Unavailable verification ----- ! ----- 11/24/92 1.1 Error detection if node is unavailable ----- ! ----- Check on addtl. username permutations ----- ! ----- Add option to display templates ----- ! ----- 11/20/92 1.0 Original ----- ! ---------------------------------------------------------------------- ! %INCLUDE "NUSER.INC" DECLARE STRING CONSTANT PROGRAM_VERSION = "V2.07" %LET %DEBUG = 0% ! 1 IF DEBUG ON, 0 IF OFF %INCLUDE "$RMSDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB" %INCLUDE "$UAIDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB" DECLARE STRING CONSTANT CLEAR_VTXXX_SCREEN = ESC + "[H" + ESC + "[2J" DECLARE WORD CONSTANT MAX_LIST_TERMIN = 20% RECORD UAIBUF ! $SETUAI RECORD VARIANT CASE WORD BUFFER_LEN WORD ITEM_CODE LONG BUFFER_ADDRESS LONG RETURN_LEN_ADDR CASE LONG LIST_TERMIN END VARIANT END RECORD UAIBUF ! ----- VARIABLE DECLARATIONS ----- DECLARE STRING A_NODE ! NODE TO GRANT IDENTIFIER ON DECLARE STRING ALLOWED_TO_ACCESS_DBMS ! "Y" IF ALLOWED TO ACCESS DBMS DECLARE STRING DEFAULT_NODE ! NULL STRING FOR DEFAULT NODE DECLARE STRING DIRDEL ! "Y" TO ALSO DELETE DIR TREE DECLARE STRING DIVISIONAL_IDENT ! USER'S DIVISIONAL IDENTIFIER DECLARE STRING ENTERED_ACCT ! USER-ENTERED ACCOUNT NAME DECLARE STRING ENTERED_FIRST ! USER-ENTERED FIRST NAME DECLARE STRING ENTERED_LAST ! USER-ENTERED LAST NAME DECLARE STRING ENTERED_RESTRICTED ! USER-ENTERED RESTRICTED/NOT DECLARE WORD EOF_FLAG ! TRUE IF DONE SEARCHING UAF DECLARE WORD ERROR_IF_UNHELD ! FLAG FOR UN-HELD IDENTIFIER DECLARE STRING GRANT_4GL_ACCESS ! "Y" TO GRANT 4GL ACCESS DECLARE STRING HELD_IDENT ! ONE HELD IDENTIFIER DECLARE LONG HELD_IDENT_INDEX ! HELD IDENTIFIER ARRAY INDEX DECLARE WORD I_O_CHNL_SYSUAF ! SYSUAF I/O CHANNEL TO ACCESS DIM STRING ITEM_DESC(MAX_LIST_TERMIN) ! SETUAI ITEM DESCRIPTIONS DECLARE WORD LIST_TERMIN_INDEX ! ARRAY INDEX OF LIST TERMINATOR DECLARE WORD LOCATE_NEXT_UIC ! TRUE TO CALCULATE UIC TO USE DECLARE WORD LOOP_AGAIN ! TRUE TO LOOP PROGRAM AGAIN DECLARE BYTE & MIN_PWD_LEN_FOR_DEFAULT_ACCT ! MINIMUM PWD LEN FOR "DEFAULT" DECLARE WORD NODE_INDEX ! LIST OF NODES TO GRANT IDENT DECLARE STRING NODE_LIST ! LIST OF NODES THAT USER'S ON DECLARE LONG ORIGINAL_ERROR ! FIRST ERROR WHICH OCCURRED DECLARE LONG OTHER_INDEX ! OTHER IDENTIFIER ARRAY INDEX DECLARE STRING PARAM1 ! SUBSEQUENT DCL PARAMETER DECLARE STRING PARAM2 ! SUBSEQUENT DCL PARAMETER DECLARE STRING PARAM3 ! SUBSEQUENT DCL PARAMETER DECLARE WORD PROMPT_LOOP ! TRUE TO PROMPT FOR USER INPUTS DECLARE WORD PRTQ ! DEFAULT PRINT QUEUE INDEX DECLARE WORD RECORD_FOUND ! TRUE IF MATCHING RECORD FOUND DECLARE STRING SYS_NODE ! TRANSLATION OF SYS$NODE DECLARE LONG SYS_STATUS ! SYSTEM SERVICE EXIT STATUS DECLARE WORD SYSUAF_CHNL ! SYSUAF.DAT I/O CHANNEL TO USE DECLARE WORD SYSUAF_RECORD_FOUND ! TRUE IF SYSUAF RECORD FOUND DECLARE WORD TEMP ! TEMPORARY WORD VARIABLE DECLARE STRING TEMP_STRING ! TEMPORARY STRING DECLARE STRING TEMP_USER_NAME ! TEMPORARY USERNAME DECLARE STRING TEMPLATE_DB ! TEMPLATE DATABASE TO BE USED DECLARE STRING THE_DB ! TEMPORARY DATABASE NUMBER DECLARE STRING THE_ID ! IDENTIFIER NAME TO DISPLAY DECLARE STRING TRANSLATED_NAME ! LOGICAL_NAME TRANSLATION DIM UAIBUF UAIITEM(MAX_LIST_TERMIN) ! EQUATE $SETUAI RECORD DECLARE LONG UAI_ACCOUNT_LEN ! LENGTH OF ACCOUNT_NAME DECLARE LONG UAI_ASTLM_LEN ! LENGTH OF ASTLM DECLARE LONG UAI_BIOLM_LEN ! LENGTH OF BIOLM DECLARE LONG UAI_BYTLM_LEN ! LENGTH OF BYTLM DECLARE LONG UAI_DEFDEV_LEN ! LENGTH OF UAI_DEFDEV DECLARE LONG UAI_DEFDIR_LEN ! LENGTH OF UAI_DEFDIR DECLARE LONG UAI_DFWSCNT_LEN ! LENGTH OF WSDEFAULT DECLARE LONG UAI_DIOLM_LEN ! LENGTH OF DIOLM DECLARE LONG UAI_ENQLM_LEN ! LENGTH OF ENQLM DECLARE LONG UAI_FILLM_LEN ! LENGTH OF FILLM DECLARE LONG UAI_FLAGS_LEN ! LENGTH OF FLAGS() ARRAY DECLARE LONG UAI_LGICMD_LEN ! LENGTH OF UAI_LGICMD DECLARE LONG UAI_MINPWDLEN_LEN ! LENGTH OF MINIMUM_PASSWORD_LEN DECLARE LONG UAI_OWNER_LEN ! LENGTH OF UAI_OWNER DECLARE LONG UAI_PASSWORD_LEN ! LENGTH OF UAI_PASSWORD DECLARE LONG UAI_PGFLQUOTA_LEN ! LENGTH OF PGFLQUOTA DECLARE LONG UAI_PRCLM_LEN ! LENGTH OF PRCLM DECLARE LONG UAI_UIC_LEN ! LENGTH OF UIC DECLARE LONG UAI_WSEXTENT_LEN ! LENGTH OF WSEXTENT DECLARE LONG UAI_WSQUOTA_LEN ! LENGTH OF WSQUOTA DECLARE WORD VTXXX ! TRUE IF VTxxx TERMINAL TYPE ! ----- MAPPED VARIABLES FOR $SETUAI SYSTEM SERVICE ----- MAP (UAIMAP) STRING UAI_PASSWORD = 32%, & STRING UAI_DEFDEV = 32%, & STRING UAI_DEFDIR = 64%, & STRING UAI_LGICMD = 64%, & STRING UAI_OWNER = 32% MAP (UAIMAP) STRING FILL = 32%, & BYTE DEFDEV_LEN, & STRING UAI_DEFDEV_CHARS = 31%, & BYTE DEFDIR_LEN, & STRING UAI_DEFDIR_CHARS = 63%, & BYTE LGICMD_LEN, & STRING UAI_LGICMD_CHARS = 63%, & BYTE OWNER_LEN, & STRING UAI_OWNER_CHARS = 31% EXTERNAL WORD FUNCTION ADD_IDENTIFIER( & WORD) ! ADD AN IDENTIFIER EXTERNAL WORD FUNCTION BAD_ASK_STATUS_VALUE( & STRING) ! CHECK ASK_STATUS_nnn VALUE EXTERNAL WORD FUNCTION CALC_DUPL_NODES( & STRING) ! RETURN LIST OF DUPL NODES EXTERNAL SUB & CALCULATE_NEXT_AVAILABLE_UIC ! CALCULATE NEXT AVAILABLE UIC EXTERNAL SUB CHANGE_CLUSTER_PASSWORD ! CHANGE USER'S CLUSTER-WIDE PWD EXTERNAL SUB CHANGE_USER_PASSWORD(WORD) ! CHANGE USER'S PASSWORD EXTERNAL SUB COPY_THIS_USER_ACCOUNT(WORD, STRING, & STRING) ! COPY ACCOUNT FROM ANOTHER NODE EXTERNAL SUB CREATE_ROOT_DIRECTORY ! CREATE THE ROOT DIRECTORY EXTERNAL SUB CREATE_SPECIAL_LOGIN_COM(WORD, & STRING) ! CREATE SPECIAL LOGIN.COM FILE EXTERNAL LONG FUNCTION DEC_TO_OCT(LONG) ! CONVERT DECIMAL TO OCTAL EXTERNAL WORD FUNCTION & DELETE_SYSUAF_RECORD ! DELETE THE SYSUAF RECORD EXTERNAL SUB DELETE_USER_DIRECTORY ! DELETE USER'S DIRECTORY TREE EXTERNAL WORD FUNCTION DISK_QUOTA( & STRING) ! ADD OR DELETE A DISK QUOTA EXTERNAL SUB GET_ACCT(STRING) ! GET ACCOUNT NAME (DEPT NUMBER) EXTERNAL SUB GET_DEFAULT_QUEUE(WORD) ! GET DEFAULT PRINT QUEUE EXTERNAL SUB GET_DIVISION ! GET DIVISION EXTERNAL SUB GET_FIRST_LAST(STRING, & STRING) ! GET FIRST AND LAST NAMES EXTERNAL SUB GET_FOREIGN_DCL_COMMAND_LINE(STRING, STRING, & STRING) ! GET/VERIFY ANY FOREIGN DCL CMD EXTERNAL SUB GET_HELD_MASTER_IDENTIFIERS! GET HELD MASTER_xxx IDENTS EXTERNAL SUB GETJPI ! GET JOB INFO EXTERNAL SUB GET_MY_SYSUAF_INFO ! LOOKUP THIS USER IN THE SYSUAF EXTERNAL SUB GET_OTHER_IDENTIFIER(STRING, & STRING) ! GET ANY OTHER IDENTIFIERS EXTERNAL SUB GET_RESTRICTED(STRING) ! GET [NON-]RESTRICTED RESPONSE EXTERNAL SUB GET_UIC ! GET UIC FOR "OTH" DIVISION EXTERNAL SUB GET_USER_ACTION ! GET USER'S MAIN PROGRAM ACTION EXTERNAL SUB GET_USERNAME(STRING, & STRING) ! GET USERNAME TO BE AFFECTED EXTERNAL WORD FUNCTION GRANT_IDENTIFIER(STRING, WORD, & STRING) ! GRANT AN IDENTIFIER EXTERNAL SUB GRANT_OR_DENY_OTHER( & STRING) ! GRANT OR DENY OTHER ACCESS EXTERNAL SUB LIB$STOP(LONG BY VALUE) ! STOP PROGRAM EXTERNAL LONG FUNCTION LOGICAL_NAME(STRING, & STRING) ! TRANSLATE LOGICAL NAME EXTERNAL WORD FUNCTION NUSER_OTHER(STRING, & STRING, STRING) ! PERFORM ALL NON-STD PROCESSING EXTERNAL SUB PROCESS_ANY_FOREIGN_DCL_COMMAND(STRING, STRING, & STRING) ! PROCESS ANY FOREIGN DCL CMD EXTERNAL SUB READ_ALL_RIGHTSLIST_SPECS ! READ IN ALL RIGHTSLIST SPECS EXTERNAL SUB READ_ALL_SYSUAF_SPECS ! READ IN ALL SYSUAF FILE SPECS EXTERNAL SUB READ_DEFAULT_QUEUES ! READ IN DEFAULT PRINT QUEUES EXTERNAL SUB READ_DIVISION_DATA ! READ IN ALL DIVISION DATA EXTERNAL SUB & READ_NON_PRIVILEGED_IDENTIFIERS ! READ IN ALL NON-PRIVED IDENTS EXTERNAL SUB READ_USER_ACTIONS ! READ IN ALL USER ACTIONS EXTERNAL WORD FUNCTION REMOVE_IDENTIFIER( & STRING) ! REMOVE AN IDENTIFIER EXTERNAL WORD FUNCTION REVOKE_IDENTIFIER! REVOKE AN IDENTIFIER FROM USER EXTERNAL WORD FUNCTION STORE_SYSUAF_RECORD( & WORD) ! STORE A NEW SYSUAF RECORD EXTERNAL LONG FUNCTION SYS$EXIT ! EXIT PROCESS WITH STATUS EXTERNAL LONG FUNCTION SYS$SETUAI ! SET UAF INFORMATION EXTERNAL SUB TURN_ON_PRIVILEGES ! TURN ON BYPASS + SYSPRV PRIVS EXTERNAL WORD FUNCTION VIDEO_TERMINAL ! TRUE IF VTXXX VIDEO TERMINAL ! ----- TRANSLATE ANY DEBUG LOGICAL NAME ----- SYS_STATUS = LOGICAL_NAME("DEBUG", TRANSLATED_NAME) SELECT SYS_STATUS CASE SS$_NOLOGNAM ! IF NO LOGICAL EQUIVALENT: %IF %DEBUG = 1% %THEN DEBUG_MODE = TRUE PRINT "DEBUG>Debug Mode On" %ELSE DEBUG_MODE = FALSE %END %IF CASE SS$_NORMAL DEBUG_MODE = TRUE PRINT "DEBUG>Debug Mode On" CASE ELSE CALL LIB$STOP(SYS_STATUS BY VALUE) END SELECT ! ----- Read the following data fields: ----- ! ----- DIVISION_CTR = Count of Divisions read in ! ----- DIVISION_NAMES() = List of Division codes ! ----- DIVISION_UIC_GROUPS() = UIC Group Numbers for each Division ! ----- DIVISION_OTHER() = List of Other Info for each Division CALL READ_DIVISION_DATA ! READ IN ALL DIVISION DATA ! ----- Read the following data fields: ----- ! ----- QUEUE_CTR = Count of divisions having default print queues ! ----- QUEUE_DEFAULTS() = Array Index (1-n) of the Default Queue ! ----- QUEUE_DIVISIONS() = List of Divisions ! ----- QUEUE_PROMPTS() = Prompt for the Division's Default Queue ! ----- QUEUE_QUEUE_CNTS() = Count (n) of default queues for div ! ----- QUEUE_QUEUE(,1->n) = List of Default Queues for this div ! ----- QUEUE_QUEUE_SOURCE(,1->n) = LOGIN.COM source template file CALL READ_DEFAULT_QUEUES ! READ IN DEFAULT PRINT QUEUES ! ----- Read the following data fields: ----- ! ----- ACCOUNT_DESC = Default string for Account Name ! ----- ACCOUNT_LEN_MAX = Max length of account name field ! ----- ACCOUNT_LEN_MIN = Min length of account name field ! ----- ACCOUNT_NUMERIC = Whether Account Name field is numeric ! ----- DBMS_EXISTS = TRUE if DBMS application is installed ! ----- DBMS_PREFIX = 3-char identifier prefix for the database ! ----- product ! ----- DBMS_PRODUCT = Description of database product ! ----- DEFAULT_RESTRICTED = Default response for "[Non-]Restricted" ! ----- DISPWDHIS = Whether to set the DISPWDHIS login flag when ! ----- adding a new user ! ----- DUPLICATE_NODES = List of nodes to duplicate data between ! ----- FOUR_GL = Name of any installed 4GL ! ----- FOUR_GL_EXISTS = TRUE if 4GL is installed ! ----- FOUR_GL_PREFIX = 4-char identifier prefix for the 4GL ! ----- LGICMD_NON_RESTRICTED = Login Command Procedure for ! ----- Non-Restricted users ! ----- LGICMD_RESTRICTED = Login Command Procedure for Restricted ! ----- users ! ----- USER_ACTION_CTR = Count of user actions ! ----- USER_ACTIONS() = List of allowable user actions ! ----- USER_DESCS() = Menu description for this user action ! ----- USER_SEQS() = Count (n) of prompt sequences ! ----- USER_SEQ(, 1->n) = List of prompt sequences CALL READ_USER_ACTIONS ! READ IN ALL USER ACTIONS READ ITEM_DESC(TEMP) FOR TEMP = 1% TO MAX_LIST_TERMIN - 1% ! ----- DESCRIPTION OF EACH $SETUAI ITEM LIST FIELD ----- DATA ASTLM,BIOLM,BYTLM,DEFDEV,DEFDIR,WSDEFAULT,DIOLM,ENQLM,FILLM,FLAGS DATA LGICMD,OWNER,PASSWORD,PGFLQUOTA,PRCLM,UIC,WSEXTENT,WSQUOTA,PWD_LEN ! ----- GETJPI returns the following data fields: ----- ! ----- PRIVILEGED = TRUE if user has SETPRV privilege ! ----- BYPASS_ON = TRUE if BYPASS privilege is turned on ! ----- SYSPRV_ON = TRUE if SYSPRV privilege is turned on ! ----- UIC = UIC of person who is running this program ! ----- THE_USERNAME = Username of person who is running this program ! ----- USERNAME_LENGTH = Length of THE_USERNAME CALL GETJPI ! GET JOB INFO ! ----- SINCE SYSTEM INTEGRITY MAY BE COMPROMISED IF WE CAN NOT ----- ! ----- OPERATE IN A NON-PRIVILEGED MODE, WHEN REQUIRED, ABORT ----- ! ----- IF THE USER HAS A SYSTEM LEVEL UIC ----- IF OCT_UIC_GROUP <= 8% THEN PRINT "Error - Can not continue processing since" + & " you have a system-level UIC" PRINT " (i.e. Group value less than 11 (octal))." PRINT PRINT " Use a SET UIC command (or SD) to" + & " change your UIC and then rerun" PRINT " this program." PRINT CALL SYS$EXIT(ERROR_WITH_NO_PUTMSG BY VALUE) END IF ! ----- CALCULATE DIVISION(S) AND DATABASE(S) FROM THIS USER'S ----- ! ----- DIVISIONAL MASTER_div IDENTIFIER(S) AND MASTER_nnn ----- ! ----- IDENTIFIERS WHICH ARE HELD (UNLESS USER IS PRIVILEGED) ----- ! ----- (Requires UIC to contain the user's UIC) CALL GET_HELD_MASTER_IDENTIFIERS ! ----- GET_HELD_MASTER_IDENTIFIERS returns the following data: ----- ! ----- HELD_DIVS_CTR will contain the count of held MASTER_div idents ! ----- HELD_DIVS() will contain the held MASTER_div identifiers ! ----- HELD_DBS_CTR will contain the count of held MASTER_nnn idents ! ----- HELD_DBS() will contain the held MASTER_nnn database numbers MY_UIC_GROUP = OCT_UIC_GROUP ! STORE MY OWN UIC GROUP MY_UIC_MEMBER = OCT_UIC_MEMBER ! STORE MY OWN UIC MEMBER ACTION_INDEX = 0% ! ASSUME NO USER ACTION INDEX COPY_USERS_ACCOUNT = FALSE ! ASSUME NOT COPYING ACCOUNT NUSER_FLAG1 = FALSE ! INIT NUSER_OTHER FLAG 1 NUSER_FLAG2 = FALSE ! INIT NUSER_OTHER FLAG 2 ! ----- GET/VERIFY ANY FOREIGN DCL CMD ----- CALL GET_FOREIGN_DCL_COMMAND_LINE(PARAM1, PARAM2, PARAM3) ! ----- GET_FOREIGN_DCL_COMMAND_LINE returns the following data: ----- ! ----- DCL_ACTION = Specified DCL action (blank if none) ! ----- PARAM1 = 1st Parameter for the DCL action (blank if n/a) ! ----- PARAM2 = 2nd Parameter for the DCL action (blank if n/a) ! ----- PARAM3 = 3rd Parameter for the DCL action (blank if n/a) ! ----- SEE WHAT TYPE OF TERMINAL DEVICE WE'RE USING ----- VTXXX = VIDEO_TERMINAL IF VTXXX AND TRM$(DCL_ACTION) = "" AND NOT DEBUG_MODE THEN ! ----- CLEAR SCREEN AND POSITION CURSOR AT LINE 11, ----- ! ----- COLUMN 26 ----- PRINT CLEAR_VTXXX_SCREEN + ESC + & "[11;26HInitializing, Please Stand By" END IF ! ----- TRANSLATE THE SYS$NODE LOGICAL NAME ----- SYS_STATUS = LOGICAL_NAME("SYS$NODE", TRANSLATED_NAME) SELECT SYS_STATUS CASE SS$_NOLOGNAM ! IF NO LOGICAL EQUIVALENT: SYS_STATUS = SS$_NORMAL ! CLEAR SYS_STATUS ERROR CONDITION SYS_NODE = "" ! NO SYS$NODE LOGICAL NAME EXISTS CASE SS$_NORMAL SYS_NODE = EDIT$(TRANSLATED_NAME, 38%) ! ----- REMOVE ANY "::" FROM NODE NAME ----- TEMP = LEN(SYS_NODE) IF MID(SYS_NODE, TEMP - 1%, 2%) = "::" THEN SYS_NODE = LEFT(SYS_NODE, TEMP - 2%) END IF CASE ELSE CALL LIB$STOP(SYS_STATUS BY VALUE) END SELECT CALL TURN_ON_PRIVILEGES ! TURN ON BYPASS + SYSPRV PRIVS ! ----- OPEN DATA FILES ----- CALL READ_ALL_RIGHTSLIST_SPECS ! READ IN ALL FILE SPECS ! ----- READ_ALL_RIGHTSLIST_SPECS returns the following data: ----- ! ----- RIGHTSLIST_COUNTER = Count of RIGHTSLIST.DAT files ! ----- RIGHTSLIST_SPECS() = List of RIGHTSLIST.DAT files (blank if ! ----- not accessible) ! ----- RIGHTSLIST_NODES() = List of RIGHTSLIST.DAT nodes (without ::) CALL READ_ALL_SYSUAF_SPECS ! READ IN ALL FILE SPECS ! ----- READ_ALL_SYSUAF_SPECS returns the following data: ----- ! ----- SYSUAF_COUNTER = Count of SYSUAF.DAT files ! ----- SYSUAF_SPECS() = List of SYSUAF.DAT files (blank if not ! ----- accessible) ! ----- SYSUAF_NODES() = List of SYSUAF.DAT nodes (without any ::) ! ----- READ IN ALL NON-PRIVILEGED IDENTIFIERS ----- CALL READ_NON_PRIVILEGED_IDENTIFIERS ! ----- READ_NON_PRIVILEGED_IDENTIFIERS returns the following data: ---- ! ----- NON_PRIV_IDENT_CTR = Count of non-privileged identifiers ! ----- NON_PRIV_IDENTS(1->NON_PRIV_IDENT_CTR) = Non-privileged idents ! ----- LOOKUP THIS USER IN THE SYSUAF ----- CALL GET_MY_SYSUAF_INFO ! VERIFY THAT THIS USER EXISTS ! ----- GET_MY_SYSUAF_INFO returns the following data: ----- ! ----- MY_MINIMUM_PASSWORD_LEN will contain the minimum password ! ----- length of this user ! ----- PLEASE_TRY_AGAIN will contain the message to be displayed when ! ----- the user is prompted to re-enter the same ! ----- data again ! ----- PROCESS ANY FOREIGN DCL COMMAND ----- IF TRM$(DCL_ACTION) <> "" THEN CALL PROCESS_ANY_FOREIGN_DCL_COMMAND(PARAM1, PARAM2, PARAM3) END IF IF NOT DEBUG_MODE THEN PRINT CLEAR_VTXXX_SCREEN & IF VTXXX ! CLEAR SCREEN, IF POSSIBLE END IF USER_SEQ(0%, 0%) = 0% ! INIT SEQUENCE FOR FIRST PROMPT PROGRAM_LOOP = TRUE ! SET TO LOOP THROUGH PROGRAM WHILE PROGRAM_LOOP LOOP_AGAIN = FALSE ! ASSUME NO PROGRAM RE-LOOP NUSER_FLAG1 = FALSE ! INIT NUSER_OTHER FLAG 1 NUSER_FLAG2 = FALSE ! INIT NUSER_OTHER FLAG 2 GRANT_DENY_OTHER_NODES = FALSE ! ASSUME NO CLUSTER-WIDE GRANT OPEN "SYS$INPUT:" AS FILE #98%, SEQUENTIAL ! ----- SKIP MENU IF ONLY ALLOWED TO CHANGE CLUSTER-WIDE ----- ! ----- PASSWORD ----- IF HELD_DIVS_CTR = 0% AND HELD_DBS_CTR = 0% AND NOT PRIVILEGED THEN PRINT ! ----- SEE IF "SET PASSWORD" IS DISABLED ----- IF (FLAGS(0%) AND 4%) <> 0% THEN PRINT PRINT "Error - You can not change a" + & " locked password" + BEL PRINT ! ----- SET FLAG TO EXIT PROGRAM ----- PROGRAM_LOOP = FALSE ITERATE END IF ! ----- SEE IF GENERATED PASSWORDS ARE REQUIRED ----- IF (FLAGS(1%) AND 1%) <> 0% THEN PRINT PRINT "Error - You can not change" + & " generated passwords" + BEL PRINT ! ----- SET FLAG TO EXIT PROGRAM ----- PROGRAM_LOOP = FALSE ITERATE END IF ! ----- CHANGE THIS USER'S CLUSTER-WIDE PASSWORD ----- CALL CHANGE_CLUSTER_PASSWORD ! ----- SET FLAG TO EXIT PROGRAM ----- PROGRAM_LOOP = FALSE ITERATE END IF PRINT PRINT "NUSER - User Account Maintenance - " + PROGRAM_VERSION PRINT PRINT " (Press B or Control/Z at any prompt" + & " to go back to the previous prompt)" PRINT ! ----- GET USER INPUTS ----- ! ! ----- Note that all of the following routines are passed ----- ! ----- the following fields, which the calling routines ----- ! ----- may change, depending on the user's response: ----- ! ----- ACTION_INDEX = Index into USER_ACTIONS() array ! ----- corresponding to the user-entered ! ----- program action (ACTION_INDEX is -1 to ! ----- exit program or main loop) ! ----- ACTION_SEQ = Next User Input Sequence routine ! ----- BACKWARDS = TRUE if we're moving backwards thru ! ----- prompts ! ACTION_INDEX = 0% ! INIT INDEX FOR FIRST PROMPT BACKWARDS = FALSE ! WE ARE NOT GOING BACKWARDS DIVISIONAL_IDENT = "" ! ASSUME NO DIVISIONAL IDENT ENTERED_ACCT = "" ! ASSUME NO ACCOUNT NAME (DEPT) ENTERED_FIRST = "" ! INIT USER-ENTERED FIRST NAME ENTERED_LAST = "" ! INIT USER-ENTERED LAST NAME ENTERED_RESTRICTED = DEFAULT_RESTRICTED GRANT_4GL_ACCESS = "N" ! ASSUME NO 4GL ACCESS OTHER_IDENTIFIERS_CTR = 0% ! ASSUME NO OTHER IDENTIFIERS OTHER_IDENTS_CTR = 0% ! ASSUME NO OTHER DATABASES PRTQ = -1% ! DEFAULT OF DEFAULT PRINT QUEUE TEMPLATE = "" ! ASSUME NO DATABASE TEMPLATE PROMPT_LOOP = TRUE ! SET SO AS TO LOOP WHILE PROMPT_LOOP ! UNTIL DONE WITH ALL PROMPTS: IF DEBUG_MODE THEN PRINT "DEBUG>---Main Program Prompt" + & " Loop: ACTION_INDEX=" + & NUM1$(ACTION_INDEX) + & ", ACTION_SEQ=" + & NUM1$(ACTION_SEQ) + & ", USER_SEQS()=" + & NUM1$(USER_SEQS(ACTION_INDEX)) END IF ! ----- IF NOT PROMPTING FOR THE USER ACTION: ----- IF ACTION_INDEX <> 0% THEN ! ----- SEE IF DONE PROMPTING FOR FIELDS ----- IF ACTION_SEQ > USER_SEQS(ACTION_INDEX) THEN ! ----- SET TO EXIT USER INPUTS ----- PROMPT_LOOP = FALSE ITERATE END IF END IF IF ACTION_SEQ = 0% OR ACTION_INDEX = 0% THEN ACTION_SEQ = 0% ACTION_INDEX = 0% END IF IF DEBUG_MODE THEN PRINT "DEBUG> Seq=" + & NUM1$(USER_SEQ(ACTION_INDEX, & ACTION_SEQ)) PRINT "DEBUG>Node List=" + TRM$(NODE_LIST) END IF SELECT USER_SEQ(ACTION_INDEX, ACTION_SEQ) CASE 0% ! GET DESIRED MAIN PROGRAM ACTION CALL GET_USER_ACTION ! ----- GET_USER_ACTION returns: ----- ! ----- COPY_USERS_ACCOUNT will be FALSE ! ----- NODE_COUNTER will be zeroed ! ----- DEBUG_MODE = TRUE if Debug Mode was ! ----- enabled ! ----- SEE IF NORMAL END OF PROGRAM ----- IF ACTION_INDEX = -1% THEN ! ----- SET TO EXIT USER INPUTS ----- PROMPT_LOOP = FALSE ! ----- SET FLAG TO EXIT PROGRAM ----- PROGRAM_LOOP = FALSE ITERATE END IF SELECT USER_ACTIONS(ACTION_INDEX) CASE "A" ! IF ADDING A NEW USER: ! ----- ASSUME NO DATABASE/4GL ----- ! ----- ACCESS ----- ALLOWED_TO_ACCESS_DBMS = "N" CASE ELSE ! ----- ASSUME DATABASE/4GL ACCESS ----- ALLOWED_TO_ACCESS_DBMS = "Y" END SELECT CASE 1% ! GET USERNAME TO BE AFFECTED CALL GET_USERNAME(DIRDEL, NODE_LIST) ! ----- GET_USERNAME returns: ----- ! ----- COPY_USER_FILE_INDEX = SYSUAF_NODES() ! ----- array index to use when ! ----- copying this user's acct ! ----- COPY_USERS_ACCOUNT = TRUE to copy this ! ----- user's account ! ----- DEFAULT_MINIMUM_PASSWORD_LEN = Default ! ----- Minimum Pwd Len ! ----- DIRDEL = "Y" to also Delete Directory ! ----- Tree ! ----- ENTERED_USERNAME = Username whose ! ----- acct is to be affected ! ----- INVALID_DIVISION = TRUE if user is in ! ----- an unauthorized division ! ----- NODE_LIST = List of nodes that user is ! ----- on ! ----- OTHER_NODE is TRUE if the username is ! ----- found on a non-local node CASE 2% ! GET FIRST AND LAST NAMES CALL GET_FIRST_LAST(ENTERED_FIRST, ENTERED_LAST) ! ----- GET_FIRST_LAST returns: ----- ! ----- ENTERED_FIRST = User-entered first name ! ----- ENTERED_LAST = User-entered last name CASE 3% ! GET DIVISION CALL GET_DIVISION ! ----- GET_DIVISION returns: ----- ! ----- DIV = User-entered (or forced) ! ----- division ! ----- DIV_INDEX = Index into ! ----- DIVISION_NAMES() of ! ----- matching division CASE 4% ! GET UIC FOR "OTH" DIVISION CALL GET_UIC ! ----- GET_UIC returns: ----- ! ----- GRP = User-entered UIC group ! ----- MBR = User-entered UIC member CASE 5% ! GET ACCOUNT NAME (DEPARTMENT NUMBER) CALL GET_ACCT(ENTERED_ACCT) ! ----- GET_ACCT returns: ----- ! ----- ENTERED_ACCT = User-entered Account ! ----- Name (Department) CASE 6% ! GET [NON-]RESTRICTED RESPONSE CALL GET_RESTRICTED(ENTERED_RESTRICTED) ! ----- GET_RESTRICTED returns: ----- ! ----- ENTERED_RESTRICTED = User-entered ! ----- [Non-]Restricted CASE 7% ! GET DEFAULT QUEUE CALL GET_DEFAULT_QUEUE(PRTQ) ! ----- GET_DEFAULT_QUEUE returns: ----- ! ----- PRTQ = User-entered Default Print Queue CASE 8% ! GET " USER?" RESPONSE TEMP = NUSER_OTHER("DBMSUSER", & ALLOWED_TO_ACCESS_DBMS, "") ! ----- NUSER_OTHER returns: ----- ! ----- DEFAULT_DB = Default Database Number ! ----- ("0" if none) ! ----- ALLOWED_TO_ACCESS_DBMS = "Y" if user ! ----- is allowed to access ! ----- database or 4GL CASE 9% ! GET SECURITY DATABASE TEMPLATE TEMP = NUSER_OTHER("GET_TEMPLATE", & ALLOWED_TO_ACCESS_DBMS, "") ! ----- NUSER_OTHER returns: ----- ! ----- TEMPLATE = Security Database Template ! ----- to grant to this user CASE 10% ! GET 4GL ACCESS FOR DEFAULT DATABASE TEMP = NUSER_OTHER("GET_4GL_ACCESS", & GRANT_4GL_ACCESS, "") ! ----- NUSER_OTHER returns: ----- ! ----- GRANT_4GL_ACCESS = "Y" if user should ! ----- be granted access to the ! ----- 4GL associated with the ! ----- Default ! ----- database CASE 11% ! GET DIVISIONAL IDENTIFIER TEMP = NUSER_OTHER( & "GET_DIVISIONAL_IDENT", & DIVISIONAL_IDENT, "") ! ----- NUSER_OTHER returns: ----- ! ----- DIVISIONAL_IDENT = 4-char divisional ! ----- identifier to be granted ! ----- to this user CASE 12% ! GET "OTHER" DATABASE TEMP = NUSER_OTHER("GET_OTHER_DATABASE",& ALLOWED_TO_ACCESS_DBMS, NODE_LIST) ! ----- NUSER_OTHER returns: ----- ! ----- GRANT_DENY_OTHER_NODES = TRUE if ! ----- Cluster-Wide Grant/Deny ! ----- OTHER_IDENTS() = List of other ! ----- databases or 4GL ! ----- identifiers to grant ! ----- OTHER_IDENTS_DB() = List of other ! ----- template databases to ! ----- use when granting ! ----- OTHER_IDENTS_CTR = Count of other ! ----- databases or 4GL ! ----- identifiers to grant ! ----- OTHER_IDENTS_TEMPLATE() = List of ! ----- templates to use when ! ----- granting the other ! ----- databases CASE 13% ! GET "OTHER" IDENTIFIER CALL GET_OTHER_IDENTIFIER(SYS_NODE, & ENTERED_RESTRICTED) ! ----- GET_OTHER_IDENTIFIER returns: ----- ! ----- OTHER_IDENTIFIERS_CTR = Count of other ! ----- identifiers ! ----- OTHER_IDENTIFIERS() = List of other ! ----- identifiers ! ----- OTHER_IDENTIFIERS_GD() = Identifier ! ----- Grant/Deny code CASE 14% ! GET PASSWORD FOR CLUSTER-WIDE CHANGE ! ----- CHANGE THE CLUSTER-WIDE PASSWORD ----- ! ----- FOR THIS USER ----- CALL CHANGE_CLUSTER_PASSWORD ITERATE ! DONE WITH "S" OPTION CASE ELSE PRINT "Error - Bad index into" + & " USER_SEQ(" + & NUM1$(ACTION_INDEX) + "," + & NUM1$(ACTION_SEQ) + & ") - Aborting..." + BEL CALL SYS$EXIT(ERROR_WITH_NO_PUTMSG BY VALUE) END SELECT NEXT ! LOOP FOR NEXT USER INPUT ! ----- DONE WITH ALL USER INPUTS ----- CLOSE #98% ! CLOSE SYS$INPUT: ITERATE IF NOT PROGRAM_LOOP ! SEE IF PROGRAM EXIT WANTED ITERATE IF LOOP_AGAIN ! SEE IF PROGRAM SHOULD RE-LOOP SELECT USER_ACTIONS(ACTION_INDEX) CASE "A" ! IF ADDING A NEW USER: ! ----- DONE IF WE ARE COPYING THIS USER'S ----- ! ----- ACCOUNT ----- IF COPY_USERS_ACCOUNT THEN ! ----- COPY_THIS_USER_ACCOUNT requires ----- ! ----- the following parameters to be ----- ! ----- passed: ----- ! ----- COPY_USER_FILE_DATA = Remote node's ! ----- SYSUAF data to copy ! ----- ENTERED_USERNAME = Username whose ! ----- acct is to be created ! ----- FOUR_GL = Description of 4GL language ! ----- PRTQ = Default Print Queue array index ! ----- to use for division ! ----- ENTERED_RESTRICTED = "Y" if this user ! ----- is Restricted CALL COPY_THIS_USER_ACCOUNT(PRTQ, & ENTERED_RESTRICTED, "") PRINT PRINT ITERATE END IF ! ----- ADD THIS NEW USER ----- ! ----- CALCULATE UIC TO BE USED ----- LOCATE_NEXT_UIC = TRUE ! SO LOOP WILL EXECUTE ONCE WHILE LOCATE_NEXT_UIC ! ----- ASSUME LOOP WILL EXIT ----- LOCATE_NEXT_UIC = FALSE ! ----- CALCULATE_NEXT_AVAILABLE_UIC is ----- ! ----- passed: ----- ! ----- DIV_INDEX = Division index into ! ----- DIVISION_UIC_GROUPS() ! ----- to use CALL CALCULATE_NEXT_AVAILABLE_UIC & IF DIV <> "OTH" ! ----- CALCULATE_NEXT_AVAILABLE_UIC ----- ! ----- returns: ----- ! ----- GRP = Next Available decimal UIC ! ----- Group number ! ----- MBR = Next Available decimal UIC ! ----- Member number ! ----- STORE OCTAL UIC GROUP AND MEMBER ----- IF DEBUG_MODE THEN PRINT "DEBUG>Using new UIC of [" + & NUM1$(DEC_TO_OCT((GRP))) + & "," + NUM1$(DEC_TO_OCT((MBR))) & + "]" END IF ! ----- ADD THE UIC-BASED IDENTIFIER FOR ----- ! ----- THIS USERNAME ----- OCT_UIC_GROUP = GRP OCT_UIC_MEMBER = MBR TEMP = ADD_IDENTIFIER(TRUE) ! ----- SEE IF CODE RETURNED INDICATING ----- ! ----- THAT THIS NEW UIC WAS JUST USED ----- ! ----- (PROBABLY BY SOMEONE ELSE ----- ! ----- SIMULTANEOUSLY RUNNING NUSER) ----- IF TEMP = 999% THEN ! ----- SET FLAG SO AS TO ----- ! ----- CALCULATE THE NEXT ----- ! ----- AVAILABLE UIC TO BE USED ----- LOCATE_NEXT_UIC = TRUE ITERATE END IF IF TEMP THEN ! PROCESS ANY UNEXPECTED ERROR PRINT "Unexpected error while" & + " adding the user's" & + " UIC identifier" PRINT "Please Notify your VAX" & + " System Manager" + BEL CALL SYS$EXIT( & ERROR_WITH_NO_PUTMSG BY VALUE) END IF NEXT ! ----- SINCE SYS$SETUAI CAN ONLY MODIFY EXISTING ----- ! ----- USER ACCOUNTS, WE WILL FIRST COPY THE ----- ! ----- DEFAULT ACCOUNT TO THE USERNAME TO BE ----- ! ----- ADDED, AND THEN CALL SYS$SETUAI TO MODIFY ----- ! ----- THAT INFORMATION TO THE DESIRED FORMAT ----- USER_NAME = "DEFAULT" ! STORE USERNAME TO SEARCH FOR ! ----- SEE IF THE DEFAULT USERNAME EXISTS ----- RECORD_FOUND = TRUE WHEN ERROR IN GET #50%, KEY #0% EQ USER_NAME, REGARDLESS USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF IF ERR = REC_NOT_FOUND THEN RECORD_FOUND = FALSE CONTINUE END IF EXIT HANDLER END WHEN IF NOT RECORD_FOUND THEN PRINT PRINT 'Error - No "DEFAULT" sysuaf' + & ' record was found!' + BEL PRINT CALL SYS$EXIT(ERROR_WITH_NO_PUTMSG BY VALUE) END IF EOF_FLAG = FALSE ! SET FLAG TO INDICATE SUCCESS UNLOCK #50% ! ----- MOVE USER RESPONSE TO MAP ----- USER_NAME = ENTERED_USERNAME ! ----- STORE THE MINIMUM PASSWORD LENGTH OF THE ----- ! ----- DEFAULT ACCOUNT, SO WE CAN CHANGE IT BACK ----- ! ----- TO ITS CORRECT VALUE LATER ----- MIN_PWD_LEN_FOR_DEFAULT_ACCT = MINIMUM_PASSWORD_LENGTH ! ----- SO WE CAN CHANGE THE PASSWORD ----- MINIMUM_PASSWORD_LENGTH = 1% ! ----- CREATE A NEW SYSUAF RECORD ----- IF STORE_SYSUAF_RECORD(50%) THEN PRINT ITERATE ! LOOP AGAIN... END IF ! ----- MOVE NEW USER INFO TO MAPPED VARIABLES ----- ! ----- ACCOUNT NAME (DEPARTMENT NUMBER) ----- ACCOUNT_NAME = ENTERED_ACCT IF ALLOWED_TO_ACCESS_DBMS = "Y" THEN ! ----- DBMS Requirements: ----- ! ----- (USE THE "DEFAULT" VALUES IF NOT ----- ! ----- AN "ASK" USER) ----- ! ----- ASTLM = Minimum of stream which ----- ! ----- has the largest number of ! ----- database buffers ----- ! ----- BYTLM = Minimum of 10240 + 1600 ----- ! ----- per stream ----- ! ----- DIOLM = ASTLM - 2 ----- ! ----- ENQLM = 8000 ----- ! ----- FILLM = 200 (approx) ----- ASTLM = 200% ! AST QUEUE LIMIT BIOLM = 40% ! BUFFERED I/O LIMIT BYTLM = 20480% ! BUFFER I/O BYTE COUNT LIMIT DIOLM = ASTLM - 2% ! DIRECT I/O LIMIT ENQLM = 8000% ! ENQUEUE LIMIT FILLM = 200% ! OPEN FILE LIMIT END IF ! ----- LENGTH OF DEFAULT DIR ----- DEFDIR_LEN = LEN(TRM$(ENTERED_USERNAME)) + 2% ! ----- DEFAULT DIRECTORY ----- UAI_DEFDIR_CHARS = "[" + TRM$(ENTERED_USERNAME) + "]" ! ----- STORE THE MINIMUM PASSWORD LENGTH OF THE ----- ! ----- DEFAULT ACCOUNT ----- MINIMUM_PASSWORD_LENGTH = MIN_PWD_LEN_FOR_DEFAULT_ACCT IF ENTERED_FIRST = "" AND ENTERED_LAST = "" THEN OWNER_LEN = 0% UAI_OWNER_CHARS = "" ELSE OWNER_LEN = LEN(ENTERED_FIRST) + & LEN(ENTERED_LAST) + 2% UAI_OWNER_CHARS = ENTERED_LAST + ", " + & ENTERED_FIRST END IF DEFDEV_LEN = 9% ! LENGTH OF DEFAULT DEVICE IF DIV = "OTH" THEN ! ----- DEFAULT DEVICE FOR "OTH" DIV ----- UAI_DEFDEV_CHARS = "DISK$PGM:" ELSE ! ----- DEFAULT DEVICE FOR ALL NORMAL ----- ! ----- DIVISIONS ----- UAI_DEFDEV_CHARS = "DISK$" + DIV + ":" END IF ! ----- STORE USERNAME AS PASSWORD ----- UAI_PASSWORD = TRM$(ENTERED_USERNAME) ! ----- DUPLICATE SOME FIELDS SO THAT WE CAN REFER ----- ! ----- TO THEM REGARDLESS OF WHETHER WE'RE ADDING ----- ! ----- A NEW ACCOUNT OR DELETING AN EXISTING ----- ! ----- ACCOUNT ----- ! ----- DEFAULT DEVICE ----- THE_DEVICE = UAI_DEFDEV_CHARS ! ----- LENGTH OF DEFAULT DEVICE ----- DEVICE_LENGTH = DEFDEV_LEN ! ----- DEFAULT DIRECTORY ----- DIRECTORY_NAME = UAI_DEFDIR_CHARS ! ----- LENGTH OF DEFAULT DIRECTORY ----- DIRECTORY_NAME_LENGTH = DEFDIR_LEN ! ----- STORE DECIMAL UIC VALUE ----- OCT_UIC_GROUP = GRP OCT_UIC_MEMBER = MBR ! ----- TKK-DIVISION USERS ON BRIT GET A BASE ----- ! ----- PRIORITY OF 5 ----- ! **** NODE-SPECIFIC **** IF SYS_NODE = "BRIT" AND DIV = "TKK" THEN BASE_PRIORITY = 5% END IF IF DIV = "PGM" THEN PRCLM = 10% ! SUBPROCESS CREATION LIMIT ! ----- PAGE FILE QUOTA ----- PGFLQUOTA = 40000% WSDEFAULT = 500%! WORKING SET SIZE WSQUOTA = 1000% ! WORKING SET QUOTA ! ----- WORKING SET EXTENT ----- WSEXTENT = 10000% ELSE ! ----- (USE THE "DEFAULT" VALUES IF NOT ----- ! ----- A DBMS USER) ----- IF ALLOWED_TO_ACCESS_DBMS = "Y" THEN ! ----- SUBPROCESS CREATION LIMIT ----- PRCLM = 2% ! ----- PAGE FILE QUOTA ----- PGFLQUOTA = 30000% ! ----- WORKING SET SIZE ----- WSDEFAULT = 500% ! ----- WORKING SET QUOTA ----- WSQUOTA = 750% ! ----- WORKING SET EXTENT ----- WSEXTENT = 10000% END IF END IF IF ENTERED_RESTRICTED = "Y" THEN LGICMD_LEN = LEN(TRM$(LGICMD_RESTRICTED)) UAI_LGICMD_CHARS = TRM$(LGICMD_RESTRICTED) ! ----- SET RESTRICTED, DISMAIL ----- ! ----- (AND DISPWDHIS) FLAGS ----- ! ----- RESTRICTED (2^3) AND DISMAIL (2^7) ----- FLAGS(0%) = -120% FLAGS(1%) = 0% IF DISPWDHIS = "Y" THEN ! ----- DISPWDHIS (2^3) ----- FLAGS(2%) = 8% ELSE FLAGS(2%) = 0% END IF ELSE LGICMD_LEN = LEN(TRM$(LGICMD_NON_RESTRICTED)) UAI_LGICMD_CHARS = TRM$(LGICMD_NON_RESTRICTED) ! ----- SET DISPWDHIS FLAG, IF WANTED ----- FLAGS(0%) = 0% FLAGS(1%) = 0% IF DISPWDHIS = "Y" THEN ! ----- DISPWDHIS (2^3) ----- FLAGS(2%) = 8% ELSE FLAGS(2%) = 0% END IF END IF ! ----- STORE ACCOUNT ----- UAIITEM(0%)::BUFFER_LEN = 32% UAIITEM(0%)::ITEM_CODE = UAI$_ACCOUNT UAIITEM(0%)::BUFFER_ADDRESS = LOC(ACCOUNT_NAME) UAIITEM(0%)::RETURN_LEN_ADDR = LOC(UAI_ACCOUNT_LEN) ! ----- STORE ASTLM ----- UAIITEM(1%)::BUFFER_LEN = 2% UAIITEM(1%)::ITEM_CODE = UAI$_ASTLM UAIITEM(1%)::BUFFER_ADDRESS = LOC(ASTLM) UAIITEM(1%)::RETURN_LEN_ADDR = LOC(UAI_ASTLM_LEN) ! ----- STORE BIOLM ----- UAIITEM(2%)::BUFFER_LEN = 2% UAIITEM(2%)::ITEM_CODE = UAI$_BIOLM UAIITEM(2%)::BUFFER_ADDRESS = LOC(BIOLM) UAIITEM(2%)::RETURN_LEN_ADDR = LOC(UAI_BIOLM_LEN) ! ----- STORE BYTLM ----- UAIITEM(3%)::BUFFER_LEN = 4% UAIITEM(3%)::ITEM_CODE = UAI$_BYTLM UAIITEM(3%)::BUFFER_ADDRESS = LOC(BYTLM) UAIITEM(3%)::RETURN_LEN_ADDR = LOC(UAI_BYTLM_LEN) ! ----- STORE THE DEFAULT DEVICE (AS A COUNTED ----- ! ----- STRING) ----- UAIITEM(4%)::BUFFER_LEN = 32% UAIITEM(4%)::ITEM_CODE = UAI$_DEFDEV UAIITEM(4%)::BUFFER_ADDRESS = LOC(UAI_DEFDEV) UAIITEM(4%)::RETURN_LEN_ADDR = LOC(UAI_DEFDEV_LEN) ! ----- STORE THE DEFAULT DIRECTORY (AS A COUNTED ----- ! ----- STRING) ----- UAIITEM(5%)::BUFFER_LEN = 64% UAIITEM(5%)::ITEM_CODE = UAI$_DEFDIR UAIITEM(5%)::BUFFER_ADDRESS = LOC(UAI_DEFDIR) UAIITEM(5%)::RETURN_LEN_ADDR = LOC(UAI_DEFDIR_LEN) ! ----- STORE WORKING SET DEFAULT ----- UAIITEM(6%)::BUFFER_LEN = 4% UAIITEM(6%)::ITEM_CODE = UAI$_DFWSCNT UAIITEM(6%)::BUFFER_ADDRESS = LOC(WSDEFAULT) UAIITEM(6%)::RETURN_LEN_ADDR = LOC(UAI_DFWSCNT_LEN) ! ----- STORE DIOLM ----- UAIITEM(7%)::BUFFER_LEN = 2% UAIITEM(7%)::ITEM_CODE = UAI$_DIOLM UAIITEM(7%)::BUFFER_ADDRESS = LOC(DIOLM) UAIITEM(7%)::RETURN_LEN_ADDR = LOC(UAI_DIOLM_LEN) ! ----- STORE ENQLM ----- UAIITEM(8%)::BUFFER_LEN = 2% UAIITEM(8%)::ITEM_CODE = UAI$_ENQLM UAIITEM(8%)::BUFFER_ADDRESS = LOC(ENQLM) UAIITEM(8%)::RETURN_LEN_ADDR = LOC(UAI_ENQLM_LEN) ! ----- STORE FILLM ----- UAIITEM(9%)::BUFFER_LEN = 2% UAIITEM(9%)::ITEM_CODE = UAI$_FILLM UAIITEM(9%)::BUFFER_ADDRESS = LOC(FILLM) UAIITEM(9%)::RETURN_LEN_ADDR = LOC(UAI_FILLM_LEN) ! ----- STORE LOGIN FLAGS ----- UAIITEM(10%)::BUFFER_LEN = 4% UAIITEM(10%)::ITEM_CODE = UAI$_FLAGS UAIITEM(10%)::BUFFER_ADDRESS = LOC(FLAGS(0%)) UAIITEM(10%)::RETURN_LEN_ADDR = LOC(UAI_FLAGS_LEN) ! ----- STORE LGICMD ----- UAIITEM(11%)::BUFFER_LEN = 64% UAIITEM(11%)::ITEM_CODE = UAI$_LGICMD UAIITEM(11%)::BUFFER_ADDRESS = LOC(UAI_LGICMD) UAIITEM(11%)::RETURN_LEN_ADDR = LOC(UAI_LGICMD_LEN) ! ----- STORE OWNER NAME ----- UAIITEM(12%)::BUFFER_LEN = 32% UAIITEM(12%)::ITEM_CODE = UAI$_OWNER UAIITEM(12%)::BUFFER_ADDRESS = LOC(UAI_OWNER) UAIITEM(12%)::RETURN_LEN_ADDR = LOC(UAI_OWNER_LEN) ! ----- STORE PASSWORD ----- UAIITEM(13%)::BUFFER_LEN = & LEN(TRM$(ENTERED_USERNAME)) UAIITEM(13%)::ITEM_CODE = UAI$_PASSWORD UAIITEM(13%)::BUFFER_ADDRESS = LOC(UAI_PASSWORD) UAIITEM(13%)::RETURN_LEN_ADDR = LOC(UAI_PASSWORD_LEN) ! ----- STORE PGFLQUOTA ----- UAIITEM(14%)::BUFFER_LEN = 4% UAIITEM(14%)::ITEM_CODE = UAI$_PGFLQUOTA UAIITEM(14%)::BUFFER_ADDRESS = LOC(PGFLQUOTA) UAIITEM(14%)::RETURN_LEN_ADDR = LOC(UAI_PGFLQUOTA_LEN) ! ----- STORE PRCLM ----- UAIITEM(15%)::BUFFER_LEN = 2% UAIITEM(15%)::ITEM_CODE = UAI$_PRCCNT UAIITEM(15%)::BUFFER_ADDRESS = LOC(PRCLM) UAIITEM(15%)::RETURN_LEN_ADDR = LOC(UAI_PRCLM_LEN) ! ----- STORE UIC ----- UAIITEM(16%)::BUFFER_LEN = 4% UAIITEM(16%)::ITEM_CODE = UAI$_UIC UAIITEM(16%)::BUFFER_ADDRESS = LOC(UIC) UAIITEM(16%)::RETURN_LEN_ADDR = LOC(UAI_UIC_LEN) ! ----- STORE WSEXTENT ----- UAIITEM(17%)::BUFFER_LEN = 4% UAIITEM(17%)::ITEM_CODE = UAI$_WSEXTENT UAIITEM(17%)::BUFFER_ADDRESS = LOC(WSEXTENT) UAIITEM(17%)::RETURN_LEN_ADDR = LOC(UAI_WSEXTENT_LEN) ! ----- STORE WSQUOTA ----- UAIITEM(18%)::BUFFER_LEN = 4% UAIITEM(18%)::ITEM_CODE = UAI$_WSQUOTA UAIITEM(18%)::BUFFER_ADDRESS = LOC(WSQUOTA) UAIITEM(18%)::RETURN_LEN_ADDR = LOC(UAI_WSQUOTA_LEN) ! ----- STORE MINIMUM PASSWORD LENGTH ----- UAIITEM(19%)::BUFFER_LEN = 1% UAIITEM(19%)::ITEM_CODE = UAI$_PWD_LENGTH UAIITEM(19%)::BUFFER_ADDRESS = & LOC(MINIMUM_PASSWORD_LENGTH) UAIITEM(19%)::RETURN_LEN_ADDR = LOC(UAI_MINPWDLEN_LEN) ! ----- ASSUME LIST TERMINATOR AT END ----- LIST_TERMIN_INDEX = MAX_LIST_TERMIN ! ----- ASSUME NO ERROR OCCURRED ----- ORIGINAL_ERROR = SS$_NORMAL SYS_STATUS = SS$_ABORT ! SO LOOP WILL WORK WHILE SYS_STATUS <> SS$_NORMAL ! ----- STORE ITEM LIST TERMINATOR VALUE ----- UAIITEM(LIST_TERMIN_INDEX)::LIST_TERMIN = 0% ! ----- STORE THIS NEW USER INFO IN THE ----- ! ----- SYSUAF FILE ----- TEMP_USER_NAME = TRM$(ENTERED_USERNAME) SYS_STATUS = SYS$SETUAI( & , ! NULL & , ! NULL & TEMP_USER_NAME, ! USERNAME TO MODIFY & UAIITEM() BY REF, ! ITEM LIST & , ! NULL & , ! NULL & ) ! NULL SELECT SYS_STATUS CASE SS$_NORMAL CASE RMS$_RNF PRINT PRINT "Someone just deleted" + & " the record for " + & TRM$(ENTERED_USERNAME) + BEL PRINT PRINT ITERATE ! LOOP AGAIN... CASE ELSE ! ----- STORE FIRST ERROR WHICH ----- ! ----- OCCURRED ----- ORIGINAL_ERROR = SYS_STATUS & IF ORIGINAL_ERROR = SS$_NORMAL ! ----- LOWER LIST TERMINATOR ----- ! ----- UNTIL THE SYSTEM SERVICE ----- ! ----- WORKS SO WE CAN DIAGNOSE ----- ! ----- WHICH PARAMETER IS BAD, ----- ! ----- IF ANY ----- LIST_TERMIN_INDEX = & LIST_TERMIN_INDEX - 1% SYS_STATUS = SS$_NORMAL IF & LIST_TERMIN_INDEX = 0% END SELECT NEXT ! ----- SEE IF ANY ERROR OCCURRED ----- IF ORIGINAL_ERROR <> SS$_NORMAL THEN TEMP = DELETE_SYSUAF_RECORD IF LIST_TERMIN_INDEX <> MAX_LIST_TERMIN THEN PRINT "Error while trying" + & " to store " + & ITEM_DESC(LIST_TERMIN_INDEX) END IF PRINT "Unexpected error for SYS$SETUAI" CALL LIB$STOP(ORIGINAL_ERROR BY VALUE) END IF ! ----- GO BACK INTO THIS SYSUAF ENTRY AND ----- ! ----- CHANGE THE PASSWORD TO PRE-EXPIRED, AND IF ----- ! ----- THE DIVISION IS "PGM", ALSO SET THE ----- ! ----- AUTHORIZED AND THE DEFAULT PRIVILEGES TO ----- ! ----- SETPRV,TMPMBX,OPER,NETMBX,SYSPRV ----- RECORD_FOUND = TRUE WHEN ERROR IN GET #50%, KEY #0% EQ USER_NAME USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF IF ERR = REC_NOT_FOUND THEN RECORD_FOUND = FALSE CONTINUE END IF EXIT HANDLER END WHEN IF NOT RECORD_FOUND THEN PRINT PRINT "Someone just deleted the" + & " record for " + & TRM$(ENTERED_USERNAME) + BEL PRINT PRINT ITERATE ! LOOP AGAIN... END IF ! ----- (PRE-EXPIRED PASSWORD ONLY TAKES EFFECT ----- ! ----- IF PASSWORD LIFETIME IS NON-ZERO) ----- IF PASSWORD_LIFETIME(0%) = 0% AND & PASSWORD_LIFETIME(1%) = 0% THEN PRINT PRINT "Since this user has no" + & " password lifetime, the" + & " password has not been pre-expired." ELSE ! ----- SET PRE-EXPIRED FLAG ----- DATE_OF_PASSWORD_CHANGE(0%) = -1% DATE_OF_PASSWORD_CHANGE(1%) = -1% END IF IF DIV = "PGM" THEN ! ----- SET SETPRV (2^6), TMPMBX (2^7) ----- PRIVILEGES(1%) = PRIVILEGES(1%) OR -64% DEFAULT_PRIVILEGES(1%) = & DEFAULT_PRIVILEGES(1%) OR -64% ! ----- SET OPER (2^2), NETMBX (2^4) ----- PRIVILEGES(2%) = PRIVILEGES(2%) OR 20% DEFAULT_PRIVILEGES(2%) = & DEFAULT_PRIVILEGES(2%) OR 20% ! ----- SET SYSPRV (2^4) ----- PRIVILEGES(3%) = PRIVILEGES(3%) OR 16% DEFAULT_PRIVILEGES(3%) = & DEFAULT_PRIVILEGES(3%) OR 16% END IF UPDATE #50% UNLOCK #50% PRINT PRINT "User " + TRM$(ENTERED_USERNAME) + & " added to " + TRM$(SYSUAF_NODES(1%)) + "..." ! ----- DUPLICATE THIS NEWLY-ADDED ACCOUNT ON ANY ----- ! ----- DUPLICATE NODES ----- ! ----- STORE SYSUAF DATA TO BE COPIED ----- COPY_USER_FILE_DATA = UAF_REC ! ----- (NO HELD IDENTIFIER DATA NEEDS TO BE ----- ! ----- COPIED BY THE COPY_THIS_USER_ACCOUNT ----- ! ----- FUNCTION, SINCE THE SUBSEQUENT ----- ! ----- GRANT_IDENTIFIER CALLS WILL GRANT THEM TO ----- ! ----- ALL OF THE DUPLICATE NODES) ----- SAVE_HELD_IDENTS_CTR = 0% ! ----- COPY_THIS_USER_ACCOUNT requires the ----- ! ----- following parameters to be passed: ----- ! ----- COPY_USER_FILE_DATA = SYSUAF data to copy to ! ----- the remote node ! ----- ENTERED_USERNAME = Username whose acct is to ! ----- be created ! ----- FOUR_GL = Description of 4GL language ! ----- PRTQ = Default Print Queue array index to use ! ----- for division ! ----- ENTERED_RESTRICTED = "Y" if this user ! ----- is Restricted ! ----- SPECIFIC_NODE = "*" (Special code to tell the ! ----- function to only copy the ! ----- SYSUAF data to duplicate ! ----- node(s)) CALL COPY_THIS_USER_ACCOUNT(PRTQ, & ENTERED_RESTRICTED, "*") IF DIVISIONAL_IDENT <> "" THEN ! ----- GRANT THIS USERNAME THE ----- ! ----- APPROPRIATE DIVISIONAL IDENTIFIER ----- THE_IDENT = DIVISIONAL_IDENT IF GRANT_IDENTIFIER("", FALSE, "") THEN TEMP = DELETE_SYSUAF_RECORD PRINT "Unexpected error while" & + " adding the user's" & + " divisional identifier" CALL SYS$EXIT( & ERROR_WITH_NO_PUTMSG BY VALUE) END IF END IF ! ----- ADD AN "INFINITE" DISK QUOTA FOR THIS USER ----- TEMP = DISK_QUOTA("ADD") ! ----- CREATE THE ROOT DIRECTORY FOR THIS USER ----- CALL CREATE_ROOT_DIRECTORY ! ----- CREATE SPECIAL LOGIN.COM FILE FOR SPECIAL ----- ! ----- DEFAULT PRINT QUEUES ----- CALL CREATE_SPECIAL_LOGIN_COM(PRTQ, ENTERED_RESTRICTED) ! ----- SEE IF USER IS TO BE GRANTED 4GL ACCESS ----- IF GRANT_4GL_ACCESS = "Y" THEN PRINT "Granting user access to the " + & TRM$(FOUR_GL) + " " + & DEFAULT_DB + " database..." ! ----- GRANT THIS USERNAME THE 4GL ----- ! ----- IDENTIFIER ----- THE_IDENT = FOUR_GL_PREFIX + DEFAULT_DB TEMP = GRANT_IDENTIFIER("", FALSE, "") END IF ! ----- SEE IF USER IS TO BE GRANTED DATABASE ----- ! ----- ACCESS ----- IF TEMPLATE <> "" AND DBMS_EXISTS THEN PRINT "Granting user access to the " + & DEFAULT_DB + " database..." ! ----- GRANT THIS USERNAME THE DATABASE ----- ! ----- IDENTIFIER ----- THE_IDENT = DBMS_PREFIX + DEFAULT_DB TEMP = GRANT_IDENTIFIER("", FALSE, "") ! ----- ADD USER TO THIS ----- ! ----- DATABASE (CALL CHANGE TO DELETE ----- ! ----- ANY POSSIBLE OLD USER DATA) ----- TEMP = NUSER_OTHER("CHANGE_DB_USER", & DEFAULT_DB, DEFAULT_DB + TEMPLATE) END IF ! ----- ALSO GRANT ACCESS TO ANY OTHER DATABASES ----- OTHER_INDEX = 0% WHILE OTHER_INDEX < OTHER_IDENTS_CTR OTHER_INDEX = OTHER_INDEX + 1% THE_DB = TRM$(OTHER_IDENTS(OTHER_INDEX)) TEMPLATE_DB = OTHER_IDENTS_DB(OTHER_INDEX) TEMPLATE = OTHER_IDENTS_TEMPLATE(OTHER_INDEX) ! ----- SEE IF ADDING DATABASE ACCESS ----- IF LEN(THE_DB) = 3% THEN PRINT "Granting user access" + & " to the " + & TRM$(DBMS_PRODUCT) + & " " + THE_DB + " database..." ! ----- GRANT THIS USERNAME THE ----- ! ----- DATABASE IDENTIFIER ----- THE_IDENT = DBMS_PREFIX + THE_DB TEMP = GRANT_IDENTIFIER("", FALSE, "") ! ----- ADD USER TO THIS DATABASE ----- ! ----- (CALL CHANGE TO DELETE ANY ----- ! ----- POSSIBLE OLD USER DATA) ----- TEMP = NUSER_OTHER( & "CHANGE_DB_USER", & THE_DB, TEMPLATE_DB + TEMPLATE) ELSE ! ADDING A 4GL DATABASE ACCESS: ! ----- REMOVE THE LEADING "F" ----- THE_DB = RIGHT(THE_DB, 2%) PRINT "Granting user access" + & " to the " + & TRM$(FOUR_GL) + " " + & THE_DB + " database..." ! ----- GRANT THIS USERNAME THE ----- ! ----- 4GL IDENTIFIER ----- THE_IDENT = FOUR_GL_PREFIX + THE_DB TEMP = GRANT_IDENTIFIER("", FALSE, "") END IF NEXT ! ----- ALSO GRANT ADDITIONAL IDENTIFIERS ----- OTHER_INDEX = 0% WHILE OTHER_INDEX < OTHER_IDENTIFIERS_CTR OTHER_INDEX = OTHER_INDEX + 1% THE_IDENT = OTHER_IDENTIFIERS(OTHER_INDEX) SELECT OTHER_IDENTIFIERS_GD(OTHER_INDEX) CASE "G" ! GRANT ! ----- GRANT THIS USERNAME THE ----- ! ----- IDENTIFIER ----- TEMP = GRANT_IDENTIFIER("", FALSE, "") END SELECT NEXT CASE "D" ! IF DELETING AN EXISTING USER: IF OTHER_NODE THEN PRINT PRINT " *************************" + & "*************************" + & "**************************" PRINT " Since this username has an" + & " account on other nodes, no " & + TRM$(DBMS_PRODUCT) + & " access will be" PRINT " deleted, since this may" + & " affect the user's account" + & " on the other node." PRINT PRINT " Also, no UIC identifier" + & " will be removed, until" + & " this user has been deleted" PRINT " from ALL of the nodes." PRINT PRINT " To delete the " + & TRM$(DBMS_PRODUCT) + & " access, you must delete" + & " this user's account from ALL of" PRINT " the nodes." PRINT " *************************" + & "*************************" + & "**************************" HELD_IDENT_INDEX = HELD_IDENTS_CTR SLEEP 1% ELSE HELD_IDENT_INDEX = 0% END IF PRINT ! ----- DELETE THIS USER FROM ALL DATABASES ----- ! ----- THAT HE/SHE/IT HAS ACCESS TO ----- WHILE HELD_IDENT_INDEX < HELD_IDENTS_CTR HELD_IDENT_INDEX = HELD_IDENT_INDEX + 1% HELD_IDENT = TRM$(HELD_IDENTS_STR( & HELD_IDENT_INDEX)) ! ----- SKIP IF NOT A DATABASE IDENTIFIER ----- ITERATE IF LEN(HELD_IDENT) <> 6% OR & NOT DBMS_EXISTS ITERATE IF LEFT(HELD_IDENT, 3%) <> DBMS_PREFIX ! ----- EXTRACT DATABASE NUMBER ----- THE_DB = RIGHT(HELD_IDENT, 4%) ! ----- SKIP IF "ASK_STATUS_nnn" IS NOT ----- ! ----- ONLINE NOR BATCH ----- ITERATE IF BAD_ASK_STATUS_VALUE(THE_DB) PRINT "Removing user access from the " & + THE_DB + " database..." ! ----- TRY TO REMOVE THIS USER FROM THE ----- ! ----- SECURITY DATABASE ----- ! ----- (IGNORE ERROR IF USER DOES NOT ----- ! ----- EXIST) ----- TEMP = NUSER_OTHER("DELETE_DB_USER", THE_DB, "") NEXT ! ----- IF THE USER'S DIRECTORY TREE IS TO BE ----- ! ----- DELETED: ----- IF DIRDEL = "Y" THEN ! ----- DELETE THE DIRECTORY TREE FOR ----- ! ----- THIS USER ----- CALL DELETE_USER_DIRECTORY END IF ! ----- REMOVE ANY DISK QUOTA FOR THIS USER ----- TEMP = DISK_QUOTA("DELETE") ! ----- REVOKE ALL IDENTIFIERS FROM THIS USER ----- ! ----- (REQUIRES HELD_IDENTS() TO CONTAIN THE ----- ! ----- HELD IDENTIFIER VALUES FOR THIS USER) ----- THE_IDENT = "*" TEMP = REVOKE_IDENTIFIER IF NOT OTHER_NODE THEN ! IF USER IS ONLY ON THIS NODE: ! ----- REMOVE THE UIC-BASED IDENTIFIER ----- ! ----- FOR THIS USER (CLUSTER-WIDE) ----- THE_IDENT = TRM$(ENTERED_USERNAME) TEMP = REMOVE_IDENTIFIER("") END IF ! ----- DELETE THIS USER'S SYSUAF RECORD FROM THIS ----- ! ----- NODE (AND ALL DUPLICATE NODES) ----- TEMP = DELETE_SYSUAF_RECORD CASE "R", "N" ! CHANGING TO [NON-]RESTRICTED ! ----- CALCULATE LIST OF DUPLICATE NODES TO ----- ! ----- CHANGE THE FLAG ON ----- DEFAULT_NODE = "" ! NULL STRING FOR DEFAULT NODE CALL SYS$EXIT(ERROR_WITH_NO_PUTMSG BY VALUE) & IF CALC_DUPL_NODES(DEFAULT_NODE) ! ----- FOR EACH DUPLICATE NODE TO BE ACCESSED: ----- NODE_INDEX = 0% WHILE NODE_INDEX < NODES_IN_MEMORY NODE_INDEX = NODE_INDEX + 1% A_NODE = NODE_LISTS(NODE_INDEX) ! ----- FOR EACH POSSIBLE SYSUAF: ----- I_O_CHNL_SYSUAF = 0% ! ----- FOR EACH OPEN SYSUAF FILE: ----- WHILE I_O_CHNL_SYSUAF < SYSUAF_COUNTER I_O_CHNL_SYSUAF = I_O_CHNL_SYSUAF + 1% ! ----- SKIP IF SYSUAF UNAVAILABLE ----- ITERATE IF TRM$(SYSUAF_SPECS( & I_O_CHNL_SYSUAF)) = "" ! ----- SKIP IF UNDESIRED NODE ----- ITERATE IF A_NODE <> & TRM$(SYSUAF_NODES( & I_O_CHNL_SYSUAF)) ! ----- CALCULATE THE REAL I/O ----- ! ----- CHANNEL ----- SYSUAF_CHNL = I_O_CHNL_SYSUAF + 49% ! ----- RE-READ THIS USER'S SYSUAF ----- ! ----- RECORD ----- RECORD_FOUND = TRUE WHEN ERROR IN GET #SYSUAF_CHNL, & KEY #0% EQ USER_NAME USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF IF ERR = REC_NOT_FOUND THEN RECORD_FOUND = FALSE CONTINUE END IF EXIT HANDLER END WHEN IF NOT RECORD_FOUND THEN PRINT PRINT "Someone just" + & " deleted the" +& " record for " +& TRM$( & ENTERED_USERNAME) + BEL ELSE SELECT USER_ACTIONS( & ACTION_INDEX) CASE "R" ! ----- SET ----- ! ----- RESTRICTED ----- ! ----- (2^3) AND ----- ! ----- DISMAIL ----- ! ----- (2^7) ----- ! ----- FLAGS ----- FLAGS(0%) = & FLAGS(0%) OR & -120% LOGIN_COMMAND_FILE_LENGTH& = LEN( & TRM$( & LGICMD_RESTRICTED)) LOGIN_COMMAND_FILE = & TRM$( & LGICMD_RESTRICTED) UPDATE #SYSUAF_CHNL UNLOCK #SYSUAF_CHNL PRINT PRINT "User " + & TRM$( & ENTERED_USERNAME)& + " has been" & + " changed" + & " to " + & "Restricted..." CASE "N" ! ----- CLEAR ----- ! ----- RESTRICTED ----- ! ----- (2^3) AND ----- ! ----- DISMAIL ----- ! ----- (2^7) ----- ! ----- FLAGS ----- FLAGS(0%) = & FLAGS(0%) AND & NOT -120% LOGIN_COMMAND_FILE_LENGTH& = LEN( & TRM$( & LGICMD_NON_RESTRICTED)) LOGIN_COMMAND_FILE = & TRM$( & LGICMD_NON_RESTRICTED) UPDATE #SYSUAF_CHNL UNLOCK #SYSUAF_CHNL PRINT PRINT "User " + & TRM$( & ENTERED_USERNAME)& + " has been" & + " changed" + & " to non-" + & "Restricted..." END SELECT END IF NEXT NEXT CASE "P" ! IF CHANGING PASSWORD: ! ----- CHANGE THE PASSWORD BACK TO THE USERNAME ----- ! ----- ON ALL DUPLICATE NODES, UNLESS OVERRIDDEN ----- ! ----- BY A PRIVILEGED USER ----- CALL CHANGE_USER_PASSWORD(OTHER_NODE) CASE "F" ! CHANGE ACCESS TO DIV-SPECIFIC PRINT ! ----- REVOKE THE PREVIOUS DIVISIONAL IDENTIFIER ----- ! ----- FROM THIS USER ----- THE_IDENT = DIV + DIVISION_ACCESS TEMP = REVOKE_IDENTIFIER IF DIVISIONAL_IDENT <> "" THEN ! ----- GRANT THIS USERNAME THE ----- ! ----- APPROPRIATE DIVISIONAL IDENTIFIER ----- THE_IDENT = DIVISIONAL_IDENT TEMP = GRANT_IDENTIFIER("", FALSE, "") END IF PRINT "Changing user's access to" + & " divisional-specific files..." CASE "G" ! IF GRANTING ACCESS: ! ----- GRANT ACCESS TO OTHER DATABASES ----- CALL GRANT_OR_DENY_OTHER(NODE_LIST) CASE "X" ! IF DENYING ACCESS: ! ----- DENYING ACCESS TO OTHER DATABASES ----- CALL GRANT_OR_DENY_OTHER(NODE_LIST) CASE "T" ! IF CHANGING TEMPLATE: ! ----- CHANGING SECURITY DATABASE ----- ! ----- TEMPLATE ACCESS ----- PRINT IF DEBUG_MODE THEN PRINT "DEBUG>OTHER_IDENTS_CTR="; & OTHER_IDENTS_CTR END IF OTHER_INDEX = 0% WHILE OTHER_INDEX < OTHER_IDENTS_CTR OTHER_INDEX = OTHER_INDEX + 1% THE_DB = TRM$(OTHER_IDENTS(OTHER_INDEX)) TEMPLATE_DB = OTHER_IDENTS_DB(OTHER_INDEX) TEMPLATE = OTHER_IDENTS_TEMPLATE(OTHER_INDEX) IF DEBUG_MODE THEN PRINT " DEBUG>THE_DB="; & THE_DB; ", TEMPLATE="; & TRM$(TEMPLATE); & ", LEN(THE_DB)="; LEN(THE_DB) END IF ! ----- SKIP IF NOT CHANGING A DATABASE ----- ITERATE IF LEN(THE_DB) <> 3% PRINT "Changing user access to the " + & TRM$(DBMS_PRODUCT) + " " + & THE_DB + " database..." ! ----- ENSURE THAT THIS USERNAME ----- ! ----- ALREADY HOLDS THE DATABASE ----- ! ----- IDENTIFIER ----- THE_IDENT = DBMS_PREFIX + THE_DB ERROR_IF_UNHELD = TRUE TEMP = GRANT_IDENTIFIER("", & ERROR_IF_UNHELD, THE_DB) ! ----- SKIP IF USER DOES NOT CURRENTLY ----- ! ----- HAVE ACCESS TO THIS DATABASE ----- ITERATE IF NOT ERROR_IF_UNHELD ! ----- TRY TO CHANGE THIS USER TO THE NEW ----- ! ----- SECURITY DATABASE ----- ! ----- TEMPLATE (IGNORE ERROR IF USER ----- ! ----- ALREADY EXISTS OR TEMPLATE DOES ----- ! ----- NOT EXIST) ----- TEMP = NUSER_OTHER( & "CHANGE_DB_USER", THE_DB, & TEMPLATE_DB + TEMPLATE) NEXT CASE "I", "Q", "Z" ! ADD/GRANT/DENY/DELETE IDENT ! ----- ADD, GRANT, DENY, OR DELETE ADDITIONAL ----- ! ----- IDENTIFIERS ----- PRINT OTHER_INDEX = 0% WHILE OTHER_INDEX < OTHER_IDENTIFIERS_CTR OTHER_INDEX = OTHER_INDEX + 1% THE_IDENT = OTHER_IDENTIFIERS(OTHER_INDEX) SELECT OTHER_IDENTIFIERS_GD(OTHER_INDEX) CASE "A" ! ADD ! ----- ADD THIS IDENTIFIER ----- ENTERED_USERNAME = THE_IDENT ! ----- ZERO THE UIC TO INDICATE ----- ! ----- THAT THIS IS A ----- ! ----- NON-UIC-BASED IDENTIFIER ----- OCT_UIC_GROUP = 0% OCT_UIC_MEMBER = 0% TEMP = ADD_IDENTIFIER(FALSE) CASE "G" ! GRANT ! ----- GRANT THIS USERNAME THE ----- ! ----- IDENTIFIER ----- TEMP = GRANT_IDENTIFIER("", FALSE, "") CASE "D" ! DENY ! ----- REVOKE THE IDENTIFIER FROM ----- ! ----- THIS USER ----- TEMP = REVOKE_IDENTIFIER CASE "X" ! DELETE ! ----- SET FLAGS TO REMOVE ----- ! ----- IDENTIFIER FROM ALL ----- ! ----- CLUSTER NODES ----- OTHER_NODE = FALSE ! ----- DELETE THIS IDENTIFIER ----- TEMP = REMOVE_IDENTIFIER("") END SELECT NEXT CASE "U" ! CHANGE ACCOUNT NAME (DEPT NO) ! ----- CHANGE THE ACCOUNT NAME (DEPARTMENT) FOR ----- ! ----- THIS USERNAME ON ALL CLUSTER-WIDE NODES ----- I_O_CHNL_SYSUAF = 0% ! ----- FOR EACH OPEN SYSUAF FILE: ----- WHILE I_O_CHNL_SYSUAF < SYSUAF_COUNTER I_O_CHNL_SYSUAF = I_O_CHNL_SYSUAF + 1% ! ----- SKIP IF SYSUAF UNAVAILABLE ----- ITERATE IF TRM$(SYSUAF_SPECS( & I_O_CHNL_SYSUAF)) = "" IF DEBUG_MODE THEN PRINT "DEBUG> Process SYSUAF" & + " #" + NUM1$(I_O_CHNL_SYSUAF) END IF ! ----- CALCULATE THE REAL I/O CHANNEL ----- SYSUAF_CHNL = I_O_CHNL_SYSUAF + 49% SYSUAF_RECORD_FOUND = TRUE WHEN ERROR IN GET #SYSUAF_CHNL, KEY #0% EQ USER_NAME USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF IF ERR = REC_NOT_FOUND THEN SYSUAF_RECORD_FOUND = FALSE CONTINUE END IF EXIT HANDLER END WHEN ITERATE IF NOT SYSUAF_RECORD_FOUND ! ----- STORE THE NEW ACCOUNT NAME (DEPT) ----- ACCOUNT_NAME = ENTERED_ACCT IF DEBUG_MODE THEN PRINT "DEBUG>Change " + & TRM$(ACCOUNT_DESC) + & " to " + ENTERED_ACCT END IF UPDATE #SYSUAF_CHNL UNLOCK #SYSUAF_CHNL NEXT PRINT PRINT "The " + TRM$(ACCOUNT_DESC) + & " has been changed for " + & TRM$(ENTERED_USERNAME) + "..." CASE "O" ! CHANGE OWNER NAME ! ----- CHANGE THE OWNER NAME FOR THIS USERNAME ----- ! ----- ON ALL CLUSTER-WIDE NODES ----- I_O_CHNL_SYSUAF = 0% ! ----- FOR EACH OPEN SYSUAF FILE: ----- WHILE I_O_CHNL_SYSUAF < SYSUAF_COUNTER I_O_CHNL_SYSUAF = I_O_CHNL_SYSUAF + 1% ! ----- SKIP IF SYSUAF UNAVAILABLE ----- ITERATE IF TRM$(SYSUAF_SPECS( & I_O_CHNL_SYSUAF)) = "" IF DEBUG_MODE THEN PRINT "DEBUG> Process SYSUAF" & + " #" + NUM1$(I_O_CHNL_SYSUAF) END IF ! ----- CALCULATE THE REAL I/O CHANNEL ----- SYSUAF_CHNL = I_O_CHNL_SYSUAF + 49% SYSUAF_RECORD_FOUND = TRUE WHEN ERROR IN GET #SYSUAF_CHNL, KEY #0% EQ USER_NAME USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF IF ERR = REC_NOT_FOUND THEN SYSUAF_RECORD_FOUND = FALSE CONTINUE END IF EXIT HANDLER END WHEN ITERATE IF NOT SYSUAF_RECORD_FOUND ! ----- STORE THE NEW OWNER NAME ----- IF ENTERED_FIRST = "" AND ENTERED_LAST = "" THEN OWNER_NAME_LENGTH = 0% OWNER_NAME = "" ELSE OWNER_NAME_LENGTH = & LEN(ENTERED_FIRST) + & LEN(ENTERED_LAST) + 2% OWNER_NAME = ENTERED_LAST + & ", " + ENTERED_FIRST END IF IF DEBUG_MODE THEN PRINT "DEBUG>Change Owner to " & + TRM$(OWNER_NAME) END IF UPDATE #SYSUAF_CHNL UNLOCK #SYSUAF_CHNL PRINT "Changed first, last name for " + & TRM$(ENTERED_USERNAME) + " on " & + TRM$(SYSUAF_NODES( & I_O_CHNL_SYSUAF)) + "..." NEXT PRINT END SELECT PRINT PRINT NEXT ! MAIN PROGRAM LOOP... ! ----- DONE ----- CLOSE #98% ! CLOSE ANY TERMINAL FILE CLOSE #99% ! CLOSE ANY SEQUENTIAL FILE TEMP = 0% WHILE TEMP < RIGHTSLIST_COUNTER ! FOR EACH OPEN RIGHTSLIST: TEMP = TEMP + 1% CLOSE #TEMP ! CLOSE THE OPEN RIGHTLIST FILE NEXT TEMP = 0% WHILE TEMP < SYSUAF_COUNTER ! FOR EACH OPEN SYSUAF FILE TEMP = TEMP + 1% SYSUAF_CHNL = TEMP + 49% CLOSE #SYSUAF_CHNL ! CLOSE THE OPEN SYSUAF FILE NEXT ! ----- DO THE ROLLBACK/UNBIND FOR ANY DATABASE ----- TEMP = NUSER_OTHER("ROLLBACK", "", "") ! ----- NO MESSAGE IF ONLY ALLOWED TO CHANGE CLUSTER-WIDE ----- ! ----- PASSWORD ----- IF HELD_DIVS_CTR <> 0% OR HELD_DBS_CTR <> 0% OR PRIVILEGED THEN PRINT "Done..." END IF END