]>
Commit | Line | Data |
---|---|---|
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 | ||
23 | EXEC SQL INCLUDE sqlca; | |
24 | ||
f2546b02 | 25 | EXEC SQL BEGIN DECLARE SECTION; |
26 | char db[33] = "moira"; | |
27 | EXEC SQL END DECLARE SECTION; | |
28 | ||
c7e4633e | 29 | #ifndef min |
01c57ca1 | 30 | #define min(x,y) ((x) < (y) ? (x) : (y)) |
c7e4633e | 31 | #endif |
01c57ca1 | 32 | char *whoami = "sync"; |
33 | ||
01c57ca1 | 34 | int dbase_fd; |
35 | ||
36 | int ucount = 0; | |
37 | int gcount = 0; | |
f2546b02 | 38 | int kcount = 0; |
01c57ca1 | 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 | ||
01c57ca1 | 55 | main(argc, argv) |
56 | int argc; | |
57 | char **argv; | |
58 | { | |
01c57ca1 | 59 | int status; |
60 | long t; | |
61 | ||
c7e4633e | 62 | setvbuf(stdout, NULL, _IOLBF, BUFSIZ); |
63 | ||
01c57ca1 | 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) { | |
fe7208bc | 76 | perror("opening data file"); |
01c57ca1 | 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 | ||
c7e4633e | 87 | EXEC SQL WHENEVER SQLERROR DO sqlerr(); |
88 | EXEC SQL CONNECT :db IDENTIFIED BY :db; | |
01c57ca1 | 89 | |
90 | do_passwd(); | |
91 | do_groups(); | |
92 | ||
93 | t = time(0); | |
f2546b02 | 94 | fprintf(stderr, "Done (%d users, %d groups, %d kerberos, %d members): %s", |
95 | ucount, gcount, kcount, mcount, ctime(&t)); | |
01c57ca1 | 96 | |
c7e4633e | 97 | EXEC SQL COMMIT; |
01c57ca1 | 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 | ||
01c57ca1 | 117 | EXEC SQL DECLARE u_cursor CURSOR FOR |
c7e4633e | 118 | SELECT u.login, u.unix_uid, u.users_id |
01c57ca1 | 119 | FROM users u |
c7e4633e | 120 | WHERE u.unix_uid > 0 AND (u.status = 1 OR u.status = 2) |
121 | ORDER BY unix_uid; | |
01c57ca1 | 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; | |
f2546b02 | 154 | char name[33], string[129]; |
818ac4aa | 155 | int gid, id, lid, hide, ustatus; |
01c57ca1 | 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 | ||
01c57ca1 | 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); | |
f2546b02 | 219 | fprintf(stderr, "Reading/preparing members: %s", ctime(&t)); |
01c57ca1 | 220 | |
221 | EXEC SQL DECLARE m_cursor CURSOR FOR | |
f2546b02 | 222 | SELECT m.list_id, m.member_id, m.member_type |
01c57ca1 | 223 | FROM imembers m |
01c57ca1 | 224 | ORDER BY member_id; |
225 | EXEC SQL OPEN m_cursor; | |
226 | while (1) { | |
f2546b02 | 227 | EXEC SQL FETCH m_cursor INTO :lid, :id, :name; |
01c57ca1 | 228 | if (sqlca.sqlcode != 0) break; |
f2546b02 | 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 | } | |
01c57ca1 | 245 | } |
246 | EXEC SQL CLOSE m_cursor; | |
247 | ||
f2546b02 | 248 | t = time(0); |
249 | fprintf(stderr, "Doing members: %s", ctime(&t)); | |
250 | ||
01c57ca1 | 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 | { | |
c7e4633e | 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); | |
01c57ca1 | 307 | } |