]>
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]; | |
48c9cd1f | 46 | whoami = argv[0]; |
f10e3ca2 | 47 | |
48 | strcpy(buf, table); | |
49 | strcat(buf, " ("); | |
810d12a7 | 50 | for (i = 0; i < beforec; i++) { |
51 | if (i > 0) | |
52 | strcat(buf, ","); | |
53 | strcat(buf, before[i]); | |
54 | } | |
55 | strcat(buf, ")->("); | |
56 | for (i = 0; i < afterc; i++) { | |
57 | if (i > 0) | |
58 | strcat(buf, ","); | |
59 | strcat(buf, after[i]); | |
60 | } | |
d1be2e3a | 61 | #ifdef DEBUG |
f10e3ca2 | 62 | printf("%s\n", buf); |
810d12a7 | 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 | { | |
8ec23c21 | 183 | register int agid, bgid; |
184 | int ahide, bhide; | |
60c22e5f | 185 | long code, id; |
ed9a5300 | 186 | char hostname[64]; |
60c22e5f | 187 | char g1[PR_MAXNAMELEN], g2[PR_MAXNAMELEN]; |
ed9a5300 | 188 | char *av[2]; |
fb8809f4 | 189 | |
60c22e5f | 190 | agid = bgid = 0; |
8ec23c21 | 191 | if (beforec > L_GID && atoi(before[L_ACTIVE]) && atoi(before[L_GROUP])) { |
60c22e5f | 192 | bgid = atoi(before[L_GID]); |
8ec23c21 | 193 | bhide = atoi(before[L_HIDDEN]); |
194 | } | |
195 | if (afterc > L_GID && atoi(after[L_ACTIVE]) && atoi(after[L_GROUP])) { | |
60c22e5f | 196 | agid = atoi(after[L_GID]); |
8ec23c21 | 197 | ahide = atoi(after[L_HIDDEN]); |
198 | } | |
fb8809f4 | 199 | |
60c22e5f | 200 | if (agid == 0 && bgid == 0) /* Not active groups */ |
201 | return; | |
60c22e5f | 202 | |
203 | code=pr_Initialize(1, AFSCONF_CLIENTNAME, 0); | |
204 | if (code) { | |
205 | critical_alert("incremental", "Couldn't initialize libprot: %s", | |
206 | error_message(code)); | |
fb8809f4 | 207 | return; |
208 | } | |
60c22e5f | 209 | |
210 | if (agid && bgid) { | |
8ec23c21 | 211 | if (strcmp(after[L_NAME], before[L_NAME])) { |
212 | /* Only a modify is required */ | |
213 | strcpy(g1, "system:"); | |
214 | strcpy(g2, "system:"); | |
215 | strcat(g1, before[L_NAME]); | |
216 | strcat(g2, after[L_NAME]); | |
217 | code = pr_ChangeEntry(g1, g2, (agid==bgid) ? 0 : -agid, ""); | |
218 | if (code) { | |
219 | critical_alert("incremental", | |
220 | "Couldn't change group %s (id %d) to %s (id %d): %s", | |
221 | before[L_NAME], -bgid, after[L_NAME], -agid, | |
222 | error_message(code)); | |
223 | } | |
224 | } | |
225 | if (ahide != bhide) { | |
226 | code = pr_SetFieldsEntry | |
227 | (-agid, PR_SF_ALLBITS, | |
e9f07a3b | 228 | (ahide ? PRP_STATUS_ANY : PRP_GROUP_DEFAULT) >> PRIVATE_SHIFT, |
8ec23c21 | 229 | 0 /*ngroups*/, 0 /*nusers*/); |
230 | if (code) { | |
231 | critical_alert("incremental", | |
232 | "Couldn't set flags of group %s: %s", | |
233 | after[L_NAME], error_message(code)); | |
234 | } | |
60c22e5f | 235 | } |
fb8809f4 | 236 | return; |
237 | } | |
60c22e5f | 238 | if (bgid) { |
239 | code = pr_DeleteByID(-bgid); | |
240 | if (code && code != PRNOENT) { | |
241 | critical_alert("incremental", | |
242 | "Couldn't delete group %s (id %d): %s", | |
243 | before[L_NAME], -bgid, error_message(code)); | |
244 | } | |
fb8809f4 | 245 | return; |
246 | } | |
60c22e5f | 247 | if (agid) { |
248 | strcpy(g1, "system:"); | |
249 | strcat(g1, after[L_NAME]); | |
250 | strcpy(g2, "system:administrators"); | |
251 | id = -agid; | |
252 | code = pr_CreateGroup(g1, g2, &id); | |
253 | if (code) { | |
254 | critical_alert("incremental", | |
255 | "Couldn't create group %s (id %d): %s", | |
ed9a5300 | 256 | after[L_NAME], id, error_message(code)); |
60c22e5f | 257 | return; |
258 | } | |
8ec23c21 | 259 | if (ahide) { |
260 | code = pr_SetFieldsEntry | |
261 | (-agid, PR_SF_ALLBITS, | |
e9f07a3b | 262 | (ahide ? PRP_STATUS_ANY : PRP_GROUP_DEFAULT) >> PRIVATE_SHIFT, |
8ec23c21 | 263 | 0 /*ngroups*/, 0 /*nusers*/); |
264 | if (code) { | |
265 | critical_alert("incremental", | |
266 | "Couldn't set flags of group %s: %s", | |
267 | after[L_NAME], error_message(code)); | |
268 | } | |
269 | } | |
60c22e5f | 270 | |
271 | /* We need to make sure the group is properly populated */ | |
272 | if (beforec < L_ACTIVE || atoi(before[L_ACTIVE]) == 0) return; | |
273 | ||
ed9a5300 | 274 | gethostname(hostname, sizeof(hostname)); |
275 | code = mr_connect(hostname); | |
276 | if (!code) code = mr_auth("afs.incr"); | |
277 | if (code) { | |
278 | critical_alert("incremental", | |
279 | "Error contacting Moira server to resolve %s: %s", | |
280 | after[L_NAME], error_message(code)); | |
281 | return; | |
282 | } | |
283 | av[0] = "LIST"; | |
284 | av[1] = after[L_NAME]; | |
285 | get_members(2, av, after[L_NAME]); | |
286 | ||
287 | mr_disconnect(); | |
288 | return; | |
60c22e5f | 289 | } |
fb8809f4 | 290 | } |
291 | ||
292 | ||
293 | do_member(before, beforec, after, afterc) | |
294 | char **before; | |
295 | int beforec; | |
296 | char **after; | |
297 | int afterc; | |
298 | { | |
60c22e5f | 299 | int code; |
300 | char *p; | |
301 | ||
bd70a79d | 302 | if ((beforec < 4 || !atoi(before[LM_END])) && |
303 | (afterc < 4 || !atoi(after[LM_END]))) | |
fb8809f4 | 304 | return; |
60c22e5f | 305 | |
306 | code=pr_Initialize(1, AFSCONF_CLIENTNAME, 0); | |
307 | if (code) { | |
308 | critical_alert("incremental", "Couldn't initialize libprot: %s", | |
309 | error_message(code)); | |
fb8809f4 | 310 | return; |
311 | } | |
60c22e5f | 312 | |
ed9a5300 | 313 | if (afterc) |
314 | edit_group(1, after[LM_LIST], after[LM_TYPE], after[LM_MEMBER]); | |
315 | if (beforec) | |
e9f07a3b | 316 | edit_group(0, before[LM_LIST], before[LM_TYPE], before[LM_MEMBER]); |
ed9a5300 | 317 | } |
318 | ||
319 | ||
320 | get_members(ac, av, group) | |
321 | int ac; | |
322 | char *av[]; | |
323 | char *group; | |
324 | { | |
325 | int code=0; | |
326 | ||
327 | if (strcmp(av[0], "LIST")) { | |
328 | sleep(1); /* give the ptserver room */ | |
329 | edit_group(1, group, av[0], av[1]); | |
330 | } else { | |
cdd40d28 | 331 | code = mr_query("get_end_members_of_list", 1, &av[1], |
332 | get_members, group); | |
ed9a5300 | 333 | if (code) |
334 | critical_alert("incremental", | |
335 | "Couldn't retrieve full membership of %s: %s", | |
336 | group, error_message(code)); | |
337 | } | |
338 | return code; | |
339 | } | |
340 | ||
341 | ||
342 | edit_group(op, group, type, member) | |
343 | int op; | |
344 | char *group; | |
345 | char *type; | |
346 | char *member; | |
347 | { | |
348 | char *p = 0; | |
349 | char buf[PR_MAXNAMELEN]; | |
350 | int (*fn)(); | |
351 | int code; | |
d1be2e3a | 352 | static char local_realm[REALM_SZ+1] = ""; |
ed9a5300 | 353 | extern long pr_AddToGroup(), pr_RemoveUserFromGroup(); |
354 | ||
355 | fn = op ? pr_AddToGroup : pr_RemoveUserFromGroup; | |
356 | ||
60c22e5f | 357 | /* The following KERBEROS code allows for the use of entities |
358 | * user@foreign_cell. | |
359 | */ | |
d1be2e3a | 360 | if (!local_realm[0]) |
361 | krb_get_lrealm(local_realm, 1); | |
ed9a5300 | 362 | if (!strcmp(type, "KERBEROS")) { |
363 | p = index(member, '@'); | |
d1be2e3a | 364 | if (p && !strcasecmp(p+1, local_realm)) |
60c22e5f | 365 | *p = 0; |
ed9a5300 | 366 | } else if (strcmp(type, "USER")) |
367 | return; /* invalid type */ | |
60c22e5f | 368 | |
ed9a5300 | 369 | strcpy(buf, "system:"); |
370 | strcat(buf, group); | |
371 | code = (*fn)(member, buf); | |
372 | if (code) { | |
373 | if (op==0 && code == PRNOENT) return; | |
374 | if (op==1 && code == PRIDEXIST) return; | |
375 | if (strcmp(type, "KERBEROS") || code != PRNOENT) { | |
60c22e5f | 376 | critical_alert("incremental", |
ed9a5300 | 377 | "Couldn't %s %s %s %s: %s", |
378 | op ? "add" : "remove", member, | |
379 | op ? "to" : "from", buf, | |
60c22e5f | 380 | error_message(code)); |
60c22e5f | 381 | } |
57bc9f26 | 382 | } |
ed9a5300 | 383 | if (p) *p = '@'; |
fb8809f4 | 384 | } |
385 | ||
386 | ||
387 | do_filesys(before, beforec, after, afterc) | |
388 | char **before; | |
389 | int beforec; | |
390 | char **after; | |
391 | int afterc; | |
392 | { | |
60c22e5f | 393 | char cmd[1024]; |
394 | ||
d43ba793 | 395 | if (beforec < FS_CREATE) { |
60c22e5f | 396 | if (afterc < FS_CREATE || atoi(after[FS_CREATE])==0 || |
397 | strcmp(after[FS_TYPE], "AFS")) | |
398 | return; | |
399 | ||
d43ba793 | 400 | /* new locker creation */ |
60c22e5f | 401 | sprintf(cmd, "%s/perl -I%s %s/afs_create.pl %s %s %s %s %s %s", |
402 | BIN_DIR, BIN_DIR, BIN_DIR, | |
403 | after[FS_NAME], after[FS_L_TYPE], after[FS_MACHINE], | |
404 | after[FS_PACK], after[FS_OWNER], after[FS_OWNERS]); | |
d43ba793 | 405 | do_cmd(cmd); |
406 | return; | |
f633445d | 407 | } |
60c22e5f | 408 | |
409 | /* What do we do? When do we use FS_CREATE? | |
410 | * | |
411 | * TYPE change: AFS->ERR, ERR->AFS: rename/unmount/remount | |
412 | * LOCKERTYPE change: rename/remount | |
413 | * PACK change: remount | |
414 | * LABEL change: rename/remount | |
415 | * Deletion: rename/unmount | |
416 | */ | |
9b9540a1 | 417 | if (afterc < FS_CREATE) { |
418 | if (!strcmp(before[FS_TYPE], "AFS")) | |
419 | critical_alert("incremental", | |
420 | "Could not delete AFS filesystem %s: Operation not supported\n", | |
421 | before[FS_NAME]); | |
422 | return; | |
423 | } | |
424 | ||
425 | if (!strcmp(after[FS_TYPE], "AFS")) { | |
426 | if (strcmp(before[FS_TYPE], "AFS")) { | |
427 | critical_alert("incremental", | |
428 | "Cannot convert %s to an AFS filesystem: Operation not supported\n", | |
429 | after[FS_NAME]); | |
430 | } else { | |
431 | critical_alert("incremental", | |
432 | "Cannot change attributes of AFS filesystem %s: Operation not supported\n", | |
433 | after[FS_NAME]); | |
434 | } | |
435 | return; | |
436 | } | |
fb8809f4 | 437 | } |
438 | ||
439 | ||
440 | do_quota(before, beforec, after, afterc) | |
441 | char **before; | |
442 | int beforec; | |
443 | char **after; | |
444 | int afterc; | |
445 | { | |
60c22e5f | 446 | char cmd[1024]; |
fb8809f4 | 447 | |
1f377b55 | 448 | if (afterc < Q_DIRECTORY || strcmp("ANY", after[Q_TYPE]) || |
60c22e5f | 449 | strncmp("/afs/", after[Q_DIRECTORY], 5)) |
450 | return; | |
1f377b55 | 451 | |
60c22e5f | 452 | sprintf(cmd, "%s/perl -I%s %s/afs_quota.pl %s %s", |
453 | BIN_DIR, BIN_DIR, BIN_DIR, | |
1f377b55 | 454 | after[Q_DIRECTORY], after[Q_QUOTA]); |
455 | do_cmd(cmd); | |
456 | return; | |
fb8809f4 | 457 | } |