48 privdrop(
const char *username,
const char *groupname,
const char *newroot)
60 int final_group_len = -1;
63 uid = olduid = geteuid();
64 gid = oldgid = getegid();
69 if ((pwd = getpwnam(username)) == NULL) {
71 syslog_r(LOG_ERR, &sdata,
"user '%s' does not exist. exiting...\n", username);
73 syslog(LOG_ERR,
"user '%s' does not exist. exiting...\n", username);
85 if ((grp = getgrnam(groupname)) == NULL) {
87 syslog_r(LOG_ERR, &sdata,
"group '%s' does not exist. exiting...\n", groupname);
89 syslog(LOG_ERR,
"group '%s' does not exist. exiting...\n", groupname);
100 if (chroot(newroot) != 0 || chdir(
"/") != 0) {
102 syslog_r(LOG_ERR, &sdata,
"chroot to '%s' failed. exiting...\n", newroot);
104 syslog(LOG_ERR,
"chroot to '%s' failed. exiting...\n", newroot);
111 if (username != NULL && !olduid) {
112 if (initgroups(username, gid) < 0) {
114 syslog_r(LOG_ERR, &sdata,
"initgroups failed: %s: %.100s", username, strerror(errno));
116 syslog(LOG_ERR,
"initgroups failed: %s: %.100s", username, strerror(errno));
121 ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1;
122 final_groups = (gid_t *)malloc(ngroups_max *
sizeof(gid_t));
123 if (final_groups == NULL) {
125 syslog_r(LOG_ERR, &sdata,
"Malloc for group struct failed");
127 syslog(LOG_ERR,
"Malloc for group struct failed");
132 final_group_len = getgroups(ngroups_max, final_groups);
134 if (!olduid) setgroups(final_group_len, final_groups);
140 if (!olduid) setgroups(1, &(gid));
146 #if defined(HAVE_SETRESGID) && !defined(BROKEN_SETRESGID)
147 status = setresgid(gid, gid, gid);
148 #elif defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID)
149 status = setregid(gid, gid);
151 status = setegid(gid);
154 syslog_r(LOG_ERR, &sdata,
"unable to drop group privileges: %s (%lu). exiting...\n",
155 groupname, (
unsigned long) gid);
157 syslog(LOG_ERR,
"unable to drop group privileges: %s (%lu). exiting...\n",
158 groupname, (
unsigned long) gid);
162 status = setgid(gid);
167 syslog_r(LOG_ERR, &sdata,
"unable to drop group privileges: %s (%lu). exiting...\n",
168 groupname, (
unsigned long) gid);
170 syslog(LOG_ERR,
"unable to drop group privileges: %s (%lu). exiting...\n",
171 groupname, (
unsigned long) gid);
177 syslog_r(LOG_ERR, &sdata,
"group set to: %s (%lu)\n", groupname, (
unsigned long) gid);
179 syslog(LOG_ERR,
"group set to: %s (%lu)\n", groupname, (
unsigned long) gid);
187 #if defined(HAVE_SETRESUID) && !defined(BROKEN_SETRESUID)
188 status = setresuid(uid, uid, uid);
189 #elif defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID)
190 status = setreuid(uid, uid);
193 # ifndef SETEUID_BREAKS_SETUID
194 status = seteuid(uid);
197 syslog_r(LOG_ERR, &sdata,
"unable to drop user privileges (seteuid): %s (%lu). exiting...\n",
198 username, (
unsigned long) uid);
200 syslog(LOG_ERR,
"unable to drop user privileges (seteuid): %s (%lu). exiting...\n",
201 username, (
unsigned long) uid);
207 status = setuid(uid);
212 syslog_r(LOG_ERR, &sdata,
"unable to drop user privileges: %s (%lu). exiting...\n",
213 username, (
unsigned long) uid);
215 syslog(LOG_ERR,
"unable to drop user privileges: %s (%lu). exiting...\n",
216 username, (
unsigned long) uid);
222 syslog_r(LOG_ERR, &sdata,
"user set to: %s (%lu)\n", username, (
unsigned long) uid);
224 syslog(LOG_ERR,
"user set to: %s (%lu)\n", username, (
unsigned long) uid);
int privdrop(const char *username, const char *groupname, const char *newroot)