]> andersk Git - moira.git/blob - afssync/sync.pc
Handle null instance KERBEROS list members.
[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, root_flag;
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                 root_flag = 0;
264                 strtrim(string);
265
266                 if (p = strchr(string, '@')) 
267                   {
268                     *p = 0;
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                   {
279                     strncpy(name, string, p-string);
280                     name[p-string] = 0;
281                     root_flag = 1;
282                   }
283                 else
284                   aid = -1;
285
286                 if (aid == 0) {
287                     EXEC SQL DECLARE k_cursor2 CURSOR FOR
288                         SELECT unix_uid, status
289                         FROM users
290                         WHERE login = :name
291                         ORDER BY unix_uid;
292                     EXEC SQL OPEN k_cursor2;
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                           }
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
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         }
340 #endif
341     }
342     EXEC SQL CLOSE m_cursor;
343
344     t = time(0);
345     fprintf(stderr, "Doing members: %s", ctime(&t));
346
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     }
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
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     
415 sqlerr()
416 {
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);
424 }
This page took 0.091422 seconds and 5 git commands to generate.