]> jfr.im git - solanum.git/blame - ircd/privilege.c
send: add sendto_one_multiline_* API
[solanum.git] / ircd / privilege.c
CommitLineData
9c3f080b 1/*
a6f63a82 2 * Solanum: a slightly advanced ircd
9c3f080b
AC
3 * privilege.c: Dynamic privileges API.
4 *
5 * Copyright (c) 2008 William Pitcock <nenolod@dereferenced.org>
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice is present in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
12 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
15 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
17 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
19 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
20 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
21 * POSSIBILITY OF SUCH DAMAGE.
22 */
23
24#include <stdinc.h>
422bb0b5 25#include "s_conf.h"
9c3f080b 26#include "privilege.h"
3a177354 27#include "numeric.h"
77d3d2db
KB
28#include "s_assert.h"
29#include "logger.h"
30#include "send.h"
9c3f080b 31
29c92cf9 32static rb_dlink_list privilegeset_list = {NULL, NULL, 0};
9c3f080b
AC
33
34int
35privilegeset_in_set(struct PrivilegeSet *set, const char *priv)
36{
37 s_assert(set != NULL);
38 s_assert(priv != NULL);
39
40 return strstr(set->privs, priv) != NULL;
41}
42
422bb0b5
JT
43static struct PrivilegeSet *
44privilegeset_get_any(const char *name)
45{
46 rb_dlink_node *iter;
47
48 s_assert(name != NULL);
49
50 RB_DLINK_FOREACH(iter, privilegeset_list.head)
51 {
52 struct PrivilegeSet *set = (struct PrivilegeSet *) iter->data;
53
f956cb0f 54 if (!rb_strcasecmp(set->name, name))
422bb0b5
JT
55 return set;
56 }
57
58 return NULL;
59}
60
9c3f080b
AC
61struct PrivilegeSet *
62privilegeset_set_new(const char *name, const char *privs, PrivilegeFlags flags)
63{
64 struct PrivilegeSet *set;
65
422bb0b5
JT
66 set = privilegeset_get_any(name);
67 if (set != NULL)
68 {
69 if (!(set->status & CONF_ILLEGAL))
70 ilog(L_MAIN, "Duplicate privset %s", name);
71 set->status &= ~CONF_ILLEGAL;
72 rb_free(set->privs);
73 }
74 else
75 {
76 set = rb_malloc(sizeof(struct PrivilegeSet));
77 set->status = 0;
78 set->refs = 0;
79 set->name = rb_strdup(name);
353f8625 80
422bb0b5
JT
81 rb_dlinkAdd(set, &set->node, &privilegeset_list);
82 }
9c3f080b
AC
83 set->privs = rb_strdup(privs);
84 set->flags = flags;
85
9c3f080b
AC
86 return set;
87}
88
353f8625
AC
89struct PrivilegeSet *
90privilegeset_extend(struct PrivilegeSet *parent, const char *name, const char *privs, PrivilegeFlags flags)
91{
92 struct PrivilegeSet *set;
93
94 s_assert(parent != NULL);
95 s_assert(name != NULL);
96 s_assert(privs != NULL);
353f8625 97
422bb0b5
JT
98 set = privilegeset_get_any(name);
99 if (set != NULL)
100 {
101 if (!(set->status & CONF_ILLEGAL))
102 ilog(L_MAIN, "Duplicate privset %s", name);
103 set->status &= ~CONF_ILLEGAL;
104 rb_free(set->privs);
105 }
106 else
107 {
108 set = rb_malloc(sizeof(struct PrivilegeSet));
109 set->status = 0;
110 set->refs = 0;
111 set->name = rb_strdup(name);
112
113 rb_dlinkAdd(set, &set->node, &privilegeset_list);
114 }
353f8625
AC
115 set->flags = flags;
116 set->privs = rb_malloc(strlen(parent->privs) + 1 + strlen(privs) + 1);
76de8880 117 strcpy(set->privs, parent->privs);
353f8625
AC
118 strcat(set->privs, " ");
119 strcat(set->privs, privs);
120
121 return set;
122}
123
9c3f080b
AC
124struct PrivilegeSet *
125privilegeset_get(const char *name)
126{
422bb0b5 127 struct PrivilegeSet *set;
9c3f080b 128
422bb0b5
JT
129 set = privilegeset_get_any(name);
130 if (set != NULL && set->status & CONF_ILLEGAL)
131 set = NULL;
132 return set;
9c3f080b
AC
133}
134
598b4cf1 135struct PrivilegeSet *
9c3f080b
AC
136privilegeset_ref(struct PrivilegeSet *set)
137{
138 s_assert(set != NULL);
139
140 set->refs++;
598b4cf1
AC
141
142 return set;
9c3f080b
AC
143}
144
145void
146privilegeset_unref(struct PrivilegeSet *set)
147{
148 s_assert(set != NULL);
149
422bb0b5
JT
150 if (set->refs > 0)
151 set->refs--;
152 else
153 ilog(L_MAIN, "refs on privset %s is already 0",
154 set->name);
155 if (set->refs == 0 && set->status & CONF_ILLEGAL)
9c3f080b
AC
156 {
157 rb_dlinkDelete(&set->node, &privilegeset_list);
158
159 rb_free(set->name);
160 rb_free(set->privs);
161 rb_free(set);
162 }
163}
422bb0b5
JT
164
165void
166privilegeset_mark_all_illegal(void)
167{
168 rb_dlink_node *iter;
169
170 RB_DLINK_FOREACH(iter, privilegeset_list.head)
171 {
172 struct PrivilegeSet *set = (struct PrivilegeSet *) iter->data;
173
a1d2fafd
JT
174 /* the "default" privset is special and must remain available */
175 if (!strcmp(set->name, "default"))
176 continue;
177
422bb0b5 178 set->status |= CONF_ILLEGAL;
106c8873
JT
179 rb_free(set->privs);
180 set->privs = rb_strdup("");
422bb0b5
JT
181 /* but do not free it yet */
182 }
183}
184
185void
186privilegeset_delete_all_illegal(void)
187{
188 rb_dlink_node *iter, *next;
189
190 RB_DLINK_FOREACH_SAFE(iter, next, privilegeset_list.head)
191 {
192 struct PrivilegeSet *set = (struct PrivilegeSet *) iter->data;
193
194 privilegeset_ref(set);
195 privilegeset_unref(set);
196 }
197}
3a177354
JT
198
199void
200privilegeset_report(struct Client *source_p)
201{
202 rb_dlink_node *ptr;
203
204 RB_DLINK_FOREACH(ptr, privilegeset_list.head)
205 {
206 struct PrivilegeSet *set = ptr->data;
207
208 /* use RPL_STATSDEBUG for now -- jilles */
209 sendto_one_numeric(source_p, RPL_STATSDEBUG,
210 "O :%s %s",
211 set->name,
212 set->privs);
213 }
214}