]>
Commit | Line | Data |
---|---|---|
01c57ca1 | 1 | /* $Header$ |
2 | * | |
3 | * | |
4 | * (c) Copyright 1989 by the Massachusetts Institute of Technology. | |
5 | * For copying and distribution information, please see the file | |
6 | * <mit-copyright.h>. | |
7 | */ | |
8 | ||
9 | #include <mit-copyright.h> | |
10 | #include <stdio.h> | |
11 | #include <sys/file.h> | |
c7e4633e | 12 | #include <string.h> |
01c57ca1 | 13 | |
14 | #include <rx/xdr.h> | |
15 | #include "ptint.h" | |
16 | #include "ptserver.h" | |
17 | #include "pterror.h" | |
18 | ||
19 | #include <moira.h> | |
20 | #include <moira_site.h> | |
21 | #include <ctype.h> | |
22 | ||
f2546b02 | 23 | /* The following enables the processing of .root instances */ |
24 | #define DO_KERBEROS | |
25 | ||
01c57ca1 | 26 | EXEC SQL INCLUDE sqlca; |
27 | ||
f2546b02 | 28 | EXEC SQL BEGIN DECLARE SECTION; |
29 | char db[33] = "moira"; | |
30 | EXEC SQL END DECLARE SECTION; | |
31 | ||
c7e4633e | 32 | #ifndef min |
01c57ca1 | 33 | #define min(x,y) ((x) < (y) ? (x) : (y)) |
c7e4633e | 34 | #endif |
01c57ca1 | 35 | char *whoami = "sync"; |
36 | ||
01c57ca1 | 37 | int dbase_fd; |
38 | ||
39 | int ucount = 0; | |
40 | int gcount = 0; | |
f2546b02 | 41 | int kcount = 0; |
01c57ca1 | 42 | int mcount = 0; |
43 | ||
44 | struct hash *users; | |
45 | struct hash *groups; | |
f2546b02 | 46 | #ifdef DO_KERBEROS |
47 | struct hash *strings; | |
48 | #endif | |
01c57ca1 | 49 | |
50 | struct member { | |
51 | struct entry *user; | |
52 | struct entry *group; | |
53 | struct member *unext; | |
54 | struct member *gnext; | |
55 | }; | |
56 | struct entry { | |
57 | long id; | |
58 | struct member *members; | |
59 | }; | |
60 | ||
01c57ca1 | 61 | main(argc, argv) |
62 | int argc; | |
63 | char **argv; | |
64 | { | |
01c57ca1 | 65 | int status; |
66 | long t; | |
67 | ||
c7e4633e | 68 | setvbuf(stdout, NULL, _IOLBF, BUFSIZ); |
69 | ||
01c57ca1 | 70 | if (argc > 2 && !strcmp(argv[1], "-db")) { |
71 | strncpy(db, argv[2], sizeof(db)-1); | |
72 | argc -= 2; | |
73 | argv += 2; | |
74 | } | |
75 | if (argc != 2) { | |
76 | fprintf(stderr, "usage: %s [-db moira] outfile\n", whoami); | |
77 | exit(MR_ARGS); | |
78 | } | |
79 | ||
80 | dbase_fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0660); | |
81 | if (dbase_fd < 0) { | |
fe7208bc | 82 | perror("opening data file"); |
01c57ca1 | 83 | exit(1); |
84 | } | |
85 | ||
86 | initialize_sms_error_table(); | |
87 | initialize_pt_error_table(); | |
88 | Initdb(); /* Initialize prdb */ | |
89 | ||
90 | users = create_hash(10000); | |
91 | groups = create_hash(15000); | |
f2546b02 | 92 | #ifdef DO_KERBEROS |
93 | strings = create_hash(1000); | |
94 | #endif | |
01c57ca1 | 95 | |
c7e4633e | 96 | EXEC SQL WHENEVER SQLERROR DO sqlerr(); |
97 | EXEC SQL CONNECT :db IDENTIFIED BY :db; | |
01c57ca1 | 98 | |
99 | do_passwd(); | |
100 | do_groups(); | |
101 | ||
102 | t = time(0); | |
f2546b02 | 103 | fprintf(stderr, "Done (%d users, %d groups, %d kerberos, %d members): %s", |
104 | ucount, gcount, kcount, mcount, ctime(&t)); | |
01c57ca1 | 105 | |
c7e4633e | 106 | EXEC SQL COMMIT; |
01c57ca1 | 107 | |
108 | exit(MR_SUCCESS); | |
109 | } | |
110 | ||
111 | ||
112 | do_passwd() | |
113 | { | |
114 | EXEC SQL BEGIN DECLARE SECTION; | |
115 | char login[9], name[33]; | |
116 | int uid, id, status; | |
117 | EXEC SQL END DECLARE SECTION; | |
118 | ||
119 | long t; | |
120 | struct prentry tentry; | |
121 | struct entry *u; | |
122 | ||
123 | t = time(0); | |
124 | fprintf(stderr, "Doing users: %s", ctime(&t)); | |
125 | ||
01c57ca1 | 126 | EXEC SQL DECLARE u_cursor CURSOR FOR |
c7e4633e | 127 | SELECT u.login, u.unix_uid, u.users_id |
01c57ca1 | 128 | FROM users u |
c7e4633e | 129 | WHERE u.unix_uid > 0 AND (u.status = 1 OR u.status = 2) |
130 | ORDER BY unix_uid; | |
01c57ca1 | 131 | EXEC SQL OPEN u_cursor; |
132 | while (1) { | |
133 | EXEC SQL FETCH u_cursor INTO :login, :uid, :id; | |
134 | if (sqlca.sqlcode != 0) break; | |
135 | ||
136 | lowercase(strtrim(login)); | |
137 | ||
138 | if (FindByID(0,uid)) | |
139 | status = PRIDEXIST; | |
140 | else | |
141 | status = CreateEntry(0,login,&uid,1 /*idflag*/,0/*gflag*/, | |
142 | SYSADMINID /*oid*/, SYSADMINID/*cid*/); | |
143 | if (status) | |
144 | fprintf(stderr, "Error adding user %s uid %d: %s\n", | |
145 | login, uid, error_message(status)); | |
146 | else { | |
147 | u = (struct entry *)malloc(sizeof(struct entry)); | |
148 | u->id = uid; | |
149 | u->members = 0; | |
150 | hash_store(users, id, u); | |
151 | ucount++; | |
152 | } | |
153 | } | |
154 | EXEC SQL CLOSE u_cursor; | |
155 | return; | |
156 | } | |
157 | ||
158 | ||
159 | ||
160 | do_groups() | |
161 | { | |
162 | EXEC SQL BEGIN DECLARE SECTION; | |
f2546b02 | 163 | char name[33], string[129]; |
1db0775a | 164 | int gid, id, lid, hide, ustatus, root_flag; |
01c57ca1 | 165 | EXEC SQL END DECLARE SECTION; |
166 | ||
167 | long status, pos; | |
168 | struct prentry gentry, uentry; | |
169 | struct entry *u, *g; | |
170 | struct member *m; | |
171 | struct bucket **p, *b; | |
172 | char namebuf[40]; | |
173 | long aid, t; | |
174 | ||
175 | t = time(0); | |
176 | fprintf(stderr, "Doing groups: %s", ctime(&t)); | |
177 | ||
01c57ca1 | 178 | EXEC SQL DECLARE l_cursor CURSOR FOR |
179 | SELECT l.name, l.gid, l.list_id, l.hidden | |
180 | FROM list l | |
181 | WHERE l.gid > 0 AND l.active != 0 AND l.grouplist != 0 | |
182 | ORDER BY gid; | |
183 | EXEC SQL OPEN l_cursor; | |
184 | while (1) { | |
185 | EXEC SQL FETCH l_cursor INTO :name, :gid, :lid, :hide; | |
186 | if (sqlca.sqlcode != 0) break; | |
187 | ||
188 | lowercase(strtrim(name)); | |
189 | sprintf(namebuf, "system:%s", name); | |
190 | aid = -gid; | |
191 | ||
192 | if (FindByID(0, aid)) | |
193 | status = PRIDEXIST; | |
194 | else | |
195 | status = CreateEntry(0,namebuf,&aid,1 /*idflag*/,PRGRP/*gflag*/, | |
196 | SYSADMINID /*oid*/, SYSADMINID/*cid*/); | |
197 | if (status) | |
198 | fprintf(stderr, "Error adding group %s id %d: %s\n", | |
199 | namebuf, aid, error_message(status)); | |
200 | ||
201 | if ((status==0 || status==PRIDEXIST) && | |
202 | (aid!=ANYUSERID && aid!=AUTHUSERID)) { | |
203 | ||
204 | g = (struct entry *)malloc(sizeof(struct entry)); | |
205 | g->id = aid; | |
206 | g->members = 0; | |
207 | hash_store(groups, lid, g); | |
208 | gcount++; | |
209 | ||
210 | /* Set modes on hidden lists (S----) */ | |
211 | if (hide) { | |
212 | pos = FindByID(0, aid); | |
213 | status = pr_Read(0, 0, pos, &gentry, sizeof(gentry)); | |
214 | if (!status) { | |
215 | gentry.flags = htonl(PRGRP|PRACCESS|PRP_STATUS_ANY); | |
216 | status = pr_Write(0, 0, pos, &gentry, sizeof(gentry)); | |
217 | } | |
218 | if (status) | |
219 | fprintf(stderr, | |
220 | "Error setting flags on group %s: %s\n", | |
221 | namebuf, error_message(status)); | |
222 | } | |
223 | } | |
224 | } | |
225 | EXEC SQL CLOSE l_cursor; | |
226 | ||
227 | t = time(0); | |
f2546b02 | 228 | fprintf(stderr, "Reading/preparing members: %s", ctime(&t)); |
01c57ca1 | 229 | |
230 | EXEC SQL DECLARE m_cursor CURSOR FOR | |
f2546b02 | 231 | SELECT m.list_id, m.member_id, m.member_type |
01c57ca1 | 232 | FROM imembers m |
01c57ca1 | 233 | ORDER BY member_id; |
234 | EXEC SQL OPEN m_cursor; | |
235 | while (1) { | |
f2546b02 | 236 | EXEC SQL FETCH m_cursor INTO :lid, :id, :name; |
01c57ca1 | 237 | if (sqlca.sqlcode != 0) break; |
f2546b02 | 238 | |
239 | if (!(g = (struct entry *)hash_lookup(groups, lid))) | |
240 | continue; | |
241 | ||
242 | strtrim(name); | |
243 | if (!strcmp(name, "USER")) { | |
244 | if (u = (struct entry *)hash_lookup(users, id)) { | |
245 | m = (struct member *)malloc(sizeof(struct member)); | |
246 | m->user = u; | |
247 | m->group = g; | |
248 | m->unext = u->members; | |
249 | m->gnext = g->members; | |
250 | u->members = g->members = m; | |
251 | mcount++; | |
252 | } | |
253 | } | |
254 | #ifdef DO_KERBEROS | |
255 | else if (!strcmp(name, "KERBEROS")) { | |
256 | if (!(u = (struct entry *)hash_lookup(strings, id))) { | |
257 | char *p; | |
258 | ||
259 | EXEC SQL SELECT string INTO :string | |
260 | FROM strings WHERE string_id = :id; | |
261 | ||
262 | aid = 0; | |
1db0775a | 263 | root_flag = 0; |
2d849db8 | 264 | ustatus = NULL; |
f2546b02 | 265 | strtrim(string); |
266 | ||
1db0775a | 267 | if (p = strchr(string, '@')) |
268 | { | |
f2546b02 | 269 | *p = 0; |
1db0775a | 270 | if (strcmp(p+1, "ATHENA.MIT.EDU")) |
271 | aid = -1; | |
272 | } | |
273 | else aid = -1; | |
274 | ||
275 | p = strchr(string, '.'); | |
276 | if ((!p) && (strlen(string) < 9)) | |
277 | strcpy(name, string); | |
278 | else if ((p-string) < 9 && !strcmp(p+1, "root")) | |
279 | { | |
f2546b02 | 280 | strncpy(name, string, p-string); |
281 | name[p-string] = 0; | |
1db0775a | 282 | root_flag = 1; |
283 | } | |
284 | else | |
285 | aid = -1; | |
f2546b02 | 286 | |
287 | if (aid == 0) { | |
288 | EXEC SQL DECLARE k_cursor2 CURSOR FOR | |
c7e4633e | 289 | SELECT unix_uid, status |
f2546b02 | 290 | FROM users |
291 | WHERE login = :name | |
c7e4633e | 292 | ORDER BY unix_uid; |
f2546b02 | 293 | EXEC SQL OPEN k_cursor2; |
1db0775a | 294 | while (1) |
295 | { | |
296 | if (sqlca.sqlcode) | |
297 | break; | |
298 | EXEC SQL FETCH k_cursor2 INTO :lid, :ustatus; | |
299 | if (ustatus==1 || ustatus==2) | |
300 | { | |
301 | if (root_flag == 1) | |
302 | aid = lid+65536; | |
303 | else | |
304 | aid = lid; | |
305 | } | |
f2546b02 | 306 | } |
307 | EXEC SQL CLOSE k_cursor2; | |
308 | } | |
309 | ||
310 | if (aid > 0) { | |
311 | if (FindByID(0,aid)) | |
312 | status = PRIDEXIST; | |
313 | else | |
314 | status = CreateEntry(0, string, &aid, 1 /*idflag*/, | |
315 | 0 /*gflag*/, SYSADMINID /*oid*/, | |
316 | SYSADMINID /*cid */); | |
317 | if (status) { | |
318 | fprintf(stderr, "Error adding %s (id %d): %s\n", | |
319 | string, aid, error_message(status)); | |
320 | if (status != PRIDEXIST) aid = 0; | |
321 | } | |
322 | } else | |
323 | aid = 0; | |
324 | ||
325 | u = (struct entry *)malloc(sizeof(struct entry)); | |
326 | u->id = aid; | |
327 | u->members = 0; | |
328 | hash_store(strings, id, u); | |
329 | if (aid) kcount++; | |
330 | } | |
331 | if (u->id == 0) continue; | |
332 | ||
01c57ca1 | 333 | m = (struct member *)malloc(sizeof(struct member)); |
334 | m->user = u; | |
335 | m->group = g; | |
336 | m->unext = u->members; | |
337 | m->gnext = g->members; | |
338 | u->members = g->members = m; | |
339 | mcount++; | |
340 | } | |
f2546b02 | 341 | #endif |
01c57ca1 | 342 | } |
343 | EXEC SQL CLOSE m_cursor; | |
344 | ||
f2546b02 | 345 | t = time(0); |
346 | fprintf(stderr, "Doing members: %s", ctime(&t)); | |
347 | ||
01c57ca1 | 348 | /* Do the bulk of the membership quickly. |
349 | * Add PRSIZE members into the user/group record. After that, we | |
350 | * require the use of continuation records, but we assume this is | |
351 | * few enough that we do this the slow way (AddToEntry). | |
352 | */ | |
353 | for (p = &(users->data[users->size - 1]); p >= users->data; p--) { | |
354 | for (b = *p; b; b = b->next) { | |
355 | if ((u = (struct entry *)b->data)->members == 0) | |
356 | continue; | |
357 | pos = FindByID(0, u->id); | |
358 | pr_Read(0, 0, pos, &uentry, sizeof(uentry)); | |
359 | for (t=0, m=u->members; m && t<PRSIZE; m=m->unext, t++) | |
360 | uentry.entries[t] = htonl(m->group->id); | |
361 | uentry.count = htonl(t); | |
362 | pr_Write(0, 0, pos, &uentry, sizeof(uentry)); | |
363 | if (m) { | |
364 | pr_ReadEntry(0, 0, pos, &uentry); | |
365 | while (m) { | |
366 | AddToEntry(0, &uentry, pos, m->group->id); | |
367 | m = m->unext; | |
368 | } | |
369 | } | |
370 | } | |
371 | } | |
f2546b02 | 372 | #ifdef DO_KERBEROS |
373 | for (p = &(strings->data[strings->size - 1]); p >= strings->data; p--) { | |
374 | for (b = *p; b; b = b->next) { | |
375 | if ((u = (struct entry *)b->data)->members == 0) | |
376 | continue; | |
377 | pos = FindByID(0, u->id); | |
378 | pr_Read(0, 0, pos, &uentry, sizeof(uentry)); | |
379 | for (t=0, m=u->members; m && t<PRSIZE; m=m->unext, t++) | |
380 | uentry.entries[t] = htonl(m->group->id); | |
381 | uentry.count = htonl(t); | |
382 | pr_Write(0, 0, pos, &uentry, sizeof(uentry)); | |
383 | if (m) { | |
384 | pr_ReadEntry(0, 0, pos, &uentry); | |
385 | while (m) { | |
386 | AddToEntry(0, &uentry, pos, m->group->id); | |
387 | m = m->unext; | |
388 | } | |
389 | } | |
390 | } | |
391 | } | |
392 | #endif | |
01c57ca1 | 393 | for (p = &(groups->data[groups->size - 1]); p >= groups->data; p--) { |
394 | for (b = *p; b; b = b->next) { | |
395 | if ((g = (struct entry *)b->data)->members == 0) | |
396 | continue; | |
397 | pos = FindByID(0, g->id); | |
398 | pr_Read(0, 0, pos, &gentry, sizeof(gentry)); | |
399 | for (t=0, m=g->members; m && t<PRSIZE; m=m->gnext, t++) | |
400 | gentry.entries[t] = htonl(m->user->id); | |
401 | gentry.count = htonl(t); | |
402 | pr_Write(0, 0, pos, &gentry, sizeof(gentry)); | |
403 | if (m) { | |
404 | pr_ReadEntry(0, 0, pos, &gentry); | |
405 | while (m) { | |
406 | AddToEntry(0, &gentry, pos, m->user->id); | |
407 | m = m->gnext; | |
408 | } | |
409 | } | |
410 | } | |
411 | } | |
412 | return; | |
413 | } | |
414 | ||
415 | ||
416 | sqlerr() | |
417 | { | |
c7e4633e | 418 | char buf[256]; |
419 | int size=256, len=0; | |
420 | ||
421 | sqlglm(buf, &size, &len); | |
422 | buf[len]='\0'; | |
423 | com_err(whoami, MR_DBMS_ERR, " code %d\n%s", sqlca.sqlcode, buf); | |
424 | exit(MR_DBMS_ERR); | |
01c57ca1 | 425 | } |