]> andersk Git - moira.git/blobdiff - incremental/afs.c
Preserve hidden status of groups
[moira.git] / incremental / afs.c
index b294fccce18ed97fdc5d787837f925e3ab849bb0..b38347bc023e5eb4eeae80b34ef5a63078b11073 100644 (file)
@@ -2,23 +2,28 @@
  *
  * Do AFS incremental updates
  *
- * Copyright (C) 1989 by the Massachusetts Institute of Technology
+ * Copyright (C) 1989,1992 by the Massachusetts Institute of Technology
  * for copying and distribution information, please see the file
  * <mit-copyright.h>.
  */
 
-#include <sms.h>
-#include <sms_app.h>
-#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <strings.h>
+
 #include <krb.h>
-#include <krb_et.h>
-#include <afs/auth.h>
-#include <pwd.h>
+#include <moira.h>
+#include <moira_site.h>
+
+#include <afs/param.h>
+#include <afs/cellconfig.h>
+#include <afs/venus.h>
+#include <afs/ptclient.h>
+#include <afs/pterror.h>
 
-#define LOCALCELL "sms_test.mit.edu"
-#define PRS    "/u1/sms/bin/prs"
-#define FS     "/u1/sms/bin/fs"
+#define STOP_FILE "/moira/afs/noafs"
 
+#define file_exists(file) (access((file), F_OK) == 0)
 
 char *whoami;
 
@@ -26,8 +31,12 @@ main(argc, argv)
 char **argv;
 int argc;
 {
-    int beforec, afterc;
+    int beforec, afterc, i;
     char *table, **before, **after;
+    char buf[1024];
+
+    for (i = getdtablesize() - 1; i > 2; i--)
+      close(i);
 
     table = argv[1];
     beforec = atoi(argv[2]);
@@ -36,9 +45,36 @@ int argc;
     after = &argv[4 + beforec];
     whoami = argv[0];
 
+    strcpy(buf, table);
+    strcat(buf, " (");
+    for (i = 0; i < beforec; i++) {
+       if (i > 0)
+         strcat(buf, ",");
+       strcat(buf, before[i]);
+    }
+    strcat(buf, ")->(");
+    for (i = 0; i < afterc; i++) {
+       if (i > 0)
+         strcat(buf, ",");
+       strcat(buf, after[i]);
+    }
+#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")) {
@@ -47,10 +83,9 @@ int argc;
        do_member(before, beforec, after, afterc);
     } else if (!strcmp(table, "filesys")) {
        do_filesys(before, beforec, after, afterc);
-    } else if (!strcmp(table, "nfsquota")) {
+    } else if (!strcmp(table, "quota")) {
        do_quota(before, beforec, after, afterc);
     }
-    unlog();
     exit(0);
 }
 
