|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T b
Length: 12012 (0x2eec) Types: TextFile Names: »bind.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/euug-87hel/sec8/mcp/src/bind.c«
/***************************************************************************\ * * * bind.c * * * * Herein lie most of the user interface routines to bind classes, sigs and * * groups to sendmail aliases. The idea behind the bindings is that * * accurate e-mail mailing lists can be maintained most easily be * * integrating their maintenance into the same software that creates and * * deletes accounts. * * * \***************************************************************************/ #include <stdio.h> #include <sys/types.h> #include <lastlog.h> #include "sysdep.h" #ifdef SENDMAIL #include "macros.h" #include "mem.h" #include "gpa.h" #include "lists.h" #include "account.h" #include "alias.h" #include "class.h" #include "groupmap.h" #include "sig.h" #include "sort.h" #include "save.h" extern struct list AccountList, Aliases, AliasList; extern int ModBits; bindgroup(c, v) int c; addr *v; { struct alias *al; struct account *ac; struct groupmap *gm; addr *aliasv; int cc, bound = 0; register int i, j; if (c > 2) { err1("%s: too many arguments", (char *)v[0]); return; } if (c != 2) { err1("usage: %s <group>", (char *)v[0]); return; } gm = getgmnam((char *)v[1]); if (!gm) { err1("%s: no such group", (char *)v[1]); return; } aliasv = get_gpa(17); GetLine("To-Aliases: ", 16, &cc, aliasv, &Aliases); if (cc == 0) { err("no change"); return; } for (i=0; i < cc; i++) { al = getalnam((char *)aliasv[i]); if (!al) { err1("%s: no such alias", (char *)aliasv[i]); continue; } if (instrlist(&al->al_groups, (char *)v[1])) { err2("%s: already bound to %s", (char *)v[1], al->al_name); continue; } strlistadd(&al->al_groups, (char *)v[1]); strlistadd(&gm->gm_aliases, al->al_name); sort_list(&al->al_groups, pstrcmp); sort_list(&gm->gm_aliases, pstrcmp); for (j=0; j < AccountList.l_count; j++) { ac = (struct account *) AccountList.l_list[j]; if (ac->ac_gid != gm->gm_gid && !instrlist(&ac->ac_groups, (char *)v[1])) continue; if (instrlist(&al->al_addresses, (char *)ac->ac_name)) continue; strlistadd(&al->al_addresses, (char *)ac->ac_name); sort_list(&al->al_addresses, pstrcmp); } bound++; } if (bound) { ModBits |= AL; (void) printf("%d bound\n", bound); } non_critical(); return; } bindclass(c, v) int c; addr *v; { struct alias *al; struct account *ac; struct class *cs; addr *aliasv; int cc, bound = 0; register int i, j; if (c > 2) { err1("%s: too many arguments", (char *)v[0]); return; } if (c != 2) { err1("usage: %s <class>", (char *)v[0]); return; } cs = getcsnam((char *)v[1]); if (!cs) { err1("%s: no such class", (char *)v[1]); return; } aliasv = get_gpa(17); GetLine("To-Aliases: ", 16, &cc, aliasv, &Aliases); if (cc == 0) { err("no change"); return; } for (i=0; i < cc; i++) { al = getalnam((char *)aliasv[i]); if (!al) { err1("%s: no such alias", (char *)aliasv[i]); continue; } if (instrlist(&al->al_classes, (char *)v[1])) { err2("%s: already bound to %s", (char *)v[1], al->al_name); continue; } strlistadd(&al->al_classes, (char *)v[1]); strlistadd(&cs->cs_aliases, al->al_name); sort_list(&al->al_classes, pstrcmp); sort_list(&cs->cs_aliases, pstrcmp); for (j=0; j < AccountList.l_count; j++) { ac = (struct account *) AccountList.l_list[j]; if (!instrlist(&ac->ac_classes, (char *)v[1])) continue; if (instrlist(&al->al_addresses, (char *)ac->ac_name)) continue; strlistadd(&al->al_addresses, (char *)ac->ac_name); sort_list(&al->al_addresses, pstrcmp); } bound++; } if (bound) { ModBits |= AL; (void) printf("%d bound\n", bound); } non_critical(); return; } bindsig(c, v) int c; addr *v; { struct alias *al; struct account *ac; struct sig *sg; addr *aliasv; int cc, bound = 0; register int i, j; if (c > 2) { err1("%s: too many arguments", (char *)v[0]); return; } if (c != 2) { err1("usage: %s <sig>", (char *)v[0]); return; } sg = getsgnam((char *)v[1]); if (!sg) { err1("%s: no such sig", (char *)v[1]); return; } aliasv = get_gpa(17); GetLine("To-Aliases: ", 16, &cc, aliasv, &Aliases); if (cc == 0) { err("no change"); return; } for (i=0; i < cc; i++) { al = getalnam((char *)aliasv[i]); if (!al) { err1("%s: no such alias", (char *)aliasv[i]); continue; } if (instrlist(&al->al_sigs, (char *)v[1])) { err2("%s: already bound to %s", (char *)v[1], al->al_name); continue; } strlistadd(&al->al_sigs, (char *)v[1]); strlistadd(&sg->sg_aliases, al->al_name); sort_list(&al->al_sigs, pstrcmp); sort_list(&sg->sg_aliases, pstrcmp); for (j=0; j < AccountList.l_count; j++) { ac = (struct account *) AccountList.l_list[j]; if (!instrlist(&ac->ac_sigs, (char *)v[1])) continue; if (instrlist(&al->al_addresses, (char *)ac->ac_name)) continue; strlistadd(&al->al_addresses, (char *)ac->ac_name); sort_list(&al->al_addresses, pstrcmp); } bound++; } if (bound) { ModBits |= AL; (void) printf("%d bound\n", bound); } non_critical(); return; } ubindgroup(c, v) int c; addr *v; { struct account *ac; struct alias *al; struct groupmap *gm; addr *aliasv; register int i, j; int unbound = 0, cc; if (c > 2) { err1("%s: too many arguements", (char *)v[0]); return; } if (c < 2) { err1("usage: %s <group>", (char *)v[0]); return; } gm = getgmnam((char *)v[1]); if (!gm) { err1("%s: no such group", (char *)v[1]); return; } if (gm->gm_aliases.l_count) { err1("%s: not bound to any aliases", gm->gm_name); return; } aliasv = get_gpa(17); GetLine("From-Aliases: ", 16, &cc, aliasv, &Aliases); if (cc == 0) { err("no change"); return; } critical(); for (i=0; i < cc; i++) { al = getalnam((char *)aliasv[i]); if (!al) { err1("%s: no such alias", (char *)aliasv[i]); continue; } if (!instrlist(&al->al_groups, (char *)v[1])) { err2("%s: not bound to %s", (char *)v[1], al->al_name); continue; } strlistdel(&al->al_groups, (char *)v[1]); strlistdel(&gm->gm_aliases, al->al_name); for (j=0; j < AccountList.l_count; j++) { ac = (struct account *) AccountList.l_list[j]; if (!instrlist(&al->al_addresses, (char *)ac->ac_name)) continue; if (LegalAKA(ac, al)) continue; strlistdel(&al->al_addresses, (char *)ac->ac_name); } unbound++; } if (unbound) { (void) printf("%d unbound\n", unbound); ModBits |= AL; } non_critical(); return; } ubindclass(c, v) int c; addr *v; { struct account *ac; struct alias *al; struct class *cs; addr *aliasv; register int i, j; int unbound = 0, cc; if (c > 2) { err1("%s: too many arguements", (char *)v[0]); return; } if (c < 2) { err1("usage: %s <class>", (char *)v[0]); return; } cs = getcsnam((char *)v[1]); if (!cs) { err1("%s: no such class", (char *)v[1]); return; } if (cs->cs_aliases.l_count) { err1("%s: not bound to any aliases", cs->cs_name); return; } aliasv = get_gpa(17); GetLine("From-Aliases: ", 16, &cc, aliasv, &Aliases); if (cc == 0) { err("no change"); return; } critical(); for (i=0; i < cc; i++) { al = getalnam((char *)aliasv[i]); if (!al) { err1("%s: no such alias", (char *)aliasv[i]); continue; } if (!instrlist(&al->al_classes, (char *)v[1])) { err2("%s: not bound to %s", (char *)v[1], al->al_name); continue; } strlistdel(&al->al_classes, (char *)v[1]); strlistdel(&cs->cs_aliases, al->al_name); for (j=0; j < AccountList.l_count; j++) { ac = (struct account *) AccountList.l_list[j]; if (!instrlist(&ac->ac_classes, (char *)v[1])) continue; if (!instrlist(&al->al_addresses, (char *)ac->ac_name)) continue; if (LegalAKA(ac, al)) continue; strlistdel(&al->al_addresses, (char *)ac->ac_name); } unbound++; } if (unbound) { (void) printf("%d unbound\n", unbound); ModBits |= AL; } non_critical(); return; } ubindsig(c, v) int c; addr *v; { struct account *ac; struct alias *al; struct sig *sg; addr *aliasv; register int i, j; int unbound = 0, cc; if (c > 2) { err1("%s: too many arguements", (char *)v[0]); return; } if (c < 2) { err1("usage: %s <sig>", (char *)v[0]); return; } sg = getsgnam((char *)v[1]); if (!sg) { err1("%s: no such sig", (char *)v[1]); return; } if (sg->sg_aliases.l_count) { err1("%s: not bound to any aliases", sg->sg_name); return; } aliasv = get_gpa(17); GetLine("From-Aliases: ", 16, &cc, aliasv, &Aliases); if (cc == 0) { err("no change"); return; } critical(); for (i=0; i < cc; i++) { al = getalnam((char *)aliasv[i]); if (!al) { err1("%s: no such alias", (char *)aliasv[i]); continue; } if (!instrlist(&al->al_sigs, (char *)v[1])) { err2("%s: not bound to %s", (char *)v[1], al->al_name); continue; } strlistdel(&al->al_sigs, (char *)v[1]); strlistdel(&sg->sg_aliases, al->al_name); for (j=0; j < AccountList.l_count; j++) { ac = (struct account *) AccountList.l_list[j]; if (!instrlist(&ac->ac_sigs, (char *)v[1])) continue; if (!instrlist(&al->al_addresses, (char *)ac->ac_name)) continue; if (LegalAKA(ac, al)) continue; strlistdel(&al->al_addresses, (char *)ac->ac_name); } unbound++; } if (unbound) { (void) printf("%d unbound\n", unbound); ModBits |= AL; } non_critical(); return; } /* * Routine to determine if a user should be left in an alias after * his class, sig, or group memberships have changed. If the user is still * a member of another class, sig or group that is bound to the given aliasm * then the user should remain in the alias. Also if the user a member of * the alias above and beyond any class, sig or group bindings he should be * allowed to remain. */ int LegalAKA(ac, al) struct account *ac; struct alias *al; { char *name; struct groupmap *gm; register int i; /* * REMEMBER: * ac_aliases always contains the list of aliasses that the user is * in, even if he were not member of classes, sig, etc. that * are bound to aliases. Thus class, sig, or group membership * changes have no bearing on this so we return 1 immediately. */ if (instrlist(&ac->ac_aliases, al->al_name)) return 1; /* * Check for membership via group being bound. */ gm = getgmgid(ac->ac_gid); if (gm && instrlist(&al->al_groups, (char *)gm->gm_name)) return 1; for (i=0; i < ac->ac_groups.l_count; i++) { name = (char *) ac->ac_groups.l_list[i]; if (instrlist(&al->al_groups, name)) return 1; } /* * Are any of this user's classes bound to this alias? */ for (i=0; i < ac->ac_classes.l_count; i++) { name = (char *) ac->ac_classes.l_list[i]; if (instrlist(&al->al_classes, name)) return 1; } /* * Are any of this user's sigs bound to this alias? */ for (i=0; i < ac->ac_sigs.l_count; i++) { name = (char *) ac->ac_sigs.l_list[i]; if (instrlist(&al->al_sigs, name)) return 1; } return 0; } /* * Patch up aliases. * Should be used right after removing users from classes, * sigs, or groups, to be sure that if these are bound the changes are * reflected in the aliases. */ RXBindings(ac) struct account *ac; { register struct alias *al; register int i; critical(); for (i=0; i < AliasList.l_count; i++) { al = (struct alias *) AliasList.l_list[i]; if (instrlist(&al->al_addresses, (char *)ac->ac_name)) { if (LegalAKA(ac, al) == 0) { strlistdel(&al->al_addresses, (char *)ac->ac_name); ModBits |= AL; } } } non_critical(); return; } #endif SENDMAIL