... | ... |
@@ -52,6 +52,7 @@ int main(int argc, char **argv) { |
52 | 52 |
const struct optstruct *opt; |
53 | 53 |
struct optstruct *opts; |
54 | 54 |
time_t currtime; |
55 |
+ mode_t umsk; |
|
55 | 56 |
int ret; |
56 | 57 |
|
57 | 58 |
memset(&descr, 0, sizeof(struct smfiDesc)); |
... | ... |
@@ -280,6 +281,7 @@ int main(int argc, char **argv) { |
280 | 280 |
return 1; |
281 | 281 |
} |
282 | 282 |
opt = optget(opts, "FixStaleSocket"); |
283 |
+ umsk = umask(0777); /* socket is created with 000 to avoid races */ |
|
283 | 284 |
if(smfi_opensocket(opt->enabled) == MI_FAILURE) { |
284 | 285 |
logg("!Failed to create socket %s\n", my_socket); |
285 | 286 |
localnets_free(); |
... | ... |
@@ -288,6 +290,65 @@ int main(int argc, char **argv) { |
288 | 288 |
optfree(opts); |
289 | 289 |
return 1; |
290 | 290 |
} |
291 |
+ umask(umsk); /* restore umask */ |
|
292 |
+ if(strncmp(my_socket, "inet:", 5) && strncmp(my_socket, "inet6:", 6)) { |
|
293 |
+ /* set group ownership and perms on the local socket */ |
|
294 |
+ char *sock_name = my_socket; |
|
295 |
+ mode_t sock_mode; |
|
296 |
+ if(!strncmp(my_socket, "unix:", 5)) |
|
297 |
+ sock_name += 5; |
|
298 |
+ if(!strncmp(my_socket, "local:", 6)) |
|
299 |
+ sock_name += 6; |
|
300 |
+ if(*my_socket == ':') |
|
301 |
+ sock_name ++; |
|
302 |
+ |
|
303 |
+ if(optget(opts, "MilterSocketGroup")->enabled) { |
|
304 |
+ char *gname = optget(opts, "MilterSocketGroup")->strarg, *end; |
|
305 |
+ gid_t sock_gid = strtol(gname, &end, 10); |
|
306 |
+ if(*end) { |
|
307 |
+ struct group *pgrp = getgrnam(gname); |
|
308 |
+ if(!pgrp) { |
|
309 |
+ logg("!Unknown group %s\n", gname); |
|
310 |
+ localnets_free(); |
|
311 |
+ whitelist_free(); |
|
312 |
+ logg_close(); |
|
313 |
+ optfree(opts); |
|
314 |
+ return 1; |
|
315 |
+ } |
|
316 |
+ sock_gid = pgrp->gr_gid; |
|
317 |
+ } |
|
318 |
+ if(chown(sock_name, -1, sock_gid)) { |
|
319 |
+ logg("!Failed to change socket ownership to group %s\n", gname); |
|
320 |
+ localnets_free(); |
|
321 |
+ whitelist_free(); |
|
322 |
+ logg_close(); |
|
323 |
+ optfree(opts); |
|
324 |
+ return 1; |
|
325 |
+ } |
|
326 |
+ } |
|
327 |
+ if(optget(opts, "MilterSocketMode")->enabled) { |
|
328 |
+ char *end; |
|
329 |
+ sock_mode = strtol(optget(opts, "MilterSocketMode")->strarg, &end, 8); |
|
330 |
+ if(*end) { |
|
331 |
+ logg("!Invalid MilterSocketMode %s\n", optget(opts, "MilterSocketMode")->strarg); |
|
332 |
+ localnets_free(); |
|
333 |
+ whitelist_free(); |
|
334 |
+ logg_close(); |
|
335 |
+ optfree(opts); |
|
336 |
+ return 1; |
|
337 |
+ } |
|
338 |
+ } else |
|
339 |
+ sock_mode = 0777 & ~umsk; |
|
340 |
+ |
|
341 |
+ if(chmod(sock_name, sock_mode & 0666)) { |
|
342 |
+ logg("!Cannot set milter socket permission to %s\n", optget(opts, "MilterSocketMode")->strarg); |
|
343 |
+ localnets_free(); |
|
344 |
+ whitelist_free(); |
|
345 |
+ logg_close(); |
|
346 |
+ optfree(opts); |
|
347 |
+ return 1; |
|
348 |
+ } |
|
349 |
+ } |
|
291 | 350 |
|
292 | 351 |
maxfilesize = optget(opts, "MaxFileSize")->numarg; |
293 | 352 |
readtimeout = optget(opts, "ReadTimeout")->numarg; |
... | ... |
@@ -487,11 +487,11 @@ int main(int argc, char **argv) |
487 | 487 |
break; |
488 | 488 |
} |
489 | 489 |
} |
490 |
- if(optget(opts, "LocalSocketPerms")->enabled) { |
|
490 |
+ if(optget(opts, "LocalSocketMode")->enabled) { |
|
491 | 491 |
char *end; |
492 |
- sock_mode = strtol(optget(opts, "LocalSocketPerms")->strarg, &end, 8); |
|
492 |
+ sock_mode = strtol(optget(opts, "LocalSocketMode")->strarg, &end, 8); |
|
493 | 493 |
if(*end) { |
494 |
- logg("!Invalid LocalSocketPerms %s\n", optget(opts, "LocalSocketPerms")->strarg); |
|
494 |
+ logg("!Invalid LocalSocketMode %s\n", optget(opts, "LocalSocketMode")->strarg); |
|
495 | 495 |
ret = 1; |
496 | 496 |
break; |
497 | 497 |
} |
... | ... |
@@ -499,7 +499,7 @@ int main(int argc, char **argv) |
499 | 499 |
sock_mode = 0777 /* & ~umsk*/; /* conservative default: umask was 0 in clamd < 0.96 */ |
500 | 500 |
|
501 | 501 |
if(chmod(optget(opts, "LocalSocket")->strarg, sock_mode & 0666)) { |
502 |
- logg("!Cannot set socket permission to %s\n", optget(opts, "LocalSocketPerms")->strarg); |
|
502 |
+ logg("!Cannot set socket permission to %s\n", optget(opts, "LocalSocketMode")->strarg); |
|
503 | 503 |
ret = 1; |
504 | 504 |
break; |
505 | 505 |
} |
... | ... |
@@ -186,7 +186,7 @@ const struct clam_option __clam_options[] = { |
186 | 186 |
|
187 | 187 |
{ "LocalSocketGroup", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD, "Sets the group ownership on the unix socket.", "virusgroup" }, |
188 | 188 |
|
189 |
- { "LocalSocketPerms", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD, "Sets the permissions on the unix socket.", "660" }, |
|
189 |
+ { "LocalSocketMode", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD, "Sets the permissions on the unix socket to the specified mode.", "660" }, |
|
190 | 190 |
|
191 | 191 |
{ "FixStaleSocket", NULL, 0, TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_CLAMD | OPT_MILTER, "Remove a stale socket after unclean shutdown", "yes" }, |
192 | 192 |
|
... | ... |
@@ -395,6 +395,10 @@ const struct clam_option __clam_options[] = { |
395 | 395 |
|
396 | 396 |
{ "MilterSocket",NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "Define the interface through which we communicate with sendmail.\nThis option is mandatory! Possible formats are:\n[[unix|local]:]/path/to/file - to specify a unix domain socket;\ninet:port@[hostname|ip-address] - to specify an ipv4 socket;\ninet6:port@[hostname|ip-address] - to specify an ipv6 socket.", "/tmp/clamav-milter.socket\ninet:7357" }, |
397 | 397 |
|
398 |
+ { "MilterSocketGroup", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "Define the group ownership for the (unix) milter socket.", "virusgroup" }, |
|
399 |
+ |
|
400 |
+ { "MilterSocketMode", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "Sets the permissions on the (unix) milter socket to the specified mode.", "660" }, |
|
401 |
+ |
|
398 | 402 |
{ "LocalNet", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_MILTER, "Messages originating from these hosts/networks will not be scanned\nThis option takes a host(name)/mask pair in CIRD notation and can be\nrepeated several times. If \"/mask\" is omitted, a host is assumed.\nTo specify a locally orignated, non-smtp, email use the keyword \"local\".", "local\n192.168.0.0/24\n1111:2222:3333::/48" }, |
399 | 403 |
|
400 | 404 |
{ "OnClean", NULL, 0, TYPE_STRING, "^(Accept|Reject|Defer|Blackhole|Quarantine)$", -1, "Accept", 0, OPT_MILTER, "Action to be performed on clean messages (mostly useful for testing).\nThe following actions are available:\nAccept: the message is accepted for delievery\nReject: immediately refuse delievery (a 5xx error is returned to the peer)\nDefer: return a temporary failure message (4xx) to the peer\nBlackhole: like Accept but the message is sent to oblivion\nQuarantine: like Accept but message is quarantined instead of being delivered", "Accept" }, |