-/* $Cambridge: exim/src/src/auths/call_radius.c,v 1.8 2009/11/16 19:50:38 nm4 Exp $ */
-
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) The Exim Maintainers 2020 - 2021 */
+/* Copyright (c) University of Cambridge 1995 - 2016 */
/* See the file NOTICE for conditions of use and distribution. */
/* This file was originally supplied by Ian Kirk. The libradius support came
from Alex Kiernan. */
+/* ugly hack to work around redefinition of ENV by radiusclient.h and
+ * db.h: define _DB_H_ so the db.h include thinks it's already included,
+ * we can get away with it like this, since this file doesn't use any db
+ * functions. */
+#ifndef _DB_H_
+# define _DB_H_ 1
+# define _DB_EXT_PROT_IN_ 1
+# define DB void
+#endif
+
#include "../exim.h"
/* This module contains functions that call the Radius authentication
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. */
+loops. Then use a mutually-recursive pair as gcc is just getting stupid. */
#ifndef RADIUS_CONFIG_FILE
-static void dummy(int x) { dummy(x-1); }
+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 */
#include <radlib.h>
#else
#if !defined(RADIUS_LIB_RADIUSCLIENT) && !defined(RADIUS_LIB_RADIUSCLIENTNEW)
- #define RADIUS_LIB_RADIUSCLIENT
+ # define RADIUS_LIB_RADIUSCLIENT
+ #endif
+
+ #ifdef RADIUS_LIB_RADIUSCLIENTNEW
+ # include <freeradius-client.h>
+ #else
+ # include <radiusclient.h>
#endif
- #include <radiusclient.h>
#endif
*/
int
-auth_call_radius(uschar *s, uschar **errptr)
+auth_call_radius(const uschar *s, uschar **errptr)
{
uschar *user;
-uschar *radius_args = s;
+const uschar *radius_args = s;
int result;
int sep = 0;
#endif
-user = string_nextinlist(&radius_args, &sep, big_buffer, big_buffer_size);
-if (user == NULL) user = US"";
+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 = string_sprintf("RADIUS: can't open %s", RADIUS_CONFIG_FILE);
else if (rc_read_dictionary(rc_conf_str("dictionary")) != 0)
- *errptr = string_sprintf("RADIUS: can't read dictionary");
+ *errptr = US"RADIUS: can't read dictionary";
-else if (rc_avpair_add(&send, PW_USER_NAME, user, 0) == NULL)
- *errptr = string_sprintf("RADIUS: add user name failed\n");
+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) == NULL)
- *errptr = string_sprintf("RADIUS: add password failed\n");
+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) == NULL)
- *errptr = string_sprintf("RADIUS: add service type failed\n");
+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)) == NULL)
+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 = string_sprintf("RADIUS: can't read dictionary");
+ *errptr = US"RADIUS: can't read dictionary";
-else if (rc_avpair_add(h, &send, PW_USER_NAME, user, Ustrlen(user), 0) == NULL)
- *errptr = string_sprintf("RADIUS: add user name failed\n");
+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) == NULL)
- *errptr = string_sprintf("RADIUS: add password failed\n");
+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) == NULL)
- *errptr = string_sprintf("RADIUS: add service type failed\n");
+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 != NULL)
+if (*errptr)
{
DEBUG(D_auth) debug_printf("%s\n", *errptr);
return ERROR;
switch (result)
{
case OK_RC:
- return OK;
+ return OK;
+ case REJECT_RC:
case ERROR_RC:
- return FAIL;
+ return FAIL;
case TIMEOUT_RC:
- *errptr = US"RADIUS: timed out";
- return ERROR;
+ *errptr = US"RADIUS: timed out";
+ return ERROR;
- default:
case BADRESP_RC:
- *errptr = string_sprintf("RADIUS: unexpected response (%d)", result);
- return ERROR;
+ default:
+ *errptr = string_sprintf("RADIUS: unexpected response (%d)", result);
+ return ERROR;
}
#else /* RADIUS_LIB_RADLIB is set */
/* Authenticate using the libradius library */
-h = rad_auth_open();
-if (h == NULL)
+if (!(h = rad_auth_open()))
{
*errptr = string_sprintf("RADIUS: can't initialise libradius");
return ERROR;
result = ERROR;
}
else
- {
- result = rad_send_request(h);
-
- switch(result)
+ switch (result = rad_send_request(h))
{
case RAD_ACCESS_ACCEPT:
- result = OK;
- break;
+ result = OK;
+ break;
case RAD_ACCESS_REJECT:
- result = FAIL;
- break;
+ result = FAIL;
+ break;
case -1:
- *errptr = string_sprintf("RADIUS: %s", rad_strerror(h));
- result = ERROR;
- break;
+ *errptr = string_sprintf("RADIUS: %s", rad_strerror(h));
+ result = ERROR;
+ break;
default:
- *errptr = string_sprintf("RADIUS: unexpected response (%d)", result);
- result= ERROR;
- break;
+ *errptr = string_sprintf("RADIUS: unexpected response (%d)", result);
+ result= ERROR;
+ break;
}
- }
-if (*errptr != NULL) DEBUG(D_auth) debug_printf("%s\n", *errptr);
+if (*errptr) DEBUG(D_auth) debug_printf("%s\n", *errptr);
rad_close(h);
return result;