|
|
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 a
Length: 24061 (0x5dfd)
Types: TextFile
Names: »auth.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Src/submit/auth.c«
/* auth.c: authorisation procedures used by submit */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Src/submit/RCS/auth.c,v 5.0 90/09/20 16:22:30 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Src/submit/RCS/auth.c,v 5.0 90/09/20 16:22:30 pp Exp Locker: pp $
*
* $Log: auth.c,v $
* Revision 5.0 90/09/20 16:22:30 pp
* rcsforce : 5.0 public release
*
*/
#include "head.h"
#include "q.h"
#include "dr.h"
#include "tb_auth.h"
#include <isode/cmd_srch.h>
typedef struct _bindings {
LIST_RCHAN *outchan;
LIST_RCHAN *fmtchans;
LIST_BPT *bpts;
int cost;
struct _bindings *next;
} Bindings;
#define ORED FALSE
#define freason(i) (rcmd_srch (i, authtbl_reasons))
#define rrights(i) (rcmd_srch (i, authtbl_rights))
#define gval(x) ((x -> ad_type) == AD_X400_TYPE ? \
(x -> ad_r400adr) : (x -> ad_r822adr))
extern CMD_TABLE authtbl_rights[];
extern CMD_TABLE authtbl_loglevel[];
extern ADDR *ad_originator;
extern ADDR *ad_recip;
extern CHAN *ch_inbound;
extern Q_struct Qstruct;
extern LIST_AUTH_CHAN *authchan_new();
extern LIST_AUTH_MTA *authmta_new ();
extern AUTH_USER *authusr_new();
extern AUTH *auth_new();
extern long msg_size;
extern char *re_comp();
extern CMD_TABLE authtbl_reasons[];
extern char *authchannel;
extern char *authloglevel;
extern char *mgt_inhost;
extern char *loc_dom_site;
extern void do_reason();
extern void tb_parse_authchan();
extern void authchan_add(), authmta_add();
/* -- static variables -- */
static AUTH *sender_auth = NULL_AUTH;
static LIST_AUTH_CHAN *def_authchan = NULLIST_AUTHCHAN;
static LIST_AUTH_CHAN *authchan_start = NULLIST_AUTHCHAN;
static LIST_AUTH_MTA *authmta_start = NULLIST_AUTHMTA;
/* -- globals -- */
char auth2submit_msg[BUFSIZ];
int auth_loglev;
/* -- local routines -- */
int auth_finish();
int fillin_orig_outchan();
void auth_start();
static Bindings *bindings_new();
static Bindings *do_ch_binds();
static char *ltoa();
static int test_pair();
static int bindings_free();
static int chk_mtarights();
static int chk_usrights();
static int do_stage_1();
static int do_stage_2();
static int test_flags();
static int test_recip_finish();
static int test_recip_start();
static int test_regex();
static void auth_chan();
static void auth_err2adr();
static void auth_init();
static void auth_init_recip();
static void auth_mta();
static void auth_remdup();
static void auth_usr();
static void auth_usr_chks();
static void bindings_add();
static void pr_rights();
static void rem_excess_outchans();
static void rem_pair();
static void set_fmt_and_content();
/* ------------------------ Begin Routines ------------------------------- */
void auth_start()
{
ADDR *ad;
PP_TRACE (("auth_start()"));
auth_init();
auth_usr();
for (ad = ad_recip; ad; ad = ad -> ad_next)
if (ad -> ad_status == AD_STAT_PEND)
test_recip_start (ad);
}
int auth_finish()
{
ADDR *ad;
int retval = RP_OK;
for (ad = ad_recip; ad; ad = ad -> ad_next) {
PP_TRACE (("auth_finish ('%s', '%d')",
ad -> ad_value, ad -> ad_status));
switch (ad -> ad_status) {
case AD_STAT_PEND:
if (test_recip_finish (ad) == NOTOK)
retval = RP_NAUTH;
continue;
default:
continue;
}
}
PP_TRACE (("auth_finish returns ('%s')", rp_valstr (retval)));
return retval;
}
int fillin_orig_outchan (ad)
ADDR *ad;
{
Bindings *binds;
char *content_out;
if ((binds = do_ch_binds (ad)) == (Bindings *) NULL)
return NOTOK;
/* just pick first no auth checking */
ad -> ad_fmtchan = binds -> fmtchans;
binds -> fmtchans = NULLIST_RCHAN;
ad -> ad_eit = binds -> bpts;
binds -> bpts = NULLIST_BPT;
if (ad -> ad_content != NULLCP) {
free (ad -> ad_content);
ad -> ad_content = NULLCP;
}
content_out = binds -> outchan -> li_chan -> ch_content_out;
if (isstr (Qstruct.cont_type) &&
isstr (content_out) &&
strcmp (Qstruct.cont_type, content_out) != 0)
ad -> ad_content = strdup (content_out);
else if (isstr (content_out))
ad -> ad_content = strdup (content_out);
rem_excess_outchans (ad, binds -> outchan);
ad -> ad_type = binds -> outchan -> li_chan -> ch_ad_type;
bindings_free (binds);
return OK;
}
/* ------------------------ Static Routines ------------------------------- */
static int bindings_free (ix)
Bindings *ix;
{
if (ix == NULL) return;
if (ix -> next != (Bindings *) NULL) bindings_free (ix -> next);
list_rchan_free (ix -> fmtchans);
list_bpt_free (ix -> bpts);
free ((char *) ix);
}
static Bindings *bindings_new (out, fmts, bpts, cost)
LIST_RCHAN *out,
*fmts;
LIST_BPT *bpts;
int cost;
{
Bindings *ret = (Bindings *) malloc(sizeof(Bindings));
ret -> outchan = out;
ret -> fmtchans = fmts;
ret -> bpts = bpts;
ret -> cost = cost;
ret -> next = (Bindings *) NULL;
return ret;
}
static void bindings_add (plist, new)
Bindings **plist,
*new;
{
Bindings *ix;
PP_TRACE (("bindings_add ('%s')",
new -> outchan -> li_chan -> ch_name));
if (*plist == (Bindings *) NULL
|| new -> cost < (*plist) -> cost) {
/* easy */
new -> next = *plist;
*plist = new;
return;
}
ix = *plist;
while (ix -> next != (Bindings *) NULL
&& ix -> next -> cost <= new -> cost)
ix = ix -> next;
new -> next = ix -> next;
ix -> next = new;
}
static Bindings *do_ch_binds (ad)
ADDR *ad;
{
Bindings *ret = (Bindings *) NULL;
LIST_RCHAN *ix = ad -> ad_outchan, *fmts;
LIST_BPT *bpts;
int cost;
while (ix != NULLIST_RCHAN) {
PP_TRACE (("do_ch_binds ('%s')", ix -> li_chan -> ch_name));
if (ch_bind (ad, ix, &fmts, &bpts, &cost) == OK)
bindings_add(&ret, bindings_new(ix, fmts, bpts, cost));
ix = ix -> li_next;
}
return ret;
}
static int test_recip_finish (ad)
ADDR *ad;
{
Bindings *binds, *ix;
int retval = OK;
int test = ad -> ad_outchan -> li_auth -> chan -> test;
PP_TRACE (("test_recip_finish : %s", gval(ad)));
if ((binds = do_ch_binds (ad)) == (Bindings *) NULL)
return NOTOK;
for (ix = binds; ix != (Bindings *) NULL; ix = ix -> next) {
switch (ix -> outchan -> li_auth -> status) {
case AUTH_OK:
case AUTH_DR_OK:
ad -> ad_type = ix -> outchan -> li_chan -> ch_ad_type;
retval = test_pair (ad, ix -> outchan);
if (retval == NOTOK) {
rem_pair (ad, ix -> outchan);
if (test != AUTH_CHAN_TEST)
continue;
}
/* --- otherwise fall through --- */
case AUTH_FAILED_TEST: /* --- failed at do_stage_1 --- */
set_fmt_and_content (ad, ix);
rem_excess_outchans (ad, ix -> outchan);
bindings_free (binds);
return OK;
default:
continue;
}
}
bindings_free (binds);
return NOTOK;
}
static void set_fmt_and_content (ad, ix)
ADDR *ad;
Bindings *ix;
{
char *content_out = ix -> outchan -> li_chan -> ch_content_out;
PP_TRACE (("submit/Give message to '%s'",
ix -> outchan -> li_chan -> ch_name));
ad -> ad_fmtchan = ix -> fmtchans;
/* -- stop them being freed -- */
ix -> fmtchans = NULLIST_RCHAN;
ad -> ad_eit = ix -> bpts;
/* -- stop them being freed -- */
ix -> bpts = NULLIST_BPT;
if (ad -> ad_content != NULLCP) {
free (ad -> ad_content);
ad -> ad_content = NULLCP;
}
if (isstr (Qstruct.cont_type) &&
isstr (content_out) &&
strcmp (Qstruct.cont_type, content_out) != 0)
ad -> ad_content = strdup (content_out);
else if (isstr (content_out))
ad -> ad_content = strdup (content_out);
return;
}
static int test_recip_start (ad)
ADDR *ad;
{
LIST_RCHAN *lp = ad -> ad_outchan;
int retval = FALSE;
PP_TRACE (("test_recip_start : %s", gval(ad)));
for (; lp != NULLIST_RCHAN; lp = lp -> li_next) {
ad -> ad_type = lp -> li_chan -> ch_ad_type;
switch (lp -> li_auth -> status) {
case AUTH_OK:
case AUTH_DR_OK:
retval = test_pair (ad, lp);
if (retval == OK) return OK;
rem_pair (ad, lp);
continue;
default:
continue;
}
}
return retval;
}
static int test_pair (ad, lp) /* -- Test chan/mta/usr per recip -- */
ADDR *ad;
LIST_RCHAN *lp;
{
char *val = gval(ad);
AUTH *au = lp -> li_auth;
int retval;
PP_TRACE (("test_pair : '%s' '%s' '%s'", val,
au -> chan -> li_chan -> ch_name, au -> mta -> li_mta));
switch (au -> stage) {
case AUTH_STAGE_1:
if (au -> chan -> li_found == FALSE) auth_chan (au -> chan);
if (au -> mta -> li_found == FALSE) auth_mta (au -> mta);
retval = do_stage_1 (val, au);
return retval;
case AUTH_STAGE_2:
retval = do_stage_2 (val, au);
return retval;
}
PP_LOG (LLOG_EXCEPTIONS,
("auth/Internal error unknown test stage %d", au -> stage));
return NOTOK;
}
static int do_stage_1 (adval, au)
char *adval;
AUTH *au;
{
int t[4];
int i = 0;
int retval = NOTOK;
char buf[LINESIZE];
LIST_REGEX *lr;
PP_TRACE (("do_stage_1: %s", adval));
switch (au -> chan -> policy) {
default:
PP_LOG (LLOG_EXCEPTIONS,
("auth/do_stage_1 unknown channel policy %d",
au -> chan -> policy));
break;
case AUTH_CHAN_FREE:
do_reason (au, freason(AUR_CH_FREE));
retval = OK;
break;
case AUTH_CHAN_NONE:
do_reason (au, freason(AUR_CH_NONE));
break;
case AUTH_CHAN_NEGATIVE:
t [i++] = chk_mtarights (sender_auth, au -> chan -> li_chan);
t [i++] = chk_usrights (sender_auth, au -> chan -> li_chan);
t [i++] = chk_mtarights (au, au -> chan -> li_chan);
t [i++] = chk_usrights (au, au -> chan -> li_chan);
pr_rights (au, AUTH_CHAN_NEGATIVE);
if (test_flags (t, NOTOK, ORED))
break;
retval = OK;
break;
case AUTH_CHAN_BLOCK:
t [i++] = chk_mtarights (sender_auth, au -> chan -> li_chan);
t [i++] = chk_usrights (sender_auth, au -> chan -> li_chan);
t [i++] = chk_mtarights (au, au -> chan -> li_chan);
t [i++] = chk_usrights (au, au -> chan -> li_chan);
if (test_flags (t, OK, ORED))
retval = OK;
pr_rights (au, AUTH_CHAN_BLOCK);
break;
}
if (retval == NOTOK)
return NOTOK;
/* -- regex testing -- */
bzero (buf, LINESIZE);
lr = sender_auth -> mta -> requires;
if (lr && (!test_regex (gval (ad_originator), lr, buf))) {
do_reason (au, freason(AUR_IMTA_MISSING_SNDR), buf);
return NOTOK;
}
lr = sender_auth -> mta -> excludes;
if (lr && (test_regex (gval (ad_originator), lr, buf))) {
do_reason (au, freason(AUR_IMTA_EXCLUDES_SNDR), buf);
return NOTOK;
}
lr = au -> mta -> requires;
if (lr && (!test_regex (adval, lr, buf))) {
do_reason (au, freason(AUR_OMTA_MISSING_RECIP), buf);
return NOTOK;
}
lr = au -> mta -> excludes;
if (lr && (test_regex (adval, lr, buf))) {
do_reason (au, freason(AUR_OMTA_EXCLUDES_RECIP), buf);
return NOTOK;
}
au -> stage = AUTH_STAGE_2;
return OK;
}
static int do_stage_2 (adval, au)
char *adval;
AUTH *au;
{
LIST_BPT *le, *lb;
long size;
PP_TRACE (("do_stage_2: %s", adval));
/* -- content tests -- */
size = au -> chan -> sizelimit;
if (size && (msg_size > size)) {
do_reason (au, freason(AUR_MSGSIZE_FOR_CHAN),
ltoa(msg_size), ltoa(size));
return NOTOK;
}
size = au -> mta -> sizelimit;
if (size && (msg_size > size)) {
do_reason (au, freason(AUR_MSGSIZE_FOR_MTA),
ltoa(msg_size), ltoa(size));
return NOTOK;
}
size = au -> user -> sizelimit;
if (size && (msg_size > size)) {
do_reason (au, freason(AUR_MSGSIZE_FOR_USR),
ltoa(msg_size), ltoa(size));
return NOTOK;
}
/* -- body part tests -- */
for (le = au -> mta -> content_excludes; le; le = le -> li_next) {
for (lb = Qstruct.encodedinfo.eit_types; lb; lb = lb -> li_next) {
PP_TRACE (("do_stage_2 exclude mta body parts %s : %s",
le -> li_name, lb -> li_name));
if (strcmp (le -> li_name, lb -> li_name) == 0) {
do_reason (au, freason(AUR_MTA_BPT),
le -> li_name);
return NOTOK;
}
}
}
for (le = au -> user -> content_excludes; le; le = le -> li_next) {
for (lb = Qstruct.encodedinfo.eit_types; lb; lb=lb -> li_next) {
PP_TRACE (("do_stage_2 exclude user body parts %s : %s",
le -> li_name, lb -> li_name));
if (strcmp (le -> li_name, lb -> li_name) == 0) {
do_reason (au, freason(AUR_USR_BPT),
le -> li_name);
return NOTOK;
}
}
}
au -> stage ++;
PP_TRACE (("do_stage_2: successful & returns '%s'", au -> reason));
return OK;
}
static int test_regex (val, list, ptr)
char *val;
LIST_REGEX *list;
char *ptr;
{
LIST_REGEX *lr;
char *cp;
int test;
PP_TRACE (("test_regex: %s", val));
for (lr = list; lr != NULLIST_REGEX; lr = lr -> li_next) {
PP_TRACE (("auth/test_regex: '%s'", lr -> li_regex));
cp = re_comp (lr -> li_regex);
if (cp) {
PP_LOG (LLOG_EXCEPTIONS,
("auth/test_regex: invalid expression <%s> %s",
lr -> li_regex, cp));
continue;
}
test = re_exec (val);
if (test == 1) {
(void) sprintf (ptr, "%s", lr -> li_regex);
PP_TRACE (("auth/test_regex : %s matches %s",
val, lr -> li_regex));
return TRUE;
}
if (test == -1) {
PP_LOG (LLOG_EXCEPTIONS,
("auth/test_regex : internal error <%s>",
lr -> li_regex));
continue;
}
if (strlen (ptr)) {
(void) strcat (ptr, " | ");
(void) strcat (ptr, lr -> li_regex);
}
else
(void) sprintf (ptr, "%s", lr -> li_regex);
PP_TRACE (("auth/test_regex: no match: %s : %s",
lr -> li_regex, ptr));
continue;
}
return FALSE;
}
static int chk_mtarights (au, ch)
AUTH *au;
CHAN *ch;
{
int infound = FALSE,
outfound = FALSE;
LIST_CHAN_RIGHTS *lr;
PP_TRACE (("chk_mtarights()"));
if (au -> mta -> li_found == FALSE) return MAYBE;
if (au -> mta -> rights != AUTH_RIGHTS_UNSET) {
au -> mta_inrights = au -> mta -> rights;
au -> mta_outrights = au -> mta -> rights;
}
for (lr = au -> mta -> li_cr; lr; lr = lr -> li_next) {
if (lr -> li_chan == ch_inbound) {
infound = TRUE;
au -> mta_inrights = lr -> li_rights;
}
if (lr -> li_chan == ch) {
outfound = TRUE;
au -> mta_outrights = lr -> li_rights;
}
if (infound && outfound)
break;
}
/* -- returns OK if (inbound = in|both && outbound = out|both -- */
if (au -> mta_inrights == AUTH_RIGHTS_NONE ||
au -> mta_inrights == AUTH_RIGHTS_OUT ||
au -> mta_inrights == AUTH_RIGHTS_UNSET)
return NOTOK;
if (au -> mta_outrights == AUTH_RIGHTS_NONE ||
au -> mta_outrights == AUTH_RIGHTS_IN ||
au -> mta_outrights == AUTH_RIGHTS_UNSET)
return NOTOK;
PP_TRACE (("chk_mtarights : successful: in = %s out = %s",
rrights (au -> mta_inrights),
rrights (au -> mta_outrights)));
return OK;
}
static int chk_usrights (au, ch)
AUTH *au;
CHAN *ch;
{
int infound = FALSE,
outfound = FALSE;
LIST_CHAN_RIGHTS *lr;
PP_TRACE (("chk_usrights()"));
if (au -> user -> found == FALSE)
return MAYBE;
if (au -> user -> rights != AUTH_RIGHTS_UNSET) {
au -> user_inrights = au -> user -> rights;
au -> user_outrights = au -> user -> rights;
}
for (lr = au -> user -> li_cr; lr; lr = lr -> li_next) {
if (lr -> li_chan == ch_inbound) {
infound = TRUE;
au -> user_inrights = lr -> li_rights;
}
if (lr -> li_chan == ch) {
outfound = TRUE;
au -> user_outrights = lr -> li_rights;
}
if (infound && outfound)
break;
}
/* -- returns OK if (inbound = in|both && outbound = out|both -- */
if (au -> user_inrights == AUTH_RIGHTS_NONE ||
au -> user_inrights == AUTH_RIGHTS_OUT ||
au -> user_inrights == AUTH_RIGHTS_UNSET)
return NOTOK;
if (au -> user_outrights == AUTH_RIGHTS_NONE ||
au -> user_outrights == AUTH_RIGHTS_IN ||
au -> user_outrights == AUTH_RIGHTS_UNSET)
return NOTOK;
PP_TRACE (("chk_usrights : successful : in = %s out = %s",
rrights (au -> user_inrights),
rrights (au -> user_outrights)));
return OK;
}
static void rem_excess_outchans (ad, outchan)
ADDR *ad;
LIST_RCHAN *outchan;
{
LIST_RCHAN *ix, *tmp;
/* remove excess ad_outchans */
ix = ad -> ad_outchan;
if (ix != outchan) {
while (ix -> li_next != NULLIST_RCHAN
&& ix -> li_next != outchan)
ix = ix -> li_next;
if (ix -> li_next != NULLIST_RCHAN) {
tmp = ad -> ad_outchan;
ad -> ad_outchan = ix -> li_next;
ix -> li_next = NULLIST_RCHAN;
list_rchan_free (tmp);
}
}
if (ad -> ad_outchan -> li_next != NULLIST_RCHAN) {
list_rchan_free (ad -> ad_outchan -> li_next);
ad -> ad_outchan -> li_next = NULLIST_RCHAN;
}
}
static void rem_pair (ad, remch)
ADDR *ad;
LIST_RCHAN *remch;
{
LIST_RCHAN *lp;
AUTH *au = remch -> li_auth;
int allgone = TRUE;
if (remch == NULLIST_RCHAN) return;
PP_TRACE (("rem_pair : '%s' '%s' '%s' '%d'",
gval (ad), remch -> li_chan -> ch_name,
remch -> li_mta, au -> chan -> test));
switch (au -> chan -> test) {
case AUTH_CHAN_TEST:
au -> status = AUTH_FAILED_TEST;
return;
default:
au -> status = AUTH_FAILED;
break;
}
for (lp = ad -> ad_outchan; lp; lp = lp -> li_next)
if (lp -> li_auth -> status == AUTH_OK) {
allgone = FALSE;
break;
}
if (allgone)
auth_err2adr (ad);
}
static void auth_err2adr (ad)
ADDR *ad;
{
char buf [BUFSIZ * 2];
if (ad == NULLADDR) return;
ad -> ad_status = AD_STAT_DRREQUIRED;
ad -> ad_reason = DRR_UNABLE_TO_TRANSFER;
ad -> ad_diagnostic = DRD_NO_BILATERAL_AGREEMENT;
(void) sprintf (buf,
"Authorisation failure at site '%s' for recip '%s' Reason: '%s'",
loc_dom_site, ad -> ad_value, auth2submit_msg);
ad -> ad_add_info = strdup (buf);
PP_TRACE (("auth_err2adr: '%s'", buf));
}
static void auth_chan (ch)
LIST_AUTH_CHAN *ch;
{
if (tb_getauthchan (ch) == NOTOK)
err_abrt (RP_NAUTH, "auth_chan/Cannot look up chan table '%s'",
ch -> li_chan -> ch_name);
if (ch -> li_found == FALSE)
PP_TRACE (("auth_chan/Chan '%s' missing",
ch -> li_chan -> ch_name));
}
static void auth_mta (mta)
LIST_AUTH_MTA *mta;
{
if (tb_getauthmta (mta) == NOTOK)
err_abrt (RP_NAUTH, "auth_mta/Cannot look up mta table '%s'",
mta -> li_mta);
if (mta -> li_found == FALSE)
PP_TRACE (("auth_mta/Mta '%s' missing", mta -> li_mta));
}
static void auth_usr()
{
ADDR *ad;
PP_TRACE (("auth_usr()"));
if (sender_auth -> user == NULL_AUTHUSR)
err_abrt (RP_NAUTH, "auth_usr/No sender user table");
if (ad_originator == NULLADDR)
err_abrt (RP_NAUTH, "auth_usr/No sender address found");
if (tb_getauthusr (sender_auth -> user, ad_originator) == NOTOK)
err_abrt (RP_NAUTH, "auth_usr/Lookup failed for '%s'",
gval (ad_originator));
if (sender_auth -> user -> found == FALSE)
PP_TRACE (("auth_usr/sender user '%s' missing",
gval (ad_originator)));
for (ad = ad_recip; ad; ad = ad -> ad_next)
auth_usr_chks (ad);
/* -- eliminate duplicates -- */
for (ad = ad_recip; ad; ad = ad -> ad_next) {
PP_TRACE (("auth_usr/dup loop '%s' stat='%d', resp='%d')",
ad -> ad_value, ad -> ad_status, ad -> ad_resp));
if (ad -> ad_resp == FALSE)
continue;
switch (ad -> ad_status) {
case AD_STAT_DRREQUIRED:
case AD_STAT_DONE:
continue;
}
auth_remdup (ad, ad -> ad_next);
}
}
static void auth_usr_chks (ad)
ADDR *ad;
{
char *value = ad -> ad_value;
PP_TRACE (("auth_usr_chks (%s)", gval (ad)));
if (ad -> ad_status == AD_STAT_DRREQUIRED ||
ad -> ad_status == AD_STAT_DRWRITTEN ||
ad -> ad_resp == FALSE) {
PP_TRACE (("auth_usr/recip='%s' stat=%d resp=%d",
value, ad -> ad_status, ad -> ad_resp));
return;
}
if (ad -> ad_outchan == NULL)
err_abrt (RP_NAUTH, "auth_usr_chks/ad_outchan unset for '%s'",
value);
if (ad -> ad_outchan -> li_auth == NULL_AUTH)
err_abrt (RP_NAUTH, "auth_usr_chks/chan auth unset for '%s'",
value);
if (tb_getauthusr (ad -> ad_outchan -> li_auth -> user, ad) == NOTOK)
err_abrt (RP_NAUTH, "auth_usr_chks/Cannot look up '%s'",
value);
if (ad -> ad_outchan -> li_auth -> user -> found == FALSE)
PP_TRACE (("auth_usr_chks/recipient '%s' missing", gval (ad)));
}
static void auth_remdup (ad, list) /* -- removes duplicates -- */
ADDR *ad;
ADDR *list;
{
AUTH *au;
PP_TRACE (("auth_remdup (%s)", gval (ad)));
for (list = ad -> ad_next; list; list = list -> ad_next) {
PP_TRACE (("auth_remdup/'%s' stat='%d', resp='%d')",
list -> ad_value, list -> ad_status, list -> ad_resp));
if (list -> ad_resp == FALSE)
continue;
switch (list -> ad_status) {
case AD_STAT_DRREQUIRED:
case AD_STAT_DONE:
continue;
}
if (strcmp (gval(ad), gval(list)) == 0) {
PP_TRACE (("auth_remdup/removed: '%s' (%d)",
gval (list), list -> ad_no));
list -> ad_status = AD_STAT_DONE;
list -> ad_outchan -> li_next = NULLIST_RCHAN;
au = list -> ad_outchan -> li_auth;
au -> status = AUTH_FAILED;
do_reason (au, freason (AUR_DUPLICATE_REMOVED));
}
}
}
static void auth_init()
{
char *argv[MAX_AUTH_ARGS],
*cp;
int argc;
ADDR *ad;
PP_TRACE (("auth_init: authloglevel='%s' authchannel='%s'",
authloglevel, authchannel));
bzero (auth2submit_msg, BUFSIZ);
switch (auth_loglev = cmd_srch (authloglevel, authtbl_loglevel)) {
case AUTH_LOGLEVEL_LOW:
case AUTH_LOGLEVEL_MEDIUM:
case AUTH_LOGLEVEL_HIGH:
break;
default:
auth_loglev = AUTH_LOGLEVEL_LOW;
PP_LOG (LLOG_EXCEPTIONS,
("auth_init/authloglevel invalid : '%s' (low assumed)",
authloglevel));
break;
}
cp = strdup (authchannel);
if ((argc = sstr2arg (cp, MAX_AUTH_ARGS, argv, " \t,")) == NOTOK)
err_abrt (RP_NAUTH, "auth_init/authchannel invalid '%s'",
authchannel);
def_authchan = authchan_new (NULLCHAN, NULLIST_AUTHCHAN);
tb_parse_authchan (def_authchan, argc, argv);
sender_auth = auth_new();
authmta_start = authmta_new (mgt_inhost);
sender_auth -> mta = authmta_start;
auth_mta (sender_auth -> mta);
sender_auth -> user = authusr_new();
for (ad = ad_recip; ad; ad = ad -> ad_next)
auth_init_recip (ad);
free (cp);
}
static void auth_init_recip (ad)
ADDR *ad;
{
AUTH_USER *up;
LIST_RCHAN *lr;
LIST_AUTH_CHAN *lc;
LIST_AUTH_MTA *lm;
int found = FALSE;
char *val;
PP_TRACE (("auth_init_recip (%s)", gval (ad)));
up = authusr_new();
for (lr = ad -> ad_outchan; lr; lr = lr -> li_next) {
lr -> li_auth = auth_new();
lr -> li_auth -> user = up;
val = lr -> li_chan -> ch_name;
found = FALSE;
for (lc = authchan_start; lc; lc = lc -> li_next)
if (strcmp (val, lc -> li_chan -> ch_name) == 0) {
found = TRUE;
break;
}
if (!found && lr -> li_chan) {
lc = authchan_new (lr -> li_chan, def_authchan);
authchan_add (&authchan_start, lc);
}
lr -> li_auth -> chan = lc;
found = FALSE;
for (lm = authmta_start; lm; lm = lm -> li_next)
if (strcmp (lm -> li_mta, lr -> li_mta) == 0) {
found = TRUE;
break;
}
if (!found && lr -> li_mta) {
lm = authmta_new (lr -> li_mta);
authmta_add (&authmta_start, lm);
}
lr -> li_auth -> mta = lm;
}
}
static void pr_rights (au, ch_policy)
AUTH *au;
int ch_policy;
{
char buf[BUFSIZ*2];
PP_TRACE (("pr_rights ('%d')", ch_policy));
bzero (buf, sizeof *buf);
(void) sprintf (buf,
"%s: imta (%s %s) sender (%s %s) omta (%s %s) recip (%s %s)",
ch_policy == AUTH_CHAN_BLOCK ? "block" :
ch_policy == AUTH_CHAN_NEGATIVE ? "negative" : "UnknownPolicy",
rrights (sender_auth -> mta_inrights),
rrights (sender_auth -> mta_outrights),
rrights (sender_auth -> user_inrights),
rrights (sender_auth -> user_outrights),
rrights (au -> mta_inrights),
rrights (au -> mta_outrights),
rrights (au -> user_inrights),
rrights (au -> user_outrights));
do_reason (au, "%s", buf);
return;
}
static char *ltoa (l)
long l;
{
char buf[LINESIZE];
(void) sprintf (buf, "%ld", l);
return (strdup (buf));
}
static int test_flags (f, val, type)
int f[];
int val;
int type;
{
switch (type) {
case ORED:
if (f[0] == val || f[1] == val || f[2] == val || f[3] == val)
return TRUE;
break;
}
return FALSE;
}