ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/privs.C
Revision: 1.1
Committed: Thu Jul 19 08:24:59 2007 UTC (16 years, 10 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Log Message:
initial import. the most important changes since Atheme are:
- fixed many memory leaks
- fixed many bugs
- converted to C++ and use more STL containers
- added a (not very enhanced yet) perl module
- greatly improved XML-RPC speed
- added a JSON-RPC module with code from json-cpp
- added a valgrind memcheck module to operserv
- added a more object oriented base64 implementation
- added a specialised unit test framework
- improved stability
- use gettimeofday() if available
- reworked adding/removing commands
- MemoServ IGNORE DEL can now remove indices

File Contents

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