diff options
author | Volker Lendecke <vl@samba.org> | 2020-08-10 16:24:04 +0200 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2020-08-31 09:26:35 +0000 |
commit | a8dfc1ad59f662ff1f01192c91a8a7d169e0938b (patch) | |
tree | 068f86c159ca3fe14bd2f5dab52965f47f5b73b9 /source4/ldap_server/ldap_server.c | |
parent | 6026130628ea63eade45409360e434f4813f4ebe (diff) | |
download | samba-a8dfc1ad59f662ff1f01192c91a8a7d169e0938b.tar.gz |
ldap_server: Terminate LDAP connections on krb ticket expiry
See RFC4511 section 4.4.1 and
https://lists.samba.org/archive/cifs-protocol/2020-August/003515.html
for details: Windows terminates LDAP connections when the krb5 ticket
expires, Samba should do the same. This patch slightly deviates from
Windows behaviour by sending a LDAP exop response with msgid 0 that is
ASN1-encoded conforming to RFC4511.
Bug: https://bugzilla.samba.org/show_bug.cgi?id=14465
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit eb72f887b0bf91c050fd5d911f58a1b3ff9b8bcc)
Diffstat (limited to 'source4/ldap_server/ldap_server.c')
-rw-r--r-- | source4/ldap_server/ldap_server.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index 3a37ddbcaf9..fd2309b7ce3 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -69,6 +69,7 @@ static void ldapsrv_terminate_connection(struct ldapsrv_connection *conn, tevent_queue_stop(conn->sockets.send_queue); TALLOC_FREE(conn->sockets.read_req); + TALLOC_FREE(conn->deferred_expire_disconnect); if (conn->active_call) { tevent_req_cancel(conn->active_call); conn->active_call = NULL; @@ -1016,16 +1017,62 @@ static struct tevent_req *ldapsrv_process_call_send(TALLOC_CTX *mem_ctx, return req; } +static void ldapsrv_disconnect_ticket_expired(struct tevent_req *subreq); + static void ldapsrv_process_call_trigger(struct tevent_req *req, void *private_data) { struct ldapsrv_process_call_state *state = tevent_req_data(req, struct ldapsrv_process_call_state); + struct ldapsrv_connection *conn = state->call->conn; NTSTATUS status; + if (conn->deferred_expire_disconnect != NULL) { + /* + * Just drop this on the floor + */ + tevent_req_done(req); + return; + } + /* make the call */ status = ldapsrv_do_call(state->call); + + if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) { + /* + * For testing purposes, defer the TCP disconnect + * after having sent the msgid 0 + * 1.3.6.1.4.1.1466.20036 exop response. LDAP clients + * should not wait for the TCP connection to close but + * handle this packet equivalent to a TCP + * disconnect. This delay enables testing both cases + * in LDAP client libraries. + */ + + int defer_msec = lpcfg_parm_int( + conn->lp_ctx, + NULL, + "ldap_server", + "delay_expire_disconnect", + 0); + + conn->deferred_expire_disconnect = tevent_wakeup_send( + conn, + conn->connection->event.ctx, + timeval_current_ofs_msec(defer_msec)); + if (tevent_req_nomem(conn->deferred_expire_disconnect, req)) { + return; + } + tevent_req_set_callback( + conn->deferred_expire_disconnect, + ldapsrv_disconnect_ticket_expired, + conn); + + tevent_req_done(req); + return; + } + if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); return; @@ -1034,6 +1081,21 @@ static void ldapsrv_process_call_trigger(struct tevent_req *req, tevent_req_done(req); } +static void ldapsrv_disconnect_ticket_expired(struct tevent_req *subreq) +{ + struct ldapsrv_connection *conn = tevent_req_callback_data( + subreq, struct ldapsrv_connection); + bool ok; + + ok = tevent_wakeup_recv(subreq); + TALLOC_FREE(subreq); + if (!ok) { + DBG_WARNING("tevent_wakeup_recv failed\n"); + } + conn->deferred_expire_disconnect = NULL; + ldapsrv_terminate_connection(conn, "network session expired"); +} + static NTSTATUS ldapsrv_process_call_recv(struct tevent_req *req) { NTSTATUS status; |