[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

OpenVMS Programming Concepts Manual


Previous Contents Index

32.3 Rights Database

The rights database is an indexed file containing two types of records that define all identifiers: identifier records and holder records.

One identifier record appears in the rights database for each identifier. The identifier record associates the identifier name with its 32-bit binary value and specifies the attributes of the identifier. Figure 32-4 depicts the format of the identifier record.

Figure 32-4 Format of the Identifier Record


One holder record exists in the rights database for each holder of each identifier. The holder record associates the holder with the identifier, specifies the attributes of the holder, and identifies the UIC identifier of the holder. Figure 32-5 depicts the format of the holder record.

Figure 32-5 Format of the Holder Record


The rights database is an indexed file with three keys. The primary key is the identifier value, the secondary key is the holder ID, and the tertiary key is the identifier name. Through the use of the secondary key of the holder ID, all the identifiers held by a process can be retrieved quickly when the system creates the process's rights list.

32.3.1 Initializing a Rights Database

You initialize the rights database in one of the following ways:

  • When a system is installed
  • With the Authorize utility
  • With the SYS$CREATE_RDB system service

When you call SYS$CREATE_RDB, you can use the sysid argument to pass the system identification value associated with the rights database. If you omit sysid, the system uses the current system time in 64-bit format. If the rights database already exists, SYS$CREATE_RDB fails with the error code RMS$_FEX. To create a new rights database when one already exists, you must explicitly delete or rename the old one.

You can specify the location and name of the rights database by defining the logical name RIGHTSLIST as a system logical name in executive mode; its equivalence string must contain the device, directory, and file name of the rights database.

The file RIGHTSLIST.DAT has the protection of (S:RWED,O:RWED,G:R,W).

In order to use SYS$CREATE_RDB, write access to the database is necessary. If the database is in SYS$SYSTEM, which is the default, you need the SYSPRV privilege to grant write access to the directory.

When SYS$CREATE_RDB initializes a rights database, system-defined identifiers, which describe the environment in which a process can operate, are automatically created.

To add any other identifiers to the rights database, you must define them with the Authorize utility or with the appropriate system service.

32.3.2 Using System Services to Affect a Rights Database

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

  • Identifier binary value
  • Identifier name
  • Holders of each identifier
  • Attribute of each identifier and each holder of each identifier

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 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 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


Previous Next Contents Index