@@ -58,42 +93,17 @@ int argc;
 do_cmd(cmd)
 char *cmd;
 {
-    char realm[REALM_SZ + 1];
-    static int inited = 0;
     int success = 0, tries = 0;
-    CREDENTIALS *c, *get_ticket();
-    struct passwd *pw;
-    char buf[128];
-
-    while (success == 0 && tries < 3) {
-       if (!inited) {
-           if (krb_get_lrealm(realm) != KSUCCESS)
-             (void) strcpy(realm, KRB_REALM);
-           sprintf(buf, "/tmp/tkt_%d_afsinc", getpid());
-           krb_set_tkt_string(buf);
-           
-           if (((pw = getpwnam("smsdba")) == NULL) ||
-               ((c = get_ticket("sms", "", realm, LOCALCELL)) == NULL) ||
-               (setpag() < 0) ||
-               (setreuid(pw->pw_uid, pw->pw_uid) < 0) ||
-               aklog(c, LOCALCELL)) {
-               com_err(whoami, 0, "failed to authenticate");
-           } else
-             inited++;
-       }
 
-       if (inited) {
-           com_err(whoami, 0, "Executing command: %s", cmd);
-           if (system(cmd) == 0)
-             success++;
-       }
-       if (!success) {
-           tries++;
-           sleep(5 * 60);
-       }
+    while (success == 0 && tries < 1) {
+       if (tries++)
+           sleep(5*60);
+       com_err(whoami, 0, "Executing command: %s", cmd);
+       if (system(cmd) == 0)
+           success++;
     }
     if (!success)
-      critical_alert("incremental", "failed command: %s", cmd);
+       critical_alert("incremental", "failed command: %s", cmd);
 }
 
 
@@ -103,39 +113,62 @@ int beforec;
 char **after;
 int afterc;
 {
-    int bstate, astate;
-    char cmd[512];
-
-    cmd[0] = bstate = astate = 0;
-    if (afterc > U_STATE)
-      astate = atoi(after[U_STATE]);
-    if (beforec > U_STATE)
-      bstate = atoi(before[U_STATE]);
-
-    if (astate != 1 && bstate != 1)
-      return;
-    if (astate == 1 && bstate != 1) {
-       sprintf(cmd, "%s newuser -name %s -id %s -cell %s",
-               PRS, after[U_NAME], after[U_UID], LOCALCELL);
-       do_cmd(cmd);
+    int astate, bstate, auid, buid, code;
+
+    auid = buid = astate = bstate = 0;
+    if (afterc > U_STATE) astate = atoi(after[U_STATE]);
+    if (beforec > U_STATE) bstate = atoi(before[U_STATE]);
+    if (afterc > U_UID) auid = atoi(after[U_UID]);
+    if (beforec > U_UID) buid = atoi(before[U_UID]);
+
+    /* We consider "half-registered" users to be active */
+    if (astate == 2) astate = 1;
+    if (bstate == 2) bstate = 1;
+
+    if (astate != 1 && bstate != 1)            /* inactive user */
        return;
-    } else if (astate != 1 && bstate == 1) {
-       sprintf(cmd, "%s delete %s -cell %s", PRS, before[U_NAME], LOCALCELL);
-       do_cmd(cmd);
+
+    if (astate == bstate && auid == buid && 
+       !strcmp(before[U_NAME], after[U_NAME]))
+       /* No AFS related attributes have changed */
        return;
-    }
 
-    if (beforec > U_UID && afterc > U_UID &&
-       strcmp(before[U_UID], after[U_UID])) {
-       /* change UID, & possibly user name here */
-       exit(1);
+    code=pr_Initialize(1, AFSCONF_CLIENTNAME, 0);
+    if (code) {
+       critical_alert("incremental", "Couldn't initialize libprot: %s",
+                      error_message(code));
+       return;
     }
-
-    if (beforec > U_NAME && afterc > U_NAME &&
-       strcmp(before[U_NAME], after[U_NAME])) {
-       sprintf(cmd, "%s chname -oldname %s -newname %s -cell %s",
-               PRS, before[U_NAME], after[U_NAME], LOCALCELL);
-       do_cmd(cmd);
+    
+    if (astate == bstate) {
+       /* Only a modify has to be done */
+       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",
+                          before[U_NAME], buid, after[U_NAME], auid,
+                          error_message(code));
+       }
+       return;
+    }
+    if (bstate == 1) {
+       code = pr_DeleteByID(buid);
+       if (code && code != PRNOENT) {
+           critical_alert("incremental",
+                          "Couldn't delete user %s (id %d): %s",
+                          before[U_NAME], buid, error_message(code));
+       }
+       return;
+    }
+    if (astate == 1) {
+       code = pr_CreateUser(after[U_NAME], &auid);
+       if (code) {
+           critical_alert("incremental",
+                          "Couldn't create user %s (id %d): %s",
+                          after[U_NAME], auid, error_message(code));
+       }
+       return;
     }
 }
 
@@ -147,34 +180,111 @@ int beforec;
 char **after;
 int afterc;
 {
-    char cmd[512];
-    int agid, bgid;
-
-    cmd[0] = agid = bgid = 0;
-    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]))
-      agid = atoi(after[L_GID]);
-
-    if (bgid == 0 && agid != 0) {
-       sprintf(cmd, "%s create -name system:%s -id %s -cell %s",
-               PRS, after[L_NAME], after[L_GID], LOCALCELL);
-       do_cmd(cmd);
+    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])) {
+       bgid = atoi(before[L_GID]);
+       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;
+
+    code=pr_Initialize(1, AFSCONF_CLIENTNAME, 0);
+    if (code) {
+       critical_alert("incremental", "Couldn't initialize libprot: %s",
+                      error_message(code));
        return;
     }
-    if (agid == 0 && bgid != 0) {
-       sprintf(cmd, "%s delete -name system:%s -cell %s",
-               PRS, before[L_NAME], LOCALCELL);
-       do_cmd(cmd);
+
+    if (agid && bgid) {
+       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 (agid == 0 && bgid == 0)
-      return;
-    if (strcmp(before[L_NAME], after[L_NAME])) {
-       sprintf(cmd,
-               "%s chname -oldname system:%s -newname system:%s -cell %s",
-               PRS, before[L_NAME], after[L_NAME], LOCALCELL);
-       do_cmd(cmd);
+    if (bgid) {
+       code = pr_DeleteByID(-bgid);
+       if (code && code != PRNOENT) {
+           critical_alert("incremental",
+                          "Couldn't delete group %s (id %d): %s",
+                          before[L_NAME], -bgid, error_message(code));
+       }
+       return;
+    }
+    if (agid) {
+       strcpy(g1, "system:");
+       strcat(g1, after[L_NAME]);
+       strcpy(g2, "system:administrators");
+       id = -agid;
+       code = pr_CreateGroup(g1, g2, &id);
+       if (code) {
+           critical_alert("incremental",
+                          "Couldn't create group %s (id %d): %s",
+                          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;
+
+       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;
     }
 }
@@ -186,107 +296,141 @@ int beforec;
 char **after;
 int afterc;
 {
-    char cmd[512];
+    int code;
+    char *p;
+    
+    if ((beforec < 4 || !atoi(before[LM_END])) &&
+       (afterc < 4 || !atoi(after[LM_END])))
+       return;
 
-    if (beforec == 0 && !strcmp(after[LM_TYPE], "USER")) {
-       sprintf(cmd, "%s add -user %s -group system:%s -cell %s",
-               PRS, after[LM_MEMBER], after[LM_LIST], LOCALCELL);
-       do_cmd(cmd);
+    code=pr_Initialize(1, AFSCONF_CLIENTNAME, 0);
+    if (code) {
+       critical_alert("incremental", "Couldn't initialize libprot: %s",
+                      error_message(code));
        return;
     }
-    if (afterc == 0 && !strcmp(before[LM_TYPE], "USER")) {
-       sprintf(cmd, "%s delete -user %s -group system:%s -cell %s",
-               PRS, before[LM_MEMBER], before[LM_LIST], LOCALCELL);
-       do_cmd(cmd);
-       return;
+
+    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]);
+}
+
+
+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;
 }
 
 
-do_filesys(before, beforec, after, afterc)
-char **before;
-int beforec;
-char **after;
-int afterc;
+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 %s %s %s %s: %s",
+                          op ? "add" : "remove", member,
+                          op ? "to" : "from", buf,
+                          error_message(code));
+       }
+    }
+    if (p) *p = '@';
 }
 
 
