49 privdrop(
const char *username,
const char *groupname,
const char *newroot)
61 int final_group_len = -1;
64 uid = olduid = geteuid();
65 gid = oldgid = getegid();
70 if ((pwd = getpwnam(username)) == NULL) {
71 syslog(LOG_ERR,
"user '%s' does not exist. exiting...\n", username);
82 if ((grp = getgrnam(groupname)) == NULL) {
83 syslog(LOG_ERR,
"group '%s' does not exist. exiting...\n", groupname);
93 if (chroot(newroot) != 0 || chdir(
"/") != 0) {
94 syslog(LOG_ERR,
"chroot to '%s' failed. exiting...\n", newroot);
100 if (username != NULL && !olduid) {
101 if (initgroups(username, gid) < 0) {
102 syslog(LOG_ERR,
"initgroups failed: %s: %.100s", username, strerror(errno));
106 ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1;
107 final_groups = (gid_t *)malloc(ngroups_max *
sizeof(gid_t));
108 if (final_groups == NULL) {
109 syslog(LOG_ERR,
"Malloc for group struct failed");
113 final_group_len = getgroups(ngroups_max, final_groups);
115 if (!olduid) setgroups(final_group_len, final_groups);
121 if (!olduid) setgroups(1, &(gid));
127 #if defined(HAVE_SETRESGID) && !defined(BROKEN_SETRESGID)
128 status = setresgid(gid, gid, gid);
129 #elif defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID)
130 status = setregid(gid, gid);
132 status = setegid(gid);
134 syslog(LOG_ERR,
"unable to drop group privileges: %s (%lu). exiting...\n",
135 groupname, (
unsigned long) gid);
138 status = setgid(gid);
142 syslog(LOG_ERR,
"unable to drop group privileges: %s (%lu). exiting...\n",
143 groupname, (
unsigned long) gid);
147 syslog(LOG_ERR,
"group set to: %s (%lu)\n", groupname, (
unsigned long) gid);
154 #if defined(HAVE_SETRESUID) && !defined(BROKEN_SETRESUID)
155 status = setresuid(uid, uid, uid);
156 #elif defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID)
157 status = setreuid(uid, uid);
160 # ifndef SETEUID_BREAKS_SETUID
161 status = seteuid(uid);
163 syslog(LOG_ERR,
"unable to drop user privileges (seteuid): %s (%lu). exiting...\n",
164 username, (
unsigned long) uid);
169 status = setuid(uid);
173 syslog(LOG_ERR,
"unable to drop user privileges: %s (%lu). exiting...\n",
174 username, (
unsigned long) uid);
178 syslog(LOG_ERR,
"user set to: %s (%lu)\n", username, (
unsigned long) uid);