summaryrefslogtreecommitdiff
path: root/libmailutils/server/acl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmailutils/server/acl.c')
-rw-r--r--libmailutils/server/acl.c366
1 files changed, 90 insertions, 276 deletions
diff --git a/libmailutils/server/acl.c b/libmailutils/server/acl.c
index 0b7a507e0..ba1a4b86b 100644
--- a/libmailutils/server/acl.c
+++ b/libmailutils/server/acl.c
@@ -40,14 +40,20 @@
40#include <mailutils/kwd.h> 40#include <mailutils/kwd.h>
41#include <mailutils/io.h> 41#include <mailutils/io.h>
42#include <mailutils/util.h> 42#include <mailutils/util.h>
43#include <mailutils/sockaddr.h>
44#include <mailutils/cidr.h>
45#include <mailutils/stream.h>
46#include <mailutils/stdstream.h>
47
48#ifndef MU_INADDR_BYTES
49#define MU_INADDR_BYTES 16
50#endif
43 51
44struct _mu_acl_entry 52struct _mu_acl_entry
45{ 53{
46 mu_acl_action_t action; 54 mu_acl_action_t action;
47 void *arg; 55 void *arg;
48 unsigned netmask; 56 struct mu_cidr cidr;
49 int salen;
50 struct sockaddr sa[1];
51}; 57};
52 58
53struct _mu_acl 59struct _mu_acl
@@ -64,52 +70,19 @@ _destroy_acl_entry (void *item)
64 /* FIXME: free arg? */ 70 /* FIXME: free arg? */
65} 71}
66 72
67static size_t
68mu_acl_entry_size (int salen)
69{
70 return sizeof (struct _mu_acl_entry) + salen - sizeof (struct sockaddr);
71}
72
73static int
74prepare_sa (struct sockaddr *sa)
75{
76 switch (sa->sa_family)
77 {
78 case AF_INET:
79 {
80 struct sockaddr_in *s_in = (struct sockaddr_in *)sa;
81 s_in->sin_addr.s_addr = ntohl (s_in->sin_addr.s_addr);
82 break;
83 }
84
85 case AF_UNIX:
86 break;
87
88 default:
89 return 1;
90 }
91 return 0;
92}
93
94int 73int
95mu_acl_entry_create (struct _mu_acl_entry **pent, 74mu_acl_entry_create (struct _mu_acl_entry **pent,
96 mu_acl_action_t action, void *data, 75 mu_acl_action_t action, void *data,
97 struct sockaddr *sa, int salen, unsigned long netmask) 76 struct mu_cidr *cidr)
98{ 77{
99 struct _mu_acl_entry *p = malloc (mu_acl_entry_size (salen)); 78 struct _mu_acl_entry *p = malloc (sizeof (*p));
100 if (!p) 79 if (!p)
101 return EINVAL; 80 return EINVAL;
102 81
103 p->action = action; 82 p->action = action;
104 p->arg = data; 83 p->arg = data;
105 p->netmask = ntohl (netmask); 84 memcpy (&p->cidr, cidr, sizeof (p->cidr));
106 p->salen = salen; 85
107 memcpy (p->sa, sa, salen);
108 if (prepare_sa (p->sa))
109 {
110 free (p);
111 return EINVAL;
112 }
113 *pent = p; 86 *pent = p;
114 return 0; 87 return 0;
115} 88}
@@ -165,15 +138,14 @@ mu_acl_get_iterator (mu_acl_t acl, mu_iterator_t *pitr)
165 138
166int 139int
167mu_acl_append (mu_acl_t acl, mu_acl_action_t act, 140mu_acl_append (mu_acl_t acl, mu_acl_action_t act,
168 void *data, struct sockaddr *sa, int salen, 141 void *data, struct mu_cidr *cidr)
169 unsigned long netmask)
170{ 142{
171 int rc; 143 int rc;
172 struct _mu_acl_entry *ent; 144 struct _mu_acl_entry *ent;
173 145
174 if (!acl) 146 if (!acl)
175 return EINVAL; 147 return EINVAL;
176 rc = mu_acl_entry_create (&ent, act, data, sa, salen, netmask); 148 rc = mu_acl_entry_create (&ent, act, data, cidr);
177 if (rc) 149 if (rc)
178 { 150 {
179 mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, 151 mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR,
@@ -193,14 +165,14 @@ mu_acl_append (mu_acl_t acl, mu_acl_action_t act,
193 165
194int 166int
195mu_acl_prepend (mu_acl_t acl, mu_acl_action_t act, void *data, 167mu_acl_prepend (mu_acl_t acl, mu_acl_action_t act, void *data,
196 struct sockaddr *sa, int salen, unsigned long netmask) 168 struct mu_cidr *cidr)
197{ 169{
198 int rc; 170 int rc;
199 struct _mu_acl_entry *ent; 171 struct _mu_acl_entry *ent;
200 172
201 if (!acl) 173 if (!acl)
202 return EINVAL; 174 return EINVAL;
203 rc = mu_acl_entry_create (&ent, act, data, sa, salen, netmask); 175 rc = mu_acl_entry_create (&ent, act, data, cidr);
204 if (rc) 176 if (rc)
205 { 177 {
206 mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, 178 mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR,
@@ -219,8 +191,7 @@ mu_acl_prepend (mu_acl_t acl, mu_acl_action_t act, void *data,
219 191
220int 192int
221mu_acl_insert (mu_acl_t acl, size_t pos, int before, 193mu_acl_insert (mu_acl_t acl, size_t pos, int before,
222 mu_acl_action_t act, void *data, 194 mu_acl_action_t act, void *data, struct mu_cidr *cidr)
223 struct sockaddr *sa, int salen, unsigned long netmask)
224{ 195{
225 int rc; 196 int rc;
226 void *ptr; 197 void *ptr;
@@ -236,7 +207,7 @@ mu_acl_insert (mu_acl_t acl, size_t pos, int before,
236 ("No such entry %lu", (unsigned long) pos)); 207 ("No such entry %lu", (unsigned long) pos));
237 return rc; 208 return rc;
238 } 209 }
239 rc = mu_acl_entry_create (&ent, act, data, sa, salen, netmask); 210 rc = mu_acl_entry_create (&ent, act, data, cidr);
240 if (!ent) 211 if (!ent)
241 { 212 {
242 mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, 213 mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR,
@@ -279,124 +250,19 @@ mu_acl_string_to_action (const char *str, mu_acl_action_t *pres)
279 return rc; 250 return rc;
280} 251}
281 252
282#define MU_S_UN_NAME(sa, salen) \ 253struct run_closure
283 ((salen < mu_offsetof (struct sockaddr_un,sun_path)) ? "" : (sa)->sun_path)
284
285static void
286debug_sockaddr (struct sockaddr *sa, int salen)
287{
288 switch (sa->sa_family)
289 {
290 case AF_INET:
291 {
292 struct sockaddr_in s_in = *(struct sockaddr_in *)sa;
293 s_in.sin_addr.s_addr = htonl (s_in.sin_addr.s_addr);
294 mu_debug_log_cont ("{AF_INET %s:%d}",
295 inet_ntoa (s_in.sin_addr), ntohs (s_in.sin_port));
296 break;
297 }
298
299 case AF_UNIX:
300 {
301 struct sockaddr_un *s_un = (struct sockaddr_un *)sa;
302 if (MU_S_UN_NAME(s_un, salen)[0] == 0)
303 mu_debug_log_cont ("{AF_UNIX}");
304 else
305 mu_debug_log_cont ("{AF_UNIX %s}", s_un->sun_path);
306 break;
307 }
308
309 default:
310 mu_debug_log_cont ("{Unsupported family: %d}", sa->sa_family);
311 }
312}
313
314size_t
315mu_stpcpy (char **pbuf, size_t *psize, const char *src)
316{
317 size_t slen = strlen (src);
318 if (pbuf == NULL || *pbuf == NULL)
319 return slen;
320 else
321 {
322 char *buf = *pbuf;
323 size_t size = *psize;
324 if (size > slen)
325 size = slen;
326 memcpy (buf, src, size);
327 *psize -= size;
328 *pbuf += size;
329 if (*psize)
330 **pbuf = 0;
331 else
332 (*pbuf)[-1] = 0;
333 return size;
334 }
335}
336
337void
338mu_sockaddr_to_str (const struct sockaddr *sa, int salen,
339 char *bufptr, size_t buflen,
340 size_t *plen)
341{ 254{
342 char *nbuf; 255 unsigned idx;
343 size_t len = 0; 256 struct mu_cidr addr;