Skip to content

Commit

Permalink
permissions: Integrate with 'db_default_url'
Browse files Browse the repository at this point in the history
    * DB partitions now inherit their DB URL (if not given explicitly)
        from 'db_url' -> 'db_default_url'
    * the above is similar for the 'table_name' property
       (inherit from the 'address_table' modparam)
    * rewrite the 'partitions' parser: no more coding style limitations
    * backwards-compatible: the 'db_url' is still mandatory if you are
      not specifying a partition definition!  This is due to the fact
      that the module has a non-DB based usage mode

Part of a series of patches for #2117
  • Loading branch information
liviuchircu committed Jul 7, 2020
1 parent b429338 commit bb57cc1
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 177 deletions.
57 changes: 55 additions & 2 deletions modules/permissions/address.c
Expand Up @@ -47,6 +47,20 @@

str def_part = str_init("default");

/* table & column names */
str db_url;
str address_table = str_init("address"); /* Name of address table */
str ip_col = str_init("ip"); /* Name of ip column */
str proto_col = str_init("proto"); /* Name of protocol column */
str pattern_col = str_init("pattern"); /* Name of pattern column */
str info_col = str_init("context_info"); /* Name of context info column */
str grp_col = str_init("grp"); /* Name of address group column */
str mask_col = str_init("mask"); /* Name of mask column */
str port_col = str_init("port"); /* Name of port column */
str id_col = str_init("id"); /* Name of id column */

int init_address_part(struct pm_partition*);


