masqmail

annotate src/peopen.c @ 421:f37384470855

Changed lockdir to /var/lock/masqmail; Create lockdir and piddir on startup. Moved the lockdir out of the spool dir. (When /var/lock is a ramdisk we do well to have the lock files there.) Added the new configure option --with-lockdir to change that location. Nontheless, if we run_as_user, then lock files are always stored in the spool dir directly. Instead of installing the lockdir and piddir at installation time, we create them on startup time now if they are missing. This is necessary if lockdir or piddir are a tmpfs.
author markus schnalke <meillo@marmaro.de>
date Wed, 30 May 2012 09:38:38 +0200
parents b27f66555ba8
children
rev   line source
meillo@367 1 /*
meillo@367 2 ** This a snippet I found in sourceforge. I just changed the identing
meillo@367 3 ** style to my own and deleted the main function. -- oku
meillo@367 4 ** The functions destroy_argv() and create_argv() were added by oku.
meillo@29 5 */
meillo@0 6
meillo@0 7 #include <errno.h>
meillo@0 8 #include <stdio.h>
meillo@0 9 #include <stdlib.h>
meillo@0 10 #include <unistd.h>
meillo@0 11 #include <string.h>
meillo@0 12 #include <sys/types.h>
meillo@15 13 #include <sysexits.h>
meillo@0 14
meillo@0 15 #include "peopen.h"
meillo@0 16 #include "masqmail.h"
meillo@0 17
meillo@377 18 /*
meillo@377 19 ** static void
meillo@377 20 ** destroy_argv(char **arr)
meillo@377 21 ** {
meillo@377 22 ** char *p = arr[0];
meillo@377 23 ** int i = 0;
meillo@377 24 **
meillo@377 25 ** while (p) {
meillo@377 26 ** free(p);
meillo@377 27 ** p = arr[i++];
meillo@377 28 ** }
meillo@377 29 ** free(arr);
meillo@377 30 ** }
meillo@377 31 */
meillo@0 32
meillo@10 33 static char**
meillo@10 34 create_argv(const char *cmd, int count)
meillo@0 35 {
meillo@10 36 char buf[strlen(cmd) + 1];
meillo@10 37 char **arr, *q;
meillo@10 38 const char *p;
meillo@10 39 int i = 0;
meillo@0 40
meillo@27 41 arr = (char **) g_malloc(sizeof(char *) * count);
meillo@0 42
meillo@10 43 p = cmd;
meillo@10 44 while (*p && i < (count - 1)) {
meillo@10 45 while (*p && isspace(*p))
meillo@10 46 p++;
meillo@10 47 q = buf;
meillo@10 48 while (*p && !isspace(*p))
meillo@10 49 *q++ = *p++;
meillo@15 50 *q = '\0';
meillo@10 51 arr[i++] = strdup(buf);
meillo@10 52 while (*p && isspace(*p))
meillo@10 53 p++;
meillo@10 54 }
meillo@10 55 arr[i] = NULL;
meillo@10 56
meillo@10 57 return arr;
meillo@0 58 }
meillo@0 59
meillo@10 60 FILE*
meillo@367 61 peidopen(const char *command, const char *type, char *const envp[],
meillo@367 62 int *ret_pid, uid_t uid, gid_t gid)
meillo@0 63 {
meillo@10 64 enum { Read, Write } mode;
meillo@10 65 int pipe_fd[2];
meillo@10 66 pid_t pid;
meillo@0 67
meillo@10 68 if (command == NULL || type == NULL) {
meillo@10 69 errno = EINVAL;
meillo@10 70 return NULL;
meillo@10 71 }
meillo@0 72
meillo@10 73 if (strcmp(type, "r")) {
meillo@10 74 if (strcmp(type, "w")) {
meillo@10 75 errno = EINVAL;
meillo@10 76 return NULL;
meillo@10 77 } else
meillo@10 78 mode = Write;
meillo@10 79 } else
meillo@10 80 mode = Read;
meillo@0 81
meillo@10 82 if (pipe(pipe_fd) == -1)
meillo@10 83 return NULL;
meillo@0 84
meillo@10 85 switch (pid = fork()) {
meillo@10 86 case 0: /* child thread */
meillo@0 87
meillo@10 88 {
meillo@10 89 int i, max_fd = sysconf(_SC_OPEN_MAX);
meillo@10 90
meillo@10 91 if (max_fd <= 0)
meillo@10 92 max_fd = 64;
meillo@10 93 for (i = 0; i < max_fd; i++)
meillo@10 94 if ((i != pipe_fd[0]) && (i != pipe_fd[1]))
meillo@10 95 close(i);
meillo@10 96 }
meillo@10 97 if (close(pipe_fd[mode == Read ? 0 : 1]) != -1 &&
meillo@10 98 dup2(pipe_fd[mode == Read ? 1 : 0],
meillo@10 99 mode == Read ? STDOUT_FILENO : STDIN_FILENO) != -1) {
meillo@367 100 /* char *argv [] = { "/bin/sh", "-c", (char*) command, NULL }; */
meillo@10 101 char **argv = create_argv(command, 10);
meillo@10 102 int ret;
meillo@10 103
meillo@10 104 if (uid != (uid_t) - 1) {
meillo@10 105 if ((ret = seteuid(0)) != 0) {
meillo@10 106 exit(EX_NOPERM);
meillo@10 107 }
meillo@10 108 }
meillo@10 109 if (gid != (gid_t) - 1) {
meillo@10 110 if ((ret = setgid(gid)) != 0) {
meillo@10 111 exit(EX_NOPERM);
meillo@10 112 }
meillo@10 113 }
meillo@10 114 if (uid != (uid_t) - 1) {
meillo@10 115 if ((ret = setuid(uid)) != 0) {
meillo@10 116 exit(EX_NOPERM);
meillo@10 117 }
meillo@10 118 }
meillo@10 119 execve(*argv, argv, envp);
meillo@10 120 }
meillo@10 121
meillo@10 122 _exit(errno);
meillo@10 123
meillo@10 124 default: /* parent thread */
meillo@10 125 *ret_pid = pid;
meillo@10 126 close(pipe_fd[mode == Read ? 1 : 0]);
meillo@10 127 return fdopen(pipe_fd[mode == Read ? 0 : 1], type);
meillo@10 128
meillo@10 129 case -1:
meillo@10 130 close(pipe_fd[0]);
meillo@10 131 close(pipe_fd[1]);
meillo@10 132 return NULL;
meillo@0 133 }
meillo@0 134 }
meillo@0 135
meillo@10 136 FILE*
meillo@10 137 peopen(const char *command, const char *type, char *const envp[], int *ret_pid)
meillo@0 138 {
meillo@10 139 return peidopen(command, type, envp, ret_pid, -1, -1);
meillo@0 140 }