|
|
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