The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
state.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 18d822c2621ea0eeb1fb24de38194b596723a0c9 $
19 * @file lib/ldap/state.c
20 * @brief Connection state machine for asynchronous LDAP connections
21 *
22 * @copyright 2017 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
23 */
24RCSID("$Id: 18d822c2621ea0eeb1fb24de38194b596723a0c9 $")
25
27
28#include <freeradius-devel/ldap/base.h>
29
30#define STATE_TRANSITION(_new) \
31do { \
32 DEBUG4("Changed state %s -> %s", \
33 fr_table_str_by_value(fr_ldap_connection_states, c->state, "<INVALID>"), \
34 fr_table_str_by_value(fr_ldap_connection_states, _new, "<INVALID>")); \
35 c->state = _new; \
36} while (0)
37
38/** Move between LDAP connection states
39 *
40 * Bringing up an LDAP connection is quite complex, as we need to do multiple operations
41 * before we can install the main mux/demux functions which do the work of sending
42 * requests to the directory and processing the responses.
43 *
44 * This function moves the connection through different states, setting different I/O
45 * handlers.
46 *
47 * If any of the states fail to be entered, the connection is moved to the error
48 * state, which restarts the state machine by signalling a reconnect.
49 */
51{
52again:
53 switch (c->state) {
54 /*
55 * Start by negotiating TLS, or binding
56 */
58 if (c->config->start_tls) {
59 if (fr_ldap_start_tls_async(c, NULL, NULL) < 0) {
61 goto again;
62 }
64 break;
65 }
67
68 /*
69 * If we're successful in negotiating TLS,
70 * bind to the server as the credentials
71 * will now be protected.
72 */
75
76 /*
77 * SASL uses a different (and more complex) codepath
78 */
79#ifdef WITH_SASL
80 if (c->config->admin_sasl.mech) {
87 NULL, NULL) < 0) {
89 goto again;
90 }
91 break;
92 }
93#endif
94
95 /*
96 * Normal binds are just a simple request/response pair
97 */
101 NULL, NULL) < 0) {
103 goto again;
104 }
105 break;
106
107 /*
108 * After binding install the mux (write) and
109 * demux (read) I/O functions.
110 */
114 break;
115
116 /*
117 * Something went wrong
118 */
119 case FR_LDAP_STATE_RUN: /* There's no next state for run, so this an error */
123 /*
124 * The old connection has been freed, so specifically return the INIT state
125 */
126 return FR_LDAP_STATE_INIT;
127 }
128
129 return c->state;
130}
131
132/** Signal that there's been an error on the connection
133 *
134 */
#define USES_APPLE_DEPRECATED_API
Definition build.h:499
#define RCSID(id)
Definition build.h:512
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
Definition build.h:343
@ CONNECTION_FAILED
Connection is being reconnected because it failed.
Definition connection.h:85
char const * mech
SASL mech(s) to try.
Definition base.h:129
char const * proxy
Identity to proxy.
Definition base.h:130
char const * admin_password
Password used in administrative bind.
Definition base.h:231
fr_ldap_state_t state
LDAP connection state machine.
Definition base.h:347
char const * admin_identity
Identity we bind as when we need to query the LDAP directory.
Definition base.h:229
int fr_ldap_bind_async(fr_ldap_connection_t *c, char const *bind_dn, char const *password, LDAPControl **serverctrls, LDAPControl **clientctrls)
Install I/O handlers for the bind operation.
Definition bind.c:187
fr_ldap_state_t
LDAP connection handle states.
Definition base.h:167
@ FR_LDAP_STATE_ERROR
Connection is in an error state.
Definition base.h:172
@ FR_LDAP_STATE_BIND
Connection is being bound.
Definition base.h:170
@ FR_LDAP_STATE_START_TLS
TLS is being negotiated.
Definition base.h:169
@ FR_LDAP_STATE_RUN
Connection is muxing/demuxing requests.
Definition base.h:171
@ FR_LDAP_STATE_INIT
Connection uninitialised.
Definition base.h:168
fr_ldap_config_t const * config
rlm_ldap connection configuration.
Definition base.h:344
bool start_tls
Send the Start TLS message to the LDAP directory to start encrypted communications using the standard...
Definition base.h:258
char const * realm
Kerberos realm.
Definition base.h:131
fr_ldap_sasl_t admin_sasl
SASL parameters used when binding as the admin.
Definition base.h:233
int fr_ldap_start_tls_async(fr_ldap_connection_t *c, LDAPControl **serverctrls, LDAPControl **clientctrls)
Install I/O handlers for Start TLS negotiation.
Definition start_tls.c:223
connection_t * conn
Connection state handle.
Definition base.h:345
Tracks the state of a libldap connection handle.
Definition base.h:332
void fr_ldap_state_error(fr_ldap_connection_t *c)
Signal that there's been an error on the connection.
Definition state.c:135
fr_ldap_state_t fr_ldap_state_next(fr_ldap_connection_t *c)
Move between LDAP connection states.
Definition state.c:50
#define STATE_TRANSITION(_new)
Definition state.c:30
int fr_ldap_sasl_bind_async(fr_ldap_connection_t *c, char const *mechs, char const *identity, char const *password, char const *proxy, char const *realm, LDAPControl **serverctrls, LDAPControl **clientctrls)
Install I/O handlers for the bind operation.
Definition sasl.c:308
void connection_signal_reconnect(connection_t *conn, connection_reason_t reason)
Asynchronously signal the connection should be reconnected.
void connection_signal_connected(connection_t *conn)
Asynchronously signal that the connection is open.