From eb154e963cd3e2bdab0b128d84ac03f6d8465a0d Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Tue, 16 Oct 2007 21:14:34 +0000 Subject: [PATCH] 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/branches/1.4@85958 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 3fee3f28bf..b178a9b999 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -124,6 +124,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"; @@ -2962,13 +2963,21 @@ static int remove_from_queue(const char *queuename, const char *interface) continue; } - 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) @@ -3345,6 +3354,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; } ast_module_user_remove(lu); @@ -4411,6 +4425,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; @@ -4551,6 +4568,9 @@ static int handle_queue_remove_member(int fd, int argc, char *argv[]) case RES_OUTOFMEMORY: ast_cli(fd, "Out of memory\n"); return RESULT_FAILURE; + case RES_NOT_DYNAMIC: + ast_cli(fd, "Member not dynamic\n"); + return RESULT_FAILURE; default: return RESULT_FAILURE; }