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