comparison src/local.c @ 10:26e34ae9a3e3

changed indention and line wrapping to a more consistent style
author meillo@marmaro.de
date Mon, 27 Oct 2008 16:23:10 +0100
parents 08114f7dcc23
children f671821d8222
comparison
equal deleted inserted replaced
9:31cc8a89cb74 10:26e34ae9a3e3
18 18
19 #include "masqmail.h" 19 #include "masqmail.h"
20 #include "peopen.h" 20 #include "peopen.h"
21 #include <sys/wait.h> 21 #include <sys/wait.h>
22 22
23 static 23 static void
24 void message_stream(FILE *out, message *msg, GList *hdr_list, guint flags) 24 message_stream(FILE * out, message * msg, GList * hdr_list, guint flags)
25 { 25 {
26 time_t now = time(NULL); 26 time_t now = time(NULL);
27 GList *node; 27 GList *node;
28 28
29 if(flags & MSGSTR_FROMLINE){ 29 if (flags & MSGSTR_FROMLINE) {
30 fprintf(out, "From <%s@%s> %s", msg->return_path->local_part, 30 fprintf(out, "From <%s@%s> %s", msg->return_path->local_part, msg->return_path->domain, ctime(&now));
31 msg->return_path->domain, ctime(&now)); 31 }
32 } 32
33 33 foreach(hdr_list, node) {
34 foreach(hdr_list, node){ 34 header *hdr = (header *) (node->data);
35 header *hdr = (header *)(node->data); 35 fputs(hdr->header, out);
36 fputs(hdr->header, out); 36 }
37 } 37 putc('\n', out);
38 putc('\n', out); 38 foreach(msg->data_list, node) {
39 foreach(msg->data_list, node){ 39 /* From hack: */
40 /* From hack: */ 40 if (flags & MSGSTR_FROMHACK) {
41 if(flags & MSGSTR_FROMHACK){ 41 if (strncmp(node->data, "From ", 5) == 0)
42 if(strncmp(node->data, "From ", 5) == 0) 42 putc('>', out);
43 putc('>', out); 43 }
44 } 44 fputs(node->data, out);
45 fputs(node->data, out); 45 }
46 } 46 putc('\n', out);
47 putc('\n', out);
48 } 47 }
49 48
50 gboolean append_file(message *msg, GList *hdr_list, gchar *user) 49 gboolean
50 append_file(message * msg, GList * hdr_list, gchar * user)
51 { 51 {
52 struct passwd *pw; 52 struct passwd *pw;
53 gboolean ok = FALSE; 53 gboolean ok = FALSE;
54 54
55 /* headers may be special for a local delivery */ 55 /* headers may be special for a local delivery */
56 if(hdr_list == NULL) 56 if (hdr_list == NULL)
57 hdr_list = msg->hdr_list; 57 hdr_list = msg->hdr_list;
58 58
59 if((pw = getpwnam(user))){ 59 if ((pw = getpwnam(user))) {
60 uid_t saved_uid = geteuid(); 60 uid_t saved_uid = geteuid();
61 gid_t saved_gid = getegid(); 61 gid_t saved_gid = getegid();
62 gboolean uid_ok = TRUE, gid_ok = TRUE; 62 gboolean uid_ok = TRUE, gid_ok = TRUE;
63 63
64 if(!conf.run_as_user){ 64 if (!conf.run_as_user) {
65 uid_ok = (seteuid(0) == 0); 65 uid_ok = (seteuid(0) == 0);
66 if(uid_ok){ 66 if (uid_ok) {
67 gid_ok = (setegid(conf.mail_gid) == 0); 67 gid_ok = (setegid(conf.mail_gid) == 0);
68 uid_ok = (seteuid(pw->pw_uid) == 0); 68 uid_ok = (seteuid(pw->pw_uid) == 0);
69 } 69 }
70 } 70 }
71 71
72 DEBUG(5) debugf("running as euid %d\n", geteuid()); 72 DEBUG(5) debugf("running as euid %d\n", geteuid());
73 DEBUG(5) debugf("running as egid %d\n", getegid()); 73 DEBUG(5) debugf("running as egid %d\n", getegid());
74 74
75 if(uid_ok && gid_ok){ 75 if (uid_ok && gid_ok) {
76 gchar *filename; 76 gchar *filename;
77 FILE *out; 77 FILE *out;
78 78
79 filename = g_strdup_printf("%s/%s", conf.mail_dir, user); 79 filename = g_strdup_printf("%s/%s", conf.mail_dir, user);
80 if((out = fopen(filename, "a"))){ 80 if ((out = fopen(filename, "a"))) {
81 #ifdef USE_LIBLOCKFILE 81 #ifdef USE_LIBLOCKFILE
82 gint err; 82 gint err;
83 /* lock file using liblockfile */ 83 /* lock file using liblockfile */
84 err = maillock(user,3); 84 err = maillock(user, 3);
85 if(err == 0){ 85 if (err == 0) {
86 #else 86 #else
87 /* lock file: */ 87 /* lock file: */
88 struct flock lock; 88 struct flock lock;
89 lock.l_type = F_WRLCK; 89 lock.l_type = F_WRLCK;
90 lock.l_whence = SEEK_END; 90 lock.l_whence = SEEK_END;
91 lock.l_start = lock.l_len = 0; 91 lock.l_start = lock.l_len = 0;
92 if(fcntl(fileno(out), F_SETLK, &lock) != -1){ 92 if (fcntl(fileno(out), F_SETLK, &lock) != -1) {
93 #endif 93 #endif
94 fchmod(fileno(out), 0600); 94 fchmod(fileno(out), 0600);
95 95
96 message_stream(out, msg, hdr_list, MSGSTR_FROMLINE|MSGSTR_FROMHACK); 96 message_stream(out, msg, hdr_list, MSGSTR_FROMLINE | MSGSTR_FROMHACK);
97 97
98 ok = TRUE; 98 ok = TRUE;
99 99
100 /* close when still user */ 100 /* close when still user */
101 fclose(out); 101 fclose(out);
102 #ifdef USE_LIBLOCKFILE 102 #ifdef USE_LIBLOCKFILE
103 mailunlock(); 103 mailunlock();
104 #endif 104 #endif
105 }else{ 105 } else {
106 fclose(out); 106 fclose(out);
107 #ifdef USE_LIBLOCKFILE 107 #ifdef USE_LIBLOCKFILE
108 DEBUG(3) debugf("could not lock file %s: error %d\n", 108 DEBUG(3) debugf("could not lock file %s: error %d\n", filename, err);
109 filename, err); 109 } /* XEmacs indenting convenience... */
110 } /* XEmacs indenting convenience... */
111 #else 110 #else
112 DEBUG(3) debugf("could not lock file %s: %s\n", 111 DEBUG(3) debugf("could not lock file %s: %s\n", filename, strerror(errno));
113 filename, strerror(errno)); 112 }
114 }
115 #endif 113 #endif
116 }else{ 114 } else {
117 logwrite(LOG_ALERT, "could not open file %s: %s\n", 115 logwrite(LOG_ALERT, "could not open file %s: %s\n", filename, strerror(errno));
118 filename, strerror(errno)); 116 }
119 } 117 g_free(filename);
120 g_free(filename); 118
121 119 if (!conf.run_as_user) {
122 if(!conf.run_as_user){ 120 uid_ok = (seteuid(0) == 0);
123 uid_ok = (seteuid(0) == 0); 121 if (uid_ok) {
124 if(uid_ok){ 122 gid_ok = (setegid(saved_gid) == 0);
125 gid_ok = (setegid(saved_gid) == 0); 123 uid_ok = (seteuid(saved_uid) == 0);
126 uid_ok = (seteuid(saved_uid) == 0); 124 }
127 } 125 }
128 } 126
129 127 if (!uid_ok || !gid_ok) {
130 if(!uid_ok || !gid_ok){ 128 /* FIXME: if this fails we HAVE to exit, because we shall not run
131 /* FIXME: if this fails we HAVE to exit, because we shall not run 129 with some users id. But we do not return, and so this message
132 with some users id. But we do not return, and so this message 130 will not be finished, so the user will get the message again
133 will not be finished, so the user will get the message again 131 next time a delivery is attempted... */
134 next time a delivery is attempted... */ 132 logwrite(LOG_ALERT, "could not set back uid or gid after local delivery: %s\n", strerror(errno));
135 logwrite(LOG_ALERT, 133 logwrite(LOG_ALERT, "uid=%d, gid=%d, euid=%d, egid=%d, want = %d, %d\n",
136 "could not set back uid or gid after local delivery: %s\n", 134 getuid(), getgid(), geteuid(), getegid(), saved_uid, saved_gid);
137 strerror(errno)); 135 exit(EXIT_FAILURE);
138 logwrite(LOG_ALERT, 136 }
139 "uid=%d, gid=%d, euid=%d, egid=%d, want = %d, %d\n", 137 } else {
140 getuid(), getgid(), geteuid(), getegid(), saved_uid, saved_gid); 138 logwrite(LOG_ALERT, "could not set uid or gid for local delivery, uid = %d: %s\n", pw->pw_uid, strerror(errno));
141 exit(EXIT_FAILURE); 139 }
142 } 140 } else {
143 }else{ 141 logwrite(LOG_ALERT, "could not find password entry for user %s\n", user);
144 logwrite(LOG_ALERT, 142 errno = ENOENT; /* getpwnam does not set errno correctly */
145 "could not set uid or gid for local delivery, uid = %d: %s\n", 143 }
146 pw->pw_uid, strerror(errno)); 144
147 } 145 return ok;
148 }else{
149 logwrite(LOG_ALERT, "could not find password entry for user %s\n", user);
150 errno = ENOENT; /* getpwnam does not set errno correctly */
151 }
152
153 return ok;
154 } 146 }
155 147
156 #ifdef ENABLE_MAILDIR 148 #ifdef ENABLE_MAILDIR
157 gboolean maildir_out(message *msg, GList *hdr_list, gchar *user, guint flags) 149 gboolean
150 maildir_out(message * msg, GList * hdr_list, gchar * user, guint flags)
158 { 151 {
159 struct passwd *pw; 152 struct passwd *pw;
160 gboolean ok = FALSE; 153 gboolean ok = FALSE;
161 154
162 /* headers may be special for a local delivery */ 155 /* headers may be special for a local delivery */
163 if(hdr_list == NULL) 156 if (hdr_list == NULL)
164 hdr_list = msg->hdr_list; 157 hdr_list = msg->hdr_list;
165 158
166 if((pw = getpwnam(user))){ 159 if ((pw = getpwnam(user))) {
167 uid_t saved_uid = geteuid(); 160 uid_t saved_uid = geteuid();
168 gid_t saved_gid = getegid(); 161 gid_t saved_gid = getegid();
169 gboolean uid_ok = TRUE, gid_ok = TRUE; 162 gboolean uid_ok = TRUE, gid_ok = TRUE;
170 163
171 if(!conf.run_as_user){ 164 if (!conf.run_as_user) {
172 uid_ok = (seteuid(0) == 0); 165 uid_ok = (seteuid(0) == 0);
173 if(uid_ok){ 166 if (uid_ok) {
174 gid_ok = (setegid(conf.mail_gid) == 0); 167 gid_ok = (setegid(conf.mail_gid) == 0);
175 uid_ok = (seteuid(pw->pw_uid) == 0); 168 uid_ok = (seteuid(pw->pw_uid) == 0);
176 } 169 }
177 } 170 }
178 171
179 DEBUG(5) debugf("running as euid %d\n", geteuid()); 172 DEBUG(5) debugf("running as euid %d\n", geteuid());
180 DEBUG(5) debugf("running as egid %d\n", getegid()); 173 DEBUG(5) debugf("running as egid %d\n", getegid());
181 174
182 if(uid_ok && gid_ok){ 175 if (uid_ok && gid_ok) {
183 char *path = g_strdup_printf("%s/Maildir", pw->pw_dir); 176 char *path = g_strdup_printf("%s/Maildir", pw->pw_dir);
184 struct stat statbuf; 177 struct stat statbuf;
185 int ret; 178 int ret;
186 179
187 DEBUG(5) debugf("path = %s\n", path); 180 DEBUG(5) debugf("path = %s\n", path);
188 181
189 ok = TRUE; 182 ok = TRUE;
190 ret = stat(path, &statbuf); 183 ret = stat(path, &statbuf);
191 if(ret != 0){ 184 if (ret != 0) {
192 ok = FALSE; 185 ok = FALSE;
193 if(errno == ENOENT){ 186 if (errno == ENOENT) {
194 logwrite(LOG_NOTICE, "directory %s does not exist, creating\n", path); 187 logwrite(LOG_NOTICE, "directory %s does not exist, creating\n", path);
195 if(mkdir(path, 0700) == 0) 188 if (mkdir(path, 0700) == 0)
196 ok = TRUE; 189 ok = TRUE;
197 }else 190 } else
198 logwrite(LOG_ALERT, "stat of %s failed: %s\n", path, strerror(errno)); 191 logwrite(LOG_ALERT, "stat of %s failed: %s\n", path, strerror(errno));
199 } 192 }
200 if(ok){ 193 if (ok) {
201 ok = FALSE; 194 ok = FALSE;
202 ret = stat(path, &statbuf); 195 ret = stat(path, &statbuf);
203 if(S_ISDIR(statbuf.st_mode)){ 196 if (S_ISDIR(statbuf.st_mode)) {
204 gchar *subdirs[] = {"tmp", "new", "cur"}; 197 gchar *subdirs[] = { "tmp", "new", "cur" };
205 int i; 198 int i;
206 for(i = 0; i < 3; i++){ 199 for (i = 0; i < 3; i++) {
207 char *path1 = g_strdup_printf("%s/%s", path, subdirs[i]); 200 char *path1 = g_strdup_printf("%s/%s", path, subdirs[i]);
208 ret = stat(path1, &statbuf); 201 ret = stat(path1, &statbuf);
209 if(ret != 0){ 202 if (ret != 0) {
210 if(errno == ENOENT){ 203 if (errno == ENOENT) {
211 logwrite(LOG_NOTICE, "directory %s does not exist, creating\n", path1); 204 logwrite(LOG_NOTICE, "directory %s does not exist, creating\n", path1);
212 if(mkdir(path1, 0700) != 0) break; 205 if (mkdir(path1, 0700) != 0)
213 } 206 break;
214 } 207 }
215 g_free(path1); 208 }
216 } 209 g_free(path1);
217 if(i == 3){ 210 }
218 FILE *out; 211 if (i == 3) {
219 mode_t saved_mode = umask(066); 212 FILE *out;
220 /* the qmail style unique works only if delivering 213 mode_t saved_mode = umask(066);
221 with different process. We do not fork for each delivery, 214 /* the qmail style unique works only if delivering
222 so our uid is more unique. Hope it is compatible with all 215 with different process. We do not fork for each delivery,
223 MUAs. 216 so our uid is more unique. Hope it is compatible with all
224 */ 217 MUAs.
225 gchar *filename = g_strdup_printf("%s/tmp/%s.%s", path, msg->uid, conf.host_name); 218 */
226 219 gchar *filename = g_strdup_printf("%s/tmp/%s.%s", path, msg->uid, conf.host_name);
227 DEBUG(5) debugf("filename = %s\n", filename); 220
228 221 DEBUG(5) debugf("filename = %s\n", filename);
229 if((out = fopen(filename, "w"))){ 222
230 gchar *newname = 223 if ((out = fopen(filename, "w"))) {
231 g_strdup_printf("%s/new/%s.%s", path, msg->uid, conf.host_name); 224 gchar *newname = g_strdup_printf("%s/new/%s.%s", path, msg->uid, conf.host_name);
232 message_stream(out, msg, hdr_list, flags); 225 message_stream(out, msg, hdr_list, flags);
233 ok = TRUE; 226 ok = TRUE;
234 if(fflush(out) == EOF) ok = FALSE; 227 if (fflush(out) == EOF)
235 else if(fdatasync(fileno(out)) != 0){ 228 ok = FALSE;
236 if(errno != EINVAL) /* some fs do not support this.. 229 else if (fdatasync(fileno(out)) != 0) {
237 I hope this also means that it is not necessary */ 230 if (errno != EINVAL) /* some fs do not support this.. I hope this also means that it is not necessary */
238 ok = FALSE; 231 ok = FALSE;
239 } 232 }
240 fclose(out); 233 fclose(out);
241 if(rename(filename, newname) != 0){ 234 if (rename(filename, newname) != 0) {
242 ok = FALSE; 235 ok = FALSE;
243 logwrite(LOG_ALERT, "moving %s to %s failed: %s", 236 logwrite(LOG_ALERT, "moving %s to %s failed: %s", filename, newname, strerror(errno));
244 filename, newname, strerror(errno)); 237 }
245 } 238 g_free(newname);
246 g_free(newname); 239 }
247 } 240 umask(saved_mode);
248 umask(saved_mode); 241 g_free(filename);
249 g_free(filename); 242 }
250 } 243 } else {
251 }else{ 244 logwrite(LOG_ALERT, "%s is not a directory\n", path);
252 logwrite(LOG_ALERT, "%s is not a directory\n", path); 245 errno = ENOTDIR;
253 errno = ENOTDIR; 246 }
254 } 247 }
255 } 248 if (!conf.run_as_user) {
256 if(!conf.run_as_user){ 249 uid_ok = (seteuid(0) == 0);
257 uid_ok = (seteuid(0) == 0); 250 if (uid_ok) {
258 if(uid_ok){ 251 gid_ok = (setegid(saved_gid) == 0);
259 gid_ok = (setegid(saved_gid) == 0); 252 uid_ok = (seteuid(saved_uid) == 0);
260 uid_ok = (seteuid(saved_uid) == 0); 253 }
261 } 254 }
262 } 255 if (!uid_ok || !gid_ok) {
263 if(!uid_ok || !gid_ok){ 256 /* FIXME: if this fails we HAVE to exit, because we shall not run
264 /* FIXME: if this fails we HAVE to exit, because we shall not run 257 with some users id. But we do not return, and so this message
265 with some users id. But we do not return, and so this message 258 will not be finished, so the user will get the message again
266 will not be finished, so the user will get the message again 259 next time a delivery is attempted... */
267 next time a delivery is attempted... */ 260 logwrite(LOG_ALERT, "could not set back uid or gid after local delivery: %s\n", strerror(errno));
268 logwrite(LOG_ALERT, 261 exit(EXIT_FAILURE);
269 "could not set back uid or gid after local delivery: %s\n", 262 }
270 strerror(errno)); 263 g_free(path);
271 exit(EXIT_FAILURE); 264 } else {
272 } 265 logwrite(LOG_ALERT, "could not set uid or gid for local delivery, uid = %d: %s\n", pw->pw_uid, strerror(errno));
273 g_free(path); 266 }
274 }else{ 267 } else {
275 logwrite(LOG_ALERT, 268 logwrite(LOG_ALERT, "could not find password entry for user %s\n", user);
276 "could not set uid or gid for local delivery, uid = %d: %s\n", 269 errno = ENOENT; /* getpwnam does not set errno correctly */
277 pw->pw_uid, strerror(errno)); 270 }
278 } 271 return ok;
279 }else{
280 logwrite(LOG_ALERT, "could not find password entry for user %s\n", user);
281 errno = ENOENT; /* getpwnam does not set errno correctly */
282 }
283 return ok;
284 } 272 }
285 #endif 273 #endif
286 274
287 gboolean 275 gboolean
288 pipe_out(message *msg, GList *hdr_list, address *rcpt, gchar *cmd, guint flags) 276 pipe_out(message * msg, GList * hdr_list, address * rcpt, gchar * cmd, guint flags)
289 { 277 {
290 gchar *envp[40]; 278 gchar *envp[40];
291 FILE *out; 279 FILE *out;
292 uid_t saved_uid = geteuid(); 280 uid_t saved_uid = geteuid();
293 gid_t saved_gid = getegid(); 281 gid_t saved_gid = getegid();
294 gboolean ok = FALSE; 282 gboolean ok = FALSE;
295 gint i, n; 283 gint i, n;
296 pid_t pid; 284 pid_t pid;
297 void (*old_signal)(int); 285 void (*old_signal) (int);
298 int status; 286 int status;
299 287
300 /* set uid and gid to the mail ids */ 288 /* set uid and gid to the mail ids */
301 if(!conf.run_as_user){ 289 if (!conf.run_as_user) {
302 set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); 290 set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid);
303 } 291 }
304 292
305 /* set environment */ 293 /* set environment */
306 { 294 {
307 gint i = 0; 295 gint i = 0;
308 address *ancestor = addr_find_ancestor(rcpt); 296 address *ancestor = addr_find_ancestor(rcpt);
309 297
310 envp[i++] = g_strdup_printf("SENDER=%s@%s", msg->return_path->local_part, msg->return_path->domain); 298 envp[i++] = g_strdup_printf("SENDER=%s@%s", msg->return_path->local_part, msg->return_path->domain);
311 envp[i++] = g_strdup_printf("SENDER_DOMAIN=%s", msg->return_path->domain); 299 envp[i++] = g_strdup_printf("SENDER_DOMAIN=%s", msg->return_path->domain);
312 envp[i++] = g_strdup_printf("SENDER_LOCAL=%s", msg->return_path->local_part); 300 envp[i++] = g_strdup_printf("SENDER_LOCAL=%s", msg->return_path->local_part);
313 envp[i++] = g_strdup_printf("RECEIVED_HOST=%s", msg->received_host ? msg->received_host : ""); 301 envp[i++] = g_strdup_printf("RECEIVED_HOST=%s", msg->received_host ? msg->received_host : "");
314 302
315 envp[i++] = g_strdup_printf("RETURN_PATH=%s@%s", 303 envp[i++] = g_strdup_printf("RETURN_PATH=%s@%s", msg->return_path->local_part, msg->return_path->domain);
316 msg->return_path->local_part, msg->return_path->domain); 304 envp[i++] = g_strdup_printf("DOMAIN=%s", ancestor->domain);
317 envp[i++] = g_strdup_printf("DOMAIN=%s", ancestor->domain); 305
318 306 envp[i++] = g_strdup_printf("LOCAL_PART=%s", ancestor->local_part);
319 envp[i++] = g_strdup_printf("LOCAL_PART=%s", ancestor->local_part); 307 envp[i++] = g_strdup_printf("USER=%s", ancestor->local_part);
320 envp[i++] = g_strdup_printf("USER=%s", ancestor->local_part); 308 envp[i++] = g_strdup_printf("LOGNAME=%s", ancestor->local_part);
321 envp[i++] = g_strdup_printf("LOGNAME=%s", ancestor->local_part); 309
322 310 envp[i++] = g_strdup_printf("MESSAGE_ID=%s", msg->uid);
323 envp[i++] = g_strdup_printf("MESSAGE_ID=%s", msg->uid); 311 envp[i++] = g_strdup_printf("QUALIFY_DOMAIN=%s", conf.host_name);
324 envp[i++] = g_strdup_printf("QUALIFY_DOMAIN=%s", conf.host_name); 312
325 313 envp[i] = NULL;
326 envp[i] = NULL; 314 n = i;
327 n = i; 315 }
328 } 316
329 317 old_signal = signal(SIGCHLD, SIG_DFL);
330 old_signal = signal(SIGCHLD, SIG_DFL); 318
331 319 out = peidopen(cmd, "w", envp, &pid, conf.mail_uid, conf.mail_gid);
332 out = peidopen(cmd, "w", envp, &pid, conf.mail_uid, conf.mail_gid); 320 if (out != NULL) {
333 if(out != NULL){ 321 message_stream(out, msg, hdr_list, flags);
334 message_stream(out, msg, hdr_list, flags); 322
335 323 fclose(out);
336 fclose(out); 324
337 325 waitpid(pid, &status, 0);
338 waitpid(pid, &status, 0); 326
339 327 if (WEXITSTATUS(status) != 0) {
340 if(WEXITSTATUS(status) != 0){ 328 int exstat = WEXITSTATUS(status);
341 int exstat = WEXITSTATUS(status); 329 logwrite(LOG_ALERT, "process returned %d (%s)\n", exstat, ext_strerror(1024 + exstat));
342 logwrite(LOG_ALERT, "process returned %d (%s)\n", exstat, ext_strerror(1024 + exstat)); 330 errno = 1024 + exstat;
343 errno = 1024 + exstat; 331 } else if (WIFSIGNALED(status)) {
344 }else if(WIFSIGNALED(status)){ 332 logwrite(LOG_ALERT, "process got signal %d\n", WTERMSIG(status));
345 logwrite(LOG_ALERT, "process got signal %d\n", WTERMSIG(status)); 333 } else
346 }else 334 ok = TRUE;
347 ok = TRUE; 335
348 336 } else
349 }else 337 logwrite(LOG_ALERT, "could not open pipe '%s': %s\n", cmd, strerror(errno));
350 logwrite(LOG_ALERT, "could not open pipe '%s': %s\n", cmd, strerror(errno)); 338
351 339 signal(SIGCHLD, old_signal);
352 signal(SIGCHLD, old_signal); 340
353 341 /* free environment */
354 /* free environment */ 342 for (i = 0; i < n; i++) {
355 for(i = 0; i < n; i++){ 343 g_free(envp[i]);
356 g_free(envp[i]); 344 }
357 } 345
358 346 /* set uid and gid back */
359 /* set uid and gid back */ 347 if (!conf.run_as_user) {
360 if(!conf.run_as_user){ 348 set_euidgid(saved_uid, saved_gid, NULL, NULL);
361 set_euidgid(saved_uid, saved_gid, NULL, NULL); 349 }
362 } 350
363 351 return ok;
364 return ok;
365 } 352 }
366