SPDX: license tags (mostly by guesswork)
[exim.git] / src / src / auths / check_serv_cond.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2012 */
6 /* See the file NOTICE for conditions of use and distribution. */
7 /* SPDX-License-Identifier: GPL-2.0-only */
8
9 #include "../exim.h"
10
11 /* This module contains the function server_condition(), which is used
12 by all authenticators. */
13
14
15 /*************************************************
16 *              Check server_condition            *
17 *************************************************/
18
19 /* This function is called from the server code of all authenticators. For
20 plaintext and gsasl, it is always called: the argument cannot be empty, because
21 for those, setting server_condition is what enables it as a server
22 authenticator. For all the other authenticators, this function is called after
23 they have authenticated, to enable additional authorization to be done.
24
25 Argument:     the authenticator's instance block
26
27 Returns:
28   OK          NULL argument, or success
29   DEFER       couldn't complete the check
30   FAIL        authentication failed
31 */
32
33 int
34 auth_check_serv_cond(auth_instance *ablock)
35 {
36   return auth_check_some_cond(ablock,
37       US"server_condition", ablock->server_condition, OK);
38 }
39
40
41 /*************************************************
42 *         Check some server condition            *
43 *************************************************/
44
45 /* This underlies server_condition, but is also used for some more generic
46  checks.
47
48 Arguments:
49   ablock     the authenticator's instance block
50   label      debugging label naming the string checked
51   condition  the condition string to be expanded and checked
52   unset      value to return on NULL condition
53
54 Returns:
55   OK          success (or unset=OK)
56   DEFER       couldn't complete the check
57   FAIL        authentication failed
58 */
59
60 int
61 auth_check_some_cond(auth_instance *ablock,
62     uschar *label, uschar *condition, int unset)
63 {
64 uschar *cond;
65
66 HDEBUG(D_auth)
67   {
68   debug_printf("%s authenticator %s:\n", ablock->name, label);
69   for (int i = 0; i < AUTH_VARS; i++) if (auth_vars[i])
70     debug_printf("  $auth%d = %s\n", i + 1, auth_vars[i]);
71   for (int i = 1; i <= expand_nmax; i++)
72     debug_printf("  $%d = %.*s\n", i, expand_nlength[i], expand_nstring[i]);
73   debug_print_string(ablock->server_debug_string);    /* customized debug */
74   }
75
76 /* For the plaintext authenticator, server_condition is never NULL. For the
77 rest, an unset condition lets everything through. */
78
79 /* For server_condition, an unset condition lets everything through.
80 For plaintext/gsasl authenticators, it will have been pre-checked to prevent
81 this.  We return the unset scenario value given to us, which for
82 server_condition will be OK and otherwise will typically be FAIL. */
83
84 if (!condition) return unset;
85 cond = expand_string(condition);
86
87 HDEBUG(D_auth)
88   if (!cond)
89     debug_printf("expansion failed: %s\n", expand_string_message);
90   else
91     debug_printf("expanded string: %s\n", cond);
92
93 /* A forced expansion failure causes authentication to fail. Other expansion
94 failures yield DEFER, which will cause a temporary error code to be returned to
95 the AUTH command. The problem is at the server end, so the client should try
96 again later. */
97
98 if (!cond)
99   {
100   if (f.expand_string_forcedfail) return FAIL;
101   auth_defer_msg = expand_string_message;
102   return DEFER;
103   }
104
105 /* Return FAIL for empty string, "0", "no", and "false"; return OK for
106 "1", "yes", and "true"; return DEFER for anything else, with the string
107 available as an error text for the user. */
108
109 if (*cond == 0 ||
110     Ustrcmp(cond, "0") == 0 ||
111     strcmpic(cond, US"no") == 0 ||
112     strcmpic(cond, US"false") == 0)
113   return FAIL;
114
115 if (Ustrcmp(cond, "1") == 0 ||
116     strcmpic(cond, US"yes") == 0 ||
117     strcmpic(cond, US"true") == 0)
118   return OK;
119
120 auth_defer_msg = cond;
121 auth_defer_user_msg = string_sprintf(": %s", cond);
122 return DEFER;
123 }
124
125 /* End of check_serv_cond.c */