Extension Point for Server Security

Printer-friendly version

This is informal user documentation for a new 10.2 feature that provides the ability to plug in code that implements security restrictions on certain server administration operations.

Contents

Purpose

This feature lets you provide plugin code to implement security restrictions on certain administration operations. You can provide code to prevent an unauthorized user from:
  • Stopping a lock server, advanced multithreaded server (AMS), or query server
  • Getting exclusive locks on databases or federated databases (exclusive locks are needed for creating, deleting, or moving such entities)

Note: Future Objectivity versions can extend this feature to control additional security operations.

Prevent Server Shutdown

Your plugin code can prevent unauthorized use of the following administrative tools that stop servers:

  • ookillls
  • oostopams
  • ooqueryserver -stop

Note: This feature is not currently available for AMS on Windows platforms or for the in-process lock server on any platform.

Prevent Exclusive Locking

Your plugin code can prevent unauthorized users from getting exclusive locks on databases or federated databases. This can prevent operations such as the following:

  • oonewfd
  • oodeletefd
  • oonewdb
  • oodeletedb

Users

This is an advanced feature for database administrators.

Conceptual Model

The affected servers provide an extension point called ServerSecurity. A plugin for this extension point implements a class derived from the ooServerAdminSecurity class. When the server receives a request for certain critical actions, it calls a virtual method of that class. Each method has a default definition that always returns true, meaning the operation is allowed. Your plugin code can override methods to prevent certain operations.

Task Descriptions

To implement a server security plugin, you need to:
  • Define a class derived from ooServerAdminSecurity.
  • Implement overrides for methods relevant to the purpose of your plugin.
  • Implement the plugin's createPlugin entry-point function to create and return an instance of the class.
  • Build the implementation code into a shared library.
  • Provide a plugin specification file entry to specify the location of the library.

Implement the Plugin

The following sample code shows how to create a NoRemoteStop class that inherits from ooServerAdminSecurity, overriding the allowStopping method. The method implementation denies requests to stop the server unless they come from the same host.

#include <ooServerSecurity.h>

class NoRemoteStop : public ooServerAdminSecurity
{
public:
  // Overriden method
  virtual bool allowStopping(ooClientIdentity & client)
    { return client.isCurrentHost(); }
};

Refer to the Reference Descriptions for more information about ooServerAdminSecurity and related classes.

Implement the Entry-Point Function

Your plugin code must also implement a global entry-point function, as shown in the following example.

...

// Plugin's entry-point function
extern "C" { 
  #ifdef _MSC_VER
  __declspec(dllexport) 
  #endif
  void* createPlugin(const char* key) { return new NoRemoteStop; }
}

Install a Plugin Specification File

Objectivity/DB uses a plugin specification file (with a .plugin suffix) to load the plugin. This file must be placed in the plugins directory of the Objectivity installation on the host running the server. Server processes started after that time automatically load and invoke the plugin.

The plugin file declares the shared library as an implementation of the ServerSecurity extension point. The file can optionally specify parameter values to pass to the plugin library.

A plugin specification for our example might look like this:

  <ObjectivityPlugins>
     <Plugin extensionPoint="ServerSecurity" enable="true">
       <CppImplementation library="NoRemoteStop.dll"/>
     </Plugin>
  </ObjectivityPlugins>

Reference Descriptions

The following definitions are in the ooServerSecurity.h header file:

class ooServerAdminSecurity
{
public:
  virtual void initialize(const char* server_name, int argc, char **argv,
                          ooPluginArguments& pluginArgs) { }
  virtual void terminate() { }
  virtual bool allowStopping(ooClientIdentity & client) { return true; }
  virtual bool allowExclusiveLock(ooClientIdentity & client, unsigned FD,
                                  unsigned DB, unsigned container)
    { return true; }
};

class ooClientIdentity
{
public:
  virtual const char *           getHostName()   = 0;
  virtual bool                   isCurrentHost() = 0;
  virtual const struct sockaddr* getHostAddress()= 0;
  virtual const char *           getUserName()   = 0;
};

