This chapter describes how to setup GemStone users, file permissions, and interprocess connections to ensure users have access while protecting files from unauthorized access. This chapter describes OS-level access security; GemStone login security is described in Chapter 6.
Overview
an introduction to the GemStone processes and network objects that facilitate distributed GemStone systems.
The NetLDI
explains GemStone’s Network Long Distance Information process, and how it works within the system.
NetLDI configuration
describes the options for configuring the NetLDI.
File Permissions
the permissions for executable and data files work with the NetLDI modes to allow secure access for authorized users.
Linked Gem Sessions
managing access for linked sessions that do not use the NetLDI.
As a multiuser system, GemStone must allow applications running under different UNIX userIds to log in and perform work, while ensuring that the disk files and other resources are protected against unauthorized access or modification, inadvertent as well as intentional. There are a number of ways to configure process ownership and disk file access depending on your security requirements.
At the simplest level, with a single UNIX user on a single private node, nothing else is needed after installation. Configuring secure file and process access becomes important when you have multiple users, on a shared system, with critical or sensitive data.
In addition to OS-level process and file access, users must also authenticate with GemStone as described in Chapter 6, and object-level permissions provide additional data security as described in the Programming Guide. This chapter is concerned with configuring the processes and files that make up a GemStone installation.
The topics that must be considered include:
This may involve both the ownership and file permissions for the NetLDI executable, and the options that are specified when starting up the NetLDI.
Unless you are on a single-user system, or a system with no security concerns, it is recommended to create an administrative UNIX user account to install GemStone and run shared processes. This chapter assumes that you have defined such a user, and in the examples this user is gsadmin. The actual administrative userId you create is up to you.
The examples also use gsgroup to specify a UNIX group, that includes all UNIX users that will use GemStone.
When logging in to GemStone, client applications provide a number of login parameters:
For example, Topaz lets you set these values:
topaz> set gemstone nodeName
topaz> set hostusername hostUserName
topaz> set hostpassword hostPwd
topaz> set gemnetid !#netldi:netldiName!gemnetobject
These are all used by RPC logins; for a Linked login, only the Stone name and GemStone credentials are required.
During an RPC login, an initial request goes to the NetLDI with instructions to fork the Gem process. This request includes the host credentials and the gem script (the other login parameters are used later, by the Gem to login to the Stone).
The host username is used, along with the NetLDI configuration, to determine how to set the owner of the forked Gem process. The owner of the Gem process is important since the Gem needs to be able to open the extent files, and attach to the shared page cache, operations which should not be available to unauthorized users.
You can avoid specifying the host username and password for each login by configuring the system to run without host authentication, or by using Kerberos. While in some cases using a .netrc may work, the .netrc is inherently insecure and is not supported.
GemStone NetLDIs (Network Long Distance Information) are responsible for spawning processes and providing information about GemStone processes on a given node. They are a key element connecting a distributed system together, and as such, require care to ensure that their services are available to all authorized users, but secure against unauthorized use.
In a distributed system, each node where the Stone or an RPC Gem runs must have its own NetLDI process running. NetLDIs are also required on mid-level cache nodes and to support some remote utilities.
You start a NetLDI by invoking the startnetldi command (described here). The NetLDI, in turn, starts Gem and other processes on demand.
The NetLDI listens for all requests on a single, fixed TCP/IP port, selected either by querying the OS using getservbyname(), as provided by the startnetldi -P argument, or by randomly selecting an available unreserved port.
Client applications can then access the NetLDI either by name (either specifying the name, or relying on the default NetLDI name) or by using the port number directly.
During the installation process, you are instructed on configuring your system to allow NetLDIs to be accessed by name. This involves adding the NetLDI name to the network services database (which can be the /etc/services file), and assigning a port number. The default name of the NetLDI process is gs64ldi. You may define your own NetLDI name instead, or in addition to gs64ldi, and include multiple NetLDI names with different reserved ports.
Your login parameters and command line access can then specify the NetLDI by name, for example:
[oboe]$ startnetldi mynetldi
topaz> set gemstone !@oboe#netldi:mynetldi!devstone
To access NetLDIs by name, either gs64ldi or your own name, the same name and port must be defined on every node, including nodes that do not need to run NetLDI; for example, client applications on Windows. This allows client nodes to reference a NetLDI by name during login.
To avoid the need to update the network services database, you can instead access NetLDIs by port.
If startnetldi uses the -P option to specify a port, or uses a number in the port range (1024 to 65535) instead of a name, then this will be used as the listening port, provided it is not already in use. If a port is not specified in the services database, nor by the -P option, nor by name, then the NetLDI will select a port at random. This port number can be used in login parameters, but since every time the NetLDI is restarted it will select a new port number and require changing the parameters, this is impractical in most cases. You can determine the NetLDI’s port in this case by looking at the results of gslist -l.
These examples show several ways you could start the NetLDI, then use the port number in the login parameters. The differences between the startnetldi commands is in what name is assigned, which (if not also added to the services database), does not affect the login parameters.
[oboe]$ startnetldi 10382
[oboe]$ startnetldi -P 10382
[oboe]$ startnetldi -P 10382 mynetldi
topaz> set gemstone !@oboe#netldi:10382!devstone
The GEMSTONE_NRS_ALL environment variable provides a convenient way to set a default name or port number to access the NetLDI.
By setting this environment variable across nodes and users, access to the NetLDI from commands such as startnetldi and stopnetldi, and the parameters for login requests, will automatically use the correct NetLDI.
$ GEMSTONE_NRS_ALL=#netldi:mynetldi
$ export GEMSTONE_NRS_ALL
For more information about GEMSTONE_NRS_ALL, see Appendix C, “Network Resource Strings (NRS)”.
When determining the way you will configure the NetLDI, there are two decisions that need to be made: which UNIX userId will own the processes that the NetLDI forks, and what categories of requests require authentication. Each of these has several options, and the answers to the questions can combine in several ways.
There are two usual solutions:
Both of these solutions provide multi-user access and appropriate security. The details of how to set up these solutions are described later, under Setting up the NetLDI Configuration.
The next sections go into more detail on the decisions that need to be made before you can select the right configuration.
During an RPC login, the client application passes along GemStone login parameters, including the name of the stone, the GemStone userId, and so on. These are sent to the NetLDI to perform the steps of the login.
These login parameters include fields for the host UserId, and the host password. If the host userId is left empty, the UNIX userId of the client application is used.
When the NetLDI receives the request, as part of login it forks a Gem process. The NetLDI configuration determines whether the owner of the Gem process will be the UserId that is provided with the login parameters, or an administrative user.
The owner of the Gem process is important since the Gem needs to be able to open the extent files, and attach to the shared page cache. While it is more intuitive to have Gem processes owned by individual userIds, that requires that each of these individual userIds have write permission to on the extent files, usually by being part of a group that has access.
In default mode, an ordinary user such as the administrative user, starts and owns the NetLDI process. Regardless of authentication level, all logins must provide the UNIX userId and password of the account that started the NetLDI, since a non-root user cannot fork processes that belong to another user.
This is generally suitable only for single-user systems or systems in which no additional UNIX-level authentication is required, since anyone that can login has sufficient information to access all parts of the GemStone installation.
In Root mode, the NetLDI process is owned by the root user. This allows individual spawned processes to be owned by individual userIds; since root user can fork processes that will be owned by any user.
To setup root mode, the owner of the netldid process is changed to root, and the setuid bit is set. The NetLDI can be started by any user with access permission to the executable, and the NetLDI will run with an effective UserId of root.
Either secure or default authentication is required when the NetLDI is running in root mode. Guest authentication mode is disallowed in this mode.
In captive account mode, all forked Gem processes are owned by a specific administrative user Id.
To specify captive account, pass the name of the designated account as an argument when starting the NetLDI, using the -a argument.
While technically it is possible to run the NetLDI as root and also startup in captive account, this provides no new capabilities so is not normally done.
Captive account is designed to be used with Guest mode, as described in the next section.
The effect of captive account mode is much like setuid method, but it only affects ownership of processes started by the NetLDI, not linked applications invoked directly by the user.
A disadvantage for some applications is that the Gem session process will perform all I/O as that account, not as the account running the application; including file operations and System class >> performOnServer:.
Also, captive account mode affects all services started by the NetLDI, including any ad hoc processes, which are processes started from the user’s home directory. (The NetLDI looks in the user’s home directory if it cannot find a service listed in $GEMSTONE/sys/services.dat.) If you prefer, you can prohibit such ad hoc services by specifying the -n option when starting the NetLDI.
Linked sessions do not use a separate Gem Session; the Gem is integrated into the client process. The owner of the client application process therefore needs to have the appropriate access.
For consistency with RPC sessions started by the NetLDI, If you are running with captive account, this means using ownership and the setuid bit for the client application executables, to ensure client applications run as the administrative user.
The Netldi can be configured to require authentication for all requests, for only process fork requests, or to not require authentication for any requests. Process fork requests include forking new Gems to support login; other kinds of requests includes information, such as Stone name and gslist results.
In secure mode, all accesses, including requests for information such as waitstone and gslist, as well as process forks such as logins, require authentication. In secure mode, authentication is needed before a Gem or Stone can start a page server to access an extent or shared page cache on another node.
This mode is configured by the -s argument when starting the NetLDI.
In this mode, PAM (Pluggable Authentication Modules) is used to access user authentication, though the actual means of authentication, such as LDAP, depends on how your system administrators have configured your UNIX installation.
In this mode, all requests to the NetLDI must include HostUserId and HostPassword.
In fork mode, which is the default, only process forks require authentication. Anyone can make informational requests such as gslist. This is the default mode if another authentication mode is not specified.
In this mode, GemStone login parameters must include HostUserId and HostPassword.
In either Secure or Fork mode, the authentication can be done using Kerberos to bypass the need to enter the HostUserId and HostPassword.
For authentication to succeed, there must be a currently valid ticket (TGT) associated with a principle for the UNIX user id that the NetLDI is authenticating as.
In guest mode, no host authentication is required (GemStone login still requires authentication, of course). PAM is not needed. If userIds other than the user that starts the NetLDI will be logging in, this is used in combination with captive account.
This is configured by the -g argument when starting the NetLDI. You do not need to include HostUserId/HostPassword; if the HostUserId is included, it will be used when determining ownership of the Gem process.
Table 4.1 shows how guest mode and captive account mode combinations affect NetLDI operation.
As described in the previous sections, there are two common combinations of features that configure the NetLDI for secure multi-user accessibility.
To run the NetLDI with an effective UserId of root, you can change the ownership of the NetLDI executable, and set the S bit (setuid). This allows any user with execute permissions to start the NetLDI and let that NetLDI run as root.
If you are logged in as root when you run the GemStone installation program, it offers to set the ownership and permissions for the NetLDI. To set them manually, do the following as root:
# cd $GEMSTONE/sys
# chown root netldid
# chmod u+s netldid
The resulting file permissions and ownership for the NetLDI executable should look similar to this:
-r-sr-xr-x 1 root gsgroup 2007036 Mar 7 11:29 netldid
In this mode, PAM (Pluggable Authentication Modules) is used to authenticate, and the system should either configure a service with the name gemstone.netldi, or ensure that the default PAM authentication will allow logins. The actual means of authentication, such as LDAP, depends on how your system administrators have configured your UNIX installation.
When you start the NetLDI, you may choose to authenticate all requests by including the
-s argument to startnetldi, or omit that argument and only authenticate requests for process forks. Using the -g for guest mode is not allowed with the NetLDI running as root.
Your application’s login interface will generally let you specify a UNIX login name and password for the node on which you will be running an RPC Gem session process. For example, Topaz lets you set these values:
topaz> set hostusername HostUserName
topaz> set hostpassword HostPwd
GemBuilder for Smalltalk (GBS) provides similar fields in its login dialog, as does GsExternalSession, and other interfaces provide ways to enter this information.
NOTE
Authentication is always done using the “real” user id, not the effective user id as set by the S bit on GemStone executables.
These fields are used to compose instructions in NRS syntax to be sent to the NetLDI. For example, if you set the Topaz login parameters HostUserName and HostPwd, the application puts them in an NRS like the following:
'!@Server#auth:HostUserName@HostPwd!gemnetobject'
Although it is less convenient for ordinary use, this can be done manually, by entering the authorization modifier directly using the Topaz GemNetId parameter. For example:
topaz> set gemnetid !@Server#auth:HostUserName@HostPwd!gemnetobject
When NRS is used to login using GsExternalSession, you can compose the NRS programmatically using the kernel class GsNetworkResourceString. See the Programming Guide for more on External Sessions, and the classes in the image.
The NetLDI can be configured to use Kerberos for authentication for the hostUserId/hostPassword.
To configure Kerberos authentication for NetLDI:
The -k option cannot be used with guest mode; no authentication is done in guest mode.
To configure guest mode with captive account, do the following
If you do not already have one, create an OS account to own the GemStone distribution tree and serve as the captive account. This will be referred to as gsadmin.
1. Make gsadmin the owner of the distribution tree
2. Set the setuid bit for any linked GemStone executables that run on the server node.
3. Make the repository extents accessible only by gsadmin (mode 600). For instructions, see How To Set Up a Raw Partition.
4. Make sure that gsadmin has execute permission for $GEMSTONE/sys/netldid.
The setgid bit should NOT be set on the netldid executable ; it should look similar to this:
-r-xr-xr-x 1 gsadmin gsadmin 674488 Mar 7 11:29 netldid
The considerations in setting file permissions is the same as in configuring the NetLDI; to protect the repository extents, while ensuring that authorized users can use the repository.
All reads and writes to the extents should be done through GemStone repository executables: the executables that run the Stone, Page Servers, and Gems.
This does not include file copy backups of the GemStone extents, nor restore if that is needed. These are OS level operations that also require protection.
For the tightest security, you can have the extents and executables owned by a single UNIX account, using the setuid bit on the executable files, and making the extents writable only by that account. This way, all processes started from any of the executables are owned by a single user, and only that user can write the extent files.
While most processes that write files such as fileouts and programmatic backups will set the ownership of the resulting file to the client user, this may not be possible for linked sessions in client applications, if the client application does not distinguish between real userId and effective userId.
If this is an issue, rather than using the administrative account, you can make the extents writable by a particular UNIX group and have all users belong to that group. While this means all Gems are owned by the individual user accounts, there is the risk of inadvertent damage or deletion of the extent files.
When all extents and executables are owned and can only be written by a single UNIX account, it provides the strongest security. By setting the setuid bit, the processes started from that executable are owned by the owner you specify for the file.
Table 4.2 shows the recommended file settings. In this table, gsadmin and gsgroup can be any ordinary UNIX account and group (do NOT use the root account for this purpose). The person who starts the Stone must be logged in as gsadmin or have execute permission.
Ownership and permissions for the netldid executable depend on the authentication mode chosen, and are discussed in Chapter 3.
If you are logged in as root when you run the GemStone installation program, it offers to set file protections in the manner described in Table 4.2. To set them manually, do the following as root:
# cd $GEMSTONE/sys
# chown gsadmin gem pgsvr pgsvrmain stoned
# chmod u+s gem pgsvr pgsvrmain stoned
# cd $GEMSTONE/data
# chown gsadmin extent0.dbf
# chmod 600 extent0.dbf
You must take similar steps to provide access for repository linked clients, which is described under Linked Gem Sessions.
For sites that prefer not to use the setuid bit, the alternative is to make the extents writable by a particular UNIX group and have all users belong to that group. That group must be the primary group of the person who starts the Stone (that is, the one listed in /etc/passwd). Do the following, where gsgroup is a group of your choice:
% cd $GEMSTONE/data
% chmod 660 extent0.dbf
% chgrp gsgroup extent0.dbf
Sites that run linked sessions may also prefer to use this protection so that fileouts and other I/O operations that do not read or write the repository will be done using the individual user’s id instead of the single gsadmin account.
The shared memory and semaphore resources used by GemStone are created and owned by the user account under which the Stone repository monitor is running and have the same group membership. Access for the shared page cache is set by the SHR_PAGE_CACHE_PERMISSIONS configuration option; by default, it is read-write for the owner and read for the group (the equivalent of file protection 640). You can inspect the cache ownership and permissions by using the ipcs command.
For a session to log in using a shared page cache, the OS user account of the linked application or Gem session process must either be the same as that of the Stone (such as the gsadmin account) or be one that belongs to the same group as the Stone. The same requirement applies to page server processes, which are discussed in Chapter 5, “Connecting Distributed Systems”.
If the setuid bit is set on repository executables, the Stone process and shared page cache will belong to the owner you specify for those files (such as gsadmin).
GemStone creates log files and other special files in several locations. In a multi-user environment, the protection of these resources must be such that the appropriate file can be created or updated in response to actions by several users.
/opt/gemstone/locks
All users should be able to read files in the directory /opt/gemstone/locks on each node (or an equivalent location, as discussed here).
/opt/gemstone/log
Users who will start a NetLDI process require read, write and execute access to /opt/gemstone/log, if this directory is used for logging.
system.conf
The user who owns the Stone process must have write permission to the configuration file, since the Stone must be able to write as well as read its primary configuration file. Writes are made if an extent is added while the Stone is running, so that subsequent restart will be correct. By default, this file is $GEMSTONE/data/system.conf.
$HOME
GemStone by default creates log files for session processes, such as RPC Gems, in the home directory of the user owning the Gem. This may be the owner of the Gem executable, or the user specified for the NetLDI’s captive account.
An alternate location can be specified using NRS syntax. This NRS can be included in the login parameters, or defined by GEMSTONE_NRS_ALL. See Controlling log file names and locations.
GemStone supports both RPC logins, in which the Gem is a separate process from the client application, and linked logins, in which the Gem is in the client application process.
The above discussions of executable permissions are focused on the issues with RPC logins, which are facilitated by the NetLDI. For linked logins, however, the client application, which could be topaz, client Smalltalk such as VisualWorks or VA/Smalltalk, Pharo, GemBuilder for Java, a GCI Application, or something else, is also involved.
For linked applications on the server, we recommend you use the setuid bit on the application’s executable file, and have the file owned by an administrative user, gsadmin. This works well for linked topaz logins. The installgs script offers to set the file ownership and permissions for you. To do it manually, do this (you may need to login or sudo as root):
# cd $GEMSTONE/bin
# chmod u+s topaz
# chown gsadmin topaz
GemStone’s topaz executable performs repository reads and writes as the effective user (the account that owns the executable’s file), but performs other reads and writes as the real user (the one who invoked it).
For linked applications that do not distinguish between real and effective user IDs, you may prefer not to use the setuid bit. Linked applications that do not make this distinction are likely to perform all I/O as the effective user, or gsadmin. In this case, it may be preferable to remove the S bit on that executable and add group write permission to the extents.