From bece7e24f23a06058b1f87b76bfc43232e486b3b Mon Sep 17 00:00:00 2001
From: Mark Michelson <mmichelson@digium.com>
Date: Tue, 16 Oct 2007 21:16:00 +0000
Subject: [PATCH] Merged revisions 85958 via svnmerge from
 https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r85958 | mmichelson | 2007-10-16 16:14:34 -0500 (Tue, 16 Oct 2007) | 5 lines

Trying to remove a non-dynamic queue member via dynamic means can lead to some
interesting (read nasty) situations. This patch clears up the issue by making
only dynamic queue members removable via dynamic methods.


........


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@85959 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 apps/app_queue.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/apps/app_queue.c b/apps/app_queue.c
index 482200dad1..3f14761b48 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -126,6 +126,7 @@ static struct strategy {
 #define	RES_EXISTS	(-1)		/* Entry already exists */
 #define	RES_OUTOFMEMORY	(-2)		/* Out of memory */
 #define	RES_NOSUCHQUEUE	(-3)		/* No such queue */
+#define RES_NOT_DYNAMIC (-4)		/* Member is not dynamic */
 
 static char *app = "Queue";
 
@@ -3210,13 +3211,21 @@ static int remove_from_queue(const char *queuename, const char *interface)
 	ast_copy_string(tmpq.name, queuename, sizeof(tmpq.name));
 	if((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
 		ao2_lock(q);
-		if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER | OBJ_UNLINK))) {
+		if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
+			/* XXX future changes should beware of this assumption!! */
+			if(!mem->dynamic) {
+				res = RES_NOT_DYNAMIC;
+				ao2_ref(mem, -1);
+				ast_mutex_unlock(&q->lock);
+				break;
+			}
 			q->membercount--;
 			manager_event(EVENT_FLAG_AGENT, "QueueMemberRemoved",
 				"Queue: %s\r\n"
 				"Location: %s\r\n"
 				"MemberName: %s\r\n",
 				q->name, mem->interface, mem->membername);
+			ao2_unlink(q->members, mem);
 			ao2_ref(mem, -1);
 
 			if (queue_persistent_members)
@@ -3553,6 +3562,11 @@ static int rqm_exec(struct ast_channel *chan, void *data)
 		pbx_builtin_setvar_helper(chan, "RQMSTATUS", "NOSUCHQUEUE");
 		res = 0;
 		break;
+	case RES_NOT_DYNAMIC:
+		ast_log(LOG_WARNING, "Unable to remove interface from queue '%s': '%s' is not a dynamic member\n", args.queuename, args.interface);
+		pbx_builtin_setvar_helper(chan, "RQMSTATUS", "NOTDYNAMIC");
+		res = 0;
+		break;
 	}
 
 	return res;
@@ -4686,6 +4700,9 @@ static int manager_remove_queue_member(struct mansession *s, const struct messag
 	case RES_OUTOFMEMORY:
 		astman_send_error(s, m, "Out of memory");
 		break;
+	case RES_NOT_DYNAMIC:
+		astman_send_error(s, m, "Member not dynamic");
+		break;
 	}
 
 	return 0;
@@ -4826,6 +4843,9 @@ static char *handle_queue_add_member(struct ast_cli_entry *e, int cmd, struct as
 	case RES_OUTOFMEMORY:
 		ast_cli(a->fd, "Out of memory\n");
 		return CLI_FAILURE;
+	case RES_NOT_DYNAMIC:
+		ast_cli(fd, "Member not dynamic\n");
+		return RESULT_FAILURE;
 	default:
 		return CLI_FAILURE;
 	}
-- 
GitLab