/* ** generic wrapper that will take info from a environment ** variable, and pass it to two commands. ** ** 10-17-96 : Hal Schechner ** ** 12-14-96 : John Viega -- changed to work on 1 command, take a list of ** valid commands, just pass on argv, and use ** execvp() Also threw in some useful feedback for ** when there's a failure, mainly for future ** debugging. Made it a root script so we could ** call setuid() ** ** Chmod this bitch 4755. ** */ #include const char *COMMAND_LOCATION = "/home/mailman/mailman/scripts"; extern int errno; FILE *f; const char *VALID_COMMANDS[] = { "post", "mailcmd", "mailowner", NULL /* Sentinal, don't remove */ }; /* Might want to make this full path. I can write whatever program named * sendmail, so this isn't much for security. */ const char *LEGAL_PARENT_NAMES[] = { "sendmail", NULL /* Sentinal, don't remove */ }; /* Should make these arrays too... */ const int LEGAL_PARENT_UID = 1; /* mail's UID */ const int LEGAL_PARENT_GID = 1; /* mail's GID */ /* ** what is the name of the process with pid of 'pid' */ char * get_process_name(int pid) { FILE *proc; char fname[30]; char tmp[255]; static char procname[255]; sprintf(fname, "/proc/%d/status", pid); proc = fopen(fname, "r"); fgets(tmp, 256, proc); sscanf(tmp, "Name: %s\n", procname); fclose(proc); return procname; } int valid_parent(char *parent) { int i = 0; while (LEGAL_PARENT_NAMES[i] != NULL) { if (!strcmp(parent, LEGAL_PARENT_NAMES[i])) { return 1; } i++; } return 0; } /* ** is the parent process allowed to call us? */ int legal_caller() { /* compare to our parent's uid */ if (LEGAL_PARENT_UID != getuid()) { /* fprintf(f,"GOT UID %d.\n", getuid()); */ printf("GOT UID %d.\n", getuid()); return 0; } if (LEGAL_PARENT_GID != getgid()) { /* fprintf(f,"GOT GID %d.\n", getgid()); */ printf("GOT GID %d.\n", getgid()); return 0; } return 1; } int valid_command(char *command) { int i = 0; while (VALID_COMMANDS[i] != NULL) { if (!strcmp(command, VALID_COMMANDS[i])) { return 1; } i++; } return 0; } int main(int argc, char **argv) { char *command; int i; if (argc < 2) { printf("Usage: %s program [args...]\n", argv[0]); fflush(stdout); exit(0); } i = strlen(argv[1]) + strlen(COMMAND_LOCATION) + 2; command = (char *)malloc(sizeof(char) * i); sprintf(command, "%s/%s", COMMAND_LOCATION, argv[1]); if (!valid_command(argv[1])) { printf("Illegal command.\n"); } else { if (legal_caller()) { setuid(geteuid()); execv(command, &argv[1]); } else { printf("Illegal caller!\n"); } } } /* * Local Variables: * c-file-style: "python" * End: */