Define some macros only once
[nagios-reports-module.git] / auth.c
blob7d33f1a8c92c21e813e6408d90c6e43b7b912b2c
1 #include "logutils.h"
2 #include "cfgfile.h"
3 #include "hash.h"
4 #include "auth.h"
6 static const char *user;
7 static char **cgroups;
8 static uint num_cgroups, cgroup_idx;
9 static hash_table *auth_hosts, *auth_services;
10 static int is_host_root = 1, is_service_root = 1;
12 int auth_host_ok(const char *host)
14 if (is_host_root)
15 return 1;
17 return !!hash_find(auth_hosts, host);
20 int auth_service_ok(const char *host, const char *svc)
22 if (is_service_root || is_host_root)
23 return 1;
25 if ((hash_find2(auth_services, host, svc)) || auth_host_ok(host))
26 return 1;
28 return 0;
31 static int list_has_entry(const char *list, const char *ent)
33 unsigned int len;
34 const char *p;
36 len = strlen(ent);
38 for (p = list - 1; p; p = strchr(++p, ',')) {
39 p++;
40 if (!strncmp(p, ent, len) && (p[len] == ',' || !p[len])) {
41 return 1;
45 return 0;
48 static int list_has_any_entry(const char *list, char **ents, int nents)
50 int i;
52 for (i = 0; i < nents; i++) {
53 if (list_has_entry(list, ents[i])) {
54 return 1;
57 return 0;
60 static int grok_host(struct cfg_comp *obj)
62 int i;
63 char *host_name = NULL;
64 char *contacts = NULL;
65 char *groups = NULL;
67 for (i = 0; i < obj->vars; i++) {
68 struct cfg_var *v = obj->vlist[i];
69 if (!strcmp(v->key, "host_name")) {
70 host_name = v->value;
71 } else if (!strcmp(v->key, "contacts")) {
72 contacts = v->value;
73 } else if (!strcmp(v->key, "contact_groups")) {
74 groups = v->value;
78 if ((contacts && list_has_entry(contacts, user)) ||
79 (groups && list_has_any_entry(groups, cgroups, cgroup_idx)))
81 hash_add(auth_hosts, host_name, (void *)user);
84 if (!host_name)
85 return -1;
87 return 0;
90 static int grok_service(struct cfg_comp *obj)
92 int i;
93 char *host_name = NULL;
94 char *contacts = NULL;
95 char *groups = NULL;
96 char *service_description = NULL;
98 for (i = 0; i < obj->vars; i++) {
99 struct cfg_var *v = obj->vlist[i];
100 if (!strcmp(v->key, "host_name")) {
101 host_name = v->value;
102 } else if (!strcmp(v->key, "contacts")) {
103 contacts = v->value;
104 } else if (!strcmp(v->key, "contact_groups")) {
105 groups = v->value;
106 } else if (!strcmp(v->key, "service_description")) {
107 service_description = v->value;
111 if ((contacts && list_has_entry(contacts, user)) ||
112 (groups && list_has_any_entry(groups, cgroups, cgroup_idx)))
114 hash_add2(auth_services, host_name, service_description, (void *)user);
117 return 0;
120 static int grok_contactgroup(struct cfg_comp *obj)
122 int i;
123 char *name = NULL;
124 char *members = NULL;
126 for (i = 0; i < obj->vars; i++) {
127 struct cfg_var *v = obj->vlist[i];
128 if (!strcmp(v->key, "contactgroup_name")) {
129 name = v->value;
130 } else if (!strcmp(v->key, "members")) {
131 members = v->value;
135 if (list_has_entry(members, user)) {
136 if (cgroup_idx >= num_cgroups - 1) {
137 cgroups = realloc(cgroups, (num_cgroups + 5) * sizeof(char *));
138 if (!cgroups) {
139 printf("Failed to realloc(cgroups)\n");
140 exit(1);
142 num_cgroups += 5;
144 cgroups[cgroup_idx++] = name;
147 return 0;
150 static int grok_object(struct cfg_comp *conf, const char *str, int (*handler)(struct cfg_comp *))
152 int i;
154 for (i = 0; i < conf->nested; i++) {
155 struct cfg_comp *obj;
156 obj = conf->nest[i];
157 if (!strcmp(obj->name, str)) {
158 handler(obj);
162 return 0;
165 void auth_set_user(const char *username)
167 user = username;
170 const char *auth_get_user(void)
172 return user;
175 void auth_parse_permission(const char *key, const char *value)
177 int val;
179 if (!user || prefixcmp(key, "authorized_for_"))
180 return;
182 val = list_has_entry(value, user) | list_has_entry(value, "*");
183 if (!prefixcmp(key, "authorized_for_all_services")) {
184 is_service_root = val;
186 if (!prefixcmp(key, "authorized_for_all_hosts")) {
187 is_host_root = val;
188 is_service_root = val;
192 static struct cfg_comp *conf;
193 int auth_init(const char *path)
195 int host_buckets, service_buckets;
198 * if the user can see all hosts (and thus all services),
199 * we don't need to read the configuration
201 if (is_host_root)
202 return 0;
204 cgroups = calloc(20, sizeof(char *));
205 if (cgroups) {
206 num_cgroups = 20;
209 conf = cfg_parse_file(path);
210 if (!conf) {
211 printf("Failed to parse %s for some reason\n", path);
212 exit(1);
215 grok_object(conf, "define contactgroup ", grok_contactgroup);
216 if (!is_host_root) {
217 host_buckets = conf->nested / 10;
218 auth_hosts = hash_init(host_buckets);
219 grok_object(conf, "define host ", grok_host);
222 if (!is_service_root) {
223 service_buckets = conf->nested / 2;
224 auth_services = hash_init(service_buckets);
225 grok_object(conf, "define service ", grok_service);
227 return 0;
230 void auth_deinit(void)
232 if (conf)
233 cfg_destroy_compound(conf);
235 if (auth_hosts)
236 free(auth_hosts);
237 if (auth_services)
238 free(auth_services);
239 if (cgroups)
240 free(cgroups);