Asterisk - The Open Source Telephony Project  18.5.0
named_acl.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012, Digium, Inc.
5  *
6  * Mark Spencer <[email protected]>
7  * Jonathan Rose <[email protected]>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19 
20 /*! \file
21  *
22  * \brief Named Access Control Lists
23  *
24  * \author Jonathan Rose <[email protected]>
25  *
26  * \note Based on a feature proposed by
27  * Olle E. Johansson <[email protected]>
28  */
29 
30 /* This maintains the original "module reload acl" CLI command instead
31  * of replacing it with "module reload named_acl". */
32 #undef AST_MODULE
33 #define AST_MODULE "acl"
34 
35 #include "asterisk.h"
36 
37 #include "asterisk/config.h"
39 #include "asterisk/utils.h"
40 #include "asterisk/module.h"
41 #include "asterisk/cli.h"
42 #include "asterisk/acl.h"
43 #include "asterisk/astobj2.h"
44 #include "asterisk/paths.h"
45 #include "asterisk/stasis.h"
46 #include "asterisk/json.h"
48 
49 #define NACL_CONFIG "acl.conf"
50 #define ACL_FAMILY "acls"
51 
52 /*** DOCUMENTATION
53  <configInfo name="named_acl" language="en_US">
54  <configFile name="named_acl.conf">
55  <configObject name="named_acl">
56  <synopsis>Options for configuring a named ACL</synopsis>
57  <configOption name="permit">
58  <synopsis>An address/subnet from which to allow access</synopsis>
59  </configOption>
60  <configOption name="deny">
61  <synopsis>An address/subnet from which to disallow access</synopsis>
62  </configOption>
63  </configObject>
64  </configFile>
65  </configInfo>
66 ***/
67 
68 /*
69  * Configuration structure - holds pointers to ao2 containers used for configuration
70  * Since there isn't a general level or any other special levels for acl.conf at this
71  * time, it's really a config options friendly wrapper for the named ACL container
72  */
75 };
76 
78 
79 /*! \note These functions are used for placing/retrieving named ACLs in their ao2_container. */
80 static void *named_acl_config_alloc(void);
81 static void *named_acl_alloc(const char *cat);
82 static void *named_acl_find(struct ao2_container *container, const char *cat);
83 
84 /* Config type for named ACL profiles (must not be named general) */
85 static struct aco_type named_acl_type = {
86  .type = ACO_ITEM, /*!< named_acls are items stored in containers, not individual global objects */
87  .name = "named_acl",
88  .category_match = ACO_BLACKLIST_EXACT,
89  .category = "general", /*!< Match everything but "general" */
90  .item_alloc = named_acl_alloc, /*!< A callback to allocate a new named_acl based on category */
91  .item_find = named_acl_find, /*!< A callback to find a named_acl in some container of named_acls */
92  .item_offset = offsetof(struct named_acl_config, named_acl_list), /*!< Could leave this out since 0 */
93 };
94 
95 /* This array of aco_type structs is necessary to use aco_option_register */
96 struct aco_type *named_acl_types[] = ACO_TYPES(&named_acl_type);
97 
99  .filename = "acl.conf",
100  .types = ACO_TYPES(&named_acl_type),
101 };
102 
103 /* Create a config info struct that describes the config processing for named ACLs. */
104 CONFIG_INFO_CORE("named_acl", cfg_info, globals, named_acl_config_alloc,
105  .files = ACO_FILES(&named_acl_conf),
106 );
107 
108 struct named_acl {
109  struct ast_ha *ha;
110  char name[ACL_NAME_LENGTH]; /* Same max length as a configuration category */
111 };
112 
115 
116 /*! \brief destructor for named_acl_config */
117 static void named_acl_config_destructor(void *obj)
118 {
119  struct named_acl_config *cfg = obj;
121 }
122 
123 /*! \brief allocator callback for named_acl_config. Notice it returns void * since it is used by
124  * the backend config code
125  */
126 static void *named_acl_config_alloc(void)
127 {
128  struct named_acl_config *cfg;
129 
130  if (!(cfg = ao2_alloc(sizeof(*cfg), named_acl_config_destructor))) {
131  return NULL;
132  }
133 
135  named_acl_hash_fn, NULL, named_acl_cmp_fn);
136  if (!cfg->named_acl_list) {
137  goto error;
138  }
139 
140  return cfg;
141 
142 error:
143  ao2_ref(cfg, -1);
144  return NULL;
145 }
146 
147 /*! \brief Destroy a named ACL object */
148 static void destroy_named_acl(void *obj)
149 {
150  struct named_acl *named_acl = obj;
151  ast_free_ha(named_acl->ha);
152 }
153 
154 /*!
155  * \brief Create a named ACL structure
156  *
157  * \param cat name given to the ACL
158  * \retval NULL failure
159  *\retval non-NULL successfully allocated named ACL
160  */
161 static void *named_acl_alloc(const char *cat)
162 {
163  struct named_acl *named_acl;
164 
165  named_acl = ao2_alloc(sizeof(*named_acl), destroy_named_acl);
166  if (!named_acl) {
167  return NULL;
168  }
169 
170  ast_copy_string(named_acl->name, cat, sizeof(named_acl->name));
171 
172  return named_acl;
173 }
174 
175 /*!
176  * \brief Find a named ACL in a container by its name
177  *
178  * \param container ao2container holding the named ACLs
179  * \param cat name of the ACL wanted to be found
180  * \retval pointer to the named ACL if available. Null if not found.
181  */
182 static void *named_acl_find(struct ao2_container *container, const char *cat)
183 {
184  struct named_acl tmp;
185  ast_copy_string(tmp.name, cat, sizeof(tmp.name));
186  return ao2_find(container, &tmp, OBJ_POINTER);
187 }
188 
189 /*!
190  * \internal
191  * \brief Callback function to compare the ACL order of two given categories.
192  * This function is used to sort lists of ACLs received from realtime.
193  *
194  * \param p first category being compared
195  * \param q second category being compared
196  *
197  * \retval -1 (p < q)
198  * \retval 0 (p == q)
199  * \retval 1 (p > q)
200  */
201 static int acl_order_comparator(struct ast_category *p, struct ast_category *q)
202 {
203  int p_value = 0, q_value = 0;
204  struct ast_variable *p_var = ast_category_first(p);
205  struct ast_variable *q_var = ast_category_first(q);
206 
207  while (p_var) {
208  if (!strcasecmp(p_var->name, "rule_order")) {
209  p_value = atoi(p_var->value);
210  break;
211  }
212  p_var = p_var->next;
213  }
214 
215  while (q_var) {
216  if (!strcasecmp(q_var->name, "rule_order")) {
217  q_value = atoi(q_var->value);
218  break;
219  }
220  q_var = q_var->next;
221  }
222 
223  if (p_value < q_value) {
224  return -1;
225  } else if (q_value < p_value) {
226  return 1;
227  }
228 
229  return 0;
230 }
231 
232 /*!
233  * \internal
234  * \brief Search for a named ACL via realtime Database and build the named_acl
235  * if it is valid.
236  *
237  * \param name of the ACL wanted to be found
238  * \retval pointer to the named ACL if available. Null if the ACL subsystem is unconfigured.
239  */
240 static struct named_acl *named_acl_find_realtime(const char *name)
241 {
242  struct ast_config *cfg;
243  char *item = NULL;
244  const char *systemname = NULL;
245  struct ast_ha *built_ha = NULL;
246  struct named_acl *acl;
247 
248  /* If we have a systemname set in the global options, we only want to retrieve entries with a matching systemname field. */
249  systemname = ast_config_AST_SYSTEM_NAME;
250 
251  if (ast_strlen_zero(systemname)) {
252  cfg = ast_load_realtime_multientry(ACL_FAMILY, "name", name, SENTINEL);
253  } else {
254  cfg = ast_load_realtime_multientry(ACL_FAMILY, "name", name, "systemname", systemname, SENTINEL);
255  }
256 
257  if (!cfg) {
258  return NULL;
259  }
260 
261  /* At this point, the configuration must be sorted by the order field. */
263 
264  while ((item = ast_category_browse(cfg, item))) {
265  int append_ha_error = 0;
266  const char *order = ast_variable_retrieve(cfg, item, "rule_order");
267  const char *sense = ast_variable_retrieve(cfg, item, "sense");
268  const char *rule = ast_variable_retrieve(cfg, item, "rule");
269 
270  built_ha = ast_append_ha(sense, rule, built_ha, &append_ha_error);
271  if (append_ha_error) {
272  /* We need to completely reject an ACL that contains any bad rules. */
273  ast_log(LOG_ERROR, "Rejecting realtime ACL due to bad ACL definition '%s': %s - %s - %s\n", name, order, sense, rule);
274  ast_free_ha(built_ha);
275  return NULL;
276  }
277  }
278 
279  ast_config_destroy(cfg);
280 
281  acl = named_acl_alloc(name);
282  if (!acl) {
283  ast_log(LOG_ERROR, "allocation error\n");
284  ast_free_ha(built_ha);
285  return NULL;
286  }
287 
288  acl->ha = built_ha;
289 
290  return acl;
291 }
292 
293 struct ast_ha *ast_named_acl_find(const char *name, int *is_realtime, int *is_undefined)
294 {
295  struct ast_ha *ha = NULL;
296 
299 
300  if (is_realtime) {
301  *is_realtime = 0;
302  }
303 
304  if (is_undefined) {
305  *is_undefined = 0;
306  }
307 
308  /* If the config or its named_acl_list hasn't been initialized, abort immediately. */
309  if ((!cfg) || (!(cfg->named_acl_list))) {
310  ast_log(LOG_ERROR, "Attempted to find named ACL '%s', but the ACL configuration isn't available.\n", name);
311  return NULL;
312  }
313 
314  named_acl = named_acl_find(cfg->named_acl_list, name);
315 
316  /* If a named ACL couldn't be retrieved locally, we need to try realtime storage. */
317  if (!named_acl) {
318  RAII_VAR(struct named_acl *, realtime_acl, NULL, ao2_cleanup);
319 
320  /* Attempt to create from realtime */
321  if ((realtime_acl = named_acl_find_realtime(name))) {
322  if (is_realtime) {
323  *is_realtime = 1;
324  }
325  ha = ast_duplicate_ha_list(realtime_acl->ha);
326  return ha;
327  }
328 
329  /* Couldn't create from realtime. Raise relevant flags and print relevant warnings. */
331  ast_log(LOG_WARNING, "ACL '%s' does not exist. The ACL will be marked as undefined and will automatically fail if applied.\n"
332  "This ACL may exist in the configured realtime backend, but that backend hasn't been registered yet. "
333  "Fix this establishing preload for the backend in 'modules.conf'.\n", name);
334  } else {
335  ast_log(LOG_WARNING, "ACL '%s' does not exist. The ACL will be marked as undefined and will automatically fail if applied.\n", name);
336  }
337 
338  if (is_undefined) {
339  *is_undefined = 1;
340  }
341 
342  return NULL;
343  }
344 
346 
347  if (!ha) {
348  ast_log(LOG_NOTICE, "ACL '%s' contains no rules. It is valid, but it will accept addresses unconditionally.\n", name);
349  }
350 
351  return ha;
352 }
353 
354 /*! \brief Message type for named ACL changes */
356 
357 /*!
358  * \internal
359  * \brief Sends a stasis message corresponding to a given named ACL that has changed or
360  * that all ACLs have been updated and old copies must be refreshed. Consumers of
361  * named ACLs should subscribe to the ast_security_topic and respond to messages
362  * of the ast_named_acl_change_type stasis message type in order to be able to
363  * accommodate changes to named ACLs.
364  *
365  * \param name Name of the ACL that has changed. May be an empty string (but not NULL)
366  * If name is an empty string, then all ACLs must be refreshed.
367  *
368  * \retval 0 success
369  * \retval 1 failure
370  */
371 static int publish_acl_change(const char *name)
372 {
373  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
374  RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup);
375  RAII_VAR(struct ast_json *, json_object, ast_json_object_create(), ast_json_unref);
376 
377  if (!json_object || !ast_named_acl_change_type()) {
378  goto publish_failure;
379  }
380 
381  if (ast_json_object_set(json_object, "name", ast_json_string_create(name))) {
382  goto publish_failure;
383  }
384 
385  if (!(json_payload = ast_json_payload_create(json_object))) {
386  goto publish_failure;
387  }
388 
389  msg = stasis_message_create(ast_named_acl_change_type(), json_payload);
390 
391  if (!msg) {
392  goto publish_failure;
393  }
394 
396 
397  return 0;
398 
399 publish_failure:
400  ast_log(LOG_ERROR, "Failed to issue ACL change message for %s.\n",
401  ast_strlen_zero(name) ? "all named ACLs" : name);
402  return -1;
403 }
404 
405 /*!
406  * \internal
407  * \brief secondary handler for the 'acl show <name>' command (with arg)
408  *
409  * \param fd file descriptor of the cli
410  * \name name of the ACL requested for display
411  */
412 static void cli_display_named_acl(int fd, const char *name)
413 {
414  int is_realtime = 0;
415 
418 
419  /* If the configuration or the configuration's named_acl_list is unavailable, abort. */
420  if ((!cfg) || (!cfg->named_acl_list)) {
421  ast_log(LOG_ERROR, "Attempted to show named ACL '%s', but the acl configuration isn't available.\n", name);
422  return;
423  }
424 
425  named_acl = named_acl_find(cfg->named_acl_list, name);
426 
427  /* If the named_acl couldn't be found with the search, also abort. */
428  if (!named_acl) {
429  if (!(named_acl = named_acl_find_realtime(name))) {
430  ast_cli(fd, "\nCould not find ACL named '%s'\n", name);
431  return;
432  }
433 
434  is_realtime = 1;
435  }
436 
437  ast_cli(fd, "\nACL: %s%s\n---------------------------------------------\n", name, is_realtime ? " (realtime)" : "");
439 }
440 
441 /*!
442  * \internal
443  * \brief secondary handler for the 'acl show' command (no args)
444  *
445  * \param fd file descriptor of the cli
446  */
447 static void cli_display_named_acl_list(int fd)
448 {
449  struct ao2_iterator i;
450  void *o;
452 
453  ast_cli(fd, "\nacl\n---\n");
454 
455  if (!cfg || !cfg->named_acl_list) {
456  ast_cli(fd, "ACL configuration isn't available.\n");
457  return;
458  }
459  i = ao2_iterator_init(cfg->named_acl_list, 0);
460 
461  while ((o = ao2_iterator_next(&i))) {
462  struct named_acl *named_acl = o;
463  ast_cli(fd, "%s\n", named_acl->name);
464  ao2_ref(o, -1);
465  }
466 
468 }
469 
470 /* \brief ACL command show <name> */
471 static char *handle_show_named_acl_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
472 {
473  struct named_acl_config *cfg;
474  int length;
475  struct ao2_iterator i;
476  struct named_acl *named_acl;
477 
478  switch (cmd) {
479  case CLI_INIT:
480  e->command = "acl show";
481  e->usage =
482  "Usage: acl show [name]\n"
483  " Shows a list of named ACLs or lists all entries in a given named ACL.\n";
484  return NULL;
485  case CLI_GENERATE:
486  if (a->pos != 2) {
487  return NULL;
488  }
489 
491  if (!cfg) {
492  return NULL;
493  }
494  length = strlen(a->word);
495  i = ao2_iterator_init(cfg->named_acl_list, 0);
496  while ((named_acl = ao2_iterator_next(&i))) {
497  if (!strncasecmp(a->word, named_acl->name, length)) {
498  if (ast_cli_completion_add(ast_strdup(named_acl->name))) {
499  ao2_ref(named_acl, -1);
500  break;
501  }
502  }
503  ao2_ref(named_acl, -1);
504  }
506  ao2_ref(cfg, -1);
507 
508  return NULL;
509  }
510 
511  if (a->argc == 2) {
513  return CLI_SUCCESS;
514  }
515 
516  if (a->argc == 3) {
517  cli_display_named_acl(a->fd, a->argv[2]);
518  return CLI_SUCCESS;
519  }
520 
521 
522  return CLI_SHOWUSAGE;
523 }
524 
525 static struct ast_cli_entry cli_named_acl[] = {
526  AST_CLI_DEFINE(handle_show_named_acl_cmd, "Show a named ACL or list all named ACLs"),
527 };
528 
529 static int reload_module(void)
530 {
532 
533  status = aco_process_config(&cfg_info, 1);
534 
535  if (status == ACO_PROCESS_ERROR) {
536  ast_log(LOG_WARNING, "Could not reload ACL config\n");
537  return 0;
538  }
539 
540  if (status == ACO_PROCESS_UNCHANGED) {
541  /* We don't actually log anything if the config was unchanged,
542  * but we don't need to send a config change event either.
543  */
544  return 0;
545  }
546 
547  /* We need to push an ACL change event with no ACL name so that all subscribers update with all ACLs */
548  publish_acl_change("");
549 
550  return 0;
551 }
552 
553 static int unload_module(void)
554 {
555  ast_cli_unregister_multiple(cli_named_acl, ARRAY_LEN(cli_named_acl));
556 
558  aco_info_destroy(&cfg_info);
560 
561  return 0;
562 }
563 
564 static int load_module(void)
565 {
566  if (aco_info_init(&cfg_info)) {
568  }
569 
571 
572  /* Register the per level options. */
573  aco_option_register(&cfg_info, "permit", ACO_EXACT, named_acl_types, NULL, OPT_ACL_T, 1, FLDSET(struct named_acl, ha));
574  aco_option_register(&cfg_info, "deny", ACO_EXACT, named_acl_types, NULL, OPT_ACL_T, 0, FLDSET(struct named_acl, ha));
575 
576  aco_process_config(&cfg_info, 0);
577 
578  ast_cli_register_multiple(cli_named_acl, ARRAY_LEN(cli_named_acl));
579 
581 }
582 
584  .support_level = AST_MODULE_SUPPORT_CORE,
585  .load = load_module,
586  .unload = unload_module,
588  .load_pri = AST_MODPRI_CORE,
589  .requires = "extconfig",
590 );
struct ast_variable * next
struct ast_ha * ast_duplicate_ha_list(struct ast_ha *original)
Duplicate the contents of a list of host access rules.
Definition: acl.c:277
static int reload_module(void)
Definition: named_acl.c:529
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
static struct aco_type named_acl_type
Definition: named_acl.c:85
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
Security Event Reporting API.
CONFIG_INFO_CORE("named_acl", cfg_info, globals, named_acl_config_alloc,.files=ACO_FILES(&named_acl_conf),)
STASIS_MESSAGE_TYPE_DEFN(ast_named_acl_change_type)
Message type for named ACL changes.
#define AO2_STRING_FIELD_HASH_FN(stype, field)
Creates a hash function for a structure string field.
Definition: astobj2.h:2055
static int publish_acl_change(const char *name)
Definition: named_acl.c:371
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
struct ast_json_payload * ast_json_payload_create(struct ast_json *json)
Create an ao2 object to pass json blobs as data payloads for stasis.
Definition: json.c:735
struct ao2_container * named_acl_list
Definition: named_acl.c:74
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1501
#define OBJ_POINTER
Definition: astobj2.h:1154
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
descriptor for a cli entry.
Definition: cli.h:171
static char * handle_show_named_acl_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: named_acl.c:471
const int argc
Definition: cli.h:160
#define LOG_WARNING
Definition: logger.h:274
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: main/config.c:3363
Structure for variables, used for configurations and for channel variables.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1523
Definition: cli.h:152
struct stasis_message_type * ast_named_acl_change_type(void)
a stasis_message_type for changes against a named ACL or the set of all named ACLs ...
static struct named_acl * named_acl_find_realtime(const char *name)
Definition: named_acl.c:240
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
static struct aco_type item
Definition: test_config.c:1463
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
The representation of a single configuration file to be processed.
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
enum aco_type_t type
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition: json.c:404
Utility functions.
static void destroy_named_acl(void *obj)
Destroy a named ACL object.
Definition: named_acl.c:148
#define ast_strlen_zero(foo)
Definition: strings.h:52
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
static int load_module(void)
Definition: named_acl.c:564
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
Configuration File Parser.
#define ast_log
Definition: astobj2.c:42
struct ast_ha * ha
Definition: named_acl.c:109
#define SENTINEL
Definition: compiler.h:87
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
Asterisk JSON abstraction layer.
static void cli_display_named_acl_list(int fd)
Definition: named_acl.c:447
Asterisk file paths, configured in asterisk.conf.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:268
const int fd
Definition: cli.h:159
integer order
Definition: analys.c:66
Access Control of various sorts.
static AO2_GLOBAL_OBJ_STATIC(globals)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1157
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
aco_process_status
Return values for the aco_process functions.
struct ao2_container * container
Definition: res_fax.c:502
static struct console_pvt globals
The config had not been edited and no changes applied.
Their was an error and no changes were applied.
const char *const * argv
Definition: cli.h:161
Configuration option-handling.
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: main/config.c:3452
#define LOG_ERROR
Definition: logger.h:285
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static void cli_display_named_acl(int fd, const char *name)
Definition: named_acl.c:412
#define CLI_SHOWUSAGE
Definition: cli.h:45
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
#define ao2_global_obj_release(holder)
Definition: astobj2.h:865
static void * named_acl_alloc(const char *cat)
Create a named ACL structure.
Definition: named_acl.c:161
#define ACL_NAME_LENGTH
Definition: acl.h:59
struct aco_type * named_acl_types[]
Definition: named_acl.c:96
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define LOG_NOTICE
Definition: logger.h:263
Definition: test_acl.c:111
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511
static const char name[]
Definition: cdr_mysql.c:74
char * command
Definition: cli.h:186
Type for default option handler for ACLs.
static int reload(void)
Definition: cdr_mysql.c:741
Module could not be loaded properly.
Definition: module.h:102
static int acl_order_comparator(struct ast_category *p, struct ast_category *q)
Definition: named_acl.c:201
const char * word
Definition: cli.h:163
int ast_realtime_is_mapping_defined(const char *family)
Determine if a mapping exists for a given family.
Definition: main/config.c:3026
static void * named_acl_find(struct ao2_container *container, const char *cat)
Find a named ACL in a container by its name.
Definition: named_acl.c:182
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
const char * usage
Definition: cli.h:177
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:222
#define CLI_SUCCESS
Definition: cli.h:44
struct ast_json * ast_json_object_create(void)
Create a new JSON object.
Definition: json.c:389
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
#define ACO_FILES(...)
#define AO2_STRING_FIELD_CMP_FN(stype, field)
Creates a compare function for a structure string field.
Definition: astobj2.h:2071
struct ast_ha * ast_named_acl_find(const char *name, int *is_realtime, int *is_undefined)
Retrieve a named ACL.
Definition: named_acl.c:293
static int unload_module(void)
Definition: named_acl.c:553
struct aco_file named_acl_conf
Definition: named_acl.c:98
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
void ast_config_sort_categories(struct ast_config *config, int descending, int(*comparator)(struct ast_category *p, struct ast_category *q))
Sorts categories in a config in the order of a numerical value contained within them.
Definition: main/config.c:1171
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Standard Command Line Interface.
Type information about a category-level configurable object.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static void named_acl_config_destructor(void *obj)
destructor for named_acl_config
Definition: named_acl.c:117
const int pos
Definition: cli.h:164
const char * filename
void ast_ha_output(int fd, const struct ast_ha *ha, const char *prefix)
output an HA to the provided fd
Definition: acl.c:1087
static void * named_acl_config_alloc(void)
allocator callback for named_acl_config. Notice it returns void * since it is used by the backend con...
Definition: named_acl.c:126
static struct ast_cli_entry cli_named_acl[]
Definition: named_acl.c:525
Abstract JSON element (object, array, string, int, ...).
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
Definition: acl.c:713
int error(const char *format,...)
Definition: utils/frame.c:999
Generic container type.
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2726
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
#define ACL_FAMILY
Definition: named_acl.c:50
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
char name[ACL_NAME_LENGTH]
Definition: named_acl.c:110
jack_status_t status
Definition: app_jack.c:146
static struct test_val a