LCOV - code coverage report
Current view: top level - source4/dsdb/common - dsdb_dn.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 195 265 73.6 %
Date: 2024-04-21 15:09:00 Functions: 16 16 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    Samba utility functions
       4             : 
       5             :    Copyright (C) Andrew Tridgell 2009
       6             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
       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 "dsdb/samdb/samdb.h"
      24             : #include <ldb_module.h>
      25             : #include "librpc/ndr/libndr.h"
      26             : #include "libcli/security/dom_sid.h"
      27             : #include "lib/util/smb_strtox.h"
      28             : 
      29    73491772 : enum dsdb_dn_format dsdb_dn_oid_to_format(const char *oid) 
      30             : {
      31    73491772 :         if (strcmp(oid, LDB_SYNTAX_DN) == 0) {
      32    17559748 :                 return DSDB_NORMAL_DN;
      33    55340375 :         } else if (strcmp(oid, DSDB_SYNTAX_BINARY_DN) == 0) {
      34    20854573 :                 return DSDB_BINARY_DN;
      35    34457075 :         } else if (strcmp(oid, DSDB_SYNTAX_STRING_DN) == 0) {
      36       28147 :                 return DSDB_STRING_DN;
      37    34428565 :         } else if (strcmp(oid, DSDB_SYNTAX_OR_NAME) == 0) {
      38           0 :                 return DSDB_NORMAL_DN;
      39             :         } else {
      40    34428561 :                 return DSDB_INVALID_DN;
      41             :         }
      42             : }
      43             : 
      44    23401424 : static struct dsdb_dn *dsdb_dn_construct_internal(TALLOC_CTX *mem_ctx, 
      45             :                                                   struct ldb_dn *dn, 
      46             :                                                   DATA_BLOB extra_part, 
      47             :                                                   enum dsdb_dn_format dn_format, 
      48             :                                                   const char *oid) 
      49             : {
      50    23401424 :         struct dsdb_dn *dsdb_dn = NULL;
      51             : 
      52    23401424 :         switch (dn_format) {
      53    10296311 :         case DSDB_BINARY_DN:
      54             :         case DSDB_STRING_DN:
      55    10296311 :                 break;
      56    13092230 :         case DSDB_NORMAL_DN:
      57    13092230 :                 if (extra_part.length != 0) {
      58           0 :                         errno = EINVAL;
      59           0 :                         return NULL;
      60             :                 }
      61    12563888 :                 break;
      62           0 :         case DSDB_INVALID_DN:
      63             :         default:
      64           0 :                 errno = EINVAL;
      65           0 :                 return NULL;
      66             :         }
      67             : 
      68    23401424 :         dsdb_dn = talloc(mem_ctx, struct dsdb_dn);
      69    23401424 :         if (!dsdb_dn) {
      70           0 :                 errno = ENOMEM;
      71           0 :                 return NULL;
      72             :         }
      73    23401424 :         dsdb_dn->dn = talloc_steal(dsdb_dn, dn);
      74    23401424 :         dsdb_dn->extra_part = extra_part;
      75    23401424 :         dsdb_dn->dn_format = dn_format;
      76             : 
      77    23401424 :         dsdb_dn->oid = oid;
      78    23401424 :         talloc_steal(dsdb_dn, extra_part.data);
      79    23401424 :         return dsdb_dn;
      80             : }
      81             : 
      82    10451579 : struct dsdb_dn *dsdb_dn_construct(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, DATA_BLOB extra_part, 
      83             :                                   const char *oid) 
      84             : {
      85    10451579 :         enum dsdb_dn_format dn_format = dsdb_dn_oid_to_format(oid);
      86    10451579 :         return dsdb_dn_construct_internal(mem_ctx, dn, extra_part, dn_format, oid);
      87             : }
      88             : 
      89    23227568 : struct dsdb_dn *dsdb_dn_parse_trusted(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 
      90             :                                       const struct ldb_val *dn_blob, const char *dn_oid)
      91             : {
      92      535378 :         struct dsdb_dn *dsdb_dn;
      93      535378 :         struct ldb_dn *dn;
      94      535378 :         size_t len;
      95      535378 :         TALLOC_CTX *tmp_ctx;
      96      535378 :         char *p1;
      97      535378 :         char *p2;
      98      535378 :         uint32_t blen;
      99      535378 :         struct ldb_val bval;
     100      535378 :         struct ldb_val dval;
     101      535378 :         char *dn_str;
     102    23227568 :         int error = 0;
     103             : 
     104    23227568 :         enum dsdb_dn_format dn_format = dsdb_dn_oid_to_format(dn_oid);
     105             : 
     106    23227568 :         if (dn_blob == NULL || dn_blob->data == NULL || dn_blob->length == 0) {
     107           1 :                 return NULL;
     108             :         }
     109             : 
     110    23227567 :         switch (dn_format) {
     111           0 :         case DSDB_INVALID_DN:
     112           0 :                 return NULL;
     113    12949846 :         case DSDB_NORMAL_DN:
     114             :         {
     115    12949846 :                 dn = ldb_dn_from_ldb_val(mem_ctx, ldb, dn_blob);
     116    12949846 :                 if (!dn) {
     117           1 :                         talloc_free(dn);
     118           1 :                         return NULL;
     119             :                 }
     120    12949845 :                 return dsdb_dn_construct_internal(mem_ctx, dn, data_blob_null, dn_format, dn_oid);
     121             :         }
     122    10277709 :         case DSDB_BINARY_DN:
     123    10277709 :                 if (dn_blob->length < 2 || dn_blob->data[0] != 'B' || dn_blob->data[1] != ':') {
     124          11 :                         return NULL;
     125             :                 }
     126    10265474 :                 break;
     127          12 :         case DSDB_STRING_DN:
     128          12 :                 if (dn_blob->length < 2 || dn_blob->data[0] != 'S' || dn_blob->data[1] != ':') {
     129           0 :                         return NULL;
     130             :                 }
     131           0 :                 break;
     132           0 :         default:
     133           0 :                 return NULL;
     134             :         }
     135             : 
     136    10277707 :         if (strlen((const char*)dn_blob->data) != dn_blob->length) {
     137             :                 /* The RDN must not contain a character with value 0x0 */
     138           0 :                 return NULL;
     139             :         }
     140             : 
     141    10277706 :         tmp_ctx = talloc_new(mem_ctx);
     142    10277706 :         if (tmp_ctx == NULL) {
     143           0 :                 return NULL;
     144             :         }
     145             : 
     146    10277706 :         len = dn_blob->length - 2;
     147    10277706 :         p1 = talloc_strndup(tmp_ctx, (const char *)dn_blob->data + 2, len);
     148    10277706 :         if (!p1) {
     149           0 :                 goto failed;
     150             :         }
     151             : 
     152    10277706 :         errno = 0;
     153    10277706 :         blen = smb_strtoul(p1, &p2, 10, &error, SMB_STR_STANDARD);
     154    10277706 :         if (error != 0) {
     155           0 :                 DEBUG(10, (__location__ ": failed\n"));
     156           0 :                 goto failed;
     157             :         }
     158    10277706 :         if (p2 == NULL) {
     159           0 :                 DEBUG(10, (__location__ ": failed\n"));
     160           0 :                 goto failed;
     161             :         }
     162    10277706 :         if (p2[0] != ':') {
     163           0 :                 DEBUG(10, (__location__ ": failed\n"));
     164           0 :                 goto failed;
     165             :         }
     166    10277706 :         len -= PTR_DIFF(p2,p1);//???
     167    10277706 :         p1 = p2+1;
     168    10277706 :         len--;
     169             :                 
     170    10277706 :         if (blen >= len) {
     171          12 :                 DEBUG(10, (__location__ ": blen=%u len=%u\n", (unsigned)blen, (unsigned)len));
     172          12 :                 goto failed;
     173             :         }
     174             :                 
     175    10277694 :         p2 = p1 + blen;
     176    10277694 :         if (p2[0] != ':') {
     177           6 :                 DEBUG(10, (__location__ ": %s", p2));
     178           6 :                 goto failed;
     179             :         }
     180    10277688 :         dn_str = p2+1;
     181             :                 
     182             :                 
     183    10277688 :         switch (dn_format) {
     184    10277679 :         case DSDB_BINARY_DN:
     185    10277679 :                 if ((blen % 2 != 0)) {
     186           0 :                         DEBUG(10, (__location__ ": blen=%u - not an even number\n", (unsigned)blen));
     187           0 :                         goto failed;
     188             :                 }
     189             :                 
     190    10277679 :                 if (blen >= 2) {
     191    10277678 :                         bval.length = (blen/2)+1;
     192    10277678 :                         bval.data = talloc_size(tmp_ctx, bval.length);
     193    10277678 :                         if (bval.data == NULL) {
     194           0 :                                 DEBUG(10, (__location__ ": err\n"));
     195           0 :                                 goto failed;
     196             :                         }
     197    10277678 :                         bval.data[bval.length-1] = 0;
     198             :                 
     199    10277678 :                         bval.length = strhex_to_str((char *)bval.data, bval.length,
     200             :                                                     p1, blen);
     201    10277678 :                         if (bval.length != (blen / 2)) {
     202           2 :                                 DEBUG(10, (__location__ ": non hexadecimal characters found in binary prefix\n"));
     203           2 :                                 goto failed;
     204             :                         }
     205             :                 } else {
     206           1 :                         bval = data_blob_null;
     207             :                 }
     208             : 
     209    10265463 :                 break;
     210           9 :         case DSDB_STRING_DN:
     211           9 :                 bval = data_blob(p1, blen);
     212           9 :                 break;
     213           0 :         default:
     214             :                 /* never reached */
     215           0 :                 return NULL;
     216             :         }
     217             :         
     218             : 
     219    10277686 :         dval.data = (uint8_t *)dn_str;
     220    10277686 :         dval.length = strlen(dn_str);
     221             :                 
     222    10277686 :         dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &dval);
     223    10277686 :         if (!dn) {
     224           0 :                 DEBUG(10, (__location__ ": err\n"));
     225           0 :                 goto failed;
     226             :         }
     227             :                 
     228    10277686 :         dsdb_dn = dsdb_dn_construct(mem_ctx, dn, bval, dn_oid);
     229             :                 
     230    10277686 :         talloc_free(tmp_ctx);
     231    10277686 :         return dsdb_dn;
     232             : 
     233          20 : failed:
     234          20 :         talloc_free(tmp_ctx);
     235          20 :         return NULL;
     236             : }
     237             : 
     238     1400118 : struct dsdb_dn *dsdb_dn_parse(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 
     239             :                               const struct ldb_val *dn_blob, const char *dn_oid)
     240             : {
     241     1400118 :         struct dsdb_dn *dsdb_dn = dsdb_dn_parse_trusted(mem_ctx, ldb,
     242             :                                                         dn_blob, dn_oid);
     243     1400118 :         if (dsdb_dn == NULL) {
     244          23 :                 return NULL;
     245             :         }
     246     1400081 :         if (ldb_dn_validate(dsdb_dn->dn) == false) {
     247          15 :                 DEBUG(10, ("could not parse %.*s as a %s DN\n",
     248             :                            (int)dn_blob->length, dn_blob->data,
     249             :                            dn_oid));
     250          15 :                 return NULL;
     251             :         }
     252     1278825 :         return dsdb_dn;
     253             : }
     254             : 
     255    21668758 : static char *dsdb_dn_get_with_postfix(TALLOC_CTX *mem_ctx, 
     256             :                                      struct dsdb_dn *dsdb_dn,
     257             :                                      const char *postfix)
     258             : {
     259    21668758 :         if (!postfix) {
     260           0 :                 return NULL;
     261             :         }
     262             : 
     263    21668758 :         switch (dsdb_dn->dn_format) {
     264    11758128 :         case DSDB_NORMAL_DN:
     265             :         {
     266    11758128 :                 return talloc_strdup(mem_ctx, postfix);
     267             :         }
     268     9910616 :         case DSDB_BINARY_DN:
     269             :         {
     270     9910616 :                 char *hexstr = data_blob_hex_string_upper(mem_ctx, &dsdb_dn->extra_part);
     271             :         
     272     9910616 :                 char *p = talloc_asprintf(mem_ctx, "B:%u:%s:%s", (unsigned)(dsdb_dn->extra_part.length*2), hexstr, 
     273             :                                           postfix);
     274     9910616 :                 talloc_free(hexstr);
     275     9910616 :                 return p;
     276             :         }
     277          14 :         case DSDB_STRING_DN:
     278             :         {
     279          14 :                 return talloc_asprintf(mem_ctx, "S:%u:%*.*s:%s", 
     280           0 :                                     (unsigned)(dsdb_dn->extra_part.length), 
     281           0 :                                     (int)(dsdb_dn->extra_part.length), 
     282          14 :                                     (int)(dsdb_dn->extra_part.length), 
     283          14 :                                     (const char *)dsdb_dn->extra_part.data, 
     284             :                                     postfix);
     285             :         }
     286           0 :         default:
     287           0 :                 return NULL;
     288             :         }
     289             : }
     290             : 
     291     4856833 : char *dsdb_dn_get_linearized(TALLOC_CTX *mem_ctx, 
     292             :                               struct dsdb_dn *dsdb_dn)
     293             : {
     294     4856833 :         const char *postfix = ldb_dn_get_linearized(dsdb_dn->dn);
     295     4856833 :         return dsdb_dn_get_with_postfix(mem_ctx, dsdb_dn, postfix);
     296             : }
     297             : 
     298        1138 : char *dsdb_dn_get_casefold(TALLOC_CTX *mem_ctx, 
     299             :                            struct dsdb_dn *dsdb_dn) 
     300             : {
     301        1138 :         const char *postfix = ldb_dn_get_casefold(dsdb_dn->dn);
     302        1138 :         return dsdb_dn_get_with_postfix(mem_ctx, dsdb_dn, postfix);
     303             : }
     304             : 
     305    16810787 : char *dsdb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, 
     306             :                                       struct dsdb_dn *dsdb_dn,
     307             :                                       int mode)
     308             : {
     309    16810787 :         char *postfix = ldb_dn_get_extended_linearized(mem_ctx, dsdb_dn->dn, mode);
     310    16810787 :         char *ret = dsdb_dn_get_with_postfix(mem_ctx, dsdb_dn, postfix);
     311    16810787 :         talloc_free(postfix);
     312    16810787 :         return ret;
     313             : }
     314             : 
     315        1147 : int dsdb_dn_binary_canonicalise(struct ldb_context *ldb, void *mem_ctx,
     316             :                                 const struct ldb_val *in, struct ldb_val *out)
     317             : {
     318        1147 :         struct dsdb_dn *dsdb_dn = dsdb_dn_parse(mem_ctx, ldb, in, DSDB_SYNTAX_BINARY_DN);
     319             :         
     320        1147 :         if (!dsdb_dn) {
     321          22 :                 return -1;
     322             :         }
     323        1124 :         *out = data_blob_string_const(dsdb_dn_get_casefold(mem_ctx, dsdb_dn));
     324        1124 :         talloc_free(dsdb_dn);
     325        1124 :         if (!out->data) {
     326           0 :                 return -1;
     327             :         }
     328        1110 :         return 0;
     329             : }
     330             : 
     331         403 : int dsdb_dn_binary_comparison(struct ldb_context *ldb, void *mem_ctx,
     332             :                                      const struct ldb_val *v1,
     333             :                                      const struct ldb_val *v2)
     334             : {
     335         403 :         return ldb_any_comparison(ldb, mem_ctx, dsdb_dn_binary_canonicalise, v1, v2);
     336             : }
     337             : 
     338           9 : int dsdb_dn_string_canonicalise(struct ldb_context *ldb, void *mem_ctx,
     339             :                                 const struct ldb_val *in, struct ldb_val *out)
     340             : {
     341           9 :         struct dsdb_dn *dsdb_dn = dsdb_dn_parse(mem_ctx, ldb, in, DSDB_SYNTAX_STRING_DN);
     342             :         
     343           9 :         if (!dsdb_dn) {
     344           0 :                 return -1;
     345             :         }
     346           8 :         *out = data_blob_string_const(dsdb_dn_get_casefold(mem_ctx, dsdb_dn));
     347           8 :         talloc_free(dsdb_dn);
     348           8 :         if (!out->data) {
     349           0 :                 return -1;
     350             :         }
     351           0 :         return 0;
     352             : }
     353             : 
     354           4 : int dsdb_dn_string_comparison(struct ldb_context *ldb, void *mem_ctx,
     355             :                                      const struct ldb_val *v1,
     356             :                                      const struct ldb_val *v2)
     357             : {
     358           4 :         return ldb_any_comparison(ldb, mem_ctx, dsdb_dn_string_canonicalise, v1, v2);
     359             : }
     360             : 
     361             : /*
     362             :  * format a drsuapi_DsReplicaObjectIdentifier naming context as a string for debugging
     363             :  *
     364             :  * When forming a DN for DB access you must use drs_ObjectIdentifier_to_dn()
     365             :  */
     366           8 : char *drs_ObjectIdentifier_to_debug_string(TALLOC_CTX *mem_ctx,
     367             :                                            struct drsuapi_DsReplicaObjectIdentifier *nc)
     368             : {
     369           8 :         char *ret = NULL;
     370           8 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     371           8 :         if (!GUID_all_zero(&nc->guid)) {
     372           0 :                 char *guid = GUID_string(tmp_ctx, &nc->guid);
     373           0 :                 if (guid) {
     374           0 :                         ret = talloc_asprintf_append(ret, "<GUID=%s>;", guid);
     375             :                 }
     376             :         }
     377           8 :         if (nc->__ndr_size_sid != 0 && nc->sid.sid_rev_num != 0) {
     378           0 :                 const char *sid = dom_sid_string(tmp_ctx, &nc->sid);
     379           0 :                 if (sid) {
     380           0 :                         ret = talloc_asprintf_append(ret, "<SID=%s>;", sid);
     381             :                 }
     382             :         }
     383           8 :         if (nc->__ndr_size_dn != 0 && nc->dn) {
     384           8 :                 ret = talloc_asprintf_append(ret, "%s", nc->dn);
     385             :         }
     386           8 :         talloc_free(tmp_ctx);
     387           8 :         talloc_steal(mem_ctx, ret);
     388           8 :         return ret;
     389             : }
     390             : 
     391             : /*
     392             :  * Safely convert a drsuapi_DsReplicaObjectIdentifier into an LDB DN
     393             :  *
     394             :  * We need to have GUID and SID priority and not allow extended
     395             :  * components in the DN.
     396             :  *
     397             :  * We must also totally honour the priority even if the string DN is not valid or able to parse as a DN.
     398             :  */
     399       35618 : static struct ldb_dn *drs_ObjectIdentifier_to_dn(TALLOC_CTX *mem_ctx,
     400             :                                                  struct ldb_context *ldb,
     401             :                                                  struct drsuapi_DsReplicaObjectIdentifier *nc)
     402             : {
     403       35618 :         struct ldb_dn *new_dn = NULL;
     404             : 
     405       35618 :         if (!GUID_all_zero(&nc->guid)) {
     406           0 :                 struct GUID_txt_buf buf;
     407       15302 :                 char *guid = GUID_buf_string(&nc->guid, &buf);
     408             : 
     409       15302 :                 new_dn = ldb_dn_new_fmt(mem_ctx,
     410             :                                         ldb,
     411             :                                         "<GUID=%s>",
     412             :                                         guid);
     413       15302 :                 if (new_dn == NULL) {
     414           0 :                         DBG_ERR("Failed to prepare drs_ObjectIdentifier "
     415             :                                 "GUID %s into a DN\n",
     416             :                                 guid);
     417           0 :                         return NULL;
     418             :                 }
     419             : 
     420       15302 :                 return new_dn;
     421             :         }
     422             : 
     423       20316 :         if (nc->__ndr_size_sid != 0 && nc->sid.sid_rev_num != 0) {
     424           0 :                 struct dom_sid_buf buf;
     425           0 :                 char *sid = dom_sid_str_buf(&nc->sid, &buf);
     426             : 
     427           0 :                 new_dn = ldb_dn_new_fmt(mem_ctx,
     428             :                                         ldb,
     429             :                                         "<SID=%s>",
     430             :                                         sid);
     431           0 :                 if (new_dn == NULL) {
     432           0 :                         DBG_ERR("Failed to prepare drs_ObjectIdentifier "
     433             :                                 "SID %s into a DN\n",
     434             :                                 sid);
     435           0 :                         return NULL;
     436             :                 }
     437           0 :                 return new_dn;
     438             :         }
     439             : 
     440       20316 :         if (nc->__ndr_size_dn != 0 && nc->dn) {
     441       20316 :                 int dn_comp_num = 0;
     442       20316 :                 bool new_dn_valid = false;
     443             : 
     444       20316 :                 new_dn = ldb_dn_new(mem_ctx, ldb, nc->dn);
     445       20316 :                 if (new_dn == NULL) {
     446             :                         /* Set to WARNING as this is user-controlled, don't print the value into the logs */
     447           0 :                         DBG_WARNING("Failed to parse string DN in "
     448             :                                     "drs_ObjectIdentifier into an LDB DN\n");
     449           0 :                         return NULL;
     450             :                 }
     451             : 
     452       20316 :                 new_dn_valid = ldb_dn_validate(new_dn);
     453       20316 :                 if (!new_dn_valid) {
     454             :                         /*
     455             :                          * Set to WARNING as this is user-controlled,
     456             :                          * but can print the value into the logs as it
     457             :                          * parsed a bit
     458             :                          */
     459           0 :                         DBG_WARNING("Failed to validate string DN [%s] in "
     460             :                                     "drs_ObjectIdentifier as an LDB DN\n",
     461             :                                     ldb_dn_get_linearized(new_dn));
     462           0 :                         return NULL;
     463             :                 }
     464             : 
     465       20316 :                 dn_comp_num = ldb_dn_get_comp_num(new_dn);
     466       20316 :                 if (dn_comp_num <= 0) {
     467             :                         /*
     468             :                          * Set to WARNING as this is user-controlled,
     469             :                          * but can print the value into the logs as it
     470             :                          * parsed a bit
     471             :                          */
     472           0 :                         DBG_WARNING("DN [%s] in drs_ObjectIdentifier "
     473             :                                     "must have 1 or more components\n",
     474             :                                     ldb_dn_get_linearized(new_dn));
     475           0 :                         return NULL;
     476             :                 }
     477             : 
     478       20316 :                 if (ldb_dn_is_special(new_dn)) {
     479             :                         /*
     480             :                          * Set to WARNING as this is user-controlled,
     481             :                          * but can print the value into the logs as it
     482             :                          * parsed a bit
     483             :                          */
     484           0 :                         DBG_WARNING("New string DN [%s] in "
     485             :                                     "drs_ObjectIdentifier is a "
     486             :                                     "special LDB DN\n",
     487             :                                     ldb_dn_get_linearized(new_dn));
     488           0 :                         return NULL;
     489             :                 }
     490             : 
     491             :                 /*
     492             :                  * We want this just to be a string DN, extended
     493             :                  * components are manually handled above
     494             :                  */
     495       20316 :                 if (ldb_dn_has_extended(new_dn)) {
     496             :                         /*
     497             :                          * Set to WARNING as this is user-controlled,
     498             :                          * but can print the value into the logs as it
     499             :                          * parsed a bit
     500             :                          */
     501           0 :                         DBG_WARNING("Refusing to parse New string DN [%s] in "
     502             :                                     "drs_ObjectIdentifier as an "
     503             :                                     "extended LDB DN "
     504             :                                     "(GUIDs and SIDs should be in the "
     505             :                                     ".guid and .sid IDL elements, "
     506             :                                     "not in the string\n",
     507             :                                     ldb_dn_get_extended_linearized(mem_ctx,
     508             :                                                                    new_dn,
     509             :                                                                    1));
     510           0 :                         return NULL;
     511             :                 }
     512       20316 :                 return new_dn;
     513             :         }
     514             : 
     515           0 :         DBG_WARNING("Refusing to parse empty string DN "
     516             :                     "(and no GUID or SID) "
     517             :                     "drs_ObjectIdentifier into a empty "
     518             :                     "(eg RootDSE) LDB DN\n");
     519           0 :         return NULL;
     520             : }
     521             : 
     522             : /*
     523             :  * Safely convert a drsuapi_DsReplicaObjectIdentifier into a validated
     524             :  * LDB DN of an existing DB entry, and/or find the NC root
     525             :  *
     526             :  * We need to have GUID and SID priority and not allow extended
     527             :  * components in the DN.
     528             :  *
     529             :  * We must also totally honour the priority even if the string DN is
     530             :  * not valid or able to parse as a DN.
     531             :  *
     532             :  * Finally, we must return the DN as found in the DB, as otherwise a
     533             :  * subsequence ldb_dn_compare(dn, nc_root) will fail (as this is based
     534             :  * on the string components).
     535             :  */
     536       35618 : int drs_ObjectIdentifier_to_dn_and_nc_root(TALLOC_CTX *mem_ctx,
     537             :                                            struct ldb_context *ldb,
     538             :                                            struct drsuapi_DsReplicaObjectIdentifier *nc,
     539             :                                            struct ldb_dn **normalised_dn,
     540             :                                            struct ldb_dn **nc_root)
     541             : {
     542           0 :         int ret;
     543       35618 :         struct ldb_dn *new_dn = NULL;
     544             : 
     545       35618 :         new_dn = drs_ObjectIdentifier_to_dn(mem_ctx,
     546             :                                             ldb,
     547             :                                             nc);
     548       35618 :         if (new_dn == NULL) {
     549           0 :                 return LDB_ERR_INVALID_DN_SYNTAX;
     550             :         }
     551             : 
     552       35618 :         ret = dsdb_normalise_dn_and_find_nc_root(ldb,
     553             :                                                  mem_ctx,
     554             :                                                  new_dn,
     555             :                                                  normalised_dn,
     556             :                                                  nc_root);
     557       35618 :         if (ret != LDB_SUCCESS) {
     558             :                 /*
     559             :                  * dsdb_normalise_dn_and_find_nc_root() sets LDB error
     560             :                  * strings, and the functions it calls do also
     561             :                  */
     562          16 :                 DBG_NOTICE("Failed to find DN \"%s\" -> \"%s\" for normalisation: %s (%s)\n",
     563             :                            drs_ObjectIdentifier_to_debug_string(mem_ctx, nc),
     564             :                            ldb_dn_get_extended_linearized(mem_ctx, new_dn, 1),
     565             :                            ldb_errstring(ldb),
     566             :                            ldb_strerror(ret));
     567             :         }
     568             : 
     569       35618 :         TALLOC_FREE(new_dn);
     570       35618 :         return ret;
     571             : }

Generated by: LCOV version 1.14