LCOV - code coverage report
Current view: top level - source4/ldap_server - ldap_server.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 601 796 75.5 %
Date: 2024-02-28 12:06:22 Functions: 29 31 93.5 %

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

Generated by: LCOV version 1.14