manager: Fix could not extend string messages.
authorRichard Mudgett <rmudgett@digium.com>
Fri, 21 Nov 2014 19:16:55 +0000 (19:16 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Fri, 21 Nov 2014 19:16:55 +0000 (19:16 +0000)
When shutting down Asterisk that has an active AMI connection, you get
several "failed to extend from %d to %d" messages because use of the
EVENT_FLAG_SHUTDOWN attempts to add all AMI permission strings to the
event.

* Created MAX_AUTH_PERM_STRING to use when creating stack based struct
ast_str variables used with the authority_to_str() and
user_authority_to_str() functions instead of a variety of magic numbers
that could be too small.

* Added a special check for EVENT_FLAG_SHUTDOWN to authority_to_str() so
it will not attempt to add all permission level strings.

Review: https://reviewboard.asterisk.org/r/4200/
........

Merged revisions 428570 from http://svn.asterisk.org/svn/asterisk/branches/11
........

Merged revisions 428571 from http://svn.asterisk.org/svn/asterisk/branches/12
........

Merged revisions 428572 from http://svn.asterisk.org/svn/asterisk/branches/13

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@428573 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/manager.c

index 1d243ac..6adce5f 100644 (file)
@@ -1854,6 +1854,9 @@ static const struct permalias {
        { 0, "none" },
 };
 
+/*! Maximum string length of the AMI authority permission string buildable from perms[]. */
+#define MAX_AUTH_PERM_STRING   150
+
 /*! \brief Checks to see if a string which can be used to evaluate functions should be rejected */
 static int function_capable_string_allowed_with_auths(const char *evaluating, int writepermlist)
 {
@@ -1882,8 +1885,10 @@ static const char *user_authority_to_str(int authority, struct ast_str **res)
                }
        }
 
-       if (ast_str_strlen(*res) == 0)  /* replace empty string with something sensible */
+       if (ast_str_strlen(*res) == 0) {
+               /* replace empty string with something sensible */
                ast_str_append(res, 0, "<none>");
+       }
 
        return ast_str_buffer(*res);
 }
@@ -1897,15 +1902,19 @@ static const char *authority_to_str(int authority, struct ast_str **res)
        char *sep = "";
 
        ast_str_reset(*res);
-       for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
-               if (authority & perms[i].num) {
-                       ast_str_append(res, 0, "%s%s", sep, perms[i].label);
-                       sep = ",";
+       if (authority != EVENT_FLAG_SHUTDOWN) {
+               for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
+                       if (authority & perms[i].num) {
+                               ast_str_append(res, 0, "%s%s", sep, perms[i].label);
+                               sep = ",";
+                       }
                }
        }
 
-       if (ast_str_strlen(*res) == 0)  /* replace empty string with something sensible */
+       if (ast_str_strlen(*res) == 0) {
+               /* replace empty string with something sensible */
                ast_str_append(res, 0, "<none>");
+       }
 
        return ast_str_buffer(*res);
 }
@@ -2174,7 +2183,7 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_
                AST_RWLIST_UNLOCK(&actions);
                return ret;
        }
-       authority = ast_str_alloca(80);
+       authority = ast_str_alloca(MAX_AUTH_PERM_STRING);
        if (a->argc < 4) {
                return CLI_SHOWUSAGE;
        }
@@ -2279,8 +2288,8 @@ static char *handle_showmanager(struct ast_cli_entry *e, int cmd, struct ast_cli
        struct ast_manager_user *user = NULL;
        int l, which;
        char *ret = NULL;
-       struct ast_str *rauthority = ast_str_alloca(128);
-       struct ast_str *wauthority = ast_str_alloca(128);
+       struct ast_str *rauthority = ast_str_alloca(MAX_AUTH_PERM_STRING);
+       struct ast_str *wauthority = ast_str_alloca(MAX_AUTH_PERM_STRING);
        struct ast_variable *v;
 
        switch (cmd) {
@@ -3968,7 +3977,7 @@ static int action_waitevent(struct mansession *s, const struct message *m)
 static int action_listcommands(struct mansession *s, const struct message *m)
 {
        struct manager_action *cur;
-       struct ast_str *temp = ast_str_alloca(256);
+       struct ast_str *temp = ast_str_alloca(MAX_AUTH_PERM_STRING);
 
        astman_start_ack(s, m);
        AST_RWLIST_RDLOCK(&actions);
@@ -4057,8 +4066,9 @@ static int action_login(struct mansession *s, const struct message *m)
        if ((s->session->send_events & EVENT_FLAG_SYSTEM)
                && (s->session->readperm & EVENT_FLAG_SYSTEM)
                && ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
-               struct ast_str *auth = ast_str_alloca(80);
+               struct ast_str *auth = ast_str_alloca(MAX_AUTH_PERM_STRING);
                const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
+
                astman_append(s, "Event: FullyBooted\r\n"
                        "Privilege: %s\r\n"
                        "Status: Fully Booted\r\n\r\n", cat_str);
@@ -6559,7 +6569,7 @@ int __ast_manager_event_multichan(int category, const char *event, int chancount
        RAII_VAR(struct ao2_container *, sessions, ao2_global_obj_ref(mgr_sessions), ao2_cleanup);
        struct mansession_session *session;
        struct manager_custom_hook *hook;
-       struct ast_str *auth = ast_str_alloca(80);
+       struct ast_str *auth = ast_str_alloca(MAX_AUTH_PERM_STRING);
        const char *cat_str;
        va_list ap;
        struct timeval now;