Skip to content

Commit d4c7d6d

Browse files
committed
Normalizing non-mac user creation logic
1 parent 56c65d1 commit d4c7d6d

File tree

6 files changed

+79
-48
lines changed

6 files changed

+79
-48
lines changed

cmake/detect_system.cmake

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,31 @@ check_cxx_source_compiles("
8282
}"
8383
HAVE_ABI_CXA_THROW)
8484

85+
if (NOT DEFINED USERADD_PATH)
86+
find_program(USERADD_PATH useradd PATHS /usr/sbin /bin NO_DEFAULT_PATH)
87+
if (USERADD_PATH)
88+
message(STATUS "Looking for useradd - found at ${USERADD_PATH}")
89+
else()
90+
message(STATUS "Looking for useradd - not found")
91+
endif()
92+
endif()
8593

86-
find_program(USERADD_PATH useradd PATHS /usr/sbin /bin NO_DEFAULT_PATH)
87-
if (USERADD_PATH)
88-
set(HAVE_USERADD ON CACHE INTERNAL "Whether platform has useradd command")
89-
else()
90-
set(HAVE_USERADD OFF CACHE INTERNAL "Whether platform has useradd command")
94+
if (NOT DEFINED GROUPADD_PATH)
95+
find_program(GROUPADD_PATH groupadd PATHS /usr/sbin /bin NO_DEFAULT_PATH)
96+
if (GROUPADD_PATH)
97+
message(STATUS "Looking for groupadd - found at ${GROUPADD_PATH}")
98+
else()
99+
message(STATUS "Looking for groupadd - not found")
100+
endif()
91101
endif()
92102

93-
find_program(PW_PATH pw PATHS /usr/sbin NO_DEFAULT_PATH)
94-
if (PW_PATH)
95-
set(HAVE_PW ON CACHE INTERNAL "Whether platform has pw command")
96-
else()
97-
set(HAVE_PW OFF CACHE INTERNAL "Whether platform has pw command")
103+
if (NOT DEFINED PW_PATH)
104+
find_program(PW_PATH pw PATHS /usr/sbin NO_DEFAULT_PATH)
105+
if (PW_PATH)
106+
message(STATUS "Looking for pw - found at ${PW_PATH}")
107+
else()
108+
message(STATUS "Looking for pw - not found")
109+
endif()
98110
endif()
99111

100112
if (WSDDN_WITH_SYSTEMD STREQUAL "yes" OR WSDDN_WITH_SYSTEMD STREQUAL "auto" AND NOT DEFINED CACHE{HAVE_SYSTEMD})

