]> andersk Git - moira.git/blob - gen/genacl.pc
Generic acl support.
[moira.git] / gen / genacl.pc
1 /* $Id$
2  *
3  * Utility functions for outputting ACLs
4  *
5  * Copyright (C) 1999 by the Massachusetts Institute of Technology.
6  * For copying and distribution information, please see the file
7  * <mit-copyright.h>.
8  */
9
10 #include <mit-copyright.h>
11 #include <moira.h>
12 #include <moira_site.h>
13 #include "util.h"
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include <krb.h>
20
21 EXEC SQL INCLUDE sqlca;
22
23 RCSID("$Header$");
24
25 static char defaultrealm[REALM_SZ];
26
27 static struct hash *users, *strings;
28
29 static void save_imember(struct save_queue *sq, char *type, int id, char *tag);
30 static struct imember *imember(char type, char *name, char *tag);
31 static struct save_queue *merge_imembers(struct save_queue *sq,
32                                          char *(merge_func)(char *, char *));
33
34 void init_acls(void)
35 {
36   users = create_hash(2000);
37   strings = create_hash(2000);
38   krb_get_lrealm(defaultrealm, 1);
39 }
40
41 void dump_krb_acl(FILE *out, char *type, int id, int vers)
42 {
43   struct save_queue *sq;
44   struct imember *m;
45   char kbuf[MAX_K_NAME_SZ];
46
47   sq = get_acl(type, id, NULL);
48   while (sq_remove_data(sq, &m))
49     {
50       if (m->type != 'S')
51         {
52           canon_krb(m, vers, kbuf, sizeof(kbuf));
53           fprintf(out, "%s\n", kbuf);
54         }
55       freeimember(m);
56     }
57   sq_destroy(sq);
58 }
59
60 void canon_krb(struct imember *m, int vers, char *buf, int len)
61 {
62   char *at;
63
64   switch (m->type)
65     {
66     case 'U':
67       snprintf(buf, len, "%s@%s", m->name, defaultrealm);
68       break;
69
70     case 'K':
71       at = strchr(m->name, '@');
72       if (!at)
73         at = strchr(m->name, '\0');
74       if (vers == 5)
75         {
76           char *dot = strchr(m->name, '.');
77           if (dot && dot < at)
78             snprintf(buf, len, "%.*s/%s", dot - m->name, m->name, dot + 1);
79           else
80             snprintf(buf, len, "%s", m->name);
81         }
82       else
83         {
84           char *slash = strchr(m->name, '/');
85           if (slash && slash < at)
86             snprintf(buf, len, "%.*s.%s", slash - m->name, m->name, slash + 1);
87           else
88             snprintf(buf, len, "%s", m->name);
89         }
90       if (!*at)
91         {
92           int plen = strlen(buf);
93           snprintf(buf + plen, len - plen, "@%s", defaultrealm);
94         }
95       break;
96     }
97 }
98
99 void dump_user_list(FILE *out, char *type, int id)
100 {
101   struct save_queue *sq;
102   struct imember *m;
103
104   sq = get_acl(type, id, NULL);
105   while (sq_remove_data(sq, &m))
106     {
107       if (m->type == 'U' || (m->type == 'S' && !strchr(m->name, '@')))
108         fprintf(out, "%s\n", m->name);
109       freeimember(m);
110     }
111   sq_destroy(sq);
112 }
113
114 struct save_queue *get_acl(char *type, int id,
115                            char *(merge_func)(char *, char *))
116 {
117   struct save_queue *sq;
118
119   sq = sq_create();
120   save_imember(sq, type, id, NULL);
121   return merge_imembers(sq, merge_func);
122 }
123
124 static void save_imember(struct save_queue *sq, char *type, int id, char *tag)
125 {
126   EXEC SQL BEGIN DECLARE SECTION;
127   int lid = id, mid, mid2, tagid;
128   char mtype[IMEMBERS_MEMBER_TYPE_SIZE];
129   EXEC SQL END DECLARE SECTION;
130   char *mtag;
131
132   switch (*type)
133     {
134     case 'U':
135       sq_save_data(sq, imember('U', user_lookup(id), tag));
136       break;
137
138     case 'K':
139     case 'S':
140       sq_save_data(sq, imember(*type, string_lookup(id), tag));
141       break;
142
143     case 'L':
144       EXEC SQL DECLARE csr_acl_mem CURSOR FOR
145         SELECT member_type, member_id, tag FROM imembers
146         WHERE list_id = :lid AND direct = 1;
147       EXEC SQL OPEN csr_acl_mem;
148       while (1)
149         {
150           EXEC SQL FETCH csr_acl_mem INTO :mtype, :mid, :tagid;
151           if (sqlca.sqlcode)
152             break;
153
154           if (tag)
155             mtag = tag;
156           else
157             mtag = string_lookup(tagid);
158           if (mtype[0] == 'L')
159             {
160               EXEC SQL DECLARE csr_list CURSOR FOR
161                 SELECT member_type, member_id FROM imembers
162                 WHERE list_id = :mid AND member_type != 'LIST';
163               EXEC SQL OPEN csr_list;
164               while (1)
165                 {
166                   EXEC SQL FETCH csr_list INTO :mtype, :mid;
167                   if (sqlca.sqlcode)
168                     break;
169
170                   save_imember(sq, mtype, mid, mtag);
171                 }
172               EXEC SQL CLOSE csr_list;
173             }
174           else
175             save_imember(sq, mtype, mid, mtag);
176         }
177     }
178 }
179
180 static struct save_queue *merge_imembers(struct save_queue *sq,
181                                          char *(merge_func)(char *, char *))
182 {
183   int n;
184   struct imember *m1, *m2;
185   struct save_queue *out;
186   char *t1;
187
188   out = sq_create();
189   while (sq_remove_data(sq, &m1))
190     {
191       while (sq_get_data(sq, &m2))
192         {
193           if (m1->type == m2->type && !strcmp(m1->name, m2->name))
194             {
195               sq_remove_last_data(sq);
196               if (merge_func)
197                 {
198                   t1 = m1->tag;
199                   m1->tag = merge_func(m1->tag, m2->tag);
200                   free(t1);
201                 }
202               freeimember(m2);
203             }
204         }
205       sq_save_data(out, m1);
206     }
207   sq_destroy(sq);
208   return out;
209 }  
210
211 static struct imember *imember(char type, char *name, char *tag)
212 {
213   struct imember *m;
214   m = malloc(sizeof(struct imember));
215   m->type = type;
216   m->name = name;
217   m->tag = strdup(tag ? tag : "");
218   return m;
219 }
220
221 void freeimember(struct imember *m)
222 {
223   free(m->tag);
224   free(m);
225 }
226
227 char *user_lookup(int users_id)
228 {
229   char *u;
230
231   u = hash_lookup(users, users_id);
232   if (u)
233     return u;
234   else
235     {
236       EXEC SQL BEGIN DECLARE SECTION;
237       char login[USERS_LOGIN_SIZE];
238       EXEC SQL END DECLARE SECTION;
239
240       EXEC SQL SELECT login INTO :login FROM users
241         WHERE users_id = :users_id;
242       if (sqlca.sqlcode)
243         return NULL;
244
245       u = strdup(strtrim(login));
246       hash_store(users, users_id, u);
247       return u;
248     }
249 }
250
251 char *string_lookup(int string_id)
252 {
253   char *s;
254
255   s = hash_lookup(strings, string_id);
256   if (s)
257     return s;
258   else
259     {
260       EXEC SQL BEGIN DECLARE SECTION;
261       char string[STRINGS_STRING_SIZE];
262       EXEC SQL END DECLARE SECTION;
263
264       EXEC SQL SELECT string INTO :string FROM strings
265         WHERE string_id = :string_id;
266       if (sqlca.sqlcode)
267         return NULL;
268
269       s = strdup(strtrim(string));
270       hash_store(strings, string_id, s);
271       return s;
272     }
273 }
This page took 0.125219 seconds and 5 git commands to generate.