]>
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]; |
818ac4aa | 164 | int gid, id, lid, hide, ustatus; |
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; | |
263 | strtrim(string); | |
264 | ||
818ac4aa | 265 | if (p = (char *)index(string, '@')) { |
f2546b02 | 266 | *p = 0; |
818ac4aa | 267 | if (strcmp(p+1, "ATHENA.MIT.EDU")) aid = -1; |
268 | } else aid = -1; | |
269 | ||
270 | if ((p = (char *)index(string, '.')) && (p-string) < 9 && | |
271 | !strcmp(p+1, "root")) | |
272 | { | |
f2546b02 | 273 | strncpy(name, string, p-string); |
274 | name[p-string] = 0; | |
818ac4aa | 275 | } else aid = -1; |
f2546b02 | 276 | |
277 | if (aid == 0) { | |
278 | EXEC SQL DECLARE k_cursor2 CURSOR FOR | |
c7e4633e | 279 | SELECT unix_uid, status |
f2546b02 | 280 | FROM users |
281 | WHERE login = :name | |
c7e4633e | 282 | ORDER BY unix_uid; |
f2546b02 | 283 | EXEC SQL OPEN k_cursor2; |
818ac4aa | 284 | while (1) { |
285 | if (sqlca.sqlcode) break; | |
286 | EXEC SQL FETCH k_cursor2 INTO :lid, :ustatus; | |
287 | if (ustatus==1 || ustatus==2) aid = lid+65536; | |
f2546b02 | 288 | } |
289 | EXEC SQL CLOSE k_cursor2; | |
290 | } | |
291 | ||
292 | if (aid > 0) { | |
293 | if (FindByID(0,aid)) | |
294 | status = PRIDEXIST; | |
295 | else | |
296 | status = CreateEntry(0, string, &aid, 1 /*idflag*/, | |
297 | 0 /*gflag*/, SYSADMINID /*oid*/, | |
298 | SYSADMINID /*cid */); | |
299 | if (status) { | |
300 | fprintf(stderr, "Error adding %s (id %d): %s\n", | |
301 | string, aid, error_message(status)); | |
302 | if (status != PRIDEXIST) aid = 0; | |
303 | } | |
304 | } else | |
305 | aid = 0; | |
306 | ||
307 | u = (struct entry *)malloc(sizeof(struct entry)); | |
308 | u->id = aid; | |
309 | u->members = 0; | |
310 | hash_store(strings, id, u); | |
311 | if (aid) kcount++; | |
312 | } | |
313 | if (u->id == 0) continue; | |
314 | ||
01c57ca1 | 315 | m = (struct member *)malloc(sizeof(struct member)); |
316 | m->user = u; | |
317 | m->group = g; | |
318 | m->unext = u->members; | |
319 | m->gnext = g->members; | |
320 | u->members = g->members = m; | |
321 | mcount++; | |
322 | } | |
f2546b02 | 323 | #endif |
01c57ca1 | 324 | } |
325 | EXEC SQL CLOSE m_cursor; | |
326 | ||
f2546b02 | 327 | t = time(0); |
328 | fprintf(stderr, "Doing members: %s", ctime(&t)); | |
329 | ||
01c57ca1 | 330 | /* Do the bulk of the membership quickly. |
331 | * Add PRSIZE members into the user/group record. After that, we | |
332 | * require the use of continuation records, but we assume this is | |
333 | * few enough that we do this the slow way (AddToEntry). | |
334 | */ | |
335 | for (p = &(users->data[users->size - 1]); p >= users->data; p--) { | |
336 | for (b = *p; b; b = b->next) { | |
337 | if ((u = (struct entry *)b->data)->members == 0) | |
338 | continue; | |
339 | pos = FindByID(0, u->id); | |
340 | pr_Read(0, 0, pos, &uentry, sizeof(uentry)); | |
341 | for (t=0, m=u->members; m && t<PRSIZE; m=m->unext, t++) | |
342 | uentry.entries[t] = htonl(m->group->id); | |
343 | uentry.count = htonl(t); | |
344 | pr_Write(0, 0, pos, &uentry, sizeof(uentry)); | |
345 | if (m) { | |
346 | pr_ReadEntry(0, 0, pos, &uentry); | |
347 | while (m) { | |
348 | AddToEntry(0, &uentry, pos, m->group->id); | |
349 | m = m->unext; | |
350 | } | |
351 | } | |
352 | } | |
353 | } | |
f2546b02 | 354 | #ifdef DO_KERBEROS |
355 | for (p = &(strings->data[strings->size - 1]); p >= strings->data; p--) { | |
356 | for (b = *p; b; b = b->next) { | |
357 | if ((u = (struct entry *)b->data)->members == 0) | |
358 | continue; | |
359 | pos = FindByID(0, u->id); | |
360 | pr_Read(0, 0, pos, &uentry, sizeof(uentry)); | |
361 | for (t=0, m=u->members; m && t<PRSIZE; m=m->unext, t++) | |
362 | uentry.entries[t] = htonl(m->group->id); | |
363 | uentry.count = htonl(t); | |
364 | pr_Write(0, 0, pos, &uentry, sizeof(uentry)); | |
365 | if (m) { | |
366 | pr_ReadEntry(0, 0, pos, &uentry); | |
367 | while (m) { | |
368 | AddToEntry(0, &uentry, pos, m->group->id); | |
369 | m = m->unext; | |
370 | } | |
371 | } | |
372 | } | |
373 | } | |
374 | #endif | |
01c57ca1 | 375 | for (p = &(groups->data[groups->size - 1]); p >= groups->data; p--) { |
376 | for (b = *p; b; b = b->next) { | |
377 | if ((g = (struct entry *)b->data)->members == 0) | |
378 | continue; | |
379 | pos = FindByID(0, g->id); | |
380 | pr_Read(0, 0, pos, &gentry, sizeof(gentry)); | |
381 | for (t=0, m=g->members; m && t<PRSIZE; m=m->gnext, t++) | |
382 | gentry.entries[t] = htonl(m->user->id); | |
383 | gentry.count = htonl(t); | |
384 | pr_Write(0, 0, pos, &gentry, sizeof(gentry)); | |
385 | if (m) { | |
386 | pr_ReadEntry(0, 0, pos, &gentry); | |
387 | while (m) { | |
388 | AddToEntry(0, &gentry, pos, m->user->id); | |
389 | m = m->gnext; | |
390 | } | |
391 | } | |
392 | } | |
393 | } | |
394 | return; | |
395 | } | |
396 | ||
397 | ||
398 | sqlerr() | |
399 | { | |
c7e4633e | 400 | char buf[256]; |
401 | int size=256, len=0; | |
402 | ||
403 | sqlglm(buf, &size, &len); | |
404 | buf[len]='\0'; | |
405 | com_err(whoami, MR_DBMS_ERR, " code %d\n%s", sqlca.sqlcode, buf); | |
406 | exit(MR_DBMS_ERR); | |
01c57ca1 | 407 | } |