/* This file is part of GNU Pies. Copyright (C) 2015-2016 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 . */ #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 = grecs_strdup (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 = grecs_calloc (1, sizeof (*prov)); prov->name = grecs_strdup (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; }