LCOV - code coverage report
Current view: top level - source4/cldap_server - rootdse.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 70 85 82.4 %
Date: 2024-04-21 15:09:00 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    CLDAP server - rootdse handling
       5             : 
       6             :    Copyright (C) Stefan Metzmacher      2006
       7             :    
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include <tevent.h>
      24             : #include <ldb.h>
      25             : #include <ldb_errors.h>
      26             : #include "samba/service_task.h"
      27             : #include "cldap_server/cldap_server.h"
      28             : #include "librpc/gen_ndr/ndr_misc.h"
      29             : #include "dsdb/samdb/samdb.h"
      30             : #include "ldb_wrap.h"
      31             : 
      32        2503 : static void cldapd_rootdse_fill(struct cldapd_server *cldapd,
      33             :                                 TALLOC_CTX *mem_ctx,
      34             :                                 struct ldap_SearchRequest *search,
      35             :                                 struct ldap_SearchResEntry **response,
      36             :                                 struct ldap_Result *result)
      37             : {
      38        2503 :         struct ldap_SearchResEntry *ent = NULL;
      39        2503 :         struct ldb_result *res = NULL;
      40          36 :         struct ldb_request *lreq;
      41        2503 :         const char **attrs = NULL;
      42        2503 :         const char *errstr = NULL;
      43        2503 :         int ret = LDAP_SUCCESS, ldb_ret;
      44             : 
      45        2503 :         if (search->num_attributes >= 1) {
      46          36 :                 size_t i;
      47             : 
      48        2499 :                 attrs = talloc_array(mem_ctx, const char *, search->num_attributes+1);
      49        2499 :                 if (attrs == NULL) goto nomem;
      50             : 
      51        5005 :                 for (i=0; i < search->num_attributes; i++) {
      52        2506 :                         attrs[i] = search->attributes[i];
      53             :                 }
      54        2499 :                 attrs[i] = NULL;
      55             :         }
      56             : 
      57        2503 :         res = talloc_zero(mem_ctx, struct ldb_result);
      58        2503 :         if (res == NULL) goto nomem;
      59             : 
      60        2503 :         ldb_ret = ldb_build_search_req_ex(&lreq, cldapd->samctx, mem_ctx,
      61             :                                           NULL, LDB_SCOPE_BASE,
      62             :                                           search->tree, attrs,
      63             :                                           NULL,
      64             :                                           res, ldb_search_default_callback,
      65             :                                           NULL);
      66             : 
      67        2503 :         if (ldb_ret != LDB_SUCCESS) {
      68           0 :                 goto reply;
      69             :         }
      70             : 
      71             :         /* Copy the timeout from the incoming call */
      72        2503 :         ldb_set_timeout(cldapd->samctx, lreq, search->timelimit);
      73             : 
      74        2503 :         ldb_ret = ldb_request(cldapd->samctx, lreq);
      75        2503 :         if (ldb_ret != LDB_SUCCESS) {
      76           0 :                 goto reply;
      77             :         }
      78             : 
      79        2503 :         ldb_ret = ldb_wait(lreq->handle, LDB_WAIT_ALL);
      80        2503 :         if (ldb_ret != LDB_SUCCESS) {
      81           0 :                 goto reply;
      82             :         }
      83             : 
      84        2503 :         if (res->count > 1) {
      85           0 :                 errstr = "Internal error: to much replies";
      86           0 :                 ldb_ret = LDB_ERR_OTHER;
      87           0 :                 goto reply;
      88        2503 :         } else if (res->count == 1) {
      89          36 :                 int j;
      90             : 
      91        2497 :                 ent = talloc(mem_ctx, struct ldap_SearchResEntry);
      92        2497 :                 if (ent == NULL) goto nomem;
      93             : 
      94        2497 :                 ent->dn = ldb_dn_alloc_linearized(ent, res->msgs[0]->dn);
      95        2497 :                 if (ent->dn == NULL) goto nomem;
      96        2497 :                 ent->num_attributes = 0;
      97        2497 :                 ent->attributes = NULL;
      98        2497 :                 if (res->msgs[0]->num_elements == 0) {
      99           0 :                         goto reply;
     100             :                 }
     101        2497 :                 ent->num_attributes = res->msgs[0]->num_elements;
     102        2497 :                 ent->attributes = talloc_array(ent, struct ldb_message_element,
     103             :                                                ent->num_attributes);
     104        2497 :                 if (ent->attributes == NULL) goto nomem;
     105        5098 :                 for (j=0; j < ent->num_attributes; j++) {
     106        2601 :                         ent->attributes[j].name = talloc_steal(ent->attributes,
     107             :                                                                res->msgs[0]->elements[j].name);
     108        2601 :                         ent->attributes[j].num_values = 0;
     109        2601 :                         ent->attributes[j].values = NULL;
     110        2601 :                         if (search->attributesonly && (res->msgs[0]->elements[j].num_values == 0)) {
     111           0 :                                 continue;
     112             :                         }
     113        2601 :                         ent->attributes[j].num_values = res->msgs[0]->elements[j].num_values;
     114        2601 :                         ent->attributes[j].values = res->msgs[0]->elements[j].values;
     115        2601 :                         talloc_steal(ent->attributes, res->msgs[0]->elements[j].values);
     116             :                 }
     117             :         }
     118             : 
     119        2503 : reply:
     120        2503 :         if (ret != LDAP_SUCCESS) {
     121             :                 /* nothing ... */
     122        2503 :         } else if (ldb_ret == LDB_SUCCESS) {
     123        2467 :                 ret = LDAP_SUCCESS;
     124        2467 :                 errstr = NULL;
     125             :         } else {
     126           0 :                 ret = ldb_ret;
     127           0 :                 errstr = ldb_errstring(cldapd->samctx);
     128             :         }
     129        2503 :         goto done;
     130           0 : nomem:
     131           0 :         talloc_free(ent);
     132           0 :         ret = LDAP_OPERATIONS_ERROR;
     133           0 :         errstr = "No memory";
     134        2503 : done:
     135        2503 :         *response = ent;
     136        2503 :         result->resultcode = ret;
     137        2503 :         result->errormessage = (errstr?talloc_strdup(mem_ctx, errstr):NULL);
     138        2503 : }
     139             : 
     140             : /*
     141             :   handle incoming cldap requests
     142             : */
     143        2503 : void cldapd_rootdse_request(struct cldap_socket *cldap, 
     144             :                             struct cldapd_server *cldapd,
     145             :                             TALLOC_CTX *tmp_ctx,
     146             :                             uint32_t message_id,
     147             :                             struct ldap_SearchRequest *search,
     148             :                             struct tsocket_address *src)
     149             : {
     150          36 :         NTSTATUS status;
     151          36 :         struct cldap_reply reply;
     152          36 :         struct ldap_Result result;
     153             : 
     154        2503 :         ZERO_STRUCT(result);
     155             : 
     156        2503 :         reply.messageid         = message_id;
     157        2503 :         reply.dest              = src;
     158        2503 :         reply.response          = NULL;
     159        2503 :         reply.result            = &result;
     160             : 
     161             :         /* Note: The remoteAddress should rather be set on a ldb request.
     162             :          * We can set this safely on the context here,
     163             :          * since cldapd_rootdse_fill operates synchronously. */
     164        2503 :         ldb_set_opaque(cldapd->samctx, "remoteAddress", src);
     165             : 
     166        2503 :         cldapd_rootdse_fill(cldapd, tmp_ctx, search, &reply.response,
     167             :                             reply.result);
     168             : 
     169             :         /*
     170             :          * We clear this after cldapd_rootdse_fill as this is shared ldb
     171             :          * and if it was not cleared the audit logging would report changes
     172             :          * made by internal processes as coming from the last cldap requester
     173             :          */
     174        2503 :         ldb_set_opaque(cldapd->samctx, "remoteAddress", NULL);
     175             : 
     176        2503 :         status = cldap_reply_send(cldap, &reply);
     177        2503 :         if (!NT_STATUS_IS_OK(status)) {
     178           0 :                 DEBUG(2,("cldap rootdse query failed '%s' - %s\n",
     179             :                          ldb_filter_from_tree(tmp_ctx, search->tree), nt_errstr(status)));
     180             :         }
     181             : 
     182        2503 :         return;
     183             : }

Generated by: LCOV version 1.14