LCOV - code coverage report
Current view: top level - source4/ldap_server - ldap_server.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 608 808 75.2 %
Date: 2024-05-31 13:13:24 Functions: 30 32 93.8 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    LDAP server
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2005
       7             :    Copyright (C) Volker Lendecke 2004
       8             :    Copyright (C) Stefan Metzmacher 2004
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "system/network.h"
      26             : #include "lib/events/events.h"
      27             : #include "auth/auth.h"
      28             : #include "auth/credentials/credentials.h"
      29             : #include "librpc/gen_ndr/ndr_samr.h"
      30             : #include "../lib/util/dlinklist.h"
      31             : #include "../lib/util/asn1.h"
      32             : #include "ldap_server/ldap_server.h"
      33             : #include "samba/service_task.h"
      34             : #include "samba/service_stream.h"
      35             : #include "samba/service.h"
      36             : #include "samba/process_model.h"
      37             : #include "lib/tls/tls.h"
      38             : #include "lib/messaging/irpc.h"
      39             : #include <ldb.h>
      40             : #include <ldb_errors.h>
      41             : #include "libcli/ldap/ldap_proto.h"
      42             : #include "system/network.h"
      43             : #include "lib/socket/netif.h"
      44             : #include "dsdb/samdb/samdb.h"
      45             : #include "param/param.h"
      46             : #include "../lib/tsocket/tsocket.h"
      47             : #include "../lib/util/tevent_ntstatus.h"
      48             : #include "../libcli/util/tstream.h"
      49             : #include "libds/common/roles.h"
      50             : #include "lib/util/time.h"
      51             : #include "lib/util/server_id.h"
      52             : #include "lib/util/server_id_db.h"
      53             : #include "lib/messaging/messaging_internal.h"
      54             : 
      55             : #undef strcasecmp
      56             : 
      57             : static void ldapsrv_terminate_connection_done(struct tevent_req *subreq);
      58             : 
      59             : /*
      60             :   close the socket and shutdown a server_context
      61             : */
      62       27423 : static void ldapsrv_terminate_connection(struct ldapsrv_connection *conn,
      63             :                                          const char *reason)
      64             : {
      65         122 :         struct tevent_req *subreq;
      66             : 
      67       27423 :         if (conn->limits.reason) {
      68           0 :                 return;
      69             :         }
      70             : 
      71       27423 :         DLIST_REMOVE(conn->service->connections, conn);
      72             : 
      73       27423 :         conn->limits.endtime = timeval_current_ofs(0, 500);
      74             : 
      75       27423 :         tevent_queue_stop(conn->sockets.send_queue);
      76       27423 :         TALLOC_FREE(conn->sockets.read_req);
      77       27423 :         TALLOC_FREE(conn->deferred_expire_disconnect);
      78       27423 :         if (conn->active_call) {
      79           0 :                 tevent_req_cancel(conn->active_call);
      80           0 :                 conn->active_call = NULL;
      81             :         }
      82             : 
      83       27423 :         conn->limits.reason = talloc_strdup(conn, reason);
      84       27423 :         if (conn->limits.reason == NULL) {
      85           0 :                 TALLOC_FREE(conn->sockets.tls);
      86           0 :                 TALLOC_FREE(conn->sockets.sasl);
      87           0 :                 TALLOC_FREE(conn->sockets.raw);
      88           0 :                 stream_terminate_connection(conn->connection, reason);
      89           0 :                 return;
      90             :         }
      91             : 
      92       27545 :         subreq = tstream_disconnect_send(conn,
      93       27423 :                                          conn->connection->event.ctx,
      94             :                                          conn->sockets.active);
      95       27423 :         if (subreq == NULL) {
      96           0 :                 TALLOC_FREE(conn->sockets.tls);
      97           0 :                 TALLOC_FREE(conn->sockets.sasl);
      98           0 :                 TALLOC_FREE(conn->sockets.raw);
      99           0 :                 stream_terminate_connection(conn->connection, reason);
     100           0 :                 return;
     101             :         }
     102       27423 :         tevent_req_set_endtime(subreq,
     103       27423 :                                conn->connection->event.ctx,
     104             :                                conn->limits.endtime);
     105       27423 :         tevent_req_set_callback(subreq, ldapsrv_terminate_connection_done, conn);
     106             : }
     107             : 
     108       54128 : static void ldapsrv_terminate_connection_done(struct tevent_req *subreq)
     109             : {
     110         244 :         struct ldapsrv_connection *conn =
     111       54128 :                 tevent_req_callback_data(subreq,
     112             :                 struct ldapsrv_connection);
     113         244 :         int sys_errno;
     114         244 :         bool ok;
     115             : 
     116       54128 :         tstream_disconnect_recv(subreq, &sys_errno);
     117       54128 :         TALLOC_FREE(subreq);
     118             : 
     119       54128 :         if (conn->sockets.active == conn->sockets.raw) {
     120       27423 :                 TALLOC_FREE(conn->sockets.tls);
     121       27423 :                 TALLOC_FREE(conn->sockets.sasl);
     122       27423 :                 TALLOC_FREE(conn->sockets.raw);
     123       27423 :                 stream_terminate_connection(conn->connection,
     124             :                                             conn->limits.reason);
     125       12344 :                 return;
     126             :         }
     127             : 
     128       26705 :         TALLOC_FREE(conn->sockets.tls);
     129       26705 :         TALLOC_FREE(conn->sockets.sasl);
     130       26705 :         conn->sockets.active = conn->sockets.raw;
     131             : 
     132       26827 :         subreq = tstream_disconnect_send(conn,
     133       26705 :                                          conn->connection->event.ctx,
     134             :                                          conn->sockets.active);
     135       26705 :         if (subreq == NULL) {
     136           0 :                 TALLOC_FREE(conn->sockets.raw);
     137           0 :                 stream_terminate_connection(conn->connection,
     138             :                                             conn->limits.reason);
     139           0 :                 return;
     140             :         }
     141       26827 :         ok = tevent_req_set_endtime(subreq,
     142       26705 :                                     conn->connection->event.ctx,
     143             :                                     conn->limits.endtime);
     144       26705 :         if (!ok) {
     145           0 :                 TALLOC_FREE(conn->sockets.raw);
     146           0 :                 stream_terminate_connection(conn->connection,
     147             :                                             conn->limits.reason);
     148           0 :                 return;
     149             :         }
     150       26705 :         tevent_req_set_callback(subreq, ldapsrv_terminate_connection_done, conn);
     151             : }
     152             : 
     153             : /*
     154             :   called when a LDAP socket becomes readable
     155             : */
     156           0 : void ldapsrv_recv(struct stream_connection *c, uint16_t flags)
     157             : {
     158           0 :         smb_panic(__location__);
     159             : }
     160             : 
     161             : /*
     162             :   called when a LDAP socket becomes writable
     163             : */
     164           0 : static void ldapsrv_send(struct stream_connection *c, uint16_t flags)
     165             : {
     166           0 :         smb_panic(__location__);
     167             : }
     168             : 
     169       27426 : static int ldapsrv_load_limits(struct ldapsrv_connection *conn)
     170             : {
     171         122 :         TALLOC_CTX *tmp_ctx;
     172       27426 :         const char *attrs[] = { "configurationNamingContext", NULL };
     173       27426 :         const char *attrs2[] = { "lDAPAdminLimits", NULL };
     174         122 :         struct ldb_message_element *el;
     175       27426 :         struct ldb_result *res = NULL;
     176         122 :         struct ldb_dn *basedn;
     177         122 :         struct ldb_dn *conf_dn;
     178         122 :         struct ldb_dn *policy_dn;
     179         122 :         unsigned int i;
     180         122 :         int ret;
     181             : 
     182             :         /* set defaults limits in case of failure */
     183       27426 :         conn->limits.initial_timeout = 120;
     184       27426 :         conn->limits.conn_idle_time = 900;
     185       27426 :         conn->limits.max_page_size = 1000;
     186       27426 :         conn->limits.max_notifications = 5;
     187       27426 :         conn->limits.search_timeout = 120;
     188       27548 :         conn->limits.expire_time = (struct timeval) {
     189       27426 :                 .tv_sec = get_time_t_max(),
     190             :         };
     191             : 
     192             : 
     193       27426 :         tmp_ctx = talloc_new(conn);
     194       27426 :         if (tmp_ctx == NULL) {
     195           0 :                 return -1;
     196             :         }
     197             : 
     198       27426 :         basedn = ldb_dn_new(tmp_ctx, conn->ldb, NULL);
     199       27426 :         if (basedn == NULL) {
     200           0 :                 goto failed;
     201             :         }
     202             : 
     203       27426 :         ret = ldb_search(conn->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_BASE, attrs, NULL);
     204       27426 :         if (ret != LDB_SUCCESS) {
     205           0 :                 goto failed;
     206             :         }
     207             : 
     208       27426 :         if (res->count != 1) {
     209           0 :                 goto failed;
     210             :         }
     211             : 
     212       27426 :         conf_dn = ldb_msg_find_attr_as_dn(conn->ldb, tmp_ctx, res->msgs[0], "configurationNamingContext");
     213       27426 :         if (conf_dn == NULL) {
     214           0 :                 goto failed;
     215             :         }
     216             : 
     217       27426 :         policy_dn = ldb_dn_copy(tmp_ctx, conf_dn);
     218       27426 :         ldb_dn_add_child_fmt(policy_dn, "CN=Default Query Policy,CN=Query-Policies,CN=Directory Service,CN=Windows NT,CN=Services");
     219       27426 :         if (policy_dn == NULL) {
     220           0 :                 goto failed;
     221             :         }
     222             : 
     223       27426 :         ret = ldb_search(conn->ldb, tmp_ctx, &res, policy_dn, LDB_SCOPE_BASE, attrs2, NULL);
     224       27426 :         if (ret != LDB_SUCCESS) {
     225           0 :                 goto failed;
     226             :         }
     227             : 
     228       27426 :         if (res->count != 1) {
     229           0 :                 goto failed;
     230             :         }
     231             : 
     232       27426 :         el = ldb_msg_find_element(res->msgs[0], "lDAPAdminLimits");
     233       27426 :         if (el == NULL) {
     234           0 :                 goto failed;
     235             :         }
     236             : 
     237      383964 :         for (i = 0; i < el->num_values; i++) {
     238        1586 :                 char policy_name[256];
     239        1586 :                 int policy_value, s;
     240             : 
     241      356538 :                 s = sscanf((const char *)el->values[i].data, "%255[^=]=%d", policy_name, &policy_value);
     242      356538 :                 if (s != 2 || policy_value == 0)
     243      137130 :                         continue;
     244      356538 :                 if (strcasecmp("InitRecvTimeout", policy_name) == 0) {
     245       27426 :                         conn->limits.initial_timeout = policy_value;
     246       27426 :                         continue;
     247             :                 }
     248      329112 :                 if (strcasecmp("MaxConnIdleTime", policy_name) == 0) {
     249       27426 :                         conn->limits.conn_idle_time = policy_value;
     250       27426 :                         continue;
     251             :                 }
     252      301686 :                 if (strcasecmp("MaxPageSize", policy_name) == 0) {
     253       27426 :                         conn->limits.max_page_size = policy_value;
     254       27426 :                         continue;
     255             :                 }
     256      274260 :                 if (strcasecmp("MaxNotificationPerConn", policy_name) == 0) {
     257       27426 :                         conn->limits.max_notifications = policy_value;
     258       27426 :                         continue;
     259             :                 }
     260      246834 :                 if (strcasecmp("MaxQueryDuration", policy_name) == 0) {
     261       27426 :                         if (policy_value > 0) {
     262       27426 :                                 conn->limits.search_timeout = policy_value;
     263             :                         }
     264       27426 :                         continue;
     265             :                 }
     266             :         }
     267             : 
     268       27304 :         return 0;
     269             : 
     270           0 : failed:
     271           0 :         DBG_ERR("Failed to load ldap server query policies\n");
     272           0 :         talloc_free(tmp_ctx);
     273           0 :         return -1;
     274             : }
     275             : 
     276      635535 : static int ldapsrv_call_destructor(struct ldapsrv_call *call)
     277             : {
     278      635535 :         if (call->conn == NULL) {
     279           0 :                 return 0;
     280             :         }
     281             : 
     282      635535 :         DLIST_REMOVE(call->conn->pending_calls, call);
     283             : 
     284      635535 :         call->conn = NULL;
     285      635535 :         return 0;
     286             : }
     287             : 
     288             : static struct tevent_req *ldapsrv_process_call_send(TALLOC_CTX *mem_ctx,
     289             :                                                     struct tevent_context *ev,
     290             :                                                     struct tevent_queue *call_queue,
     291             :                                                     struct ldapsrv_call *call);
     292             : static NTSTATUS ldapsrv_process_call_recv(struct tevent_req *req);
     293             : 
     294             : static bool ldapsrv_call_read_next(struct ldapsrv_connection *conn);
     295             : static void ldapsrv_accept_tls_done(struct tevent_req *subreq);
     296             : 
     297             : /*
     298             :   initialise a server_context from a open socket and register a event handler
     299             :   for reading from that socket
     300             : */
     301       27426 : static void ldapsrv_accept(struct stream_connection *c,
     302             :                            struct auth_session_info *session_info,
     303             :                            bool is_privileged,
     304             :                            bool is_ldapi)
     305             : {
     306         122 :         struct ldapsrv_service *ldapsrv_service =
     307       27426 :                 talloc_get_type(c->private_data, struct ldapsrv_service);
     308         122 :         struct ldapsrv_connection *conn;
     309         122 :         struct cli_credentials *server_credentials;
     310         122 :         struct socket_address *socket_address;
     311         122 :         int port;
     312         122 :         int ret;
     313         122 :         struct tevent_req *subreq;
     314         122 :         struct timeval endtime;
     315       27426 :         char *errstring = NULL;
     316             : 
     317       27426 :         conn = talloc_zero(c, struct ldapsrv_connection);
     318       27426 :         if (!conn) {
     319           0 :                 stream_terminate_connection(c, "ldapsrv_accept: out of memory");
     320       26859 :                 return;
     321             :         }
     322       27426 :         conn->is_privileged = is_privileged;
     323       27426 :         conn->is_ldapi = is_ldapi;
     324             : 
     325       27426 :         conn->sockets.send_queue = tevent_queue_create(conn, "ldapsrv send queue");
     326       27426 :         if (conn->sockets.send_queue == NULL) {
     327           0 :                 stream_terminate_connection(c,
     328             :                                             "ldapsrv_accept: tevent_queue_create failed");
     329           0 :                 return;
     330             :         }
     331             : 
     332       27426 :         TALLOC_FREE(c->event.fde);
     333             : 
     334       27426 :         ret = tstream_bsd_existing_socket(conn,
     335             :                                           socket_get_fd(c->socket),
     336             :                                           &conn->sockets.raw);
     337       27426 :         if (ret == -1) {
     338           0 :                 stream_terminate_connection(c,
     339             :                                             "ldapsrv_accept: out of memory");
     340           0 :                 return;
     341             :         }
     342       27426 :         socket_set_flags(c->socket, SOCKET_FLAG_NOCLOSE);
     343             :         /* as server we want to fail early */
     344       27426 :         tstream_bsd_fail_readv_first_error(conn->sockets.raw, true);
     345             : 
     346       27426 :         conn->connection  = c;
     347       27426 :         conn->service     = ldapsrv_service;
     348       27426 :         conn->lp_ctx      = ldapsrv_service->lp_ctx;
     349             : 
     350       27426 :         c->private_data   = conn;
     351             : 
     352       27426 :         socket_address = socket_get_my_addr(c->socket, conn);
     353       27426 :         if (!socket_address) {
     354           0 :                 ldapsrv_terminate_connection(conn, "ldapsrv_accept: failed to obtain local socket address!");
     355           0 :                 return;
     356             :         }
     357       27426 :         port = socket_address->port;
     358       27426 :         talloc_free(socket_address);
     359       27426 :         if (port == 3268 || port == 3269) /* Global catalog */ {
     360           3 :                 conn->global_catalog = true;
     361             :         }
     362             : 
     363       27426 :         server_credentials = cli_credentials_init_server(conn, conn->lp_ctx);
     364       27426 :         if (!server_credentials) {
     365           0 :                 stream_terminate_connection(c, "Failed to init server credentials\n");
     366           0 :                 return;
     367             :         }
     368             : 
     369       27426 :         conn->server_credentials = server_credentials;
     370             : 
     371       27426 :         conn->session_info = session_info;
     372             : 
     373       27426 :         conn->sockets.active = conn->sockets.raw;
     374             : 
     375       27426 :         if (conn->is_privileged) {
     376          70 :                 conn->require_strong_auth = LDAP_SERVER_REQUIRE_STRONG_AUTH_NO;
     377             :         } else {
     378       27356 :                 conn->require_strong_auth = lpcfg_ldap_server_require_strong_auth(conn->lp_ctx);
     379             :         }
     380             : 
     381       27426 :         if (conn->require_strong_auth ==
     382             :             LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS)
     383             :         {
     384           0 :                 D_ERR("WARNING: You have not configured "
     385             :                       "'ldap server require strong auth = "
     386             :                       "allow_sasl_over_tls'.\n"
     387             :                       "Please change to 'yes' (preferred and default) or "
     388             :                       "'allow_sasl_without_tls_channel_bindings' "
     389             :                       "(if really needed)\n\n");
     390             :         }
     391             : 
     392       27426 :         ret = ldapsrv_backend_Init(conn, &errstring);
     393       27426 :         if (ret != LDB_SUCCESS) {
     394           0 :                 char *reason = talloc_asprintf(conn,
     395             :                                                "LDB backend for LDAP Init "
     396             :                                                "failed: %s: %s",
     397             :                                                errstring, ldb_strerror(ret));
     398           0 :                 ldapsrv_terminate_connection(conn, reason);
     399           0 :                 return;
     400             :         }
     401             : 
     402             :         /* load limits from the conf partition */
     403       27426 :         ldapsrv_load_limits(conn); /* should we fail on error ? */
     404             : 
     405             :         /* register the server */
     406       27426 :         irpc_add_name(c->msg_ctx, "ldap_server");
     407             : 
     408       27426 :         DLIST_ADD_END(ldapsrv_service->connections, conn);
     409             : 
     410       27426 :         if (port != 636 && port != 3269) {
     411       26859 :                 ldapsrv_call_read_next(conn);
     412       26859 :                 return;
     413             :         }
     414             : 
     415         567 :         endtime = timeval_current_ofs(conn->limits.conn_idle_time, 0);
     416             : 
     417         567 :         subreq = tstream_tls_accept_send(conn,
     418             :                                          conn->connection->event.ctx,
     419             :                                          conn->sockets.raw,
     420             :                                          conn->service->tls_params);
     421         567 :         if (subreq == NULL) {
     422           0 :                 ldapsrv_terminate_connection(conn, "ldapsrv_accept: "
     423             :                                 "no memory for tstream_tls_accept_send");
     424           0 :                 return;
     425             :         }
     426         567 :         tevent_req_set_endtime(subreq,
     427         567 :                                conn->connection->event.ctx,
     428             :                                endtime);
     429         567 :         tevent_req_set_callback(subreq, ldapsrv_accept_tls_done, conn);
     430             : }
     431             : 
     432         567 : static void ldapsrv_accept_tls_done(struct tevent_req *subreq)
     433             : {
     434           0 :         struct ldapsrv_connection *conn =
     435         567 :                 tevent_req_callback_data(subreq,
     436             :                 struct ldapsrv_connection);
     437           0 :         int ret;
     438           0 :         int sys_errno;
     439             : 
     440         567 :         ret = tstream_tls_accept_recv(subreq, &sys_errno,
     441             :                                       conn, &conn->sockets.tls);
     442         567 :         TALLOC_FREE(subreq);
     443         567 :         if (ret == -1) {
     444           0 :                 const char *reason;
     445             : 
     446           1 :                 reason = talloc_asprintf(conn, "ldapsrv_accept_tls_loop: "
     447             :                                          "tstream_tls_accept_recv() - %d:%s",
     448             :                                          sys_errno, strerror(sys_errno));
     449           1 :                 if (!reason) {
     450           0 :                         reason = "ldapsrv_accept_tls_loop: "
     451             :                                  "tstream_tls_accept_recv() - failed";
     452             :                 }
     453             : 
     454           1 :                 ldapsrv_terminate_connection(conn, reason);
     455           1 :                 return;
     456             :         }
     457             : 
     458         566 :         conn->sockets.active = conn->sockets.tls;
     459         566 :         conn->referral_scheme = LDAP_REFERRAL_SCHEME_LDAPS;
     460         566 :         ldapsrv_call_read_next(conn);
     461             : }
     462             : 
     463             : static void ldapsrv_call_read_done(struct tevent_req *subreq);
     464             : static NTSTATUS ldapsrv_packet_check(
     465             :         struct tstream_context *stream,
     466             :         void *private_data,
     467             :         DATA_BLOB blob,
     468             :         size_t *packet_size);
     469             : 
     470      635542 : static bool ldapsrv_call_read_next(struct ldapsrv_connection *conn)
     471             : {
     472         709 :         struct tevent_req *subreq;
     473             : 
     474      635542 :         if (conn->pending_calls != NULL) {
     475        4779 :                 conn->limits.endtime = timeval_zero();
     476             : 
     477        4779 :                 ldapsrv_notification_retry_setup(conn->service, false);
     478      630763 :         } else if (timeval_is_zero(&conn->limits.endtime)) {
     479         122 :                 conn->limits.endtime =
     480       27500 :                         timeval_current_ofs(conn->limits.initial_timeout, 0);
     481             :         } else {
     482         587 :                 conn->limits.endtime =
     483      603263 :                         timeval_current_ofs(conn->limits.conn_idle_time, 0);
     484             :         }
     485             : 
     486      635542 :         if (conn->sockets.read_req != NULL) {
     487           2 :                 return true;
     488             :         }
     489             : 
     490             :         /*
     491             :          * The minimum size of a LDAP pdu is 7 bytes
     492             :          *
     493             :          * dumpasn1 -hh ldap-unbind-min.dat
     494             :          *
     495             :          *     <30 05 02 01 09 42 00>
     496             :          *    0    5: SEQUENCE {
     497             :          *     <02 01 09>
     498             :          *    2    1:   INTEGER 9
     499             :          *     <42 00>
     500             :          *    5    0:   [APPLICATION 2]
     501             :          *          :     Error: Object has zero length.
     502             :          *          :   }
     503             :          *
     504             :          * dumpasn1 -hh ldap-unbind-windows.dat
     505             :          *
     506             :          *     <30 84 00 00 00 05 02 01 09 42 00>
     507             :          *    0    5: SEQUENCE {
     508             :          *     <02 01 09>
     509             :          *    6    1:   INTEGER 9
     510             :          *     <42 00>
     511             :          *    9    0:   [APPLICATION 2]
     512             :          *          :     Error: Object has zero length.
     513             :          *          :   }
     514             :          *
     515             :          * This means using an initial read size
     516             :          * of 7 is ok.
     517             :          */
     518      636249 :         subreq = tstream_read_pdu_blob_send(conn,
     519      635540 :                                             conn->connection->event.ctx,
     520             :                                             conn->sockets.active,
     521             :                                             7, /* initial_read_size */
     522             :                                             ldapsrv_packet_check,
     523             :                                             conn);
     524      635540 :         if (subreq == NULL) {
     525           0 :                 ldapsrv_terminate_connection(conn, "ldapsrv_call_read_next: "
     526             :                                 "no memory for tstream_read_pdu_blob_send");
     527           0 :                 return false;
     528             :         }
     529      635540 :         if (!timeval_is_zero(&conn->limits.endtime)) {
     530         709 :                 bool ok;
     531      631472 :                 ok = tevent_req_set_endtime(subreq,
     532      630763 :                                             conn->connection->event.ctx,
     533             :                                             conn->limits.endtime);
     534      630763 :                 if (!ok) {
     535           0 :                         ldapsrv_terminate_connection(
     536             :                                 conn,
     537             :                                 "ldapsrv_call_read_next: "
     538             :                                 "no memory for tevent_req_set_endtime");
     539           0 :                         return false;
     540             :                 }
     541             :         }
     542      635540 :         tevent_req_set_callback(subreq, ldapsrv_call_read_done, conn);
     543      635540 :         conn->sockets.read_req = subreq;
     544      635540 :         return true;
     545             : }
     546             : 
     547             : static void ldapsrv_call_process_done(struct tevent_req *subreq);
     548             : static int ldapsrv_check_packet_size(
     549             :         struct ldapsrv_connection *conn,
     550             :         size_t size);
     551             : 
     552      635535 : static void ldapsrv_call_read_done(struct tevent_req *subreq)
     553             : {
     554         709 :         struct ldapsrv_connection *conn =
     555      635535 :                 tevent_req_callback_data(subreq,
     556             :                 struct ldapsrv_connection);
     557         709 :         NTSTATUS status;
     558         709 :         struct ldapsrv_call *call;
     559         709 :         struct asn1_data *asn1;
     560         709 :         DATA_BLOB blob;
     561      635535 :         int ret = LDAP_SUCCESS;
     562      635535 :         struct ldap_request_limits limits = {0};
     563             : 
     564      635535 :         conn->sockets.read_req = NULL;
     565             : 
     566      635535 :         call = talloc_zero(conn, struct ldapsrv_call);
     567      635535 :         if (!call) {
     568           0 :                 ldapsrv_terminate_connection(conn, "no memory");
     569       27397 :                 return;
     570             :         }
     571      635535 :         talloc_set_destructor(call, ldapsrv_call_destructor);
     572             : 
     573      635535 :         call->conn = conn;
     574             : 
     575      635535 :         status = tstream_read_pdu_blob_recv(subreq,
     576             :                                             call,
     577             :                                             &blob);
     578      635535 :         TALLOC_FREE(subreq);
     579      635535 :         if (!NT_STATUS_IS_OK(status)) {
     580         122 :                 const char *reason;
     581             : 
     582       27395 :                 reason = talloc_asprintf(call, "ldapsrv_call_loop: "
     583             :                                          "tstream_read_pdu_blob_recv() - %s",
     584             :                                          nt_errstr(status));
     585       27395 :                 if (!reason) {
     586           0 :                         reason = nt_errstr(status);
     587             :                 }
     588             : 
     589       27395 :                 ldapsrv_terminate_connection(conn, reason);
     590       27395 :                 return;
     591             :         }
     592             : 
     593      608140 :         ret = ldapsrv_check_packet_size(conn, blob.length);
     594      608140 :         if (ret != LDAP_SUCCESS) {
     595           0 :                 ldapsrv_terminate_connection(
     596             :                         conn,
     597             :                         "Request packet too large");
     598           0 :                 return;
     599             :         }
     600             : 
     601      608140 :         asn1 = asn1_init(call, ASN1_MAX_TREE_DEPTH);
     602      608140 :         if (asn1 == NULL) {
     603           0 :                 ldapsrv_terminate_connection(conn, "no memory");
     604           0 :                 return;
     605             :         }
     606             : 
     607      608140 :         call->request = talloc(call, struct ldap_message);
     608      608140 :         if (call->request == NULL) {
     609           0 :                 ldapsrv_terminate_connection(conn, "no memory");
     610           0 :                 return;
     611             :         }
     612             : 
     613      608140 :         asn1_load_nocopy(asn1, blob.data, blob.length);
     614             : 
     615      608727 :         limits.max_search_size =
     616      608140 :                 lpcfg_ldap_max_search_request_size(conn->lp_ctx);
     617      608140 :         status = ldap_decode(
     618             :                 asn1,
     619             :                 &limits,
     620             :                 samba_ldap_control_handlers(),
     621             :                 call->request);
     622      608140 :         if (!NT_STATUS_IS_OK(status)) {
     623           2 :                 ldapsrv_terminate_connection(conn, nt_errstr(status));
     624           2 :                 return;
     625             :         }
     626             : 
     627      608138 :         data_blob_free(&blob);
     628      608138 :         TALLOC_FREE(asn1);
     629             : 
     630             : 
     631             :         /* queue the call in the global queue */
     632      608725 :         subreq = ldapsrv_process_call_send(call,
     633      608138 :                                            conn->connection->event.ctx,
     634      608138 :                                            conn->service->call_queue,
     635             :                                            call);
     636      608138 :         if (subreq == NULL) {
     637           0 :                 ldapsrv_terminate_connection(conn, "ldapsrv_process_call_send failed");
     638           0 :                 return;
     639             :         }
     640      608138 :         tevent_req_set_callback(subreq, ldapsrv_call_process_done, call);
     641      608138 :         conn->active_call = subreq;
     642             : }
     643             : 
     644             : static void ldapsrv_call_wait_done(struct tevent_req *subreq);
     645             : static void ldapsrv_call_writev_start(struct ldapsrv_call *call);
     646             : static void ldapsrv_call_writev_done(struct tevent_req *subreq);
     647             : 
     648      608140 : static void ldapsrv_call_process_done(struct tevent_req *subreq)
     649             : {
     650         587 :         struct ldapsrv_call *call =
     651      608140 :                 tevent_req_callback_data(subreq,
     652             :                 struct ldapsrv_call);
     653      608140 :         struct ldapsrv_connection *conn = call->conn;
     654         587 :         NTSTATUS status;
     655             : 
     656      608140 :         conn->active_call = NULL;
     657             : 
     658      608140 :         status = ldapsrv_process_call_recv(subreq);
     659      608140 :         TALLOC_FREE(subreq);
     660      608140 :         if (!NT_STATUS_IS_OK(status)) {
     661           0 :                 ldapsrv_terminate_connection(conn, nt_errstr(status));
     662       36369 :                 return;
     663             :         }
     664             : 
     665      608140 :         if (call->wait_send != NULL) {
     666       36491 :                 subreq = call->wait_send(call,
     667       36369 :                                          conn->connection->event.ctx,
     668             :                                          call->wait_private);
     669       36369 :                 if (subreq == NULL) {
     670           0 :                         ldapsrv_terminate_connection(conn,
     671             :                                         "ldapsrv_call_process_done: "
     672             :                                         "call->wait_send - no memory");
     673           0 :                         return;
     674             :                 }
     675       36369 :                 tevent_req_set_callback(subreq,
     676             :                                         ldapsrv_call_wait_done,
     677             :                                         call);
     678       36369 :                 conn->active_call = subreq;
     679       36369 :                 return;
     680             :         }
     681             : 
     682      571771 :         ldapsrv_call_writev_start(call);
     683             : }
     684             : 
     685       36369 : static void ldapsrv_call_wait_done(struct tevent_req *subreq)
     686             : {
     687         122 :         struct ldapsrv_call *call =
     688       36369 :                 tevent_req_callback_data(subreq,
     689             :                 struct ldapsrv_call);
     690       36369 :         struct ldapsrv_connection *conn = call->conn;
     691         122 :         NTSTATUS status;
     692             : 
     693       36369 :         conn->active_call = NULL;
     694             : 
     695       36369 :         status = call->wait_recv(subreq);
     696       36369 :         TALLOC_FREE(subreq);
     697       36369 :         if (!NT_STATUS_IS_OK(status)) {
     698           0 :                 const char *reason;
     699             : 
     700          23 :                 reason = talloc_asprintf(call, "ldapsrv_call_wait_done: "
     701             :                                          "call->wait_recv() - %s",
     702             :                                          nt_errstr(status));
     703          23 :                 if (reason == NULL) {
     704           0 :                         reason = nt_errstr(status);
     705             :                 }
     706             : 
     707          23 :                 ldapsrv_terminate_connection(conn, reason);
     708          23 :                 return;
     709             :         }
     710             : 
     711       36346 :         ldapsrv_call_writev_start(call);
     712             : }
     713             : 
     714      608267 : static void ldapsrv_call_writev_start(struct ldapsrv_call *call)
     715             : {
     716      608267 :         struct ldapsrv_connection *conn = call->conn;
     717      608267 :         struct ldapsrv_reply *reply = NULL;
     718      608267 :         struct tevent_req *subreq = NULL;
     719         587 :         struct timeval endtime;
     720      608267 :         size_t length = 0;
     721         587 :         size_t i;
     722             : 
     723      608267 :         call->iov_count = 0;
     724             : 
     725             :         /* build all the replies into an IOV (no copy) */
     726      608267 :         for (reply = call->replies;
     727     1969820 :              reply != NULL;
     728     1361553 :              reply = reply->next) {
     729             : 
     730             :                 /* Cap output at 25MB per writev() */
     731     1361693 :                 if (length > length + reply->blob.length
     732     1361693 :                     || length + reply->blob.length > LDAP_SERVER_MAX_CHUNK_SIZE) {
     733             :                         break;
     734             :                 }
     735             : 
     736             :                 /*
     737             :                  * Overflow is harmless here, just used below to
     738             :                  * decide if to read or write, but checked above anyway
     739             :                  */
     740     1361553 :                 length += reply->blob.length;
     741             : 
     742             :                 /*
     743             :                  * At worst an overflow would mean we send less
     744             :                  * replies
     745             :                  */
     746     1361553 :                 call->iov_count++;
     747             :         }
     748             : 
     749      608267 :         if (length == 0) {
     750         160 :                 if (!call->notification.busy) {
     751          80 :                         TALLOC_FREE(call);
     752             :                 }
     753             : 
     754         160 :                 ldapsrv_call_read_next(conn);
     755         160 :                 return;
     756             :         }
     757             : 
     758             :         /* Cap call->iov_count at IOV_MAX */
     759      608107 :         call->iov_count = MIN(call->iov_count, IOV_MAX);
     760             : 
     761      608107 :         call->out_iov = talloc_array(call,
     762             :                                      struct iovec,
     763             :                                      call->iov_count);
     764      608107 :         if (!call->out_iov) {
     765             :                 /* This is not ideal */
     766           0 :                 ldapsrv_terminate_connection(conn,
     767             :                                              "failed to allocate "
     768             :                                              "iovec array");
     769           0 :                 return;
     770             :         }
     771             : 
     772             :         /* We may have had to cap the number of replies at IOV_MAX */
     773      607520 :         for (i = 0;
     774     1962841 :              i < call->iov_count && call->replies != NULL;
     775     1354734 :              i++) {
     776     1354734 :                 reply = call->replies;
     777     1354734 :                 call->out_iov[i].iov_base = reply->blob.data;
     778     1354734 :                 call->out_iov[i].iov_len = reply->blob.length;
     779             : 
     780             :                 /* Keep only the ASN.1 encoded data */
     781     1354734 :                 talloc_steal(call->out_iov, reply->blob.data);
     782             : 
     783     1354734 :                 DLIST_REMOVE(call->replies, reply);
     784     1354734 :                 TALLOC_FREE(reply);
     785             :         }
     786             : 
     787      608107 :         if (i > call->iov_count) {
     788             :                 /* This is not ideal, but also (essentially) impossible */
     789           0 :                 ldapsrv_terminate_connection(conn,
     790             :                                              "call list ended"
     791             :                                              "before iov_count");
     792           0 :                 return;
     793             :         }
     794             : 
     795      608694 :         subreq = tstream_writev_queue_send(call,
     796      608107 :                                            conn->connection->event.ctx,
     797             :                                            conn->sockets.active,
     798             :                                            conn->sockets.send_queue,
     799      608107 :                                            call->out_iov, call->iov_count);
     800      608107 :         if (subreq == NULL) {
     801           0 :                 ldapsrv_terminate_connection(conn, "stream_writev_queue_send failed");
     802           0 :                 return;
     803             :         }
     804      608107 :         endtime = timeval_current_ofs(conn->limits.conn_idle_time, 0);
     805      608107 :         tevent_req_set_endtime(subreq,
     806      608107 :                                conn->connection->event.ctx,
     807             :                                endtime);
     808      608107 :         tevent_req_set_callback(subreq, ldapsrv_call_writev_done, call);
     809             : }
     810             : 
     811             : static void ldapsrv_call_postprocess_done(struct tevent_req *subreq);
     812             : 
     813      608107 : static void ldapsrv_call_writev_done(struct tevent_req *subreq)
     814             : {
     815         587 :         struct ldapsrv_call *call =
     816      608107 :                 tevent_req_callback_data(subreq,
     817             :                 struct ldapsrv_call);
     818      608107 :         struct ldapsrv_connection *conn = call->conn;
     819         587 :         int sys_errno;
     820         587 :         int rc;
     821             : 
     822      608107 :         rc = tstream_writev_queue_recv(subreq, &sys_errno);
     823      608107 :         TALLOC_FREE(subreq);
     824             : 
     825             :         /* This releases the ASN.1 encoded packets from memory */
     826      608107 :         TALLOC_FREE(call->out_iov);
     827      608107 :         if (rc == -1) {
     828           0 :                 const char *reason;
     829             : 
     830           0 :                 reason = talloc_asprintf(call, "ldapsrv_call_writev_done: "
     831             :                                          "tstream_writev_queue_recv() - %d:%s",
     832             :                                          sys_errno, strerror(sys_errno));
     833           0 :                 if (reason == NULL) {
     834           0 :                         reason = "ldapsrv_call_writev_done: "
     835             :                                  "tstream_writev_queue_recv() failed";
     836             :                 }
     837             : 
     838           0 :                 ldapsrv_terminate_connection(conn, reason);
     839       26292 :                 return;
     840             :         }
     841             : 
     842      608107 :         if (call->postprocess_send) {
     843       26264 :                 subreq = call->postprocess_send(call,
     844       26142 :                                                 conn->connection->event.ctx,
     845             :                                                 call->postprocess_private);
     846       26142 :                 if (subreq == NULL) {
     847           0 :                         ldapsrv_terminate_connection(conn, "ldapsrv_call_writev_done: "
     848             :                                         "call->postprocess_send - no memory");
     849           0 :                         return;
     850             :                 }
     851       26142 :                 tevent_req_set_callback(subreq,
     852             :                                         ldapsrv_call_postprocess_done,
     853             :                                         call);
     854       26142 :                 return;
     855             :         }
     856             : 
     857             :         /* Perhaps still some more to send */
     858      581965 :         if (call->replies != NULL) {
     859         150 :                 ldapsrv_call_writev_start(call);
     860         150 :                 return;
     861             :         }
     862             : 
     863      581815 :         if (!call->notification.busy) {
     864      581814 :                 TALLOC_FREE(call);
     865             :         }
     866             : 
     867      581815 :         ldapsrv_call_read_next(conn);
     868             : }
     869             : 
     870       26142 : static void ldapsrv_call_postprocess_done(struct tevent_req *subreq)
     871             : {
     872         122 :         struct ldapsrv_call *call =
     873       26142 :                 tevent_req_callback_data(subreq,
     874             :                 struct ldapsrv_call);
     875       26142 :         struct ldapsrv_connection *conn = call->conn;
     876         122 :         NTSTATUS status;
     877             : 
     878       26142 :         status = call->postprocess_recv(subreq);
     879       26142 :         TALLOC_FREE(subreq);
     880       26142 :         if (!NT_STATUS_IS_OK(status)) {
     881           0 :                 const char *reason;
     882             : 
     883           0 :                 reason = talloc_asprintf(call, "ldapsrv_call_postprocess_done: "
     884             :                                          "call->postprocess_recv() - %s",
     885             :                                          nt_errstr(status));
     886           0 :                 if (reason == NULL) {
     887           0 :                         reason = nt_errstr(status);
     888             :                 }
     889             : 
     890           0 :                 ldapsrv_terminate_connection(conn, reason);
     891           0 :                 return;
     892             :         }
     893             : 
     894       26142 :         TALLOC_FREE(call);
     895             : 
     896       26142 :         ldapsrv_call_read_next(conn);
     897             : }
     898             : 
     899             : static void ldapsrv_notification_retry_done(struct tevent_req *subreq);
     900             : 
     901      235239 : void ldapsrv_notification_retry_setup(struct ldapsrv_service *service, bool force)
     902             : {
     903      235239 :         struct ldapsrv_connection *conn = NULL;
     904         216 :         struct timeval retry;
     905      235239 :         size_t num_pending = 0;
     906      235239 :         size_t num_active = 0;
     907             : 
     908      235239 :         if (force) {
     909      230449 :                 TALLOC_FREE(service->notification.retry);
     910      230449 :                 service->notification.generation += 1;
     911             :         }
     912             : 
     913      235239 :         if (service->notification.retry != NULL) {
     914      235202 :                 return;
     915             :         }
     916             : 
     917      510185 :         for (conn = service->connections; conn != NULL; conn = conn->next) {
     918      279692 :                 if (conn->pending_calls == NULL) {
     919      279655 :                         continue;
     920             :                 }
     921             : 
     922          37 :                 num_pending += 1;
     923             : 
     924          37 :                 if (conn->pending_calls->notification.generation !=
     925          37 :                     service->notification.generation)
     926             :                 {
     927           1 :                         num_active += 1;
     928             :                 }
     929             :         }
     930             : 
     931      230493 :         if (num_pending == 0) {
     932      230240 :                 return;
     933             :         }
     934             : 
     935          37 :         if (num_active != 0) {
     936           1 :                 retry = timeval_current_ofs(0, 100);
     937             :         } else {
     938          36 :                 retry = timeval_current_ofs(5, 0);
     939             :         }
     940             : 
     941          37 :         service->notification.retry = tevent_wakeup_send(service,
     942             :                                                          service->current_ev,
     943             :                                                          retry);
     944          37 :         if (service->notification.retry == NULL) {
     945             :                 /* retry later */
     946           0 :                 return;
     947             :         }
     948             : 
     949          37 :         tevent_req_set_callback(service->notification.retry,
     950             :                                 ldapsrv_notification_retry_done,
     951             :                                 service);
     952             : }
     953             : 
     954          11 : static void ldapsrv_notification_retry_done(struct tevent_req *subreq)
     955             : {
     956           0 :         struct ldapsrv_service *service =
     957          11 :                 tevent_req_callback_data(subreq,
     958             :                 struct ldapsrv_service);
     959          11 :         struct ldapsrv_connection *conn = NULL;
     960          11 :         struct ldapsrv_connection *conn_next = NULL;
     961           0 :         bool ok;
     962             : 
     963          11 :         service->notification.retry = NULL;
     964             : 
     965          11 :         ok = tevent_wakeup_recv(subreq);
     966          11 :         TALLOC_FREE(subreq);
     967          11 :         if (!ok) {
     968             :                 /* ignore */
     969           0 :         }
     970             : 
     971          27 :         for (conn = service->connections; conn != NULL; conn = conn_next) {
     972          16 :                 struct ldapsrv_call *call = conn->pending_calls;
     973             : 
     974          16 :                 conn_next = conn->next;
     975             : 
     976          16 :                 if (conn->pending_calls == NULL) {
     977          14 :                         continue;
     978             :                 }
     979             : 
     980           2 :                 if (conn->active_call != NULL) {
     981           0 :                         continue;
     982             :                 }
     983             : 
     984           2 :                 DLIST_DEMOTE(conn->pending_calls, call);
     985           2 :                 call->notification.generation =
     986           2 :                                 service->notification.generation;
     987             : 
     988             :                 /* queue the call in the global queue */
     989           2 :                 subreq = ldapsrv_process_call_send(call,
     990           2 :                                                    conn->connection->event.ctx,
     991           2 :                                                    conn->service->call_queue,
     992             :                                                    call);
     993           2 :                 if (subreq == NULL) {
     994           0 :                         ldapsrv_terminate_connection(conn,
     995             :                                         "ldapsrv_process_call_send failed");
     996           0 :                         continue;
     997             :                 }
     998           2 :                 tevent_req_set_callback(subreq, ldapsrv_call_process_done, call);
     999           2 :                 conn->active_call = subreq;
    1000             :         }
    1001             : 
    1002          11 :         ldapsrv_notification_retry_setup(service, false);
    1003          11 : }
    1004             : 
    1005             : struct ldapsrv_process_call_state {
    1006             :         struct ldapsrv_call *call;
    1007             : };
    1008             : 
    1009             : static void ldapsrv_process_call_trigger(struct tevent_req *req,
    1010             :                                          void *private_data);
    1011             : 
    1012      608140 : static struct tevent_req *ldapsrv_process_call_send(TALLOC_CTX *mem_ctx,
    1013             :                                                     struct tevent_context *ev,
    1014             :                                                     struct tevent_queue *call_queue,
    1015             :                                                     struct ldapsrv_call *call)
    1016             : {
    1017         587 :         struct tevent_req *req;
    1018         587 :         struct ldapsrv_process_call_state *state;
    1019         587 :         bool ok;
    1020             : 
    1021      608140 :         req = tevent_req_create(mem_ctx, &state,
    1022             :                                 struct ldapsrv_process_call_state);
    1023      608140 :         if (req == NULL) {
    1024           0 :                 return req;
    1025             :         }
    1026             : 
    1027      608140 :         state->call = call;
    1028             : 
    1029      608140 :         ok = tevent_queue_add(call_queue, ev, req,
    1030             :                               ldapsrv_process_call_trigger, NULL);
    1031      608140 :         if (!ok) {
    1032           0 :                 tevent_req_oom(req);
    1033           0 :                 return tevent_req_post(req, ev);
    1034             :         }
    1035             : 
    1036      607553 :         return req;
    1037             : }
    1038             : 
    1039             : static void ldapsrv_disconnect_ticket_expired(struct tevent_req *subreq);
    1040             : 
    1041      608140 : static void ldapsrv_process_call_trigger(struct tevent_req *req,
    1042             :                                          void *private_data)
    1043             : {
    1044         587 :         struct ldapsrv_process_call_state *state =
    1045      608140 :                 tevent_req_data(req,
    1046             :                 struct ldapsrv_process_call_state);
    1047      608140 :         struct ldapsrv_connection *conn = state->call->conn;
    1048         587 :         NTSTATUS status;
    1049             : 
    1050      608140 :         if (conn->deferred_expire_disconnect != NULL) {
    1051             :                 /*
    1052             :                  * Just drop this on the floor
    1053             :                  */
    1054           0 :                 tevent_req_done(req);
    1055           4 :                 return;
    1056             :         }
    1057             : 
    1058             :         /* make the call */
    1059      608140 :         status = ldapsrv_do_call(state->call);
    1060             : 
    1061      608140 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
    1062             :                 /*
    1063             :                  * For testing purposes, defer the TCP disconnect
    1064             :                  * after having sent the msgid 0
    1065             :                  * 1.3.6.1.4.1.1466.20036 exop response. LDAP clients
    1066             :                  * should not wait for the TCP connection to close but
    1067             :                  * handle this packet equivalent to a TCP
    1068             :                  * disconnect. This delay enables testing both cases
    1069             :                  * in LDAP client libraries.
    1070             :                  */
    1071             : 
    1072           4 :                 int defer_msec = lpcfg_parm_int(
    1073             :                         conn->lp_ctx,
    1074             :                         NULL,
    1075             :                         "ldap_server",
    1076             :                         "delay_expire_disconnect",
    1077             :                         0);
    1078             : 
    1079           4 :                 conn->deferred_expire_disconnect = tevent_wakeup_send(
    1080             :                         conn,
    1081           4 :                         conn->connection->event.ctx,
    1082             :                         timeval_current_ofs_msec(defer_msec));
    1083           4 :                 if (tevent_req_nomem(conn->deferred_expire_disconnect, req)) {
    1084           4 :                         return;
    1085             :                 }
    1086           4 :                 tevent_req_set_callback(
    1087             :                         conn->deferred_expire_disconnect,
    1088             :                         ldapsrv_disconnect_ticket_expired,
    1089             :                         conn);
    1090             : 
    1091           4 :                 tevent_req_done(req);
    1092           4 :                 return;
    1093             :         }
    1094             : 
    1095      608136 :         if (!NT_STATUS_IS_OK(status)) {
    1096           0 :                 tevent_req_nterror(req, status);
    1097           0 :                 return;
    1098             :         }
    1099             : 
    1100      608136 :         tevent_req_done(req);
    1101             : }
    1102             : 
    1103           2 : static void ldapsrv_disconnect_ticket_expired(struct tevent_req *subreq)
    1104             : {
    1105           2 :         struct ldapsrv_connection *conn = tevent_req_callback_data(
    1106             :                 subreq, struct ldapsrv_connection);
    1107           0 :         bool ok;
    1108             : 
    1109           2 :         ok = tevent_wakeup_recv(subreq);
    1110           2 :         TALLOC_FREE(subreq);
    1111           2 :         if (!ok) {
    1112           0 :                 DBG_WARNING("tevent_wakeup_recv failed\n");
    1113             :         }
    1114           2 :         conn->deferred_expire_disconnect = NULL;
    1115           2 :         ldapsrv_terminate_connection(conn, "network session expired");
    1116           2 : }
    1117             : 
    1118      608140 : static NTSTATUS ldapsrv_process_call_recv(struct tevent_req *req)
    1119             : {
    1120         587 :         NTSTATUS status;
    1121             : 
    1122      608140 :         if (tevent_req_is_nterror(req, &status)) {
    1123           0 :                 tevent_req_received(req);
    1124           0 :                 return status;
    1125             :         }
    1126             : 
    1127      608140 :         tevent_req_received(req);
    1128      608140 :         return NT_STATUS_OK;
    1129             : }
    1130             : 
    1131       27318 : static void ldapsrv_accept_nonpriv(struct stream_connection *c)
    1132             : {
    1133       27318 :         struct ldapsrv_service *ldapsrv_service = talloc_get_type_abort(
    1134             :                 c->private_data, struct ldapsrv_service);
    1135         122 :         struct auth_session_info *session_info;
    1136         122 :         NTSTATUS status;
    1137             : 
    1138       27318 :         status = auth_anonymous_session_info(
    1139             :                 c, ldapsrv_service->lp_ctx, &session_info);
    1140       27318 :         if (!NT_STATUS_IS_OK(status)) {
    1141           0 :                 stream_terminate_connection(c, "failed to setup anonymous "
    1142             :                                             "session info");
    1143           0 :                 return;
    1144             :         }
    1145       27318 :         ldapsrv_accept(c, session_info, false, false);
    1146             : }
    1147             : 
    1148             : static const struct stream_server_ops ldap_stream_nonpriv_ops = {
    1149             :         .name                   = "ldap",
    1150             :         .accept_connection      = ldapsrv_accept_nonpriv,
    1151             :         .recv_handler           = ldapsrv_recv,
    1152             :         .send_handler           = ldapsrv_send,
    1153             : };
    1154             : 
    1155          38 : static void ldapsrv_accept_nonpriv_ldapi(struct stream_connection *c)
    1156             : {
    1157          38 :         struct ldapsrv_service *ldapsrv_service = talloc_get_type_abort(
    1158             :                 c->private_data, struct ldapsrv_service);
    1159           0 :         struct auth_session_info *session_info;
    1160           0 :         NTSTATUS status;
    1161             : 
    1162          38 :         status = auth_anonymous_session_info(
    1163             :                 c, ldapsrv_service->lp_ctx, &session_info);
    1164          38 :         if (!NT_STATUS_IS_OK(status)) {
    1165           0 :                 stream_terminate_connection(c, "failed to setup anonymous "
    1166             :                                             "session info");
    1167           0 :                 return;
    1168             :         }
    1169          38 :         ldapsrv_accept(c, session_info, false, true);
    1170             : }
    1171             : 
    1172             : static const struct stream_server_ops ldapi_stream_nonpriv_ops = {
    1173             :         .name                   = "ldap",
    1174             :         .accept_connection      = ldapsrv_accept_nonpriv_ldapi,
    1175             :         .recv_handler           = ldapsrv_recv,
    1176             :         .send_handler           = ldapsrv_send,
    1177             : };
    1178             : 
    1179             : /* The feature removed behind an #ifdef until we can do it properly
    1180             :  * with an EXTERNAL bind. */
    1181             : 
    1182             : #define WITH_LDAPI_PRIV_SOCKET
    1183             : 
    1184             : #ifdef WITH_LDAPI_PRIV_SOCKET
    1185          70 : static void ldapsrv_accept_priv_ldapi(struct stream_connection *c)
    1186             : {
    1187          70 :         struct ldapsrv_service *ldapsrv_service = talloc_get_type_abort(
    1188             :                 c->private_data, struct ldapsrv_service);
    1189           0 :         struct auth_session_info *session_info;
    1190             : 
    1191          70 :         session_info = system_session(ldapsrv_service->lp_ctx);
    1192          70 :         if (!session_info) {
    1193           0 :                 stream_terminate_connection(c, "failed to setup system "
    1194             :                                             "session info");
    1195           0 :                 return;
    1196             :         }
    1197          70 :         ldapsrv_accept(c, session_info, true, true);
    1198             : }
    1199             : 
    1200             : static const struct stream_server_ops ldapi_stream_priv_ops = {
    1201             :         .name                   = "ldap",
    1202             :         .accept_connection      = ldapsrv_accept_priv_ldapi,
    1203             :         .recv_handler           = ldapsrv_recv,
    1204             :         .send_handler           = ldapsrv_send,
    1205             : };
    1206             : 
    1207             : #endif
    1208             : 
    1209             : 
    1210             : /*
    1211             :   add a socket address to the list of events, one event per port
    1212             : */
    1213         120 : static NTSTATUS add_socket(struct task_server *task,
    1214             :                            struct loadparm_context *lp_ctx,
    1215             :                            const struct model_ops *model_ops,
    1216             :                            const char *address, struct ldapsrv_service *ldap_service)
    1217             : {
    1218         120 :         uint16_t port = 389;
    1219           4 :         NTSTATUS status;
    1220           4 :         struct ldb_context *ldb;
    1221             : 
    1222         120 :         status = stream_setup_socket(task, task->event_ctx, lp_ctx,
    1223             :                                      model_ops, &ldap_stream_nonpriv_ops,
    1224             :                                      "ip", address, &port,
    1225             :                                      lpcfg_socket_options(lp_ctx),
    1226             :                                      ldap_service, task->process_context);
    1227         120 :         if (!NT_STATUS_IS_OK(status)) {
    1228           0 :                 DBG_ERR("ldapsrv failed to bind to %s:%u - %s\n",
    1229             :                         address, port, nt_errstr(status));
    1230           0 :                 return status;
    1231             :         }
    1232             : 
    1233         120 :         if (tstream_tls_params_enabled(ldap_service->tls_params)) {
    1234             :                 /* add ldaps server */
    1235         120 :                 port = 636;
    1236         120 :                 status = stream_setup_socket(task, task->event_ctx, lp_ctx,
    1237             :                                              model_ops,
    1238             :                                              &ldap_stream_nonpriv_ops,
    1239             :                                              "ip", address, &port,
    1240             :                                              lpcfg_socket_options(lp_ctx),
    1241             :                                              ldap_service,
    1242             :                                              task->process_context);
    1243         120 :                 if (!NT_STATUS_IS_OK(status)) {
    1244           0 :                         DBG_ERR("ldapsrv failed to bind to %s:%u - %s\n",
    1245             :                                 address, port, nt_errstr(status));
    1246           0 :                         return status;
    1247             :                 }
    1248             :         }
    1249             : 
    1250             :         /* Load LDAP database, but only to read our settings */
    1251         120 :         ldb = samdb_connect(ldap_service,
    1252             :                             ldap_service->current_ev,
    1253             :                             lp_ctx,
    1254             :                             system_session(lp_ctx),
    1255             :                             NULL,
    1256             :                             0);
    1257         120 :         if (!ldb) {
    1258           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    1259             :         }
    1260             : 
    1261         120 :         if (samdb_is_gc(ldb)) {
    1262         120 :                 port = 3268;
    1263         120 :                 status = stream_setup_socket(task, task->event_ctx, lp_ctx,
    1264             :                                              model_ops,
    1265             :                                              &ldap_stream_nonpriv_ops,
    1266             :                                              "ip", address, &port,
    1267             :                                              lpcfg_socket_options(lp_ctx),
    1268             :                                              ldap_service,
    1269             :                                              task->process_context);
    1270         120 :                 if (!NT_STATUS_IS_OK(status)) {
    1271           0 :                         DBG_ERR("ldapsrv failed to bind to %s:%u - %s\n",
    1272             :                                 address, port, nt_errstr(status));
    1273           0 :                         return status;
    1274             :                 }
    1275         120 :                 if (tstream_tls_params_enabled(ldap_service->tls_params)) {
    1276             :                         /* add ldaps server for the global catalog */
    1277         120 :                         port = 3269;
    1278         120 :                         status = stream_setup_socket(task, task->event_ctx, lp_ctx,
    1279             :                                                      model_ops,
    1280             :                                                      &ldap_stream_nonpriv_ops,
    1281             :                                                      "ip", address, &port,
    1282             :                                                      lpcfg_socket_options(lp_ctx),
    1283             :                                                      ldap_service,
    1284             :                                                      task->process_context);
    1285         120 :                         if (!NT_STATUS_IS_OK(status)) {
    1286           0 :                                 DBG_ERR("ldapsrv failed to bind to %s:%u - %s\n",
    1287             :                                         address, port, nt_errstr(status));
    1288           0 :                                 return status;
    1289             :                         }
    1290             :                 }
    1291             :         }
    1292             : 
    1293             :         /* And once we are bound, free the temporary ldb, it will
    1294             :          * connect again on each incoming LDAP connection */
    1295         120 :         talloc_unlink(ldap_service, ldb);
    1296             : 
    1297         120 :         return NT_STATUS_OK;
    1298             : }
    1299             : 
    1300           2 : static void ldap_reload_certs(struct imessaging_context *msg_ctx,
    1301             :                               void *private_data,
    1302             :                               uint32_t msg_type,
    1303             :                               struct server_id server_id,
    1304             :                               size_t num_fds,
    1305             :                               int *fds,
    1306             :                               DATA_BLOB *data)
    1307             : {
    1308           2 :         TALLOC_CTX *frame = talloc_stackframe();
    1309           0 :         struct ldapsrv_service *ldap_service =
    1310           2 :                 talloc_get_type_abort(private_data,
    1311             :                 struct ldapsrv_service);
    1312           0 :         int default_children;
    1313           0 :         int num_children;
    1314           0 :         int i;
    1315           0 :         bool ok;
    1316           0 :         struct server_id ldap_master_id;
    1317           0 :         NTSTATUS status;
    1318           2 :         struct tstream_tls_params *new_tls_params = NULL;
    1319             : 
    1320           2 :         SMB_ASSERT(msg_ctx == ldap_service->current_msg);
    1321             : 
    1322             :         /* reload certificates */
    1323           4 :         status = tstream_tls_params_server(ldap_service,
    1324             :                                            ldap_service->dns_host_name,
    1325           2 :                                            lpcfg_tls_enabled(ldap_service->lp_ctx),
    1326           2 :                                            lpcfg_tls_keyfile(frame, ldap_service->lp_ctx),
    1327           2 :                                            lpcfg_tls_certfile(frame, ldap_service->lp_ctx),
    1328           2 :                                            lpcfg_tls_cafile(frame, ldap_service->lp_ctx),
    1329           2 :                                            lpcfg_tls_crlfile(frame, ldap_service->lp_ctx),
    1330           2 :                                            lpcfg_tls_dhpfile(frame, ldap_service->lp_ctx),
    1331             :                                            lpcfg_tls_priority(ldap_service->lp_ctx),
    1332             :                                            &new_tls_params);
    1333           2 :         if (!NT_STATUS_IS_OK(status)) {
    1334           0 :                 DBG_ERR("ldapsrv failed tstream_tls_params_server - %s\n",
    1335             :                         nt_errstr(status));
    1336           0 :                 TALLOC_FREE(frame);
    1337           2 :                 return;
    1338             :         }
    1339             : 
    1340           2 :         TALLOC_FREE(ldap_service->tls_params);
    1341           2 :         ldap_service->tls_params = new_tls_params;
    1342             : 
    1343           2 :         if (getpid() != ldap_service->parent_pid) {
    1344             :                 /*
    1345             :                  * If we are not the master process we are done
    1346             :                  */
    1347           0 :                 TALLOC_FREE(frame);
    1348           0 :                 return;
    1349             :         }
    1350             : 
    1351             :         /*
    1352             :          * Check we're running under the prefork model,
    1353             :          * by checking if the prefork-master-ldap name
    1354             :          * was registered
    1355             :          */
    1356           2 :         ok = server_id_db_lookup_one(msg_ctx->names, "prefork-master-ldap", &ldap_master_id);
    1357           2 :         if (!ok) {
    1358             :                 /*
    1359             :                  * We are done if another process model is in use.
    1360             :                  */
    1361           2 :                 TALLOC_FREE(frame);
    1362           2 :                 return;
    1363             :         }
    1364             : 
    1365             :         /*
    1366             :          * Now we loop over all possible prefork workers
    1367             :          * in order to notify them about the reload
    1368             :          */
    1369           0 :         default_children = lpcfg_prefork_children(ldap_service->lp_ctx);
    1370           0 :         num_children = lpcfg_parm_int(ldap_service->lp_ctx,
    1371             :                                       NULL, "prefork children", "ldap",
    1372             :                                       default_children);
    1373           0 :         for (i = 0; i < num_children; i++) {
    1374           0 :                 char child_name[64] = { 0, };
    1375           0 :                 struct server_id ldap_worker_id;
    1376             : 
    1377           0 :                 snprintf(child_name, sizeof(child_name), "prefork-worker-ldap-%d", i);
    1378           0 :                 ok = server_id_db_lookup_one(msg_ctx->names, child_name, &ldap_worker_id);
    1379           0 :                 if (!ok) {
    1380           0 :                         DBG_ERR("server_id_db_lookup_one(%s) - failed\n",
    1381             :                                 child_name);
    1382           0 :                         continue;
    1383             :                 }
    1384             : 
    1385           0 :                 status = imessaging_send(msg_ctx, ldap_worker_id,
    1386             :                                          MSG_RELOAD_TLS_CERTIFICATES, NULL);
    1387           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1388           0 :                         struct server_id_buf id_buf;
    1389           0 :                         DBG_ERR("ldapsrv failed imessaging_send(%s, %s) - %s\n",
    1390             :                                 child_name,
    1391             :                                 server_id_str_buf(ldap_worker_id, &id_buf),
    1392             :                                 nt_errstr(status));
    1393           0 :                         continue;
    1394             :                 }
    1395             :         }
    1396             : 
    1397           0 :         TALLOC_FREE(frame);
    1398             : }
    1399             : 
    1400             : /*
    1401             :   open the ldap server sockets
    1402             : */
    1403          66 : static NTSTATUS ldapsrv_task_init(struct task_server *task)
    1404             : {
    1405           2 :         char *ldapi_path;
    1406             : #ifdef WITH_LDAPI_PRIV_SOCKET
    1407           2 :         char *priv_dir;
    1408             : #endif
    1409           2 :         struct ldapsrv_service *ldap_service;
    1410           2 :         NTSTATUS status;
    1411             : 
    1412          66 :         switch (lpcfg_server_role(task->lp_ctx)) {
    1413           0 :         case ROLE_STANDALONE:
    1414           0 :                 task_server_terminate(task, "ldap_server: no LDAP server required in standalone configuration",
    1415             :                                       false);
    1416           0 :                 return NT_STATUS_INVALID_DOMAIN_ROLE;
    1417           6 :         case ROLE_DOMAIN_MEMBER:
    1418           6 :                 task_server_terminate(task, "ldap_server: no LDAP server required in member server configuration",
    1419             :                                       false);
    1420           0 :                 return NT_STATUS_INVALID_DOMAIN_ROLE;
    1421          58 :         case ROLE_ACTIVE_DIRECTORY_DC:
    1422             :                 /* Yes, we want an LDAP server */
    1423          58 :                 break;
    1424             :         }
    1425             : 
    1426          60 :         task_server_set_title(task, "task[ldapsrv]");
    1427             : 
    1428          60 :         ldap_service = talloc_zero(task, struct ldapsrv_service);
    1429          60 :         if (ldap_service == NULL) {
    1430           0 :                 status = NT_STATUS_NO_MEMORY;
    1431           0 :                 goto failed;
    1432             :         }
    1433             : 
    1434          60 :         ldap_service->lp_ctx = task->lp_ctx;
    1435          60 :         ldap_service->current_ev = task->event_ctx;
    1436          60 :         ldap_service->current_msg = task->msg_ctx;
    1437             : 
    1438          60 :         ldap_service->dns_host_name = talloc_asprintf(ldap_service, "%s.%s",
    1439             :                                         lpcfg_netbios_name(task->lp_ctx),
    1440             :                                         lpcfg_dnsdomain(task->lp_ctx));
    1441          60 :         if (ldap_service->dns_host_name == NULL) {
    1442           0 :                 status = NT_STATUS_NO_MEMORY;
    1443           0 :                 goto failed;
    1444             :         }
    1445             : 
    1446          60 :         ldap_service->parent_pid = getpid();
    1447             : 
    1448         120 :         status = tstream_tls_params_server(ldap_service,
    1449             :                                            ldap_service->dns_host_name,
    1450          60 :                                            lpcfg_tls_enabled(task->lp_ctx),
    1451          60 :                                            lpcfg_tls_keyfile(ldap_service, task->lp_ctx),
    1452          60 :                                            lpcfg_tls_certfile(ldap_service, task->lp_ctx),
    1453          60 :                                            lpcfg_tls_cafile(ldap_service, task->lp_ctx),
    1454          60 :                                            lpcfg_tls_crlfile(ldap_service, task->lp_ctx),
    1455          60 :                                            lpcfg_tls_dhpfile(ldap_service, task->lp_ctx),
    1456             :                                            lpcfg_tls_priority(task->lp_ctx),
    1457             :                                            &ldap_service->tls_params);
    1458          60 :         if (!NT_STATUS_IS_OK(status)) {
    1459           0 :                 DBG_ERR("ldapsrv failed tstream_tls_params_server - %s\n",
    1460             :                         nt_errstr(status));
    1461           0 :                 goto failed;
    1462             :         }
    1463             : 
    1464          60 :         ldap_service->call_queue = tevent_queue_create(ldap_service, "ldapsrv_call_queue");
    1465          60 :         if (ldap_service->call_queue == NULL) {
    1466           0 :                 status = NT_STATUS_NO_MEMORY;
    1467           0 :                 goto failed;
    1468             :         }
    1469             : 
    1470          60 :         if (lpcfg_interfaces(task->lp_ctx) && lpcfg_bind_interfaces_only(task->lp_ctx)) {
    1471           0 :                 struct interface *ifaces;
    1472           0 :                 int num_interfaces;
    1473           0 :                 int i;
    1474             : 
    1475           0 :                 load_interface_list(task, task->lp_ctx, &ifaces);
    1476           0 :                 num_interfaces = iface_list_count(ifaces);
    1477             : 
    1478             :                 /* We have been given an interfaces line, and been
    1479             :                    told to only bind to those interfaces. Create a
    1480             :                    socket per interface and bind to only these.
    1481             :                 */
    1482           0 :                 for(i = 0; i < num_interfaces; i++) {
    1483           0 :                         const char *address = iface_list_n_ip(ifaces, i);
    1484           0 :                         status = add_socket(task, task->lp_ctx, task->model_ops,
    1485             :                                             address, ldap_service);
    1486           0 :                         if (!NT_STATUS_IS_OK(status)) goto failed;
    1487             :                 }
    1488             :         } else {
    1489           2 :                 char **wcard;
    1490           2 :                 size_t i;
    1491          60 :                 size_t num_binds = 0;
    1492          60 :                 wcard = iface_list_wildcard(task);
    1493          60 :                 if (wcard == NULL) {
    1494           0 :                         DBG_ERR("No wildcard addresses available\n");
    1495           0 :                         status = NT_STATUS_UNSUCCESSFUL;
    1496           0 :                         goto failed;
    1497             :                 }
    1498         180 :                 for (i=0; wcard[i]; i++) {
    1499         120 :                         status = add_socket(task, task->lp_ctx, task->model_ops,
    1500         116 :                                             wcard[i], ldap_service);
    1501         120 :                         if (NT_STATUS_IS_OK(status)) {
    1502         120 :                                 num_binds++;
    1503             :                         }
    1504             :                 }
    1505          60 :                 talloc_free(wcard);
    1506          60 :                 if (num_binds == 0) {
    1507           0 :                         status = NT_STATUS_UNSUCCESSFUL;
    1508           0 :                         goto failed;
    1509             :                 }
    1510             :         }
    1511             : 
    1512          60 :         ldapi_path = lpcfg_private_path(ldap_service, task->lp_ctx, "ldapi");
    1513          60 :         if (!ldapi_path) {
    1514           0 :                 status = NT_STATUS_UNSUCCESSFUL;
    1515           0 :                 goto failed;
    1516             :         }
    1517             : 
    1518          60 :         status = stream_setup_socket(task, task->event_ctx, task->lp_ctx,
    1519             :                                      task->model_ops, &ldapi_stream_nonpriv_ops,
    1520             :                                      "unix", ldapi_path, NULL,
    1521             :                                      lpcfg_socket_options(task->lp_ctx),
    1522             :                                      ldap_service, task->process_context);
    1523          60 :         talloc_free(ldapi_path);
    1524          60 :         if (!NT_STATUS_IS_OK(status)) {
    1525           0 :                 DBG_ERR("ldapsrv failed to bind to %s - %s\n",
    1526             :                         ldapi_path, nt_errstr(status));
    1527             :         }
    1528             : 
    1529             : #ifdef WITH_LDAPI_PRIV_SOCKET
    1530          60 :         priv_dir = lpcfg_private_path(ldap_service, task->lp_ctx, "ldap_priv");
    1531          60 :         if (priv_dir == NULL) {
    1532           0 :                 status = NT_STATUS_UNSUCCESSFUL;
    1533           0 :                 goto failed;
    1534             :         }
    1535             :         /*
    1536             :          * Make sure the directory for the privileged ldapi socket exists, and
    1537             :          * is of the correct permissions
    1538             :          */
    1539          60 :         if (!directory_create_or_exist(priv_dir, 0750)) {
    1540           0 :                 task_server_terminate(task, "Cannot create ldap "
    1541             :                                       "privileged ldapi directory", true);
    1542           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1543             :         }
    1544          60 :         ldapi_path = talloc_asprintf(ldap_service, "%s/ldapi", priv_dir);
    1545          60 :         talloc_free(priv_dir);
    1546          60 :         if (ldapi_path == NULL) {
    1547           0 :                 status = NT_STATUS_NO_MEMORY;
    1548           0 :                 goto failed;
    1549             :         }
    1550             : 
    1551          60 :         status = stream_setup_socket(task, task->event_ctx, task->lp_ctx,
    1552             :                                      task->model_ops, &ldapi_stream_priv_ops,
    1553             :                                      "unix", ldapi_path, NULL,
    1554             :                                      lpcfg_socket_options(task->lp_ctx),
    1555             :                                      ldap_service,
    1556             :                                      task->process_context);
    1557          60 :         talloc_free(ldapi_path);
    1558          60 :         if (!NT_STATUS_IS_OK(status)) {
    1559           0 :                 DBG_ERR("ldapsrv failed to bind to %s - %s\n",
    1560             :                         ldapi_path, nt_errstr(status));
    1561             :         }
    1562             : 
    1563             : #endif
    1564             : 
    1565             :         /* register the server */
    1566          60 :         irpc_add_name(task->msg_ctx, "ldap_server");
    1567             : 
    1568          60 :         task->private_data = ldap_service;
    1569             : 
    1570          60 :         return NT_STATUS_OK;
    1571             : 
    1572           0 : failed:
    1573           0 :         task_server_terminate(task, "Failed to startup ldap server task", true);
    1574           0 :         return status;
    1575             : }
    1576             : 
    1577             : /*
    1578             :  * Open a database to be later used by LDB wrap code (although it should be
    1579             :  * plumbed through correctly eventually).
    1580             :  */
    1581         140 : static void ldapsrv_post_fork(struct task_server *task, struct process_details *pd)
    1582             : {
    1583           8 :         struct ldapsrv_service *ldap_service =
    1584         140 :                 talloc_get_type_abort(task->private_data, struct ldapsrv_service);
    1585             : 
    1586             :         /*
    1587             :          * As ldapsrv_before_loop() may changed the values for the parent loop
    1588             :          * we need to adjust the pointers to the correct value in the child
    1589             :          */
    1590         140 :         ldap_service->lp_ctx = task->lp_ctx;
    1591         140 :         ldap_service->current_ev = task->event_ctx;
    1592         140 :         ldap_service->current_msg = task->msg_ctx;
    1593             : 
    1594         140 :         ldap_service->sam_ctx = samdb_connect(ldap_service,
    1595             :                                               ldap_service->current_ev,
    1596             :                                               ldap_service->lp_ctx,
    1597             :                                               system_session(ldap_service->lp_ctx),
    1598             :                                               NULL,
    1599             :                                               0);
    1600         140 :         if (ldap_service->sam_ctx == NULL) {
    1601           0 :                 task_server_terminate(task, "Cannot open system session LDB",
    1602             :                                       true);
    1603           0 :                 return;
    1604             :         }
    1605             : }
    1606             : 
    1607         169 : static void ldapsrv_before_loop(struct task_server *task)
    1608             : {
    1609          10 :         struct ldapsrv_service *ldap_service =
    1610         169 :                 talloc_get_type_abort(task->private_data, struct ldapsrv_service);
    1611          10 :         NTSTATUS status;
    1612             : 
    1613         169 :         if (ldap_service->sam_ctx != NULL) {
    1614             :                 /*
    1615             :                  * Make sure the values are still the same
    1616             :                  * as set in ldapsrv_post_fork()
    1617             :                  */
    1618         140 :                 SMB_ASSERT(task->lp_ctx == ldap_service->lp_ctx);
    1619         140 :                 SMB_ASSERT(task->event_ctx == ldap_service->current_ev);
    1620         140 :                 SMB_ASSERT(task->msg_ctx == ldap_service->current_msg);
    1621             :         } else {
    1622             :                 /*
    1623             :                  * We need to adjust the pointers to the correct value
    1624             :                  * in the parent loop.
    1625             :                  */
    1626          29 :                 ldap_service->lp_ctx = task->lp_ctx;
    1627          29 :                 ldap_service->current_ev = task->event_ctx;
    1628          29 :                 ldap_service->current_msg = task->msg_ctx;
    1629             :         }
    1630             : 
    1631         169 :         status = imessaging_register(ldap_service->current_msg,
    1632             :                                      ldap_service,
    1633             :                                      MSG_RELOAD_TLS_CERTIFICATES,
    1634             :                                      ldap_reload_certs);
    1635         169 :         if (!NT_STATUS_IS_OK(status)) {
    1636           0 :                 task_server_terminate(task, "Cannot register ldap_reload_certs",
    1637             :                                       true);
    1638           0 :                 return;
    1639             :         }
    1640             : }
    1641             : 
    1642             : /*
    1643             :  * Check the size of an ldap request packet.
    1644             :  *
    1645             :  * For authenticated connections the maximum packet size is controlled by
    1646             :  * the smb.conf parameter "ldap max authenticated request size"
    1647             :  *
    1648             :  * For anonymous connections the maximum packet size is controlled by
    1649             :  * the smb.conf parameter "ldap max anonymous request size"
    1650             :  */
    1651     1216286 : static int ldapsrv_check_packet_size(
    1652             :         struct ldapsrv_connection *conn,
    1653             :         size_t size)
    1654             : {
    1655     1216286 :         bool is_anonymous = false;
    1656     1216286 :         size_t max_size = 0;
    1657             : 
    1658     1216286 :         max_size = lpcfg_ldap_max_anonymous_request_size(conn->lp_ctx);
    1659     1216286 :         if (size <= max_size) {
    1660     1213098 :                 return LDAP_SUCCESS;
    1661             :         }
    1662             : 
    1663             :         /*
    1664             :          * Request is larger than the maximum unauthenticated request size.
    1665             :          * As this code is called frequently we avoid calling
    1666             :          * security_token_is_anonymous if possible
    1667             :          */
    1668        2014 :         if (conn->session_info != NULL &&
    1669        2014 :                 conn->session_info->security_token != NULL) {
    1670        2014 :                 is_anonymous = security_token_is_anonymous(
    1671        2014 :                         conn->session_info->security_token);
    1672             :         }
    1673             : 
    1674        2014 :         if (is_anonymous) {
    1675           4 :                 DBG_WARNING(
    1676             :                         "LDAP request size (%zu) exceeds (%zu)\n",
    1677             :                         size,
    1678             :                         max_size);
    1679           4 :                 return LDAP_UNWILLING_TO_PERFORM;
    1680             :         }
    1681             : 
    1682        2010 :         max_size = lpcfg_ldap_max_authenticated_request_size(conn->lp_ctx);
    1683        2010 :         if (size > max_size) {
    1684           2 :                 DBG_WARNING(
    1685             :                         "LDAP request size (%zu) exceeds (%zu)\n",
    1686             :                         size,
    1687             :                         max_size);
    1688           2 :                 return LDAP_UNWILLING_TO_PERFORM;
    1689             :         }
    1690        2008 :         return LDAP_SUCCESS;
    1691             : 
    1692             : }
    1693             : 
    1694             : /*
    1695             :  * Check that the blob contains enough data to be a valid packet
    1696             :  * If there is a packet header check the size to ensure that it does not
    1697             :  * exceed the maximum sizes.
    1698             :  *
    1699             :  */
    1700     1216268 : static NTSTATUS ldapsrv_packet_check(
    1701             :         struct tstream_context *stream,
    1702             :         void *private_data,
    1703             :         DATA_BLOB blob,
    1704             :         size_t *packet_size)
    1705             : {
    1706        1174 :         NTSTATUS ret;
    1707     1216268 :         struct ldapsrv_connection *conn = private_data;
    1708     1216268 :         int result = LDB_SUCCESS;
    1709             : 
    1710     1216268 :         ret = ldap_full_packet(stream, private_data, blob, packet_size);
    1711     1216268 :         if (!NT_STATUS_IS_OK(ret)) {
    1712      608122 :                 return ret;
    1713             :         }
    1714      608146 :         result = ldapsrv_check_packet_size(conn, *packet_size);
    1715      608146 :         if (result != LDAP_SUCCESS) {
    1716           6 :                 return NT_STATUS_LDAP(result);
    1717             :         }
    1718      608140 :         return NT_STATUS_OK;
    1719             : }
    1720             : 
    1721          66 : NTSTATUS server_service_ldap_init(TALLOC_CTX *ctx)
    1722             : {
    1723           3 :         static const struct service_details details = {
    1724             :                 .inhibit_fork_on_accept = false,
    1725             :                 .inhibit_pre_fork = false,
    1726             :                 .task_init = ldapsrv_task_init,
    1727             :                 .post_fork = ldapsrv_post_fork,
    1728             :                 .before_loop = ldapsrv_before_loop,
    1729             :         };
    1730          66 :         return register_server_service(ctx, "ldap", &details);
    1731             : }

Generated by: LCOV version 1.14