hp.com home products and services support and drivers solutions how to buy
cd-rom home
End of Jump to page title
HP OpenVMS systems
documentation

Jump to content


HP OpenVMS Programming Concepts Manual

HP OpenVMS Programming Concepts Manual


Previous Contents Index

32.3.2 Using System Services to Affect a Rights Database

The identifier and holder records in the rights database contain the following elements:

You can use the Authorize utility or one of the system services described in Table 32-1 to add, delete, display, modify, or translate the various elements of the rights database.

Table 32-1 Using System Services to Manipulate Elements of the Rights Database
Action Element Service Used
Translate Identifier name to identifier binary value SYS$ASCTOID
  Identifier binary value to identifier name SYS$IDTOASC
Add Identifier holder record SYS$ADD_HOLDER
  New identifier record SYS$ADD_IDENT
Find Identifier value held by holder SYS$FIND_HELD
  Holders of an identifier SYS$FIND_HOLDER
  All identifiers SYS$IDTOASC
Modify Attribute in holder record SYS$MOD_HOLDER
  Attribute in identifier record SYS$MOD_IDENT
Delete Holder from identifier record SYS$REM_HOLDER
  Identifier and all its holders SYS$REM_IDENT

The following table shows what access you need for which services:
Service Required Access
SYS$ADD_HOLDER Write
SYS$ADD_IDENT Write
SYS$ASCTOID Read 1
SYS$CREATE_RDB Write 2
SYS$FIND_HELD Read 1
SYS$FIND_HOLDER Read 1
SYS$FINISH_RDB Read 1
SYS$IDTOASC Read 1
SYS$MOD_HOLDER Write
SYS$MOD_IDENT Write
SYS$REM_HOLDER Write
SYS$REM_IDENT Write


1On VAX systems, read access is required when certain restrictions are present (for example, if the identifiers have the name hidden or holder hidden attributes).
2File creation access.

32.3.2.1 Translating Identifier Values and Identifier Names

To the system, an identifier is a 32-bit binary value; however, to make identifiers easy to use, each binary value has an associated identifier name. The identifier value and the ASCII identifier name string are associated in the rights database. You can use the SYS$ASCTOID and SYS$IDTOASC system services to translate from one format to another. When you pass to SYS$ASCTOID the address of a string descriptor pointing to an identifier name, the corresponding identifier binary value is returned. Conversely, you use the SYS$IDTOASC service to translate a binary identifier value to an ASCII identifier name string.

Preventing a Translation

You can prevent a translation operation by unauthorized users by specifying the KGB$V_NAME_HIDDEN within an attributes mask.

Listing Identifiers in the Rights Database

You can also use the SYS$IDTOASC service to list the identifier names of all of the identifiers in the rights database. Specify the id argument as -1 , initialize the context argument to 0, and repeatedly call SYS$IDTOASC until the status code SS$_NOSUCHID is returned. The SYS$IDTOASC service returns the identifier names in alphabetical order. When SS$_NOSUCHID is returned, SYS$IDTOASC clears the context longword and deallocates the record stream. If you complete your calls to SYS$IDTOASC before SS$_NOSUCHID is returned, use SYS$FINISH_RDB to clear the context longword and to deallocate the record stream.

The following programming example uses SYS$IDTOASC to identify all identifiers in a rights database:


      Program ID_LIST 
 
* 
* Produce a list of all the identifiers 
* 
 
      integer SYS$IDTOASC 
      external SS$_NORMAL, SS$_NOSUCHID 
 
      character*31 NAME 
      integer IDENTIFIER, ATTRIBUTES 
 
      integer ID/-1/, LENGTH, CONTEXT/0/ 
      integer NAME_DSC(2)/31, 0/ 
 
      integer STATUS 
* 
* Initialization 
* 
 
      NAME_DSC(2) = %loc(NAME) 
      STATUS = %loc(SS$_NORMAL) 
* 
* Scan through the entire RDB ... 
* 
 
      do while (STATUS .and. (STATUS .ne. %loc(SS$_NOSUCHID))) 
 
         STATUS = SYS$IDTOASC(%val(ID), LENGTH, NAME_DSC, 
     +                           IDENTIFIER, ATTRIBUTES, CONTEXT) 
 
         if (STATUS .and. (STATUS .ne. %loc(SS$_NOSUCHID))) then 
 
            NAME(LENGTH+1:LENGTH+1) = ',' 
 
            print 1, NAME, IDENTIFIER, ATTRIBUTES 
    1       format(1X,'Name: ',A31,' Id: ',Z8,', Attributes: ',Z8) 
 
         end if 
 
      end do 
