Permissions and Privileges
Screen uses POSIX-style permissions (read, write, execute) and permission classes (owner(user), manager, other) to manage the various levels of access in Screen. This model is used to control not only the level of access to various instances of Screen API objects (e.g. windows, sessions), but also the level of access that a given Screen API object has to a given function or property.
Permissions refers to the ability to perform certain operations such as calling a function (screen_post_window()) or setting a property (SCREEN_PROPERTY_VISIBLE). Privileges refers to the set of permissions that are granted based on the type of role.
Note that permissions are not applied to the creation (e.g., screen_create_*())or destruction (e.g., screen_destroy_*()) of objects.
Privileges
Privileges are permissions that are controlled by roles. Screen uses the POSIX permission classes to control permissions based on the type of role.
Any user of Screen (e.g. Screen context) is granted other permissions in relation to any given Screen object. Generally, there is no visibility to user-created objects for contexts that are related through other privileges. However, some Screen-owned objects, such as display objects defined in the graphics.conf configuration file, grant read permissions to objects with other privileges by default, so that all contexts are aware of these display objects.
A context can have elevated privileges in the combination of the following types of roles: Owner, User, and Manager.- Owner
- An owner is defined as whoever creates the object. The owner, by default, has user permissions on the object. Because of these permissions, it has the ability to get and set certain properties and perform certain functions. See the user role described below. An owner can also grant user permissions on the object to other Screen contexts through SCREEN_PROPERTY_PERMISSIONS. Since it is the owner, it may also have additional permissions which cannot be granted to other Screen contexts.
- User
- Similar to an owner, a user has privileges based on user permissions. These permissions
are granted by the owner as mentioned above. User permissions, SCREEN_PROPERTY_PERMISSIONS,
are set through the Screen API.
Note:The permissions associated with the user role are the ones granted by the owner, to other contexts, through SCREEN_PROPERTY_PERMISSIONS. When the owner sets SCREEN_PROPERTY_PERMISSIONS through a combination of strings or integer values, contexts that fall within the classification are granted user privileges to that object. Masked with whatever permissions are being set. For example:
In this example, any context with a user ID of 1000 is granted user permissions on that Screen window. If the context did not previously have read access to this window, then they would at this point receive a SCREEN_EVENT_CREATE for the window.char permissions[] = "user:1000:r--"; screen_set_window_property_cv(screen_win, SCREEN_PROPERTY_PERMISSIONS, strlen(permissions), permissions);
- Manager
-
A manager, by default, is granted group permissions on applicable objects that it should have manager access to. This gives you the ability to get and set certain properties and perform certain functions allowed by group permissions.
Managers must be created within a privileged context type. The following context types create privileged manager contexts:
SCREEN_WINDOW_MANAGER_CONTEXT
SCREEN_POWER_MANAGER_CONTEXT
SCREEN_DISPLAY_MANAGER_CONTEXT
SCREEN_INPUT_MANAGER_CONTEXT
A parent assumes a manager role for read and write access to certain properties, since it can be considered a manager of its child windows (but not all parents necessarily manage their children).
Manager privileges can't be set. The role of manager can only be gained or lost by joining or leaving groups, respectively.
For example, a context created as a SCREEN_INPUT_MANAGER_CONTEXT will be granted group permissions to all device API objects on the system. For device objects, properties such as SCREEN_PROPERTY_WINDOW and SCREEN_PROPERTY_KEYMAP have the permission set to rw-rw-r--. With group access, this context can both read and write these properties for any device on the system. Conversely, a property such as SCREEN_PROPERTY_POSITION has the permissions set to rw-r--r--. With group access, this context can read this property, but cannot write it. Only contexts with user access to that device object can set this property.
Permissions
Permissions from the user role are what's granted to others. The owner grants these user permissions so that others can access the object. A SCREEN_EVENT_CREATE and a SCREEN_EVENT_CLOSE event are used to notify whoever gains or loses access to the object respectively. In the case of multiple grants of access, a SCREEN_EVENT_CREATE event is received only by those actually gaining the access. For example, someone granted access to its top-level window to everyone. A window manager, who already has access to all top-level windows doesn't receive a SCREEN_EVENT_CREATE event for this action. Instead, it receives a SCREEN_EVENT_PROPERTY event to indicate that the SCREEN_PROPERTY_PERMISSIONS property of that window has changed.
The user permissions apply only to those properties that can be changed by the owner of the object. Properties that can be changed only by a specific role remain unaffected regardless of the setting of SCREEN_PROPERTY_PERMISSIONS. For example, there are window properties that can be changed only by a window's parent. This rule still holds true despite the value that SCREEN_PROPERTY_PERMISSIONS is set to. The exception is that if the window has no parent, or if there is no window manager, then the permissions apply to all window properties.
Permissions can be set dynamically; this means you can set the SCREEN_PROPERTY_PERMISSIONS property at any time. However, note that permissions are not cached. If you change permissions, you'll need to ensure that it doesn't interfere with any ongoing processing that your application is doing. For example, a screen_blit() could be successful, but then if permissions are changed, it could cause a subsequent call to screen_blit() to fail.
Similar to setting file permissions with chmod (change file modes in POSIX) or setfacl, if you want someone to have special access to an object, you need to set the appropriate permissions on that object. The permissions control the read, write, and execute accessibilities to your object following file permissions conventions.
The read, write, and execute permissions can be specified for each class of user for an object. Note that the following mapping applies:
- read
- Read permission means that you're able to access the object to retrieve
properties and buffers. Examples of functions that can be performed if you
have read access are:
- screen_read_window()
- screen_get_window_property_iv()
- screen_blit() when the window is the source
- write
- Write permission means that you're able to access the object to set
properties and write to buffers. Examples of functions that can be performed
if you have write access are:
- screen_set_window_property_iv()
- screen_blit() when the window is the destination
- execute
-
Execute permission means that you're able to access the object to inject events to it. This means that screen_inject_event() function can be used to inject the event.
The function screen_inject_event() doesn't require an object handle. Therefore, if you grant only execute permissions to others, Screen doesn't send SCREEN_EVENT_CREATE or SCREEN_EVENT_CLOSE events.
Permissions are set using the SCREEN_PROPERTY_PERMISSIONS property. You can set this property as:
- an integer
- a string
When you set the SCREEN_PROPERTY_PERMISSIONS as a string, Screen updates the integer value where applicable.
The SCREEN_PROPERTY_PERMISSIONS can't be retrieved as a string. When you retrieve it using a screen_get_*_property_iv() function, you won't see any permission changes you've made by setting SCREEN_PROPERTY_PERMISSIONS as a string, unless your string permissions correspond to an integer setting.
Setting SCREEN_PROPERTY_PERMISSIONS as an integer
Valid permissions that can be used and combined are defined by Screen permission masks. You can retrieve and set this property by using the Screen API functions screen_get_*_property_iv() and screen_set_*_property_iv(), respectively. For example, if the object in question is a window, then you'd use screen_get_window_property_iv() to retrieve SCREEN_PROPERTY_PERMISSIONS and screen_set_window_property_iv() to set it.
Class | Mask group | Description | Permission masks |
---|---|---|---|
Owner | WIN | If you are the owner of this object, you will have the specified permissions to this object. |
SCREEN_PERMISSION_IRWIN SCREEN_PERMISSION_IWWIN SCREEN_PERMISSION_IXWIN |
Parent | TOP | If you are the parent of this object, you will have the specified permissions to this object. |
SCREEN_PERMISSION_IRTOP SCREEN_PERMISSION_IWTOP SCREEN_PERMISSION_IXTOP |
User ID | USR | If you have the same user ID as the owner of this object, you will have the specified permissions to this object. |
SCREEN_PERMISSION_IRUSR SCREEN_PERMISSION_IWUSR SCREEN_PERMISSION_IXUSR |
Group ID | GRP | If you have the same group ID as the owner of this object, you will have the specified permissions to this object. |
SCREEN_PERMISSION_IRGRP SCREEN_PERMISSION_IWGRP SCREEN_PERMISSION_IXGRP |
Process ID | PID | If you have the same process ID as the owner of this object, you will have the specified permissions to this object. |
SCREEN_PERMISSION_IRPID SCREEN_PERMISSION_IWPID SCREEN_PERMISSION_IXPID |
Process group ID | PGP | If you have the same process group ID as the owner of this object, you will have the specified permissions to this object. |
SCREEN_PERMISSION_IRPGP SCREEN_PERMISSION_IWPGP SCREEN_PERMISSION_IXPGP |
Application group | AGP | If you are in the same application group as the owner of this object, you will have the specified permissions to this object. |
SCREEN_PERMISSION_IRAGP SCREEN_PERMISSION_IWAGP SCREEN_PERMISSION_IXAGP |
Other | OTH | Anyone will have the specified permissions to this object. |
SCREEN_PERMISSION_IROTH SCREEN_PERMISSION_IWOTH SCREEN_PERMISSION_IXOTH |
For example, let's say you have this code:
...
screen_window_t screen_win;
int permissions = SCREEN_PERMISSION_IRWIN | SCREEN_PERMISSION_IWWIN |
SCREEN_PERMISSION_IXWIN | \ SCREEN_PERMISSION_IRPID |
SCREEN_PERMISSION_IWPID | SCREEN_PERMISSION_IXPID;
/* Note that the above permissions include the owner privileges.
* These need to be included because when setting permissions using masks,
* the setting replaces all previous values. That's why we include the
* owner privileges so that we don't lose them.
*/
...
screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_PERMISSIONS, permissions);
...
- screen_read_window()
- screen_set_window_property_iv()
- screen_inject_event() to inject an event into that window
- screen_blit() with that window as either source or destination
- SCREEN_PERMISSION_IRWIN
- SCREEN_PERMISSION_IWWIN
- SCREEN_PERMISSION_IXWIN
When you use SCREEN_PROPERTY_PERMISSIONS as an integer, you're able to grant access to different classes, but all within the context created by the same process. If you want to grant access to an outside process, the only way to do so is to set the permissions for Others. However, by granting the Others permission, it includes all others. So, there's really no way to grant access to a particular outside process without giving access to everyone else. Use SCREEN_PROPERTY_PERMISSIONS as a string if you need to have more control on filtering permissions.
Setting SCREEN_PROPERTY_PERMISSIONS as a string
You can further restrict permissions to particular clients or classes of clients if you use the SCREEN_PROPERTY_PERMISSIONS property as a string. Unlike the integer permissions, the string permissions allow you to specify a specific context, process, process group, group, or user that's not the same as the owner of the object.
You can set this property by using the Screen API set functions (screen_set_*_property_cv()). For example, if the object in question is a window, then you'd use screen_set_window_property_cv() to set it. When using permissions as a string, the permissions masks (integer) are set, but only the bits that have an integer association with the string form.
The following table shows each permission string and its corresponding permissions masks:
Class | Permissions string | Applicable permissions masks |
---|---|---|
Owner | context::rwx |
SCREEN_PERMISSION_IRWIN SCREEN_PERMISSION_IWWIN SCREEN_PERMISSION_IXWIN |
Parent | parent::rwx |
SCREEN_PERMISSION_IRTOP SCREEN_PERMISSION_IWTOP SCREEN_PERMISSION_IXTOP |
Application | application::rwx |
SCREEN_PERMISSION_IRAGP SCREEN_PERMISSION_IWAGP SCREEN_PERMISSION_IXAGP |
Process | process::rwx |
SCREEN_PERMISSION_IRPID SCREEN_PERMISSION_IWPID SCREEN_PERMISSION_IXPID |
Process group | processgroup::rwx |
SCREEN_PERMISSION_IRPGP SCREEN_PERMISSION_IWPGP SCREEN_PERMISSION_IXPGP |
User | user::rwx |
SCREEN_PERMISSION_IRUSR SCREEN_PERMISSION_IWUSR SCREEN_PERMISSION_IXUSR |
Group | group::rwx |
SCREEN_PERMISSION_IRGRP SCREEN_PERMISSION_IWGRP SCREEN_PERMISSION_IXGRP |
Other | other::rwx |
SCREEN_PERMISSION_IROTH SCREEN_PERMISSION_IWOTH SCREEN_PERMISSION_IXOTH |
The following table shows the format for all permissions strings:
Class | Format | Example |
---|---|---|
Parent | parent::permissions | parent::rwx |
Application | application::permissions | application::rwx |
Owner | context::permissions | context::rwx |
Specified context | context:id:permissions | context:screen-ctx-0-00000000-657eb725d72a0c965a743c0672534abf:rwx |
Process | process::permissions | process::rwx |
Specified process | process:pid:permissions | process:1234:rwx |
Process group | process group::permissions | process group::rwx |
Specified process group | process group:pgid:permissions | process group:5678:rwx |
User | user::permissions | user::rwx |
Specified user | user:uid:permissions | user:1000:rwx |
Named user | user:uname:permissions | user:root:rwx |
Group | group::permissions | group::rwx |
Specified group | group:gid:permissions | group:2000:rwx |
Named group | group:gname:permissions | group:root:rwx |
Other | other::permissions | other::rwx |
-
The id for specified contexts is the identifier of the context object. You can retrieve this identifier from the context by calling screen_get_context_property_cv() for SCREEN_PROPERTY_ID. The ID of the context is returned. This string is used to set the permissions.
-
The permissions string is a combination of r (read), w (write), x (execute), and - (no permission). The permissions must be specified in this order.
Here are some examples (presuming a default set of permissions mask that includes owner privileges):
Example 1: Setting SCREEN_PROPERTY_PERMISSIONS as a string, then retrieving the property
...
char c_permissions[] = "parent::rwx";
int i_permissions;
screen_set_window_property_cv(screen_win, SCREEN_PROPERTY_PERMISSIONS,
strlen(c_permissions),c_permissions);
screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_PERMISSIONS,
i_permissions);
SCREEN_PERMISSION_IRTOP
SCREEN_PERMISSION_IWTOP
SCREEN_PERMISSION_IXTOP
Example 2: Setting SCREEN_PROPERTY_PERMISSIONS as a string and as an integer, then retrieving the property
...
char c_permissions[] =
"context:screen-ctx-0-00000000-657eb725d72a0c965a743c0672534abf:rwx";
int i_permissions = SCREEN_PERMISSION_IRWIN | SCREEN_PERMISSION_IWWIN |
SCREEN_PERMISSION_IXWIN | \ SCREEN_PERMISSION_IRGRP |
SCREEN_PERMISSION_IWGRP | SCREEN_PERMISSION_IXGRP;
screen_set_window_property_cv(screen_win, SCREEN_PROPERTY_PERMISSIONS,
strlen(c_permissions), c_permissions);
screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_PERMISSIONS, i_permissions);
screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_PERMISSIONS, i_permissions);
In this example, the permissions set in string form don't have corresponding
permissions masks. Therefore, the resulting property value is:
SCREEN_PERMISSION_IRGRP | SCREEN_PERMISSION_IWGRP | SCREEN_PERMISSION_IXGRP |
SCREEN_PERMISSION_IRWIN | SCREEN_PERMISSION_IWWIN | SCREEN_PERMISSION_IXWIN
. Despite not being accounted for in the integer value, the permissions
that were set in string form are still applied.
Example 3: Setting SCREEN_PROPERTY_PERMISSIONS as strings, then retrieving the property
...
char permissions1000[] = "user:1000:rw-";
char permissions1001[] = "user:1001:rw-";
int permissions;
screen_set_window_property_cv(screen_win, SCREEN_PROPERTY_PERMISSIONS, \
strlen(permissions1000), permissions1000);
screen_set_window_property_cv(screen_win, SCREEN_PROPERTY_PERMISSIONS, \
strlen(permissions1001), permissions1001);
screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_PERMISSIONS, permissions);
In this example, the permissions set in string form don't have corresponding
permissions masks. Therefore, the default permissions mask is returned from the
query of SCREEN_PROPERTY_PERMISSIONS. Despite not being accounted for
in the integer value, the permissions that are set in string form are still applied.
Unlike setting permissions as an integer, setting permissions as a string is
additive. Subsequent settings of permissions won't undo previous settings.
Therefore, users 1000 and 1001 both result in having rw-
permissions.
To remove permissions from user 1000, you can call set again with the string
permissions as: user:1000:---
Setting specified classes won't affect the permission masks