LCOV - code coverage report
Current view: top level - source4/ldap_server - ldap_server.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 510 668 76.3 %
Date: 2024-06-13 04:01:37 Functions: 27 29 93.1 %

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

Generated by: LCOV version 1.13