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
[EMAIL PROTECTED]  http://www.xorcom.com
#! /bin/sh /usr/share/dpatch/dpatch-run
## voicemail_fix_mkdir.dpatch by Tzafrir Cohen <[EMAIL PROTECTED]>
##
## 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 [EMAIL PROTECTED] to [EMAIL 
PROTECTED]", 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), "[EMAIL PROTECTED]", 
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), 
"[EMAIL PROTECTED]", 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);
        }

Reply via email to