]> andersk Git - moira.git/blob - afssync/sync.pc
OpenAFS 1.4.x support; steal bits of ubik.h we need rather than including it.
[moira.git] / afssync / sync.pc
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>
12 #include <string.h>
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
23 /* The following enables the processing of .root instances */
24 #define DO_KERBEROS
25
26 EXEC SQL INCLUDE sqlca;
27
28 EXEC SQL BEGIN DECLARE SECTION;
29 char db[33] = "moira";
30 EXEC SQL END DECLARE SECTION;
31
32 #ifndef min
33 #define min(x,y)        ((x) < (y) ? (x) : (y))
34 #endif
35 char *whoami = "sync";
36
37 int dbase_fd;
38
39 int ucount = 0;
40 int gcount = 0;
41 int kcount = 0;
42 int mcount = 0;
43
44 struct hash *users;
45 struct hash *groups;
46 #ifdef DO_KERBEROS
47 struct hash *strings;
48 #endif
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
61 main(argc, argv)
62 int argc;
63 char **argv;
64 {
65     int status;
66     long t;
67
68     setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
69
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) {
82         perror("opening data file");
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);
92 #ifdef DO_KERBEROS
93     strings = create_hash(1000);
94 #endif
95
96     EXEC SQL WHENEVER SQLERROR DO sqlerr();
97     EXEC SQL CONNECT :db IDENTIFIED BY :db;
98
99     do_passwd();
100     do_groups();
101
102     t = time(0);
103     fprintf(stderr, "Done (%d users, %d groups, %d kerberos, %d members): %s",
104             ucount, gcount, kcount, mcount, ctime(&t));
105
106     EXEC SQL COMMIT;
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
126     EXEC SQL DECLARE u_cursor CURSOR FOR
127         SELECT u.login, u.unix_uid, u.users_id
128         FROM users u
129         WHERE u.unix_uid > 0 AND (u.status = 1 OR u.status = 2)
130         ORDER BY unix_uid;
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;
163     char name[33], string[129];
164     int gid, id, lid, hide, ustatus;
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
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);
228     fprintf(stderr, "Reading/preparing members: %s", ctime(&t));
229
230     EXEC SQL DECLARE m_cursor CURSOR FOR
231         SELECT m.list_id, m.member_id, m.member_type
232         FROM imembers m
233         ORDER BY member_id;
234     EXEC SQL OPEN m_cursor;
235     while (1) {
236         EXEC SQL FETCH m_cursor INTO :lid, :id, :name;
237         if (sqlca.sqlcode != 0) break;
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
265                 if (p = (char *)index(string, '@')) {
266                     *p = 0;
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                 {
273                     strncpy(name, string, p-string);
274                     name[p-string] = 0;
275                 } else aid = -1;
276
277                 if (aid == 0) {
278                     EXEC SQL DECLARE k_cursor2 CURSOR FOR
279                         SELECT unix_uid, status
280                         FROM users
281                         WHERE login = :name
282                         ORDER BY unix_uid;
283                     EXEC SQL OPEN k_cursor2;
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;
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
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         }
323 #endif
324     }
325     EXEC SQL CLOSE m_cursor;
326
327     t = time(0);
328     fprintf(stderr, "Doing members: %s", ctime(&t));
329
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     }
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
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 {
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);
407 }
This page took 0.239702 seconds and 5 git commands to generate.