1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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 */
|