libamxrt  0.4.2
Ambiorix Run Time Library
amxrt_cap.c
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** SPDX-License-Identifier: BSD-2-Clause-Patent
4 **
5 ** SPDX-FileCopyrightText: Copyright (c) 2023 SoftAtHome
6 **
7 ** Redistribution and use in source and binary forms, with or without modification,
8 ** are permitted provided that the following conditions are met:
9 **
10 ** 1. Redistributions of source code must retain the above copyright notice,
11 ** this list of conditions and the following disclaimer.
12 **
13 ** 2. Redistributions in binary form must reproduce the above copyright notice,
14 ** this list of conditions and the following disclaimer in the documentation
15 ** and/or other materials provided with the distribution.
16 **
17 ** Subject to the terms and conditions of this license, each copyright holder
18 ** and contributor hereby grants to those receiving rights under this license
19 ** a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
20 ** (except for failure to satisfy the conditions of this license) patent license
21 ** to make, have made, use, offer to sell, sell, import, and otherwise transfer
22 ** this software, where such license applies only to those patent claims, already
23 ** acquired or hereafter acquired, licensable by such copyright holder or contributor
24 ** that are necessarily infringed by:
25 **
26 ** (a) their Contribution(s) (the licensed copyrights of copyright holders and
27 ** non-copyrightable additions of contributors, in source or binary form) alone;
28 ** or
29 **
30 ** (b) combination of their Contribution(s) with the work of authorship to which
31 ** such Contribution(s) was added by such copyright holder or contributor, if,
32 ** at the time the Contribution is added, such addition causes such combination
33 ** to be necessarily infringed. The patent license shall not apply to any other
34 ** combinations which include the Contribution.
35 **
36 ** Except as expressly stated above, no rights or licenses from any copyright
37 ** holder or contributor is granted under this license, whether expressly, by
38 ** implication, estoppel or otherwise.
39 **
40 ** DISCLAIMER
41 **
42 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
46 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49 ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
51 ** USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 **
53 ****************************************************************************/
54 
55 #include <stdio.h>
56 #include <string.h>
57 #include <pwd.h>
58 #include <grp.h>
59 #include <cap-ng.h>
60 
61 #include <amxrt/amxrt.h>
62 
63 #include "amxrt_priv.h"
64 
65 static int32_t amxrt_get_user_id(amxc_var_t* user) {
66  int32_t uid = 0;
67 
68  if(amxc_var_type_of(user) == AMXC_VAR_ID_NULL) {
69  uid = -1;
70  } else if(amxc_var_type_of(user) == AMXC_VAR_ID_CSTRING) {
71  struct passwd* user_info = NULL;
72  user_info = getpwnam(GET_CHAR(user, NULL));
73  when_null_status(user_info, exit, uid = -1);
74  uid = user_info->pw_uid;
75  } else {
76  uid = GET_INT32(user, NULL);
77  }
78 
79 exit:
80  return uid;
81 }
82 
83 static int32_t amxrt_get_group_id(amxc_var_t* group) {
84  int32_t gid = 0;
85 
86  if(amxc_var_type_of(group) == AMXC_VAR_ID_NULL) {
87  gid = -1;
88  } else if(amxc_var_type_of(group) == AMXC_VAR_ID_CSTRING) {
89  struct group* group_info = NULL;
90  group_info = getgrnam(GET_CHAR(group, NULL));
91  when_null_status(group_info, exit, gid = -1);
92  gid = group_info->gr_gid;
93  } else {
94  gid = GET_INT32(group, NULL);
95  }
96 
97 exit:
98  return gid;
99 }
100 
101 int amxrt_caps_apply(void) {
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 }
179 
180 void amxrt_caps_dump(void) {
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 }
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,...)
void amxrt_caps_dump(void)
Dumps the capabilities of the process.
Definition: amxrt_cap.c:180
int amxrt_caps_apply(void)
Apply the user, group and capabilities as defined in the configuration.
Definition: amxrt_cap.c:101
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