]> andersk Git - moira.git/blob - incremental/afs.c
line buffer the output
[moira.git] / incremental / afs.c
1 /* $Header$
2  *
3  * Do AFS incremental updates
4  *
5  * Copyright (C) 1989,1992 by the Massachusetts Institute of Technology
6  * for copying and distribution information, please see the file
7  * <mit-copyright.h>.
8  */
9
10 #include <sys/types.h>
11 #include <sys/file.h>
12 #include <strings.h>
13
14 #include <krb.h>
15 #include <moira.h>
16 #include <moira_site.h>
17
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>
23
24 #define STOP_FILE "/moira/afs/noafs"
25
26 #define file_exists(file) (access((file), F_OK) == 0)
27
28 char *whoami;
29
30 main(argc, argv)
31 char **argv;
32 int argc;
33 {
34     int beforec, afterc, i;
35     char *table, **before, **after;
36     char buf[1024];
37
38     for (i = getdtablesize() - 1; i > 2; i--)
39       close(i);
40
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
48     strcpy(buf, table);
49     strcat(buf, " (");
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     }
61 #ifdef DEBUG
62     printf("%s\n", buf);
63 #endif
64
65     initialize_sms_error_table();
66     initialize_krb_error_table();
67
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
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);
86     } else if (!strcmp(table, "quota")) {
87         do_quota(before, beforec, after, afterc);
88     }
89     exit(0);
90 }
91
92
93 do_cmd(cmd)
94 char *cmd;
95 {
96     int success = 0, tries = 0;
97
98     while (success == 0 && tries < 1) {
99         if (tries++)
100             sleep(5*60);
101         com_err(whoami, 0, "Executing command: %s", cmd);
102         if (system(cmd) == 0)
103             success++;
104     }
105     if (!success)
106         critical_alert("incremental", "failed command: %s", cmd);
107 }
108
109
110 do_user(before, beforec, after, afterc)
111 char **before;
112 int beforec;
113 char **after;
114 int afterc;
115 {
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 */
125     if (astate == 2) astate = 1;
126     if (bstate == 2) bstate = 1;
127
128     if (astate != 1 && bstate != 1)             /* inactive user */
129         return;
130
131     if (astate == bstate && auid == buid && 
132         !strcmp(before[U_NAME], after[U_NAME]))
133         /* No AFS related attributes have changed */
134         return;
135
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;
141     }
142     
143     if (astate == bstate) {
144         /* Only a modify has to be done */
145         code = pr_ChangeEntry(before[U_NAME], after[U_NAME],
146                               (auid==buid) ? 0 : auid, "");
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;
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 {
183     register int agid, bgid;
184     int ahide, bhide;
185     long code, id;
186     char hostname[64];
187     char g1[PR_MAXNAMELEN], g2[PR_MAXNAMELEN];
188     char *av[2];
189
190     agid = bgid = 0;
191     if (beforec > L_GID && atoi(before[L_ACTIVE]) && atoi(before[L_GROUP])) {
192         bgid = atoi(before[L_GID]);
193         bhide = atoi(before[L_HIDDEN]);
194     }
195     if (afterc > L_GID && atoi(after[L_ACTIVE]) && atoi(after[L_GROUP])) {
196         agid = atoi(after[L_GID]);
197         ahide = atoi(after[L_HIDDEN]);
198     }
199
200     if (agid == 0 && bgid == 0)                 /* Not active groups */
201         return;
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));
207         return;
208     }
209
210     if (agid && bgid) {
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,
228                  (ahide ? PRP_STATUS_ANY : PRP_GROUP_DEFAULT) >> PRIVATE_SHIFT,
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             }
235         }
236         return;
237     }
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         }
245         return;
246     }
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",
256                            after[L_NAME], id, error_message(code));
257             return;
258         }
259         if (ahide) {
260             code = pr_SetFieldsEntry
261                 (-agid, PR_SF_ALLBITS,
262                  (ahide ? PRP_STATUS_ANY : PRP_GROUP_DEFAULT) >> PRIVATE_SHIFT,
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         }
270
271         /* We need to make sure the group is properly populated */
272         if (beforec < L_ACTIVE || atoi(before[L_ACTIVE]) == 0) return;
273
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;
289     }
290 }
291
292
293 do_member(before, beforec, after, afterc)
294 char **before;
295 int beforec;
296 char **after;
297 int afterc;
298 {
299     int code;
300     char *p;
301     
302     if ((beforec < 4 || !atoi(before[LM_END])) &&
303         (afterc < 4 || !atoi(after[LM_END])))
304         return;
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));
310         return;
311     }
312
313     if (afterc) 
314         edit_group(1, after[LM_LIST], after[LM_TYPE], after[LM_MEMBER]);
315     if (beforec)
316         edit_group(0, before[LM_LIST], before[LM_TYPE], before[LM_MEMBER]);
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 {
331         code = mr_query("get_members_of_list", 1, &av[1], get_members, group);
332         if (code)
333             critical_alert("incremental",
334                            "Couldn't retrieve full membership of %s: %s",
335                            group, error_message(code));
336     }
337     return code;
338 }
339
340
341 edit_group(op, group, type, member)
342     int op;
343     char *group;
344     char *type;
345     char *member;
346 {
347     char *p = 0;
348     char buf[PR_MAXNAMELEN];
349     int (*fn)();
350     int code;
351     static char local_realm[REALM_SZ+1] = "";
352     extern long pr_AddToGroup(), pr_RemoveUserFromGroup();
353
354     fn = op ? pr_AddToGroup : pr_RemoveUserFromGroup;
355     
356     /* The following KERBEROS code allows for the use of entities
357      * user@foreign_cell.
358      */
359     if (!local_realm[0])
360         krb_get_lrealm(local_realm, 1);
361     if (!strcmp(type, "KERBEROS")) {
362         p = index(member, '@');
363         if (p && !strcasecmp(p+1, local_realm))
364             *p = 0;
365     } else if (strcmp(type, "USER"))
366         return;                                 /* invalid type */
367
368     strcpy(buf, "system:");
369     strcat(buf, group);
370     code = (*fn)(member, buf);
371     if (code) {
372         if (op==0 && code == PRNOENT) return;
373         if (op==1 && code == PRIDEXIST) return;
374         if (strcmp(type, "KERBEROS") || code != PRNOENT) {
375             critical_alert("incremental",
376                            "Couldn't %s %s %s %s: %s",
377                            op ? "add" : "remove", member,
378                            op ? "to" : "from", buf,
379                            error_message(code));
380         }
381     }
382     if (p) *p = '@';
383 }
384
385
386 do_filesys(before, beforec, after, afterc)
387 char **before;
388 int beforec;
389 char **after;
390 int afterc;
391 {
392     char cmd[1024];
393     
394     if (beforec < FS_CREATE) {
395         if (afterc < FS_CREATE || atoi(after[FS_CREATE])==0 ||
396             strcmp(after[FS_TYPE], "AFS"))
397             return;
398
399         /* new locker creation */
400         sprintf(cmd, "%s/perl -I%s %s/afs_create.pl %s %s %s %s %s %s",
401                 BIN_DIR, BIN_DIR, BIN_DIR,
402                 after[FS_NAME], after[FS_L_TYPE], after[FS_MACHINE],
403                 after[FS_PACK], after[FS_OWNER], after[FS_OWNERS]);
404         do_cmd(cmd);
405         return;
406     }
407
408     /* What do we do?  When do we use FS_CREATE?
409      * 
410      * TYPE change:  AFS->ERR, ERR->AFS: rename/unmount/remount
411      * LOCKERTYPE change: rename/remount
412      * PACK change: remount
413      * LABEL change: rename/remount
414      * Deletion: rename/unmount
415      */
416 }
417
418
419 do_quota(before, beforec, after, afterc)
420 char **before;
421 int beforec;
422 char **after;
423 int afterc;
424 {
425     char cmd[1024];
426
427     if (afterc < Q_DIRECTORY || strcmp("ANY", after[Q_TYPE]) ||
428         strncmp("/afs/", after[Q_DIRECTORY], 5))
429         return;
430
431     sprintf(cmd, "%s/perl -I%s %s/afs_quota.pl %s %s",
432             BIN_DIR, BIN_DIR, BIN_DIR,
433             after[Q_DIRECTORY], after[Q_QUOTA]);
434     do_cmd(cmd);
435     return;
436 }
This page took 0.073007 seconds and 5 git commands to generate.