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