#include <err.h>
#include <errno.h>
#include <pwd.h>
#include <spawn.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/debug.h>
#include <sys/types.h>
#include <sys/wait.h>
#define TARGET "zdump"
extern char **environ;
static bool
spawn_and_reap(const char *desc, const posix_spawnattr_t *attr)
{
char *argv[] = { TARGET, NULL };
pid_t pid;
int ret, status;
ret = posix_spawnp(&pid, TARGET, NULL, attr, argv, environ);
if (ret != 0) {
warnc(ret, "TEST FAILED: %s: posix_spawnp returned %d",
desc, ret);
return (false);
}
if (waitpid(pid, &status, 0) != pid) {
warn("TEST FAILED: %s: waitpid", desc);
return (false);
}
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
warnx("TEST FAILED: %s: unexpected wait status %#x",
desc, status);
return (false);
}
return (true);
}
int
main(void)
{
posix_spawnattr_t attr;
struct passwd *pw;
int ret = EXIT_SUCCESS;
if (getuid() != 0 && geteuid() != 0)
errx(EXIT_FAILURE, "this test must be run as root");
VERIFY0(unsetenv("PATH"));
if (spawn_and_reap("uid 0, euid 0 default path includes /usr/sbin",
NULL)) {
(void) printf("TEST PASSED: uid 0, euid 0 default path "
"includes /usr/sbin\n");
} else {
ret = EXIT_FAILURE;
}
if ((pw = getpwnam("nobody")) == NULL)
errx(EXIT_FAILURE, "could not look up user 'nobody'");
VERIFY0(setreuid(pw->pw_uid, 0));
if (spawn_and_reap("euid 0 default path includes /usr/sbin",
NULL)) {
(void) printf("TEST PASSED: euid 0 default path "
"includes /usr/sbin\n");
} else {
ret = EXIT_FAILURE;
}
VERIFY0(posix_spawnattr_init(&attr));
VERIFY0(posix_spawnattr_setflags(&attr, POSIX_SPAWN_RESETIDS));
if (spawn_and_reap("default path unaffected by RESETIDS", &attr)) {
(void) printf("TEST PASSED: default path unaffected by "
"RESETIDS\n");
} else {
ret = EXIT_FAILURE;
}
VERIFY0(posix_spawnattr_destroy(&attr));
if (ret == EXIT_SUCCESS)
(void) printf("All tests passed successfully!\n");
return (ret);
}