]> andersk Git - moira.git/blob - incremental/afs.c
Backed out the "whoami" change that tried printing only the last component
[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     int agid, bgid;
184     long code, id;
185     char hostname[64];
186     char g1[PR_MAXNAMELEN], g2[PR_MAXNAMELEN];
187     char *av[2];
188
189     agid = bgid = 0;
190     if (beforec > L_GID && atoi(before[L_ACTIVE]) && atoi(before[L_GROUP]))
191         bgid = atoi(before[L_GID]);
192     if (afterc > L_GID && atoi(after[L_ACTIVE]) && atoi(after[L_GROUP]))
193         agid = atoi(after[L_GID]);
194
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));
204         return;
205     }
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]);
213         code = pr_ChangeEntry(g1, g2, (agid==bgid) ? 0 : -agid, "");
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         }
220         return;
221     }
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         }
229         return;
230     }
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",
240                            after[L_NAME], id, error_message(code));
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
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;
262     }
263 }
264
265
266 do_member(before, beforec, after, afterc)
267 char **before;
268 int beforec;
269 char **after;
270 int afterc;
271 {
272     int code;
273     char *p;
274     
275     if ((beforec < 4 || !atoi(before[LM_END])) &&
276         (afterc < 4 || !atoi(after[LM_END])))
277         return;
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));
283         return;
284     }
285
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;
324     static char local_realm[REALM_SZ+1] = "";
325     extern long pr_AddToGroup(), pr_RemoveUserFromGroup();
326
327     fn = op ? pr_AddToGroup : pr_RemoveUserFromGroup;
328     
329     /* The following KERBEROS code allows for the use of entities
330      * user@foreign_cell.
331      */
332     if (!local_realm[0])
333         krb_get_lrealm(local_realm, 1);
334     if (!strcmp(type, "KERBEROS")) {
335         p = index(member, '@');
336         if (p && !strcasecmp(p+1, local_realm))
337             *p = 0;
338     } else if (strcmp(type, "USER"))
339         return;                                 /* invalid type */
340
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) {
348             critical_alert("incremental",
349                            "Couldn't %s %s %s %s: %s",
350                            op ? "add" : "remove", member,
351                            op ? "to" : "from", buf,
352                            error_message(code));
353         }
354     }
355     if (p) *p = '@';
356 }
357
358
359 do_filesys(before, beforec, after, afterc)
360 char **before;
361 int beforec;
362 char **after;
363 int afterc;
364 {
365     char cmd[1024];
366     
367     if (beforec < FS_CREATE) {
368         if (afterc < FS_CREATE || atoi(after[FS_CREATE])==0 ||
369             strcmp(after[FS_TYPE], "AFS"))
370             return;
371
372         /* new locker creation */
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]);
377         do_cmd(cmd);
378         return;
379     }
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      */
389 }
390
391
392 do_quota(before, beforec, after, afterc)
393 char **before;
394 int beforec;
395 char **after;
396 int afterc;
397 {
398     char cmd[1024];
399
400     if (afterc < Q_DIRECTORY || strcmp("ANY", after[Q_TYPE]) ||
401         strncmp("/afs/", after[Q_DIRECTORY], 5))
402         return;
403
404     sprintf(cmd, "%s/perl -I%s %s/afs_quota.pl %s %s",
405             BIN_DIR, BIN_DIR, BIN_DIR,
406             after[Q_DIRECTORY], after[Q_QUOTA]);
407     do_cmd(cmd);
408     return;
409 }
This page took 0.067776 seconds and 5 git commands to generate.