next up previous contents index
Next: 14. Ovrimos Files and Up: Ovrimos version 3.0 On-line Previous: 12. Database Maintenance

Subsections

  
13. Database Security

The security of data is an important and sensitive issue. It is also a multi-faceted subject, ranging from data integrity, to prevention of physical hostile actions.

This chapter describes the following security issues as addressed by Ovrimos:

  
13.1 Data Integrity

Ruling out failure or hostile actions, Data Integrity may be compromised in two ways: either by violating semantic integrity or by violating transaction atomicity. Ovrimos prevents both of these mishaps by enforcing integrity checks and by endorsing transaction atomicity.

   
13.1.1 Semantic Integrity

Semantic Integrity in Ovrimos is obtained by defining and enforcing Integrity constraints. An integrity constraint is a conditional expression that is required not to evaluate to false.

The following integrity constraints are currently enforced by Ovrimos:

  
13.1.1.0.1 Domain constraints

Domain constraints are turned into column constraints to the columns belonging to this domain during table creation.

The following is a very simple example, of defining a domain and using this domain to constrain the values of a particular column of a table.

Example:
CREATE DOMAIN natural integer
check value
> 0;

CREATE TABLE alpha (
...,
serial_number natural,
...
);

See also B.4.2.(Create Table in Ovrimos SQL).

  
13.1.1.0.2 Table constraints

Table constraints are set at table creation.

Table constraints are defined as:

  
13.1.1.0.3 Check constraints

A check constraint takes the following form:

CHECK (conditional-expression)

These constraints are checked during insert and update statements.

Example:
CREATE TABLE alpha (
...,
payment integer,
commission integer,
...,
CHECK (commission
< 0.15*payment)
);

The check constraint on insert and on update can only refer to the affected table rows, not to the whole table. In particular, the check expression should not refer to the table as a whole when its result depends on the row inserted or updated. At this point, it is not possible to make a SELECT in the same table where the INSERT or UPDATE is taking place.

See also B.4.2.(Create Table in Ovrimos SQL).

  
13.1.1.0.4 Candidate keys

All unique keys are candidate keys. One of these candidate keys is defined as primary key . There can be no NULL values in any component of a candidate key.

Ovrimos examines the row and allows insertion or update only when it complies to this rule.

Example:
CREATE TABLE alpha (
product_id integer PRIMARY KEY,
product_serial integer UNIQUE,
...
);

In the example above, the column product_id is the primary key, while column product_serial is a candidate key (because it is defined as unique).

See also B.4.2.(Create Table in Ovrimos SQL).

  
13.1.1.0.5 Foreign keys

A foreign key is a column (or a list of columns) belonging in a table and referencing a candidate key of another table. Referential integrity requires that the values found in these columns correspond to existing values in the referred table.

It is permitted to have NULL values in a foreign key (unless otherwise specified at column definition). If any one component of a foreign key is NULL, the entire foreign key is considered as NULL (i.e. it does not reference a row in the referenced table).

Example:
CREATE TABLE beta (
...
main_product_id integer REFERENCES alpha(product_id),
...
);

The above main_product_id REFERENCES alpha(product_id) is a shorthand for the statement:

main_product_id integer,
FOREIGN KEY (main_product_id)
REFERENCES alpha(product_id)

In the example above, column main_product_id is a foreign key that references product_id, the primary key of table alpha.

You can see more on table creation in the examples of section B.4.(Supported SQL Statements.)

Finally, a few shortcomings on referential integrity:

There are no default values.
Foreign key constraints are now enforced only when INSERTing. One can only insert a row when the primary key referenced exists in the primary table. No control is exercised, though, when DELETE'ing or UPDATE'ing the primary key. This violates the constraint that "all candidate keys referenced by a foreign key exist in the referred table".

This is a shortcoming expected to be removed in Ovrimos Gold release.

13.1.1.0.6 Other constraints

Besides the candidate key constraint for NOT NULL, columns, other than key components, may be defined as NOT NULL. This constraint, which has a special SQL support, is checked during insertion or update to ensure that the row complies to the rule.

Example:
CREATE TABLE alpha (
...
product_name varchar(40) NOT NULL,
...
);

The above product_name varchar(40) NOT NULL is a shorthand for:
product_name varchar(40)
check (product_name is NOT NULL)

