#include <sys/file.h>
#include <strings.h>
+#include <krb.h>
#include <moira.h>
#include <moira_site.h>
#include <afs/ptclient.h>
#include <afs/pterror.h>
+#define STOP_FILE "/moira/afs/noafs"
+
#define file_exists(file) (access((file), F_OK) == 0)
char *whoami;
-char *cellname = "ATHENA.MIT.EDU";
main(argc, argv)
char **argv;
{
int beforec, afterc, i;
char *table, **before, **after;
-#ifdef DEBUG
char buf[1024];
-#endif
for (i = getdtablesize() - 1; i > 2; i--)
close(i);
after = &argv[4 + beforec];
whoami = argv[0];
-#ifdef DEBUG
- sprintf(buf, "%s (", table);
+ strcpy(buf, table);
+ strcat(buf, " (");
for (i = 0; i < beforec; i++) {
if (i > 0)
strcat(buf, ",");
strcat(buf, ",");
strcat(buf, after[i]);
}
- strcat(buf, ")\n");
- write(1,buf,strlen(buf));
+#ifdef DEBUG
+ printf("%s\n", buf);
#endif
initialize_sms_error_table();
initialize_krb_error_table();
+ for (i=0; file_exists(STOP_FILE); i++) {
+ if (i > 30) {
+ critical_alert("incremental",
+ "AFS incremental failed (%s exists): %s",
+ STOP_FILE, buf);
+ exit(1);
+ }
+ sleep(60);
+ }
+
if (!strcmp(table, "users")) {
do_user(before, beforec, after, afterc);
} else if (!strcmp(table, "list")) {
if (astate == bstate) {
/* Only a modify has to be done */
- code = pr_ChangeEntry(before[U_NAME], after[U_NAME], auid, "");
+ code = pr_ChangeEntry(before[U_NAME], after[U_NAME],
+ (auid==buid) ? 0 : auid, "");
if (code) {
critical_alert("incremental",
"Couldn't change user %s (id %d) to %s (id %d): %s",
char **after;
int afterc;
{
- int agid, bgid;
+ register int agid, bgid;
+ int ahide, bhide;
long code, id;
+ char hostname[64];
char g1[PR_MAXNAMELEN], g2[PR_MAXNAMELEN];
+ char *av[2];
agid = bgid = 0;
- if (beforec > L_GID && atoi(before[L_ACTIVE]) && atoi(before[L_GROUP]))
+ if (beforec > L_GID && atoi(before[L_ACTIVE]) && atoi(before[L_GROUP])) {
bgid = atoi(before[L_GID]);
- if (afterc > L_GID && atoi(after[L_ACTIVE]) && atoi(after[L_GROUP]))
+ bhide = atoi(before[L_HIDDEN]);
+ }
+ if (afterc > L_GID && atoi(after[L_ACTIVE]) && atoi(after[L_GROUP])) {
agid = atoi(after[L_GID]);
+ ahide = atoi(after[L_HIDDEN]);
+ }
if (agid == 0 && bgid == 0) /* Not active groups */
return;
- if (agid == bgid && !strcmp(after[L_NAME], before[L_NAME]))
- return; /* No change */
code=pr_Initialize(1, AFSCONF_CLIENTNAME, 0);
if (code) {
}
if (agid && bgid) {
- /* Only a modify is required */
- strcpy(g1, "system:");
- strcpy(g2, "system:");
- strcat(g1, before[L_NAME]);
- strcat(g2, after[L_NAME]);
- code = pr_ChangeEntry(g1, g2, -agid, "");
- if (code) {
- critical_alert("incremental",
- "Couldn't change group %s (id %d) to %s (id %d): %s",
- before[L_NAME], -bgid, after[L_NAME], -agid,
- error_message(code));
+ if (strcmp(after[L_NAME], before[L_NAME])) {
+ /* Only a modify is required */
+ strcpy(g1, "system:");
+ strcpy(g2, "system:");
+ strcat(g1, before[L_NAME]);
+ strcat(g2, after[L_NAME]);
+ code = pr_ChangeEntry(g1, g2, (agid==bgid) ? 0 : -agid, "");
+ if (code) {
+ critical_alert("incremental",
+ "Couldn't change group %s (id %d) to %s (id %d): %s",
+ before[L_NAME], -bgid, after[L_NAME], -agid,
+ error_message(code));
+ }
+ }
+ if (ahide != bhide) {
+ code = pr_SetFieldsEntry
+ (-agid, PR_SF_ALLBITS,
+ (ahide ? PRP_STATUS_MEM : PRP_GROUP_DEFAULT) >> PRIVATE_SHIFT,
+ 0 /*ngroups*/, 0 /*nusers*/);
+ if (code) {
+ critical_alert("incremental",
+ "Couldn't set flags of group %s: %s",
+ after[L_NAME], error_message(code));
+ }
}
return;
}
if (code) {
critical_alert("incremental",
"Couldn't create group %s (id %d): %s",
- after[L_NAME], -agid, error_message(code));
+ after[L_NAME], id, error_message(code));
return;
}
+ if (ahide) {
+ code = pr_SetFieldsEntry
+ (-agid, PR_SF_ALLBITS,
+ (ahide ? PRP_STATUS_MEM : PRP_GROUP_DEFAULT) >> PRIVATE_SHIFT,
+ 0 /*ngroups*/, 0 /*nusers*/);
+ if (code) {
+ critical_alert("incremental",
+ "Couldn't set flags of group %s: %s",
+ after[L_NAME], error_message(code));
+ }
+ }
/* We need to make sure the group is properly populated */
if (beforec < L_ACTIVE || atoi(before[L_ACTIVE]) == 0) return;
- /* XXX - To be implemented */
- critical_alert("incremental",
- "Status change for list %s; membership may be wrong",
- after[L_NAME]);
+ gethostname(hostname, sizeof(hostname));
+ code = mr_connect(hostname);
+ if (!code) code = mr_auth("afs.incr");
+ if (code) {
+ critical_alert("incremental",
+ "Error contacting Moira server to resolve %s: %s",
+ after[L_NAME], error_message(code));
+ return;
+ }
+ av[0] = "LIST";
+ av[1] = after[L_NAME];
+ get_members(2, av, after[L_NAME]);
+
+ mr_disconnect();
+ return;
}
}
return;
}
- /* The following KERBEROS code allows for the use of entities
- * user@foreign_cell.
- */
- if (afterc && !strcmp(after[LM_TYPE], "KERBEROS")) {
- p = index(after[LM_MEMBER], '@');
- if (p && !strcasecmp(p+1, cellname))
- *p = 0;
- }
- if (beforec && !strcmp(before[LM_TYPE], "KERBEROS")) {
- p = index(before[LM_MEMBER], '@');
- if (p && !strcasecmp(p+1, cellname))
- *p = 0;
- }
+ if (afterc)
+ edit_group(1, after[LM_LIST], after[LM_TYPE], after[LM_MEMBER]);
+ if (beforec)
+ edit_group(0, after[LM_LIST], after[LM_TYPE], after[LM_MEMBER]);
+}
- if (afterc) {
- if (!strcmp(after[LM_TYPE], "KERBEROS")) {
- p = index(after[LM_MEMBER], '@');
- if (p && !strcasecmp(p+1, cellname))
- *p = 0;
- } else if (strcmp(after[LM_TYPE], "USER"))
- return; /* invalid type */
- code = pr_AddToGroup(after[LM_MEMBER], after[LM_LIST]);
- if (code) {
- if (strcmp(after[LM_TYPE], "KERBEROS") || code != PRNOENT) {
- critical_alert("incremental",
- "Couldn't add %s to %s: %s",
- after[LM_MEMBER], after[LM_LIST],
- error_message(code));
- return;
- }
- }
+get_members(ac, av, group)
+ int ac;
+ char *av[];
+ char *group;
+{
+ int code=0;
+
+ if (strcmp(av[0], "LIST")) {
+ sleep(1); /* give the ptserver room */
+ edit_group(1, group, av[0], av[1]);
+ } else {
+ code = mr_query("get_members_of_list", 1, &av[1], get_members, group);
+ if (code)
+ critical_alert("incremental",
+ "Couldn't retrieve full membership of %s: %s",
+ group, error_message(code));
}
+ return code;
+}
- if (beforec) {
- if (!strcmp(before[LM_TYPE], "KERBEROS")) {
- p = index(before[LM_MEMBER], '@');
- if (p && !strcasecmp(p+1, cellname))
- *p = 0;
- } else if (strcmp(before[LM_TYPE], "USER"))
- return; /* invalid type */
- code = pr_RemoveUserFromGroup(before[LM_MEMBER], before[LM_LIST]);
- if (code && code != PRNOENT) {
+edit_group(op, group, type, member)
+ int op;
+ char *group;
+ char *type;
+ char *member;
+{
+ char *p = 0;
+ char buf[PR_MAXNAMELEN];
+ int (*fn)();
+ int code;
+ static char local_realm[REALM_SZ+1] = "";
+ extern long pr_AddToGroup(), pr_RemoveUserFromGroup();
+
+ fn = op ? pr_AddToGroup : pr_RemoveUserFromGroup;
+
+ /* The following KERBEROS code allows for the use of entities
+ * user@foreign_cell.
+ */
+ if (!local_realm[0])
+ krb_get_lrealm(local_realm, 1);
+ if (!strcmp(type, "KERBEROS")) {
+ p = index(member, '@');
+ if (p && !strcasecmp(p+1, local_realm))
+ *p = 0;
+ } else if (strcmp(type, "USER"))
+ return; /* invalid type */
+
+ strcpy(buf, "system:");
+ strcat(buf, group);
+ code = (*fn)(member, buf);
+ if (code) {
+ if (op==0 && code == PRNOENT) return;
+ if (op==1 && code == PRIDEXIST) return;
+ if (strcmp(type, "KERBEROS") || code != PRNOENT) {
critical_alert("incremental",
- "Couldn't remove %s from %s: %s",
- before[LM_MEMBER], before[LM_LIST],
+ "Couldn't %s %s %s %s: %s",
+ op ? "add" : "remove", member,
+ op ? "to" : "from", buf,
error_message(code));
- return;
}
}
+ if (p) *p = '@';
}