]> andersk Git - moira.git/blame - gen/acl.pc
fix two bugs noticed by kretch
[moira.git] / gen / acl.pc
CommitLineData
883e2e2b 1/* $Id$
2 *
3 * This generates acl files for various servers.
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 <sys/stat.h>
16#include <sys/types.h>
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22#include <krb.h>
23
24EXEC SQL INCLUDE sqlca;
25
26RCSID("$Header$");
27
28char *whoami = "acl.gen";
29char *db = "moira/moira";
30char defaultrealm[REALM_SZ];
31
32void dump_access_file(FILE *out, int lid);
33char *merge_access_bits(char *t1, char *t2);
34void dump_discuss_acl(FILE *out, int lid);
35void dump_passwd_file(FILE *out, int lid);
36void dump_group_file(FILE *out, int id);
37char *merge_discuss_acls(char *one, char *two);
38void sqlerr(void);
39
40int main(int argc, char **argv)
41{
42 EXEC SQL BEGIN DECLARE SECTION;
43 int mid, lid;
44 char target[ACL_TARGET_SIZE], kind[ACL_KIND_SIZE];
45 char host[MACHINE_NAME_SIZE];
46 EXEC SQL END DECLARE SECTION;
47 char filename[MAXPATHLEN];
48 TARFILE *tf;
49 FILE *out;
50 struct save_queue *sq;
51 time_t now = time(NULL);
52
53 EXEC SQL WHENEVER SQLERROR DO sqlerr();
54 EXEC SQL CONNECT :db;
55 init_acls();
56
57 EXEC SQL DECLARE csr_mach CURSOR FOR
58 SELECT UNIQUE mach_id FROM acl;
59 EXEC SQL OPEN csr_mach;
60 while (1)
61 {
62 EXEC SQL FETCH csr_mach INTO :mid;
63 if (sqlca.sqlcode)
64 break;
65
66 EXEC SQL SELECT name INTO :host FROM machine
67 WHERE mach_id = :mid;
68 if (sqlca.sqlcode)
69 continue;
70 strtrim(host);
71
72 sprintf(filename, "%s/acl/%s", DCM_DIR, host);
73 tf = tarfile_open(filename);
74
75 EXEC SQL DECLARE csr_acl CURSOR FOR
76 SELECT target, kind, list_id
77 FROM acl
78 WHERE mach_id = :mid;
79 EXEC SQL OPEN csr_acl;
80 while (1)
81 {
82 EXEC SQL FETCH csr_acl INTO :target, :kind, :lid;
83 if (sqlca.sqlcode)
84 break;
85
86 strtrim(target);
87 strtrim(kind);
88
89 out = tarfile_start(tf, target, 0644, 0, 0, "root", "root", now);
90
91 if (!strcasecmp(kind, "kerberos4"))
92 dump_krb_acl(out, "LIST", lid, 4);
93 else if (!strcasecmp(kind, "kerberos5"))
94 dump_krb_acl(out, "LIST", lid, 5);
95 else if (!strcasecmp(kind, "access"))
96 dump_access_file(out, lid);
97 else if (!strcasecmp(kind, "discuss"))
98 dump_discuss_acl(out, lid);
99 else if (!strcasecmp(kind, "passwd"))
100 dump_passwd_file(out, lid);
101 else if (!strcasecmp(kind, "group"))
102 dump_group_file(out, lid);
103
104 tarfile_end(tf);
105 }
106
107 tarfile_close(tf);
108 }
109
110 EXEC SQL COMMIT RELEASE;
111
112 exit(MR_SUCCESS);
113}
114
115void dump_access_file(FILE *out, int lid)
116{
117 struct save_queue *sq = get_acl("LIST", lid, merge_access_bits);
118 struct imember *m;
119
120 while (sq_remove_data(sq, &m))
121 {
122 if (m->type == 'U' ||
123 (m->type == 'S' && m->name[0] == '*'))
124 {
125 if (*(m->tag))
126 fprintf(out, "%-10s %s\n", m->name, m->tag);
127 else
128 fprintf(out, "%-10s rl\n", m->name);
129 }
130 freeimember(m);
131 }
132 sq_destroy(sq);
133}
134
135char *merge_access_bits(char *t1, char *t2)
136{
137 char *m = NULL, *ans;
138 int r = 1, l = 1;
139
140 /* Clear bits that aren't granted by both tags. */
141 if ((*t1 && t1[0] != 'r' && t1[1] != 'r') ||
142 (*t2 && t2[0] != 'r' && t2[1] != 'r'))
143 r = 0;
144 if ((*t1 && t1[0] != 'l' && t1[1] != 'l') ||
145 (*t2 && t2[0] != 'l' && t2[1] != 'l'))
146 l = 0;
147
148 if (!r || !l)
149 {
150 /* Skip to message part of tag 1 */
151 m = t1;
152 while (*m && !isspace(*m))
153 m++;
154 while (isspace(*m))
155 m++;
156
157 /* If nothing there, skip to message part of tag 2 */
158 if (!*m)
159 {
160 m = t2;
161 while (*m && !isspace(*m))
162 m++;
163 while (isspace(*m))
164 m++;
165 }
166
167 ans = malloc(4 + strlen(m));
168 sprintf(ans, "%c %s", r ? 'r' : l ? 'l' : '-', m);
169 }
170 else
171 {
172 ans = malloc(3);
173 strcpy(ans, "rl");
174 }
175 return ans;
176}
177
178void dump_discuss_acl(FILE *out, int lid)
179{
180 struct save_queue *sq = get_acl("LIST", lid, merge_discuss_acls);
181 struct imember *m;
182 char name[STRINGS_STRING_SIZE], *bits;
183 int num;
184
185 num = 0;
186 while (sq_get_data(sq, &m))
187 num++;
188
189 fprintf(out, "%d\n", num);
190 while (sq_remove_data(sq, &m))
191 {
192 if (m->type != 'S')
193 {
194 canon_krb(m, 4, name, sizeof(name));
195 bits = merge_discuss_acls(m->tag, "");
196 fprintf(out, "%s %s\n", bits, name);
197 free(bits);
198 }
199 freeimember(m);
200 }
201 sq_destroy(sq);
202}
203
204char *merge_discuss_acls(char *one, char *two)
205{
206 char bits[8];
207
208 sprintf(bits, "%c%c%c%c%c%c%c",
209 strchr(one, 'a') || strchr(two, 'a') ? 'a' : ' ',
210 strchr(one, 'c') || strchr(two, 'c') ? 'c' : ' ',
211 strchr(one, 'd') || strchr(two, 'd') ? 'd' : ' ',
212 strchr(one, 'o') || strchr(two, 'o') ? 'o' : ' ',
213 strchr(one, 'r') || strchr(two, 'r') ? 'r' : ' ',
214 strchr(one, 's') || strchr(two, 's') ? 's' : ' ',
215 strchr(one, 'w') || strchr(two, 'w') ? 'w' : ' ');
216 return strdup(bits);
217}
218
219void dump_passwd_file(FILE *out, int lid)
220{
221 struct save_queue *sq = get_acl("LIST", lid, NULL);
222 struct imember *m;
223 EXEC SQL BEGIN DECLARE SECTION;
224 char shell[USERS_SHELL_SIZE], fullname[USERS_FULLNAME_SIZE];
225 char nickname[USERS_NICKNAME_SIZE], oa[USERS_OFFICE_ADDR_SIZE];
226 char op[USERS_OFFICE_PHONE_SIZE], hp[USERS_HOME_PHONE_SIZE];
227 int uid;
228 char *name;
229 EXEC SQL END DECLARE SECTION;
230
231 while (sq_remove_data(sq, &m))
232 {
233 switch (m->type)
234 {
235 case 'U':
236 name = m->name;
237
238 EXEC SQL SELECT unix_uid, shell, fullname, nickname,
239 office_addr, office_phone, home_phone
240 INTO :uid, :shell, :fullname, :nickname, :oa, :op, :hp
241 FROM users
242 WHERE login = :name AND status != 3;
243 if (sqlca.sqlcode)
244 continue;
245
246 strtrim(shell);
247 strtrim(fullname);
248 strtrim(nickname);
249 strtrim(op);
250 strtrim(oa);
251 strtrim(hp);
252
253 fprintf(out, "%s:*:%d:101:%s,%s,%s,%s,%s:/mit/%s:%s\n",
254 name, uid, fullname, nickname, oa, op, hp, name, shell);
255 break;
256 }
257 freeimember(m);
258 }
259 sq_destroy(sq);
260}
261
262/* This one is a bit weird since we actually look at top-level
263 * lists rather then flattening them.
264 */
265void dump_group_file(FILE *out, int id)
266{
267 EXEC SQL BEGIN DECLARE SECTION;
268 int lid = id, mid, gid, grouplist;
269 char mtype[IMEMBERS_MEMBER_TYPE_SIZE], name[LIST_NAME_SIZE];
270 EXEC SQL END DECLARE SECTION;
271 struct save_queue *sq;
272 struct imember *m;
273 char *maybecomma, *s;
274
275 EXEC SQL DECLARE csr_grp CURSOR FOR
276 SELECT member_type, member_id FROM imembers
277 WHERE list_id = :lid AND direct = 1;
278 EXEC SQL OPEN csr_grp;
279 while (1)
280 {
281 EXEC SQL FETCH csr_grp INTO :mtype, :mid;
282 if (sqlca.sqlcode)
283 break;
284
285 switch (*mtype)
286 {
287 case 'L':
288 EXEC SQL SELECT name, gid, grouplist
289 INTO :name, :gid, :grouplist
290 FROM list
291 WHERE list_id = :mid;
292 if (sqlca.sqlcode || !grouplist)
293 break;
294
295 strtrim(name);
296
297 fprintf(out, "%s:*:%d:", name, gid);
298 sq = get_acl("LIST", mid, NULL);
299 maybecomma = "";
300 while (sq_remove_data(sq, &m))
301 {
302 if (m->type == 'U')
303 {
304 fprintf(out, "%s%s", maybecomma, m->name);
305 maybecomma = ",";
306 }
307 freeimember(m);
308 }
309 fprintf(out, "\n");
310 sq_destroy(sq);
311 break;
312 }
313 }
314 EXEC SQL CLOSE csr_grp;
315}
316
317void sqlerr(void)
318{
319 db_error(sqlca.sqlcode);
320 exit(MR_DBMS_ERR);
321}
This page took 0.23171 seconds and 5 git commands to generate.