summaryrefslogtreecommitdiffstats
path: root/src/auths/check_serv_cond.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/auths/check_serv_cond.c')
-rw-r--r--src/auths/check_serv_cond.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/auths/check_serv_cond.c b/src/auths/check_serv_cond.c
new file mode 100644
index 0000000..457a715
--- /dev/null
+++ b/src/auths/check_serv_cond.c
@@ -0,0 +1,124 @@
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+#include "../exim.h"
+
+/* This module contains the function server_condition(), which is used
+by all authenticators. */
+
+
+/*************************************************
+* Check server_condition *
+*************************************************/
+
+/* This function is called from the server code of all authenticators. For
+plaintext and gsasl, it is always called: the argument cannot be empty, because
+for those, setting server_condition is what enables it as a server
+authenticator. For all the other authenticators, this function is called after
+they have authenticated, to enable additional authorization to be done.
+
+Argument: the authenticator's instance block
+
+Returns:
+ OK NULL argument, or success
+ DEFER couldn't complete the check
+ FAIL authentication failed
+*/
+
+int
+auth_check_serv_cond(auth_instance *ablock)
+{
+ return auth_check_some_cond(ablock,
+ US"server_condition", ablock->server_condition, OK);
+}
+
+
+/*************************************************
+* Check some server condition *
+*************************************************/
+
+/* This underlies server_condition, but is also used for some more generic
+ checks.
+
+Arguments:
+ ablock the authenticator's instance block
+ label debugging label naming the string checked
+ condition the condition string to be expanded and checked
+ unset value to return on NULL condition
+
+Returns:
+ OK success (or unset=OK)
+ DEFER couldn't complete the check
+ FAIL authentication failed
+*/
+
+int
+auth_check_some_cond(auth_instance *ablock,
+ uschar *label, uschar *condition, int unset)
+{
+uschar *cond;
+
+HDEBUG(D_auth)
+ {
+ debug_printf("%s authenticator %s:\n", ablock->name, label);
+ for (int i = 0; i < AUTH_VARS; i++) if (auth_vars[i])
+ debug_printf(" $auth%d = %s\n", i + 1, auth_vars[i]);
+ for (int i = 1; i <= expand_nmax; i++)
+ debug_printf(" $%d = %.*s\n", i, expand_nlength[i], expand_nstring[i]);
+ debug_print_string(ablock->server_debug_string); /* customized debug */
+ }
+
+/* For the plaintext authenticator, server_condition is never NULL. For the
+rest, an unset condition lets everything through. */
+
+/* For server_condition, an unset condition lets everything through.
+For plaintext/gsasl authenticators, it will have been pre-checked to prevent
+this. We return the unset scenario value given to us, which for
+server_condition will be OK and otherwise will typically be FAIL. */
+
+if (!condition) return unset;
+cond = expand_string(condition);
+
+HDEBUG(D_auth)
+ if (!cond)
+ debug_printf("expansion failed: %s\n", expand_string_message);
+ else
+ debug_printf("expanded string: %s\n", cond);
+
+/* A forced expansion failure causes authentication to fail. Other expansion
+failures yield DEFER, which will cause a temporary error code to be returned to
+the AUTH command. The problem is at the server end, so the client should try
+again later. */
+
+if (!cond)
+ {
+ if (f.expand_string_forcedfail) return FAIL;
+ auth_defer_msg = expand_string_message;
+ return DEFER;
+ }
+
+/* Return FAIL for empty string, "0", "no", and "false"; return OK for
+"1", "yes", and "true"; return DEFER for anything else, with the string
+available as an error text for the user. */
+
+if (*cond == 0 ||
+ Ustrcmp(cond, "0") == 0 ||
+ strcmpic(cond, US"no") == 0 ||
+ strcmpic(cond, US"false") == 0)
+ return FAIL;
+
+if (Ustrcmp(cond, "1") == 0 ||
+ strcmpic(cond, US"yes") == 0 ||
+ strcmpic(cond, US"true") == 0)
+ return OK;
+
+auth_defer_msg = cond;
+auth_defer_user_msg = string_sprintf(": %s", cond);
+return DEFER;
+}
+
+/* End of check_serv_cond.c */