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