Index: include/asterisk/manager.h =================================================================== --- include/asterisk/manager.h (revision 7687) +++ include/asterisk/manager.h (working copy) @@ -64,6 +64,18 @@ char eventdata[1]; }; +struct ast_manager_user { + char username[80]; + char *secret; + char *deny; + char *permit; + char *read; + char *write; + unsigned int displayconnects:1; + struct ast_manager_user *next; +}; + + struct mansession { /*! Execution thread */ pthread_t t; Index: manager.c =================================================================== --- manager.c (revision 7687) +++ manager.c (working copy) @@ -87,6 +87,9 @@ static pthread_t t; AST_MUTEX_DEFINE_STATIC(sessionlock); + +static struct ast_manager_user *amus =NULL; +AST_MUTEX_DEFINE_STATIC(amulock); static int block_sockets = 0; static struct permalias { @@ -108,6 +111,11 @@ static struct manager_action *first_action = NULL; AST_MUTEX_DEFINE_STATIC(actionlock); +/* Prototypes */ +int *ast_manager_user_add(struct ast_manager_user *amu); +struct ast_manager_user *ast_get_manager_by_name_locked(const char *name); + + /*! If you are calling ast_carefulwrite, it is assumed that you are calling it on a file descriptor that _DOES_ have NONBLOCK set. This way, there is only one system call made to do a write, unless we actually @@ -266,6 +274,97 @@ { { "show", "manager", "connected", NULL }, handle_showmanconn, "Show connected manager interface users", showmanconn_help }; + +static int handle_showmanager(int fd, int argc, char *argv[]) +{ + struct ast_manager_user *tmp; + if (argc != 4 ) + return RESULT_SHOWUSAGE; + + /* try to lock manager_user list ... */ + if (ast_mutex_lock(&amulock)) { + ast_log(LOG_ERROR, "Unable to lock manager_user list\n"); + return -1; + } + + tmp = ast_get_manager_by_name_locked(argv[3]); + + if (!tmp) { + ast_cli(fd, "There are no manager called %s\n",argv[3]); + ast_mutex_unlock(&amulock); + return -1; + } + ast_cli(fd,"\n"); + ast_cli(fd, + " username: %s\n" + " secret: %s\n" + " deny: %s\n" + " permit: %s\n" + " read: %s\n" + " write: %s\n" + "displayconnects: %s\n", + (tmp->username ? tmp->username : "(N/A)"), + (tmp->secret ? tmp->secret : "(N/A)"), + (tmp->deny ? tmp->deny : "(N/A)"), + (tmp->permit ? tmp->permit : "(N/A)"), + (tmp->read ? tmp->read : "(N/A)"), + (tmp->write ? tmp->write : "(N/A)"), + (tmp->displayconnects ? "yes" : "no")); + ast_mutex_unlock(&amulock); + + return RESULT_SUCCESS; +} + + +static int handle_showmanagers(int fd, int argc, char *argv[]) { + struct ast_manager_user *tmp; + int count_amu = 0; + + if ( argc > 4 ) + return RESULT_SHOWUSAGE; + + /* try to lock manager_user list ... */ + if (ast_mutex_lock(&amulock)) { + ast_log(LOG_ERROR, "Unable to lock manager_user list\n"); + return -1; + } + + tmp=amus; + if (!tmp) { + ast_cli(fd, "There are no manager user.\n"); + ast_mutex_unlock(&amulock); + return -1; + } + ast_cli(fd, "\nusername\n--------\n"); + while (tmp) { + ast_cli(fd, "%s\n", tmp->username); + tmp = tmp->next; + count_amu++; + } + ast_mutex_unlock(&amulock); + ast_cli(fd,"-------------------\n"); + ast_cli(fd,"%d manager users configured.\n", count_amu); + return RESULT_SUCCESS; +} + +static char showmanagers_help[] = +"Usage: manager show users\n" +" Prints a listing of all managers that are currently configured on that\n" +" system.\n"; + +static char showmanager_help[] = +" Usage: manager user foobar\n" +" Display all the infos related to the user foobar.\n"; + + +static struct ast_cli_entry show_managers_cli = + { { "manager", "show", "users" }, + handle_showmanagers, "Show all managers users (connected or not)", showmanagers_help }; + +static struct ast_cli_entry show_manager_cli = +{ { "manager", "show", "user" }, handle_showmanager, "Display information on a specific manager", showmanager_help}; + + static void free_session(struct mansession *s) { struct eventqent *eqe; @@ -1646,15 +1745,29 @@ /*! @} END Doxygen group */ +int *ast_manager_user_add(struct ast_manager_user *amu) { + if (!amu) { + ast_log(LOG_DEBUG, "You cant pass NULL to that function"); + return NULL; + } + ast_mutex_lock(&amulock); + amu->next = amus; + amus = amu; + ast_mutex_unlock(&amulock); + return NULL; +} + + static int registered = 0; int init_manager(void) { struct ast_config *cfg; - char *val; + char *val,*cat; int oldportno = portno; static struct sockaddr_in ba; int x = 1; + amus = NULL; if (!registered) { /* Register default actions */ ast_manager_register2("Ping", 0, action_ping, "Keepalive command", mandescr_ping); @@ -1676,6 +1789,8 @@ ast_cli_register(&show_mancmd_cli); ast_cli_register(&show_mancmds_cli); ast_cli_register(&show_manconn_cli); + ast_cli_register(&show_managers_cli); + ast_cli_register(&show_manager_cli); ast_extension_state_add(NULL, NULL, manager_state_cb, NULL); registered = 1; } @@ -1733,6 +1848,59 @@ ast_log(LOG_WARNING, "Unable to change management port / enabled\n"); #endif } + + cat = ast_category_browse(cfg, NULL); + amus=NULL; /* Resetting the boss */ + while(cat) { + if (!strcasecmp(cat, "general")) { + ast_log(LOG_NOTICE, "ignoring the cat general\n"); + cat = ast_category_browse(cfg, cat); + continue; + } + + struct ast_manager_user *amu = malloc(sizeof(struct ast_manager_user)); + memset(amu, 0, sizeof(struct ast_manager_user)); + struct ast_variable *var; + var = ast_variable_browse(cfg, cat); + + while (var) { + if (!strcasecmp(var->name, "secret")) { + if (amu->secret) + free(amu->secret); + amu->secret=strdup(var->value); + } else if (!strcasecmp(var->name, "deny") ) { + if (amu->deny) + free(amu->deny); + amu->deny=strdup(var->value); + } else if (!strcasecmp(var->name, "permit") ) { + if (amu->permit) + free(amu->permit); + amu->permit=strdup(var->value); + } else if (!strcasecmp(var->name, "read") ) { + if (amu->read) + free(amu->read); + amu->read=strdup(var->value); + } else if (!strcasecmp(var->name, "write") ) { + if (amu->write) + free(amu->write); + amu->write=strdup(var->value); + } else if (!strcasecmp(var->name, "displayconnects") ) { + amu->displayconnects=ast_true(var->value); + } else { + ast_log(LOG_DEBUG, "%s is unknown.\n",var->name); + } + var = var->next; + } + + ast_copy_string(amu->username,cat,sizeof(amu->username)); + + ast_log(LOG_DEBUG, "Adding %s\n",amu->username); + ast_manager_user_add(amu); + amu=NULL; + cat = ast_category_browse(cfg, cat); + } + + ast_config_destroy(cfg); /* If not enabled, do nothing */ @@ -1770,3 +1938,19 @@ manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n"); return init_manager(); } + + +struct ast_manager_user *ast_get_manager_by_name_locked(const char *name) +{ + struct ast_manager_user *tmp = NULL; + tmp=amus; + while (tmp) { + if (!strcasecmp(tmp->username, name)) + break; + tmp = tmp->next; + } + if ( tmp) + return tmp; + return NULL; +} +