| 33 | |
| 34 | |
| 35 | void drop_root() |
| 36 | { |
| 37 | if (getegid() == 0) |
| 38 | { |
| 39 | std::cout << "[INFO] Dropping root group privileges to " << OPENVPN_GROUP << std::endl; |
| 40 | |
| 41 | // Retrieve the group information |
| 42 | errno = 0; |
| 43 | struct group *groupinfo = getgrnam(OPENVPN_GROUP); |
| 44 | if (NULL == groupinfo) |
| 45 | { |
| 46 | if (errno == 0) |
| 47 | { |
| 48 | throw std::runtime_error("Could not find the group ID for " + std::string(OPENVPN_GROUP)); |
| 49 | } |
| 50 | throw std::runtime_error("An error occurred while calling getgrnam():" |
| 51 | + std::string(strerror(errno))); |
| 52 | } |
| 53 | gid_t gid = groupinfo->gr_gid; |
| 54 | if (-1 == setresgid(gid, gid, gid)) |
| 55 | { |
| 56 | throw std::runtime_error("Could not set the new group ID (" + std::to_string(gid) + ") " |
| 57 | + "for the user " + std::string(OPENVPN_GROUP)); |
| 58 | } |
| 59 | |
| 60 | // Remove any potential supplementary groups |
| 61 | if (-1 == setgroups(0, NULL)) |
| 62 | { |
| 63 | throw std::runtime_error("Could not remove supplementary groups"); |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | if (geteuid() == 0) |
| 68 | { |
| 69 | std::cout << "[INFO] Dropping root user privileges to " << OPENVPN_USERNAME << std::endl; |
| 70 | |
| 71 | // Retrieve the user information |
| 72 | struct passwd *userinfo = getpwnam(OPENVPN_USERNAME); |
| 73 | if (NULL == userinfo) |
| 74 | { |
| 75 | if (errno == 0) |
| 76 | { |
| 77 | throw std::runtime_error("Could not find the User ID for " + std::string(OPENVPN_USERNAME)); |
| 78 | } |
| 79 | throw std::runtime_error("An error occurred while calling getgrnam():" |
| 80 | + std::string(strerror(errno))); |
| 81 | } |
| 82 | |
| 83 | uid_t uid = userinfo->pw_uid; |
| 84 | if (-1 == setresuid(uid, uid, uid)) |
| 85 | { |
| 86 | throw std::runtime_error("Could not set the new user ID (" + std::to_string(uid) + ") " |
| 87 | + "for the user " + OPENVPN_USERNAME); |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | |
| 92 |
no outgoing calls