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, 8 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

# User Rev Content
1 pippijn 1.1 /*
2     * privs.C: Services operator privileges
3 pippijn 1.6 *
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 pippijn 1.2 * Rights to this code are documented in doc/pod/license.pod.
10 pippijn 1.4 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
11 pippijn 1.1 */
12    
13 pippijn 1.7 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 pippijn 1.1
17     #include "atheme.h"
18     #include <account/myuser.h>
19     #include "privs.h"
20    
21 pippijn 1.7 operclass_t::list_type operclass_t::list;
22     soper_t::list_type soper_t::list;
23 pippijn 1.1
24     void
25     init_privs (void)
26     {
27 pippijn 1.4 #if 0
28 pippijn 1.1 operclass_heap = BlockHeapCreate (sizeof (operclass_t), 2);
29     soper_heap = BlockHeapCreate (sizeof (soper_t), 2);
30 pippijn 1.4 #endif
31 pippijn 1.1 }
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 pippijn 1.4 operclass = new operclass_t;
49 pippijn 1.7 operclass_t::list.insert (operclass);
50 pippijn 1.1 operclass->name = sstrdup (name);
51     operclass->privs = sstrdup (privs);
52     cnt.operclass++;
53 pippijn 1.7
54     foreach (soper_t *soper, soper_t::list)
55 pippijn 1.1 if (soper->operclass == NULL && !strcasecmp (name, soper->classname))
56     soper->operclass = operclass;
57 pippijn 1.7
58 pippijn 1.1 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 pippijn 1.7
68     operclass_t::list.erase (operclass);
69    
70     foreach (soper_t *soper, soper_t::list)
71 pippijn 1.1 if (soper->operclass == operclass)
72     soper->operclass = NULL;
73 pippijn 1.7
74 pippijn 1.4 sfree (operclass->name);
75     sfree (operclass->privs);
76     delete operclass;
77 pippijn 1.1 cnt.operclass--;
78     }
79    
80     operclass_t *
81 pippijn 1.4 operclass_find (char const * const name)
82 pippijn 1.1 {
83 pippijn 1.7 foreach (operclass_t *oc, operclass_t::list)
84     if (!strcasecmp (oc->name, name))
85     return oc;
86 pippijn 1.1
87 pippijn 1.7 return NULL;
88     }
89 pippijn 1.1
90 pippijn 1.7 void
91     operclass_cleanup ()
92     {
93     while (!operclass_t::list.empty ())
94     operclass_delete (operclass_t::list.back ());
95 pippijn 1.1 }
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 pippijn 1.5 myuser_t *mu = myuser_t::find (name);
106 pippijn 1.1 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 pippijn 1.4 soper = new soper_t;
130 pippijn 1.1
131 pippijn 1.7 soper_t::list.insert (soper);
132 pippijn 1.1
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 pippijn 1.7 soper_t::list.erase (soper);
166 pippijn 1.1
167     if (soper->myuser)
168     soper->myuser->soper = NULL;
169    
170     if (soper->name)
171 pippijn 1.4 sfree (soper->name);
172 pippijn 1.1
173 pippijn 1.4 sfree (soper->classname);
174 pippijn 1.1
175 pippijn 1.4 delete soper;
176 pippijn 1.1
177     cnt.soper--;
178     }
179    
180     soper_t *
181     soper_find (myuser_t *myuser)
182     {
183 pippijn 1.7 foreach (soper_t *soper, soper_t::list)
184 pippijn 1.1 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 pippijn 1.7 foreach (soper_t *so, soper_t::list)
194     if (so->name && !irccasecmp (so->name, name))
195     return so;
196 pippijn 1.1
197 pippijn 1.7 return NULL;
198     }
199 pippijn 1.1
200 pippijn 1.7 void
201     soper_cleanup ()
202     {
203     while (!soper_t::list.empty ())
204     soper_delete (soper_t::list.back ());
205 pippijn 1.1 }
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 pippijn 1.4 string_in_list (char const * const str, char const * const name)
234 pippijn 1.1 {
235     char *p;
236 pippijn 1.4 char const *s = str;
237 pippijn 1.1 int l;
238    
239 pippijn 1.4 if (s == NULL)
240 pippijn 1.1 return false;
241     l = strlen (name);
242 pippijn 1.4 while (*s != '\0')
243 pippijn 1.1 {
244 pippijn 1.4 p = strchr (s, ' ');
245     if (p != NULL ? p - s == l && !strncasecmp (s, name, p - s) : !strcasecmp (s, name))
246 pippijn 1.1 return true;
247     if (p == NULL)
248     return false;
249 pippijn 1.4 s = p;
250     while (*s == ' ')
251     s++;
252 pippijn 1.1 }
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 pippijn 1.4 has_priv (sourceinfo_t *si, char const * const priv)
280 pippijn 1.1 {
281     return si->su != NULL ? has_priv_user (si->su, priv) : has_priv_myuser (si->smu, priv);
282     }
283    
284     bool
285 pippijn 1.4 has_priv_user (user_t *u, char const * const priv)
286 pippijn 1.1 {
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 pippijn 1.4 has_priv_myuser (myuser_t *mu, char const * const priv)
314 pippijn 1.1 {
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 pippijn 1.4 has_priv_operclass (operclass_t *operclass, char const * const priv)
333 pippijn 1.1 {
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 pippijn 1.4 sfree (privs2);
354 pippijn 1.1 return false;
355     }
356     priv = strtok (NULL, " ");
357     }
358 pippijn 1.4 sfree (privs2);
359 pippijn 1.1 return true;
360     }