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

Generated by: LCOV version 1.14