2024-02-15 00:17:20 +01:00
|
|
|
#include "sandbox.h"
|
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
#include "entry.h"
|
2024-02-15 00:17:20 +01:00
|
|
|
|
|
|
|
#include <stdio.h>
|
2024-02-15 19:42:22 +01:00
|
|
|
#include <stdlib.h>
|
2024-02-16 17:13:52 +01:00
|
|
|
#include <string.h>
|
2024-02-17 23:59:38 +01:00
|
|
|
#include <errno.h>
|
2024-02-17 15:15:40 +01:00
|
|
|
#include <pwd.h>
|
|
|
|
#include <unistd.h>
|
2024-02-17 23:59:38 +01:00
|
|
|
|
|
|
|
Command COMMANDS[] = {
|
|
|
|
{CommandHelp, "help", "[command]", "Prints this help message.",
|
|
|
|
"TODO: Add details."},
|
|
|
|
{CommandVersion, "version", NULL, "Prints the version of the program.",
|
|
|
|
"TODO: Add details."},
|
2024-02-17 00:40:09 +01:00
|
|
|
};
|
|
|
|
|
2024-02-15 00:17:20 +01:00
|
|
|
int main(int argc, char* argv[]) {
|
2024-02-17 23:59:38 +01:00
|
|
|
struct passwd* pw = getpwnam(SANDBOX_USER);
|
|
|
|
if (pw == NULL) {
|
|
|
|
Log(LOG_LEVEL_ERROR, "Failed to get the 'sandbox' user (%s).", strerror(errno));
|
2024-02-17 15:15:40 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
// Check if the current user is root or the 'sandbox' user
|
|
|
|
if (getuid() != 0 && getuid() != pw->pw_uid) {
|
|
|
|
Log(LOG_LEVEL_ERROR, "You must be root or the 'sandbox' user to use this program.");
|
2024-02-17 15:15:40 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
// Try and switch to the 'sandbox' user if we are root
|
2024-02-17 15:15:40 +01:00
|
|
|
if (geteuid() == 0) {
|
2024-02-17 23:59:38 +01:00
|
|
|
if (setregid(pw->pw_gid, pw->pw_gid) == -1) {
|
|
|
|
Log(LOG_LEVEL_ERROR, "Failed to set the real and effective group ID to the 'sandbox' user (%s).", strerror(errno));
|
2024-02-17 15:15:40 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
if (setreuid(pw->pw_uid, pw->pw_uid) == -1) {
|
|
|
|
Log(LOG_LEVEL_ERROR, "Failed to set the real and effective user ID to the 'sandbox' user (%s).", strerror(errno));
|
2024-02-17 15:15:40 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
// If there are no arguments, print the help message
|
|
|
|
if (argc == 1)
|
|
|
|
return CommandHelp(0, NULL);
|
2024-02-17 00:40:09 +01:00
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
const char* input = argv[1];
|
|
|
|
size_t input_length = strlen(input);
|
2024-02-17 00:40:09 +01:00
|
|
|
|
|
|
|
const Command* command = NULL;
|
2024-02-17 23:59:38 +01:00
|
|
|
for (size_t i = 0; i < sizeof(COMMANDS) / sizeof(COMMANDS[0]); i++) {
|
2024-02-17 00:40:09 +01:00
|
|
|
if (COMMANDS[i].name == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (input_length > strlen(COMMANDS[i].name))
|
|
|
|
continue;
|
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
if (strncmp(input, COMMANDS[i].name, input_length) == 0) {
|
2024-02-17 00:40:09 +01:00
|
|
|
if (command != NULL) {
|
2024-02-17 23:59:38 +01:00
|
|
|
Log(LOG_LEVEL_ERROR, "Ambiguous command '%s'.", input);
|
2024-02-17 00:40:09 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
command = &COMMANDS[i];
|
|
|
|
}
|
2024-02-16 17:13:52 +01:00
|
|
|
}
|
2024-02-16 16:53:02 +01:00
|
|
|
|
2024-02-16 17:13:52 +01:00
|
|
|
if (command == NULL) {
|
2024-02-17 23:59:38 +01:00
|
|
|
Log(LOG_LEVEL_ERROR, "Unknown command '%s'.", input);
|
2024-02-17 00:40:09 +01:00
|
|
|
return EXIT_FAILURE;
|
2024-02-16 17:13:52 +01:00
|
|
|
}
|
2024-02-16 16:53:02 +01:00
|
|
|
|
2024-02-17 00:40:09 +01:00
|
|
|
return command->handler(argc - 2, argv + 2);
|
|
|
|
}
|
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
int CommandHelp(int argc, char* argv[]) {
|
2024-02-17 00:40:09 +01:00
|
|
|
if (argc == 0) {
|
2024-02-17 23:59:38 +01:00
|
|
|
fprintf(stdout, "Usage: sandbox <command> [arguments] [options]\n");
|
|
|
|
fprintf(stdout, "\n");
|
2024-02-17 00:40:09 +01:00
|
|
|
fprintf(stdout, "Commands:\n");
|
2024-02-17 23:59:38 +01:00
|
|
|
for (size_t i = 0; i < sizeof(COMMANDS) / sizeof(COMMANDS[0]); i++) {
|
|
|
|
if (COMMANDS[i].name == NULL) {
|
|
|
|
fprintf(stdout, "\n");
|
2024-02-17 00:40:09 +01:00
|
|
|
continue;
|
|
|
|
}
|
2024-02-16 23:26:29 +01:00
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
fprintf(stdout, " %s", COMMANDS[i].name);
|
|
|
|
if (COMMANDS[i].arguments != NULL)
|
|
|
|
fprintf(stdout, " %s", COMMANDS[i].arguments);
|
|
|
|
fprintf(stdout, " - %s\n", COMMANDS[i].description);
|
2024-02-17 00:40:09 +01:00
|
|
|
}
|
2024-02-16 17:19:56 +01:00
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
fprintf(stdout, "\nFor more information, run 'sandbox help <command>'.\n");
|
2024-02-17 00:40:09 +01:00
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
2024-02-17 23:59:38 +01:00
|
|
|
} else if (argc == 1) {
|
|
|
|
const char* input = argv[0];
|
2024-02-17 14:38:52 +01:00
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
for (size_t i = 0; i < sizeof(COMMANDS) / sizeof(COMMANDS[0]); i++) {
|
|
|
|
if (COMMANDS[i].name == NULL)
|
|
|
|
continue;
|
2024-02-17 14:38:52 +01:00
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
if (strcmp(input, COMMANDS[i].name) == 0) {
|
|
|
|
fprintf(stdout, "Usage: sandbox %s", COMMANDS[i].name);
|
|
|
|
if (COMMANDS[i].arguments != NULL)
|
|
|
|
fprintf(stdout, " %s", COMMANDS[i].arguments);
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
fprintf(stdout, "%s\n", COMMANDS[i].description);
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
fprintf(stdout, "%s\n", COMMANDS[i].details);
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
2024-02-17 14:38:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
Log(LOG_LEVEL_ERROR, "Unknown command '%s'.", input);
|
2024-02-17 14:38:52 +01:00
|
|
|
return EXIT_FAILURE;
|
2024-02-17 23:59:38 +01:00
|
|
|
} else {
|
|
|
|
Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'help'.");
|
2024-02-17 15:15:40 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
2024-02-17 12:00:17 +01:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2024-02-17 23:59:38 +01:00
|
|
|
int CommandVersion(int argc, char* argv[]) {
|
|
|
|
fprintf(stdout, "Sandbox utility v%s\n", VERSION);
|
2024-02-17 12:00:17 +01:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|