ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/privs.C
Revision: 1.7
Committed: Sat Sep 22 14:27:30 2007 UTC (16 years, 7 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +37 -54 lines
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

File Contents

# Content
1 /*
2 * privs.C: Services operator privileges
3 *
4 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5 * Rights to this code are as documented in COPYING.
6 *
7 *
8 * Portions of this file were derived from sources bearing the following license:
9 * Rights to this code are documented in doc/pod/license.pod.
10 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
11 */
12
13 static char const rcsid[] = "$Id: privs.C,v 1.6 2007-09-16 18:54:45 pippijn Exp $";
14
15 #include <boost/foreach.hpp>
16
17 #include "atheme.h"
18 #include <account/myuser.h>
19 #include "privs.h"
20
21 operclass_t::list_type operclass_t::list;
22 soper_t::list_type soper_t::list;
23
24 void
25 init_privs (void)
26 {
27 #if 0
28 operclass_heap = BlockHeapCreate (sizeof (operclass_t), 2);
29 soper_heap = BlockHeapCreate (sizeof (soper_t), 2);
30 #endif
31 }
32
33 /*************************
34 * O P E R C L A S S E S *
35 *************************/
36 operclass_t *
37 operclass_add (char *name, char const *privs)
38 {
39 operclass_t *operclass;
40
41 operclass = operclass_find (name);
42 if (operclass != NULL)
43 {
44 slog (LG_DEBUG, "operclass_add(): duplicate class %s", name);
45 return NULL;
46 }
47 slog (LG_DEBUG, "operclass_add(): %s [%s]", name, privs);
48 operclass = new operclass_t;
49 operclass_t::list.insert (operclass);
50 operclass->name = sstrdup (name);
51 operclass->privs = sstrdup (privs);
52 cnt.operclass++;
53
54 foreach (soper_t *soper, soper_t::list)
55 if (soper->operclass == NULL && !strcasecmp (name, soper->classname))
56 soper->operclass = operclass;
57
58 return operclass;
59 }
60
61 void
62 operclass_delete (operclass_t *operclass)
63 {
64 if (operclass == NULL)
65 return;
66 slog (LG_DEBUG, "operclass_delete(): %s", operclass->name);
67
68 operclass_t::list.erase (operclass);
69
70 foreach (soper_t *soper, soper_t::list)
71 if (soper->operclass == operclass)
72 soper->operclass = NULL;
73
74 sfree (operclass->name);
75 sfree (operclass->privs);
76 delete operclass;
77 cnt.operclass--;
78 }
79
80 operclass_t *
81 operclass_find (char const * const name)
82 {
83 foreach (operclass_t *oc, operclass_t::list)
84 if (!strcasecmp (oc->name, name))
85 return oc;
86
87 return NULL;
88 }
89
90 void
91 operclass_cleanup ()
92 {
93 while (!operclass_t::list.empty ())
94 operclass_delete (operclass_t::list.back ());
95 }
96
97 /***************
98 * S O P E R S *
99 ***************/
100
101 soper_t *
102 soper_add (char *name, char *classname, int flags)
103 {
104 soper_t *soper;
105 myuser_t *mu = myuser_t::find (name);
106 operclass_t *operclass = operclass_find (classname);
107
108 soper = mu ? soper_find (mu) : soper_find_named (name);
109 if (soper != NULL)
110 {
111 if (flags & SOPER_CONF && !(soper->flags & SOPER_CONF))
112 {
113 slog (LG_INFO, "soper_add(): conf soper %s (%s) is replacing DB soper with class %s", name, classname, soper->classname);
114 soper_delete (soper);
115 }
116 else if (!(flags & SOPER_CONF) && soper->flags & SOPER_CONF)
117 {
118 slog (LG_INFO, "soper_add(): ignoring DB soper %s (%s) because of conf soper with class %s", name, classname, soper->classname);
119 return NULL;
120 }
121 else
122 {
123 slog (LG_INFO, "soper_add(): duplicate soper %s", name);
124 return NULL;
125 }
126 }
127 slog (LG_DEBUG, "soper_add(): %s -> %s", (mu) ? mu->name : name, operclass ? operclass->name : "<null>");
128
129 soper = new soper_t;
130
131 soper_t::list.insert (soper);
132
133 if (mu)
134 {
135 soper->myuser = mu;
136 mu->soper = soper;
137 soper->name = NULL;
138 }
139 else
140 {
141 soper->name = sstrdup (name);
142 soper->myuser = NULL;
143 }
144 soper->operclass = operclass;
145 soper->classname = sstrdup (classname);
146 soper->flags = flags;
147
148 cnt.soper++;
149
150 return soper;
151 }
152
153 void
154 soper_delete (soper_t *soper)
155 {
156 if (!soper)
157 {
158 slog (LG_DEBUG, "soper_delete(): called for null soper");
159
160 return;
161 }
162
163 slog (LG_DEBUG, "soper_delete(): %s", (soper->myuser) ? soper->myuser->name : soper->name);
164
165 soper_t::list.erase (soper);
166
167 if (soper->myuser)
168 soper->myuser->soper = NULL;
169
170 if (soper->name)
171 sfree (soper->name);
172
173 sfree (soper->classname);
174
175 delete soper;
176
177 cnt.soper--;
178 }
179
180 soper_t *
181 soper_find (myuser_t *myuser)
182 {
183 foreach (soper_t *soper, soper_t::list)
184 if (soper->myuser && soper->myuser == myuser)
185 return soper;
186
187 return NULL;
188 }
189
190 soper_t *
191 soper_find_named (char *name)
192 {
193 foreach (soper_t *so, soper_t::list)
194 if (so->name && !irccasecmp (so->name, name))
195 return so;
196
197 return NULL;
198 }
199
200 void
201 soper_cleanup ()
202 {
203 while (!soper_t::list.empty ())
204 soper_delete (soper_t::list.back ());
205 }
206
207 bool
208 is_soper (myuser_t *myuser)
209 {
210 if (!myuser)
211 return false;
212
213 if (myuser->soper)
214 return true;
215
216 return false;
217 }
218
219 bool
220 is_conf_soper (myuser_t *myuser)
221 {
222 if (!myuser)
223 return false;
224
225 if (myuser->soper && myuser->soper->flags & SOPER_CONF)
226 return true;
227
228 return false;
229 }
230
231 /* name1 name2 name3... */
232 static bool
233 string_in_list (char const * const str, char const * const name)
234 {
235 char *p;
236 char const *s = str;
237 int l;
238
239 if (s == NULL)
240 return false;
241 l = strlen (name);
242 while (*s != '\0')
243 {
244 p = strchr (s, ' ');
245 if (p != NULL ? p - s == l && !strncasecmp (s, name, p - s) : !strcasecmp (s, name))
246 return true;
247 if (p == NULL)
248 return false;
249 s = p;
250 while (*s == ' ')
251 s++;
252 }
253 return false;
254 }
255
256 bool
257 has_any_privs (sourceinfo_t *si)
258 {
259 if (si->su != NULL && is_ircop (si->su))
260 return true;
261 if (si->smu && is_soper (si->smu))
262 return true;
263 return false;
264 }
265
266 bool
267 has_any_privs_user (user_t *u)
268 {
269 if (u == NULL)
270 return false;
271 if (is_ircop (u))
272 return true;
273 if (u->myuser && is_soper (u->myuser))
274 return true;
275 return false;
276 }
277
278 bool
279 has_priv (sourceinfo_t *si, char const * const priv)
280 {
281 return si->su != NULL ? has_priv_user (si->su, priv) : has_priv_myuser (si->smu, priv);
282 }
283
284 bool
285 has_priv_user (user_t *u, char const * const priv)
286 {
287 operclass_t *operclass;
288
289 if (priv == NULL)
290 return true;
291 if (u == NULL)
292 return false;
293 if (is_ircop (u))
294 {
295 operclass = operclass_find ("ircop");
296 if (operclass != NULL && string_in_list (operclass->privs, priv))
297 return true;
298 }
299 if (u->myuser && is_soper (u->myuser))
300 {
301 operclass = u->myuser->soper->operclass;
302 if (operclass == NULL)
303 return false;
304 if (operclass->flags & OPERCLASS_NEEDOPER && !is_ircop (u))
305 return false;
306 if (string_in_list (operclass->privs, priv))
307 return true;
308 }
309 return false;
310 }
311
312 bool
313 has_priv_myuser (myuser_t *mu, char const * const priv)
314 {
315 operclass_t *operclass;
316
317 if (priv == NULL)
318 return true;
319 if (mu == NULL)
320 return false;
321 if (!is_soper (mu))
322 return false;
323 operclass = mu->soper->operclass;
324 if (operclass == NULL)
325 return false;
326 if (string_in_list (operclass->privs, priv))
327 return true;
328 return false;
329 }
330
331 bool
332 has_priv_operclass (operclass_t *operclass, char const * const priv)
333 {
334 if (operclass == NULL)
335 return false;
336 if (string_in_list (operclass->privs, priv))
337 return true;
338 return false;
339 }
340
341 bool
342 has_all_operclass (sourceinfo_t *si, operclass_t *operclass)
343 {
344 char *privs2;
345 char *priv;
346
347 privs2 = sstrdup (operclass->privs);
348 priv = strtok (privs2, " ");
349 while (priv != NULL)
350 {
351 if (!has_priv (si, priv))
352 {
353 sfree (privs2);
354 return false;
355 }
356 priv = strtok (NULL, " ");
357 }
358 sfree (privs2);
359 return true;
360 }