Commit d2f8345a authored by jan.koester's avatar jan.koester
Browse files

test

parent 5da7c39c
Loading
Loading
Loading
Loading
+30 −5
Changes for src/service.cpp: 30 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -221,16 +221,41 @@ namespace syslite {
            setenv(key.c_str(), val.c_str(), 1);
        }

        // Drop privileges
        // Drop privileges. Group= defaults to User='s primary group; a
        // missing user/group or a failing call ends the child instead of
        // running the service with root's ids.
        if (!entry.unit.user.empty() || !entry.unit.group.empty()) {
            gid_t gid = 0;
            uid_t uid = 0;
            bool haveGid = false;
            if (!entry.unit.group.empty()) {
                struct group *gr = getgrnam(entry.unit.group.c_str());
            if (gr) setgid(gr->gr_gid);
                if (!gr) {
                    std::cerr << "[syslite] unknown group: " << entry.unit.group << std::endl;
                    _exit(126);
                }
                gid = gr->gr_gid;
                haveGid = true;
            }
            if (!entry.unit.user.empty()) {
                struct passwd *pw = getpwnam(entry.unit.user.c_str());
            if (pw) {
                initgroups(entry.unit.user.c_str(), pw->pw_gid);
                setuid(pw->pw_uid);
                if (!pw) {
                    std::cerr << "[syslite] unknown user: " << entry.unit.user << std::endl;
                    _exit(126);
                }
                uid = pw->pw_uid;
                if (!haveGid) gid = pw->pw_gid;
                if (initgroups(entry.unit.user.c_str(), gid) != 0) {
                    std::cerr << "[syslite] initgroups failed for " << entry.unit.user << std::endl;
                    _exit(126);
                }
            } else if (setgroups(0, nullptr) != 0) {
                std::cerr << "[syslite] setgroups failed" << std::endl;
                _exit(126);
            }
            if (setgid(gid) != 0 || (!entry.unit.user.empty() && setuid(uid) != 0)) {
                std::cerr << "[syslite] dropping privileges failed" << std::endl;
                _exit(126);
            }
        }