]> andersk Git - moira.git/blob - incremental/afs.c
added addusr
[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_end_members_of_list", 1, &av[1],
332                         get_members, group);
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;
352     static char local_realm[REALM_SZ+1] = "";
353     extern long pr_AddToGroup(), pr_RemoveUserFromGroup();
354
355     fn = op ? pr_AddToGroup : pr_RemoveUserFromGroup;
356     
357     /* The following KERBEROS code allows for the use of entities
358      * user@foreign_cell.
359      */
360     if (!local_realm[0])
361         krb_get_lrealm(local_realm, 1);
362     if (!strcmp(type, "KERBEROS")) {
363         p = index(member, '@');
364         if (p && !strcasecmp(p+1, local_realm))
365             *p = 0;
366     } else if (strcmp(type, "USER"))
367         return;                                 /* invalid type */
368
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) {
376             critical_alert("incremental",
377                            "Couldn't %s %s %s %s: %s",
378                            op ? "add" : "remove", member,
379                            op ? "to" : "from", buf,
380                            error_message(code));
381         }
382     }
383     if (p) *p = '@';
384 }
385
386
387 do_filesys(before, beforec, after, afterc)
388 char **before;
389 int beforec;
390 char **after;
391 int afterc;
392 {
393     char cmd[1024];
394     
395     if (beforec < FS_CREATE) {
396         if (afterc < FS_CREATE || atoi(after[FS_CREATE])==0 ||
397             strcmp(after[FS_TYPE], "AFS"))
398             return;
399
400         /* new locker creation */
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]);
405         do_cmd(cmd);
406         return;
407     }
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      */
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     }
437 }
438
439
440 do_quota(before, beforec, after, afterc)
441 char **before;
442 int beforec;
443 char **after;
444 int afterc;
445 {
446     char cmd[1024];
447
448     if (afterc < Q_DIRECTORY || strcmp("ANY", after[Q_TYPE]) ||
449         strncmp("/afs/", after[Q_DIRECTORY], 5))
450         return;
451
452     sprintf(cmd, "%s/perl -I%s %s/afs_quota.pl %s %s",
453             BIN_DIR, BIN_DIR, BIN_DIR,
454             after[Q_DIRECTORY], after[Q_QUOTA]);
455     do_cmd(cmd);
456     return;
457 }
This page took 0.094151 seconds and 5 git commands to generate.