master
c 255 lines 7.99 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "database/rrd.h"
4 #include "registry_internals.h"
5
6 struct registry registry;
7
8 // ----------------------------------------------------------------------------
9 // common functions
10
11 // parse a GUID and re-generated to be always lower case
12 // this is used as a protection against the variations of GUIDs
13 int regenerate_guid(const char *guid, char *result) {
14 nd_uuid_t uuid;
15 if(unlikely(uuid_parse(guid, uuid) == -1)) {
16 netdata_log_info("Registry: GUID '%s' is not a valid GUID.", guid);
17 return -1;
18 }
19 else {
20 uuid_unparse_lower(uuid, result);
21
22 #ifdef NETDATA_INTERNAL_CHECKS
23 if(strcmp(guid, result) != 0)
24 netdata_log_info("GUID '%s' and re-generated GUID '%s' differ!", guid, result);
25 #endif /* NETDATA_INTERNAL_CHECKS */
26 }
27
28 return 0;
29 }
30
31 // make sure the names of the machines / URLs do not contain any tabs
32 // (which are used as our separator in the database files)
33 // and are properly trimmed (before and after)
34 static inline char *registry_fix_machine_name(char *name, size_t *len) {
35 char *s = name?name:"";
36
37 // skip leading spaces
38 while(*s && isspace((uint8_t)*s)) s++;
39
40 // make sure all spaces are a SPACE
41 char *t = s;
42 while(*t) {
43 if(unlikely(isspace((uint8_t)*t)))
44 *t = ' ';
45
46 t++;
47 }
48
49 // remove trailing spaces
50 while(--t >= s) {
51 if(*t == ' ')
52 *t = '\0';
53 else
54 break;
55 }
56 t++;
57
58 if(likely(len))
59 *len = (t - s);
60
61 return s;
62 }
63
64 static inline char *registry_fix_url(char *url, size_t *len) {
65 size_t l = 0;
66 char *s = registry_fix_machine_name(url, &l);
67
68 // protection from too big URLs
69 if(l > registry.max_url_length) {
70 l = registry.max_url_length;
71 s[l] = '\0';
72 }
73
74 if(len) *len = l;
75 return s;
76 }
77
78
79 // ----------------------------------------------------------------------------
80 // HELPERS
81
82 // verify the person, the machine and the URL exist in our DB
83 REGISTRY_PERSON_URL *registry_verify_request(const char *person_guid, char *machine_guid, char *url, REGISTRY_PERSON **pp, REGISTRY_MACHINE **mm) {
84 char pbuf[GUID_LEN + 1], mbuf[GUID_LEN + 1];
85
86 if(!person_guid || !*person_guid || !machine_guid || !*machine_guid || !url || !*url) {
87 netdata_log_info("Registry Request Verification: invalid request! person: '%s', machine '%s', url '%s'", person_guid?person_guid:"UNSET", machine_guid?machine_guid:"UNSET", url?url:"UNSET");
88 return NULL;
89 }
90
91 // normalize the url
92 url = registry_fix_url(url, NULL);
93
94 // make sure the person GUID is valid
95 if(regenerate_guid(person_guid, pbuf) == -1) {
96 netdata_log_info("Registry Request Verification: invalid person GUID, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
97 return NULL;
98 }
99 person_guid = pbuf;
100
101 // make sure the machine GUID is valid
102 if(regenerate_guid(machine_guid, mbuf) == -1) {
103 netdata_log_info("Registry Request Verification: invalid machine GUID, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
104 return NULL;
105 }
106 machine_guid = mbuf;
107
108 // make sure the machine exists
109 REGISTRY_MACHINE *m = registry_machine_find(machine_guid);
110 if(!m) {
111 netdata_log_info("Registry Request Verification: machine not found, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
112 return NULL;
113 }
114 if(mm) *mm = m;
115
116 // make sure the person exist
117 REGISTRY_PERSON *p = registry_person_find(person_guid);
118 if(!p) {
119 netdata_log_info("Registry Request Verification: person not found, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
120 return NULL;
121 }
122 if(pp) *pp = p;
123
124 STRING *u = string_strdupz(url);
125 REGISTRY_PERSON_URL *pu = registry_person_url_index_find(p, u);
126 string_freez(u);
127
128 if(!pu) {
129 netdata_log_info("Registry Request Verification: URL not found for person, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
130 return NULL;
131 }
132 //else if (pu->machine != m) {
133 // netdata_log_info("Registry Request Verification: Machine mismatch: person: '%s', machine requested='%s' <> loaded='%s', url '%s'", person_guid, machine_guid, pu->machine->guid, url);
134 // return NULL;
135 //}
136
137 return pu;
138 }
139
140
141 // ----------------------------------------------------------------------------
142 // REGISTRY REQUESTS
143
144 REGISTRY_PERSON *registry_request_access(const char *person_guid, char *machine_guid, char *url, char *name, time_t when) {
145 netdata_log_debug(D_REGISTRY, "registry_request_access('%s', '%s', '%s'): NEW REQUEST", (person_guid)?person_guid:"", machine_guid, url);
146
147 bool is_dummy = is_dummy_person(person_guid);
148
149 REGISTRY_MACHINE *m = registry_machine_find_or_create(machine_guid, when, is_dummy);
150 if(!m) return NULL;
151
152 REGISTRY_PERSON *p = registry_person_find_or_create(person_guid, when, is_dummy);
153
154 // make sure the name is valid
155 size_t name_len;
156 name = registry_fix_machine_name(name, &name_len);
157
158 size_t url_len;
159 url = registry_fix_url(url, &url_len);
160
161 STRING *u = string_strdupz(url);
162
163 if(!is_dummy)
164 registry_person_link_to_url(p, m, u, name, name_len, when);
165
166 registry_machine_link_to_url(m, u, when);
167
168 registry_log('A', p, m, u, name);
169
170 registry.usages_count++;
171
172 return p;
173 }
174
175 REGISTRY_PERSON *registry_request_delete(const char *person_guid, char *machine_guid, char *url, char *delete_url, time_t when) {
176 (void) when;
177
178 REGISTRY_PERSON *p = NULL;
179 REGISTRY_MACHINE *m = NULL;
180 REGISTRY_PERSON_URL *pu = registry_verify_request(person_guid, machine_guid, url, &p, &m);
181 if(!pu || !p || !m) return NULL;
182
183 // normalize the url
184 delete_url = registry_fix_url(delete_url, NULL);
185
186 // make sure the user is not deleting the url it uses
187 /*
188 if(!strcmp(delete_url, pu->url->url)) {
189 netdata_log_info("Registry Delete Request: delete URL is the one currently accessed, person: '%s', machine '%s', url '%s', delete url '%s'"
190 , p->guid, m->guid, pu->url->url, delete_url);
191 return NULL;
192 }
193 */
194
195 STRING *d_url = string_strdupz(delete_url);
196 REGISTRY_PERSON_URL *dpu = registry_person_url_index_find(p, d_url);
197 string_freez(d_url);
198
199 if(!dpu) {
200 netdata_log_info("Registry Delete Request: URL not found for person: '%s', machine '%s', url '%s', delete url '%s'", p->guid
201 , m->guid, string2str(pu->url), delete_url);
202 return NULL;
203 }
204
205 registry_log('D', p, m, pu->url, string2str(dpu->url));
206 registry_person_unlink_from_url(p, dpu);
207
208 return p;
209 }
210
211
212 REGISTRY_MACHINE *registry_request_machine(const char *person_guid, char *request_machine, STRING **hostname) {
213 char pbuf[GUID_LEN + 1];
214 char mbuf[GUID_LEN + 1];
215
216 // make sure the person GUID is valid
217 if(regenerate_guid(person_guid, pbuf) == -1) {
218 netdata_log_info("REGISTRY: %s(): invalid person GUID '%s'", __FUNCTION__ , person_guid);
219 return NULL;
220 }
221 person_guid = pbuf;
222
223 // make sure the person GUID is valid
224 if(regenerate_guid(request_machine, mbuf) == -1) {
225 netdata_log_info("REGISTRY: %s(): invalid search machine GUID '%s'", __FUNCTION__ , request_machine);
226 return NULL;
227 }
228 request_machine = mbuf;
229
230 REGISTRY_PERSON *p = registry_person_find(person_guid);
231 if(!p) return NULL;
232
233 REGISTRY_MACHINE *m = registry_machine_find(request_machine);
234 if(!m) return NULL;
235
236 // Verify the user has in the past accessed this machine
237 // We will walk through the PERSON_URLs to find the machine
238 // linking to our machine
239
240 // make sure the user has access
241 for(REGISTRY_PERSON_URL *pu = p->person_urls; pu ;pu = pu->next)
242 if(pu->machine == m) {
243 *hostname = string_dup(pu->machine_name);
244 return m;
245 }
246
247 return NULL;
248 }
249
250
251 // ----------------------------------------------------------------------------
252
253 const char *registry_get_this_machine_hostname(void) {
254 return registry.hostname;
255 }