X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/0f82335aa22623b7b264a598b20c51d481e6a8b1..dc1d1c52813ce1141673c90a54d7bfa62eade695:/incremental/afs.c diff --git a/incremental/afs.c b/incremental/afs.c index 4171c2a7..ac881bd5 100644 --- a/incremental/afs.c +++ b/incremental/afs.c @@ -41,7 +41,8 @@ int do_quota(); /* Support stub routines */ int run_cmd(); int add_user_lists(); -int get_members(); +int add_list_members(); +int check_user(); int edit_group(); int pr_try(); int check_afs(); @@ -57,6 +58,15 @@ extern long pr_AddToGroup(); extern long pr_RemoveUserFromGroup(); static char tbl_buf[1024]; +static struct member { + int op; + char list[33]; + char type[9]; + char member[129]; + struct member *next; +} *member_head = 0; + +static int mr_connections=0; main(argc, argv) char **argv; @@ -68,12 +78,13 @@ int argc; for (i = getdtablesize() - 1; i > 2; i--) close(i); + whoami = ((whoami = rindex(argv[0], '/')) ? whoami++ : argv[0]); + table = argv[1]; beforec = atoi(argv[2]); before = &argv[4]; afterc = atoi(argv[3]); after = &argv[4 + beforec]; - whoami = argv[0]; setlinebuf(stdout); @@ -92,7 +103,7 @@ int argc; } strcat(tbl_buf, ")"); #ifdef DEBUG - printf("%s\n", tbl_buf); + com_err(whoami, 0, "%s", tbl_buf); #endif initialize_sms_error_table(); @@ -120,7 +131,6 @@ char **after; int afterc; { int astate, bstate, auid, buid, code; - char hostname[64]; char *av[2]; auid = buid = astate = bstate = 0; @@ -143,6 +153,9 @@ int afterc; if (astate == bstate) { /* Only a modify has to be done */ + com_err(whoami, 0, "Changing user %s (uid %d) to %s (uid %d)", + before[U_NAME], buid, after[U_NAME], auid); + code = pr_try(pr_ChangeEntry, before[U_NAME], after[U_NAME], auid, ""); if (code) { critical_alert("incremental", @@ -153,6 +166,9 @@ int afterc; return; } if (bstate == 1) { + com_err(whoami, 0, "Deleting user %s (uid %d)", + before[U_NAME], buid); + code = pr_try(pr_DeleteByID, buid); if (code && code != PRNOENT) { critical_alert("incremental", @@ -162,6 +178,10 @@ int afterc; return; } if (astate == 1) { + com_err(whoami, 0, "%s user %s (uid %d)", + ((bstate != 0) ? "Reactivating" : "Creating"), + after[U_NAME], auid); + code = pr_try(pr_CreateUser, after[U_NAME], &auid); if (code) { critical_alert("incremental", @@ -172,9 +192,7 @@ int afterc; if (bstate != 0) { /* Reactivating a user; get his group list */ - gethostname(hostname, sizeof(hostname)); - code = mr_connect(hostname); - if (!code) code = mr_auth("afs.incr"); + code = moira_connect(); if (code) { critical_alert("incremental", "Error contacting Moira server to retrieve grouplist of user %s: %s", @@ -189,7 +207,7 @@ int afterc; critical_alert("incremental", "Couldn't retrieve membership of user %s: %s", after[U_NAME], error_message(code)); - mr_disconnect(); + moira_disconnect(); } return; } @@ -205,7 +223,6 @@ int afterc; register int agid, bgid; int ahide, bhide; long code, id; - char hostname[64]; char g1[PR_MAXNAMELEN], g2[PR_MAXNAMELEN]; char *av[2]; @@ -229,6 +246,10 @@ int afterc; strcpy(g2, "system:"); strcat(g1, before[L_NAME]); strcat(g2, after[L_NAME]); + + com_err(whoami, 0, "Changing group %s (gid %d) to %s (gid %d)", + before[L_NAME], bgid, after[L_NAME], agid); + code = pr_try(pr_ChangeEntry, g1, g2, -agid, ""); if (code) { critical_alert("incremental", @@ -238,6 +259,9 @@ int afterc; } } if (ahide != bhide) { + com_err(whoami, 0, "Making group %s (gid %d) %s", + after[L_NAME], agid, + (ahide ? "hidden" : "visible")); code = pr_try(pr_SetFieldsEntry, -agid, PR_SF_ALLBITS, (ahide ? PRP_STATUS_ANY : PRP_GROUP_DEFAULT) >>PRIVATE_SHIFT, 0 /*ngroups*/, 0 /*nusers*/); @@ -250,6 +274,8 @@ int afterc; return; } if (bgid) { + com_err(whoami, 0, "Deleting group %s (gid %d)", + before[L_NAME], bgid); code = pr_try(pr_DeleteByID, -bgid); if (code && code != PRNOENT) { critical_alert("incremental", @@ -263,6 +289,8 @@ int afterc; strcat(g1, after[L_NAME]); strcpy(g2, "system:administrators"); id = -agid; + com_err(whoami, 0, "Creating %s group %s (gid %d)", + (ahide ? "hidden" : "visible"), after[L_NAME], agid); code = pr_try(pr_CreateGroup, g1, g2, &id); if (code) { critical_alert("incremental", @@ -282,27 +310,37 @@ int afterc; } /* We need to make sure the group is properly populated */ - if (beforec < L_ACTIVE || atoi(before[L_ACTIVE]) == 0) return; + if (beforec < L_ACTIVE) return; - gethostname(hostname, sizeof(hostname)); - code = mr_connect(hostname); - if (!code) code = mr_auth("afs.incr"); + code = moira_connect(); 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(); + av[0] = after[L_NAME]; + code = mr_query("get_end_members_of_list", 1, av, + add_list_members, after[L_NAME]); + if (code) + critical_alert("incremental", + "Couldn't retrieve full membership of list %s: %s", + after[L_NAME], error_message(code)); + moira_disconnect(); return; } } + +#define LM_EXTRA_ACTIVE (LM_END) +#define LM_EXTRA_PUBLIC (LM_END+1) +#define LM_EXTRA_HIDDEN (LM_END+2) +#define LM_EXTRA_MAILLIST (LM_END+3) +#define LM_EXTRA_GROUP (LM_END+4) +#define LM_EXTRA_GID (LM_END+5) +#define LM_EXTRA_END (LM_END+6) + do_member(before, beforec, after, afterc) char **before; int beforec; @@ -311,15 +349,27 @@ int afterc; { int code; char *p; - - if ((beforec < 4 || !atoi(before[LM_END])) && - (afterc < 4 || !atoi(after[LM_END]))) - return; - if (afterc) - edit_group(1, after[LM_LIST], after[LM_TYPE], after[LM_MEMBER]); - if (beforec) + if (afterc) { + if (afterc < LM_EXTRA_END) { + return; + } else if (afterc < LM_EXTRA_END) { + if (!atoi(after[LM_EXTRA_GROUP])) return; + } else + if (!atoi(after[LM_EXTRA_ACTIVE]) && !atoi(after[LM_EXTRA_GROUP])) + return; + + edit_group(1, after[LM_LIST], after[LM_TYPE], after[LM_MEMBER]); + } else if (beforec) { + if (beforec < LM_EXTRA_END) { + return; + } else if (beforec < LM_EXTRA_END) { + if (!atoi(before[LM_EXTRA_GROUP])) return; + } else + if (!atoi(before[LM_EXTRA_ACTIVE]) && !atoi(before[LM_EXTRA_GROUP])) + return; edit_group(0, before[LM_LIST], before[LM_TYPE], before[LM_MEMBER]); + } } @@ -439,29 +489,29 @@ add_user_lists(ac, av, user) char *av[]; char *user; { - if (atoi(av[5])) - edit_group(1, av[0], "USER", user); + if (atoi(av[L_ACTIVE]) && atoi(av[L_GROUP])) /* active group ? */ + edit_group(1, av[L_NAME], "USER", user); + return 0; } -get_members(ac, av, group) +add_list_members(ac, av, group) int ac; char *av[]; char *group; { - int code=0; + edit_group(1, group, av[0], av[1]); + return 0; +} - if (strcmp(av[0], "LIST")) { - edit_group(1, group, av[0], av[1]); - } else { - code = mr_query("get_end_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; + +check_user(ac, av, ustate) + int ac; + char *av[]; + int *ustate; +{ + *ustate = atoi(av[U_STATE]); + return 0; } @@ -473,8 +523,9 @@ edit_group(op, group, type, member) { char *p = 0; char buf[PR_MAXNAMELEN]; - int code; + int code, ustate; static char local_realm[REALM_SZ+1] = ""; + struct member *m; /* The following KERBEROS code allows for the use of entities * user@foreign_cell. @@ -488,19 +539,65 @@ edit_group(op, group, type, member) } else if (strcmp(type, "USER")) return; /* invalid type */ + /* Cannot risk doing another query during a callback */ + /* We could do this simply for type USER, but eventually this may also + * dynamically add KERBEROS types to the prdb, and we will need to do + * a query to look up the uid of the null-instance user */ + if (mr_connections) { + m = (struct member *)malloc(sizeof(struct member)); + if (!m) { + critical_alert("incremental", "Out of memory"); + exit(1); + } + m->op = op; + strcpy(m->list, group); + strcpy(m->type, type); + strcpy(m->member, member); + m->next = member_head; + member_head = m; + return; + } + strcpy(buf, "system:"); strcat(buf, group); + com_err(whoami, 0, "%s %s %s group %s", + (op ? "Adding" : "Removing"), member, + (op ? "to" : "from"), group); + code = 0; code=pr_try(op ? pr_AddToGroup : pr_RemoveUserFromGroup, 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 (op==1 && code == PRIDEXIST) return; /* Already added */ + + if (code == PRNOENT) { /* Something is missing */ + if (op==0) return; /* Already deleted */ + if (!strcmp(type, "KERBEROS")) /* Special instances; ok */ + return; + + /* Check whether the member being added is an active user */ + code = moira_connect(); + if (!code) code = mr_query("get_user_by_login", 1, &member, + check_user, &ustate); + if (code) { + critical_alert("incremental", + "Error contacting Moira server to lookup user %s: %s", + member, error_message(code)); + } + + /* We don't use moira_disconnect() + * because we may already be in the routine. + */ + mr_disconnect(); + mr_connections--; + + if (!code && ustate!=1 && ustate!=2) return; /* inactive user */ + code = PRNOENT; } + + critical_alert("incremental", + "Couldn't %s %s %s %s: %s", + op ? "add" : "remove", member, + op ? "to" : "from", buf, + error_message(code)); } } @@ -517,16 +614,20 @@ long pr_try(fn, a1, a2, a3, a4, a5, a6, a7, a8) #endif check_afs(); - - if (!initd) { - code=pr_Initialize(1, AFSCONF_CLIENTNAME, 0); - if (code) { - critical_alert("incremental", "Couldn't initialize libprot: %s", - error_message(code)); - return; - } + + if (initd) { + code=pr_Initialize(0, AFSCONF_CLIENTNAME, 0); + } else { + code = 0; initd = 1; } + if (!code) code=pr_Initialize(1, AFSCONF_CLIENTNAME, 0); + if (code) { + critical_alert("incremental", "Couldn't initialize libprot: %s", + error_message(code)); + return; + } + sleep(1); /* give ptserver room */ while (code = (*fn)(a1, a2, a3, a4, a5, a6, a7, a8)) { @@ -580,3 +681,37 @@ check_afs() sleep(60); } } + + +moira_connect() +{ + static char hostname[64]; + long code; + + if (!mr_connections++) { +#ifdef DEBUG + code = mr_connect("moira"); +#else + gethostname(hostname, sizeof(hostname)); + code = mr_connect(hostname); +#endif + if (!code) code = mr_auth("afs.incr"); + return code; + } + return 0; +} + +moira_disconnect() +{ + struct member *m; + + if (!--mr_connections) { + mr_disconnect(); + while(m = member_head) { + edit_group(m->op, m->list, m->type, m->member); + member_head = m->next; + free(m); + } + } + return 0; +}