From: Jeremy Harris Date: Sat, 7 Sep 2024 13:56:11 +0000 (+0100) Subject: radius dynamic module X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/2484552ee924d5e5a30d4c41be365a19cdd48ed5?ds=sidebyside radius dynamic module --- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 5220408e8..fe94e46c7 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -14,9 +14,9 @@ Version 4.98 3. Events smtp:fail:protocol and smtp:fail:syntax - 4. JSON and LDAP lookup support, SPF, DKIM, DMARC and ARC support, all the - router and authenticator drivers, and all the transport drivers except - smtp, can now be built as loadable modules + 4. JSON and LDAP lookup support, RADIUS, SPF, DKIM, DMARC and ARC support, + all the router and authenticator drivers, and all the transport drivers + except smtp, can now be built as loadable modules Version 4.98 ------------ diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base index ccbe3ccdd..ddd7cf5ac 100644 --- a/src/OS/Makefile-Base +++ b/src/OS/Makefile-Base @@ -509,7 +509,7 @@ OBJ_LOOKUPS = lf_quote.o lf_check_file.o lf_sqlperform.o OBJ_ROUTERS = rf_change_domain.o rf_expand_data.o rf_get_errors_address.o \ rf_get_munge_headers.o rf_get_transport.o rf_get_ugid.o \ rf_lookup_hostlist.o rf_queue_add.o rf_self_action.o rf_set_ugid.o -OBJ_AUTHS = call_pam.o call_pwcheck.o call_radius.o check_serv_cond.o \ +OBJ_AUTHS = call_pam.o call_pwcheck.o check_serv_cond.o \ get_data.o get_no64_data.o pwcheck.o OBJ_EXIM = acl.o base64.o child.o crypt16.o daemon.o dbfn.o debug.o deliver.o \ @@ -974,9 +974,6 @@ call_pam.o: auths/call_pam.c call_pwcheck.o: auths/call_pwcheck.c auths/pwcheck.h @echo "$(CC) $<" $(FE)$(CC) -c $(CFLAGS) -I. $(INCLUDE) $< -call_radius.o: auths/call_radius.c - @echo "$(CC) $<" - $(FE)$(CC) -c $(CFLAGS) -I. $(INCLUDE) $< check_serv_cond.o: auths/check_serv_cond.c @echo "$(CC) $<" $(FE)$(CC) -c $(CFLAGS) -I. $(INCLUDE) $< diff --git a/src/scripts/Configure-Makefile b/src/scripts/Configure-Makefile index 1eb79a291..96a6cce22 100755 --- a/src/scripts/Configure-Makefile +++ b/src/scripts/Configure-Makefile @@ -247,17 +247,6 @@ then yes|YES|y|Y) echo >&2 "pcre is no longer supported; migrate to pcre2" exit 1 - -# cflags=`pcre-config --cflags` -# if [ $? -ne 0 ]; then -# echo >&2 "*** Missing pcre-config for regular expression support" -# exit 1 -# fi -# libs=`pcre-config --libs` -# if [ ".$cflags" != "." ]; then -# echo "INCLUDE += $cflags" -# fi -# echo "PCRE_LIBS=$libs" ;; esac ;; @@ -295,23 +284,32 @@ then fi rm -f $mftt +#XXX look for RADIUS in $mft; add a SUPPORT_ +if $egrep -q "^RADIUS_CONFIG_FILE" $mft; then + echo "# radius fixup" + $egrep -q "^SUPPORT_RADIUS" $mft || echo "SUPPORT_RADIUS=yes" >> $mft +fi + + # make the lookups Makefile with the definitions # the auxiliary script generates $look_mf_post from $look_mf_pre cp ../src/lookups/Makefile $look_mf_pre ../scripts/lookups-Makefile +# make the Makefiles for routers, transports, auths and miscmods +# while read class classdef names do cp ../src/$class/Makefile $class/Makefile.predynamic - CLASS=$class CLASSDEF=$classdef DRNAMES="$names" ../scripts/drivers-Makefile + CLASS=$class CLASSDEF=$classdef DRNAMES="$names" EGREP="$egrep" ../scripts/drivers-Makefile mv $class/Makefile.postdynamic $class/Makefile rm $class/Makefile.predynamic done <<-END routers ROUTER ACCEPT DNSLOOKUP IPLITERAL IPLOOKUP MANUALROUTE QUERYPROGRAM REDIRECT transports TRANSPORT APPENDFILE AUTOREPLY LMTP PIPE QUEUEFILE SMTP auths AUTH CRAM_MD5 CYRUS_SASL DOVECOT EXTERNAL GSASL HEIMDAL_GSSAPI PLAINTEXT SPA TLS - miscmods SUPPORT ARC _DKIM DMARC SPF + miscmods SUPPORT ARC _DKIM DMARC RADIUS SPF END # See if there is a definition of EXIM_PERL in what we have built so far. diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks index 481f36fe3..1b272a5c9 100755 --- a/src/scripts/MakeLinks +++ b/src/scripts/MakeLinks @@ -79,7 +79,7 @@ mkdir $d cd $d # Makefile is generated for f in README call_pam.c call_pwcheck.c \ - call_radius.c check_serv_cond.c cyrus_sasl.c cyrus_sasl.h gsasl.c \ + check_serv_cond.c cyrus_sasl.c cyrus_sasl.h gsasl.c \ gsasl.h get_data.c get_no64_data.c heimdal_gssapi.c heimdal_gssapi.h \ cram_md5.c cram_md5.h plaintext.c plaintext.h \ pwcheck.c pwcheck.h auth-spa.c auth-spa.h dovecot.c dovecot.h spa.c \ @@ -102,6 +102,7 @@ for f in dummy.c \ pdkim/crypt_ver.h pdkim/pdkim.c pdkim/pdkim.h \ pdkim/pdkim_hash.h pdkim/signing.c pdkim/signing.h \ dmarc.c dmarc.h dmarc_api.h \ + radius.c radius_api.h \ spf.c spf.h spf_api.h do ln -s ../../src/$d/$f `basename $f` diff --git a/src/scripts/drivers-Makefile b/src/scripts/drivers-Makefile index 085eedbda..de3c239a6 100755 --- a/src/scripts/drivers-Makefile +++ b/src/scripts/drivers-Makefile @@ -6,6 +6,7 @@ class=${CLASS:?} classdef=${CLASSDEF:?} drnames="${DRNAMES:?}" +egrep="${EGREP:?}" # We turn the configure-built build-$foo/$class/Makefile.predynamic into Makefile. # This is used for router and transport drivers, called from scripts/Configure-Makefile. @@ -97,19 +98,18 @@ fi want_dynamic() { local dyn_name="${1#_}" local re="(${classdef}|EXPERIMENTAL)_${dyn_name}[ $tab]*=[ $tab]*2" - #XXX Solaris does not support -E on grep. Must use egrep. - env | grep -E -q "^$re" + env | ${egrep} -q "^$re" if [ $? -eq 0 ]; then return 0; fi - grep -E -q "^[ $tab]*$re" "$defs_source" + ${egrep} -q "^[ $tab]*$re" "$defs_source" } want_not_disabled() { local want_name="${1#_}" [ "$local_want_name" = "$1" ] && return 0; local re="DISABLED_${want_name}[ $tab]*=[ $tab]*." - env | grep -E -q "^$re" + env | ${egrep} -q "^$re" [ $? -ne 0 ] && return 0 - grep -E -q "^[ $tab]*$re" "$defs_source" + ${egrep} -q "^[ $tab]*$re" "$defs_source" [ $? -ne 0 ] && return 0 return 1 } @@ -117,9 +117,9 @@ want_not_disabled() { want_at_all() { local want_name="$1" local re="(${classdef}|EXPERIMENTAL)_${want_name}[ $tab]*=[ $tab]*." - env | grep -E -q "^$re" + env | ${egrep} -q "^$re" if [ $? -eq 0 ]; then return 0; fi - grep -E -q "^[ $tab]*$re" "$defs_source" + ${egrep} -q "^[ $tab]*$re" "$defs_source" } # The values of these variables will be emitted into the Makefile. diff --git a/src/src/auths/call_radius.c b/src/src/auths/call_radius.c deleted file mode 100644 index 65882c108..000000000 --- a/src/src/auths/call_radius.c +++ /dev/null @@ -1,224 +0,0 @@ -/************************************************* -* Exim - an Internet mail transport agent * -*************************************************/ - -/* Copyright (c) The Exim Maintainers 2020 - 2022 */ -/* Copyright (c) University of Cambridge 1995 - 2016 */ -/* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* This file was originally supplied by Ian Kirk. The libradius support came -from Alex Kiernan. */ - -#include "../exim.h" - -/* This module contains functions that call the Radius authentication -mechanism. - -We can't just compile this code and allow the library mechanism to omit the -functions if they are not wanted, because we need to have the Radius headers -available for compiling. Therefore, compile these functions only if -RADIUS_CONFIG_FILE is defined. However, some compilers don't like compiling -empty modules, so keep them happy with a dummy when skipping the rest. Make it -reference itself to stop picky compilers complaining that it is unused, and put -in a dummy argument to stop even pickier compilers complaining about infinite -loops. Then use a mutually-recursive pair as gcc is just getting stupid. */ - -#ifndef RADIUS_CONFIG_FILE -static void dummy(int x); -static void dummy2(int x) { dummy(x-1); } -static void dummy(int x) { dummy2(x-1); } -#else /* RADIUS_CONFIG_FILE */ - - -/* Two different Radius libraries are supported. The default is radiusclient, -using its original API. At release 0.4.0 the API changed. */ - -#ifdef RADIUS_LIB_RADLIB -# include -#else -# if !defined(RADIUS_LIB_RADIUSCLIENT) && !defined(RADIUS_LIB_RADIUSCLIENTNEW) -# define RADIUS_LIB_RADIUSCLIENT -# endif - -# ifdef RADIUS_LIB_RADIUSCLIENTNEW -# define ENV FREERADIUSCLIENT_ENV /* Avoid clash with Berkeley DB */ -# include -# else -# include -# endif -#endif - - - -/************************************************* -* Perform RADIUS authentication * -*************************************************/ - -/* This function calls the Radius authentication mechanism, passing over one or -more data strings. - -Arguments: - s a colon-separated list of strings - errptr where to point an error message - -Returns: OK if authentication succeeded - FAIL if authentication failed - ERROR some other error condition -*/ - -int -auth_call_radius(const uschar *s, uschar **errptr) -{ -uschar *user; -const uschar *radius_args = s; -int result; -int sep = 0; - -#ifdef RADIUS_LIB_RADLIB - struct rad_handle *h; -#else - #ifdef RADIUS_LIB_RADIUSCLIENTNEW - rc_handle *h; - #endif - VALUE_PAIR *send = NULL; - VALUE_PAIR *received; - unsigned int service = PW_AUTHENTICATE_ONLY; - char msg[4096]; -#endif - - -if (!(user = string_nextinlist(&radius_args, &sep, NULL, 0))) user = US""; - -DEBUG(D_auth) debug_printf("Running RADIUS authentication for user \"%s\" " - "and \"%s\"\n", user, radius_args); - -*errptr = NULL; - - -/* Authenticate using the radiusclient library */ - -#ifndef RADIUS_LIB_RADLIB - -rc_openlog("exim"); - -#ifdef RADIUS_LIB_RADIUSCLIENT -if (rc_read_config(RADIUS_CONFIG_FILE) != 0) - *errptr = string_sprintf("RADIUS: can't open %s", RADIUS_CONFIG_FILE); - -else if (rc_read_dictionary(rc_conf_str("dictionary")) != 0) - *errptr = US"RADIUS: can't read dictionary"; - -else if (!rc_avpair_add(&send, PW_USER_NAME, user, 0)) - *errptr = US"RADIUS: add user name failed"; - -else if (!rc_avpair_add(&send, PW_USER_PASSWORD, CS radius_args, 0)) - *errptr = US"RADIUS: add password failed"); - -else if (!rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0)) - *errptr = US"RADIUS: add service type failed"; - -#else /* RADIUS_LIB_RADIUSCLIENT unset => RADIUS_LIB_RADIUSCLIENT2 */ - -if (!(h = rc_read_config(RADIUS_CONFIG_FILE))) - *errptr = string_sprintf("RADIUS: can't open %s", RADIUS_CONFIG_FILE); - -else if (rc_read_dictionary(h, rc_conf_str(h, "dictionary")) != 0) - *errptr = US"RADIUS: can't read dictionary"; - -else if (!rc_avpair_add(h, &send, PW_USER_NAME, user, Ustrlen(user), 0)) - *errptr = US"RADIUS: add user name failed"; - -else if (!rc_avpair_add(h, &send, PW_USER_PASSWORD, CS radius_args, - Ustrlen(radius_args), 0)) - *errptr = US"RADIUS: add password failed"; - -else if (!rc_avpair_add(h, &send, PW_SERVICE_TYPE, &service, 0, 0)) - *errptr = US"RADIUS: add service type failed"; - -#endif /* RADIUS_LIB_RADIUSCLIENT */ - -if (*errptr) - { - DEBUG(D_auth) debug_printf("%s\n", *errptr); - return ERROR; - } - -#ifdef RADIUS_LIB_RADIUSCLIENT -result = rc_auth(0, send, &received, msg); -#else -result = rc_auth(h, 0, send, &received, msg); -#endif - -DEBUG(D_auth) debug_printf("RADIUS code returned %d\n", result); - -switch (result) - { - case OK_RC: - return OK; - - case REJECT_RC: - case ERROR_RC: - return FAIL; - - case TIMEOUT_RC: - *errptr = US"RADIUS: timed out"; - return ERROR; - - case BADRESP_RC: - default: - *errptr = string_sprintf("RADIUS: unexpected response (%d)", result); - return ERROR; - } - -#else /* RADIUS_LIB_RADLIB is set */ - -/* Authenticate using the libradius library */ - -if (!(h = rad_auth_open())) - { - *errptr = string_sprintf("RADIUS: can't initialise libradius"); - return ERROR; - } -if (rad_config(h, RADIUS_CONFIG_FILE) != 0 || - rad_create_request(h, RAD_ACCESS_REQUEST) != 0 || - rad_put_string(h, RAD_USER_NAME, CS user) != 0 || - rad_put_string(h, RAD_USER_PASSWORD, CS radius_args) != 0 || - rad_put_int(h, RAD_SERVICE_TYPE, RAD_AUTHENTICATE_ONLY) != 0 || - rad_put_string(h, RAD_NAS_IDENTIFIER, CS primary_hostname) != 0) - { - *errptr = string_sprintf("RADIUS: %s", rad_strerror(h)); - result = ERROR; - } -else - switch (result = rad_send_request(h)) - { - case RAD_ACCESS_ACCEPT: - result = OK; - break; - - case RAD_ACCESS_REJECT: - result = FAIL; - break; - - case -1: - *errptr = string_sprintf("RADIUS: %s", rad_strerror(h)); - result = ERROR; - break; - - default: - *errptr = string_sprintf("RADIUS: unexpected response (%d)", result); - result= ERROR; - break; - } - -if (*errptr) DEBUG(D_auth) debug_printf("%s\n", *errptr); -rad_close(h); -return result; - -#endif /* RADIUS_LIB_RADLIB */ -} - -#endif /* RADIUS_CONFIG_FILE */ - -/* End of call_radius.c */ diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults index 20a288d66..60aacee5b 100644 --- a/src/src/config.h.defaults +++ b/src/src/config.h.defaults @@ -168,8 +168,9 @@ Do not put spaces between # and the 'define'. #define SUPPORT_TRANSLATE_IP_ADDRESS /* Required to support dynamic-module build */ -#define SUPPORT_DKIM #define SUPPORT_ARC +#define SUPPORT_DKIM +#define SUPPORT_RADIUS #define SYSLOG_LOG_PID #define SYSLOG_LONG_LINES diff --git a/src/src/exim.h b/src/src/exim.h index f5043aea9..550f1a7bd 100644 --- a/src/src/exim.h +++ b/src/src/exim.h @@ -558,6 +558,9 @@ config.h, mytypes.h, and store.h, so we don't need to mention them explicitly. #ifdef EXPERIMENTAL_ARC # include "miscmods/arc_api.h" #endif +#ifdef RADIUS_CONFIG_FILE +# include "miscmods/radius_api.h" +#endif /* The following stuff must follow the inclusion of config.h because it requires various things that are set therein. */ diff --git a/src/src/expand.c b/src/src/expand.c index a41ba98cf..521a30d49 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -2775,12 +2775,19 @@ switch(cond_type = identify_operator(&s, &opname)) #endif /* SUPPORT_PAM */ case ECOND_RADIUS: - #ifdef RADIUS_CONFIG_FILE - rc = auth_call_radius(sub[0], &expand_string_message); - goto END_AUTH; - #else - goto COND_FAILED_NOT_COMPILED; - #endif /* RADIUS_CONFIG_FILE */ +#ifdef RADIUS_CONFIG_FILE + { + const misc_module_info * mi = misc_mod_find(US"radius", NULL); + typedef int (*fn_t)(const uschar *, uschar **); + if (!mi) + goto COND_FAILED_NOT_COMPILED; + rc = (((fn_t *) mi->functions)[RADIUS_AUTH_CALL]) + (sub[0], &expand_string_message); + goto END_AUTH; + } +#else + goto COND_FAILED_NOT_COMPILED; +#endif /* RADIUS_CONFIG_FILE */ case ECOND_LDAPAUTH: #ifdef LOOKUP_LDAP diff --git a/src/src/functions.h b/src/src/functions.h index deec54590..ac0c31097 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -113,7 +113,6 @@ extern void add_driver_info(driver_info **, const driver_info *, size_t); extern void assert_no_variables(void *, int, const char *, int); extern int auth_call_pam(const uschar *, uschar **); extern int auth_call_pwcheck(uschar *, uschar **); -extern int auth_call_radius(const uschar *, uschar **); extern int auth_call_saslauthd(const uschar *, const uschar *, const uschar *, const uschar *, uschar **); extern int auth_check_serv_cond(auth_instance *); diff --git a/src/src/miscmods/Makefile b/src/src/miscmods/Makefile index a4ffcfc92..a15fd9b38 100644 --- a/src/src/miscmods/Makefile +++ b/src/src/miscmods/Makefile @@ -41,13 +41,14 @@ spf.o spf.so: $(HDRS) spf.h spf.c dkim.o: @echo "$(CC) dkim.c dkim_transport.c pdkim.c signing.c" - $(FE)$(CC) -r $(LDFLAGS_PARTIAL) $(CFLAGS) $(INCLUDE) \ - dkim.c dkim_transport.c pdkim.c signing.c -o $@ + $(FE)$(CC) -r $(LDFLAGS_PARTIAL) -o $@ $(CFLAGS) $(INCLUDE) \ + dkim.c dkim_transport.c pdkim.c signing.c dkim.so: @echo "$(CC) -shared dkim.c dkim_transport.c pdkim.c signing.c" - $(FE)$(CC) $(SUPPORT_$*_INCLUDE) $(SUPPORT_$*_LIBS) \ - -DDYNLOOKUP $(CFLAGS_DYNAMIC) $(CFLAGS) $(INCLUDE) \ - $(DLFLAGS) dkim.c dkim_transport.c pdkim.c signing.c -o $@ + $(FE)$(CC) -DDYNLOOKUP $(CFLAGS_DYNAMIC) -o $@ \ + $(SUPPORT_$*_INCLUDE) $(SUPPORT_$*_LIBS) \ + $(CFLAGS) $(INCLUDE) $(DLFLAGS) \ + dkim.c dkim_transport.c pdkim.c signing.c # End diff --git a/src/src/miscmods/arc.c b/src/src/miscmods/arc.c index db546e1ab..a48d1987b 100644 --- a/src/src/miscmods/arc.c +++ b/src/src/miscmods/arc.c @@ -2151,7 +2151,7 @@ static var_entry arc_variables[] = { misc_module_info arc_module_info = { .name = US"arc", -# if SUPPORT_SPF==2 +# ifdef DYNLOOKUP .dyn_magic = MISC_MODULE_MAGIC, # endif .init = arc_init, diff --git a/src/src/miscmods/dkim.c b/src/src/miscmods/dkim.c index 632ff4813..40339d100 100644 --- a/src/src/miscmods/dkim.c +++ b/src/src/miscmods/dkim.c @@ -1359,7 +1359,7 @@ static var_entry dkim_variables[] = { misc_module_info dkim_module_info = { .name = US"dkim", -# if SUPPORT_DKIM==2 +# ifdef DYNLOOKUP .dyn_magic = MISC_MODULE_MAGIC, # endif .init = dkim_exim_init, diff --git a/src/src/miscmods/dmarc.c b/src/src/miscmods/dmarc.c index e192bda1b..161bfeece 100644 --- a/src/src/miscmods/dmarc.c +++ b/src/src/miscmods/dmarc.c @@ -806,7 +806,7 @@ static var_entry dmarc_variables[] = { misc_module_info dmarc_module_info = { .name = US"dmarc", -# if SUPPORT_SPF==2 +# ifdef DYNLOOKUP .dyn_magic = MISC_MODULE_MAGIC, # endif .init = dmarc_init, diff --git a/src/src/miscmods/radius.c b/src/src/miscmods/radius.c new file mode 100644 index 000000000..61ca6ea3a --- /dev/null +++ b/src/src/miscmods/radius.c @@ -0,0 +1,244 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* Copyright (c) The Exim Maintainers 2020 - 2022 */ +/* Copyright (c) University of Cambridge 1995 - 2016 */ +/* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* This file was originally supplied by Ian Kirk. The libradius support came +from Alex Kiernan. */ + +#include "../exim.h" + +/* This module contains functions that call the Radius authentication +mechanism. + +We can't just compile this code and allow the library mechanism to omit the +functions if they are not wanted, because we need to have the Radius headers +available for compiling. Therefore, compile these functions only if +RADIUS_CONFIG_FILE is defined. However, some compilers don't like compiling +empty modules, so keep them happy with a dummy when skipping the rest. Make it +reference itself to stop picky compilers complaining that it is unused, and put +in a dummy argument to stop even pickier compilers complaining about infinite +loops. Then use a mutually-recursive pair as gcc is just getting stupid. */ + +#ifndef RADIUS_CONFIG_FILE +static void dummy(int x); +static void dummy2(int x) { dummy(x-1); } +static void dummy(int x) { dummy2(x-1); } +#else /* RADIUS_CONFIG_FILE */ + + +/* Two different Radius libraries are supported. The default is radiusclient, +using its original API. At release 0.4.0 the API changed. */ + +#ifdef RADIUS_LIB_RADLIB +# include +#else +# if !defined(RADIUS_LIB_RADIUSCLIENT) && !defined(RADIUS_LIB_RADIUSCLIENTNEW) +# define RADIUS_LIB_RADIUSCLIENT +# endif + +# ifdef RADIUS_LIB_RADIUSCLIENTNEW +# define ENV FREERADIUSCLIENT_ENV /* Avoid clash with Berkeley DB */ +# include +# else +# include +# endif +#endif + + + +/************************************************* +* Perform RADIUS authentication * +*************************************************/ + +/* This function calls the Radius authentication mechanism, passing over one or +more data strings. + +Arguments: + s a colon-separated list of strings + errptr where to point an error message + +Returns: OK if authentication succeeded + FAIL if authentication failed + ERROR some other error condition +*/ + +static int +auth_call_radius(const uschar *s, uschar **errptr) +{ +uschar *user; +const uschar *radius_args = s; +int result; +int sep = 0; + +#ifdef RADIUS_LIB_RADLIB + struct rad_handle *h; +#else + #ifdef RADIUS_LIB_RADIUSCLIENTNEW + rc_handle *h; + #endif + VALUE_PAIR *send = NULL; + VALUE_PAIR *received; + unsigned int service = PW_AUTHENTICATE_ONLY; + char msg[4096]; +#endif + + +if (!(user = string_nextinlist(&radius_args, &sep, NULL, 0))) user = US""; + +DEBUG(D_auth) debug_printf("Running RADIUS authentication for user \"%s\" " + "and \"%s\"\n", user, radius_args); + +*errptr = NULL; + + +/* Authenticate using the radiusclient library */ + +#ifndef RADIUS_LIB_RADLIB + +rc_openlog("exim"); + +#ifdef RADIUS_LIB_RADIUSCLIENT +if (rc_read_config(RADIUS_CONFIG_FILE) != 0) + *errptr = string_sprintf("RADIUS: can't open %s", RADIUS_CONFIG_FILE); + +else if (rc_read_dictionary(rc_conf_str("dictionary")) != 0) + *errptr = US"RADIUS: can't read dictionary"; + +else if (!rc_avpair_add(&send, PW_USER_NAME, user, 0)) + *errptr = US"RADIUS: add user name failed"; + +else if (!rc_avpair_add(&send, PW_USER_PASSWORD, CS radius_args, 0)) + *errptr = US"RADIUS: add password failed"); + +else if (!rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0)) + *errptr = US"RADIUS: add service type failed"; + +#else /* RADIUS_LIB_RADIUSCLIENT unset => RADIUS_LIB_RADIUSCLIENT2 */ + +if (!(h = rc_read_config(RADIUS_CONFIG_FILE))) + *errptr = string_sprintf("RADIUS: can't open %s", RADIUS_CONFIG_FILE); + +else if (rc_read_dictionary(h, rc_conf_str(h, "dictionary")) != 0) + *errptr = US"RADIUS: can't read dictionary"; + +else if (!rc_avpair_add(h, &send, PW_USER_NAME, user, Ustrlen(user), 0)) + *errptr = US"RADIUS: add user name failed"; + +else if (!rc_avpair_add(h, &send, PW_USER_PASSWORD, CS radius_args, + Ustrlen(radius_args), 0)) + *errptr = US"RADIUS: add password failed"; + +else if (!rc_avpair_add(h, &send, PW_SERVICE_TYPE, &service, 0, 0)) + *errptr = US"RADIUS: add service type failed"; + +#endif /* RADIUS_LIB_RADIUSCLIENT */ + +if (*errptr) + { + DEBUG(D_auth) debug_printf("%s\n", *errptr); + return ERROR; + } + +#ifdef RADIUS_LIB_RADIUSCLIENT +result = rc_auth(0, send, &received, msg); +#else +result = rc_auth(h, 0, send, &received, msg); +#endif + +DEBUG(D_auth) debug_printf("RADIUS code returned %d\n", result); + +switch (result) + { + case OK_RC: + return OK; + + case REJECT_RC: + case ERROR_RC: + return FAIL; + + case TIMEOUT_RC: + *errptr = US"RADIUS: timed out"; + return ERROR; + + case BADRESP_RC: + default: + *errptr = string_sprintf("RADIUS: unexpected response (%d)", result); + return ERROR; + } + +#else /* RADIUS_LIB_RADLIB is set */ + +/* Authenticate using the libradius library */ + +if (!(h = rad_auth_open())) + { + *errptr = string_sprintf("RADIUS: can't initialise libradius"); + return ERROR; + } +if (rad_config(h, RADIUS_CONFIG_FILE) != 0 || + rad_create_request(h, RAD_ACCESS_REQUEST) != 0 || + rad_put_string(h, RAD_USER_NAME, CS user) != 0 || + rad_put_string(h, RAD_USER_PASSWORD, CS radius_args) != 0 || + rad_put_int(h, RAD_SERVICE_TYPE, RAD_AUTHENTICATE_ONLY) != 0 || + rad_put_string(h, RAD_NAS_IDENTIFIER, CS primary_hostname) != 0) + { + *errptr = string_sprintf("RADIUS: %s", rad_strerror(h)); + result = ERROR; + } +else + switch (result = rad_send_request(h)) + { + case RAD_ACCESS_ACCEPT: + result = OK; + break; + + case RAD_ACCESS_REJECT: + result = FAIL; + break; + + case -1: + *errptr = string_sprintf("RADIUS: %s", rad_strerror(h)); + result = ERROR; + break; + + default: + *errptr = string_sprintf("RADIUS: unexpected response (%d)", result); + result= ERROR; + break; + } + +if (*errptr) DEBUG(D_auth) debug_printf("%s\n", *errptr); +rad_close(h); +return result; + +#endif /* RADIUS_LIB_RADLIB */ +} + + + +/******************************************************************************/ +/* Module API */ + +static void * rad_functions[] = { + [RADIUS_AUTH_CALL] = auth_call_radius, +}; + +misc_module_info rad_module_info = +{ + .name = US"radius", +# ifdef DYNLOOKUP + .dyn_magic = MISC_MODULE_MAGIC, +# endif + + .functions = rad_functions, + .functions_count = nelem(rad_functions), +}; + +#endif /* RADIUS_CONFIG_FILE */ + +/* End of call_radius.c */ diff --git a/src/src/miscmods/spf.c b/src/src/miscmods/spf.c index 14937e799..17c1a3602 100644 --- a/src/src/miscmods/spf.c +++ b/src/src/miscmods/spf.c @@ -585,7 +585,7 @@ static var_entry spf_variables[] = { misc_module_info spf_module_info = { .name = US"spf", -# if SUPPORT_SPF==2 +# ifdef DYNLOOKUP .dyn_magic = MISC_MODULE_MAGIC, # endif .init = spf_init,