123 lines
3.2 KiB
C
123 lines
3.2 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include <limits.h>
|
|
#include <pwd.h>
|
|
|
|
void *emalloc(void *ptr, size_t size) {
|
|
void *m = realloc(ptr,size);
|
|
if (size != 0 && m == NULL) {
|
|
fprintf(stderr,"["APP_NAME"] Error 255: realloc() failed\n");
|
|
exit(255);
|
|
}
|
|
return m;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
if (clearenv() != 0) { // Clear environment to boost security
|
|
fprintf(stderr,"["APP_NAME"] Error 254: Clearing environment failed\n");
|
|
exit(254);
|
|
}
|
|
|
|
uid_t uid = getuid(); // User who's calling the program
|
|
gid_t gid = getgid(); // Group that's calling the program
|
|
uid_t euid = geteuid(); // User who owns the program
|
|
gid_t egid = getegid(); // Group that owns the program
|
|
|
|
// ENV
|
|
// PATH
|
|
if (euid == 0) {
|
|
setenv("PATH","/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",1);
|
|
} else {
|
|
setenv("PATH","/usr/local/bin:/usr/bin:/bin",1);
|
|
}
|
|
|
|
// UID, USER, HOME
|
|
char passwStore[sizeof(struct passwd)];
|
|
sprintf(passwStore,"%d",euid);
|
|
setenv("UID",passwStore,1);
|
|
struct passwd * pw = getpwuid(euid);
|
|
if (pw == NULL) {
|
|
fprintf(stderr,"["APP_NAME"] Error 253: Failed to get user information (errno: %d: %s)\n",errno,strerror(errno));
|
|
return 253;
|
|
}
|
|
setenv("USER",pw -> pw_name,1);
|
|
setenv("HOME",pw -> pw_dir,1);
|
|
|
|
// Strip first argument, and move them by 1
|
|
char **cmd;
|
|
if (argc > 1) {
|
|
cmd = emalloc(NULL,argc * sizeof(char*));
|
|
int i = 1;
|
|
while (i < argc) {
|
|
cmd[i - 1] = argv[i];
|
|
++i;
|
|
}
|
|
cmd[argc - 1] = NULL;
|
|
} else {
|
|
fprintf(stderr,"["APP_NAME"] Error 252: Invalid syntax, use: %s <command> ...\n",argv[0]);
|
|
return 252;
|
|
}
|
|
|
|
int file;
|
|
file = open(APP_CONF"/commands.conf",O_RDONLY);
|
|
if (file == -1) {
|
|
fprintf(stderr,"["APP_NAME"] Error 251: Failed opening "APP_CONF"/commands.conf (errno %d: %s)\n",errno,strerror(errno));
|
|
return 251;
|
|
}
|
|
|
|
char program[PATH_MAX];
|
|
program[0] = 0;
|
|
{
|
|
int lineIndex = 0;
|
|
ssize_t size;
|
|
while (1) {
|
|
size = read(file,(void *)(program + lineIndex),1);
|
|
if (size == -1) {
|
|
fprintf(stderr,"["APP_NAME"] Error 250: Failed reading commands.conf (errno %d: %s)\n",errno,strerror(errno));
|
|
return 250;
|
|
}
|
|
|
|
if ((program[lineIndex] == '\n') || (size == 0)) { // end of line/file
|
|
program[lineIndex] = 0;
|
|
|
|
if (strcmp(program,cmd[0]) == 0) { // command found
|
|
break;
|
|
}
|
|
|
|
program[0] = 0;
|
|
lineIndex = 0;
|
|
} else {
|
|
++lineIndex;
|
|
}
|
|
|
|
if (size == 0) { // end of file
|
|
fprintf(stderr,"["APP_NAME"] Error 249: Requested program is not in commands.conf\n");
|
|
return 249;
|
|
}
|
|
|
|
if (lineIndex >= PATH_MAX) { // line is too long (this could be handled better)
|
|
fprintf(stderr,"["APP_NAME"] Error 248: Malformed commands.conf (line longer than %d bytes)\n",PATH_MAX);
|
|
return 248;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get permissions
|
|
if (setreuid(euid,egid) == -1) {
|
|
fprintf(stderr,"["APP_NAME"] Error 247: Failed to elevate user (errno %d: %s)\n",errno,strerror(errno));
|
|
return 247;
|
|
}
|
|
|
|
// Run progrem
|
|
if (execvp(cmd[0],cmd) == -1) {
|
|
setreuid(uid,gid);
|
|
fprintf(stderr,"["APP_NAME"] Error 246: Failed launching process (errno %d: %s)\n",errno,strerror(errno));
|
|
return 246;
|
|
}
|
|
return 0;
|
|
}
|