Skip to content

Commit 2c9b4a5

Browse files
committed
server: support run as user and fix initialize timer
1 parent e168f6e commit 2c9b4a5

File tree

13 files changed

+242
-31
lines changed

13 files changed

+242
-31
lines changed

src/libmodelbox/base/include/modelbox/base/utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,10 @@ Status ListSubDirectoryFiles(const std::string &path, const std::string &filter,
277277
/**
278278
* @brief Create directory recursively
279279
* @param path path to directory
280+
* @param mode directory mode
280281
* @return create result
281282
*/
282-
Status CreateDirectory(const std::string &path);
283+
Status CreateDirectory(const std::string &path, mode_t mode = 0700);
283284

284285
/**
285286
* @brief Revmoe directory recursively

src/libmodelbox/base/utils/utils.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ Status ListSubDirectoryFiles(const std::string &path, const std::string &filter,
185185
return STATUS_OK;
186186
}
187187

188-
Status CreateDirectory(const std::string &path) {
188+
Status CreateDirectory(const std::string &path, mode_t mode) {
189189
std::string directory_path = path + "/";
190190
uint32_t dir_path_len = directory_path.length();
191191
if (dir_path_len > PATH_MAX) {
@@ -203,7 +203,7 @@ Status CreateDirectory(const std::string &path) {
203203
continue;
204204
}
205205

206-
int32_t ret = mkdir(dir_path, 0700);
206+
int32_t ret = mkdir(dir_path, mode);
207207
if (ret != 0) {
208208
return {STATUS_FAULT, StrError(errno)};
209209
}

src/modelbox/common/flowuint_info.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ std::shared_ptr<FlowUnitManager> FlowUnitInfo::GetFlowUnitManager() {
8686

8787
std::shared_ptr<Drivers> FlowUnitInfo::GetDriverManager() { return drivers_; }
8888

89-
Status GetInfoInFromTomlFile(const std::string &file, nlohmann::json &json) {
89+
Status GetInfoFromTomlFile(const std::string &file, nlohmann::json &json) {
9090
MBLOG_DEBUG << "flowunit from file: " << file;
9191
std::string json_data;
9292
std::ifstream infile(file);
@@ -267,7 +267,7 @@ Status FlowUnitInfo::GetInfoInJson(std::string *result) {
267267

268268
for (const auto &f : flowunits_from_files_) {
269269
nlohmann::json json_flowunit;
270-
auto ret = GetInfoInFromTomlFile(f, json_flowunit);
270+
auto ret = GetInfoFromTomlFile(f, json_flowunit);
271271
if (!ret) {
272272
if (ret == STATUS_BADCONF) {
273273
continue;

src/modelbox/common/include/modelbox/common/utils.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,29 @@ int modelbox_cpu_register_data(char *buf, int buf_size, ucontext_t *ucontext);
8080
*/
8181
Status SplitIPPort(const std::string &host, std::string &ip, std::string &port);
8282

83+
/**
84+
* @brief Get user id and gid by username
85+
* @param user username
86+
* @param uid user id
87+
* @param gid group id
88+
* @return result.
89+
*/
90+
Status GetUidGid(const std::string &user, uid_t &uid, gid_t &gid);
91+
92+
/**
93+
* @brief change user and group of path
94+
* @param user username
95+
* @param path path to change
96+
* @return result.
97+
*/
98+
Status ChownToUser(const std::string &user, const std::string &path);
99+
100+
/**
101+
* @brief run as user
102+
* @return result.
103+
*/
104+
Status RunAsUser(const std::string &user);
105+
83106
/**
84107
* @brief Custom stream
85108
*/

src/modelbox/common/utils.cc

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@
1818

1919
#include <errno.h>
2020
#include <fcntl.h>
21+
#include <linux/capability.h>
22+
#include <pwd.h>
2123
#include <signal.h>
2224
#include <stdio.h>
2325
#include <string.h>
26+
#include <sys/prctl.h>
2427
#include <unistd.h>
2528

2629
#include <mutex>
@@ -34,6 +37,11 @@ namespace modelbox {
3437

3538
static int kPidFileFd = -1;
3639

40+
extern "C" int capget(struct __user_cap_header_struct *header,
41+
struct __user_cap_data_struct *cap);
42+
extern "C" int capset(struct __user_cap_header_struct *header,
43+
struct __user_cap_data_struct *cap);
44+
3745
std::once_flag root_dir_flag;
3846

3947
const std::string &modelbox_root_dir() {
@@ -244,6 +252,90 @@ int modelbox_cpu_register_data(char *buf, int buf_size, ucontext_t *ucontext) {
244252
return 0;
245253
}
246254

255+
Status GetUidGid(const std::string &user, uid_t &uid, gid_t &gid) {
256+
struct passwd *result = nullptr;
257+
struct passwd pwd;
258+
std::vector<char> buff;
259+
ssize_t bufsize = 0;
260+
int ret = -1;
261+
262+
if (user == "") {
263+
return {STATUS_INVALID, "user is empty"};
264+
}
265+
266+
bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
267+
if (bufsize == -1) {
268+
bufsize = 1024 * 16;
269+
}
270+
271+
buff.reserve(bufsize);
272+
ret = getpwnam_r(user.c_str(), &pwd, buff.data(), bufsize, &result);
273+
if (ret != 0) {
274+
return {STATUS_FAULT, "get user " + user + " failed: " + StrError(errno)};
275+
}
276+
277+
if (result == nullptr) {
278+
return {STATUS_NOTFOUND, "user " + user + " not found"};
279+
}
280+
281+
uid = result->pw_uid;
282+
gid = result->pw_gid;
283+
284+
return STATUS_OK;
285+
}
286+
287+
Status ChownToUser(const std::string &user, const std::string &path) {
288+
uid_t uid = 0;
289+
gid_t gid = 0;
290+
int unused __attribute__((unused)) = 0;
291+
292+
auto ret = GetUidGid(user, uid, gid);
293+
if (ret != STATUS_OK) {
294+
return ret;
295+
}
296+
297+
if (chown(path.c_str(), uid, gid) != 0) {
298+
return {STATUS_INVALID, "chown " + path + " failed: " + StrError(errno)};
299+
}
300+
301+
return STATUS_OK;
302+
}
303+
304+
Status RunAsUser(const std::string &user) {
305+
struct __user_cap_data_struct cap;
306+
struct __user_cap_header_struct header;
307+
header.version = _LINUX_CAPABILITY_VERSION;
308+
header.pid = 0;
309+
uid_t uid = 0;
310+
gid_t gid = 0;
311+
int unused __attribute__((unused)) = 0;
312+
313+
auto ret = GetUidGid(user, uid, gid);
314+
if (ret != STATUS_OK) {
315+
return ret;
316+
}
317+
318+
if (getuid() == uid) {
319+
return STATUS_OK;
320+
}
321+
322+
if (capget(&header, &cap) < 0) {
323+
return {STATUS_INVALID, "capget failed: " + StrError(errno)};
324+
}
325+
326+
prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
327+
cap.effective |= (1 << CAP_NET_RAW | 1 << CAP_NET_ADMIN);
328+
cap.permitted |= (1 << CAP_NET_RAW | 1 << CAP_NET_ADMIN);
329+
unused = setgid(gid);
330+
unused = setuid(uid);
331+
if (capset(&header, &cap) < 0) {
332+
return {STATUS_INVALID, "capset failed: " + StrError(errno)};
333+
}
334+
335+
prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0);
336+
return STATUS_OK;
337+
}
338+
247339
Status SplitIPPort(const std::string &host, std::string &ip,
248340
std::string &port) {
249341
auto pos = host.find_last_of(':');

src/modelbox/manager/src/manager.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,6 @@ int manager_init(char *name) {
316316
return -1;
317317
}
318318

319-
mkdir(MANAGER_PID_PATH, 0750);
320-
321319
manager_log_callback_reg(manager_tlog);
322320

323321
if (strnlen(pid_file_path, sizeof(pid_file_path)) <= 0) {
@@ -332,6 +330,7 @@ int manager_init(char *name) {
332330

333331
strncpy_s(piddir, sizeof(piddir), pid_file_path, sizeof(pid_file_path));
334332
dirname(piddir);
333+
mkdir(piddir, 0750);
335334

336335
/* create key */
337336
if (strnlen(key_file_path, sizeof(key_file_path)) <= 0) {

src/modelbox/server/etc/modelbox-opts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ fi
2121
# custom env variable here
2222

2323
# modelbox server opts
24-
MODELBOX_OPTS="-c ${MODELBOX_ROOT}@CMAKE_INSTALL_FULL_SYSCONFDIR@/modelbox/modelbox.conf"
24+
MODELBOX_OPTS="$MODELBOX_OPTS -c ${MODELBOX_ROOT}@CMAKE_INSTALL_FULL_SYSCONFDIR@/modelbox/modelbox.conf"

src/modelbox/server/etc/modelbox.conf.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ port = "1104"
44
flow_path = "@MODELBOX_ROOT_VAR@@CMAKE_INSTALL_FULL_SYSCONFDIR@/modelbox/graph"
55
application_root = "@MODELBOX_ROOT_VAR@/opt/modelbox/application"
66

7+
# run as user
8+
# user = "modelbox"
9+
710
# [acl]
811
# allow = [
912
# "127.0.0.1/8"

0 commit comments

Comments
 (0)