]> andersk Git - moira.git/blame - gen/genacl.pc
Fix a pile of error messages.
[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>
85bc153c 20#include <krb5.h>
883e2e2b 21
22EXEC SQL INCLUDE sqlca;
23
24RCSID("$Header$");
25
26static char defaultrealm[REALM_SZ];
27
28static struct hash *users, *strings;
29
30static void save_imember(struct save_queue *sq, char *type, int id, char *tag);
31static struct imember *imember(char type, char *name, char *tag);
32static struct save_queue *merge_imembers(struct save_queue *sq,
33 char *(merge_func)(char *, char *));
34
35void init_acls(void)
36{
37 users = create_hash(2000);
38 strings = create_hash(2000);
39 krb_get_lrealm(defaultrealm, 1);
40}
41
42void dump_krb_acl(FILE *out, char *type, int id, int vers)
43{
44 struct save_queue *sq;
45 struct imember *m;
46 char kbuf[MAX_K_NAME_SZ];
47
48 sq = get_acl(type, id, NULL);
49 while (sq_remove_data(sq, &m))
50 {
1bc309fb 51 if (m->name == NULL)
52 {
53 fprintf(stderr, "Found string_id with no associated string. Exiting.\n");
54 exit(MR_DBMS_ERR);
55 }
56 if (m->type != 'S')
883e2e2b 57 {
58 canon_krb(m, vers, kbuf, sizeof(kbuf));
59 fprintf(out, "%s\n", kbuf);
60 }
61 freeimember(m);
62 }
63 sq_destroy(sq);
64}
65
66void canon_krb(struct imember *m, int vers, char *buf, int len)
67{
68 char *at;
85bc153c 69 char kbuf[MAX_K_NAME_SZ];
883e2e2b 70
71 switch (m->type)
72 {
73 case 'U':
74 snprintf(buf, len, "%s@%s", m->name, defaultrealm);
75 break;
76
77 case 'K':
85bc153c 78 /* We assume we have a krb4-style namespace. If we want a krb5 acl, we need to
79 * krb5_425_conv_principal() on it. For krb4, do nothing special.
80 */
883e2e2b 81 at = strchr(m->name, '@');
82 if (!at)
83 at = strchr(m->name, '\0');
85bc153c 84 snprintf(kbuf, len, "%s", m->name);
85
86 if (!*at)
883e2e2b 87 {
85bc153c 88 int plen = strlen(kbuf);
89 snprintf(kbuf + plen, len - plen, "@%s", defaultrealm);
883e2e2b 90 }
85bc153c 91
92 if (vers == 5)
883e2e2b 93 {
85bc153c 94 char name[ANAME_SZ] = "\0", inst[INST_SZ] = "\0", realm[REALM_SZ] = "\0";
95 char *kuser = NULL;
96 krb5_context context = NULL;
97 krb5_principal client = NULL;
98 int status = 0;
99
100 if (kname_parse(name, inst, realm, kbuf) != KSUCCESS)
101 goto out;
102
103 status = krb5_init_context(&context);
104 if (status)
105 goto out;
106
107 status = krb5_425_conv_principal(context, name, inst, realm, &client);
108 if (status)
109 goto out;
110
111 status = krb5_unparse_name(context, client, &kuser);
112 if (status)
113 goto out;
114
115 strncpy(buf, kuser, MAX_K_NAME_SZ);
116 buf[MAX_K_NAME_SZ - 1] = '\0';
117
118 out:
119 if (kuser)
120 krb5_free_unparsed_name(context, kuser);
121 if (client)
122 krb5_free_principal(context, client);
123 if (context)
124 krb5_free_context(context);
883e2e2b 125 }
85bc153c 126 else
883e2e2b 127 {
85bc153c 128 /* v4 output, and we should already have added a realm. */
129 snprintf(buf, len, "%s", kbuf);
883e2e2b 130 }
131 break;
132 }
133}
134
135void dump_user_list(FILE *out, char *type, int id)
136{
137 struct save_queue *sq;
138 struct imember *m;
139
140 sq = get_acl(type, id, NULL);
141 while (sq_remove_data(sq, &m))
142 {
143 if (m->type == 'U' || (m->type == 'S' && !strchr(m->name, '@')))
144 fprintf(out, "%s\n", m->name);
145 freeimember(m);
146 }
147 sq_destroy(sq);
148}
149
150struct save_queue *get_acl(char *type, int id,
151 char *(merge_func)(char *, char *))
152{
153 struct save_queue *sq;
154
155 sq = sq_create();
156 save_imember(sq, type, id, NULL);
157 return merge_imembers(sq, merge_func);
158}
159
160static void save_imember(struct save_queue *sq, char *type, int id, char *tag)
161{
162 EXEC SQL BEGIN DECLARE SECTION;
f5da21ba 163 int lid = id, mid, mid2, tagid, status;
883e2e2b 164 char mtype[IMEMBERS_MEMBER_TYPE_SIZE];
165 EXEC SQL END DECLARE SECTION;
166 char *mtag;
167
168 switch (*type)
169 {
170 case 'U':
f5da21ba 171 EXEC SQL SELECT status INTO :status FROM users WHERE users_id = :id;
172 if (status != 3)
173 sq_save_data(sq, imember('U', user_lookup(id), tag));
883e2e2b 174 break;
175
176 case 'K':
177 case 'S':
178 sq_save_data(sq, imember(*type, string_lookup(id), tag));
179 break;
180
181 case 'L':
182 EXEC SQL DECLARE csr_acl_mem CURSOR FOR
183 SELECT member_type, member_id, tag FROM imembers
184 WHERE list_id = :lid AND direct = 1;
185 EXEC SQL OPEN csr_acl_mem;
186 while (1)
187 {
188 EXEC SQL FETCH csr_acl_mem INTO :mtype, :mid, :tagid;
189 if (sqlca.sqlcode)
190 break;
191
192 if (tag)
193 mtag = tag;
194 else
195 mtag = string_lookup(tagid);
196 if (mtype[0] == 'L')
197 {
198 EXEC SQL DECLARE csr_list CURSOR FOR
199 SELECT member_type, member_id FROM imembers
200 WHERE list_id = :mid AND member_type != 'LIST';
201 EXEC SQL OPEN csr_list;
202 while (1)
203 {
204 EXEC SQL FETCH csr_list INTO :mtype, :mid;
205 if (sqlca.sqlcode)
206 break;
207
208 save_imember(sq, mtype, mid, mtag);
209 }
210 EXEC SQL CLOSE csr_list;
211 }
212 else
213 save_imember(sq, mtype, mid, mtag);
214 }
215 }
216}
217
218static struct save_queue *merge_imembers(struct save_queue *sq,
219 char *(merge_func)(char *, char *))
220{
221 int n;
222 struct imember *m1, *m2;
223 struct save_queue *out;
224 char *t1;
225
226 out = sq_create();
227 while (sq_remove_data(sq, &m1))
228 {
229 while (sq_get_data(sq, &m2))
230 {
231 if (m1->type == m2->type && !strcmp(m1->name, m2->name))
232 {
233 sq_remove_last_data(sq);
234 if (merge_func)
235 {
236 t1 = m1->tag;
237 m1->tag = merge_func(m1->tag, m2->tag);
238 free(t1);
239 }
240 freeimember(m2);
241 }
242 }
243 sq_save_data(out, m1);
244 }
245 sq_destroy(sq);
246 return out;
247}
248
249static struct imember *imember(char type, char *name, char *tag)
250{
251 struct imember *m;
252 m = malloc(sizeof(struct imember));
253 m->type = type;
254 m->name = name;
255 m->tag = strdup(tag ? tag : "");
256 return m;
257}
258
259void freeimember(struct imember *m)
260{
261 free(m->tag);
262 free(m);
263}
264
265char *user_lookup(int users_id)
266{
267 char *u;
268
269 u = hash_lookup(users, users_id);
270 if (u)
271 return u;
272 else
273 {
274 EXEC SQL BEGIN DECLARE SECTION;
275 char login[USERS_LOGIN_SIZE];
276 EXEC SQL END DECLARE SECTION;
277
278 EXEC SQL SELECT login INTO :login FROM users
279 WHERE users_id = :users_id;
280 if (sqlca.sqlcode)
281 return NULL;
282
283 u = strdup(strtrim(login));
284 hash_store(users, users_id, u);
285 return u;
286 }
287}
288
289char *string_lookup(int string_id)
290{
291 char *s;
292
293 s = hash_lookup(strings, string_id);
294 if (s)
295 return s;
296 else
297 {
298 EXEC SQL BEGIN DECLARE SECTION;
299 char string[STRINGS_STRING_SIZE];
300 EXEC SQL END DECLARE SECTION;
301
302 EXEC SQL SELECT string INTO :string FROM strings
303 WHERE string_id = :string_id;
304 if (sqlca.sqlcode)
305 return NULL;
306
307 s = strdup(strtrim(string));
308 hash_store(strings, string_id, s);
309 return s;
310 }
311}
This page took 0.27897 seconds and 5 git commands to generate.