ObjectStore also supports Server authentication services. See Chapter 2, Server Parameters, of ObjectStore Management for more information about access control methods.
Setting User Category Permissions
For rawfs databases, you can specify a combination of types of access to a given directory, database, or segment for a given category of users.
For file databases, you can specify a combination of types of access to a given directory or database for a given category of users. To do this, use commands of the native operating system. With file databases, a segment always has the same protections as the database that contains it; see the discussions beginning with Categories of Users.
Restricting Database Access Using Schema Keys
If you want to restrict access to a database's data and metadata, use ObjectStore's schema protection facility. This facility allows you to associate a schema key (a pair of integers) with a database. Once a database has been given a schema key, an application must supply the key in order to access data in the database. See the discussions beginning with Schema Keys.
Categories of Users
For a given directory, database, or segment there are three categories of users:
Only the owner of a segment can modify its protections with os_segment::set_access_control().
For file databases, you can specify access permissions at two levels of granularity: directory and database.
For an application to open a database for read, the user must have read permission for the database. For file databases, the user must also have read permission for the directory containing the database.
If a user does not have the appropriate permissions when opening a database for read or update, ObjectStore signals err_permission_denied.
For the application to perform write access on the segment, the user must have write permission for the segment. For file databases, the user must also have write permission for the directory containing the database that contains the segment, as well as write permission for the database.
For the application to perform read access on the segment, the user must have read permission for the segment. For file databases, the user must also have read permission for the directory containing the database that contains the segment, as well as read permission for the database.
If a user does not have the appropriate permissions when attempting initial read or write access to a segment, ObjectStore signals err_permission_denied.
Establishing Access Permissions with os_segment_access
Instances of the class os_segment_access serve to associate zero or more access types with a group of a specified name, as well as with the default group (see Categories of Users).
By associating an os_segment_access with a segment (using os_segment::set_access_control()), you specify the segment's associated primary group and the segment's permissions.
Access type enumerators
The possible combinations of access types are represented by the following enumerators:
These enumerators are used as arguments to some of the members of os_segment_access.
You must be the owner of a database to set the permissions on its segments.
For more information, see os_segment_access in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
os_segment_access::set_primary_group()
There are two overloadings of this function. The first is declared as follows:
void set_primary_group( const char* group_name, os_int32 access_type ) ;This function associates a specified combination of access types with a group of a specified name. group_name is the name of the group. access_type is os_segment_access::no_access, os_segment_access::read_access, or os_segment_access::read_write_access.
The second overloading is declared as follows:
void set_primary_group( os_int32 access_type );This function associates a specified combination of access types with a group of an unspecified name. access_type is os_segment_access::no_access, os_segment_access::read_access, or os_segment_access::read_write_access.
For more information, see os_segment_access::set_primary_group() in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
os_segment_access::get_primary_group()
This function is declared as follows:
os_int32 get_primary_group( const char** group_name = 0 ) const ;It returns the types of access associated with the primary group of the os_segment_access. The function sets group_name, if supplied, to point to the name of that group.
For more information, see os_segment_access::get_primary_group() in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
os_segment_access::set_default()
This function is declared as follows:
void set_default( os_int32 access_type );This function associates a specified combination of access types with the default group. access_type is os_segment_access::no_access, os_segment_access::read_access, or os_segment_access::read_write_access.
For more information, see os_segment_access::set_default() in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
os_segment_access::get_default()
This function is declared as follows:
os_int32 get_default() const ;It returns the types of access associated with the default group for the os_segment_access.
For more information, see os_segment_access::get_default() in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
os_segment_access::os_segment_access()
This function has three overloadings. The first is declared as follows:
os_segment_access() ;This creates an os_segment_access that associates no_access with both the default group and the group named group_name.
The second overloading is declared as follows:
os_segment_access( const char* primary_group, os_int32 primary_group_access_type, os_int32 default_access_type ) ;This creates an instance of os_segment_access that associates primary_group_access_type with the group named primary_group, and associates default_access_type with the default group. primary_group_access_type and default_access_type are each os_segment_access::no_access, os_segment_access::read_access, or os_segment_access::read_write_access.
The third overloading is declared as follows:
os_segment_access( const os_segment_access& source ) ;This creates a copy of source; that is, it creates an os_segment_access that stores the same group name, and associates the same combinations of access types with the same groups.
For more information, see os_segment_access::os_segment_access() in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
os_segment_access::operator =()
This function is declared as follows:
os_segment_access& operator= ( const os_segment_access& source ) ;This function modifies the os_segment_access pointed to by this so that it is a copy of source, that is, so that it stores the same group name as source, and associates the same combinations of access types with the same groups. It returns a reference to the modified os_segment_access.
For more information, see os_segment_access::operator =() in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
os_segment_access::~os_segment_access()
The destructor frees memory associated with the deleted instance of os_segment_access.
os_segment::set_access_control()
This function is declared as follows:
void set_access_control( const os_segment_accessThis associates the specified os_segment_access with the specified segment. The os_segment_access determines the primary group and permissions for the os_segment. You must be the owner of a database to set the permissions on its segments.
*new_access) ;
If you are not the owner of a database but nevertheless have write access to it, you have the ability to create a segment in the database but not to modify its permissions. Since newly created segments allow all types of access to all categories of users, segments created by nonowners necessarily have a period of vulnerability between creation time and the time at which the owner restricts access with os_segment::set_access_control().
For more information, see os_segment::set_access_control() in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
os_segment::get_access_control()
This function is declared as follows:
os_segment_access *get_access_control() const ;It returns a pointer to the segment's associated os_segment_access, which indicates the segment's primary group and permissions.
For more information, see os_segment::get_access_control() in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
os_database::get_all_segments_and_permissions()
This member of os_database is declared as follows:
void get_all_segments_and_permissions( os_int32 max_to_return, os_segment** segs, os_segment_access** controls, os_int32 &n_returned ) ;Provides access to all the segments in the specified database, together with each segment's associated os_segment_access. The nth element of controls points to the os_segment_access associated with the segment pointed to by the nth element of segs. The arrays controls and segs must be allocated by the user. max_to_return is specified by the user.
For more information, see os_database::get_all_segments_and_permissions() in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
Segment-Level Permissions and Locking
When you change a segment's permissions, ObjectStore locks the entire segment for write. This means that permission changes at the segment level are transaction consistent (database-level changes are not transaction consistent). But this can also adversely affect the performance of the application performing the change, as well as of concurrent applications, if there is a lot of contention for the segment's pages. Permissions and Related Segments
Remember to set the permissions on related segments in a compatible way. That is, if an operation on one segment triggers access to another segment, do not forget that both segments must have the appropriate permissions. Schema Keys
If you want to restrict access to a database's data and metadata, use ObjectStore's schema protection facility. This facility allows you to associate a schema key (a pair of integers) with a database. Once a database has been given a schema key, an application must supply the key in order to access data in the database. Database Schema Keys
At any time a database can have a schema key that consists of a pair of four-byte unsigned integers. By default, a database has no schema key. You specify a key for a database with os_database::change_schema_key(). You can also freeze the schema key of a given database, preventing any change to the key, even by applications with a matching key. You do this with os_database::freeze_schema_key(). See Schema Key API.
If a database has a schema key, it can only be accessed by an application that supplies a matching schema key. See Application Schema Keys as well as Key Mismatch.
Application Schema Keys
As is the case with ObjectStore databases, ObjectStore applications can have a schema key that consists of a pair of four-byte unsigned integers. By default, an application has no current schema key. You specify a key for an application with objectstore::set_current_schema_key(). See Schema Key API. For ObjectStore tools and for ObjectStore utilities executed from the command line, you specify the schema key with environment variables. See Schema Key Environment Variables.
Key Mismatch
When an application first attempts to access the data or metadata of a protected database (one with a schema key), an err_schema_key is signaled if the application has no key or has a different key from the database. ObjectStore issues an error message like the following:
Error using schema keys <err-0025-0151>The schema is protected and the key, if provided, did not match the one in the schema of database db1. (err_schema_key)If the database's open count goes to 0 and then is increased to 1 again, the schema protection key is checked again at the first attempted access. In general, the schema protection key is checked at the first attempted access after each database open that increments the open count from 0 to 1.
If an application is linked with a version of ObjectStore that does not support schema protection, and the application tries to access a database with a schema key, err_uninitialized is signaled. ObjectStore issues an error message like the following:
The database is uninitialized. <err-0025-0508>The database db1 is corrupted or uninitialized. Possibly the transaction that created this database aborted. Use osrm to remove the database, and try again. (err_uninitialized)
Caution when using the oscp utility
In the case of the oscp utility , however, specifying the correct key can nevertheless affect the operation's result. If you specify the correct key, the copy has a different db_id from the original; otherwise, the copy has the same db_id as the original. In either case, the copy has the same key as the original, and the copy's key is frozen if and only if the original's is. For more information on the oscp utility, see oscp: Copying Databases in Chapter 4, Utilities, of ObjectStore Management.
Schema Key API
The programming interface for schema protection is provided by the following functions:
void change_schema_key( os_unsigned_int32 old_key_low, os_unsigned_int32 old_key_high, os_unsigned_int32 new_key_low, os_unsigned_int32 new_key_high ) ;Call this function from within an update transaction. The specified database must be opened for update, otherwise ObjectStore signals err_opened_read_only, and issues an error message like the following:
<err-0025-0155> Attempt to change the schema key of databaseIf the database has had its key frozen, err_schema_key is signaled, and ObjectStore issues an error message like the following:
db1, but it is opened for read only.
err_schema_key <err-0025-0152> The schema key of database db1 is frozen
and may not be changed.
Error using schema keys <err-0025-0158>Unable to change schema key of database db1. The schema is already protected and the key provided did not match the old key in the schema. (err_schema_key)If the database has no schema key, old_key_low and old_key_high are ignored.
For more information, see os_database::change_schema_key() in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
Setting Application Schema Keys with set_current_schema_key()
The function objectstore::set_current_schema_key() can be used to set or unset the schema key of the current application. This function is declared as follows:
void objectstore::set_current_schema_key( os_unsigned_int32 key_low, os_unsigned_int32 key_high ) ;Call this function only after calling objectstore::initialize(), otherwise err_schema_key is signaled and ObjectStore issues an error message like the following:
<err-0025-0153> The schema key may not be set until after
objectstore::initialize has been called.
If an application has not called this function, its key is determined by the values of OS_SCHEMA_KEY_HIGH and OS_SCHEMA_KEY_LOW (see Schema Key Environment Variables). If neither variable is set, the application has no current schema key.
For more information, see objectstore::set_current_schema_key() in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
Freezing a Database Key with freeze_schema_key()
Use os_database::freeze_schema_key() to freeze a database's key, preventing any change to the key, even by applications with a matching key. This function is declared as follows:
void os_database::freeze_schema_key( os_unsigned_int32 key_low, os_unsigned_int32 key_high ) ;Call this function from within an update transaction. The specified database must be opened for update, otherwise ObjectStore signals err_opened_read_only, and issues an error message like the following:
<err-0025-0156> Attempt to freeze the schema key of database db1, but it is opened for read only.If the database is schema protected and has not been accessed since the last time its open count was incremented from 0 to 1, the application's schema key must match the database's schema key. If it does not, err_schema_key is signaled, and ObjectStore issues an error message like the following:
<err-0025-0159>Unable to freeze the schema key of database db1. The schema is protected and the key provided did not match the key in the schema.
If the database's schema key is already frozen, and you specify the correct key, the call has no effect.
For more information, see os_database::freeze_schema_key() in Chapter 2, Class Library, of the ObjectStore C++ API Reference.
Schema Key Environment Variables
If you run certain ObjectStore tools and utilities on schema-protected databases, set the ObjectStore client environment variables OS_SCHEMA_KEY_LOW and OS_SCHEMA_KEY_HIGH to specify the schema key of the databases to be accessed.
Normally, you specify a key for an application with objectstore::set_current_schema_key(). These environment variables are provided since it is not possible for you to set the schema key of a tool or utility programmatically. ObjectStore environment variables are described in Chapter 3, Environment Variables, of ObjectStore Management.
The tools and utilities for which these variables must be set include the following:
By default, neither OS_SCHEMA_KEY_LOW nor OS_SCHEMA_KEY_HIGH is set.
Updated: 03/31/98 17:03:02