]> andersk Git - moira.git/blobdiff - incremental/afs.c
Preserve hidden status of groups
[moira.git] / incremental / afs.c
index 118eaa24395cf6795227c2c6387f5e9ef9980db2..b38347bc023e5eb4eeae80b34ef5a63078b11073 100644 (file)
@@ -11,6 +11,7 @@
 #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;
@@ -31,9 +33,7 @@ int argc;
 {
     int beforec, afterc, i;
     char *table, **before, **after;
-#ifdef DEBUG
     char buf[1024];
-#endif
 
     for (i = getdtablesize() - 1; i > 2; i--)
       close(i);
@@ -45,8 +45,8 @@ int argc;
     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, ",");
@@ -58,13 +58,23 @@ int argc;
          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")) {
@@ -132,7 +142,8 @@ int afterc;
     
     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",
@@ -169,20 +180,25 @@ int beforec;
 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) {
@@ -192,17 +208,30 @@ int afterc;
     }
 
     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;
     }
@@ -224,17 +253,39 @@ int afterc;
        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;
     }
 }
 
@@ -259,57 +310,76 @@ int afterc;
        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 = '@';
 }
 
 
This page took 0.048169 seconds and 4 git commands to generate.