Bug#330132: voicemail files not group-readable

Tzafrir Cohen tzafrir.cohen at xorcom.com
Tue Nov 8 23:12:54 UTC 2005


On Mon, Sep 26, 2005 at 11:24:25AM +0300, Tzafrir Cohen wrote:
> Package: asterisk
> Version: 1.0.9.dfsg.1-3.1
> 
> The following was only tested on my packages, but should generally
> affect other Debian systems:
> 
> Asterisk's voicemail creates files with permissions 0600. Thus they are
> only readable by the user asterisk and not by anybody else in the group
> asterisk.
> 
> A trivial, hard-wired fix is attached, though is probably not optimized

Update: previous patch has only fixed new files creation. grep 0700
apps/app_voicemail.conf to see the number of times a directory is
created with those permissions.

The attached patch makes the voicemail group-readable/writable .

Also required is a chgrp in the postinst script to give permissions to
the asterisk group in the first place.

-- 
Tzafrir Cohen     icq#16849755  +972-50-7952406
tzafrir.cohen at xorcom.com  http://www.xorcom.com
-------------- next part --------------
#! /bin/sh /usr/share/dpatch/dpatch-run
## voicemail_fix_mkdir.dpatch by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Fixes bad use of mkdir. Also Sets the default permissions to 
## DP: voicemail files and dirs to group-accessible

@DPATCH@
diff -urNad asterisk-1.0.9.dfsg.1/apps/app_voicemail.c /tmp/dpep.nwJZ0u/asterisk-1.0.9.dfsg.1/apps/app_voicemail.c
--- asterisk-1.0.9.dfsg.1/apps/app_voicemail.c	2005-11-03 17:43:13.841466513 +0200
+++ /tmp/dpep.nwJZ0u/asterisk-1.0.9.dfsg.1/apps/app_voicemail.c	2005-11-03 17:45:24.625957572 +0200
@@ -63,6 +63,8 @@
 #include "../astconf.h"
 
 #define COMMAND_TIMEOUT 5000
+#define	VOICEMAIL_DIR_MODE	0770
+#define	VOICEMAIL_FILE_MODE	0660
 
 #define VOICEMAIL_CONFIG "voicemail.conf"
 #define ASTERISK_USERNAME "asterisk"
@@ -699,23 +701,51 @@
 	ast_safe_system(buf);
 }
 
-static int make_dir(char *dest, int len, char *context, char *ext, char *mailbox)
+static int voicemaildir(char *dest, int len, char *context, char *ext, char *mailbox)
 {
 	return snprintf(dest, len, "%s/voicemail/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR,context, ext, mailbox);
 }
 
-static int make_file(char *dest, int len, char *dir, int num)
+static int voicemail_file(char *dest, int len, char *dir, int num)
 {
 	return snprintf(dest, len, "%s/msg%04d", dir, num);
 }
 
+static int create_dirpath(char *dest, int len, char *context, char *ext, char *mailbox)
+{
+	mode_t	mode = VOICEMAIL_DIR_MODE;
+
+	if(context && context[0] != '\0') {
+		voicemaildir(dest, len, context, "", "");
+		if(mkdir(dest, mode) && errno != EEXIST) {
+			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
+			return 0;
+		}
+	}
+	if(ext && ext[0] != '\0') {
+		voicemaildir(dest, len, context, ext, "");
+		if(mkdir(dest, mode) && errno != EEXIST) {
+			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
+			return 0;
+		}
+	}
+	if(mailbox && mailbox[0] != '\0') {
+		voicemaildir(dest, len, context, ext, mailbox);
+		if(mkdir(dest, mode) && errno != EEXIST) {
+			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
+			return 0;
+		}
+	}
+	return 1;
+}
+
 static int last_message_index(char *dir)
 {
         int x;
         char fn[256];
         ast_lock_path(dir);
 	for (x=0;x<MAXMSG;x++) {
-                make_file(fn, sizeof(fn), dir, x);
+                voicemail_file(fn, sizeof(fn), dir, x);
                 if (ast_fileexists(fn, NULL, NULL) < 1)
                         break;
         }
@@ -1199,7 +1229,7 @@
 			ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
 			return -1;
 		}
-		if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) {
+		if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
 			ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
 			close(ifd);
 			return -1;
@@ -1243,24 +1273,14 @@
 
 	ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
 
-	make_dir(todir, sizeof(todir), recip->context, "", "");
-	/* It's easier just to try to make it than to check for its existence */
-	if (mkdir(todir, 0700) && (errno != EEXIST))
-		ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", todir, strerror(errno));
-	make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "");
-	/* It's easier just to try to make it than to check for its existence */
-	if (mkdir(todir, 0700) && (errno != EEXIST))
-		ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", todir, strerror(errno));
-	make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
-	if (mkdir(todir, 0700) && (errno != EEXIST))
-		ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", todir, strerror(errno));
+	create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
 
