LCOV - code coverage report
Current view: top level - source4/dsdb/common - dsdb_dn.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 160 197 81.2 %
Date: 2021-09-23 10:06:22 Functions: 15 15 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    47983031 : enum dsdb_dn_format dsdb_dn_oid_to_format(const char *oid) 
      30             : {
      31    47983031 :         if (strcmp(oid, LDB_SYNTAX_DN) == 0) {
      32    13591453 :                 return DSDB_NORMAL_DN;
      33    33903770 :         } else if (strcmp(oid, DSDB_SYNTAX_BINARY_DN) == 0) {
      34     7230022 :                 return DSDB_BINARY_DN;
      35    26651507 :         } else if (strcmp(oid, DSDB_SYNTAX_STRING_DN) == 0) {
      36       21535 :                 return DSDB_STRING_DN;
      37    26629624 :         } else if (strcmp(oid, DSDB_SYNTAX_OR_NAME) == 0) {
      38           0 :                 return DSDB_NORMAL_DN;
      39             :         } else {
      40    26629621 :                 return DSDB_INVALID_DN;
      41             :         }
      42             : }
      43             : 
      44    13664727 : 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    13664727 :         struct dsdb_dn *dsdb_dn = talloc(mem_ctx, struct dsdb_dn);
      51    13664727 :         if (!dsdb_dn) {
      52           0 :                 return NULL;
      53             :         }
      54    13664727 :         dsdb_dn->dn = talloc_steal(dsdb_dn, dn);
      55    13664727 :         dsdb_dn->extra_part = extra_part;
      56    13664727 :         dsdb_dn->dn_format = dn_format;
      57             :         /* Look to see if this attributeSyntax is a DN */
      58    13664727 :         if (dsdb_dn->dn_format == DSDB_INVALID_DN) {
      59           0 :                 talloc_free(dsdb_dn);
      60           0 :                 return NULL;
      61             :         }
      62             : 
      63    13664727 :         dsdb_dn->oid = oid;
      64    13664727 :         talloc_steal(dsdb_dn, extra_part.data);
      65    13664727 :         return dsdb_dn;
      66             : }
      67             : 
      68     3649363 : struct dsdb_dn *dsdb_dn_construct(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, DATA_BLOB extra_part, 
      69             :                                   const char *oid) 
      70             : {
      71     3649363 :         enum dsdb_dn_format dn_format = dsdb_dn_oid_to_format(oid);
      72     3649363 :         return dsdb_dn_construct_internal(mem_ctx, dn, extra_part, dn_format, oid);
      73             : }
      74             : 
      75    13526858 : struct dsdb_dn *dsdb_dn_parse_trusted(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 
      76             :                                       const struct ldb_val *dn_blob, const char *dn_oid)
      77             : {
      78             :         struct dsdb_dn *dsdb_dn;
      79             :         struct ldb_dn *dn;
      80             :         size_t len;
      81             :         TALLOC_CTX *tmp_ctx;
      82             :         char *p1;
      83             :         char *p2;
      84             :         uint32_t blen;
      85             :         struct ldb_val bval;
      86             :         struct ldb_val dval;
      87             :         char *dn_str;
      88    13526858 :         int error = 0;
      89             : 
      90    13526858 :         enum dsdb_dn_format dn_format = dsdb_dn_oid_to_format(dn_oid);
      91             : 
      92    13526858 :         if (dn_blob == NULL || dn_blob->data == NULL || dn_blob->length == 0) {
      93           1 :                 return NULL;
      94             :         }
      95             : 
      96    13526857 :         switch (dn_format) {
      97           0 :         case DSDB_INVALID_DN:
      98           0 :                 return NULL;
      99    10015365 :         case DSDB_NORMAL_DN:
     100             :         {
     101    10015365 :                 dn = ldb_dn_from_ldb_val(mem_ctx, ldb, dn_blob);
     102    10015365 :                 if (!dn) {
     103           1 :                         talloc_free(dn);
     104           1 :                         return NULL;
     105             :                 }
     106    10015364 :                 return dsdb_dn_construct_internal(mem_ctx, dn, data_blob_null, dn_format, dn_oid);
     107             :         }
     108     3511480 :         case DSDB_BINARY_DN:
     109     3511480 :                 if (dn_blob->length < 2 || dn_blob->data[0] != 'B' || dn_blob->data[1] != ':') {
     110          11 :                         return NULL;
     111             :                 }
     112     3502278 :                 break;
     113          12 :         case DSDB_STRING_DN:
     114          12 :                 if (dn_blob->length < 2 || dn_blob->data[0] != 'S' || dn_blob->data[1] != ':') {
     115           0 :                         return NULL;
     116             :                 }
     117           0 :                 break;
     118           0 :         default:
     119           0 :                 return NULL;
     120             :         }
     121             : 
     122     3511478 :         if (strlen((const char*)dn_blob->data) != dn_blob->length) {
     123             :                 /* The RDN must not contain a character with value 0x0 */
     124           0 :                 return NULL;
     125             :         }
     126             : 
     127     3511477 :         tmp_ctx = talloc_new(mem_ctx);
     128     3511477 :         if (tmp_ctx == NULL) {
     129           0 :                 return NULL;
     130             :         }
     131             : 
     132     3511477 :         len = dn_blob->length - 2;
     133     3511477 :         p1 = talloc_strndup(tmp_ctx, (const char *)dn_blob->data + 2, len);
     134     3511477 :         if (!p1) {
     135           0 :                 goto failed;
     136             :         }
     137             : 
     138     3511477 :         errno = 0;
     139     3511477 :         blen = smb_strtoul(p1, &p2, 10, &error, SMB_STR_STANDARD);
     140     3511477 :         if (error != 0) {
     141           0 :                 DEBUG(10, (__location__ ": failed\n"));
     142           0 :                 goto failed;
     143             :         }
     144     3511477 :         if (p2 == NULL) {
     145           0 :                 DEBUG(10, (__location__ ": failed\n"));
     146           0 :                 goto failed;
     147             :         }
     148     3511477 :         if (p2[0] != ':') {
     149           0 :                 DEBUG(10, (__location__ ": failed\n"));
     150           0 :                 goto failed;
     151             :         }
     152     3511477 :         len -= PTR_DIFF(p2,p1);//???
     153     3511477 :         p1 = p2+1;
     154     3511477 :         len--;
     155             :                 
     156     3511477 :         if (blen >= len) {
     157          12 :                 DEBUG(10, (__location__ ": blen=%u len=%u\n", (unsigned)blen, (unsigned)len));
     158          11 :                 goto failed;
     159             :         }
     160             :                 
     161     3511465 :         p2 = p1 + blen;
     162     3511465 :         if (p2[0] != ':') {
     163           6 :                 DEBUG(10, (__location__ ": %s", p2));
     164           0 :                 goto failed;
     165             :         }
     166     3511459 :         dn_str = p2+1;
     167             :                 
     168             :                 
     169     3511459 :         switch (dn_format) {
     170     3511450 :         case DSDB_BINARY_DN:
     171     3511450 :                 if ((blen % 2 != 0)) {
     172           0 :                         DEBUG(10, (__location__ ": blen=%u - not an even number\n", (unsigned)blen));
     173           0 :                         goto failed;
     174             :                 }
     175             :                 
     176     3511450 :                 if (blen >= 2) {
     177     3511449 :                         bval.length = (blen/2)+1;
     178     3511449 :                         bval.data = talloc_size(tmp_ctx, bval.length);
     179     3511449 :                         if (bval.data == NULL) {
     180           0 :                                 DEBUG(10, (__location__ ": err\n"));
     181           0 :                                 goto failed;
     182             :                         }
     183     3511449 :                         bval.data[bval.length-1] = 0;
     184             :                 
     185     3511449 :                         bval.length = strhex_to_str((char *)bval.data, bval.length,
     186             :                                                     p1, blen);
     187     3511449 :                         if (bval.length != (blen / 2)) {
     188           2 :                                 DEBUG(10, (__location__ ": non hexadecimal characters found in binary prefix\n"));
     189           0 :                                 goto failed;
     190             :                         }
     191             :                 } else {
     192           1 :                         bval = data_blob_null;
     193             :                 }
     194             : 
     195     3502267 :                 break;
     196           9 :         case DSDB_STRING_DN:
     197           9 :                 bval = data_blob(p1, blen);
     198           9 :                 break;
     199           0 :         default:
     200             :                 /* never reached */
     201           0 :                 return NULL;
     202             :         }
     203             :         
     204             : 
     205     3511457 :         dval.data = (uint8_t *)dn_str;
     206     3511457 :         dval.length = strlen(dn_str);
     207             :                 
     208     3511457 :         dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &dval);
     209     3511457 :         if (!dn) {
     210           0 :                 DEBUG(10, (__location__ ": err\n"));
     211           0 :                 goto failed;
     212             :         }
     213             :                 
     214     3511457 :         dsdb_dn = dsdb_dn_construct(mem_ctx, dn, bval, dn_oid);
     215             :                 
     216     3511457 :         talloc_free(tmp_ctx);
     217     3511457 :         return dsdb_dn;
     218             : 
     219          11 : failed:
     220          20 :         talloc_free(tmp_ctx);
     221          20 :         return NULL;
     222             : }
     223             : 
     224     1187780 : struct dsdb_dn *dsdb_dn_parse(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 
     225             :                               const struct ldb_val *dn_blob, const char *dn_oid)
     226             : {
     227     1187780 :         struct dsdb_dn *dsdb_dn = dsdb_dn_parse_trusted(mem_ctx, ldb,
     228             :                                                         dn_blob, dn_oid);
     229     1187780 :         if (dsdb_dn == NULL) {
     230          23 :                 return NULL;
     231             :         }
     232     1187743 :         if (ldb_dn_validate(dsdb_dn->dn) == false) {
     233          15 :                 DEBUG(10, ("could not parse %.*s as a %s DN",
     234             :                            (int)dn_blob->length, dn_blob->data,
     235             :                            dn_oid));
     236          13 :                 return NULL;
     237             :         }
     238     1077484 :         return dsdb_dn;
     239             : }
     240             : 
     241    12436841 : static char *dsdb_dn_get_with_postfix(TALLOC_CTX *mem_ctx, 
     242             :                                      struct dsdb_dn *dsdb_dn,
     243             :                                      const char *postfix)
     244             : {
     245    12436841 :         if (!postfix) {
     246           0 :                 return NULL;
     247             :         }
     248             : 
     249    12436841 :         switch (dsdb_dn->dn_format) {
     250     8942898 :         case DSDB_NORMAL_DN:
     251             :         {
     252     8942898 :                 return talloc_strdup(mem_ctx, postfix);
     253             :         }
     254     3493929 :         case DSDB_BINARY_DN:
     255             :         {
     256     3493929 :                 char *hexstr = data_blob_hex_string_upper(mem_ctx, &dsdb_dn->extra_part);
     257             :         
     258     3493929 :                 char *p = talloc_asprintf(mem_ctx, "B:%u:%s:%s", (unsigned)(dsdb_dn->extra_part.length*2), hexstr, 
     259             :                                           postfix);
     260     3493929 :                 talloc_free(hexstr);
     261     3493929 :                 return p;
     262             :         }
     263          14 :         case DSDB_STRING_DN:
     264             :         {
     265          14 :                 return talloc_asprintf(mem_ctx, "S:%u:%*.*s:%s", 
     266           0 :                                     (unsigned)(dsdb_dn->extra_part.length), 
     267           0 :                                     (int)(dsdb_dn->extra_part.length), 
     268          14 :                                     (int)(dsdb_dn->extra_part.length), 
     269          14 :                                     (const char *)dsdb_dn->extra_part.data, 
     270             :                                     postfix);
     271             :         }
     272           0 :         default:
     273           0 :                 return NULL;
     274             :         }
     275             : }
     276             : 
     277     3753332 : char *dsdb_dn_get_linearized(TALLOC_CTX *mem_ctx, 
     278             :                               struct dsdb_dn *dsdb_dn)
     279             : {
     280     3753332 :         const char *postfix = ldb_dn_get_linearized(dsdb_dn->dn);
     281     3753332 :         return dsdb_dn_get_with_postfix(mem_ctx, dsdb_dn, postfix);
     282             : }
     283             : 
     284        1082 : char *dsdb_dn_get_casefold(TALLOC_CTX *mem_ctx, 
     285             :                            struct dsdb_dn *dsdb_dn) 
     286             : {
     287        1082 :         const char *postfix = ldb_dn_get_casefold(dsdb_dn->dn);
     288        1082 :         return dsdb_dn_get_with_postfix(mem_ctx, dsdb_dn, postfix);
     289             : }
     290             : 
     291     8682427 : char *dsdb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, 
     292             :                                       struct dsdb_dn *dsdb_dn,
     293             :                                       int mode)
     294             : {
     295     8682427 :         char *postfix = ldb_dn_get_extended_linearized(mem_ctx, dsdb_dn->dn, mode);
     296     8682427 :         char *ret = dsdb_dn_get_with_postfix(mem_ctx, dsdb_dn, postfix);
     297     8682427 :         talloc_free(postfix);
     298     8682427 :         return ret;
     299             : }
     300             : 
     301        1091 : int dsdb_dn_binary_canonicalise(struct ldb_context *ldb, void *mem_ctx,
     302             :                                 const struct ldb_val *in, struct ldb_val *out)
     303             : {
     304        1091 :         struct dsdb_dn *dsdb_dn = dsdb_dn_parse(mem_ctx, ldb, in, DSDB_SYNTAX_BINARY_DN);
     305             :         
     306        1091 :         if (!dsdb_dn) {
     307          22 :                 return -1;
     308             :         }
     309        1068 :         *out = data_blob_string_const(dsdb_dn_get_casefold(mem_ctx, dsdb_dn));
     310        1068 :         talloc_free(dsdb_dn);
     311        1068 :         if (!out->data) {
     312           0 :                 return -1;
     313             :         }
     314        1068 :         return 0;
     315             : }
     316             : 
     317         389 : int dsdb_dn_binary_comparison(struct ldb_context *ldb, void *mem_ctx,
     318             :                                      const struct ldb_val *v1,
     319             :                                      const struct ldb_val *v2)
     320             : {
     321         389 :         return ldb_any_comparison(ldb, mem_ctx, dsdb_dn_binary_canonicalise, v1, v2);
     322             : }
     323             : 
     324           9 : int dsdb_dn_string_canonicalise(struct ldb_context *ldb, void *mem_ctx,
     325             :                                 const struct ldb_val *in, struct ldb_val *out)
     326             : {
     327           9 :         struct dsdb_dn *dsdb_dn = dsdb_dn_parse(mem_ctx, ldb, in, DSDB_SYNTAX_STRING_DN);
     328             :         
     329           9 :         if (!dsdb_dn) {
     330           0 :                 return -1;
     331             :         }
     332           8 :         *out = data_blob_string_const(dsdb_dn_get_casefold(mem_ctx, dsdb_dn));
     333           8 :         talloc_free(dsdb_dn);
     334           8 :         if (!out->data) {
     335           0 :                 return -1;
     336             :         }
     337           8 :         return 0;
     338             : }
     339             : 
     340           4 : int dsdb_dn_string_comparison(struct ldb_context *ldb, void *mem_ctx,
     341             :                                      const struct ldb_val *v1,
     342             :                                      const struct ldb_val *v2)
     343             : {
     344           4 :         return ldb_any_comparison(ldb, mem_ctx, dsdb_dn_string_canonicalise, v1, v2);
     345             : }
     346             : 
     347             : /*
     348             :   format a drsuapi_DsReplicaObjectIdentifier naming context as a string
     349             :  */
     350       25289 : char *drs_ObjectIdentifier_to_string(TALLOC_CTX *mem_ctx,
     351             :                                      struct drsuapi_DsReplicaObjectIdentifier *nc)
     352             : {
     353       25289 :         char *ret = NULL;
     354       25289 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     355       25289 :         if (!GUID_all_zero(&nc->guid)) {
     356       18540 :                 char *guid = GUID_string(tmp_ctx, &nc->guid);
     357       18540 :                 if (guid) {
     358       18540 :                         ret = talloc_asprintf_append(ret, "<GUID=%s>;", guid);
     359             :                 }
     360             :         }
     361       25289 :         if (nc->__ndr_size_sid != 0 && nc->sid.sid_rev_num != 0) {
     362        8738 :                 const char *sid = dom_sid_string(tmp_ctx, &nc->sid);
     363        8738 :                 if (sid) {
     364        8738 :                         ret = talloc_asprintf_append(ret, "<SID=%s>;", sid);
     365             :                 }
     366             :         }
     367       25289 :         if (nc->__ndr_size_dn != 0 && nc->dn) {
     368       25289 :                 ret = talloc_asprintf_append(ret, "%s", nc->dn);
     369             :         }
     370       25289 :         talloc_free(tmp_ctx);
     371       25289 :         talloc_steal(mem_ctx, ret);
     372       25289 :         return ret;
     373             : }
     374             : 
     375       25289 : struct ldb_dn *drs_ObjectIdentifier_to_dn(TALLOC_CTX *mem_ctx,
     376             :                                           struct ldb_context *ldb,
     377             :                                           struct drsuapi_DsReplicaObjectIdentifier *nc)
     378             : {
     379       25289 :         char *dn_string = drs_ObjectIdentifier_to_string(mem_ctx, nc);
     380             :         struct ldb_dn *new_dn;
     381       25289 :         new_dn = ldb_dn_new(mem_ctx, ldb, dn_string);
     382       25289 :         talloc_free(dn_string);
     383       25289 :         return new_dn;
     384             : }

Generated by: LCOV version 1.13