int proto_char2int(str *proto) {
int ret_proto;
Expand All @@ -57,6 +71,45 @@ int proto_char2int(str *proto) {
return ret_proto;
}


int init_address(void)
{
struct pm_partition *el, *prev_el;

if (db_url.s)
db_url.len = strlen(db_url.s);

address_table.len = strlen(address_table.s);
ip_col.len = strlen(ip_col.s);
proto_col.len = strlen(proto_col.s);
pattern_col.len = strlen(pattern_col.s);
info_col.len = strlen(info_col.s);
grp_col.len = strlen(grp_col.s);
mask_col.len = strlen(mask_col.s);
port_col.len = strlen(port_col.s);

if (init_address_df_part() != 0) {
LM_ERR("failed to init the 'default' partition\n");
return -1;
}

el = get_partitions();

while (el) {
if (init_address_part(el) != 0) {
LM_ERR("failed to initialize the '%.*s' partition\n",
el->name.len, el->name.s);
return -1;
}
prev_el = el;
el = el->next;
pkg_free(prev_el);
}

return 0;
}


/*
* Reload address table to new hash table and when done, make new hash table
* current one.
Expand Down Expand Up @@ -288,7 +341,7 @@ int reload_address_table(struct pm_part_struct *part_struct)
/*
* Initialize data structures
*/
int init_address(struct pm_partition *partition)
int init_address_part(struct pm_partition *partition)
{
struct pm_part_struct *part_struct;
/* Check if hash table needs to be loaded from address table */
Expand All @@ -310,7 +363,7 @@ int init_address(struct pm_partition *partition)
part_struct->table = partition->table;

if (db_bind_mod(&partition->url, &part_struct->perm_dbf) < 0) {
LM_ERR("load a database support module\n");
LM_ERR("failed to load a database support module\n");
return -1;
}

Expand Down
18 changes: 16 additions & 2 deletions modules/permissions/address.h
Expand Up @@ -26,12 +26,26 @@
#include "../../parser/msg_parser.h"
#include "partitions.h"

extern str def_part;
extern str db_url; /* Database URL */
extern str address_table; /* Name of address table */
extern str ip_col; /* Name of IP address column */
extern str proto_col; /* Name of protocol column */
extern str pattern_col; /* Name of pattern column */
extern str info_col; /* Name of context_info column */
extern str grp_col; /* Name of address group column */
extern str mask_col; /* Name of mask column */
extern str port_col; /* Name of port column */
extern str id_col; /* Name of id column */


int proto_char2int(str *proto);


/*
* Initialize data structures
* Initialize partitions & load data, if necessary
*/
int init_address(struct pm_partition*);
int init_address(void);


/*
Expand Down
185 changes: 76 additions & 109 deletions modules/permissions/partitions.c
Expand Up @@ -22,22 +22,24 @@
*
*/
#include <stdio.h>
#include "address.h"
#include "partitions.h"
#include "../../str.h"
#include "../../mem/mem.h"
#include "../../ut.h"
#include "../../db/db.h"
#include "../../lib/csv.h"

#define ERR 1

str part_db_url = {"db_url", sizeof("db_url") - 1};
str part_table_name = {"table_name", sizeof("table_name") - 1};
str part_db_url = str_init("db_url");
str part_table_name = str_init("table_name");

/* since default partition will probably be used the most
* it deserves a pointer for its own*/
struct pm_partition *partitions=NULL, *default_partition=NULL;
struct pm_partition *partitions, *default_partition;

struct pm_part_struct *part_structs=NULL;
struct pm_part_struct *part_structs;

static void *alloc_partitions(void)
{
Expand All @@ -52,8 +54,7 @@ static void *alloc_default_partition(void)
default_partition = pkg_malloc(sizeof(struct pm_partition));
if (default_partition) {
memset(default_partition, 0, sizeof(struct pm_partition));
default_partition->name.s = "default";
default_partition->name.len = sizeof("default") - 1;
default_partition->name = def_part;

default_partition->next = partitions;
partitions = default_partition;
Expand Down Expand Up @@ -85,72 +86,33 @@ struct pm_partition *partition_set(void)
return partitions;
}

/*
* set default partition url
*/
int set_default_db_url(modparam_t type, void *val)
int init_address_df_part(void)
{
str db_str;

db_str.s = (char *)val;
db_str.len = strlen(db_str.s);

str_trim_spaces_lr(db_str);

if (default_partition == NULL)
if (alloc_default_partition() == NULL)
goto out_nomem;

default_partition->url.s = (char *)val;
init_db_url( default_partition->url, 1 /* can be null */);
if (!db_url.s || default_partition)
return 0;

return 0;

out_nomem:
LM_ERR("no more memory!\n");
return -1;

}

/*
* set default partition table
*/
int set_default_table(modparam_t type, void *val)
{
str db_table;

db_table.s = (char *)val;
db_table.len = strlen(db_table.s);

str_trim_spaces_lr(db_table);

if (default_partition == NULL)
if (alloc_default_partition() == NULL)
goto out_nomem;

default_partition->table = db_table;
if (!alloc_default_partition()) {
LM_ERR("oom\n");
return -1;
}

default_partition->url = db_url;
default_partition->table = address_table;
return 0;

out_nomem:
LM_ERR("no more memory!\n");
return -1;

}



/*
* parse a partition parameter of type
* <part_name> : attr1=val1; attr2=val2;
* <part_name>: attr1=val1; attr2=val2
*/
int parse_partition(modparam_t t, void *val)
{
str type, value, token;
char *tok_end;
struct pm_partition *el, *it;
csv_record *name, *props, *params, *it;
str rem;
struct pm_partition *el, *part;

str decl = {(char*)val, strlen((char *)val)};
str in = {(char*)val, strlen((char *)val)};

if (get_partitions() == NULL) {
if (alloc_partitions() == NULL)
Expand All @@ -162,71 +124,76 @@ int parse_partition(modparam_t t, void *val)
goto out_memfault;
memset(el, 0, sizeof(struct pm_partition));

for (it=get_partitions(); it->next; it=it->next);
it->next = el;
for (part=get_partitions(); part->next; part=part->next);
part->next = el;
}

tok_end = q_memchr(decl.s, ':', decl.len);
if (tok_end == NULL)
goto out_invdef;

value.s = decl.s;
value.len = tok_end - decl.s;

str_trim_spaces_lr(value);
name = __parse_csv_record(&in, 0, ':');
if (!name)
goto bad_input;

el->name = value;
el->name = name->s;
if (str_match(&name->s, &def_part))
default_partition = el;

decl.len = decl.len - (++tok_end - decl.s);
decl.s = tok_end;

while (decl.len > 0 && decl.s) {
tok_end = q_memchr(decl.s, ';', decl.len);
if (tok_end == NULL)
break;

token.s = decl.s;
token.len = tok_end - token.s;

tok_end = q_memchr(token.s, '=', token.len);
if (tok_end == NULL)
break;

type.s = token.s;
type.len = tok_end - type.s;

value.s = tok_end + 1;
value.len = (token.s + token.len) - value.s;

decl.s += token.len + 1;
decl.len -= (token.len + 1);
if (!name->next) {
free_csv_record(name);
goto empty_part;
}

str_trim_spaces_lr(type);
str_trim_spaces_lr(value);
rem.s = name->next->s.s;
rem.len = in.len - (rem.s - in.s);
props = __parse_csv_record(&rem, 0, ';');
if (!props)
goto bad_input;

free_csv_record(name);

for (it = props; it; it = it->next) {
params = __parse_csv_record(&it->s, 0, '=');
if (!params)
goto bad_input;

if (str_match(&params->s, &part_db_url)) {
el->url = params->next->s;
} else if (str_match(&params->s, &part_table_name)) {
el->table = params->next->s;
} else if (!ZSTR(params->s)) {
LM_ERR("invalid token '%.*s' in partition '%.*s'\n",
params->s.len, params->s.s, el->name.len, el->name.s);
goto bad_input;
}

if (!str_strcmp( &type, &part_db_url))
el->url = value;
else if (!str_strcmp( &type, &part_table_name))
el->table = value;
else
goto out_invdef;
free_csv_record(params);
}

if (el->url.s == NULL) {
LM_ERR("you should define an URL for this partition %.*s\n",
el->name.len, el->name.s);
return -1;
free_csv_record(props);

empty_part:
if (!el->url.s) {
if (db_url.s) {
init_str(&el->url, db_url.s);
} else if (db_default_url) {
init_str(&el->url, db_default_url);
} else {
LM_ERR("partition '%.*s' has no 'db_url'\n",
el->name.len, el->name.s);
return -1;
}
}

if (!el->table.s)
init_str(&el->table, address_table.s);

return 0;

out_invdef:
LM_ERR("invalid partition definition!\n");
return -ERR;
bad_input:
LM_ERR("failed to parse partition: '%.*s'\n", in.len, in.s);
return -1;

out_memfault:
LM_ERR("no more memory\n");
return -ERR;
return -1;
}


Expand Down
3 changes: 1 addition & 2 deletions modules/permissions/partitions.h
Expand Up @@ -58,9 +58,8 @@ struct pm_part_struct {
};


int init_address_df_part(void);
int parse_partition(modparam_t, void*);
int set_default_table(modparam_t, void *val);
int set_default_db_url(modparam_t, void *val);
struct pm_partition *partition_set(void);
struct pm_part_struct *get_part_structs(void);
struct pm_part_struct *get_part_struct(str *name);
Expand Down

0 comments on commit bb57cc1

Please sign in to comment.