/tags/pre-autoconf/mailman/src/mail-wrapper.c

# · C · 169 lines · 94 code · 23 blank · 52 comment · 15 complexity · 756e98cbb2c270e4b7e184cea78de601 MD5 · raw file

  1. /*
  2. ** mail-wrapper.c:
  3. ** generic wrapper that will take info from a environment
  4. ** variable, and pass it to two commands.
  5. **
  6. ** Copyright (C) 1998 by the Free Software Foundation, Inc.
  7. **
  8. ** This program is free software; you can redistribute it and/or
  9. ** modify it under the terms of the GNU General Public License
  10. ** as published by the Free Software Foundation; either version 2
  11. ** of the License, or (at your option) any later version.
  12. **
  13. ** This program is distributed in the hope that it will be useful,
  14. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ** GNU General Public License for more details.
  17. **
  18. ** You should have received a copy of the GNU General Public License
  19. ** along with this program; if not, write to the Free Software
  20. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. **
  22. ** 10-17-96 : Hal Schechner (hal-j@channel21.com)
  23. **
  24. ** 12-14-96 : John Viega (viega@list.org)
  25. ** changed to work on 1 command, take a list of
  26. ** valid commands, just pass on argv, and use
  27. ** execvp() Also threw in some useful feedback for
  28. ** when there's a failure, mainly for future
  29. ** debugging. Made it a root script so we could
  30. ** call setuid()
  31. **
  32. ** Chmod this 4755.
  33. **
  34. */
  35. #include <stdio.h>
  36. const char *COMMAND_LOCATION = "/home/mailman/mailman/scripts";
  37. extern int errno;
  38. FILE *f;
  39. const char *VALID_COMMANDS[] = {
  40. "post",
  41. "mailcmd",
  42. "mailowner",
  43. NULL /* Sentinal, don't remove */
  44. };
  45. /* Might want to make this full path. I can write whatever program named
  46. * sendmail, so this isn't much for security.
  47. */
  48. const char *LEGAL_PARENT_NAMES[] = {
  49. "sendmail",
  50. NULL /* Sentinal, don't remove */
  51. };
  52. /* Should make these arrays too... */
  53. const int LEGAL_PARENT_UID = 1; /* mail's UID */
  54. const int LEGAL_PARENT_GID = 1; /* mail's GID */
  55. /*
  56. ** what is the name of the process with pid of 'pid'
  57. */
  58. char *
  59. get_process_name(int pid)
  60. {
  61. FILE *proc;
  62. char fname[30];
  63. char tmp[255];
  64. static char procname[255];
  65. sprintf(fname, "/proc/%d/status", pid);
  66. proc = fopen(fname, "r");
  67. fgets(tmp, 256, proc);
  68. sscanf(tmp, "Name: %s\n", procname);
  69. fclose(proc);
  70. return procname;
  71. }
  72. int
  73. valid_parent(char *parent)
  74. {
  75. int i = 0;
  76. while (LEGAL_PARENT_NAMES[i] != NULL) {
  77. if (!strcmp(parent, LEGAL_PARENT_NAMES[i])) {
  78. return 1;
  79. }
  80. i++;
  81. }
  82. return 0;
  83. }
  84. /*
  85. ** is the parent process allowed to call us?
  86. */
  87. int
  88. legal_caller()
  89. {
  90. /* compare to our parent's uid */
  91. if (LEGAL_PARENT_UID != getuid()) {
  92. /* fprintf(f,"GOT UID %d.\n", getuid()); */
  93. printf("GOT UID %d.\n", getuid());
  94. return 0;
  95. }
  96. if (LEGAL_PARENT_GID != getgid()) {
  97. /* fprintf(f,"GOT GID %d.\n", getgid()); */
  98. printf("GOT GID %d.\n", getgid());
  99. return 0;
  100. }
  101. return 1;
  102. }
  103. int
  104. valid_command(char *command)
  105. {
  106. int i = 0;
  107. while (VALID_COMMANDS[i] != NULL) {
  108. if (!strcmp(command, VALID_COMMANDS[i])) {
  109. return 1;
  110. }
  111. i++;
  112. }
  113. return 0;
  114. }
  115. int
  116. main(int argc, char **argv)
  117. {
  118. char *command;
  119. int i;
  120. if (argc < 2) {
  121. printf("Usage: %s program [args...]\n", argv[0]);
  122. fflush(stdout);
  123. exit(0);
  124. }
  125. i = strlen(argv[1]) + strlen(COMMAND_LOCATION) + 2;
  126. command = (char *)malloc(sizeof(char) * i);
  127. sprintf(command, "%s/%s", COMMAND_LOCATION, argv[1]);
  128. if (!valid_command(argv[1])) {
  129. printf("Illegal command.\n");
  130. }
  131. else {
  132. if (legal_caller()) {
  133. setuid(geteuid());
  134. execv(command, &argv[1]);
  135. }
  136. else {
  137. printf("Illegal caller!\n");
  138. }
  139. }
  140. }
  141. /*
  142. * Local Variables:
  143. * c-file-style: "python"
  144. * End:
  145. */