50 privdrop(
const char *username,
const char *groupname,
const char *newroot)
62 int final_group_len = -1;
65 uid = olduid = geteuid();
66 gid = oldgid = getegid();
71 if ((pwd = getpwnam(username)) == NULL) {
73 syslog_r(LOG_ERR, &sdata,
"user '%s' does not exist. exiting...\n", username);
75 syslog(LOG_ERR,
"user '%s' does not exist. exiting...\n", username);
87 if ((grp = getgrnam(groupname)) == NULL) {
89 syslog_r(LOG_ERR, &sdata,
"group '%s' does not exist. exiting...\n", groupname);
91 syslog(LOG_ERR,
"group '%s' does not exist. exiting...\n", groupname);
102 if (chroot(newroot) != 0 || chdir(
"/") != 0) {
104 syslog_r(LOG_ERR, &sdata,
"chroot to '%s' failed. exiting...\n", newroot);
106 syslog(LOG_ERR,
"chroot to '%s' failed. exiting...\n", newroot);
113 if (username != NULL && !olduid) {
114 if (initgroups(username, gid) < 0) {
116 syslog_r(LOG_ERR, &sdata,
"initgroups failed: %s: %.100s", username, strerror(errno));
118 syslog(LOG_ERR,
"initgroups failed: %s: %.100s", username, strerror(errno));
123 ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1;
124 final_groups = (gid_t *)malloc(ngroups_max *
sizeof(gid_t));
125 if (final_groups == NULL) {
127 syslog_r(LOG_ERR, &sdata,
"Malloc for group struct failed");
129 syslog(LOG_ERR,
"Malloc for group struct failed");
134 final_group_len = getgroups(ngroups_max, final_groups);
136 if (!olduid) setgroups(final_group_len, final_groups);
142 if (!olduid) setgroups(1, &(gid));
148 #if defined(HAVE_SETRESGID) && !defined(BROKEN_SETRESGID)
149 status = setresgid(gid, gid, gid);
150 #elif defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID)
151 status = setregid(gid, gid);
153 status = setegid(gid);
156 syslog_r(LOG_ERR, &sdata,
"unable to drop group privileges: %s (%lu). exiting...\n",
157 groupname, (
unsigned long) gid);
159 syslog(LOG_ERR,
"unable to drop group privileges: %s (%lu). exiting...\n",
160 groupname, (
unsigned long) gid);
164 status = setgid(gid);
169 syslog_r(LOG_ERR, &sdata,
"unable to drop group privileges: %s (%lu). exiting...\n",
170 groupname, (
unsigned long) gid);
172 syslog(LOG_ERR,
"unable to drop group privileges: %s (%lu). exiting...\n",
173 groupname, (
unsigned long) gid);
179 syslog_r(LOG_ERR, &sdata,
"group set to: %s (%lu)\n", groupname, (
unsigned long) gid);
181 syslog(LOG_ERR,
"group set to: %s (%lu)\n", groupname, (
unsigned long) gid);
189 #if defined(HAVE_SETRESUID) && !defined(BROKEN_SETRESUID)
190 status = setresuid(uid, uid, uid);
191 #elif defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID)
192 status = setreuid(uid, uid);
195 # ifndef SETEUID_BREAKS_SETUID
196 status = seteuid(uid);
199 syslog_r(LOG_ERR, &sdata,
"unable to drop user privileges (seteuid): %s (%lu). exiting...\n",
200 username, (
unsigned long) uid);
202 syslog(LOG_ERR,
"unable to drop user privileges (seteuid): %s (%lu). exiting...\n",
203 username, (
unsigned long) uid);
209 status = setuid(uid);
214 syslog_r(LOG_ERR, &sdata,
"unable to drop user privileges: %s (%lu). exiting...\n",
215 username, (
unsigned long) uid);
217 syslog(LOG_ERR,
"unable to drop user privileges: %s (%lu). exiting...\n",
218 username, (
unsigned long) uid);
224 syslog_r(LOG_ERR, &sdata,
"user set to: %s (%lu)\n", username, (
unsigned long) uid);
226 syslog(LOG_ERR,
"user set to: %s (%lu)\n", username, (
unsigned long) uid);
int privdrop(const char *username, const char *groupname, const char *newroot)