4 * (c) Copyright 1989 by the Massachusetts Institute of Technology.
5 * For copying and distribution information, please see the file
9 #include <mit-copyright.h>
20 #include <moira_site.h>
23 /* The following enables the processing of .root instances */
26 EXEC SQL INCLUDE sqlca;
28 EXEC SQL BEGIN DECLARE SECTION;
29 char db[33] = "moira";
30 EXEC SQL END DECLARE SECTION;
33 #define min(x,y) ((x) < (y) ? (x) : (y))
35 char *whoami = "sync";
58 struct member *members;
68 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
70 if (argc > 2 && !strcmp(argv[1], "-db")) {
71 strncpy(db, argv[2], sizeof(db)-1);
76 fprintf(stderr, "usage: %s [-db moira] outfile\n", whoami);
80 dbase_fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0660);
82 perror("opening data file");
86 initialize_sms_error_table();
87 initialize_pt_error_table();
88 Initdb(); /* Initialize prdb */
90 users = create_hash(10000);
91 groups = create_hash(15000);
93 strings = create_hash(1000);
96 EXEC SQL WHENEVER SQLERROR DO sqlerr();
97 EXEC SQL CONNECT :db IDENTIFIED BY :db;
103 fprintf(stderr, "Done (%d users, %d groups, %d kerberos, %d members): %s",
104 ucount, gcount, kcount, mcount, ctime(&t));
114 EXEC SQL BEGIN DECLARE SECTION;
115 char login[9], name[33];
117 EXEC SQL END DECLARE SECTION;
120 struct prentry tentry;
124 fprintf(stderr, "Doing users: %s", ctime(&t));
126 EXEC SQL DECLARE u_cursor CURSOR FOR
127 SELECT u.login, u.unix_uid, u.users_id
129 WHERE u.unix_uid > 0 AND (u.status = 1 OR u.status = 2)
131 EXEC SQL OPEN u_cursor;
133 EXEC SQL FETCH u_cursor INTO :login, :uid, :id;
134 if (sqlca.sqlcode != 0) break;
136 lowercase(strtrim(login));
141 status = CreateEntry(0,login,&uid,1 /*idflag*/,0/*gflag*/,
142 SYSADMINID /*oid*/, SYSADMINID/*cid*/);
144 fprintf(stderr, "Error adding user %s uid %d: %s\n",
145 login, uid, error_message(status));
147 u = (struct entry *)malloc(sizeof(struct entry));
150 hash_store(users, id, u);
154 EXEC SQL CLOSE u_cursor;
162 EXEC SQL BEGIN DECLARE SECTION;
163 char name[33], string[129];
164 int gid, id, lid, hide, ustatus, root_flag;
165 EXEC SQL END DECLARE SECTION;
168 struct prentry gentry, uentry;
171 struct bucket **p, *b;
176 fprintf(stderr, "Doing groups: %s", ctime(&t));
178 EXEC SQL DECLARE l_cursor CURSOR FOR
179 SELECT l.name, l.gid, l.list_id, l.hidden
181 WHERE l.gid > 0 AND l.active != 0 AND l.grouplist != 0
183 EXEC SQL OPEN l_cursor;
185 EXEC SQL FETCH l_cursor INTO :name, :gid, :lid, :hide;
186 if (sqlca.sqlcode != 0) break;
188 lowercase(strtrim(name));
189 sprintf(namebuf, "system:%s", name);
192 if (FindByID(0, aid))
195 status = CreateEntry(0,namebuf,&aid,1 /*idflag*/,PRGRP/*gflag*/,
196 SYSADMINID /*oid*/, SYSADMINID/*cid*/);
198 fprintf(stderr, "Error adding group %s id %d: %s\n",
199 namebuf, aid, error_message(status));
201 if ((status==0 || status==PRIDEXIST) &&
202 (aid!=ANYUSERID && aid!=AUTHUSERID)) {
204 g = (struct entry *)malloc(sizeof(struct entry));
207 hash_store(groups, lid, g);
210 /* Set modes on hidden lists (S----) */
212 pos = FindByID(0, aid);
213 status = pr_Read(0, 0, pos, &gentry, sizeof(gentry));
215 gentry.flags = htonl(PRGRP|PRACCESS|PRP_STATUS_ANY);
216 status = pr_Write(0, 0, pos, &gentry, sizeof(gentry));
220 "Error setting flags on group %s: %s\n",
221 namebuf, error_message(status));
225 EXEC SQL CLOSE l_cursor;
228 fprintf(stderr, "Reading/preparing members: %s", ctime(&t));
230 EXEC SQL DECLARE m_cursor CURSOR FOR
231 SELECT m.list_id, m.member_id, m.member_type
234 EXEC SQL OPEN m_cursor;
236 EXEC SQL FETCH m_cursor INTO :lid, :id, :name;
237 if (sqlca.sqlcode != 0) break;
239 if (!(g = (struct entry *)hash_lookup(groups, lid)))
243 if (!strcmp(name, "USER")) {
244 if (u = (struct entry *)hash_lookup(users, id)) {
245 m = (struct member *)malloc(sizeof(struct member));
248 m->unext = u->members;
249 m->gnext = g->members;
250 u->members = g->members = m;
255 else if (!strcmp(name, "KERBEROS")) {
256 if (!(u = (struct entry *)hash_lookup(strings, id))) {
259 EXEC SQL SELECT string INTO :string
260 FROM strings WHERE string_id = :id;
267 if (p = strchr(string, '@'))
270 if (strcmp(p+1, "ATHENA.MIT.EDU"))
275 p = strchr(string, '.');
276 if ((!p) && (strlen(string) < 9))
277 strcpy(name, string);
278 else if ((p-string) < 9 && !strcmp(p+1, "root"))
280 strncpy(name, string, p-string);
288 EXEC SQL DECLARE k_cursor2 CURSOR FOR
289 SELECT unix_uid, status
293 EXEC SQL OPEN k_cursor2;
298 EXEC SQL FETCH k_cursor2 INTO :lid, :ustatus;
299 if (ustatus==1 || ustatus==2)
307 EXEC SQL CLOSE k_cursor2;
314 status = CreateEntry(0, string, &aid, 1 /*idflag*/,
315 0 /*gflag*/, SYSADMINID /*oid*/,
316 SYSADMINID /*cid */);
318 fprintf(stderr, "Error adding %s (id %d): %s\n",
319 string, aid, error_message(status));
320 if (status != PRIDEXIST) aid = 0;
325 u = (struct entry *)malloc(sizeof(struct entry));
328 hash_store(strings, id, u);
331 if (u->id == 0) continue;
333 m = (struct member *)malloc(sizeof(struct member));
336 m->unext = u->members;
337 m->gnext = g->members;
338 u->members = g->members = m;
343 EXEC SQL CLOSE m_cursor;
346 fprintf(stderr, "Doing members: %s", ctime(&t));
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).
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)
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));
364 pr_ReadEntry(0, 0, pos, &uentry);
366 AddToEntry(0, &uentry, pos, m->group->id);
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)
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));
384 pr_ReadEntry(0, 0, pos, &uentry);
386 AddToEntry(0, &uentry, pos, m->group->id);
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)
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));
404 pr_ReadEntry(0, 0, pos, &gentry);
406 AddToEntry(0, &gentry, pos, m->user->id);
421 sqlglm(buf, &size, &len);
423 com_err(whoami, MR_DBMS_ERR, " code %d\n%s", sqlca.sqlcode, buf);