At creation time, column product_name is defined as NOT NULL. This column is not a candidate key. It is simply a column that should not contain NULL values (possibly due to application constraints).

Since having NULL values in this column violates the constraint, both insert and delete statements on the row are checked, to make sure the constraint is satisfied.

    
13.1.2 Transaction Atomicity

The notion of a transaction is extremely important in Ovrimos. All data manipulation  and many data definition  actions are executed in the environment of a transaction.

13.1.2.0.1 Transactions

An SQL transaction is a sequence of operations that is guaranteed to be atomic for recovery purposes. Every transaction terminates by executing either a COMMIT (normal termination)  or a ROLLBACK (abnormal termination) .

To get an idea of the benefits of a transaction, suppose we have the following simple scenario:

User U1 requests object A
User U1 updates object A
User U1 requests object B
User U1 updates object B
...

User U1 does not want the updates made thus far.

At this point, even if the user is alone, there is a problem. The user must undo all the updates made thus far. If the updates were made in the enveloping environment of a transaction, these updates would not be made permanent to the database, but they would be kept together as a unit. They would be made permanent when the user decided that the result was the desired. In this case, if the result is not the desired one, the user may use ROLLBACK and undo all the updates. If the result is the desired, COMMIT makes the updates permanent.

The situation is even more complicated if other users, running concurrently, have access to the same objects and make their own updates at the time. Whose updates would user U1 undo? What if another user deleted some of the objects U1 uses? What would the situation be should a power failure occur in the middle of such a complicated interaction?

Transactions are employed to alleviate some of these problems.

If a transaction T1 and a transaction T2 are running concurrently (i.e. there is interleaved execution of T1 and T2), these transactions are required to be serializable, in the sense that the result of running them concurrently must be the same as executing them one at a time. Since this requirement is very strict, there are options to loosen this restriction.

   
13.1.2.0.2 Isolation levels

Even when transactions are employed, to guarantee atomicity, it is obvious that some kind of data locking is required for two reasons:

1.
For consistency
The data available to one user are not modified (by another user) until the first user completes any transaction with these data.

2.
For integrity
The data in the database files must reflect the updates made to them.

Ovrimos performs data locking at the row level, but there are many isolation levels, as we will see below. If no locking is done, three unwanted conditions may arise in the process of concurrent data access and modification by client requests.

1.
Dirty Read (reading of non-existing or incorrect data) 
Suppose there is a transaction T1. T1 updates a row X.

Another transaction, T2, retrieves the updated row X.

T1 is rolled back and all its updates are canceled.

T2 has performed a Dirty Read, because it has retrieved something that does not exist.

2.
Non-repeatable Read 
Suppose there is a transaction T1. T1 retrieves one row.

Suppose there is a second transaction, T2, which updates this row and commits.

During the same transaction T1, the same row is retrieved, but with a different value. T1 has performed a Non-repeatable Read, since it fails to retrieve twice the same value from the row.

3.
Phantoms (sudden appearance of previously non-existing data) 
Suppose there is a transaction, T1, which selects, during a query, a set of rows, all of them satisfying a certain predicate or condition.

Suppose there is a second transaction, T2, which inserts a row, that also happens to satisfy the predicate used by T1.

T1 performs the same query and accesses a set of rows, which contains a row that was not there before.

Now T1 has read a Phantom.

To avoid all these abnormal situations, four isolation levels have been implemented, according to the SQL standard. These isolation levels are:

Each isolation level puts on transaction data interaction more severe restrictions than the previous one. The locking in Ovrimos is made on the table row level. There are two different kinds of locks:

Locks expire automatically at the end of the transaction.

The four isolation levels are achieved with the use of the locks in the following way:

1.
READ UNCOMMITTED 
For any kind of update, a write-lock on the object is necessary.

For reading, no lock is required. Therefore, uncommitted objects are visible (dirty read).

2.
READ COMMITTED 
For any kind of update, a write-lock on the object is necessary.

For reading, a wait is required until no write-locks are held on the object. This ensures that no object, that is not yet committed, will be read. Thus, the Dirty Read is avoided. It is possible though to have a Non-repeatable Read.

3.
REPEATABLE READ 
For any kind of update, a write-lock on the object is necessary.

