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