-do_quota(before, beforec, after, afterc)
+do_filesys(before, beforec, after, afterc)
 char **before;
 int beforec;
 char **after;
 int afterc;
 {
-    char cmd[512];
-
-    if (!(afterc >= Q_DIRECTORY && !strncmp("/afs", after[Q_DIRECTORY], 4)) &&
-       !(beforec >= Q_DIRECTORY && !strncmp("/afs", before[Q_DIRECTORY], 4)))
-      return;
-    if (afterc >= Q_LOGIN && strcmp("[nobody]", after[Q_LOGIN]))
-      return;
-    if (afterc != 0) {
-       sprintf(cmd, "%s setquota -dir %s -quota %s",
-               FS, after[Q_DIRECTORY], after[Q_QUOTA]);
+    char cmd[1024];
+    
+    if (beforec < FS_CREATE) {
+       if (afterc < FS_CREATE || atoi(after[FS_CREATE])==0 ||
+           strcmp(after[FS_TYPE], "AFS"))
+           return;
+
+       /* new locker creation */
+       sprintf(cmd, "%s/perl -I%s %s/afs_create.pl %s %s %s %s %s %s",
+               BIN_DIR, BIN_DIR, BIN_DIR,
+               after[FS_NAME], after[FS_L_TYPE], after[FS_MACHINE],
+               after[FS_PACK], after[FS_OWNER], after[FS_OWNERS]);
        do_cmd(cmd);
        return;
     }
-}
-
 
-CREDENTIALS *get_ticket(name, instance, realm, cell)
-char *name;
-char *instance;
-char *realm;
-char *cell;
-{
-    static CREDENTIALS c;
-    int status;
-
-    status = krb_get_svc_in_tkt(name, instance, realm,
-                               "krbtgt", realm, 1, KEYFILE);
-    if (status != 0) {
-       com_err(whoami, status+ERROR_TABLE_BASE_krb, "getting initial ticket from srvtab");
-       return(NULL);
-    }
-    status = krb_get_cred("afs", cell, realm, &c);
-    if (status != 0) {
-       status = get_ad_tkt("afs", cell, realm, 255);
-       if (status == 0)
-         status = krb_get_cred("afs", cell, realm, &c);
-    }
-    if (status != 0) {
-       com_err(whoami, status+ERROR_TABLE_BASE_krb, "getting service ticket");
-       return(NULL);
-    }
-    return(&c);
+    /* What do we do?  When do we use FS_CREATE?
+     * 
+     * TYPE change:  AFS->ERR, ERR->AFS: rename/unmount/remount
+     * LOCKERTYPE change: rename/remount
+     * PACK change: remount
+     * LABEL change: rename/remount
+     * Deletion: rename/unmount
+     */
 }
 
 
-aklog(c, cell)
-CREDENTIALS *c;
-char *cell;
+do_quota(before, beforec, after, afterc)
+char **before;
+int beforec;
+char **after;
+int afterc;
 {
-       struct ktc_principal aserver;
-       struct ktc_token atoken;
-       
-       atoken.kvno = c->kvno;
-       strcpy(aserver.name, "afs");
-       strcpy(aserver.instance, "");
-       strcpy(aserver.cell, cell);
-
-       atoken.startTime = c->issue_date;
-       atoken.endTime = c->issue_date + (c->lifetime * 5 * 60);
-       bcopy (c->session, &atoken.sessionKey, 8);
-       atoken.ticketLen = c->ticket_st.length;
-       bcopy (c->ticket_st.dat, atoken.ticket, atoken.ticketLen);
-       
-       return(ktc_SetToken(&aserver, &atoken, NULL));
-}
+    char cmd[1024];
 
+    if (afterc < Q_DIRECTORY || strcmp("ANY", after[Q_TYPE]) ||
+       strncmp("/afs/", after[Q_DIRECTORY], 5))
+       return;
 
-unlog()
-{
-    ktc_ForgetToken("afs");
-    dest_tkt();
+    sprintf(cmd, "%s/perl -I%s %s/afs_quota.pl %s %s",
+           BIN_DIR, BIN_DIR, BIN_DIR,
+           after[Q_DIRECTORY], after[Q_QUOTA]);
+    do_cmd(cmd);
+    return;
 }
This page took 0.062189 seconds and 4 git commands to generate.