For reading, a read-lock is required on the object. This ensures that repeated readings on the same object will bring the same value. Thus, the Non-repeatable Read is avoided.

4.
SERIALIZABLE 
Same as in REPEATABLE READ, with the difference that visible objects are now only those timestamped before the beginning of the transaction. This ensures that no phantoms are ever read.

13.1.2.0.3 Expected behavior of Ovrimos Transactions

The following tables describe how certain conditions arise when transactions T1 and T2 run concurrently. They are only informative examples and are by no means exhaustive of all the possible combinations of transaction interaction.

Only the isolation level of the second transaction is considered, because in the discussion below, it is the one affected by the actions of the first. The dashed line indicates an idle (or blocked) transaction.

Read Uncommitted allows Dirty Read

Transaction T1 Transaction T2
START  
updates row  
----- START (READ UNCOMMITTED)
----- retrieves updated
rolls back -----

Transaction T2 has read an (uncommitted) object which was rolled back, and in a sense never existed. This is a case of a Dirty Read.

When the Isolation Level is set to READ COMMITTED, a Dirty Read cannot occur, as the following examples indicate.

Read Committed prevents Dirty Read

Transaction T1 Transaction T2
START  
updates row  
----- START (READ COMMITTED)
  blocks retrieving uncommitted objects
rolls back unblocks, retrieves old

A write-lock is held on the updated object. Thus, T2 is blocked. As expected, by READ COMMITTED, when T1 rolled back, T2 read the old object.

Transaction T1 Transaction T2
START  
updates row  
----- START (READ COMMITTED)
  blocks retrieving uncommitted objects
commits unblocks, retrieves new

A write-lock is held on the updated object. Thus, T2 is blocked. As expected by READ COMMITTED, when T1 committed, T2 read the new object.

Both REPEATABLE READ and SERIALIZABLE isolation levels perform correctly (since their restrictions are more severe than READ COMMITTED).

Dirty Read is only one of the undesirable situations that may occur in a concurrent environment. Next, we address the Non-Repeatable Read case.

Read Uncommitted allows Non-repeatable Read

Transaction T1 Transaction T2
START  
updates row  
----- START (READ UNCOMMITTED)
  retrieves existing
updates object -----
----- retrieves new

Since T2 read different data from the same object during the same transaction, we have a case of Non-Repeatable read.

Read Committed allows Non-repeatable Read

Transaction T1 Transaction T2
----- START (READ COMMITTED)
  retrieves existing
updates -----
----- blocks retrieving uncommitted objects
commits unblocks, retrieves new

Transaction T1 Transaction T2
----- START (READ COMMITTED)
  retrieves existing
updates -----
----- blocks retrieving uncommitted objects
rolls back unblocks, retrieves old

In the cases above, when T1 committed, there was a case of Non-repeatable Read, while when T1 rolled back, there was no such occurrence. This is not desirable. The following example is a case of Repeatable Read.

Repeatable Read prevents Non-repeatable Read

Transaction T1 Transaction T2
----- START (REPEATABLE READ)
  retrieves existing
blocks updating -----
unblocks and updates commits/rolls back

When, T2 runs in Isolation Level REPEATABLE READ, it places a write-lock, which blocks other transactions from accessing objects, used by T2.

Obviously, when T2 is run in Isolation Level SERIALIZABLE, which puts more severe restrictions on concurrency, there can be no case of Non-repeatable read.

The following is an example of phantom row appearance.

Read Uncommitted allows Phantom appearance

Transaction T1 Transaction T2
----- START (READ UNCOMMITTED)
  retrieves existing rows
inserts new row -----
----- retrieves rows+new row

Transaction T2 has read a row that did not exist before.

Read Committed allows Phantom Appearance

Transaction T1 Transaction T2
----- START (READ COMMITTED)
  retrieves existing rows
inserts new row -----
----- blocks retrieving uncommitted objects
commits unblocks and retrieves rows+new row
or rolls back unblocks and retrieves rows
  without old row

Depending on the final action of T1 (commit or Roll back), T2 either retreats a row that did not exist before or does not.

Repeatable Read allows Phantom Appearance

Transaction T1 Transaction T2
----- START (REPEATABLE READ)
  retrieves existing rows
