ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/privs.C
Revision: 1.5
Committed: Tue Aug 28 22:18:31 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.4: +2 -2 lines
Log Message:
added type traits

File Contents

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