49 #include <sys/prctl.h>
60 const char *top =
"/";
63 msg(
M_ERR,
"chroot to '%s' failed", path);
67 msg(
M_ERR,
"cd to '%s' failed", top);
69 msg(
M_INFO,
"chroot to '%s' and cd to '%s' succeeded", path, top);
71 msg(
M_FATAL,
"Sorry but I can't chroot to '%s' because this operating system doesn't appear to support the chroot() system call", path);
85 #if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID)
87 const struct passwd *pw = getpwnam(username);
90 msg(
M_ERR,
"failed to find UID for user %s", username);
94 state->uid = pw->pw_uid;
96 state->username = username;
99 msg(
M_FATAL,
"cannot get UID for user %s -- platform lacks getpwname() or setuid() system calls", username);
108 #if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID)
109 if (state->username && state->uid >= 0)
111 if (setuid(state->uid))
113 msg(
M_ERR,
"setuid('%s') failed", state->username);
115 msg(
M_INFO,
"UID set to %s", state->username);
129 #if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID)
131 const struct group *gr = getgrnam(groupname);
134 msg(
M_ERR,
"failed to find GID for group %s", groupname);
138 state->gid = gr->gr_gid;
140 state->groupname = groupname;
143 msg(
M_FATAL,
"cannot get GID for group %s -- platform lacks getgrnam() or setgid() system calls", groupname);
152 #if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID)
153 if (state->groupname && state->gid >= 0)
155 if (setgid(state->gid))
157 msg(
M_ERR,
"setgid('%s') failed", state->groupname);
159 msg(
M_INFO,
"GID set to %s", state->groupname);
160 #ifdef HAVE_SETGROUPS
163 gr_list[0] = state->gid;
164 if (setgroups(1, gr_list))
166 msg(
M_ERR,
"setgroups('%s') failed", state->groupname);
224 int new_gid = -1, new_uid = -1;
236 if (group_state->groupname && group_state->gid >= 0)
238 new_gid = group_state->gid;
240 if (user_state->username && user_state->uid >= 0)
242 new_uid = user_state->uid;
246 capng_clear(CAPNG_SELECT_BOTH);
247 res = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_NET_ADMIN);
250 msg(err_flags,
"capng_update(CAP_NET_ADMIN) failed: %d", res);
257 res = capng_change_id(new_uid, new_gid, CAPNG_DROP_SUPP_GRP);
258 if (res == -4 || res == -6)
262 msg(
M_ERR,
"capng_change_id('%s','%s') failed: %d",
263 user_state->username, group_state->groupname, res);
268 msg(err_flags,
"NOTE: previous error likely due to missing capability CAP_SETPCAP.");
273 msg(err_flags |
M_ERRNO,
"capng_change_id('%s','%s') failed retaining capabilities: %d",
274 user_state->username, group_state->groupname, res);
280 msg(
M_INFO,
"UID set to %s", user_state->username);
284 msg(
M_INFO,
"GID set to %s", group_state->groupname);
287 msg(
M_INFO,
"Capabilities retained: CAP_NET_ADMIN");
294 if (prctl(PR_GET_KEEPCAPS) && prctl(PR_SET_KEEPCAPS, 0) < 0)
296 msg(
M_ERR,
"Clearing KEEPCAPS flag failed");
302 msg(err_flags,
"Unable to retain capabilities");
317 if (nice(niceval) < 0 && errno != 0)
323 msg(
M_INFO,
"nice %d succeeded", niceval);
326 msg(
M_WARN,
"WARNING: nice %d failed (function not implemented)", niceval);
336 return (
unsigned int) GetCurrentProcessId();
338 return (
unsigned int) getpid();
348 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_MEMLOCK)
349 #define MIN_LOCKED_MEM_MB 100
351 if (getrlimit(RLIMIT_MEMLOCK, &rl) < 0)
357 msg(
M_INFO,
"mlock: MEMLOCK limit: soft=%ld KB, hard=%ld KB",
358 ((
long int) rl.rlim_cur) / 1024, ((
long int) rl.rlim_max) / 1024);
359 if (rl.rlim_cur < MIN_LOCKED_MEM_MB*1024*1024)
361 msg(
M_INFO,
"mlock: RLIMIT_MEMLOCK < %d MB, increase limit",
363 rl.rlim_cur = MIN_LOCKED_MEM_MB*1024*1024;
364 if (rl.rlim_max < rl.rlim_cur)
366 rl.rlim_max = rl.rlim_cur;
368 if (setrlimit(RLIMIT_MEMLOCK, &rl) < 0)
376 if (mlockall(MCL_CURRENT | MCL_FUTURE))
385 msg(
M_WARN,
"WARNING: mlockall call failed (function not implemented)");
419 return stat != -1 && WIFEXITED(stat) && WEXITSTATUS(stat) == 0;
427 if (stat >= 0 && stat < 255)
440 if (!WIFEXITED(stat) || stat == -1)
445 int status = WEXITSTATUS(stat);
462 int ret = _waccess(
wide_string(path, &gc), mode & ~X_OK);
466 return access(path, mode);
480 tv.tv_sec = n / 1000;
481 tv.tv_usec = (n % 1000) * 1000;
482 select(0, NULL, NULL, NULL, &tv);
495 select(0, NULL, NULL, NULL, NULL);
505 BOOL ret = DeleteFileW(
wide_string(filename, &gc));
509 return (unlink(filename) == 0);
522 return fopen(path, mode);
531 int fd = _wopen(
wide_string(path, &gc), flags, mode);
535 return open(path, flags, mode);
548 return stat(path, buf);
557 const char *retfname = NULL;
558 unsigned int attempts = 0;
559 char fname[256] = { 0 };
560 const char *fname_fmt =
PACKAGE "_%.*s_%08lx%08lx.tmp";
561 const int max_prefix_len =
sizeof(fname) - (
sizeof(
PACKAGE) + 7 + (2 * 8));
567 if (!snprintf(fname,
sizeof(fname), fname_fmt, max_prefix_len,
571 msg(
M_WARN,
"ERROR: temporary filename too long");
578 msg(
M_WARN,
"Failed to create temporary filename and path");
584 fd =
platform_open(retfname, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
590 else if (fd == -1 && errno != EEXIST)
599 msg(
M_WARN,
"Failed to create temporary file after %i attempts", attempts);
614 const int CC_PATH_RESERVED =
CC_SLASH;
625 && strcmp(safe_filename,
".")
626 && strcmp(safe_filename,
"..")
632 const size_t outsize = strlen(safe_filename) + (directory ? strlen(directory) : 0) + 16;
658 const int c = pathname[0];
660 return c ==
'\\' || (isalpha(c) && pathname[1] ==
':' && pathname[2] ==
'\\');
694 filename ? filename :
"UNDEF",