* 
* Do we need to finish the RDB ??? 
* 
 
      if (STATUS .ne. %loc(SS$_NOSUCHID)) then 
         call SYS$FINISH_RDB(CONTEXT) 
      end if 
 
      end 

32.3.2.2 Adding Identifiers and Holders to the Rights Database

To add identifiers to the rights database, use the SYS$ADD_IDENT service in a program. When you call SYS$ADD_IDENT, use the name argument to pass the identifier name you want to add. You can specify an identifier value with the id argument; however, if you do not specify a value, the system selects an identifier value from the general identifier space.

In addition to defining the identifier value and identifier name, you use SYS$ADD_IDENT to specify attributes in the identifier record. Attributes are enabled for a holder of an identifier only when they are set in both the identifier record and the holder record. The attrib argument is a longword containing a bit mask specifying the attributes. The symbol KGB$V_RESOURCE, defined in the system macro library $KGBDEF, sets the Resource bit in the attribute longword, and the symbol KGB$V_DYNAMIC sets the Dynamic bit. (You can use the prefix KGB$M rather than KGB$V.) See the description of SYS$ADD_IDENT in the HP OpenVMS System Services Reference Manual for a complete list of symbols.

When SYS$ADD_IDENT successfully completes execution, a new identifier record containing the identifier value, the identifier name, and the attributes of the identifier exists in the rights database.

When the identifier record exists in the rights database, you define the holders of that identifier with the SYS$ADD_HOLDER system service. You pass the binary identifier value with the id argument and you specify the holder with the holder argument, which is the address of a quadword data structure in the following format. Figure 32-6 shows the format of the holder argument.

Figure 32-6 Format of the Holder Argument


In the rights database, the holder identifier is in UIC format. You specify the attributes of the holder with the attrib argument in the same manner as with SYS$ADD_IDENT.

After SYS$ADD_HOLDER completes execution, a new holder record containing the binary value of the identifier that the holder holds, the attributes of the holder, and the UIC of the holder exists in the rights database.

32.3.2.3 Determining Holders of Identifiers

To determine the holders of a particular identifier, use the SYS$FIND_HOLDER service in a program. When you call SYS$FIND_HOLDER, use the id argument to pass the binary value of the identifier whose holder you want to determine. On successful execution, SYS$FIND_HOLDER returns the holder identifier with the holder argument and the attributes of the holder with the attrib argument.

You can identify all of the identifier's holders by initializing the context argument to 0 and repeatedly calling SYS$FIND_HOLDER, as detailed in Section 32.3.3. Because SYS$FIND_HOLDER identifies the records by the same key (holder ID), it returns the records in the order in which they were written.

32.3.2.4 Determining Identifiers Held by a Holder

To determine the identifiers held by a holder, use the SYS$FIND_HELD service in a program. When you call SYS$FIND_HELD, use the holder argument to specify the holder whose identifier is to be found.

On successful execution, SYS$FIND_HELD returns the identifier's binary identifier value and attributes.

You can identify all the identifiers held by the specified holder by initializing the context argument to 0 and repeatedly calling SYS$FIND_HELD, as detailed in Section 32.3.3. Because SYS$FIND_HELD identifies the records by the same key (identifier), it returns the records in the order in which they were written.

32.3.2.5 Modifying the Identifier Record

To modify an identifier record by changing the identifier's name, value, or attributes, or all three in the rights database, use the SYS$MOD_IDENT service in a program. Use the id argument to pass the binary value of the identifier whose record you want to modify. To enable attributes, use the set_attrib argument, which is a longword containing a bit mask specifying the attributes. The symbol KGB$V_RESOURCE, defined in the system macro library $KGBDEF, sets the Resource bit in the attribute longword. The symbol KGB$V_DYNAMIC sets the Dynamic bit. (You can use the prefix KGB$M rather than KGB$V.) See the description of SYS$MOD_IDENT in the HP OpenVMS System Services Reference Manual for a complete list of symbols.

