]>
Commit | Line | Data |
---|---|---|
fb8809f4 | 1 | /* $Header$ |
2 | * | |
3 | * Do AFS incremental updates | |
4 | * | |
60c22e5f | 5 | * Copyright (C) 1989,1992 by the Massachusetts Institute of Technology |
fb8809f4 | 6 | * for copying and distribution information, please see the file |
7 | * <mit-copyright.h>. | |
8 | */ | |
9 | ||
60c22e5f | 10 | #include <sys/types.h> |
11 | #include <sys/file.h> | |
12 | #include <strings.h> | |
13 | ||
d1be2e3a | 14 | #include <krb.h> |
2ce085d2 | 15 | #include <moira.h> |
16 | #include <moira_site.h> | |
f633445d | 17 | |
60c22e5f | 18 | #include <afs/param.h> |
19 | #include <afs/cellconfig.h> | |
20 | #include <afs/venus.h> | |
21 | #include <afs/ptclient.h> | |
22 | #include <afs/pterror.h> | |
fb8809f4 | 23 | |
d1be2e3a | 24 | #define STOP_FILE "/moira/afs/noafs" |
25 | ||
60c22e5f | 26 | #define file_exists(file) (access((file), F_OK) == 0) |
fb8809f4 | 27 | |
28 | char *whoami; | |
29 | ||
30 | main(argc, argv) | |
31 | char **argv; | |
32 | int argc; | |
33 | { | |
a7fdf2de | 34 | int beforec, afterc, i; |
fb8809f4 | 35 | char *table, **before, **after; |
810d12a7 | 36 | char buf[1024]; |
fb8809f4 | 37 | |
a7fdf2de | 38 | for (i = getdtablesize() - 1; i > 2; i--) |
39 | close(i); | |
40 | ||
fb8809f4 | 41 | table = argv[1]; |
42 | beforec = atoi(argv[2]); | |
43 | before = &argv[4]; | |
44 | afterc = atoi(argv[3]); | |
45 | after = &argv[4 + beforec]; | |
46 | whoami = argv[0]; | |
47 | ||
810d12a7 | 48 | sprintf(buf, "%s (", table); |
49 | for (i = 0; i < beforec; i++) { | |
50 | if (i > 0) | |
51 | strcat(buf, ","); | |
52 | strcat(buf, before[i]); | |
53 | } | |
54 | strcat(buf, ")->("); | |
55 | for (i = 0; i < afterc; i++) { | |
56 | if (i > 0) | |
57 | strcat(buf, ","); | |
58 | strcat(buf, after[i]); | |
59 | } | |
60 | strcat(buf, ")\n"); | |
d1be2e3a | 61 | #ifdef DEBUG |
810d12a7 | 62 | write(1,buf,strlen(buf)); |
63 | #endif | |
64 | ||
fb8809f4 | 65 | initialize_sms_error_table(); |
66 | initialize_krb_error_table(); | |
67 | ||
d1be2e3a | 68 | for (i=0; file_exists(STOP_FILE); i++) { |
69 | if (i > 30) { | |
70 | critical_alert("incremental", | |
71 | "AFS incremental failed (%s exists): %s", | |
72 | STOP_FILE, buf); | |
73 | exit(1); | |
74 | } | |
75 | sleep(60); | |
76 | } | |
77 | ||
fb8809f4 | 78 | if (!strcmp(table, "users")) { |
79 | do_user(before, beforec, after, afterc); | |
80 | } else if (!strcmp(table, "list")) { | |
81 | do_list(before, beforec, after, afterc); | |
82 | } else if (!strcmp(table, "members")) { | |
83 | do_member(before, beforec, after, afterc); | |
84 | } else if (!strcmp(table, "filesys")) { | |
85 | do_filesys(before, beforec, after, afterc); | |
1f377b55 | 86 | } else if (!strcmp(table, "quota")) { |
fb8809f4 | 87 | do_quota(before, beforec, after, afterc); |
88 | } | |
fb8809f4 | 89 | exit(0); |
90 | } | |
91 | ||
92 | ||
93 | do_cmd(cmd) | |
94 | char *cmd; | |
95 | { | |
a7fdf2de | 96 | int success = 0, tries = 0; |
fb8809f4 | 97 | |
60c22e5f | 98 | while (success == 0 && tries < 1) { |
99 | if (tries++) | |
100 | sleep(5*60); | |
a7fdf2de | 101 | com_err(whoami, 0, "Executing command: %s", cmd); |
102 | if (system(cmd) == 0) | |
60c22e5f | 103 | success++; |
fb8809f4 | 104 | } |
105 | if (!success) | |
60c22e5f | 106 | critical_alert("incremental", "failed command: %s", cmd); |
fb8809f4 | 107 | } |
108 | ||
109 | ||
110 | do_user(before, beforec, after, afterc) | |
111 | char **before; | |
112 | int beforec; | |
113 | char **after; | |
114 | int afterc; | |
115 | { | |
60c22e5f | 116 | int astate, bstate, auid, buid, code; |
117 | ||
118 | auid = buid = astate = bstate = 0; | |
119 | if (afterc > U_STATE) astate = atoi(after[U_STATE]); | |
120 | if (beforec > U_STATE) bstate = atoi(before[U_STATE]); | |
121 | if (afterc > U_UID) auid = atoi(after[U_UID]); | |
122 | if (beforec > U_UID) buid = atoi(before[U_UID]); | |
123 | ||
124 | /* We consider "half-registered" users to be active */ | |
810d12a7 | 125 | if (astate == 2) astate = 1; |
126 | if (bstate == 2) bstate = 1; | |
fb8809f4 | 127 | |
60c22e5f | 128 | if (astate != 1 && bstate != 1) /* inactive user */ |
fb8809f4 | 129 | return; |
60c22e5f | 130 | |
131 | if (astate == bstate && auid == buid && | |
132 | !strcmp(before[U_NAME], after[U_NAME])) | |
133 | /* No AFS related attributes have changed */ | |
fb8809f4 | 134 | return; |
fb8809f4 | 135 | |
60c22e5f | 136 | code=pr_Initialize(1, AFSCONF_CLIENTNAME, 0); |
137 | if (code) { | |
138 | critical_alert("incremental", "Couldn't initialize libprot: %s", | |
139 | error_message(code)); | |
140 | return; | |
fb8809f4 | 141 | } |
60c22e5f | 142 | |
143 | if (astate == bstate) { | |
144 | /* Only a modify has to be done */ | |
58283442 | 145 | code = pr_ChangeEntry(before[U_NAME], after[U_NAME], |
146 | (auid==buid) ? 0 : auid, ""); | |
60c22e5f | 147 | if (code) { |
148 | critical_alert("incremental", | |
149 | "Couldn't change user %s (id %d) to %s (id %d): %s", | |
150 | before[U_NAME], buid, after[U_NAME], auid, | |
151 | error_message(code)); | |
152 | } | |
153 | return; | |
154 | } | |
155 | if (bstate == 1) { | |
156 | code = pr_DeleteByID(buid); | |
157 | if (code && code != PRNOENT) { | |
158 | critical_alert("incremental", | |
159 | "Couldn't delete user %s (id %d): %s", | |
160 | before[U_NAME], buid, error_message(code)); | |
161 | } | |
162 | return; | |
163 | } | |
164 | if (astate == 1) { | |
165 | code = pr_CreateUser(after[U_NAME], &auid); | |
166 | if (code) { | |
167 | critical_alert("incremental", | |
168 | "Couldn't create user %s (id %d): %s", | |
169 | after[U_NAME], auid, error_message(code)); | |
170 | } | |
171 | return; | |
fb8809f4 | 172 | } |
173 | } | |
174 | ||
175 | ||
176 | ||
177 | do_list(before, beforec, after, afterc) | |
178 | char **before; | |
179 | int beforec; | |
180 | char **after; | |
181 | int afterc; | |
182 | { | |
fb8809f4 | 183 | int agid, bgid; |
60c22e5f | 184 | long code, id; |
ed9a5300 | 185 | char hostname[64]; |
60c22e5f | 186 | char g1[PR_MAXNAMELEN], g2[PR_MAXNAMELEN]; |
ed9a5300 | 187 | char *av[2]; |
fb8809f4 | 188 | |
60c22e5f | 189 | agid = bgid = 0; |
fb8809f4 | 190 | if (beforec > L_GID && atoi(before[L_ACTIVE]) && atoi(before[L_GROUP])) |
60c22e5f | 191 | bgid = atoi(before[L_GID]); |
fb8809f4 | 192 | if (afterc > L_GID && atoi(after[L_ACTIVE]) && atoi(after[L_GROUP])) |
60c22e5f | 193 | agid = atoi(after[L_GID]); |
fb8809f4 | 194 | |
60c22e5f | 195 | if (agid == 0 && bgid == 0) /* Not active groups */ |
196 | return; | |
197 | if (agid == bgid && !strcmp(after[L_NAME], before[L_NAME])) | |
198 | return; /* No change */ | |
199 | ||
200 | code=pr_Initialize(1, AFSCONF_CLIENTNAME, 0); | |
201 | if (code) { | |
202 | critical_alert("incremental", "Couldn't initialize libprot: %s", | |
203 | error_message(code)); | |
fb8809f4 | 204 | return; |
205 | } | |
60c22e5f | 206 | |
207 | if (agid && bgid) { | |
208 | /* Only a modify is required */ | |
209 | strcpy(g1, "system:"); | |
210 | strcpy(g2, "system:"); | |
211 | strcat(g1, before[L_NAME]); | |
212 | strcat(g2, after[L_NAME]); | |
58283442 | 213 | code = pr_ChangeEntry(g1, g2, (agid==bgid) ? 0 : -agid, ""); |
60c22e5f | 214 | if (code) { |
215 | critical_alert("incremental", | |
216 | "Couldn't change group %s (id %d) to %s (id %d): %s", | |
217 | before[L_NAME], -bgid, after[L_NAME], -agid, | |
218 | error_message(code)); | |
219 | } | |
fb8809f4 | 220 | return; |
221 | } | |
60c22e5f | 222 | if (bgid) { |
223 | code = pr_DeleteByID(-bgid); | |
224 | if (code && code != PRNOENT) { | |
225 | critical_alert("incremental", | |
226 | "Couldn't delete group %s (id %d): %s", | |
227 | before[L_NAME], -bgid, error_message(code)); | |
228 | } | |
fb8809f4 | 229 | return; |
230 | } | |
60c22e5f | 231 | if (agid) { |
232 | strcpy(g1, "system:"); | |
233 | strcat(g1, after[L_NAME]); | |
234 | strcpy(g2, "system:administrators"); | |
235 | id = -agid; | |
236 | code = pr_CreateGroup(g1, g2, &id); | |
237 | if (code) { | |
238 | critical_alert("incremental", | |
239 | "Couldn't create group %s (id %d): %s", | |
ed9a5300 | 240 | after[L_NAME], id, error_message(code)); |
60c22e5f | 241 | return; |
242 | } | |
243 | ||
244 | /* We need to make sure the group is properly populated */ | |
245 | if (beforec < L_ACTIVE || atoi(before[L_ACTIVE]) == 0) return; | |
246 | ||
ed9a5300 | 247 | gethostname(hostname, sizeof(hostname)); |
248 | code = mr_connect(hostname); | |
249 | if (!code) code = mr_auth("afs.incr"); | |
250 | if (code) { | |
251 | critical_alert("incremental", | |
252 | "Error contacting Moira server to resolve %s: %s", | |
253 | after[L_NAME], error_message(code)); | |
254 | return; | |
255 | } | |
256 | av[0] = "LIST"; | |
257 | av[1] = after[L_NAME]; | |
258 | get_members(2, av, after[L_NAME]); | |
259 | ||
260 | mr_disconnect(); | |
261 | return; | |
60c22e5f | 262 | } |
fb8809f4 | 263 | } |
264 | ||
265 | ||
266 | do_member(before, beforec, after, afterc) | |
267 | char **before; | |
268 | int beforec; | |
269 | char **after; | |
270 | int afterc; | |
271 | { | |
60c22e5f | 272 | int code; |
273 | char *p; | |
274 | ||
bd70a79d | 275 | if ((beforec < 4 || !atoi(before[LM_END])) && |
276 | (afterc < 4 || !atoi(after[LM_END]))) | |
fb8809f4 | 277 | return; |
60c22e5f | 278 | |
279 | code=pr_Initialize(1, AFSCONF_CLIENTNAME, 0); | |
280 | if (code) { | |
281 | critical_alert("incremental", "Couldn't initialize libprot: %s", | |
282 | error_message(code)); | |
fb8809f4 | 283 | return; |
284 | } | |
60c22e5f | 285 | |
ed9a5300 | 286 | if (afterc) |
287 | edit_group(1, after[LM_LIST], after[LM_TYPE], after[LM_MEMBER]); | |
288 | if (beforec) | |
289 | edit_group(0, after[LM_LIST], after[LM_TYPE], after[LM_MEMBER]); | |
290 | } | |
291 | ||
292 | ||
293 | get_members(ac, av, group) | |
294 | int ac; | |
295 | char *av[]; | |
296 | char *group; | |
297 | { | |
298 | int code=0; | |
299 | ||
300 | if (strcmp(av[0], "LIST")) { | |
301 | sleep(1); /* give the ptserver room */ | |
302 | edit_group(1, group, av[0], av[1]); | |
303 | } else { | |
304 | code = mr_query("get_members_of_list", 1, &av[1], get_members, group); | |
305 | if (code) | |
306 | critical_alert("incremental", | |
307 | "Couldn't retrieve full membership of %s: %s", | |
308 | group, error_message(code)); | |
309 | } | |
310 | return code; | |
311 | } | |
312 | ||
313 | ||
314 | edit_group(op, group, type, member) | |
315 | int op; | |
316 | char *group; | |
317 | char *type; | |
318 | char *member; | |
319 | { | |
320 | char *p = 0; | |
321 | char buf[PR_MAXNAMELEN]; | |
322 | int (*fn)(); | |
323 | int code; | |
d1be2e3a | 324 | static char local_realm[REALM_SZ+1] = ""; |
ed9a5300 | 325 | extern long pr_AddToGroup(), pr_RemoveUserFromGroup(); |
326 | ||
327 | fn = op ? pr_AddToGroup : pr_RemoveUserFromGroup; | |
328 | ||
60c22e5f | 329 | /* The following KERBEROS code allows for the use of entities |
330 | * user@foreign_cell. | |
331 | */ | |
d1be2e3a | 332 | if (!local_realm[0]) |
333 | krb_get_lrealm(local_realm, 1); | |
ed9a5300 | 334 | if (!strcmp(type, "KERBEROS")) { |
335 | p = index(member, '@'); | |
d1be2e3a | 336 | if (p && !strcasecmp(p+1, local_realm)) |
60c22e5f | 337 | *p = 0; |
ed9a5300 | 338 | } else if (strcmp(type, "USER")) |
339 | return; /* invalid type */ | |
60c22e5f | 340 | |
ed9a5300 | 341 | strcpy(buf, "system:"); |
342 | strcat(buf, group); | |
343 | code = (*fn)(member, buf); | |
344 | if (code) { | |
345 | if (op==0 && code == PRNOENT) return; | |
346 | if (op==1 && code == PRIDEXIST) return; | |
347 | if (strcmp(type, "KERBEROS") || code != PRNOENT) { | |
60c22e5f | 348 | critical_alert("incremental", |
ed9a5300 | 349 | "Couldn't %s %s %s %s: %s", |
350 | op ? "add" : "remove", member, | |
351 | op ? "to" : "from", buf, | |
60c22e5f | 352 | error_message(code)); |
60c22e5f | 353 | } |
57bc9f26 | 354 | } |
ed9a5300 | 355 | if (p) *p = '@'; |
fb8809f4 | 356 | } |
357 | ||
358 | ||
359 | do_filesys(before, beforec, after, afterc) | |
360 | char **before; | |
361 | int beforec; | |
362 | char **after; | |
363 | int afterc; | |
364 | { | |
60c22e5f | 365 | char cmd[1024]; |
366 | ||
d43ba793 | 367 | if (beforec < FS_CREATE) { |
60c22e5f | 368 | if (afterc < FS_CREATE || atoi(after[FS_CREATE])==0 || |
369 | strcmp(after[FS_TYPE], "AFS")) | |
370 | return; | |
371 | ||
d43ba793 | 372 | /* new locker creation */ |
60c22e5f | 373 | sprintf(cmd, "%s/perl -I%s %s/afs_create.pl %s %s %s %s %s %s", |
374 | BIN_DIR, BIN_DIR, BIN_DIR, | |
375 | after[FS_NAME], after[FS_L_TYPE], after[FS_MACHINE], | |
376 | after[FS_PACK], after[FS_OWNER], after[FS_OWNERS]); | |
d43ba793 | 377 | do_cmd(cmd); |
378 | return; | |
f633445d | 379 | } |
60c22e5f | 380 | |
381 | /* What do we do? When do we use FS_CREATE? | |
382 | * | |
383 | * TYPE change: AFS->ERR, ERR->AFS: rename/unmount/remount | |
384 | * LOCKERTYPE change: rename/remount | |
385 | * PACK change: remount | |
386 | * LABEL change: rename/remount | |
387 | * Deletion: rename/unmount | |
388 | */ | |
fb8809f4 | 389 | } |
390 | ||
391 | ||
392 | do_quota(before, beforec, after, afterc) | |
393 | char **before; | |
394 | int beforec; | |
395 | char **after; | |
396 | int afterc; | |
397 | { | |
60c22e5f | 398 | char cmd[1024]; |
fb8809f4 | 399 | |
1f377b55 | 400 | if (afterc < Q_DIRECTORY || strcmp("ANY", after[Q_TYPE]) || |
60c22e5f | 401 | strncmp("/afs/", after[Q_DIRECTORY], 5)) |
402 | return; | |
1f377b55 | 403 | |
60c22e5f | 404 | sprintf(cmd, "%s/perl -I%s %s/afs_quota.pl %s %s", |
405 | BIN_DIR, BIN_DIR, BIN_DIR, | |
1f377b55 | 406 | after[Q_DIRECTORY], after[Q_QUOTA]); |
407 | do_cmd(cmd); | |
408 | return; | |
fb8809f4 | 409 | } |