> -------- Original Message --------
> Subject: [Asterisk-Users] Voicemail questions
> Date: Tue, 9 Nov 2004 15:16:40 -0500
> From: Chris Armour <[EMAIL PROTECTED]>
> Reply-To: Asterisk Users Mailing List - Non-Commercial Discussion <[EMAIL PROTECTED]>
> To: <[EMAIL PROTECTED]>
>
> More Newbie Questions! This time about Comedian Mail:
>
> 1. I have the vmail.cgi script running and it looks great. Is there a permanent fix to the permissions problem on the messages? Right now I
> have to "chmod 777" the voicemail directory before I can listen to messages, which is obviously not workable for normal use.
>


Attached is a patch I made to app_voicemail.c that will set the owner, group and perms of all files and directories that are created so that vmail.cgi can run as user/group apache without setuid on vmail.cgi. The owner/group/perms are configurable in some static variables at the top so if you need them to change, you only need to change them there. Hope this helps.

Adam Fineberg

--- apps/app_voicemail.c.orig	2004-11-03 16:25:47.000000000 -0800
+++ apps/app_voicemail.c	2004-11-04 16:26:17.360445768 -0800
@@ -39,6 +39,8 @@
 #include <sys/types.h>
 #include <time.h>
 #include <dirent.h>
+#include <pwd.h>
+#include <grp.h>
 
 /* we define USESQLVM when we have MySQL or POSTGRES */
 #ifdef USEMYSQLVM
@@ -117,6 +119,12 @@
 
 */
 
+/* These define the owner and group of vm files to be accessible from the web interface */
+static char *uname = "root";
+static char *gname = "apache";
+static mode_t dirMode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
+static mode_t filMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
+
 struct baseio {
 	int iocp;
 	int iolen;
@@ -288,6 +296,50 @@
 
 LOCAL_USER_DECL;
 
+static void set_owner_and_group(const char* pathname)
+{
+	/* get the uid and gid we need */
+	struct passwd pwinfo;
+	pwinfo = *getpwnam(uname);
+	struct group grinfo;
+	grinfo = *getgrnam(gname);
+
+	if (chown(pathname, pwinfo.pw_uid, grinfo.gr_gid)) {
+	        ast_log(LOG_WARNING, "chown '%s' failed: %s\n", 
+			pathname, strerror(errno));
+	}
+}
+
+static void set_owner_and_group_all(const char* dir, int msgnum)
+{
+	DIR *vmdir = NULL;
+	struct dirent *vment = NULL;
+        char fn[32];
+	char pn[1024];
+	snprintf(fn, sizeof(fn), "msg%04d", msgnum);
+
+	if (sizeof(dir) + 11 >= sizeof(pn)) {
+	        ast_log(LOG_WARNING, "directory name too long to set owner and group, skipping\n");
+		return;
+	}
+	if ((vmdir = opendir(dir))) {
+		while ((vment = readdir(vmdir))) {
+		        if (!strncmp(vment->d_name, fn, 7)) {
+				strcpy(pn, dir);
+				pn[strlen(dir)] = '/';
+				pn[strlen(dir)+1] = 0;
+				strcat(pn, vment->d_name);
+				set_owner_and_group(pn);
+				if (chmod(pn, filMode)) {
+				        ast_log(LOG_WARNING, "chmod '%s' failed: %s\n",
+						pn, strerror(errno));
+				}
+			}
+		}
+		closedir(vmdir);
+	}
+}
+
 static void populate_defaults(struct ast_vm_user *vmu)
 {
 	vmu->attach = -1;
@@ -1196,7 +1248,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, filMode)) < 0) {
 			ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
 			close(ifd);
 			return -1;
@@ -1221,10 +1273,12 @@
 		} while(len);
 		close(ifd);
 		close(ofd);
+		set_owner_and_group(outfile);
 		return 0;
 #ifdef HARDLINK_WHEN_POSSIBLE
 	} else {
 		/* Hard link succeeded */
+		set_owner_and_group(outfile);
 		return 0;
 	}
 #endif
@@ -1242,15 +1296,18 @@
 
 	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))
+	if (mkdir(todir, dirMode) && (errno != EEXIST))
 		ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", todir, strerror(errno));
+	set_owner_and_group(todir);
 	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))
+	if (mkdir(todir, dirMode) && (errno != EEXIST))
 		ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", todir, strerror(errno));
+	set_owner_and_group(todir);
 	make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
-	if (mkdir(todir, 0700) && (errno != EEXIST))
+	if (mkdir(todir, dirMode) && (errno != EEXIST))
 		ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", todir, strerror(errno));
+	set_owner_and_group(todir);
 
 	make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
 	make_file(frompath, sizeof(frompath), fromdir, msgnum);
@@ -1341,15 +1398,18 @@
 			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))
+		if (mkdir(dir, dirMode) && (errno != EEXIST))
 			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno));
+		set_owner_and_group(dir);
 		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))
+		if (mkdir(dir, dirMode) && (errno != EEXIST))
 			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno));
+		set_owner_and_group(dir);
 		make_dir(dir, sizeof(dir), vmu->context, ext, "INBOX");
-		if (mkdir(dir, 0700) && (errno != EEXIST))
+		if (mkdir(dir, dirMode) && (errno != EEXIST))
 			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno));
+		set_owner_and_group(dir);
 
 		/* Check current or macro-calling context for special extensions */
 		if (!ast_strlen_zero(vmu->exit)) {
@@ -1507,6 +1567,8 @@
 					/* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
 					goto leave_vm_out;
 				}
+				set_owner_and_group(txtfile);
+				set_owner_and_group_all(dir, msgnum);
 				/* Are there to be more recipients of this message? */
 				while (tmpptr) {
 					struct ast_vm_user recipu, *recip;
@@ -1614,7 +1676,8 @@
 	int x;
 	make_file(sfn, sizeof(sfn), dir, msg);
 	make_dir(ddir, sizeof(ddir), context, username, dbox);
-	mkdir(ddir, 0700);
+	mkdir(ddir, dirMode);
+	set_owner_and_group(ddir);
 	for (x=0;x<MAXMSG;x++) {
 		make_file(dfn, sizeof(dfn), ddir, x);
 		if (ast_fileexists(dfn, NULL, NULL) < 0)
@@ -3388,9 +3451,11 @@
 		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);
+		mkdir(vms.curdir, dirMode);
+		set_owner_and_group(vms.curdir);
 		snprintf(vms.curdir, sizeof(vms.curdir), "%s/voicemail/%s/%s", (char *)ast_config_AST_SPOOL_DIR, vmu->context, vms.username);
-		mkdir(vms.curdir, 0700);
+		mkdir(vms.curdir, dirMode);
+		set_owner_and_group(vms.curdir);
 		/* Retrieve old and new message counts */
 		open_mailbox(&vms, vmu, 1);
 		vms.oldmessages = vms.lastmsg + 1;
_______________________________________________
Asterisk-Users mailing list
[EMAIL PROTECTED]
http://lists.digium.com/mailman/listinfo/asterisk-users
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-users

Reply via email to