LCOV - code coverage report
Current view: top level - source4/torture/ldap - schema.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 153 202 75.7 %
Date: 2024-04-21 15:09:00 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS Implementation.
       3             :    LDAP schema tests
       4             :    
       5             :    Copyright (C) Stefan Metzmacher 2006
       6             :     
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             :    
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             :    
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             :    
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "libcli/ldap/ldap_client.h"
      24             : #include "lib/cmdline/cmdline.h"
      25             : #include "ldb_wrap.h"
      26             : #include "dsdb/samdb/samdb.h"
      27             : #include "../lib/util/dlinklist.h"
      28             : 
      29             : #include "torture/torture.h"
      30             : #include "torture/ldap/proto.h"
      31             : 
      32             : 
      33             : struct test_rootDSE {
      34             :         const char *defaultdn;
      35             :         const char *rootdn;
      36             :         const char *configdn;
      37             :         const char *schemadn;
      38             : };
      39             : 
      40             : struct test_schema_ctx {
      41             :         struct ldb_context *ldb;
      42             : 
      43             :         struct ldb_paged_control *ctrl;
      44             :         uint32_t count;
      45             :         bool pending;
      46             : 
      47             :         int (*callback)(void *, struct ldb_context *ldb, struct ldb_message *);
      48             :         void *private_data;
      49             : };
      50             : 
      51           1 : static bool test_search_rootDSE(struct ldb_context *ldb, struct test_rootDSE *root)
      52             : {
      53           0 :         int ret;
      54           0 :         struct ldb_message *msg;
      55           0 :         struct ldb_result *r;
      56             : 
      57           1 :         d_printf("Testing RootDSE Search\n");
      58             : 
      59           1 :         ret = ldb_search(ldb, ldb, &r, ldb_dn_new(ldb, ldb, NULL),
      60             :                          LDB_SCOPE_BASE, NULL, NULL);
      61           1 :         if (ret != LDB_SUCCESS) {
      62           0 :                 return false;
      63           1 :         } else if (r->count != 1) {
      64           0 :                 talloc_free(r);
      65           0 :                 return false;
      66             :         }
      67             : 
      68           1 :         msg = r->msgs[0];
      69             : 
      70           1 :         root->defaultdn      = ldb_msg_find_attr_as_string(msg, "defaultNamingContext", NULL);
      71           1 :         talloc_steal(ldb, root->defaultdn);
      72           1 :         root->rootdn = ldb_msg_find_attr_as_string(msg, "rootDomainNamingContext", NULL);
      73           1 :         talloc_steal(ldb, root->rootdn);
      74           1 :         root->configdn       = ldb_msg_find_attr_as_string(msg, "configurationNamingContext", NULL);
      75           1 :         talloc_steal(ldb, root->configdn);
      76           1 :         root->schemadn       = ldb_msg_find_attr_as_string(msg, "schemaNamingContext", NULL);
      77           1 :         talloc_steal(ldb, root->schemadn);
      78             : 
      79           1 :         talloc_free(r);
      80             : 
      81           1 :         return true;
      82             : }
      83             : 
      84        1771 : static int test_schema_search_callback(struct ldb_request *req, struct ldb_reply *ares)
      85             : {
      86           0 :         struct test_schema_ctx *actx;
      87        1771 :         int ret = LDB_SUCCESS;
      88             : 
      89        1771 :         actx = talloc_get_type(req->context, struct test_schema_ctx);
      90             : 
      91        1771 :         if (!ares) {
      92           0 :                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
      93             :         }
      94        1771 :         if (ares->error != LDB_SUCCESS) {
      95           0 :                 return ldb_request_done(req, ares->error);
      96             :         }
      97             : 
      98        1771 :         switch (ares->type) {
      99        1768 :         case LDB_REPLY_ENTRY:
     100        1768 :                 actx->count++;
     101        1768 :                 ret = actx->callback(actx->private_data, actx->ldb, ares->message);
     102        1768 :                 break;
     103             : 
     104           0 :         case LDB_REPLY_REFERRAL:
     105           0 :                 break;
     106             : 
     107           3 :         case LDB_REPLY_DONE:
     108           3 :                 if (ares->controls) {
     109           3 :                         struct ldb_paged_control *ctrl = NULL;
     110             :                         int i;
     111             : 
     112           3 :                         for (i=0; ares->controls[i]; i++) {
     113           3 :                                 if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, ares->controls[i]->oid) == 0) {
     114           3 :                                         ctrl = talloc_get_type(ares->controls[i]->data, struct ldb_paged_control);
     115           3 :                                         break;
     116             :                                 }
     117             :                         }
     118             : 
     119           3 :                         if (!ctrl) break;
     120             : 
     121           3 :                         talloc_free(actx->ctrl->cookie);
     122           3 :                         actx->ctrl->cookie = talloc_steal(actx->ctrl->cookie, ctrl->cookie);
     123           3 :                         actx->ctrl->cookie_len = ctrl->cookie_len;
     124             : 
     125           3 :                         if (actx->ctrl->cookie_len > 0) {
     126           1 :                                 actx->pending = true;
     127             :                         }
     128             :                 }
     129           3 :                 talloc_free(ares);
     130           3 :                 return ldb_request_done(req, LDB_SUCCESS);
     131             : 
     132           0 :         default:
     133           0 :                 d_printf("%s: unknown Reply Type %u\n", __location__, ares->type);
     134           0 :                 return ldb_request_done(req, LDB_ERR_OTHER);
     135             :         }
     136             : 
     137        1768 :         if (talloc_free(ares) == -1) {
     138           0 :                 d_printf("talloc_free failed\n");
     139           0 :                 actx->pending = 0;
     140           0 :                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
     141             :         }
     142             : 
     143        1768 :         if (ret) {
     144           0 :                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
     145             :         }
     146             : 
     147        1768 :         return LDB_SUCCESS;
     148             : }
     149             : 
     150           2 : static bool test_create_schema_type(struct ldb_context *ldb, struct test_rootDSE *root,
     151             :                                     const char *filter,
     152             :                                     int (*callback)(void *, struct ldb_context *ldb, struct ldb_message *),
     153             :                                     void *private_data)
     154             : {
     155           0 :         struct ldb_control **ctrl;
     156           0 :         struct ldb_paged_control *control;
     157           0 :         struct ldb_request *req;
     158           0 :         int ret;
     159           0 :         struct test_schema_ctx *actx;
     160             : 
     161           2 :         actx = talloc(ldb, struct test_schema_ctx);
     162           2 :         actx->ldb = ldb;
     163           2 :         actx->private_data = private_data;
     164           2 :         actx->callback= callback;
     165             : 
     166           2 :         ctrl = talloc_array(actx, struct ldb_control *, 2);
     167           2 :         ctrl[0] = talloc(ctrl, struct ldb_control);
     168           2 :         ctrl[0]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
     169           2 :         ctrl[0]->critical = true;
     170           2 :         control = talloc(ctrl[0], struct ldb_paged_control);
     171           2 :         control->size = 1000;
     172           2 :         control->cookie = NULL;
     173           2 :         control->cookie_len = 0;
     174           2 :         ctrl[0]->data = control;
     175           2 :         ctrl[1] = NULL;
     176             : 
     177           2 :         ret = ldb_build_search_req(&req, ldb, actx,
     178             :                                    ldb_dn_new(actx, ldb, root->schemadn),
     179             :                                    LDB_SCOPE_SUBTREE,
     180             :                                    filter, NULL,
     181             :                                    ctrl,
     182             :                                    actx, test_schema_search_callback,
     183             :                                    NULL);
     184             : 
     185           2 :         actx->ctrl = control;
     186           2 :         actx->count = 0;
     187           3 : again:
     188           3 :         actx->pending                = false;
     189             : 
     190           3 :         ret = ldb_request(ldb, req);
     191           3 :         if (ret != LDB_SUCCESS) {
     192           0 :                 d_printf("search failed - %s\n", ldb_errstring(ldb));
     193           0 :                 talloc_free(actx);
     194           0 :                 return false;
     195             :         }
     196             : 
     197           3 :         ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     198           3 :         if (ret != LDB_SUCCESS) {
     199           0 :                 d_printf("search error - %s\n", ldb_errstring(ldb));
     200           0 :                 talloc_free(actx);
     201           0 :                 return false;
     202             :         }
     203             : 
     204           3 :         if (actx->pending)
     205           1 :                 goto again;
     206             : 
     207           2 :         d_printf("filter[%s] count[%u]\n", filter, actx->count);
     208           2 :         talloc_free(actx);
     209           2 :         return true;
     210             : }
     211             : 
     212        1499 : static int test_add_attribute(void *ptr, struct ldb_context *ldb, struct ldb_message *msg)
     213             : {
     214        1499 :         struct dsdb_schema *schema = talloc_get_type(ptr, struct dsdb_schema);
     215           0 :         WERROR status;
     216             : 
     217        1499 :         status = dsdb_set_attribute_from_ldb(ldb, schema, msg);
     218        1499 :         if (!W_ERROR_IS_OK(status)) {
     219           0 :                 goto failed;
     220             :         }
     221             : 
     222        1499 :         return LDB_SUCCESS;
     223           0 : failed:
     224           0 :         return LDB_ERR_OTHER;
     225             : }
     226             : 
     227         269 : static int test_add_class(void *ptr, struct ldb_context *ldb, struct ldb_message *msg)
     228             : {
     229         269 :         struct dsdb_schema *schema = talloc_get_type(ptr, struct dsdb_schema);
     230           0 :         WERROR status;
     231             : 
     232         269 :         status = dsdb_set_class_from_ldb(schema, msg);
     233         269 :         if (!W_ERROR_IS_OK(status)) {
     234           0 :                 goto failed;
     235             :         }
     236             : 
     237         269 :         return LDB_SUCCESS;
     238           0 : failed:
     239           0 :         return LDB_ERR_OTHER;
     240             : }
     241             : 
     242           1 : static bool test_create_schema(struct ldb_context *ldb, struct test_rootDSE *root, struct dsdb_schema **_schema)
     243             : {
     244           1 :         bool ret = true;
     245           0 :         struct dsdb_schema *schema;
     246             : 
     247           1 :         schema = talloc_zero(ldb, struct dsdb_schema);
     248             : 
     249           1 :         d_printf("Fetching attributes...\n");
     250           1 :         ret &= test_create_schema_type(ldb, root, "(objectClass=attributeSchema)",
     251             :                                        test_add_attribute, schema);
     252           1 :         d_printf("Fetching objectClasses...\n");
     253           1 :         ret &= test_create_schema_type(ldb, root, "(objectClass=classSchema)",
     254             :                                        test_add_class, schema);
     255             : 
     256           1 :         if (ret == true) {
     257           1 :                 *_schema = schema;
     258             :         }
     259           1 :         return ret;
     260             : }
     261             : 
     262           1 : static bool test_dump_not_replicated(struct ldb_context *ldb, struct test_rootDSE *root, struct dsdb_schema *schema)
     263             : {
     264           0 :         struct dsdb_attribute *a;
     265           1 :         uint32_t a_i = 1;
     266             : 
     267           1 :         d_printf("Dumping not replicated attributes\n");
     268             : 
     269        1500 :         for (a=schema->attributes; a; a = a->next) {
     270        1499 :                 if (!(a->systemFlags & 0x00000001)) continue;
     271          98 :                 d_printf("attr[%4u]: '%s'\n", a_i++,
     272             :                          a->lDAPDisplayName);
     273             :         }
     274             : 
     275           1 :         return true;
     276             : }
     277             : 
     278           1 : static bool test_dump_partial(struct ldb_context *ldb, struct test_rootDSE *root, struct dsdb_schema *schema)
     279             : {
     280           0 :         struct dsdb_attribute *a;
     281           1 :         uint32_t a_i = 1;
     282             : 
     283           1 :         d_printf("Dumping attributes which are provided by the global catalog\n");
     284             : 
     285        1500 :         for (a=schema->attributes; a; a = a->next) {
     286        1499 :                 if (!(a->systemFlags & 0x00000002) && !a->isMemberOfPartialAttributeSet) continue;
     287         201 :                 d_printf("attr[%4u]:  %u %u '%s'\n", a_i++,
     288         201 :                          a->systemFlags & 0x00000002, a->isMemberOfPartialAttributeSet,
     289             :                          a->lDAPDisplayName);
     290             :         }
     291             : 
     292           1 :         return true;
     293             : }
     294             : 
     295           1 : static bool test_dump_contructed(struct ldb_context *ldb, struct test_rootDSE *root, struct dsdb_schema *schema)
     296             : {
     297           0 :         struct dsdb_attribute *a;
     298           1 :         uint32_t a_i = 1;
     299             : 
     300           1 :         d_printf("Dumping constructed attributes\n");
     301             : 
     302        1500 :         for (a=schema->attributes; a; a = a->next) {
     303        1499 :                 if (!(a->systemFlags & 0x00000004)) continue;
     304          55 :                 d_printf("attr[%4u]: '%s'\n", a_i++,
     305             :                          a->lDAPDisplayName);
     306             :         }
     307             : 
     308           1 :         return true;
     309             : }
     310             : 
     311           1 : static bool test_dump_sorted_syntax(struct ldb_context *ldb, struct test_rootDSE *root, struct dsdb_schema *schema)
     312             : {
     313           0 :         struct dsdb_attribute *a;
     314           1 :         uint32_t a_i = 1;
     315           0 :         uint32_t i;
     316           1 :         const char *syntaxes[] = {
     317             :                 "2.5.5.0",
     318             :                 "2.5.5.1",
     319             :                 "2.5.5.2",
     320             :                 "2.5.5.3",
     321             :                 "2.5.5.4",
     322             :                 "2.5.5.5",
     323             :                 "2.5.5.6",
     324             :                 "2.5.5.7",
     325             :                 "2.5.5.8",
     326             :                 "2.5.5.9",
     327             :                 "2.5.5.10",
     328             :                 "2.5.5.11",
     329             :                 "2.5.5.12",
     330             :                 "2.5.5.13",
     331             :                 "2.5.5.14",
     332             :                 "2.5.5.15",
     333             :                 "2.5.5.16",
     334             :                 "2.5.5.17"
     335             :         };
     336             : 
     337           1 :         d_printf("Dumping attribute syntaxes\n");
     338             : 
     339          19 :         for (i=0; i < ARRAY_SIZE(syntaxes); i++) {
     340       27000 :                 for (a=schema->attributes; a; a = a->next) {
     341           0 :                         char *om_hex;
     342             : 
     343       26982 :                         if (strcmp(syntaxes[i], a->attributeSyntax_oid) != 0) continue;
     344             : 
     345        1499 :                         om_hex = data_blob_hex_string_upper(ldb, &a->oMObjectClass);
     346        1499 :                         if (!om_hex) {
     347           0 :                                 return false;
     348             :                         }
     349             : 
     350        1499 :                         d_printf("attr[%4u]: %s %u '%s' '%s'\n", a_i++,
     351             :                                  a->attributeSyntax_oid, a->oMSyntax,
     352             :                                  om_hex, a->lDAPDisplayName);
     353        1499 :                         talloc_free(om_hex);
     354             :                 }
     355             :         }
     356             : 
     357           1 :         return true;
     358             : }
     359             : 
     360           1 : static bool test_dump_not_in_filtered_replica(struct ldb_context *ldb, struct test_rootDSE *root, struct dsdb_schema *schema)
     361             : {
     362           0 :         struct dsdb_attribute *a;
     363           1 :         uint32_t a_i = 1;
     364             : 
     365           1 :         d_printf("Dumping attributes not in filtered replica\n");
     366             : 
     367        1500 :         for (a=schema->attributes; a; a = a->next) {
     368        1499 :                 if (!dsdb_attribute_is_attr_in_filtered_replica(a)) {
     369         479 :                         d_printf("attr[%4u]: '%s'\n", a_i++,
     370             :                                  a->lDAPDisplayName);
     371             :                 }
     372             :         }
     373           1 :         return true;
     374             : }
     375             : 
     376           1 : bool torture_ldap_schema(struct torture_context *torture)
     377             : {
     378           0 :         struct ldb_context *ldb;
     379           1 :         bool ret = true;
     380           1 :         const char *host = torture_setting_string(torture, "host", NULL);
     381           0 :         char *url;
     382           0 :         struct test_rootDSE rootDSE;
     383           1 :         struct dsdb_schema *schema = NULL;
     384             : 
     385           1 :         ZERO_STRUCT(rootDSE);
     386             : 
     387           1 :         url = talloc_asprintf(torture, "ldap://%s/", host);
     388             : 
     389           1 :         ldb = ldb_wrap_connect(torture, torture->ev, torture->lp_ctx, url,
     390             :                                NULL,
     391             :                                samba_cmdline_get_creds(),
     392             :                                0);
     393           1 :         if (!ldb) goto failed;
     394             : 
     395           1 :         ret &= test_search_rootDSE(ldb, &rootDSE);
     396           1 :         if (!ret) goto failed;
     397           1 :         ret &= test_create_schema(ldb, &rootDSE, &schema);
     398           1 :         if (!ret) goto failed;
     399             : 
     400           1 :         ret &= test_dump_not_replicated(ldb, &rootDSE, schema);
     401           1 :         ret &= test_dump_partial(ldb, &rootDSE, schema);
     402           1 :         ret &= test_dump_contructed(ldb, &rootDSE, schema);
     403           1 :         ret &= test_dump_sorted_syntax(ldb, &rootDSE, schema);
     404           1 :         ret &= test_dump_not_in_filtered_replica(ldb, &rootDSE, schema);
     405             : 
     406           1 : failed:
     407           1 :         return ret;
     408             : }

Generated by: LCOV version 1.14