summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile44
-rw-r--r--src/admin-wrapper.c95
-rw-r--r--src/admindb-wrapper.c94
-rw-r--r--src/alias-wrapper.c83
-rw-r--r--src/archives-wrapper.c95
-rw-r--r--src/edithtml-wrapper.c95
-rw-r--r--src/handle_opts-wrapper.c99
-rw-r--r--src/listinfo-wrapper.c96
-rw-r--r--src/options-wrapper.c95
-rw-r--r--src/subscribe-wrapper.c106
10 files changed, 902 insertions, 0 deletions
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 000000000..34adf817b
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,44 @@
+HOME=/home/mailman
+MAILMAN=/home/mailman/mailman
+
+all: admin_wrapper admindb_wrapper archives_wrapper edithtml_wrapper options_wrapper listinfo_wrapper subscribe_wrapper handle_opts_wrapper mail_wrapper alias_wrapper
+
+admin_wrapper:
+ gcc -o ${HOME}/cgi-bin/admin admin-wrapper.c
+ chmod a+sx ${HOME}/cgi-bin/admin
+
+admindb_wrapper:
+ gcc -o ${HOME}/cgi-bin/admindb admindb-wrapper.c
+ chmod a+sx ${HOME}/cgi-bin/admindb
+
+archives_wrapper:
+ gcc -o ${HOME}/cgi-bin/archives archives-wrapper.c
+ chmod a+sx ${HOME}/cgi-bin/archives
+
+edithtml_wrapper:
+ gcc -o ${HOME}/cgi-bin/edithtml edithtml-wrapper.c
+ chmod a+sx ${HOME}/cgi-bin/edithtml
+
+options_wrapper:
+ gcc -o ${HOME}/cgi-bin/options options-wrapper.c
+ chmod a+sx ${HOME}/cgi-bin/options
+
+listinfo_wrapper:
+ gcc -o ${HOME}/cgi-bin/listinfo listinfo-wrapper.c
+ chmod a+sx ${HOME}/cgi-bin/listinfo
+
+subscribe_wrapper:
+ gcc -o ${HOME}/cgi-bin/subscribe subscribe-wrapper.c
+ chmod a+sx ${HOME}/cgi-bin/subscribe
+
+handle_opts_wrapper:
+ gcc -o ${HOME}/cgi-bin/handle_opts handle_opts-wrapper.c
+ chmod a+sx ${HOME}/cgi-bin/handle_opts
+
+mail_wrapper:
+ gcc -o ${MAILMAN}/mail/wrapper mail-wrapper.c
+ chmod a+sx ${MAILMAN}/mail/wrapper
+
+alias_wrapper:
+ gcc -o ${MAILMAN}/bin/addaliases alias-wrapper.c
+ chmod a+sx ${MAILMAN}/bin/addaliases
diff --git a/src/admin-wrapper.c b/src/admin-wrapper.c
new file mode 100644
index 000000000..df495da58
--- /dev/null
+++ b/src/admin-wrapper.c
@@ -0,0 +1,95 @@
+/*
+** 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.
+**
+** Chmod this bitch 4755.
+**
+*/
+#include <stdio.h>
+
+const char *COMMAND = "/home/mailman/mailman/cgi/admin";
+
+/* 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[] = {
+ "httpd",
+ NULL /* Sentinal, don't remove */
+};
+
+/* Should make these arrays too... */
+const int LEGAL_PARENT_UID = 60001; /* nobody's UID */
+const int LEGAL_PARENT_GID = 60001; /* nobody'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())
+ {
+ printf("GOT UID %d.\n", getuid());
+ return 0;
+ }
+ if(LEGAL_PARENT_GID != getgid())
+ {
+ printf("GOT GID %d.\n", getgid());
+ return 0;
+ }
+ return 1;
+}
+
+void main(int argc, char **argv, char **env) {
+ char *command;
+ int i;
+ command = (char *)malloc(sizeof(char) * i);
+
+ if(legal_caller()) {
+ setuid(geteuid());
+ execve(COMMAND, &argv[0], env);
+ }
+ else {
+ printf("Illegal caller!\n");
+ }
+}
+
diff --git a/src/admindb-wrapper.c b/src/admindb-wrapper.c
new file mode 100644
index 000000000..748d78812
--- /dev/null
+++ b/src/admindb-wrapper.c
@@ -0,0 +1,94 @@
+/*
+** 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.
+**
+** Chmod this bitch 4755.
+**
+*/
+#include <stdio.h>
+
+const char *COMMAND = "/home/mailman/mailman/cgi/admindb";
+
+/* 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[] = {
+ "httpd",
+ NULL /* Sentinal, don't remove */
+};
+
+/* Should make these arrays too... */
+const int LEGAL_PARENT_UID = 60001; /* nobody's UID */
+const int LEGAL_PARENT_GID = 60001; /* nobody'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())
+ {
+ printf("GOT UID %d.\n", getuid());
+ return 0;
+ }
+ if(LEGAL_PARENT_GID != getgid())
+ {
+ printf("GOT GID %d.\n", getgid());
+ return 0;
+ }
+ return 1;
+}
+
+void main(int argc, char **argv, char **env) {
+ char *command;
+ int i;
+ command = (char *)malloc(sizeof(char) * i);
+
+ if(legal_caller()) {
+ setuid(geteuid());
+ execve(COMMAND, &argv[0], env);
+ }
+ else {
+ printf("Illegal caller!\n");
+ }
+}
diff --git a/src/alias-wrapper.c b/src/alias-wrapper.c
new file mode 100644
index 000000000..d335e0c1c
--- /dev/null
+++ b/src/alias-wrapper.c
@@ -0,0 +1,83 @@
+#include <stdio.h>
+
+
+const int LEGAL_PARENT_UID = 9001; /* mailman's UID */
+const int LEGAL_PARENT_GID = 6; /* mailman's GID */
+
+const char* SENDMAIL_CMD = "/usr/sbin/sendmail";
+const char* ALIAS_FILE = "/etc/aliases";
+const char* WRAPPER = "/home/mailman/mailman/mail/wrapper";
+
+/*
+** is the parent process allowed to call us?
+*/
+int LegalCaller()
+{
+ /* compare to our parent's uid */
+ if(LEGAL_PARENT_UID != getuid())
+ {
+ printf("GOT UID %d.\n", getuid());
+ return 0;
+ }
+ if(LEGAL_PARENT_GID != getgid())
+ {
+ printf("GOT GID %d.\n", getgid());
+ return 0;
+ }
+ return 1;
+}
+
+void AddListAliases(char *list)
+{
+ FILE *f;
+ int err = 0;
+
+ f = fopen(ALIAS_FILE ,"a+");
+ if (f == NULL)
+ {
+ err = 1;
+ f = stderr;
+ fprintf(f, "\n\n***********ERROR!!!!***********\n");
+ fprintf(f, "Could not write to the /etc/aliases file.\n");
+ fprintf(f, "Please become root, add the lines below to that file,\n");
+ fprintf(f, "And then run the command %s -bi\n", SENDMAIL_CMD);
+ }
+
+ fprintf(f, "\n\n#-- %s -- mailing list aliases:\n", list);
+ fprintf(f, "%s: \t|\"%s post %s\"\n", list, WRAPPER, list);
+ fprintf(f, "%s-admin: \t|\"%s mailowner %s\"\n", list, WRAPPER, list);
+ fprintf(f, "%s-request: \t|\"%s mailcmd %s\"\n", list, WRAPPER, list);
+ fprintf(f, "# I think we don't want this one... it'll change the unix from line...\n");
+ fprintf(f, "#owner-%s: \t%s-admin\n", list, list);
+ fprintf(f, "#%s-owner: \t%s-admin\n", list, list);
+ fprintf(f, "\n");
+ fclose(f);
+
+ if (!err)
+ {
+ printf("Rebuilding alias database...\n");
+ execlp(SENDMAIL_CMD, SENDMAIL_CMD, "-bi");
+ }
+}
+
+void main(int argc, char **argv, char **env)
+{
+ char *command;
+ int i;
+
+ if(argc != 2)
+ {
+ printf("Usage: %s [list-name]\n", argv[0]);
+ exit(0);
+ }
+ if(LegalCaller())
+ {
+ setuid(geteuid());
+ AddListAliases(argv[1]);
+ }
+ else
+ {
+ printf("Illegal caller!\n");
+ }
+}
+
diff --git a/src/archives-wrapper.c b/src/archives-wrapper.c
new file mode 100644
index 000000000..89a23934b
--- /dev/null
+++ b/src/archives-wrapper.c
@@ -0,0 +1,95 @@
+/*
+** 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.
+**
+** Chmod this bitch 4755.
+**
+*/
+#include <stdio.h>
+
+const char *COMMAND = "/home/mailman/mailman/cgi/archives";
+
+/* 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[] = {
+ "httpd",
+ NULL /* Sentinal, don't remove */
+};
+
+/* Should make these arrays too... */
+const int LEGAL_PARENT_UID = 60001; /* nobody's UID */
+const int LEGAL_PARENT_GID = 60001; /* nobody'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())
+ {
+ printf("GOT UID %d.\n", getuid());
+ return 0;
+ }
+ if(LEGAL_PARENT_GID != getgid())
+ {
+ printf("GOT GID %d.\n", getgid());
+ return 0;
+ }
+ return 1;
+}
+
+void main(int argc, char **argv, char **env) {
+ char *command;
+ int i;
+ command = (char *)malloc(sizeof(char) * i);
+
+ if(legal_caller()) {
+ setuid(geteuid());
+ execve(COMMAND, &argv[0], env);
+ }
+ else {
+ printf("Illegal caller!\n");
+ }
+}
+
diff --git a/src/edithtml-wrapper.c b/src/edithtml-wrapper.c
new file mode 100644
index 000000000..08a08ecfa
--- /dev/null
+++ b/src/edithtml-wrapper.c
@@ -0,0 +1,95 @@
+/*
+** 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.
+**
+** Chmod this bitch 4755.
+**
+*/
+#include <stdio.h>
+
+const char *COMMAND = "/home/mailman/mailman/cgi/edithtml";
+
+/* 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[] = {
+ "httpd",
+ NULL /* Sentinal, don't remove */
+};
+
+/* Should make these arrays too... */
+const int LEGAL_PARENT_UID = 60001; /* nobody's UID */
+const int LEGAL_PARENT_GID = 60001; /* nobody'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())
+ {
+ printf("GOT UID %d.\n", getuid());
+ return 0;
+ }
+ if(LEGAL_PARENT_GID != getgid())
+ {
+ printf("GOT GID %d.\n", getgid());
+ return 0;
+ }
+ return 1;
+}
+
+void main(int argc, char **argv, char **env) {
+ char *command;
+ int i;
+ command = (char *)malloc(sizeof(char) * i);
+
+ if(legal_caller()) {
+ setuid(geteuid());
+ execve(COMMAND, &argv[0], env);
+ }
+ else {
+ printf("Illegal caller!\n");
+ }
+}
+
diff --git a/src/handle_opts-wrapper.c b/src/handle_opts-wrapper.c
new file mode 100644
index 000000000..bb3800a36
--- /dev/null
+++ b/src/handle_opts-wrapper.c
@@ -0,0 +1,99 @@
+/*
+** 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.
+**
+** Chmod this bitch 4755.
+**
+*/
+#include <stdio.h>
+
+const char *COMMAND = "/home/mailman/mailman/cgi/handle_opts";
+
+FILE *f;
+
+/* 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[] = {
+ "httpd",
+ NULL /* Sentinal, don't remove */
+};
+
+/* Should make these arrays too... */
+const int LEGAL_PARENT_UID = 60001; /* nobody's UID */
+const int LEGAL_PARENT_GID = 60001; /* nobody'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());
+ return 0;
+ }
+ if(LEGAL_PARENT_GID != getgid())
+ {
+ fprintf(f,"GOT GID %d.\n", getgid());
+ return 0;
+ }
+ return 1;
+}
+
+void main(int argc, char **argv, char **env) {
+ char *command;
+ int i;
+
+ f = fopen("/tmp/zozo", "w+");
+ command = (char *)malloc(sizeof(char) * i);
+
+ if(legal_caller()) {
+ setuid(geteuid());
+ execve(COMMAND, &argv[0], env);
+ }
+ else {
+ fprintf(f,"Illegal caller!\n");
+ }
+}
+
diff --git a/src/listinfo-wrapper.c b/src/listinfo-wrapper.c
new file mode 100644
index 000000000..fd42fe131
--- /dev/null
+++ b/src/listinfo-wrapper.c
@@ -0,0 +1,96 @@
+/*
+** 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.
+**
+** Chmod this bitch 4755.
+**
+*/
+#include <stdio.h>
+
+const char *COMMAND = "/home/mailman/mailman/cgi/listinfo";
+
+
+/* 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[] = {
+ "httpd",
+ NULL /* Sentinal, don't remove */
+};
+
+/* Should make these arrays too... */
+const int LEGAL_PARENT_UID = 60001; /* nobody's UID */
+const int LEGAL_PARENT_GID = 60001; /* nobody'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())
+ {
+ printf("GOT UID %d.\n", getuid());
+ return 0;
+ }
+ if(LEGAL_PARENT_GID != getgid())
+ {
+ printf("GOT GID %d.\n", getgid());
+ return 0;
+ }
+ return 1;
+}
+
+void main(int argc, char **argv, char **env) {
+ char *command;
+ int i;
+ command = (char *)malloc(sizeof(char) * i);
+
+ if(legal_caller()) {
+ argv[0] = (char *)COMMAND;
+ execve(COMMAND, argv, env);
+ }
+ else {
+ printf("Illegal caller!\n");
+ }
+}
+
diff --git a/src/options-wrapper.c b/src/options-wrapper.c
new file mode 100644
index 000000000..3a87dfd4c
--- /dev/null
+++ b/src/options-wrapper.c
@@ -0,0 +1,95 @@
+/*
+** 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.
+**
+** Chmod this bitch 4755.
+**
+*/
+#include <stdio.h>
+
+const char *COMMAND = "/home/mailman/mailman/cgi/options";
+
+
+/* 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[] = {
+ "httpd",
+ NULL /* Sentinal, don't remove */
+};
+
+/* Should make these arrays too... */
+const int LEGAL_PARENT_UID = 60001; /* nobody's UID */
+const int LEGAL_PARENT_GID = 60001; /* nobody'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())
+ {
+ printf("GOT UID %d.\n", getuid());
+ return 0;
+ }
+ if(LEGAL_PARENT_GID != getgid())
+ {
+ printf("GOT GID %d.\n", getgid());
+ return 0;
+ }
+ return 1;
+}
+
+void main(int argc, char **argv, char **env) {
+ char *command;
+ int i;
+ command = (char *)malloc(sizeof(char) * i);
+
+ if(legal_caller()) {
+ execve(COMMAND, &argv[0], env);
+ }
+ else {
+ printf("Illegal caller!\n");
+ }
+}
+
diff --git a/src/subscribe-wrapper.c b/src/subscribe-wrapper.c
new file mode 100644
index 000000000..bd1fc1582
--- /dev/null
+++ b/src/subscribe-wrapper.c
@@ -0,0 +1,106 @@
+/*
+** 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.
+**
+** Chmod this bitch 4755.
+**
+*/
+#include <stdio.h>
+
+const char *COMMAND = "/home/mailman/mailman/cgi/subscribe";
+FILE *f;
+
+/* 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[] = {
+ "httpd",
+ NULL /* Sentinal, don't remove */
+};
+
+/* Should make these arrays too... */
+const int LEGAL_PARENT_UID = 60001; /* nobody's UID */
+const int LEGAL_PARENT_GID = 60001; /* nobody'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());
+ fflush(f);
+ return 0;
+ }
+ if(LEGAL_PARENT_GID != getgid())
+ {
+ fprintf(f,"GOT GID %d.\n", getgid());
+ fflush(f);
+ return 0;
+ }
+ return 1;
+}
+
+void main(int argc, char **argv, char **env) {
+ char *command;
+ int i;
+ command = (char *)malloc(sizeof(char) * i);
+
+ f = fopen("/tmp/wtf_man","w+");
+ fprintf(f, "Hello...\n");
+ fflush(f);
+ if(legal_caller()) {
+ setuid(geteuid());
+ fprintf(f, "Sheesh...\n");
+ fflush(f);
+ execve(COMMAND, &argv[0], env);
+ fprintf(f, "Damn, I suck.\n");
+ fflush(f);
+ }
+ else {
+ fprintf(f,"Illegal caller!\n");
+ fflush(f);
+ }
+}
+