comparison src/log.c @ 331:e507c854a63e

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 16:19:07 +0200
parents f671821d8222
children b27f66555ba8
comparison
equal deleted inserted replaced
330:f899ca0835a8 331:e507c854a63e
63 openlog(PACKAGE, LOG_PID, LOG_MAIL); 63 openlog(PACKAGE, LOG_PID, LOG_MAIL);
64 } else { 64 } else {
65 uid_t saved_uid; 65 uid_t saved_uid;
66 gid_t saved_gid; 66 gid_t saved_gid;
67 67
68 saved_gid = setegid(conf.mail_gid); 68 if (!conf.run_as_user) {
69 saved_uid = seteuid(conf.mail_uid); 69 set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid);
70 }
70 71
71 filename = g_strdup_printf("%s/masqmail.log", conf.log_dir); 72 filename = g_strdup_printf("%s/masqmail.log", conf.log_dir);
72 logfile = fopen(filename, "a"); 73 logfile = fopen(filename, "a");
73 if (!logfile) { 74 if (!logfile) {
74 fprintf(stderr, "could not open log '%s': %s\n", filename, strerror(errno)); 75 fprintf(stderr, "could not open log '%s': %s\n", filename, strerror(errno));
75 return FALSE; 76 return FALSE;
76 } 77 }
77 g_free(filename); 78 g_free(filename);
78 79
79 seteuid(saved_uid); 80 if (!conf.run_as_user) {
80 setegid(saved_gid); 81 set_euidgid(saved_uid, saved_gid, NULL, NULL);
82 }
81 } 83 }
82 84
83 #ifdef ENABLE_DEBUG 85 #ifdef ENABLE_DEBUG
84 if (conf.debug_level > 0) { 86 if (conf.debug_level > 0) {
85 filename = g_strdup_printf("%s/debug.log", conf.log_dir); 87 filename = g_strdup_printf("%s/debug.log", conf.log_dir);
112 if ((conf.do_verbose && (pri & LOG_VERBOSE)) || (pri == LOG_ALERT) || (pri == LOG_WARNING)) { 114 if ((conf.do_verbose && (pri & LOG_VERBOSE)) || (pri == LOG_ALERT) || (pri == LOG_WARNING)) {
113 va_list args_copy; 115 va_list args_copy;
114 va_copy(args_copy, args); 116 va_copy(args_copy, args);
115 vfprintf(stdout, fmt, args_copy); 117 vfprintf(stdout, fmt, args_copy);
116 va_end(args_copy); 118 va_end(args_copy);
117 fflush(stdout); /* is this necessary? */ 119 fflush(stdout); /* in case output ends not with newline */
118 } 120 }
119 121
120 pri &= ~LOG_VERBOSE; 122 pri &= ~LOG_VERBOSE;
121 if (pri) { 123 if (!pri) {
122 if (conf.use_syslog) 124 return;
123 vsyslog(pri, fmt, args); 125 }
124 else { 126 if (conf.use_syslog)
125 if (pri <= conf.log_max_pri) { 127 vsyslog(pri, fmt, args);
126 FILE *file = logfile ? logfile : stderr; 128 else if (pri <= conf.log_max_pri) {
127 time_t now = time(NULL); 129 FILE *file = logfile ? logfile : stderr;
128 struct tm *t = localtime(&now); 130 time_t now = time(NULL);
129 gchar buf[24]; 131 struct tm *t = localtime(&now);
130 uid_t saved_uid; 132 gchar buf[24];
131 gid_t saved_gid; 133
132 134 strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t);
133 saved_gid = setegid(conf.mail_gid); 135 fprintf(file, "%s [%d] ", buf, getpid());
134 saved_uid = seteuid(conf.mail_uid); 136
135 137 vfprintf(file, fmt, args);
136 strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t); 138 fflush(file);
137 fprintf(file, "%s [%d] ", buf, getpid());
138
139 vfprintf(file, fmt, args);
140 fflush(file);
141
142 seteuid(saved_uid);
143 setegid(saved_gid);
144 }
145 }
146 } 139 }
147 } 140 }
148 141
149 #ifdef ENABLE_DEBUG 142 #ifdef ENABLE_DEBUG
150 void 143 void