DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T b

⟦49bca3e9b⟧ TextFile

    Length: 12012 (0x2eec)
    Types: TextFile
    Names: »bind.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec8/mcp/src/bind.c« 

TextFile

/***************************************************************************\
* 									    *
* 	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