source: trunk/third/moira/afssync/sync.pc @ 24250

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