If you want to disable the attributes for the identifier, use the clr_attrib argument, which is a longword containing a bit mask specifying the attributes. If the same attribute is specified in set_attrib and clr_attrib, the attribute is enabled.

You can also change the identifier name, value, or both with the new_name and new_value arguments. The new_name argument is the address of a descriptor pointing to the identifier name string; new_value is a longword containing the binary identifier value. If you change the value of an identifier that is the holder of other identifiers (a UIC, for example), SYS$MOD_IDENT updates all the corresponding holder records with the new holder identifier value.

When SYS$MOD_IDENT successfully completes execution, a new identifier record containing the identifier value, the identifier name, and the attributes of the identifier exists in the rights database.

32.3.2.6 Modifying a Holder Record

To modify a holder record, use the SYS$MOD_HOLDER service in a program. When you call SYS$MOD_HOLDER, use the id argument and the holder argument to pass the binary identifier value and the UIC holder identifier whose holder record you want to modify.

Use the SYS$MOD_HOLDER service to enable or disable the attributes of an identifier in the same way as with SYS$MOD_HOLDER.

When SYS$MOD_HOLDER completes execution, a new holder record containing the identifier value, the identifier name, and the attributes of the identifier exists in the rights database.

The following programming example uses SYS$MOD_HOLDER to modify holder records in the rights database:


      Program MOD_HOLDER 
 
* 
* Modify the attributes of all the holders of identifiers to reflect 
* the current attribute setting of the identifiers themselves. 
* 
 
      external SS$_NOSUCHID 
      parameter KGB$M_RESOURCE = 1, KGB$M_DYNAMIC = 2 
      integer SYS$IDTOASC, SYS$FIND_HELD, SYS$MOD_HOLDER 
 
* 
* Store information about the holder here. 
* 
 
      integer HOLDER(2)/2*0/ 
      equivalence (HOLDER(1), HOLDER_ID) 
      integer HOLDER_NAME(2)/31, 0/ 
      integer HOLDER_ID, HOLDER_CTX/0/ 
      character*31 HOLDER_STRING 
 
* 
* Store attributes here. 
* 
 
      integer OLD_ATTR, NEW_ATTR, ID_ATTR, CONTEXT 
 
* 
* Store information about the identifier here. 
* 
 
      integer IDENTIFIER, ID_NAME(2)/31, 0/ 
      character*31 ID_STRING 
 
      integer STATUS 
* 
* Initialize the descriptors. 
* 
 
      HOLDER_NAME(2) = %loc(HOLDER_STRING) 
      ID_NAME(2) = %loc(ID_STRING) 
 
* 
* Scan through all the identifiers. 
* 
 
      do while 
     +   (SYS$IDTOASC(%val(-1),, HOLDER_NAME, HOLDER_ID,, HOLDER_CTX) 
     +      .ne. %loc(SS$_NOSUCHID)) 
 
* 
* Test all the identifiers held by this identifier (our HOLDER). 
* 
 
         if (HOLDER_ID .le. 0) go to 2 
 
         CONTEXT = 0 
 
         do while 
     +      (SYS$FIND_HELD(HOLDER, IDENTIFIER, OLD_ATTR, CONTEXT) 
     +         .ne. %loc(SS$_NOSUCHID)) 
 
* 
* Get name and attributes of held identifier. 
* 
 
            STATUS = SYS$IDTOASC(%val(IDENTIFIER),, ID_NAME,, ID_ATTR,) 
 
* 
* Modify the holder record to reflect the state of the identifier itself. 
* 
 
            if ((ID_ATTR .and. KGB$M_RESOURCE) .ne. 0) then 
               STATUS = SYS$MOD_HOLDER 
     +                 (%val(IDENTIFIER), HOLDER, %val(KGB$M_RESOURCE),) 
               NEW_ATTR = OLD_ATTR .or. KGB$M_RESOURCE 
            else 
               STATUS = SYS$MOD_HOLDER 
     +                 (%val(IDENTIFIER), HOLDER,, %val(KGB$M_RESOURCE)) 
               NEW_ATTR = OLD_ATTR .and. (.not. KGB$M_RESOURCE) 
            end if 
 
            if ((ID_ATTR .and. KGB$M_DYNAMIC) .ne. 0) then 
               STATUS = SYS$MOD_HOLDER 
     +                 (%val(IDENTIFIER), HOLDER, %val(KGB$M_DYNAMIC),) 
               NEW_ATTR = OLD_ATTR .or. KGB$M_DYNAMIC 
            else 
               STATUS = SYS$MOD_HOLDER 
     +                 (%val(IDENTIFIER), HOLDER,, %val(KGB$M_DYNAMIC)) 
               NEW_ATTR = OLD_ATTR .and. (.not. KGB$M_DYNAMIC) 
            end if 
 
