masqmail-0.2

view src/log.c @ 184:b3835b6b834b

Security fix! Correct handling of seteuid() return value See Debian bug #638002, reported by John Lightsey. When possible the (already available) set_euidgid() function is used. Additionally, it is unnecessary to change the identity when writing into an already open file descriptor. This should fix the problem.
author markus schnalke <meillo@marmaro.de>
date Sat, 27 Aug 2011 18:00:40 +0200
parents f671821d8222
children
line source
1 /* MasqMail
2 Copyright (C) 1999-2001 Oliver Kurth
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
19 #include <sysexits.h>
21 #include "masqmail.h"
23 static char *_sysexit_strings[] = {
24 "command line usage error",
25 "data format error",
26 "cannot open input",
27 "addressee unknown",
28 "host name unknown",
29 "service unavailable",
30 "internal software error",
31 "system error (e.g., can't fork)",
32 "critical OS file missing",
33 "can't create (user) output file",
34 "input/output error",
35 "temp failure; user is invited to retry",
36 "remote error in protocol",
37 "permission denied",
38 "configuration error"
39 };
41 gchar*
42 ext_strerror(int err)
43 {
44 if (err < 1024)
45 return strerror(err);
46 else if (err > 1024 + EX__BASE
47 && (err - 1024 - EX__BASE < sizeof(_sysexit_strings) / sizeof(_sysexit_strings[0])))
48 return _sysexit_strings[err - 1024 - EX__BASE];
50 return "unknown error";
51 }
53 static FILE *logfile = NULL;
54 static FILE *debugfile = NULL;
56 gboolean
57 logopen()
58 {
59 gchar *filename;
60 mode_t saved_mode = umask(066);
62 if (conf.use_syslog) {
63 openlog(PACKAGE, LOG_PID, LOG_MAIL);
64 } else {
65 uid_t saved_uid;
66 gid_t saved_gid;
68 if (!conf.run_as_user) {
69 set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid);
70 }
72 filename = g_strdup_printf("%s/masqmail.log", conf.log_dir);
73 logfile = fopen(filename, "a");
74 if (!logfile) {
75 fprintf(stderr, "could not open log '%s': %s\n", filename, strerror(errno));
76 return FALSE;
77 }
78 g_free(filename);
80 if (!conf.run_as_user) {
81 set_euidgid(saved_uid, saved_gid, NULL, NULL);
82 }
83 }
85 #ifdef ENABLE_DEBUG
86 if (conf.debug_level > 0) {
87 filename = g_strdup_printf("%s/debug.log", conf.log_dir);
88 debugfile = fopen(filename, "a");
89 if (!debugfile) {
90 fprintf(stderr, "could not open debug log '%s'\n", filename);
91 return FALSE;
92 }
93 g_free(filename);
94 }
95 #endif
96 umask(saved_mode);
97 return TRUE;
98 }
100 void
101 logclose()
102 {
103 if (conf.use_syslog)
104 closelog();
105 else if (logfile)
106 fclose(logfile);
107 if (debugfile)
108 fclose(debugfile);
109 }
111 void
112 vlogwrite(int pri, const char *fmt, va_list args)
113 {
114 if ((conf.do_verbose && (pri & LOG_VERBOSE)) || (pri == LOG_ALERT) || (pri == LOG_WARNING)) {
115 va_list args_copy;
116 va_copy(args_copy, args);
117 vfprintf(stdout, fmt, args_copy);
118 va_end(args_copy);
119 fflush(stdout); /* in case output ends not with newline */
120 }
122 pri &= ~LOG_VERBOSE;
123 if (!pri) {
124 return;
125 }
126 if (conf.use_syslog)
127 vsyslog(pri, fmt, args);
128 else if (pri <= conf.log_max_pri) {
129 FILE *file = logfile ? logfile : stderr;
130 time_t now = time(NULL);
131 struct tm *t = localtime(&now);
132 gchar buf[24];
134 strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t);
135 fprintf(file, "%s [%d] ", buf, getpid());
137 vfprintf(file, fmt, args);
138 fflush(file);
139 }
140 }
142 #ifdef ENABLE_DEBUG
143 void
144 vdebugwrite(int pri, const char *fmt, va_list args)
145 {
146 time_t now = time(NULL);
147 struct tm *t = localtime(&now);
148 gchar buf[24];
149 strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t);
151 if (debugfile) {
152 fprintf(debugfile, "%s [%d] ", buf, getpid());
153 vfprintf(debugfile, fmt, args);
154 fflush(debugfile);
155 } else {
156 fprintf(stderr, "no debug file, msg was:\n");
157 vfprintf(stderr, fmt, args);
158 }
159 }
160 #endif
162 void
163 logwrite(int pri, const char *fmt, ...)
164 {
165 va_list args, args_copy;
166 int saved_errno = errno; /* somewhere this is changed to EBADF */
168 va_start(args, fmt);
169 #ifdef ENABLE_DEBUG
170 va_copy(args_copy, args);
171 #endif
172 vlogwrite(pri, fmt, args);
173 #ifdef ENABLE_DEBUG
174 if (debugfile)
175 vdebugwrite(pri, fmt, args_copy);
176 va_end(args_copy);
177 #endif
178 va_end(args);
180 errno = saved_errno;
181 }
183 #ifdef ENABLE_DEBUG
184 void
185 debugf(const char *fmt, ...)
186 {
187 va_list args;
188 va_start(args, fmt);
190 vdebugwrite(LOG_DEBUG, fmt, args);
192 va_end(args);
193 }
195 void
196 vdebugf(const char *fmt, va_list args)
197 {
198 vdebugwrite(LOG_DEBUG, fmt, args);
199 }
200 #endif
202 void
203 maillog(const char *fmt, ...)
204 {
205 va_list args;
206 va_start(args, fmt);
208 vlogwrite(LOG_NOTICE, fmt, args);
210 va_end(args);
211 }