libamxrt  0.4.2
Ambiorix Run Time Library
User privileges and capabilities

Functions

int amxrt_caps_apply (void)
 Apply the user, group and capabilities as defined in the configuration. More...
 
void amxrt_caps_dump (void)
 Dumps the capabilities of the process. More...
 

Detailed Description

For the purpose of performing permission checks, traditional UNIX implementations distinguish two categories of processes:

Privileged processes bypass all kernel permission checks, while unprivileged processes are subject to full permission checking based on the process's credentials (usually: effective UID, effective GID, and supplementary group list).

Starting with Linux 2.2, Linux divides the privileges traditionally associated with superuser into distinct units, known as capabilities, which can be independently enabled and disabled. Capabilities are a per-thread attribute.

In the config section it is possible to define to which user the started process must switch. Typically the process is started as a privileged process (started with root user), but it can drop the root privileges and switch to an unprivileged process (user id is nonzero).

When setting the user name (or id), by default all capabilities are dropped as well. It is possible to retain all capabilities are (keep all) or only retain some.

Function Documentation

◆ amxrt_caps_apply()

int amxrt_caps_apply ( void  )

Apply the user, group and capabilities as defined in the configuration.

When everything is initialized user privileges and capabilities can be dropped.

The user and group to which the process needs to switch (privileges dropping) can be defined in the configuration.

Which capabilities needs to be retained can be defined in the configuration.

Returns
returns 0 if no error occurred.

Definition at line 101 of file amxrt_cap.c.

101  {
102  int rv = -1;
103  amxc_var_t* config = amxrt_get_config();
104  amxc_var_t* privileges = GET_ARG(config, "privileges");
105  amxc_var_t* caps = GET_ARG(privileges, "capabilities");
106  amxc_var_t* user = GET_ARG(privileges, "user");
107  amxc_var_t* group = GET_ARG(privileges, "group");
108 
109  capng_get_caps_process();
110  when_null_status(privileges, exit, rv = 0);
111 
112  if(!GET_BOOL(privileges, "keep-all")) {
113  capng_clear(CAPNG_SELECT_BOTH);
114 
115  amxc_var_for_each(cap, caps) {
116  int id = -1;
117 
118  if(amxc_var_type_of(cap) == AMXC_VAR_ID_CSTRING) {
119  const char* cap_name = GET_CHAR(cap, NULL);
120  amxc_string_t str_cap_name;
121  int offset = 0;
122 
123  /* work-around for musl-c issue.
124  when using strncasecmp which is defined in <strings.h>
125  and using musl-c the following compilation error/warning
126  is given
127  In file included from amxrt_cap.c:62:
128  /home/sahbot/workspace/build/buildsystem/staging_dir/toolchain-x86_64_gcc-8.4.0_musl/include/fortify/strings.h:19:2: error: #include_next is a GCC extension [-Werror]
129  #include_next <strings.h>
130  ^~~~~~~~~~~~
131 
132  muslc strings.h uses include_next. The use of include_next should be
133  avoided as it can lead to confusion.
134 
135  see https://gcc.gnu.org/onlinedocs/cpp/Wrapper-Headers.html
136  */
137  amxc_string_init(&str_cap_name, 0);
138  amxc_string_set(&str_cap_name, cap_name);
139  amxc_string_to_upper(&str_cap_name);
140  offset = strncmp(amxc_string_get(&str_cap_name, 0), "CAP_", 4) == 0 ? 4 : 0;
141  amxc_string_clean(&str_cap_name);
142 
143  id = capng_name_to_capability(cap_name + offset);
144  if(id == -1) {
145  amxrt_print_error("Unknown capability - [%s]", cap_name);
146  continue;
147  }
148  } else {
149  id = GET_INT32(cap, NULL);
150  if((id < 0) || (id > CAP_LAST_CAP)) {
151  amxrt_print_error("Invalid capability id - [%d]", GET_INT32(cap, NULL));
152  continue;
153  }
154  }
155  rv = capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED | CAPNG_BOUNDING_SET | CAPNG_INHERITABLE), id);
156  if(rv != 0) {
157  amxrt_print_error("Apply capability [%d] failed with %d\n", id, rv);
158  }
159  }
160  }
161 
162 exit:
163  if((user == NULL) && (group == NULL)) {
165  rv = capng_apply(CAPNG_SELECT_BOTH);
166  } else {
167  int32_t uid = amxrt_get_user_id(user);
168  int32_t gid = amxrt_get_group_id(group);
169  amxrt_print_message("Switching to user id %d and group id %d", uid, gid);
171  rv = capng_change_id(uid, gid, (capng_flags_t) (CAPNG_DROP_SUPP_GRP));
172  }
173  if(rv != 0) {
174  amxrt_print_error("Apply capabilities failed with %d\n", rv);
175  }
176 
177  return rv;
178 }
static int32_t amxrt_get_user_id(amxc_var_t *user)
Definition: amxrt_cap.c:65
static int32_t amxrt_get_group_id(amxc_var_t *group)
Definition: amxrt_cap.c:83
PRIVATE void amxrt_print_message(const char *fmt,...)
PRIVATE int amxrt_dm_create_dir(amxo_parser_t *parser, uid_t uid, gid_t gid)
PRIVATE void amxrt_print_error(const char *fmt,...)
amxc_var_t * amxrt_get_config(void)
Gets the htable variant containing the configuration options.
Definition: amxrt.c:301
amxo_parser_t * amxrt_get_parser(void)
Gets runtime odl parser.
Definition: amxrt.c:305
config
Definition: test.odl:54

◆ amxrt_caps_dump()

void amxrt_caps_dump ( void  )

Dumps the capabilities of the process.

Print all capabilities of the process to stdout.

Definition at line 180 of file amxrt_cap.c.

180  {
181  capng_print_caps_numeric(CAPNG_PRINT_STDOUT, CAPNG_SELECT_BOTH);
182 
183  printf("\nCAPNG_EFFECTIVE:\n");
184  capng_print_caps_text(CAPNG_PRINT_STDOUT, CAPNG_EFFECTIVE);
185  printf("\nCAPNG_PERMITTED:\n");
186  capng_print_caps_text(CAPNG_PRINT_STDOUT, CAPNG_PERMITTED);
187  printf("\nCAPNG_INHERITABLE:\n");
188  capng_print_caps_text(CAPNG_PRINT_STDOUT, CAPNG_INHERITABLE);
189  printf("\nCAPNG_BOUNDING_SET:\n");
190  capng_print_caps_text(CAPNG_PRINT_STDOUT, CAPNG_BOUNDING_SET);
191  printf("\n");
192 }