src/app_state.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,24 @@ void AppState::init() {
6969
if (getuid() == 0) {
7070

7171
if (!m_currentCommandLine.runAs) {
72-
#if CAN_CREATE_USERS
7372
WSDLOG_DEBUG("Running as root but no account to run under is specified in configuration. Using {}", WSDDN_DEFAULT_USER_NAME);
7473
auto pwd = ptl::Passwd::getByName(WSDDN_DEFAULT_USER_NAME);
7574
if (pwd) {
7675
m_currentCommandLine.runAs = Identity(pwd->pw_uid, pwd->pw_gid);
7776
} else {
78-
WSDLOG_INFO("User {} does not exist, creating", WSDDN_DEFAULT_USER_NAME);
77+
WSDLOG_INFO("User {} does not exist, trying to create", WSDDN_DEFAULT_USER_NAME);
7978
m_currentCommandLine.runAs = Identity::createDaemonUser(WSDDN_DEFAULT_USER_NAME);
79+
80+
if (!m_currentCommandLine.runAs) {
81+
WSDLOG_INFO("User creation is not supported on this platform");
82+
WSDLOG_CRITICAL("Running network service as a root is extremely insecure and is not allowed.\n"
83+
"Please use one of the following approaches: \n"
84+
" * pass `--user username` command line option to specify which account to run network code under\n"
85+
" * start " WSDDN_PROGNAME " under a non-root account (if using systemd consider DynamicUser approach)"
86+
);
87+
exit(EXIT_FAILURE);
88+
}
8089
}
81-
#else
82-
WSDLOG_CRITICAL("Running network service as a root is extremely insecure and is not allowed.\n"
83-
"Please use one of the following approaches: \n"
84-
" * pass `--user username` command line option to specify which account to run network code under\n"
85-
" * start " WSDDN_PROGNAME " under a non-root account (if using systemd consider DynamicUser approach)"
86-
);
87-
exit(EXIT_FAILURE);
88-
#endif
8990
}
9091
if (!m_currentCommandLine.chrootDir) {
9192
WSDLOG_DEBUG("Running as root but no chroot specified in configuration. Using {}", WSDDN_DEFAULT_CHROOT_DIR);

src/sys_config.h.in

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
#cmakedefine01 HAVE_CXXABI_H
1515
#cmakedefine01 HAVE_ABI_CXA_THROW
1616
#cmakedefine01 HAVE_SYSTEMD
17-
#cmakedefine01 HAVE_USERADD
18-
#cmakedefine01 HAVE_PW
1917

2018
#cmakedefine LIBSYSTEMD_SO "${LIBSYSTEMD_SO}"
2119

2220
#cmakedefine USERADD_PATH "${USERADD_PATH}"
21+
#cmakedefine GROUPADD_PATH "${GROUPADD_PATH}"
2322
#cmakedefine PW_PATH "${PW_PATH}"
2423

2524
#if (defined(__APPLE__) && defined(__MACH__))
@@ -53,9 +52,6 @@
5352
#define HAVE_OS_LOG WSDDN_PLATFORM_APPLE
5453

5554

56-
#define CAN_CREATE_USERS HAVE_APPLE_USER_CREATION || HAVE_USERADD || HAVE_PW
57-
58-
5955
#define WSDDN_VERSION "@WSDDN_VERSION@"
6056
#define WSDDN_PROGNAME "$<TARGET_FILE_NAME:wsddn>"
6157

src/sys_util.cpp

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,55 @@ const char * OsLogHandle::s_category = "main";
1010

1111
#endif
1212

13-
#if HAVE_USERADD || HAVE_PW
13+
#if !HAVE_APPLE_USER_CREATION
1414

15-
auto Identity::createDaemonUser(const sys_string & name) -> Identity {
15+
static auto runCreateDaemonUserCommands(const sys_string & name) -> bool {
16+
17+
#if defined(__linux__) && defined(USERADD_PATH)
1618

17-
#if HAVE_USERADD
18-
#ifdef __linux__
1919
sys_string command = S(USERADD_PATH " -r -d " WSDDN_DEFAULT_CHROOT_DIR " -s /bin/false '") + name + S("'");
20-
#elif defined(__OpenBSD__) || defined(__NetBSD__)
21-
sys_string command = S(USERADD_PATH " -L daemon -g =uid -d " WSDDN_DEFAULT_CHROOT_DIR " -s /sbin/nologin -c \"WS-Discovery Daemon\" '") + name + S("'");
20+
(void)!system(command.c_str());
21+
return true;
22+
23+
#elif (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(USERADD_PATH)
24+
2225
createMissingDirs(WSDDN_DEFAULT_CHROOT_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, Identity::admin());
23-
#elif defined(__HAIKU__)
24-
sys_string command = S(USERADD_PATH " -d " WSDDN_DEFAULT_CHROOT_DIR " -s /bin/false -n \"WS-Discovery Daemon\" '") + name + S("'");
26+
sys_string command = S(USERADD_PATH " -L daemon -g =uid -d " WSDDN_DEFAULT_CHROOT_DIR " -s /sbin/nologin -c \"WS-Discovery Daemon\" '") + name + S("'");
27+
(void)!system(command.c_str());
28+
return true;
29+
30+
#elif defined(__HAIKU__) && defined(USERADD_PATH) && defined(GROUPADD_PATH)
31+
2532
createMissingDirs(WSDDN_DEFAULT_CHROOT_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, Identity::admin());
33+
34+
sys_string command = S(GROUPADD_PATH " '") + name + S("'");
35+
(void)!system(command.c_str());
36+
command = S(USERADD_PATH " -g ") + name + S(" -d " WSDDN_DEFAULT_CHROOT_DIR " -s /bin/false -n \"WS-Discovery Daemon\" '") + name + S("'");
37+
(void)!system(command.c_str());
38+
return true;
39+
40+
#elif defined(__FreeBSD__) && defined(PW_PATH)
41+
42+
sys_string command = S(PW_PATH " adduser '") + name + S("' -d " WSDDN_DEFAULT_CHROOT_DIR " -s /bin/false -c \"WS-Discovery Daemon User\"");
43+
(void)!system(command.c_str());
44+
return true;
45+
46+
#else
47+
48+
return false;
49+
2650
#endif
27-
#elif HAVE_PW
28-
sys_string command = S(PW_PATH " adduser '") + name + S("' -d " WSDDN_DEFAULT_CHROOT_DIR " -s /bin/false -c \"WS-Discovery Daemon User\"");
29-
#endif
30-
(void)!system(command.c_str());
31-
auto pwd = ptl::Passwd::getByName(name);
32-
if (!pwd)
33-
throw std::runtime_error(fmt::format("unable to create user {}", name));
34-
return Identity(pwd->pw_uid, pwd->pw_gid);
35-
}
51+
}
52+
53+
auto Identity::createDaemonUser(const sys_string & name) -> std::optional<Identity> {
54+
55+
if (!runCreateDaemonUserCommands(name))
56+
return {};
57+
auto pwd = ptl::Passwd::getByName(name);
58+
if (!pwd)
59+
throw std::runtime_error(fmt::format("unable to create user {}", name));
60+
return Identity(pwd->pw_uid, pwd->pw_gid);
61+
}
3662

3763
#endif
3864

src/sys_util.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,7 @@ class Identity {
3131
#endif
3232
}
3333

34-
#if CAN_CREATE_USERS
35-
36-
static auto createDaemonUser(const sys_string & name) -> Identity;
37-
38-
#endif
34+
static auto createDaemonUser(const sys_string & name) -> std::optional<Identity>;
3935

4036
void setMyIdentity() const {
4137
ptl::setGroups({});

src/sys_util_mac.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ static auto createRecordWithUniqueId(const cf_ptr<ODNodeRef> & localNode,
201201
return {record, idValue};
202202
}
203203

204-
auto Identity::createDaemonUser(const sys_string & name) -> Identity {
204+
auto Identity::createDaemonUser(const sys_string & name) -> std::optional<Identity> {
205205

206206
cf_ptr<CFErrorRef> err;
207207

0 commit comments

Comments
 (0)