]> andersk Git - moira.git/blob - gen/genacl.pc
break out of case statement, don't fall through.
[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->name == NULL)
51         {
52           fprintf(stderr, "Found string_id with no associated string.  Exiting.\n");
53           exit(MR_DBMS_ERR);
54         }
55       if (m->type != 'S')
56         {
57           canon_krb(m, vers, kbuf, sizeof(kbuf));
58           fprintf(out, "%s\n", kbuf);
59         }
60       freeimember(m);
61     }
62   sq_destroy(sq);
63 }
64
65 void canon_krb(struct imember *m, int vers, char *buf, int len)
66 {
67   char *at;
68
69   switch (m->type)
70     {
71     case 'U':
72       snprintf(buf, len, "%s@%s", m->name, defaultrealm);
73       break;
74
75     case 'K':
76       at = strchr(m->name, '@');
77       if (!at)
78         at = strchr(m->name, '\0');
79       if (vers == 5)
80         {
81           char *dot = strchr(m->name, '.');
82           if (dot && dot < at)
83             snprintf(buf, len, "%.*s/%s", dot - m->name, m->name, dot + 1);
84           else
85             snprintf(buf, len, "%s", m->name);
86         }
87       else
88         {
89           char *slash = strchr(m->name, '/');
90           if (slash && slash < at)
91             snprintf(buf, len, "%.*s.%s", slash - m->name, m->name, slash + 1);
92           else
93             snprintf(buf, len, "%s", m->name);
94         }
95       if (!*at)
96         {
97           int plen = strlen(buf);
98           snprintf(buf + plen, len - plen, "@%s", defaultrealm);
99         }
100       break;
101     }
102 }
103
104 void dump_user_list(FILE *out, char *type, int id)
105 {
106   struct save_queue *sq;
107   struct imember *m;
108
109   sq = get_acl(type, id, NULL);
110   while (sq_remove_data(sq, &m))
111     {
112       if (m->type == 'U' || (m->type == 'S' && !strchr(m->name, '@')))
113         fprintf(out, "%s\n", m->name);
114       freeimember(m);
115     }
116   sq_destroy(sq);
117 }
118
119 struct save_queue *get_acl(char *type, int id,
120                            char *(merge_func)(char *, char *))
121 {
122   struct save_queue *sq;
123
124   sq = sq_create();
125   save_imember(sq, type, id, NULL);
126   return merge_imembers(sq, merge_func);
127 }
128
129 static void save_imember(struct save_queue *sq, char *type, int id, char *tag)
130 {
131   EXEC SQL BEGIN DECLARE SECTION;
132   int lid = id, mid, mid2, tagid, status;
133   char mtype[IMEMBERS_MEMBER_TYPE_SIZE];
134   EXEC SQL END DECLARE SECTION;
135   char *mtag;
136
137   switch (*type)
138     {
139     case 'U':
140       EXEC SQL SELECT status INTO :status FROM users WHERE users_id = :id;
141       if (status != 3)
142         sq_save_data(sq, imember('U', user_lookup(id), tag));
143       break;
144
145     case 'K':
146     case 'S':
147       sq_save_data(sq, imember(*type, string_lookup(id), tag));
148       break;
149
150     case 'L':
151       EXEC SQL DECLARE csr_acl_mem CURSOR FOR
152         SELECT member_type, member_id, tag FROM imembers
153         WHERE list_id = :lid AND direct = 1;
154       EXEC SQL OPEN csr_acl_mem;
155       while (1)
156         {
157           EXEC SQL FETCH csr_acl_mem INTO :mtype, :mid, :tagid;
158           if (sqlca.sqlcode)
159             break;
160
161           if (tag)
162             mtag = tag;
163           else
164             mtag = string_lookup(tagid);
165           if (mtype[0] == 'L')
166             {
167               EXEC SQL DECLARE csr_list CURSOR FOR
168                 SELECT member_type, member_id FROM imembers
169                 WHERE list_id = :mid AND member_type != 'LIST';
170               EXEC SQL OPEN csr_list;
171               while (1)
172                 {
173                   EXEC SQL FETCH csr_list INTO :mtype, :mid;
174                   if (sqlca.sqlcode)
175                     break;
176
177                   save_imember(sq, mtype, mid, mtag);
178                 }
179               EXEC SQL CLOSE csr_list;
180             }
181           else
182             save_imember(sq, mtype, mid, mtag);
183         }
184     }
185 }
186
187 static struct save_queue *merge_imembers(struct save_queue *sq,
188                                          char *(merge_func)(char *, char *))
189 {
190   int n;
191   struct imember *m1, *m2;
192   struct save_queue *out;
193   char *t1;
194
195   out = sq_create();
196   while (sq_remove_data(sq, &m1))
197     {
198       while (sq_get_data(sq, &m2))
199         {
200           if (m1->type == m2->type && !strcmp(m1->name, m2->name))
201             {
202               sq_remove_last_data(sq);
203               if (merge_func)
204                 {
205                   t1 = m1->tag;
206                   m1->tag = merge_func(m1->tag, m2->tag);
207                   free(t1);
208                 }
209               freeimember(m2);
210             }
211         }
212       sq_save_data(out, m1);
213     }
214   sq_destroy(sq);
215   return out;
216 }  
217
218 static struct imember *imember(char type, char *name, char *tag)
219 {
220   struct imember *m;
221   m = malloc(sizeof(struct imember));
222   m->type = type;
223   m->name = name;
224   m->tag = strdup(tag ? tag : "");
225   return m;
226 }
227
228 void freeimember(struct imember *m)
229 {
230   free(m->tag);
231   free(m);
232 }
233
234 char *user_lookup(int users_id)
235 {
236   char *u;
237
238   u = hash_lookup(users, users_id);
239   if (u)
240     return u;
241   else
242     {
243       EXEC SQL BEGIN DECLARE SECTION;
244       char login[USERS_LOGIN_SIZE];
245       EXEC SQL END DECLARE SECTION;
246
247       EXEC SQL SELECT login INTO :login FROM users
248         WHERE users_id = :users_id;
249       if (sqlca.sqlcode)
250         return NULL;
251
252       u = strdup(strtrim(login));
253       hash_store(users, users_id, u);
254       return u;
255     }
256 }
257
258 char *string_lookup(int string_id)
259 {
260   char *s;
261
262   s = hash_lookup(strings, string_id);
263   if (s)
264     return s;
265   else
266     {
267       EXEC SQL BEGIN DECLARE SECTION;
268       char string[STRINGS_STRING_SIZE];
269       EXEC SQL END DECLARE SECTION;
270
271       EXEC SQL SELECT string INTO :string FROM strings
272         WHERE string_id = :string_id;
273       if (sqlca.sqlcode)
274         return NULL;
275
276       s = strdup(strtrim(string));
277       hash_store(strings, string_id, s);
278       return s;
279     }
280 }
This page took 0.129801 seconds and 5 git commands to generate.