#include <sys/param.h>
#include <alloca.h>
#include <errno.h>
#include <locale.h>
#include <priv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define PFEXEC "pfexec"
#ifndef TEXT_DOMAIN
#define TEXT_DOMAIN "SYS_TEST"
#endif
#define RES_PFEXEC 1
#define RES_OK 0
#define RES_FAILURE -1
int
shellname(const char *name, char buf[MAXPATHLEN])
{
const char *cmd = strrchr(name, '/');
if (cmd == NULL)
cmd = name;
else
cmd++;
if (strncmp(cmd, "pf", 2) != 0)
return (RES_FAILURE);
if (strcmp(cmd, PFEXEC) == 0)
return (RES_PFEXEC);
if (strlen(name) >= MAXPATHLEN)
return (RES_FAILURE);
if (cmd == name) {
(void) strlcpy(buf, cmd + 2, MAXPATHLEN);
} else {
(void) strncpy(buf, name, cmd - name);
(void) strcpy(buf + (cmd - name), cmd + 2);
}
return (RES_OK);
}
static void
usage(void)
{
(void) fprintf(stderr, gettext("pfexec [-P privset] cmd [arg ..]\n"));
exit(EXIT_FAILURE);
}
int
main(int argc, char **argv)
{
char *cmd;
char *pset = NULL;
char pathbuf[MAXPATHLEN];
int c;
priv_set_t *wanted;
int oflag;
oflag = getpflags(PRIV_PFEXEC);
if (setpflags(PRIV_PFEXEC, 1) != 0) {
(void) fprintf(stderr,
gettext("pfexec: unable to set PFEXEC flag: %s\n"),
strerror(errno));
exit(1);
}
if (*argv[0] == '-')
cmd = argv[0] + 1;
else
cmd = argv[0];
if (strncmp(cmd, "pf", 2) == 0) {
argv[0] += 2;
if (argv[0][-2] == '-')
*argv[0] = '-';
}
if (shellname(getexecname(), pathbuf) == RES_OK)
(void) execv(pathbuf, argv);
switch (shellname(cmd, pathbuf)) {
case RES_OK:
(void) execv(pathbuf, argv);
(void) fprintf(stderr,
gettext("pfexec: unable to execute %s: %s\n"),
pathbuf, strerror(errno));
return (1);
case RES_PFEXEC:
case RES_FAILURE:
while ((c = getopt(argc, argv, "P:")) != EOF) {
switch (c) {
case 'P':
if (pset == NULL) {
pset = optarg;
break;
}
default:
usage();
}
}
argc -= optind;
argv += optind;
if (argc < 1)
usage();
if (pset != NULL) {
if ((wanted = priv_str_to_set(pset, ",", NULL)) ==
NULL) {
(void) fprintf(stderr,
gettext("pfexec: error parsing "
"privileges: %s\n"), strerror(errno));
exit(EXIT_FAILURE);
}
if (setppriv(PRIV_ON, PRIV_INHERITABLE, wanted) != 0) {
(void) fprintf(stderr,
gettext("pfexec: error setting "
"privileges: %s\n"), strerror(errno));
exit(EXIT_FAILURE);
}
(void) setpflags(PRIV_PFEXEC, oflag);
}
(void) execvp(argv[0], argv);
(void) fprintf(stderr,
gettext("pfexec: unable to execute %s: %s\n"),
argv[0], strerror(errno));
return (1);
}
return (1);
}