]> andersk Git - moira.git/blob - afssync/sync.pc
27de1f67430630906f0ce38e286f014fd4e62744
[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 EXEC SQL INCLUDE sqlca;
24
25 EXEC SQL BEGIN DECLARE SECTION;
26 char db[33] = "moira";
27 EXEC SQL END DECLARE SECTION;
28
29 #ifndef min
30 #define min(x,y)        ((x) < (y) ? (x) : (y))
31 #endif
32 char *whoami = "sync";
33
34 int dbase_fd;
35
36 int ucount = 0;
37 int gcount = 0;
38 int kcount = 0;
39 int mcount = 0;
40
41 struct hash *users;
42 struct hash *groups;
43
44 struct member {
45     struct entry *user;
46     struct entry *group;
47     struct member *unext;
48     struct member *gnext;
49 };
50 struct entry {
51     long id;
52     struct member *members;
53 };
54
55 main(argc, argv)
56 int argc;
57 char **argv;
58 {
59     int status;
60     long t;
61
62     setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
63
64     if (argc > 2 && !strcmp(argv[1], "-db")) {
65         strncpy(db, argv[2], sizeof(db)-1);
66         argc -= 2;
67         argv += 2;
68     }
69     if (argc != 2) {
70         fprintf(stderr, "usage: %s [-db moira] outfile\n", whoami);
71         exit(MR_ARGS);
72     }
73
74     dbase_fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0660);
75     if (dbase_fd < 0) {
76         perror("opening data file");
77         exit(1);
78     }
79
80     initialize_sms_error_table();
81     initialize_pt_error_table();
82     Initdb();                                   /* Initialize prdb */
83     
84     users = create_hash(10000);
85     groups = create_hash(15000);
86
87     EXEC SQL WHENEVER SQLERROR DO sqlerr();
88     EXEC SQL CONNECT :db IDENTIFIED BY :db;
89
90     do_passwd();
91     do_groups();
92
93     t = time(0);
94     fprintf(stderr, "Done (%d users, %d groups, %d kerberos, %d members): %s",
95             ucount, gcount, kcount, mcount, ctime(&t));
96
97     EXEC SQL COMMIT;
98
99     exit(MR_SUCCESS);
100 }
101
102
103 do_passwd()
104 {
105     EXEC SQL BEGIN DECLARE SECTION;
106     char login[9], name[33];
107     int uid, id, status;
108     EXEC SQL END DECLARE SECTION;
109
110     long t;
111     struct prentry tentry;
112     struct entry *u;
113
114     t = time(0);
115     fprintf(stderr, "Doing users: %s", ctime(&t));
116
117     EXEC SQL DECLARE u_cursor CURSOR FOR
118         SELECT u.login, u.unix_uid, u.users_id
119         FROM users u
120         WHERE u.unix_uid > 0 AND (u.status = 1 OR u.status = 2)
121         ORDER BY unix_uid;
122     EXEC SQL OPEN u_cursor;
123     while (1) {
124         EXEC SQL FETCH u_cursor INTO :login, :uid, :id;
125         if (sqlca.sqlcode != 0) break;
126         
127         lowercase(strtrim(login));
128
129         if (FindByID(0,uid))
130             status = PRIDEXIST;
131         else
132             status = CreateEntry(0,login,&uid,1 /*idflag*/,0/*gflag*/,
133                                  SYSADMINID     /*oid*/, SYSADMINID/*cid*/);
134         if (status)
135             fprintf(stderr, "Error adding user %s uid %d: %s\n",
136                     login, uid, error_message(status));
137         else {
138             u = (struct entry *)malloc(sizeof(struct entry));
139             u->id = uid;
140             u->members = 0;
141             hash_store(users, id, u);
142             ucount++;
143         }
144     }
145     EXEC SQL CLOSE u_cursor;
146     return;
147 }
148
149
150
151 do_groups()
152 {
153     EXEC SQL BEGIN DECLARE SECTION;
154     char name[33], string[129];
155     int gid, id, lid, hide, ustatus;
156     EXEC SQL END DECLARE SECTION;
157
158     long status, pos;
159     struct prentry gentry, uentry;
160     struct entry *u, *g;
161     struct member *m;
162     struct bucket **p, *b;
163     char namebuf[40];
164     long aid, t;
165
166     t = time(0);
167     fprintf(stderr, "Doing groups: %s", ctime(&t));
168
169     EXEC SQL DECLARE l_cursor CURSOR FOR
170         SELECT l.name, l.gid, l.list_id, l.hidden
171         FROM list l
172         WHERE l.gid > 0 AND l.active != 0 AND l.grouplist != 0
173         ORDER BY gid;
174     EXEC SQL OPEN l_cursor;
175     while (1) {
176         EXEC SQL FETCH l_cursor INTO :name, :gid, :lid, :hide;
177         if (sqlca.sqlcode != 0) break;
178         
179         lowercase(strtrim(name));
180         sprintf(namebuf, "system:%s", name);
181         aid = -gid;
182
183         if (FindByID(0, aid))
184             status = PRIDEXIST;
185         else
186             status = CreateEntry(0,namebuf,&aid,1 /*idflag*/,PRGRP/*gflag*/,
187                                  SYSADMINID     /*oid*/, SYSADMINID/*cid*/);
188         if (status)
189             fprintf(stderr, "Error adding group %s id %d: %s\n",
190                     namebuf, aid, error_message(status));
191
192         if ((status==0 || status==PRIDEXIST) &&
193             (aid!=ANYUSERID && aid!=AUTHUSERID)) {
194
195             g = (struct entry *)malloc(sizeof(struct entry));
196             g->id = aid;
197             g->members = 0;
198             hash_store(groups, lid, g);
199             gcount++;
200
201             /* Set modes on hidden lists (S----) */
202             if (hide) {
203                 pos = FindByID(0, aid);
204                 status = pr_Read(0, 0, pos, &gentry, sizeof(gentry));
205                 if (!status) {
206                     gentry.flags = htonl(PRGRP|PRACCESS|PRP_STATUS_ANY);
207                     status = pr_Write(0, 0, pos, &gentry, sizeof(gentry));
208                 }
209                 if (status)
210                     fprintf(stderr,
211                             "Error setting flags on group %s: %s\n",
212                             namebuf, error_message(status));
213             }
214         }
215     }
216     EXEC SQL CLOSE l_cursor;
217
218     t = time(0);
219     fprintf(stderr, "Reading/preparing members: %s", ctime(&t));
220
221     EXEC SQL DECLARE m_cursor CURSOR FOR
222         SELECT m.list_id, m.member_id, m.member_type
223         FROM imembers m
224         ORDER BY member_id;
225     EXEC SQL OPEN m_cursor;
226     while (1) {
227         EXEC SQL FETCH m_cursor INTO :lid, :id, :name;
228         if (sqlca.sqlcode != 0) break;
229
230         if (!(g = (struct entry *)hash_lookup(groups, lid)))
231             continue;
232
233         strtrim(name);
234         if (!strcmp(name, "USER")) {
235             if (u = (struct entry *)hash_lookup(users, id)) {
236                 m = (struct member *)malloc(sizeof(struct member));
237                 m->user = u;
238                 m->group = g;
239                 m->unext = u->members;
240                 m->gnext = g->members;
241                 u->members = g->members = m;
242                 mcount++;
243             }
244         }
245     }
246     EXEC SQL CLOSE m_cursor;
247
248     t = time(0);
249     fprintf(stderr, "Doing members: %s", ctime(&t));
250
251     /* Do the bulk of the membership quickly.
252      * Add PRSIZE members into the user/group record.  After that, we
253      * require the use of continuation records, but we assume this is
254      * few enough that we do this the slow way (AddToEntry).
255      */
256     for (p = &(users->data[users->size - 1]); p >= users->data; p--) {
257         for (b = *p; b; b = b->next) {
258             if ((u = (struct entry *)b->data)->members == 0)
259                 continue;
260             pos = FindByID(0, u->id);
261             pr_Read(0, 0, pos, &uentry, sizeof(uentry));
262             for (t=0, m=u->members; m && t<PRSIZE; m=m->unext, t++)
263                 uentry.entries[t] = htonl(m->group->id);
264             uentry.count = htonl(t);
265             pr_Write(0, 0, pos, &uentry, sizeof(uentry));
266             if (m) {
267                 pr_ReadEntry(0, 0, pos, &uentry);
268                 while (m) {
269                     AddToEntry(0, &uentry, pos, m->group->id);
270                     m = m->unext;
271                 }
272             }
273         }
274     }
275     for (p = &(groups->data[groups->size - 1]); p >= groups->data; p--) {
276         for (b = *p; b; b = b->next) {
277             if ((g = (struct entry *)b->data)->members == 0)
278                 continue;
279             pos = FindByID(0, g->id);
280             pr_Read(0, 0, pos, &gentry, sizeof(gentry));
281             for (t=0, m=g->members; m && t<PRSIZE; m=m->gnext, t++)
282                 gentry.entries[t] = htonl(m->user->id);
283             gentry.count = htonl(t);
284             pr_Write(0, 0, pos, &gentry, sizeof(gentry));
285             if (m) {
286                 pr_ReadEntry(0, 0, pos, &gentry);
287                 while (m) {
288                     AddToEntry(0, &gentry, pos, m->user->id);
289                     m = m->gnext;
290                 }
291             }
292         }
293     }
294     return;
295 }
296
297     
298 sqlerr()
299 {
300     char buf[256];
301     int size=256, len=0;
302
303     sqlglm(buf, &size, &len);
304     buf[len]='\0';
305     com_err(whoami, MR_DBMS_ERR, " code %d\n%s", sqlca.sqlcode, buf);
306     exit(MR_DBMS_ERR);
307 }
This page took 0.047416 seconds and 3 git commands to generate.