]> andersk Git - moira.git/blame - afssync/sync.pc
Handle null instance KERBEROS list members.
[moira.git] / afssync / sync.pc
CommitLineData
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 26EXEC SQL INCLUDE sqlca;
27
f2546b02 28EXEC SQL BEGIN DECLARE SECTION;
29char db[33] = "moira";
30EXEC SQL END DECLARE SECTION;
31
c7e4633e 32#ifndef min
01c57ca1 33#define min(x,y) ((x) < (y) ? (x) : (y))
c7e4633e 34#endif
01c57ca1 35char *whoami = "sync";
36
01c57ca1 37int dbase_fd;
38
39int ucount = 0;
40int gcount = 0;
f2546b02 41int kcount = 0;
01c57ca1 42int mcount = 0;
43
44struct hash *users;
45struct hash *groups;
f2546b02 46#ifdef DO_KERBEROS
47struct hash *strings;
48#endif
01c57ca1 49
50struct member {
51 struct entry *user;
52 struct entry *group;
53 struct member *unext;
54 struct member *gnext;
55};
56struct entry {
57 long id;
58 struct member *members;
59};
60
01c57ca1 61main(argc, argv)
62int argc;
63char **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
112do_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
160do_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;
f2546b02 264 strtrim(string);
265
1db0775a 266 if (p = strchr(string, '@'))
267 {
f2546b02 268 *p = 0;
1db0775a 269 if (strcmp(p+1, "ATHENA.MIT.EDU"))
270 aid = -1;
271 }
272 else aid = -1;
273
274 p = strchr(string, '.');
275 if ((!p) && (strlen(string) < 9))
276 strcpy(name, string);
277 else if ((p-string) < 9 && !strcmp(p+1, "root"))
278 {
f2546b02 279 strncpy(name, string, p-string);
280 name[p-string] = 0;
1db0775a 281 root_flag = 1;
282 }
283 else
284 aid = -1;
f2546b02 285
286 if (aid == 0) {
287 EXEC SQL DECLARE k_cursor2 CURSOR FOR
c7e4633e 288 SELECT unix_uid, status
f2546b02 289 FROM users
290 WHERE login = :name
c7e4633e 291 ORDER BY unix_uid;
f2546b02 292 EXEC SQL OPEN k_cursor2;
1db0775a 293 while (1)
294 {
295 if (sqlca.sqlcode)
296 break;
297 EXEC SQL FETCH k_cursor2 INTO :lid, :ustatus;
298 if (ustatus==1 || ustatus==2)
299 {
300 if (root_flag == 1)
301 aid = lid+65536;
302 else
303 aid = lid;
304 }
f2546b02 305 }
306 EXEC SQL CLOSE k_cursor2;
307 }
308
309 if (aid > 0) {
310 if (FindByID(0,aid))
311 status = PRIDEXIST;
312 else
313 status = CreateEntry(0, string, &aid, 1 /*idflag*/,
314 0 /*gflag*/, SYSADMINID /*oid*/,
315 SYSADMINID /*cid */);
316 if (status) {
317 fprintf(stderr, "Error adding %s (id %d): %s\n",
318 string, aid, error_message(status));
319 if (status != PRIDEXIST) aid = 0;
320 }
321 } else
322 aid = 0;
323
324 u = (struct entry *)malloc(sizeof(struct entry));
325 u->id = aid;
326 u->members = 0;
327 hash_store(strings, id, u);
328 if (aid) kcount++;
329 }
330 if (u->id == 0) continue;
331
01c57ca1 332 m = (struct member *)malloc(sizeof(struct member));
333 m->user = u;
334 m->group = g;
335 m->unext = u->members;
336 m->gnext = g->members;
337 u->members = g->members = m;
338 mcount++;
339 }
f2546b02 340#endif
01c57ca1 341 }
342 EXEC SQL CLOSE m_cursor;
343
f2546b02 344 t = time(0);
345 fprintf(stderr, "Doing members: %s", ctime(&t));
346
01c57ca1 347 /* Do the bulk of the membership quickly.
348 * Add PRSIZE members into the user/group record. After that, we
349 * require the use of continuation records, but we assume this is
350 * few enough that we do this the slow way (AddToEntry).
351 */
352 for (p = &(users->data[users->size - 1]); p >= users->data; p--) {
353 for (b = *p; b; b = b->next) {
354 if ((u = (struct entry *)b->data)->members == 0)
355 continue;
356 pos = FindByID(0, u->id);
357 pr_Read(0, 0, pos, &uentry, sizeof(uentry));
358 for (t=0, m=u->members; m && t<PRSIZE; m=m->unext, t++)
359 uentry.entries[t] = htonl(m->group->id);
360 uentry.count = htonl(t);
361 pr_Write(0, 0, pos, &uentry, sizeof(uentry));
362 if (m) {
363 pr_ReadEntry(0, 0, pos, &uentry);
364 while (m) {
365 AddToEntry(0, &uentry, pos, m->group->id);
366 m = m->unext;
367 }
368 }
369 }
370 }
f2546b02 371#ifdef DO_KERBEROS
372 for (p = &(strings->data[strings->size - 1]); p >= strings->data; p--) {
373 for (b = *p; b; b = b->next) {
374 if ((u = (struct entry *)b->data)->members == 0)
375 continue;
376 pos = FindByID(0, u->id);
377 pr_Read(0, 0, pos, &uentry, sizeof(uentry));
378 for (t=0, m=u->members; m && t<PRSIZE; m=m->unext, t++)
379 uentry.entries[t] = htonl(m->group->id);
380 uentry.count = htonl(t);
381 pr_Write(0, 0, pos, &uentry, sizeof(uentry));
382 if (m) {
383 pr_ReadEntry(0, 0, pos, &uentry);
384 while (m) {
385 AddToEntry(0, &uentry, pos, m->group->id);
386 m = m->unext;
387 }
388 }
389 }
390 }
391#endif
01c57ca1 392 for (p = &(groups->data[groups->size - 1]); p >= groups->data; p--) {
393 for (b = *p; b; b = b->next) {
394 if ((g = (struct entry *)b->data)->members == 0)
395 continue;
396 pos = FindByID(0, g->id);
397 pr_Read(0, 0, pos, &gentry, sizeof(gentry));
398 for (t=0, m=g->members; m && t<PRSIZE; m=m->gnext, t++)
399 gentry.entries[t] = htonl(m->user->id);
400 gentry.count = htonl(t);
401 pr_Write(0, 0, pos, &gentry, sizeof(gentry));
402 if (m) {
403 pr_ReadEntry(0, 0, pos, &gentry);
404 while (m) {
405 AddToEntry(0, &gentry, pos, m->user->id);
406 m = m->gnext;
407 }
408 }
409 }
410 }
411 return;
412}
413
414
415sqlerr()
416{
c7e4633e 417 char buf[256];
418 int size=256, len=0;
419
420 sqlglm(buf, &size, &len);
421 buf[len]='\0';
422 com_err(whoami, MR_DBMS_ERR, " code %d\n%s", sqlca.sqlcode, buf);
423 exit(MR_DBMS_ERR);
01c57ca1 424}
This page took 2.38192 seconds and 5 git commands to generate.