inserts new row -----
----- retrieves old rows without new row
commits -----
----- retrieves old rows+new row

Even REPEATABLE READ is not enough to prevent the phantom appearance. In the example above, T2 does not see the phantom row until T1 commits, but eventually, it does retrieve data that did not exist before.

Serializable prevents Phantom appearance

Transaction T1 Transaction T2
----- START (SERIALIZABLE)
  retrieves existing rows
inserts new row -----
----- retrieves old rows without new row
commits -----
----- retrievies old rows without new row

All three possible concurrency anomalies are removed when the SERIALIZABLE Isolation Level is set.

The server mechanism for acquiring and releasing locks during a transaction has a growing phase, where it acquires locks and a shrinking phase, where it releases locks. During the growing phase, no locks are released. This is equivalent to the two-phase locking protocol.

Ovrimos examines the lock requests, depending on the prevailing conditions. If it is not possible to grant a lock immediately, the request is not rejected at once. Instead, a wait indication is placed in the waiting queue with the hope that the other short transactions will commit their actions and release the requested objects.

When locks are used, another undesirable situation may arise, deadlock. A deadlock  is a cycle of interdependencies, produced when a connection holds some objects and waits for a requested object, which may be locked by another connection. Although a deadlock is not a violation of data integrity, it is a detrimental situation and has to be prevented.

In order to prevent a deadlock , a graph of interdependencies is created, which is checked every time a request is candidate for the waiting list. If the insertion results in a cycle, then the request is immediately rejected.

Anyway, a request for wait may not be served for a long time if the other transactions do not release the locked objects.

  
13.1.2.0.4 Nested Transactions

The transaction is basic in all data management of Ovrimos. Commit and Rollback are used with their classical meanings and they are not described any further.

Transactions are executed under the following rules:

Picture 13.1 shows the transaction nesting.


  
Figure 13.1: Nested Transactions
\includegraphics{transactions}

The pseudocode below describes the nesting.

T1 is an example of a transaction without nesting. T2, which contains nested transactions, may be described by the following pseudocode:

Start T2
...
    Statements of T2
...
    Start T3
	...
	    Statements of T3
	...
    Commit T3

	Start T4
	...
	    Statements of T4
	...
	    Start T5
		...
		Commit T5
	...
	Commit T4
...
Commit T2

The nested transaction mechanism is implemented internally, but it is not yet available to the user through the existing SQL Terminal interface. It may be used in SQL Query Tool by the (undocumented) Nest statement. It is possible to use nesting in C and C++ applications through the Ovrimos C, C++ library. You may contact support@ovrimos.com for more information.

  
13.2 Data Recovery

Data recovery from power failure, user error, or media damage is based on backup and restore procedures, which are facilitated through the use of a log  file.

The log is used to record all actions performed to the database. Actions recorded on the log are based on transactions. The beginning and end points of a transaction, as well as the actions on the database objects, are recorded on the log and used for a possible rolling back of open transactions.

The log is particularly useful when on-line backup is taken. Since a previous backup exists and the log is always updated by Ovrimos, it is possible to take a backup at any time without halting the database. The previous backup and the log will be used in combination if data recovery is required.

It is strongly recommended to take frequent backups. We also advise users to keep their log and backup directories on a separate volume.

See also 12.(Database Maintenance).

    
13.3 Data Encryption

Data files are protected from casual inspection (i.e. reading a disk file with a binary editor) by a built-in scrambling algorithm. With the exception of BLOBs, all database objects reside in tables. Table data are scrambled.

Extra protection, through data encryption, is offered to Ovrimos database managers for each database separately, at creation time. If users opt for encrypting the database, they may choose an encryption algorithm and they must supply the name of a binary file that holds at least the number of bytes required for the key. It is best to specify a file on removable media (diskette, tape, etc), that can be safekept elsewhere after database loading. The key must be supplied every time the database is started.

The parameters defined in database creation are mentioned in 4.(Database Manager). There is also a description of parameter CIPHER in A.2.2.(Database Parameters).

Encryption algorithms used by this version are:

13.3.0.0.1 BLOBs and URLs

It is true that BLOBs have URLs and, potentially, anybody can access them through a Web browser. URLs should be treated as confidential, like every other piece of information one retrieves from the database.

