]> andersk Git - moira.git/blame - gen/genacl.pc
Don't dump core if we have a string_id with no associated string.
[moira.git] / gen / genacl.pc
CommitLineData
883e2e2b 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
21EXEC SQL INCLUDE sqlca;
22
23RCSID("$Header$");
24
25static char defaultrealm[REALM_SZ];
26
27static struct hash *users, *strings;
28
29static void save_imember(struct save_queue *sq, char *type, int id, char *tag);
30static struct imember *imember(char type, char *name, char *tag);
31static struct save_queue *merge_imembers(struct save_queue *sq,
32 char *(merge_func)(char *, char *));
33
34void init_acls(void)
35{
36 users = create_hash(2000);
37 strings = create_hash(2000);
38 krb_get_lrealm(defaultrealm, 1);
39}
40
41void 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 {
99ab61e6 50 if (m->type != 'S' && m->name != NULL)
883e2e2b 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
60void 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
99void 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
114struct 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
124static 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
180static 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
211static 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
221void freeimember(struct imember *m)
222{
223 free(m->tag);
224 free(m);
225}
226
227char *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
251char *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.109319 seconds and 5 git commands to generate.