Index: main/manager.c =================================================================== --- main/manager.c (revision 49023) +++ main/manager.c (working copy) @@ -106,6 +106,7 @@ static AST_LIST_HEAD_STATIC(all_events, eventqent); static int displayconnects = 1; +static int allowmultiplelogin; static int timestampevents; static int httptimeout = 60; @@ -165,6 +166,7 @@ char *read; char *write; int displayconnects; /*!< XXX unused */ + int allowmultiplelogin; /* allow or disallow duplicate logins */ int keep; /*!< mark entries created on a reload */ AST_LIST_ENTRY(ast_manager_user) list; }; @@ -398,6 +400,23 @@ return ret; } +static int ast_get_manager_session_count_by_name(const char *name) +{ + struct mansession *session = NULL; + int count = 0; + + AST_LIST_TRAVERSE(&sessions, session, list) + if (!strcasecmp(session->username, name)) { + count++; + ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' session count %d\n", name, count); + } + + + + return count; +} + + /*! * lookup an entry in the list of registered users. * must be called with the list lock held. @@ -2025,6 +2044,7 @@ char action[80] = ""; int ret = 0; struct manager_action *tmp; + char *user = astman_get_header(m, "Username"); ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action)); if (option_debug) @@ -2039,6 +2059,17 @@ astman_send_error(s, m, "Permission denied"); return 0; } + if (!strcasecmp(action, "Login")) { + /* Check for duplicate logins IF option is set */ + if (!allowmultiplelogin) { + if (ast_get_manager_session_count_by_name(user) > 0) { + sleep(1); + astman_send_error(s, m, "Login Already In Use"); + return -1; + } + + } + } /* XXX should we protect the list navigation ? */ for (tmp = first_action ; tmp; tmp = tmp->next) { if (!strcasecmp(action, tmp->action)) { @@ -2985,6 +3016,8 @@ ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val); memset(&ami_desc.sin.sin_addr, 0, sizeof(ami_desc.sin.sin_addr)); } + } else if (!strcasecmp(var->name, "allowmultiplelogin")) { + allowmultiplelogin = ast_true(val); } else if (!strcasecmp(var->name, "displayconnects")) { displayconnects = ast_true(val); } else if (!strcasecmp(var->name, "timestampevents")) { Index: configs/manager.conf.sample =================================================================== --- configs/manager.conf.sample (revision 49023) +++ configs/manager.conf.sample (working copy) @@ -27,6 +27,7 @@ ;httptimeout = 60 bindaddr = 0.0.0.0 + ; Parameters that control AMI over TLS. ("enabled" must be set too). ; You can open a connection to this socket with e.g. ; @@ -38,6 +39,8 @@ ; sslcert=/tmp/asterisk.pem ; path to the certificate. +; +allowmultiplelogin = yes ; IF set to no, rejects manager logins that are already in use. ;displayconnects = yes ; ; Add a Unix epoch timestamp to events (not action responses)