X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/5ecdaa1f0385c1e89a54641e8123d648420d6590..8ec23c21783e8533cf7af22edd612cebfe200916:/incremental/afs.c diff --git a/incremental/afs.c b/incremental/afs.c index 2ee887d7..b38347bc 100644 --- a/incremental/afs.c +++ b/incremental/afs.c @@ -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 * . */ -#include -#include -#include -#include -#include -#include -#include +#include #include +#include -#define file_exists(file) (access((file), F_OK) == 0) +#include +#include +#include -char prs[64], fs[64]; +#include +#include +#include +#include +#include + +#define STOP_FILE "/moira/afs/noafs" + +#define file_exists(file) (access((file), F_OK) == 0) char *whoami; @@ -26,12 +31,12 @@ main(argc, argv) char **argv; int argc; { - int beforec, afterc; + int beforec, afterc, i; char *table, **before, **after; -#ifdef DEBUG char buf[1024]; - int i; -#endif + + for (i = getdtablesize() - 1; i > 2; i--) + close(i); table = argv[1]; beforec = atoi(argv[2]); @@ -40,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, ","); @@ -53,14 +58,22 @@ 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(); - sprintf(prs, "%s/prs", BIN_DIR); - sprintf(fs, "%s/fs", BIN_DIR); + + 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); @@ -70,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); } @@ -81,56 +93,17 @@ int argc; do_cmd(cmd) char *cmd; { - char realm[REALM_SZ + 1]; - static int inited = 0; - int success = 0, tries = 0, fd, cc; - CREDENTIALS *c, *get_ticket(); - struct passwd *pw; - char buf[128], localcell[128], *p, *index(); - - 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 ((fd = open("/usr/vice/etc/ThisCell", O_RDONLY, 0)) < 0) { - critical_alert("incremental", "unable to find AFS cell"); - unlog(); - exit(1); - } - if ((cc = read(fd, localcell, sizeof(localcell))) < 0) { - critical_alert("incremental", "unable to read AFS cell"); - unlog(); - exit(1); - } - close(fd); - p = index(localcell, '\n'); - if (p) *p = 0; - - 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); - } + int success = 0, tries = 0; + + 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); } @@ -140,42 +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]); + 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) - return; - if (astate == 1 && bstate != 1) { - sprintf(cmd, "%s newuser -name %s -id %s", - prs, after[U_NAME], after[U_UID]); - do_cmd(cmd); + if (astate != 1 && bstate != 1) /* inactive user */ return; - } else if (astate != 1 && bstate == 1) { - sprintf(cmd, "%s delete %s", prs, before[U_NAME]); - 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 */ - unlog(); - 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", - prs, before[U_NAME], after[U_NAME]); - 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; } } @@ -187,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 -owner system:administrators", - prs, after[L_NAME], after[L_GID]); - 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", prs, before[L_NAME]); - 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", - prs, before[L_NAME], after[L_NAME]); - 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; } } @@ -226,116 +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", - prs, after[LM_MEMBER], after[LM_LIST]); - 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 remove -user %s -group system:%s", - prs, before[LM_MEMBER], before[LM_LIST]); - 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; { - if (afterc < FS_CREATE) - return; - if (!strcmp("AFS", after[FS_TYPE]) && - !strncmp("/afs/", after[FS_PACK], 5) && - atoi(after[FS_CREATE]) && - !file_exists(after[FS_PACK])) { - critical_alert("incremental", "unable to create locker %s", - after[FS_PACK]); + 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; }