LCOV - code coverage report
Current view: top level - source3/libads - tls_wrapping.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 66 103 64.1 %
Date: 2024-05-31 13:13:24 Functions: 10 11 90.9 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    ads tls wrapping code
       4             :    Copyright (C) Stefan Metzmacher 2024
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "ads.h"
      22             : #include "lib/param/param.h"
      23             : #include "../source4/lib/tls/tls.h"
      24             : 
      25           0 : void ndr_print_ads_tlswrap_struct(struct ndr_print *ndr, const char *name, const struct ads_tlswrap *r)
      26             : {
      27           0 :         ndr_print_struct(ndr, name, "tlswrap");
      28           0 :         ndr->depth++;
      29           0 :         ndr_print_ptr(ndr, "mem_ctx", r->mem_ctx);
      30           0 :         ndr_print_timeval(ndr, "endtime", &r->endtime);
      31             : #ifdef HAVE_ADS
      32           0 :         ndr_print_ptr(ndr, "sbiod", r->sbiod);
      33           0 :         ndr_print_ptr(ndr, "tls_params", r->tls_params);
      34           0 :         ndr_print_ptr(ndr, "tls_sync", r->tls_sync);
      35             : #endif /* HAVE_ADS */
      36           0 :         ndr->depth--;
      37           0 : }
      38             : 
      39             : #ifdef HAVE_ADS
      40             : 
      41          24 : static int ads_tlswrap_setup(Sockbuf_IO_Desc *sbiod, void *arg)
      42             : {
      43          24 :         struct ads_tlswrap *wrap = (struct ads_tlswrap *)arg;
      44             : 
      45          24 :         wrap->sbiod = sbiod;
      46             : 
      47          24 :         sbiod->sbiod_pvt = wrap;
      48             : 
      49          24 :         return 0;
      50             : }
      51             : 
      52          24 : static int ads_tlswrap_remove(Sockbuf_IO_Desc *sbiod)
      53             : {
      54          24 :         struct ads_tlswrap *wrap =
      55             :                         (struct ads_tlswrap *)sbiod->sbiod_pvt;
      56             : 
      57          24 :         wrap->sbiod = NULL;
      58             : 
      59          24 :         return 0;
      60             : }
      61             : 
      62         224 : static ssize_t ads_tlswrap_send_function(gnutls_transport_ptr_t ptr,
      63             :                                          const uint8_t *buf, size_t size)
      64             : {
      65         224 :         struct ads_tlswrap *wrap = (struct ads_tlswrap *)ptr;
      66             : 
      67         224 :         if (wrap->endtime.tv_sec != 0) {
      68          96 :                 if (timeval_expired(&wrap->endtime)) {
      69           0 :                         errno = ECONNRESET;
      70           0 :                         return -1;
      71             :                 }
      72             :         }
      73             : 
      74         224 :         return LBER_SBIOD_WRITE_NEXT(wrap->sbiod, discard_const(buf), size);
      75             : }
      76             : 
      77         504 : static ssize_t ads_tlswrap_recv_function(gnutls_transport_ptr_t ptr,
      78             :                                          uint8_t *buf, size_t size)
      79             : {
      80         504 :         struct ads_tlswrap *wrap = (struct ads_tlswrap *)ptr;
      81             : 
      82         504 :         if (wrap->endtime.tv_sec != 0) {
      83         360 :                 if (timeval_expired(&wrap->endtime)) {
      84           0 :                         errno = ECONNRESET;
      85           0 :                         return -1;
      86             :                 }
      87             :         }
      88             : 
      89         504 :         return LBER_SBIOD_READ_NEXT(wrap->sbiod, buf, size);
      90             : }
      91             : 
      92         240 : static ber_slen_t ads_tlswrap_read(Sockbuf_IO_Desc *sbiod,
      93             :                                    void *buf, ber_len_t len)
      94             : {
      95         240 :         struct ads_tlswrap *wrap =
      96             :                         (struct ads_tlswrap *)sbiod->sbiod_pvt;
      97             : 
      98         240 :         return tstream_tls_sync_read(wrap->tls_sync, buf, len);
      99             : }
     100             : 
     101          96 : static ber_slen_t ads_tlswrap_write(Sockbuf_IO_Desc *sbiod,
     102             :                                     void *buf, ber_len_t len)
     103             : {
     104          96 :         struct ads_tlswrap *wrap =
     105             :                         (struct ads_tlswrap *)sbiod->sbiod_pvt;
     106             : 
     107          96 :         return tstream_tls_sync_write(wrap->tls_sync, buf, len);
     108             : }
     109             : 
     110         192 : static int ads_tlswrap_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
     111             : {
     112         192 :         struct ads_tlswrap *wrap =
     113             :                         (struct ads_tlswrap *)sbiod->sbiod_pvt;
     114           0 :         int ret;
     115             : 
     116         192 :         switch (opt) {
     117         192 :         case LBER_SB_OPT_DATA_READY:
     118         192 :                 if (tstream_tls_sync_pending(wrap->tls_sync) > 0) {
     119          48 :                         return 1;
     120             :                 }
     121             : 
     122         144 :                 ret = LBER_SBIOD_CTRL_NEXT(sbiod, opt, arg);
     123         144 :                 break;
     124           0 :         default:
     125           0 :                 ret = LBER_SBIOD_CTRL_NEXT(sbiod, opt, arg);
     126           0 :                 break;
     127             :         }
     128             : 
     129         144 :         return ret;
     130             : }
     131             : 
     132          24 : static int ads_tlswrap_close(Sockbuf_IO_Desc *sbiod)
     133             : {
     134          24 :         struct ads_tlswrap *wrap =
     135             :                         (struct ads_tlswrap *)sbiod->sbiod_pvt;
     136             : 
     137          24 :         TALLOC_FREE(wrap->tls_sync);
     138          24 :         TALLOC_FREE(wrap->tls_params);
     139             : 
     140          24 :         return 0;
     141             : }
     142             : 
     143             : static const Sockbuf_IO ads_tlswrap_sockbuf_io = {
     144             :         ads_tlswrap_setup,      /* sbi_setup */
     145             :         ads_tlswrap_remove,     /* sbi_remove */
     146             :         ads_tlswrap_ctrl,       /* sbi_ctrl */
     147             :         ads_tlswrap_read,       /* sbi_read */
     148             :         ads_tlswrap_write,      /* sbi_write */
     149             :         ads_tlswrap_close       /* sbi_close */
     150             : };
     151             : 
     152          24 : ADS_STATUS ads_setup_tls_wrapping(struct ads_tlswrap *wrap,
     153             :                                   LDAP *ld,
     154             :                                   const char *server_name)
     155             : {
     156          24 :         TALLOC_CTX *frame = talloc_stackframe();
     157          24 :         Sockbuf_IO *io = discard_const_p(Sockbuf_IO, &ads_tlswrap_sockbuf_io);
     158          24 :         Sockbuf *sb = NULL;
     159          24 :         struct loadparm_context *lp_ctx = NULL;
     160           0 :         ADS_STATUS status;
     161           0 :         NTSTATUS ntstatus;
     162           0 :         unsigned to;
     163           0 :         int rc;
     164             : 
     165          24 :         rc = ldap_get_option(ld, LDAP_OPT_SOCKBUF, &sb);
     166          24 :         status = ADS_ERROR_LDAP(rc);
     167          24 :         if (!ADS_ERR_OK(status)) {
     168           0 :                 TALLOC_FREE(frame);
     169           0 :                 return status;
     170             :         }
     171             : 
     172          24 :         lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
     173          24 :         if (lp_ctx == NULL) {
     174           0 :                 TALLOC_FREE(frame);
     175           0 :                 return ADS_ERROR(LDAP_NO_MEMORY);
     176             :         }
     177             : 
     178          24 :         ntstatus = tstream_tls_params_client_lpcfg(wrap->mem_ctx,
     179             :                                                    lp_ctx,
     180             :                                                    server_name,
     181             :                                                    &wrap->tls_params);
     182          24 :         if (!NT_STATUS_IS_OK(ntstatus)) {
     183           0 :                 TALLOC_FREE(frame);
     184           0 :                 return ADS_ERROR_NT(ntstatus);
     185             :         }
     186             : 
     187             :         /* setup the real wrapping callbacks */
     188          24 :         rc = ber_sockbuf_add_io(sb, io, LBER_SBIOD_LEVEL_TRANSPORT, wrap);
     189          24 :         status = ADS_ERROR_LDAP(rc);
     190          24 :         if (!ADS_ERR_OK(status)) {
     191           0 :                 TALLOC_FREE(frame);
     192           0 :                 return status;
     193             :         }
     194             : 
     195          24 :         to = lpcfg_ldap_connection_timeout(lp_ctx);
     196          24 :         wrap->endtime = timeval_current_ofs(to, 0);
     197          24 :         ntstatus = tstream_tls_sync_setup(wrap->tls_params,
     198             :                                           wrap,
     199             :                                           ads_tlswrap_send_function,
     200             :                                           ads_tlswrap_recv_function,
     201          24 :                                           wrap->mem_ctx,
     202             :                                           &wrap->tls_sync);
     203          24 :         wrap->endtime = timeval_zero();
     204          24 :         if (!NT_STATUS_IS_OK(ntstatus)) {
     205           0 :                 ber_sockbuf_remove_io(sb, io, LBER_SBIOD_LEVEL_TRANSPORT);
     206           0 :                 TALLOC_FREE(frame);
     207           0 :                 return ADS_ERROR_NT(ntstatus);
     208             :         }
     209             : 
     210          24 :         TALLOC_FREE(frame);
     211          24 :         return ADS_SUCCESS;
     212             : }
     213             : 
     214         354 : const DATA_BLOB *ads_tls_channel_bindings(struct ads_tlswrap *wrap)
     215             : {
     216         354 :         if (wrap->tls_sync == NULL) {
     217         306 :                 return NULL;
     218             :         }
     219             : 
     220          48 :         return tstream_tls_sync_channel_bindings(wrap->tls_sync);
     221             : }
     222             : #else
     223           0 : ADS_STATUS ads_setup_tls_wrapping(struct ads_tlswrap *wrap,
     224             :                                   LDAP *ld,
     225             :                                   const char *server_name)
     226             : {
     227           0 :         return ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED);
     228             : }
     229           0 : const DATA_BLOB *ads_tls_channel_bindings(struct ads_tlswrap *wrap)
     230             : {
     231           0 :         return NULL;
     232             : }
     233             : #endif /* HAVE_ADS */

Generated by: LCOV version 1.14