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 @@ | |||
1 | /* This file is part of GNU Pies. | ||
2 | Copyright (C) 2015 Sergey Poznyakoff | ||
3 | |||
4 | GNU Pies is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 3, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | GNU Pies is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | #include "ident.h" | ||
18 | |||
19 | struct grecs_list *identity_provider_list; | ||
20 | |||
21 | static struct grecs_symtab *idmech_symtab; | ||
22 | |||
23 | static int | ||
24 | idmech_copy (void *a, void *b) | ||
25 | { | ||
26 | pies_identity_mechanism_t ma = a; | ||
27 | pies_identity_mechanism_t mb = b; | ||
28 | |||
29 | *ma = *mb; | ||
30 | ma->name = xstrdup (mb->name); | ||
31 | return 0; | ||
32 | } | ||
33 | |||
34 | int | ||
35 | pies_identity_mechanism_register (pies_identity_mechanism_t mech) | ||
36 | { | ||
37 | int install; | ||
38 | |||
39 | if (!idmech_symtab) | ||
40 | { | ||
41 | idmech_symtab = grecs_symtab_create (sizeof(*mech), | ||
42 | NULL, | ||
43 | NULL, | ||
44 | idmech_copy, | ||
45 | NULL, | ||
46 | NULL); | ||
47 | if (!idmech_symtab) | ||
48 | grecs_alloc_die(); | ||
49 | } | ||
50 | |||
51 | install = 1; | ||
52 | if (!grecs_symtab_lookup_or_install (idmech_symtab, mech, &install)) | ||
53 | abort (); | ||
54 | return !install; | ||
55 | } | ||
56 | |||
57 | pies_identity_mechanism_t | ||
58 | pies_identity_mechanism_lookup (char const *name) | ||
59 | { | ||
60 | struct pies_identity_mechanism key; | ||
61 | if (!idmech_symtab) | ||
62 | return NULL; | ||
63 | key.name = name; | ||
64 | return grecs_symtab_lookup_or_install (idmech_symtab, &key, NULL); | ||
65 | } | ||
66 | |||
67 | static int | ||
68 | idmech_help (void *data, void *unused) | ||
69 | { | ||
70 | pies_identity_mechanism_t p = data; | ||
71 | |||
72 | if (p->confhelp) | ||
73 | p->confhelp (); | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | void | ||
78 | pies_config_identity_mechanisms_help () | ||
79 | { | ||
80 | grecs_symtab_enumerate (idmech_symtab, idmech_help, NULL); | ||
81 | } | ||
82 | |||
83 | static int | ||
84 | get_string_node (struct grecs_node *node, const char *name, | ||
85 | struct grecs_node **pret) | ||
86 | { | ||
87 | struct grecs_node *p = grecs_find_node (node->down, name); | ||
88 | |||
89 | if (!p) | ||
90 | { | ||
91 | grecs_error (&node->locus, 0, | ||
92 | "no \"%s\" statement found", name); | ||
93 | return 1; | ||
94 | } | ||
95 | |||
96 | if (p->type != grecs_node_stmt) | ||
97 | { | ||
98 | grecs_error (&p->locus, 0, "must be simple statement"); | ||
99 | return 1; | ||
100 | } | ||
101 | |||
102 | if (p->v.value->type != GRECS_TYPE_STRING) | ||
103 | { | ||
104 | grecs_error (&p->locus, 0, "must be scalar"); | ||
105 | return 1; | ||
106 | } | ||
107 | |||
108 | *pret = p; | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | int | ||
113 | pies_config_provider (struct grecs_node *node) | ||
114 | { | ||
115 | char const *name; | ||
116 | pies_identity_mechanism_t mp; | ||
117 | struct pies_identity_provider *prov; | ||
118 | struct grecs_node *p; | ||
119 | |||
120 | if (node->v.value->type != GRECS_TYPE_STRING) | ||
121 | { | ||
122 | grecs_error (&node->locus, 0, "value must be scalar"); | ||
123 | return 1; | ||
124 | } | ||
125 | |||
126 | name = node->v.value->v.string; | ||
127 | |||
128 | if (get_string_node (node, "type", &p)) | ||
129 | return 1; | ||
130 | |||
131 | mp = pies_identity_mechanism_lookup (p->v.value->v.string); | ||
132 | if (!mp) | ||
133 | { | ||
134 | grecs_error (&p->locus, 0, "no such mechanism"); | ||
135 | return 1; | ||
136 | } | ||
137 | |||
138 | prov = xcalloc (1, sizeof (*prov)); | ||
139 | prov->name = xstrdup (name); | ||
140 | prov->mech = mp; | ||
141 | prov->locus = node->locus; | ||
142 | |||
143 | if (mp->configure && mp->configure (node, prov)) | ||
144 | { | ||
145 | grecs_error (&node->locus, 0, "provider configration failed"); | ||
146 | //FIXME: memory leak | ||
147 | return 1; | ||
148 | } | ||
149 | |||
150 | if (!identity_provider_list) | ||
151 | identity_provider_list = grecs_list_create (); | ||
152 | grecs_list_append (identity_provider_list, prov); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | char const * | ||
158 | pies_identity_provider_name (pies_identity_provider_t p) | ||
159 | { | ||
160 | return p->name; | ||
161 | } | ||