Browse code

bb#1789 - part two

aCaB authored on 2010/02/05 06:01:05
Showing 3 changed files
... ...
@@ -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" },