* 
* Was it successful? 
* 
 
      if (.not. STATUS) then 
         NEW_ATTR = OLD_ATTR 
         call LIB$SIGNAL(%val(STATUS)) 
      end if     
* 
* Report it all. 
* 
 
            print 1, HOLDER_STRING, ID_STRING, 
     +                  OLD_ATTR, ID_ATTR, NEW_ATTR 
    1       format(1X, 'Holder: ', A31, ' Id: ', A31, 
     +                ' Old: ', Z8, ' Id: ', Z8, ' New: ', Z8) 
 
         end do 
 
    2    continue 
 
      end do 
 
      end 

32.3.2.7 Removing Identifiers and Holders from the Rights Database

To remove an identifier and all of its holders, use the SYS$REM_IDENT service in a program. When you call SYS$REM_IDENT, use the id argument to pass the binary value of the identifier you want to remove. When SYS$REM_IDENT completes execution, the identifier and all of its associated holder records are removed from the rights database.

To remove a holder from the list of an identifier's holders, use the SYS$REM_HOLDER service in a program. When you call SYS$REM_HOLDER, use the id argument and the holder argument to pass the binary ID value and the UIC identifier of the holder whose holder record you want to delete.

On successful execution, SYS$REM_HOLDER removes the holder from the list of the identifier's holders.

32.3.3 Search Operations

You can search the entire rights database when you use the SYS$IDTOASC, SYS$FIND_HELD, and SYS$FIND_HOLDER services. You initialize the context longword to 0 and repeatedly call one of the three services until the status code SS$_NOSUCHID is returned. When SS$_NOSUCHID is returned, the service clears the context longword and deallocates the record stream. If you complete your calls to one of these services before SS$_NOSUCHID is returned, you must use SYS$FINISH_RDB to clear the context longword and to deallocate the record stream.

The structure of the rights database affects the order in which each of these services returns the records when you search the rights database. The rights database is an indexed file with three keys. The primary key is the identifier binary value, the secondary key is the holder UIC identifier, and the tertiary key is the identifier name.

During a searching operation, the service obtains the first record with an indexed OpenVMS RMS GET operation. The key used for the GET operation depends on the service. The SYS$FIND_HOLDER service uses the identifier binary value; SYS$FIND_HELD uses the holder UIC identifier. After the indexed GET, the service returns the records with sequential RMS GET operations. Consequently, the file organization, the key used for the first GET operation, and the order in which the records were originally written in the database determine the order of records returned.

Table 32-2 summarizes how records are returned by the SYS$IDTOASC, SYS$FIND_HELD, and SYS$FIND_HOLDER services when used in a searching operation.

Table 32-2 Returned Records of SYS$IDTOASC, SYS$FIND_HELD, and SYS$FIND_HOLDER
Service Record Order
SYS$IDTOASC Identifier name order.
SYS$FIND_HELD First GET operation---holder key. Subsequent records are returned in the order in which they were written.
SYS$FIND_HOLDER First GET operation---identifier key. Subsequent records are returned in the order in which they were written.

The following programming example uses SYS$IDTOASC, SYS$FINISH_RDB, and SYS$FIND_HOLDER to search the entire rights database for identifiers with holders and produces a list of those identifiers and their holders:


Module ID_HOLDER 
   (  main = MAIN, 
      addressing_mode(external=GENERAL) ) = 
begin 
 
! 
!       Produce a list of all the identifiers, that have holders, 
!       with their respective holders. 
! 
 
! 
!       Declarations: 
! 
 
   library 
 
      'SYS$LIBRARY:LIB'; 
 
   forward routine 
 
      MAIN; 
 
   external routine 
 
      LIB$PUT_OUTPUT, 
 
      SYS$FAO, 
      SYS$IDTOASC, 
      SYS$FINISH_RDB, 
      SYS$FIND_HOLDER; 
 