There is little chance that someone will find the BLOB address by trying URLs at random, since the BLOB URL is based on a random number from 1 to 232-1.

13.4 Authentication

Only authenticated users are allowed to view and modify database objects or data. Authentication is achieved through the combination of a User Name  and a Password .

  
13.4.1 Login Authentication

There are two different kinds of users for Ovrimos.

The Database Manager user, is a person with Database Management privileges. There is only one such user for all Ovrimos databases in one installation. This is user dbman. User dbman may create and delete databases. This user may also edit database parameters.

User dbman is authenticated through the use of a password. The dbman password is initially pass  .
We strongly recommend that you change this password the first time you log into the Database Manager.
The maximum length of the dbman password is 60 characters. See more about the Database Manager in chapter 4.(The Database Manager).

The other category of Ovrimos users are database users. Each database has an administrator with full privileges over all database objects. This is user admin. User admin may create other database users and has authority over these users. The database administrator may be different from the Database Manager. The administrator of one Ovrimos database is not necessarily the administrator of another Ovrimos database.

For every database created, there is always a user admin, with full privileges and a user public, without password, with minimal privileges. Other users, created with administrator privileges, have privilege over data not users.

User public is created without a password and is not allowed to log in. For the use of public, see 13.4.5.(Privilege Inheritance).

    
13.4.2 Passwords and Password Policy

Every time a database is created, including the tetsbase, user admin is also created with password pegasus  .
We strongly recommend that you change this password the first time you log into the newly created database.

Users may change their password (provided that this is permitted by the $USERPOLICY), using the following statement:

UPDATE USER username WITH 'new-password';

Example:
UPDATE USER admin WITH 'nebula';

As always, the password is case sensitive.

It is also possible to update the password with NULL, in which case the user may no longer login to the database, until a new password is assigned to him/her. The administrator may use a full version of the update command which is:

UPDATE USER identifier [FOR 'user name']
[WITH 'password'][LIKE identifier]
[USING 'attribute=value;attribute=value;...'];

Passwords are strings of alphanumeric characters. The maximum length of a password is 89 characters.

Every user, except admin is allowed to update only his/her own password. Even this is not always the case, as we will immediately see. Ovrimos enforces a password policy, to allow a certain degree of password protection. The password policy is set at creation time and at any other time, when required, by dbman (the user who creates and edits the database). Restrictions, currently enforced on passwords may be any of the following:

Parameter USERPOLICY, set by dbman, holds all information about user passwords. All users except admin are subject to USERPOLICY.

User admin may by-pass these rules and set his/her own password as well as other users' passwords regardless of the existing USERPOLICY. Ovrimos issues warning messages, when the rules are broken, but accepts the administrator's updates, nevertheless.

See A.2.2.(Database Parameters) and 4.(The Database Manager). For more information about setting password policy.

Also, user dbman, who is not a database user, is not subject to the rules of password policy.

   
13.4.3 Unauthorized Logins

The database admin is notified by e-mail about unauthorized logins.

Ovrimos sends the following two mail messages to the administrator's specified mailbox address (see also MAILBOX) in case of failed logins:

  
13.4.4 User Privileges

Database users have a varied degree of privileges, ranging from full administrator privileges to minimal privileges. Users without passwords are not even allowed to log in.

Privileges on database objects are granted to users through the Grant SQL statement and revoked through the Revoke SQL statement.

In the case of privileges, database objects are tables and views (treated as tables) and table columns, while privileges are the privilege to select from a table and delete from a table, to insert data into the table columns, to update all or particular columns of a table and to modify foreign keys.

Privileges may be granted with a grant option, in which case the user may grant them to other users. See more on Grant and Revoke in B.4.(Supported SQL Statements).

   
13.4.5 Privilege Inheritance

Administration of users in Ovrimos databases is performed with simple statements. One extra feature, found in Ovrimos SQL, is the option of Privilege Inheritance. Specific users can be designated as prototype users, typically with a NULL password that disallows logging in. Users created LIKE this user, inherit his/her privileges. This makes it easy to administer privileges for groups of people with a simple grant/revoke to/from the prototype user. This hierarchy can be extended to as many levels as we wish. In the future, multiple inheritance will allow the SQL3 "roles" to be implemented. Following are the user administration statements:

Other users may be created with the following statement:

