privlx/src/unpriv.c

104 lines
2.6 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,"[un"APP_NAME"] Error 255: realloc() failed\n");
exit(255);
}
return m;
}
int main(int argc, char **argv) {
char * env;
char * endptr;
// UID
env = getenv("SUDO_UID");
if (env == NULL) {
fprintf(stderr,"[un"APP_NAME"] Error 254: Could not query SUDO_UID (errno %d: %s)\n",errno,strerror(errno));
return 254;
}
uid_t euid = strtol(env,&endptr,0);
if (errno != 0) {
fprintf(stderr,"[un"APP_NAME"] Error 253: Could not convert SUDO_UID to number (errno %d: %s)\n",errno,strerror(errno));
return 253;
}
// GID
env = getenv("SUDO_GID");
if (env == NULL) {
fprintf(stderr,"[un"APP_NAME"] Error 254: Could not query SUDO_GID (errno %d: %s)\n",errno,strerror(errno));
return 254;
}
gid_t egid = strtol(env,&endptr,0);
if (errno != 0) {
fprintf(stderr,"[un"APP_NAME"] Error 253: Could not convert SUDO_GID to number (errno %d: %s)\n",errno,strerror(errno));
return 253;
}
// Clear env
if (clearenv() != 0) {
fprintf(stderr,"[un"APP_NAME"] Error 252: Clearing environment failed\n");
return 252;
}
// Clear
char passwStore[sizeof(struct passwd)];
sprintf(passwStore,"%d",euid);
setenv("UID",passwStore,1);
sprintf(passwStore,"%d",egid);
setenv("GID",passwStore,1);
struct passwd * pw = getpwuid(euid);
if (pw == NULL) {
fprintf(stderr,"[un"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);
setenv("SHELL",pw -> pw_shell,1);
// 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);
}
// 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,"[un"APP_NAME"] Error 252: Invalid syntax, use: %s <command> ...\n",argv[0]);
return 252;
}
// Get permissions
if (setreuid(euid,egid) == -1) {
fprintf(stderr,"[un"APP_NAME"] Error 247: Failed to un-elevate user (errno %d: %s)\n",errno,strerror(errno));
return 247;
}
// Run progrem
if (execvp(cmd[0],cmd) == -1) {
fprintf(stderr,"[un"APP_NAME"] Error 246: Failed launching process (errno %d: %s)\n",errno,strerror(errno));
return 246;
}
return 0;
}