Advanced Sandboxing

For more advanced control, additional sandbox paths may be specified using the API. The API functions to manipulate sandboxes are:

The server stores sandbox configuration as a mapping from username to sandbox mapping. A sandbox mapping is defined as a mapping from sandbox name to a sandbox specification. A sandbox specification can be either a simple filesystem path, or map specifying a sandbox type.

A sandbox with blank name ("") appears to the users as root (/) or the topmost level they can navigate to. There can only be one sandbox with blank name per user.

Note

Changing sandbox mappings using the setSandboxMapping() or deleteSandboxMapping() API functions does not affect logged on users. Changes will take effect the next time a user authenticates (see auth()).

If a persistent state directory has been specified, then sandbox mappings created using the API will be saved and loaded across server restarts. However, if there is a conflict between a persisted sandbox configuration and the --sandbox-dir command line option (a sandbox mapping with blank username was set), the command line option will take effect and an error will printed to the log.

Tip

When the server is started with --persistent-state-dir, the sandbox mappings will be persisted across server restarts.

There are three kinds of sandboxes:

global sandbox

Global sandboxes are specified with blank username ("") and apply to all users.

Paths specified in global sandboxes can use placeholders.

system sandbox

System sandbox is a special version of global sandbox and is specified with a blank username ("") and blank sandbox name ("").

Note

If the --sandbox-dir command line option is specified, the system sandbox can not be modified. To set the system sandbox using the API, the --sandbox-dir command line option has to be removed.

Warning

Specifying the --sandbox-dir on command line will take precendence over a persisted system sandbox configuration, and any existing system sandbox configuration will be deleted.

Paths specified in system sandboxes can use placeholders.

user sandbox

User sandboxes are attached to specific usernames, and override any other sandbox specification.

Warning

Setting the sandbox mapping for a specific user to false turns off sandboxing for that user. This allows for turning off sandboxing for selected users (for example administrators) and giving them full system access, while sandboxing everyone else.

Examples

Global And System Sandboxes

Starting the server with --sandbox-dir set to /home/%u will result in a sandbox mapping (getSandboxMappings()):

{"": {"": "/home/%u"}}

This will sandbox all users into their individual home directories. If we then update the sandbox mapping adding a data sandbox:

> api.server.setSandboxMapping("", {"data": "/data"})

We now have sandbox mapping of:

{
  "": {
    "": "/home/%u",
    "data": "/data"
  }
}

At this point, all users would have access to a second sandbox named data:/, mapped to the /data partition. Users would now observe:

  • userA:
    • / mapped to /home/%u (resolving to /home/userA)
    • data:/ mapped to /data
  • userB:
    • / mapped to /home/%u (resolving to /home/userB)
    • data:/ mapped to /data

Continuing the above example, let’s assume the server above also had the --persistent-state-dir option set to retain sandbox mapping between server restarts. If we now restarted the server without --sandbox-dir specified, users would only get the data:/ sandbox mapping.

User Sandboxes

Let’s assume we have a server running with the following sandbox configuration:

{
  "": {
    "": "/home/%u",
    "data": "/data"
  }
}

If we now update the sandbox configuration for userA and userB as follows:

> api.server.setSandboxMapping("userA", {"data": "/storage"})
> api.server.setSandboxMapping("userB", {"": "/external/userB", "home": "/home/userB"})

The sandbox configuration on the server will be:

{
  "": {
    "": "/home/%u",
    "data": "/data"
  },

  "userA": {
    "data": "/storage"
  },

  "userB": {
    "": "/external/userB",
    "home": "/home/userB"
  }
}

Users logging in will observe:

  • userA:
    • data:/ mapped to /storage
  • userB:
    • / mapped to /external/userB
    • home:/ mapped to /home/userB
  • userC:
    • / mapped to /home/%u (resolving into /home/userC)
    • data:/ mapped to /data

Now, if we want the admin user to have a full system access, we can set the sandbox mapping for the admin user to be false:

> api.server.setSandboxMapping("admin", False)

The sandbox configuration on the server will become:

{
  "": {
    "": "/home/%u",
    "data": "/data"
  },

  "userA": {
    "data": "/storage"
  },

  "userB": {
    "": "/external/userB",
    "home": "/home/userB"
  }

  "admin": false
}

Users logging in will observe:

  • userA:
    • data:/ mapped to /storage
  • userB:
    • / mapped to /external/userB
    • home:/ mapped to /home/userB
  • userC:
    • / mapped to /home/%u (resolving into /home/userC)
    • data:/ mapped to /data
  • admin:
    • The admin user will have access to all file systems. On Linux systems, this means the system root (/).