CREATE USER username FOR 'Full Name' WITH 'user password';

Example:
CREATE USER mary FOR 'Mary' WITH 'xyz123';

Full syntax is:
CREATE USER username FOR 'full name'
with 'password'|NULL [like prototype-user]
[USING 'attribute=value;...'];

Example:
CREATE USER mary FOR 'Mary' WITH 'xyz123'
LIKE john USING 'mailbox=Mary@xyzzy.com';

In this case, user mary has inherited all privileges from user john.

User public may be granted with a certain 'typical' set of privileges that will normally be granted to many users. User public will then be used as follows:

Example:
GRANT Select, Delete, ... ON TABLE tabname
TO PUBLIC;

... Other grant statements.

CREATE USER Kendal FOR 'Kendal Eridani'
WITH 'xyz' LIKE public;

It is also possible to create a user LIKE admin. This user has administrative privileges on database objects, not on database users. Thus, only admin may create, update or drop other users.

  
13.5 Secure Socket Layer

In tandem with modern application demands and offerings in cryptographic technology, Ovrimos comes with support for Public-Key Infrastructure:

1.
Ovrimos Certificate Manager is a tool that

2.
Ovrimos Database Manager is enhanced to support SSL-based network security for both the Database Manager itself and the databases it handles. The following can be configured:

3.
Open SSL is a free open-source general purpose command-line tool for performing various cryptographic operations, mainly relating to files.

Of course, no system is fail-safe if human factors are not taken into account. Users must be familiar with the Certificate Manager and follow the proper procedures. See more about certificates in 4.5.

   
13.5.1 Local Certification Authorities

If your organization wishes to issue certificates, without requesting the services of specialized outside organizations such as Verisign, Thawte, Bellsign etc., it should create a local certification authority, (LCA for short) .

If the certificates it issues are not only for internal use within the organization, a self-signed LCA is probably all that is needed. In such cases all parties involved in secure communications with Ovrimos should be configured to trust this LCA. Of course, a server certificate issued by a self-signed LCA would be quite inapropriate for a Web site for the general public such as an e-commerce Web site. Since the self-signed LCA will not be trusted outside the organization, Web browsers will not be able to verify the identity of the Web site.

Another solution, probably the most cost effective, would be to buy a certificate for the Web server signed by a globally trusted external CA, such as Verisign, Thawte, Belsign etc., and use a self-signed LCA for all internal host and client certificates. If you want some user certificates to be trusted outside your organization you can always purchase them seperately by a globally trusted External Certification Authority (ECA for short) .

The fact that an ECA has a good reputation and many products, such as Web browsers, are preconfigured to trust it, does not imply you should trust it within your organization. In some situations you should not.

Another option you have for your LCA, is to have it signed by a globally trusted ECA. Servers machines and personal certificates signed by the LCA will be trusted by the general public. However, internally, in your organization, you may still choose to trust only your LCA and not its signer, which means that you are not putting any part of your internal security infrastructure in the hands of the external CA.

Finally, you should note that you can have more than one LCA. For example, you may create an LCA, which in turn will sign you other LCAs. Big CAs do exactly that. This enables them to use the secondary LCAs for every day signing operations while the private key of the primary LCA is only used once or twice a year.

There is a problem with describing security-related software, as it is not necessarily used by security experts. Setting up and managing an Public-Key Infrastructure is a very sensitive duty. While Certificate Manager makes certain tasks easy for the security conscious system administrator, who is not necessarily a security expert, that does not imply that Certificate Manager is enough in security sensitive installations. We have given some possible scenarios which a security conscious system administrator may consider for setting up a Public Key Infrastructure (PKI for short). However, one should not be misled into thinking that because the most powerful computers of intelligence agencies can not break the kind of cryptography supported by Ovrimos, that by installink a PKI, they prevent a teenage hacker breaking into their systems taking advantage of well-known security holes or an employee taking advantage of a colleague's lunch break to use their computer and authorization to obtain sensitive information or make changes to some database. Security experts can advise not only on how to best utilize a PKI, but also how to avoid traditional attacks. If your data is sensitive, you need their expertise, more than you need a 4096 bit private key.


next up previous contents index
Next: 14. Ovrimos Files and Up: Ovrimos version 3.0 On-line Previous: 12. Database Maintenance