diff options
Diffstat (limited to 'ident/provider.c')
-rw-r--r-- | ident/provider.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/ident/provider.c b/ident/provider.c new file mode 100644 index 0000000..dd7fc3d --- /dev/null +++ b/ident/provider.c @@ -0,0 +1,161 @@ +/* This file is part of GNU Pies. + Copyright (C) 2015 Sergey Poznyakoff + + GNU Pies is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GNU Pies is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ + +#include "ident.h" + +struct grecs_list *identity_provider_list; + +static struct grecs_symtab *idmech_symtab; + +static int +idmech_copy (void *a, void *b) +{ + pies_identity_mechanism_t ma = a; + pies_identity_mechanism_t mb = b; + + *ma = *mb; + ma->name = xstrdup (mb->name); + return 0; +} + +int +pies_identity_mechanism_register (pies_identity_mechanism_t mech) +{ + int install; + + if (!idmech_symtab) + { + idmech_symtab = grecs_symtab_create (sizeof(*mech), + NULL, + NULL, + idmech_copy, + NULL, + NULL); + if (!idmech_symtab) + grecs_alloc_die(); + } + + install = 1; + if (!grecs_symtab_lookup_or_install (idmech_symtab, mech, &install)) + abort (); + return !install; +} + +pies_identity_mechanism_t +pies_identity_mechanism_lookup (char const *name) +{ + struct pies_identity_mechanism key; + if (!idmech_symtab) + return NULL; + key.name = name; + return grecs_symtab_lookup_or_install (idmech_symtab, &key, NULL); +} + +static int +idmech_help (void *data, void *unused) +{ + pies_identity_mechanism_t p = data; + + if (p->confhelp) + p->confhelp (); + return 0; +} + +void +pies_config_identity_mechanisms_help () +{ + grecs_symtab_enumerate (idmech_symtab, idmech_help, NULL); +} + +static int +get_string_node (struct grecs_node *node, const char *name, + struct grecs_node **pret) +{ + struct grecs_node *p = grecs_find_node (node->down, name); + + if (!p) + { + grecs_error (&node->locus, 0, + "no \"%s\" statement found", name); + return 1; + } + + if (p->type != grecs_node_stmt) + { + grecs_error (&p->locus, 0, "must be simple statement"); + return 1; + } + + if (p->v.value->type != GRECS_TYPE_STRING) + { + grecs_error (&p->locus, 0, "must be scalar"); + return 1; + } + + *pret = p; + return 0; +} + +int +pies_config_provider (struct grecs_node *node) +{ + char const *name; + pies_identity_mechanism_t mp; + struct pies_identity_provider *prov; + struct grecs_node *p; + + if (node->v.value->type != GRECS_TYPE_STRING) + { + grecs_error (&node->locus, 0, "value must be scalar"); + return 1; + } + + name = node->v.value->v.string; + + if (get_string_node (node, "type", &p)) + return 1; + + mp = pies_identity_mechanism_lookup (p->v.value->v.string); + if (!mp) + { + grecs_error (&p->locus, 0, "no such mechanism"); + return 1; + } + + prov = xcalloc (1, sizeof (*prov)); + prov->name = xstrdup (name); + prov->mech = mp; + prov->locus = node->locus; + + if (mp->configure && mp->configure (node, prov)) + { + grecs_error (&node->locus, 0, "provider configration failed"); + //FIXME: memory leak + return 1; + } + + if (!identity_provider_list) + identity_provider_list = grecs_list_create (); + grecs_list_append (identity_provider_list, prov); + + return 0; +} + +char const * +pies_identity_provider_name (pies_identity_provider_t p) +{ + return p->name; +} |