class ooPluginArguments
{
public:
  virtual const char* getValue(const char* name) const = 0;
  virtual bool nextPair(const char** name, const char** value) = 0;
};

ooServerAdminSecurity Methods

The methods of the ooServerAdminSecurity class are callbacks for various events. Define overrides in your subclass as needed.

void initialize(const char* server_name, int argc, char **argv, ooPluginArguments& pluginArgs)
Called just once to provide information to the plugin. The default method does nothing.
The parameters are:
server_name
One of the following strings: "LockServer", "AMS", or "QueryServer".
argc and argv
Values from the main program provided in case they might be of use.
pluginArgs
Provides access to the parameter values from the plugin specification file.
void terminate()
Called just once when the server is shutting down. The plugin instance (ooServerAdminSecurity subclass instance) can delete itself or perform other cleanup before the process ends. The default method does nothing.

bool allowStopping(ooClientIdentity & client)
Called when the server receives a request to stop, such as ookillls or oostopams. The default method always returns true, which allows the operation. If false is returned, the server continues running and an error is returned to the requester.
The parameters are:
client
Object that provides access to identification information about the requesting client. The method may use this information in making its determination about whether or not to stop the server.
Note: Stopping a server from the Windows Service Control Manager does not go through this method.

bool allowExclusiveLock(ooClientIdentity & client, unsigned FD, unsigned DB, unsigned container)
Called when the lock server receives a request for an exclusive lock on a federation, database, or container. The default method always returns true, which allows the lock. If false is returned, the lock is denied with an error message indicating an authorization failure.
A client obtains an exclusive lock before creating, deleting, or moving the designated entity, so this method can be used to limit use of tools such as oonewfd, oodeletefd, oonewdb, or oodeletedb. Note that an exclusive lock is not used when deleting a container, so that level of control is not available.
The parameters are:
client
Object that provides access to identification information about the requesting client.
FD
Identifier for the federated database.
DB
Identifier for the database to lock or 0 to lock the entire federated database.
container
Identifier for the container or 0 to lock the entire database.

ooClientIdentity Methods

The ooClientIdentity class has the following public methods:

const char* getHostName()
Returns the name of the host sending the request. This is determined by reverse name lookup from the IP address and may not always be reliable. NULL is returned if the name cannot be determined.
const struct sockaddr* getHostAddress()
Returns the IP address of the requester.
bool isCurrentHost()
Returns true if the request is from another process on the same host.
const char* getUserName()
Returns the user name of the requesting process, or NULL if not known. Currently this is provided by oostopams and ooqueryserver, but not by ookillls.
Note: The user name is self-reported, so this information should not be trusted if the request was sent by something other than the Objectivity-provided tools.

ooPluginArguments Methods

The class ooPluginArguments has the following public methods:

const char* getValue(const char* name)
Returns the value associated with the specified name in the plugin specification file.

For example, assume you have a plugin specification file declaration like this:

<Value name="foo" value="xyz"/>

The following can be used to return the value ("xyz") that is associated with "foo".

const char* fooValue = pluginArgs.getValue("foo");

bool nextPair(const char** name, const char** value)
Iterates through the plugin specification name/value pairs.

For example:

const char* name;
const char* value;
while ( pluginArgs.nextPair(&name, &value) ) {
  ...
}

Note: Future Objectivity releases can add more methods to the ooServerAdminSecurity class to support other kinds of operations. Methods can also be added to the ooClientIdentity class as new kinds of information, such as security credentials, become available.

Backward Compatibility

ookillls from an earlier release may report a cryptic message about an unknown error code. Earlier versions of oostopams or ooqueryserver that encounter the authorization failure code will hang and must be manually killed.

Related Documentation

To learn more about the plugin framework, refer to the information about extending Objectivity/DB features in the Objectivity/DB Administration manual in your Objectivity documentation.


Last modified: October 24, 2011
Date: 
Friday, October 26, 2012
Product: 
Objectivity/DB
Version: 
10.2.1
10.2