@@ -10,45 +10,104 @@ 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 ([[maybe_unused]] const sys_string & name) -> bool {
16+
17+ #if defined(__linux__) && defined(USERADD_PATH)
18+
19+ (void )run ({USERADD_PATH, " -r" , " -d" , WSDDN_DEFAULT_CHROOT_DIR, " -s" , " /bin/false" , name.c_str ()});
20+ return true ;
21+
22+ #elif defined(__linux__) && defined(IS_ALPINE_LINUX) && defined(ADDUSER_PATH) && defined(ADDGROUP_PATH)
23+
24+ // The second addgroup instead of -G for adduser is necessary since for some reason -G doesn't
25+ // modify /etc/group when run from here
26+ (void )run ({ADDGROUP_PATH, " -S" , name.c_str ()});
27+ (void )run ({ADDUSER_PATH, " -S" , " -D" , " -H" , " -h" , " /var/empty" , " -s" , " /sbin/nologin" , " -g" , name.c_str (), name.c_str ()});
28+ (void )run ({ADDGROUP_PATH, name.c_str (), name.c_str ()});
29+ return true ;
30+
31+ #elif (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(USERADD_PATH)
1632
17- #if HAVE_USERADD
18- #ifdef __linux__
19- sys_string command = S (" useradd -r -d " WSDDN_DEFAULT_CHROOT_DIR " -s /bin/false '" ) + name + S (" '" );
20- #else
21- sys_string command = S (" useradd -L daemon -g =uid -d " WSDDN_DEFAULT_CHROOT_DIR " -s /sbin/nologin -c \" WS-Discovery Daemon\" '" ) + name + S (" '" );
2233 createMissingDirs (WSDDN_DEFAULT_CHROOT_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, Identity::admin ());
34+ (void )run ({USERADD_PATH, " -L" , " daemon" , " -g" , " =uid" , " -d" , WSDDN_DEFAULT_CHROOT_DIR, " -s" , " /sbin/nologin" , " -c" , " WS-Discovery Daemon" , name.c_str ()});
35+ return true ;
36+
37+ #elif defined(__HAIKU__) && defined(USERADD_PATH) && defined(GROUPADD_PATH)
38+
39+ (void )run ({GROUPADD_PATH, name.c_str ()});
40+ (void )run ({USERADD_PATH, " -g" , name.c_str (), " -d" , WSDDN_DEFAULT_CHROOT_DIR, " -s" , " /bin/false" , " -n" , " WS-Discovery Daemon" , name.c_str ()});
41+ return true ;
42+
43+ #elif defined(__FreeBSD__) && defined(PW_PATH)
44+
45+ (void )run ({PW_PATH, " adduser" , name.c_str (), " -d" , WSDDN_DEFAULT_CHROOT_DIR, " -s" , " /usr/sbin/nologin" , " -c" , " WS-Discovery Daemon User" });
46+ return true ;
47+
48+ #elif defined(__sun) && defined(USERADD_PATH) && defined(GROUPADD_PATH)
49+
50+ (void )run ({GROUPADD_PATH, name.c_str ()});
51+ (void )run ({USERADD_PATH, " -g" , name.c_str (), " -d" , WSDDN_DEFAULT_CHROOT_DIR, " -s" , " /bin/false" , " -c" , " WS-Discovery Daemon User" , name.c_str ()});
52+ return true ;
53+
54+ #else
55+
56+ return false ;
57+
2358 #endif
24- #elif HAVE_PW
25- sys_string command = S (" pw adduser '" ) + name + S (" ' -d " WSDDN_DEFAULT_CHROOT_DIR " -s /bin/false -c \" WS-Discovery Daemon User\" " );
59+ }
60+
61+ auto Identity::createDaemonUser (const sys_string & name) -> std::optional<Identity> {
62+
63+ if (!runCreateDaemonUserCommands (name))
64+ return {};
65+ auto pwd = ptl::Passwd::getByName (name);
66+ if (!pwd)
67+ throw std::runtime_error (fmt::format (" unable to create user {}" , name));
68+ return Identity (pwd->pw_uid , pwd->pw_gid );
69+ }
70+
2671#endif
27- (void )!system (command.c_str ());
28- auto pwd = ptl::Passwd::getByName (name);
29- if (!pwd)
30- throw std::runtime_error (fmt::format (" unable to create user {}" , name));
31- return Identity (pwd->pw_uid , pwd->pw_gid );
32- }
3372
73+ int run (const ptl::StringRefArray & args) {
74+ ptl::SpawnAttr spawnAttr;
75+ #ifndef __HAIKU__
76+ spawnAttr.setFlags (POSIX_SPAWN_SETSIGDEF);
77+ auto sigs = ptl::SignalSet::all ();
78+ sigs.del (SIGKILL);
79+ sigs.del (SIGSTOP);
80+ spawnAttr.setSigDefault (sigs);
3481#endif
82+
83+ auto proc = spawn (args, ptl::SpawnSettings ().attr (spawnAttr).usePath ());
84+
85+ auto stat = proc.wait ().value ();
86+ if (WIFEXITED (stat))
87+ return WEXITSTATUS (stat);
88+ if (WIFSIGNALED (stat))
89+ return 128 +WTERMSIG (stat);
90+ throw std::runtime_error (fmt::format (" `{} finished with status 0x{:X}`" , args, stat));
91+ }
3592
3693void shell (const ptl::StringRefArray & args, bool suppressStdErr, std::function<void (const ptl::FileDescriptor & fd)> reader) {
3794 auto [read, write] = ptl::Pipe::create ();
3895 ptl::SpawnAttr spawnAttr;
96+ #ifndef __HAIKU__
3997 spawnAttr.setFlags (POSIX_SPAWN_SETSIGDEF);
4098 auto sigs = ptl::SignalSet::all ();
4199 sigs.del (SIGKILL);
42100 sigs.del (SIGSTOP);
43101 spawnAttr.setSigDefault (sigs);
102+ #endif
44103
45104 ptl::SpawnFileActions act;
46105 act.addDuplicateTo (write, stdout);
47106 act.addClose (read);
48107 if (suppressStdErr) {
49108 act.addOpen (stderr, " /dev/null" , O_WRONLY, 0 );
50109 }
51- auto proc = spawn (args, ptl::SpawnSettings ().fileActions (act).usePath ());
110+ auto proc = spawn (args, ptl::SpawnSettings ().attr (spawnAttr). fileActions (act).usePath ());
52111 write.close ();
53112
54113 reader (read);
0 commit comments