-	make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
-	make_file(frompath, sizeof(frompath), fromdir, msgnum);
+	voicemaildir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
+	voicemail_file(frompath, sizeof(frompath), fromdir, msgnum);
 	ast_lock_path(topath);
 	recipmsgnum = 0;
 	do {
-		make_file(topath, sizeof(topath), todir, recipmsgnum);
+		voicemail_file(topath, sizeof(topath), todir, recipmsgnum);
 		if (ast_fileexists(topath, NULL, chan->language) <= 0) 
 			break;
 		recipmsgnum++;
@@ -1342,17 +1362,7 @@
 			snprintf(prefile, sizeof(prefile), "voicemail/%s/%s/busy", vmu->context, ext);
 		else if (unavail)
 			snprintf(prefile, sizeof(prefile), "voicemail/%s/%s/unavail", vmu->context, ext);
-		make_dir(dir, sizeof(dir), vmu->context, "", "");
-		/* It's easier just to try to make it than to check for its existence */
-		if (mkdir(dir, 0700) && (errno != EEXIST))
-			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno));
-		make_dir(dir, sizeof(dir), vmu->context, ext, "");
-		/* It's easier just to try to make it than to check for its existence */
-		if (mkdir(dir, 0700) && (errno != EEXIST))
-			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno));
-		make_dir(dir, sizeof(dir), vmu->context, ext, "INBOX");
-		if (mkdir(dir, 0700) && (errno != EEXIST))
-			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno));
+		create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
 
 		/* Check current or macro-calling context for special extensions */
 		if (!ast_strlen_zero(vmu->exit)) {
@@ -1454,7 +1464,7 @@
 			}
 			ast_lock_path(dir);
 			do {
-				make_file(fn, sizeof(fn), dir, msgnum);
+				voicemail_file(fn, sizeof(fn), dir, msgnum);
 				if (ast_fileexists(fn, NULL, chan->language) <= 0) 
 					break;
 				msgnum++;
@@ -1582,11 +1592,11 @@
 
 	ast_lock_path(dir);
 	for (x=0,dest=0;x<MAXMSG;x++) {
-		make_file(sfn, sizeof(sfn), dir, x);
+		voicemail_file(sfn, sizeof(sfn), dir, x);
 		if (ast_fileexists(sfn, NULL, NULL) > 0) {
 
 			if(x != dest) {
-				make_file(dfn, sizeof(dfn), dir, dest);
+				voicemail_file(dfn, sizeof(dfn), dir, dest);
 				ast_filerename(sfn,dfn,NULL);
 
 				snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
@@ -1617,12 +1627,11 @@
 	char ntxt[256];
 	char *dbox = mbox(box);
 	int x;
-	make_file(sfn, sizeof(sfn), dir, msg);
-	make_dir(ddir, sizeof(ddir), context, username, dbox);
-	mkdir(ddir, 0700);
+	voicemail_file(sfn, sizeof(sfn), dir, msg);
+	create_dirpath(ddir, sizeof(ddir), context, username, dbox);
 	ast_lock_path(ddir);
 	for (x=0;x<MAXMSG;x++) {
-		make_file(dfn, sizeof(dfn), ddir, x);
+		voicemail_file(dfn, sizeof(dfn), ddir, x);
 		if (ast_fileexists(dfn, NULL, NULL) < 0)
 			break;
 	}
@@ -2216,8 +2225,8 @@
 {
 	char todir[256], fn[256], ext_context[256], *stringp;
 
-	make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
-	make_file(fn, sizeof(fn), todir, msgnum);
+	voicemaildir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
+	voicemail_file(fn, sizeof(fn), todir, msgnum);
 	snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
 
 	/* Attach only the first format */
@@ -2326,11 +2335,8 @@
 				/* if (ast_play_and_wait(chan, "vm-savedto"))
 					break;
 				*/
-				snprintf(todir, sizeof(todir), "%s/voicemail/%s/%s/INBOX",  (char *)ast_config_AST_SPOOL_DIR, vmtmp->context, vmtmp->mailbox);
-				snprintf(sys, sizeof(sys), "mkdir -p %s\n", todir);
+				create_dirpath(todir, sizeof(todir), vmtmp->context, vmtmp->mailbox, "INBOX");
 				snprintf(ext_context, sizeof(ext_context), "%s@%s", vmtmp->mailbox, vmtmp->context);
-				ast_log(LOG_DEBUG, "%s", sys);
-				ast_safe_system(sys);
 		
 				todircount = count_messages(todir);
 				strncpy(tmp, fmt, sizeof(tmp) - 1);
@@ -2548,7 +2554,7 @@
 	struct ast_config *msg_cfg;
 
 	vms->starting = 0; 
-	make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
+	voicemail_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
 	adsi_message(chan, vms);
 	if (!vms->curmsg)
 		res = wait_file2(chan, vms, "vm-first");	/* "First" */
@@ -2563,7 +2569,7 @@
 	}
 
 	/* Retrieve info from VM attribute file */
-	make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
+	voicemail_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
 	snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
 	msg_cfg = ast_load(filename);
 	if (!msg_cfg) {
@@ -2590,7 +2596,7 @@
 	ast_destroy(msg_cfg);
 
 	if (!res) {
-		make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
+		voicemail_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
 		vms->heard[vms->curmsg] = 1;
 		res = wait_file(chan, vms, vms->fn);
 	}
@@ -2600,7 +2606,7 @@
 static void open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu,int box)
 {
 	strncpy(vms->curbox, mbox(box), sizeof(vms->curbox) - 1);
-	make_dir(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
+	voicemaildir(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
 	vms->lastmsg = count_messages(vms->curdir) - 1;
 
 	/*
@@ -2631,11 +2637,11 @@
 		for (x=0;x < MAXMSG;x++) { 
 			if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
 				/* Save this message.  It's not in INBOX or hasn't been heard */ 
-				make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
+				voicemail_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
 				if (ast_fileexists(vms->fn, NULL, NULL) < 1) 
 					break;
 				vms->curmsg++; 
-				make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
+				voicemail_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
 				if (strcmp(vms->fn, vms->fn2)) { 
 					snprintf(txt, sizeof(txt), "%s.txt", vms->fn); 
 					snprintf(ntxt, sizeof(ntxt), "%s.txt", vms->fn2); 
@@ -2648,7 +2654,7 @@
 			} 
 		} 
 		for (x = vms->curmsg + 1; x <= MAXMSG; x++) { 
-			make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
+			voicemail_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
 			if (ast_fileexists(vms->fn, NULL, NULL) < 1) 
 				break;
 			vm_delete(vms->fn);
@@ -3489,10 +3495,7 @@
 		/* Set language from config to override channel language */
 		if (vmu->language && !ast_strlen_zero(vmu->language))
 			strncpy(chan->language, vmu->language, sizeof(chan->language)-1);
-		snprintf(vms.curdir, sizeof(vms.curdir), "%s/voicemail/%s", (char *)ast_config_AST_SPOOL_DIR, vmu->context);
-		mkdir(vms.curdir, 0700);
-		snprintf(vms.curdir, sizeof(vms.curdir), "%s/voicemail/%s/%s", (char *)ast_config_AST_SPOOL_DIR, vmu->context, vms.username);
-		mkdir(vms.curdir, 0700);
+		create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, "");
 		/* Retrieve old and new message counts */
 		open_mailbox(&vms, vmu, 1);
 		vms.oldmessages = vms.lastmsg + 1;
@@ -3687,7 +3690,7 @@
 					cmd = save_to_folder(vms.curdir, vms.curmsg, vmu->context, vms.username, cmd);
 					vms.deleted[vms.curmsg]=1;
 				}
-				make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
+				voicemail_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
 				if (useadsi)
 					adsi_message(chan, &vms);
 				if (!cmd)
@@ -3922,7 +3925,7 @@
 			char count[12];
 
 			if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
-				make_dir(dirname, 255, vmu->context, vmu->mailbox, "INBOX");
+				voicemaildir(dirname, 255, vmu->context, vmu->mailbox, "INBOX");
 				if ((vmdir = opendir(dirname))) {
 					/* No matter what the format of VM, there will always be a .txt file for each message. */
 					while ((vment = readdir(vmdir)))
@@ -4498,11 +4501,11 @@
 	int retries = 0;
 
 	vms->starting = 0; 
-	make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
+	voicemail_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
 
 	/* Retrieve info from VM attribute file */
 
-        make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
+        voicemail_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
         snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
         msg_cfg = ast_load(filename);
         if (!msg_cfg) {
@@ -4638,7 +4641,7 @@
 	ast_destroy(msg_cfg);
 
 	if (!res) {
-		make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
+		voicemail_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
 		vms->heard[msg] = 1;
 		res = wait_file(chan, vms, vms->fn);
 	}


More information about the Pkg-voip-maintainers mailing list