! 
!       To create static descriptors 
! 
 
   macro S_DESCRIPTOR[NAME, SIZE] = 
      own 
         %name(NAME, '_BUFFER'): block[%number(SIZE), byte], 
         %name(NAME): block[DSC$K_S_BLN, byte] 
                      preset( [DSC$B_CLASS] = DSC$K_CLASS_S, 
                              [DSC$W_LENGTH] = %number(SIZE), 
                              [DSC$A_POINTER] = %name(NAME, '_BUFFER') ); %; 


! 
!       Descriptors for ID, holder NAME, and output LINE 
! 
 
   S_DESCRIPTOR('ID_NAME', 31); 
   S_DESCRIPTOR('NAME', 31); 
   S_DESCRIPTOR('LINE', 76); 
 
   own 
 
      STATUS, 
 
      ID, 
      ID_LENGTH, 
      ID_CONTEXT: initial(0), 
 
      HOLDER, 
      LENGTH, 
      CONTEXT: initial(0), 
 
      ATTRIBS, 
      VALUE, 
      LINE_: block[DSC$K_S_BLN, byte] 
             preset( [DSC$B_CLASS] = DSC$K_CLASS_S, 
                     [DSC$A_POINTER] = LINE_BUFFER ); 
 
!      
!       To check for existence of an ID or HOLDER 
! 
 
   macro CHECK(EXPRESSION) = 
      (STATUS = %remove(EXPRESSION)) and (.STATUS neq SS$_NOSUCHID) %; 
 
! 
!       List all the identifiers, which have holders, with their holders. 
! 
 
   routine MAIN = 
   begin 
 
! 
!       Examine all IDs (-1). 
! 
 
      while                
         CHECK(<SYS$IDTOASC(-1, ID_LENGTH, ID_NAME, ID, ATTRIBS, ID_CONTEXT)>) 
      do 
         begin 
 
            CONTEXT = 0; 
 
! 
!       Find all holders of ID. 
! 
 
            while CHECK(<SYS$FIND_HOLDER(.ID, HOLDER, ATTRIBS, CONTEXT)>) do 
               begin 
 
! 
!       Translate the HOLDER to find its NAME. 
! 
 
                  SYS$IDTOASC(.HOLDER, LENGTH, NAME, VALUE, ATTRIBS, 0); 
 


! 
!       Print a message reporting ID and HOLDER. 
! 
 
                  SYS$FAO( %ascid'Id: !AD, Holder: !AD', 
                           LINE_[DSC$W_LENGTH], LINE, 
                           .ID_LENGTH, .ID_NAME[DSC$A_POINTER], 
                           .LENGTH, .NAME[DSC$A_POINTER] ); 
 
                  LIB$PUT_OUTPUT(LINE_); 
 
               end; 
 
         end; 
 
      return SS$_NORMAL;             
 
   end; 
 
end 
 
eludom 
 

32.3.4 Modifying a Rights List

When a process is created, LOGINOUT builds a rights list for the process consisting of the identifiers the user holds and any appropriate environmental identifiers. A system rights list is the default rights list used in addition to any process rights list. Modifications to the system rights list effectively become modifications to the rights of each process.

A privileged user can alter the process or system rights list with the SYS$GRANTID or SYS$REVOKID services. These services are not intended for the general system user. Use of these services requires CMKRNL privilege. The SYS$GRANTID service adds an identifier to a rights list or, if the identifier is already part of the rights list, the SYS$GRANTID service modifies the attributes of the identifier. The SYS$REVOKID service removes an identifier from a rights list.

The SYS$GRANTID and SYS$REVOKID services treat the pidadr and prcnam arguments the same way all other process control services treat these arguments. For more details, see the HP OpenVMS Guide to System Security.

You can also modify the process or system rights list with the DCL command SET RIGHTS_LIST. Additionally, you can use SET RIGHTS_LIST to modify the attributes of the identifier if the identifier is already part of the rights list. Note that you cannot use the SET RIGHTS_LIST command to modify the rights database from which the rights list was created. For more information about using the SET RIGHTS_LIST command, see the HP OpenVMS DCL Dictionary.


Previous Next Contents Index