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