LCOV - code coverage report
Current view: top level - source4/dsdb/schema - schema_prefixmap.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 248 289 85.8 %
Date: 2024-04-21 15:09:00 Functions: 16 16 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    DRS::prefixMap implementation
       5             : 
       6             :    Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 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 "librpc/gen_ndr/ndr_drsuapi.h"
      25             : #include "librpc/gen_ndr/ndr_drsblobs.h"
      26             : #include "../lib/util/asn1.h"
      27             : #include "lib/util/smb_strtox.h"
      28             : 
      29             : 
      30             : /**
      31             :  * Determine range type for supplied ATTID
      32             :  */
      33    66057143 : enum dsdb_attid_type dsdb_pfm_get_attid_type(uint32_t attid)
      34             : {
      35    66057143 :         if (attid <= 0x7FFFFFFF) {
      36    64494914 :                 return DSDB_ATTID_TYPE_PFM;
      37             :         }
      38        1899 :         else if (attid <= 0xBFFFFFFF) {
      39        1893 :                 return DSDB_ATTID_TYPE_INTID;
      40             :         }
      41           4 :         else if (attid <= 0xFFFEFFFF) {
      42           0 :                 return DSDB_ATTID_TYPE_RESERVED;
      43             :         }
      44             :         else {
      45           2 :                 return DSDB_ATTID_TYPE_INTERNAL;
      46             :         }
      47             : }
      48             : 
      49             : /**
      50             :  * Allocates schema_prefixMap object in supplied memory context
      51             :  */
      52       34630 : static struct dsdb_schema_prefixmap *_dsdb_schema_prefixmap_talloc(TALLOC_CTX *mem_ctx,
      53             :                                                                    uint32_t length)
      54             : {
      55         378 :         struct dsdb_schema_prefixmap *pfm;
      56             : 
      57       34630 :         pfm = talloc_zero(mem_ctx, struct dsdb_schema_prefixmap);
      58       34630 :         if (!pfm) {
      59           0 :                 return NULL;
      60             :         }
      61             : 
      62       34630 :         pfm->length = length;
      63       34630 :         pfm->prefixes = talloc_zero_array(pfm, struct dsdb_schema_prefixmap_oid,
      64             :                                           pfm->length);
      65       34630 :         if (!pfm->prefixes) {
      66           0 :                 talloc_free(pfm);
      67           0 :                 return NULL;
      68             :         }
      69             : 
      70       34252 :         return pfm;
      71             : }
      72             : 
      73             : /**
      74             :  * Initial prefixMap creation according to:
      75             :  * [MS-DRSR] section 5.12.2
      76             :  */
      77           3 : WERROR dsdb_schema_pfm_new(TALLOC_CTX *mem_ctx, struct dsdb_schema_prefixmap **_pfm)
      78             : {
      79           3 :         uint32_t i;
      80           3 :         struct dsdb_schema_prefixmap *pfm;
      81           3 :         const struct {
      82             :                 uint32_t        id;
      83             :                 const char      *oid_prefix;
      84           3 :         } pfm_init_data[] = {
      85             :                 {.id=0x00000000, .oid_prefix="2.5.4"},
      86             :                 {.id=0x00000001, .oid_prefix="2.5.6"},
      87             :                 {.id=0x00000002, .oid_prefix="1.2.840.113556.1.2"},
      88             :                 {.id=0x00000003, .oid_prefix="1.2.840.113556.1.3"},
      89             :                 {.id=0x00000004, .oid_prefix="2.16.840.1.101.2.2.1"},
      90             :                 {.id=0x00000005, .oid_prefix="2.16.840.1.101.2.2.3"},
      91             :                 {.id=0x00000006, .oid_prefix="2.16.840.1.101.2.1.5"},
      92             :                 {.id=0x00000007, .oid_prefix="2.16.840.1.101.2.1.4"},
      93             :                 {.id=0x00000008, .oid_prefix="2.5.5"},
      94             :                 {.id=0x00000009, .oid_prefix="1.2.840.113556.1.4"},
      95             :                 {.id=0x0000000A, .oid_prefix="1.2.840.113556.1.5"},
      96             :                 {.id=0x00000013, .oid_prefix="0.9.2342.19200300.100"},
      97             :                 {.id=0x00000014, .oid_prefix="2.16.840.1.113730.3"},
      98             :                 {.id=0x00000015, .oid_prefix="0.9.2342.19200300.100.1"},
      99             :                 {.id=0x00000016, .oid_prefix="2.16.840.1.113730.3.1"},
     100             :                 {.id=0x00000017, .oid_prefix="1.2.840.113556.1.5.7000"},
     101             :                 {.id=0x00000018, .oid_prefix="2.5.21"},
     102             :                 {.id=0x00000019, .oid_prefix="2.5.18"},
     103             :                 {.id=0x0000001A, .oid_prefix="2.5.20"},
     104             :         };
     105             : 
     106             :         /* allocate mem for prefix map */
     107           3 :         pfm = _dsdb_schema_prefixmap_talloc(mem_ctx, ARRAY_SIZE(pfm_init_data));
     108           3 :         W_ERROR_HAVE_NO_MEMORY(pfm);
     109             : 
     110             :         /* build prefixes */
     111          60 :         for (i = 0; i < pfm->length; i++) {
     112          57 :                 if (!ber_write_partial_OID_String(pfm, &pfm->prefixes[i].bin_oid, pfm_init_data[i].oid_prefix)) {
     113           0 :                         talloc_free(pfm);
     114           0 :                         return WERR_INTERNAL_ERROR;
     115             :                 }
     116          57 :                 pfm->prefixes[i].id = pfm_init_data[i].id;
     117             :         }
     118             : 
     119           3 :         *_pfm = pfm;
     120             : 
     121           3 :         return WERR_OK;
     122             : }
     123             : 
     124             : 
     125          68 : struct dsdb_schema_prefixmap *dsdb_schema_pfm_copy_shallow(TALLOC_CTX *mem_ctx,
     126             :                                                            const struct dsdb_schema_prefixmap *pfm)
     127             : {
     128          10 :         uint32_t i;
     129          10 :         struct dsdb_schema_prefixmap *pfm_copy;
     130             : 
     131          68 :         pfm_copy = _dsdb_schema_prefixmap_talloc(mem_ctx, pfm->length);
     132          68 :         if (!pfm_copy) {
     133           0 :                 return NULL;
     134             :         }
     135        3747 :         for (i = 0; i < pfm_copy->length; i++) {
     136        3679 :                 pfm_copy->prefixes[i] = pfm->prefixes[i];
     137             :         }
     138             : 
     139          58 :         return pfm_copy;
     140             : }
     141             : 
     142             : /**
     143             :  * Adds oid to prefix map.
     144             :  * On success returns ID for newly added index
     145             :  * or ID of existing entry that matches oid
     146             :  * Reference: [MS-DRSR] section 5.12.2
     147             :  *
     148             :  * \param pfm prefixMap
     149             :  * \param bin_oid OID prefix to be added to prefixMap
     150             :  * \param pfm_id Location where to store prefixMap entry ID
     151             :  */
     152         837 : WERROR dsdb_schema_pfm_add_entry(struct dsdb_schema_prefixmap *pfm,
     153             :                                  DATA_BLOB bin_oid,
     154             :                                  const uint32_t *remote_id,
     155             :                                  uint32_t *_idx)
     156             : {
     157           9 :         uint32_t i;
     158           9 :         struct dsdb_schema_prefixmap_oid * pfm_entry;
     159           9 :         struct dsdb_schema_prefixmap_oid * prefixes_new;
     160             : 
     161             :         /* dup memory for bin-oid prefix to be added */
     162         837 :         bin_oid = data_blob_dup_talloc(pfm, bin_oid);
     163         837 :         W_ERROR_HAVE_NO_MEMORY(bin_oid.data);
     164             : 
     165             :         /* make room for new entry */
     166         837 :         prefixes_new = talloc_realloc(pfm, pfm->prefixes, struct dsdb_schema_prefixmap_oid, pfm->length + 1);
     167         837 :         if (!prefixes_new) {
     168           0 :                 talloc_free(bin_oid.data);
     169           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     170             :         }
     171         837 :         pfm->prefixes = prefixes_new;
     172             : 
     173             :         /* make new unique ID in prefixMap */
     174         837 :         pfm_entry = &pfm->prefixes[pfm->length];
     175         837 :         pfm_entry->id = 0;
     176       62659 :         for (i = 0; i < pfm->length; i++) {
     177       61822 :                 if (pfm_entry->id < pfm->prefixes[i].id) {
     178       54361 :                         pfm_entry->id = pfm->prefixes[i].id;
     179             :                 }
     180             : 
     181       61822 :                 if (remote_id == NULL) {
     182       53645 :                         continue;
     183             :                 }
     184             : 
     185        8177 :                 if (pfm->prefixes[i].id == *remote_id) {
     186             :                         /*
     187             :                          * We can't use the remote id.
     188             :                          * it's already in use.
     189             :                          */
     190           0 :                         remote_id = NULL;
     191             :                 }
     192             :         }
     193             : 
     194             :         /* add new bin-oid prefix */
     195         837 :         if (remote_id != NULL) {
     196         142 :                 pfm_entry->id = *remote_id;
     197             :         } else {
     198         695 :                 pfm_entry->id++;
     199             :         }
     200         837 :         pfm_entry->bin_oid = bin_oid;
     201             : 
     202         837 :         if (_idx != NULL) {
     203         695 :                 *_idx = pfm->length;
     204             :         }
     205         837 :         pfm->length++;
     206             : 
     207         837 :         return WERR_OK;
     208             : }
     209             : 
     210             : 
     211             : /**
     212             :  * Make partial binary OID for supplied OID.
     213             :  * Reference: [MS-DRSR] section 5.12.2
     214             :  */
     215    99192865 : static WERROR _dsdb_pfm_make_binary_oid(const char *full_oid, TALLOC_CTX *mem_ctx,
     216             :                                         DATA_BLOB *_bin_oid, uint32_t *_last_subid)
     217             : {
     218     1200895 :         uint32_t last_subid;
     219     1200895 :         const char *oid_subid;
     220    99192865 :         int error = 0;
     221             : 
     222             :         /* make last sub-identifier value */
     223    99192865 :         oid_subid = strrchr(full_oid, '.');
     224    99192865 :         if (!oid_subid) {
     225           0 :                 return WERR_INVALID_PARAMETER;
     226             :         }
     227    99192865 :         oid_subid++;
     228    99192865 :         last_subid = smb_strtoul(oid_subid, NULL, 10, &error, SMB_STR_STANDARD);
     229    99192865 :         if (error != 0) {
     230           0 :                 return WERR_INVALID_PARAMETER;
     231             :         }
     232             : 
     233             :         /* encode oid in BER format */
     234    99192865 :         if (!ber_write_OID_String(mem_ctx, _bin_oid, full_oid)) {
     235           0 :                 DEBUG(0,("ber_write_OID_String() failed for %s\n", full_oid));
     236           0 :                 return WERR_INTERNAL_ERROR;
     237             :         }
     238             : 
     239             :         /* get the prefix of the OID */
     240    99192865 :         if (last_subid < 128) {
     241    57913783 :                 _bin_oid->length -= 1;
     242             :         } else {
     243    41279082 :                 _bin_oid->length -= 2;
     244             :         }
     245             : 
     246             :         /* return last_value if requested */
     247    99192865 :         if (_last_subid) {
     248    98974187 :                 *_last_subid = last_subid;
     249             :         }
     250             : 
     251    99192865 :         return WERR_OK;
     252             : }
     253             : 
     254             : /**
     255             :  * Lookup partial-binary-oid in prefixMap
     256             :  */
     257    99208639 : WERROR dsdb_schema_pfm_find_binary_oid(const struct dsdb_schema_prefixmap *pfm,
     258             :                                        DATA_BLOB bin_oid,
     259             :                                        uint32_t *_idx)
     260             : {
     261     1200945 :         uint32_t i;
     262             : 
     263  1027483270 :         for (i = 0; i < pfm->length; i++) {
     264  1027481197 :                 if (pfm->prefixes[i].bin_oid.length != bin_oid.length) {
     265   560711012 :                         continue;
     266             :                 }
     267             : 
     268   466770185 :                 if (memcmp(pfm->prefixes[i].bin_oid.data, bin_oid.data, bin_oid.length) == 0) {
     269    99206566 :                         if (_idx) {
     270    98989263 :                                 *_idx = i;
     271             :                         }
     272    99206566 :                         return WERR_OK;
     273             :                 }
     274             :         }
     275             : 
     276        2073 :         return WERR_NOT_FOUND;
     277             : }
     278             : 
     279             : /**
     280             :  * Lookup full-oid in prefixMap
     281             :  * Note: this may be slow.
     282             :  */
     283      218678 : WERROR dsdb_schema_pfm_find_oid(const struct dsdb_schema_prefixmap *pfm,
     284             :                                 const char *full_oid,
     285             :                                 uint32_t *_idx)
     286             : {
     287       38906 :         WERROR werr;
     288       38906 :         DATA_BLOB bin_oid;
     289             : 
     290      218678 :         ZERO_STRUCT(bin_oid);
     291             : 
     292             :         /* make partial-binary-oid to look for */
     293      218678 :         werr = _dsdb_pfm_make_binary_oid(full_oid, NULL, &bin_oid, NULL);
     294      218678 :         W_ERROR_NOT_OK_RETURN(werr);
     295             : 
     296             :         /* lookup the partial-oid */
     297      218678 :         werr = dsdb_schema_pfm_find_binary_oid(pfm, bin_oid, _idx);
     298             : 
     299      218678 :         data_blob_free(&bin_oid);
     300             : 
     301      218678 :         return werr;
     302             : }
     303             : 
     304             : /**
     305             :  * Make ATTID for given OID
     306             :  * If OID is not in prefixMap, new prefix
     307             :  * may be added depending on 'can_change_pfm' flag
     308             :  * Reference: [MS-DRSR] section 5.12.2
     309             :  */
     310    98974187 : static WERROR dsdb_schema_pfm_make_attid_impl(struct dsdb_schema_prefixmap *pfm,
     311             :                                               const char *oid,
     312             :                                               bool can_change_pfm,
     313             :                                               uint32_t *attid)
     314             : {
     315     1161989 :         WERROR werr;
     316     1161989 :         uint32_t idx;
     317     1161989 :         uint32_t lo_word, hi_word;
     318     1161989 :         uint32_t last_subid;
     319     1161989 :         DATA_BLOB bin_oid;
     320             : 
     321    98974187 :         if (!pfm) {
     322           0 :                 return WERR_INVALID_PARAMETER;
     323             :         }
     324    98974187 :         if (!oid) {
     325           0 :                 return WERR_INVALID_PARAMETER;
     326             :         }
     327             : 
     328    98974187 :         werr = _dsdb_pfm_make_binary_oid(oid, pfm, &bin_oid, &last_subid);
     329    98974187 :         W_ERROR_NOT_OK_RETURN(werr);
     330             : 
     331             :         /* search the prefix in the prefix table, if none found, add
     332             :          * one entry for new prefix.
     333             :          */
     334    98974187 :         werr = dsdb_schema_pfm_find_binary_oid(pfm, bin_oid, &idx);
     335    98974187 :         if (W_ERROR_IS_OK(werr)) {
     336             :                 /* free memory allocated for bin_oid */
     337    98973489 :                 data_blob_free(&bin_oid);
     338             :         } else {
     339             :                 /* return error in read-only mode */
     340         698 :                 if (!can_change_pfm) {
     341           3 :                         DEBUG(0, ("Unable to convert %s to an attid, and can_change_pfm=false!\n", oid));
     342           3 :                         return werr;
     343             :                 }
     344             : 
     345             :                 /* entry does not exists, add it */
     346         695 :                 werr = dsdb_schema_pfm_add_entry(pfm, bin_oid, NULL, &idx);
     347         695 :                 W_ERROR_NOT_OK_RETURN(werr);
     348             :         }
     349             : 
     350             :         /* compose the attid */
     351    98974184 :         lo_word = last_subid % 16384;   /* actually get lower 14 bits: lo_word & 0x3FFF */
     352    98974184 :         if (last_subid >= 16384) {
     353             :                 /* mark it so that it is known to not be the whole lastValue
     354             :                  * This will raise 16-th bit*/
     355      446706 :                 lo_word += 32768;
     356             :         }
     357    98974184 :         hi_word = pfm->prefixes[idx].id;
     358             : 
     359             :         /* make ATTID:
     360             :          * HIWORD is prefixMap id
     361             :          * LOWORD is truncated binary-oid */
     362    98974184 :         *attid = (hi_word * 65536) + lo_word;
     363             : 
     364    98974184 :         return WERR_OK;
     365             : }
     366             : 
     367             : /**
     368             :  * Make ATTID for given OID
     369             :  * Reference: [MS-DRSR] section 5.12.2
     370             :  *
     371             :  * Note: This function may change prefixMap if prefix
     372             :  * for supplied 'oid' doesn't exists yet.
     373             :  * It is recommended to be used mostly when caller
     374             :  * want to add new prefixes.
     375             :  * Otherwise dsdb_schema_pfm_attid_from_oid() should be used.
     376             :  */
     377         722 : WERROR dsdb_schema_pfm_make_attid(struct dsdb_schema_prefixmap *pfm,
     378             :                                   const char *oid,
     379             :                                   uint32_t *attid)
     380             : {
     381         722 :         return dsdb_schema_pfm_make_attid_impl(pfm, oid, true, attid);
     382             : }
     383             : 
     384             : /**
     385             :  * Make ATTID for given OID
     386             :  * Reference: [MS-DRSR] section 5.12.2
     387             :  */
     388    98973465 : WERROR dsdb_schema_pfm_attid_from_oid(struct dsdb_schema_prefixmap *pfm,
     389             :                                       const char *oid,
     390             :                                       uint32_t *attid)
     391             : {
     392    98973465 :         return dsdb_schema_pfm_make_attid_impl(pfm, oid, false, attid);
     393             : }
     394             : 
     395             : /**
     396             :  * Make OID for given ATTID.
     397             :  * Reference: [MS-DRSR] section 5.12.2
     398             :  */
     399    13123724 : WERROR dsdb_schema_pfm_oid_from_attid(const struct dsdb_schema_prefixmap *pfm,
     400             :                                       uint32_t attid,
     401             :                                       TALLOC_CTX *mem_ctx, const char **_oid)
     402             : {
     403       99421 :         uint32_t i;
     404       99421 :         uint32_t hi_word, lo_word;
     405    13123724 :         DATA_BLOB bin_oid = {NULL, 0};
     406       99421 :         char *oid;
     407       99421 :         struct dsdb_schema_prefixmap_oid *pfm_entry;
     408    13123724 :         WERROR werr = WERR_OK;
     409             : 
     410             :         /* sanity check for attid requested */
     411    13123724 :         if (dsdb_pfm_get_attid_type(attid) != DSDB_ATTID_TYPE_PFM) {
     412           6 :                 return WERR_INVALID_PARAMETER;
     413             :         }
     414             : 
     415             :         /* crack attid value */
     416    13123718 :         hi_word = attid >> 16;
     417    13123718 :         lo_word = attid & 0xFFFF;
     418             : 
     419             :         /* locate corRespoNding prefixMap entry */
     420    13123718 :         pfm_entry = NULL;
     421    84389743 :         for (i = 0; i < pfm->length; i++) {
     422    84389742 :                 if (hi_word == pfm->prefixes[i].id) {
     423    13024303 :                         pfm_entry = &pfm->prefixes[i];
     424    13024303 :                         break;
     425             :                 }
     426             :         }
     427             : 
     428    13123718 :         if (!pfm_entry) {
     429           1 :                 DEBUG(1,("Failed to find prefixMap entry for ATTID = 0x%08X (%d)\n",
     430             :                          attid, attid));
     431           1 :                 return WERR_DS_NO_ATTRIBUTE_OR_VALUE;
     432             :         }
     433             : 
     434             :         /* copy oid prefix making enough room */
     435    13123717 :         bin_oid.length = pfm_entry->bin_oid.length + 2;
     436    13123717 :         bin_oid.data = talloc_array(mem_ctx, uint8_t, bin_oid.length);
     437    13123717 :         W_ERROR_HAVE_NO_MEMORY(bin_oid.data);
     438    13123717 :         memcpy(bin_oid.data, pfm_entry->bin_oid.data, pfm_entry->bin_oid.length);
     439             : 
     440    13123717 :         if (lo_word < 128) {
     441     6438845 :                 bin_oid.length = bin_oid.length - 1;
     442     6438845 :                 bin_oid.data[bin_oid.length-1] = lo_word;
     443             :         }
     444             :         else {
     445     6684872 :                 if (lo_word >= 32768) {
     446        1287 :                         lo_word -= 32768;
     447             :                 }
     448     6684872 :                 bin_oid.data[bin_oid.length-2] = (0x80 | ((lo_word>>7) & 0x7f));
     449     6684872 :                 bin_oid.data[bin_oid.length-1] = lo_word & 0x7f;
     450             :         }
     451             : 
     452    13123717 :         if (!ber_read_OID_String(mem_ctx, bin_oid, &oid)) {
     453           0 :                 DEBUG(0,("ber_read_OID_String() failed for %s\n",
     454             :                          hex_encode_talloc(bin_oid.data, bin_oid.data, bin_oid.length)));
     455           0 :                 werr = WERR_INTERNAL_ERROR;
     456             :         }
     457             : 
     458             :         /* free locally allocated memory */
     459    13123717 :         talloc_free(bin_oid.data);
     460             : 
     461    13123717 :         *_oid = oid;
     462             : 
     463    13123717 :         return werr;
     464             : }
     465             : 
     466             : 
     467             : /**
     468             :  * Verifies drsuapi mappings.
     469             :  */
     470       42390 : static WERROR _dsdb_drsuapi_pfm_verify(const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr,
     471             :                                        bool have_schema_info)
     472             : {
     473         366 :         uint32_t i;
     474         366 :         uint32_t num_mappings;
     475         366 :         struct drsuapi_DsReplicaOIDMapping *mapping;
     476             : 
     477             :         /* check input params */
     478       42390 :         if (!ctr) {
     479           0 :                 return WERR_INVALID_PARAMETER;
     480             :         }
     481       42390 :         if (!ctr->mappings) {
     482        7514 :                 return WERR_INVALID_PARAMETER;
     483             :         }
     484       34876 :         num_mappings = ctr->num_mappings;
     485             : 
     486       34876 :         if (have_schema_info) {
     487           2 :                 DATA_BLOB blob;
     488             : 
     489        6060 :                 if (ctr->num_mappings < 2) {
     490           0 :                         return WERR_INVALID_PARAMETER;
     491             :                 }
     492             : 
     493             :                 /* check last entry for being special */
     494        6060 :                 mapping = &ctr->mappings[ctr->num_mappings - 1];
     495        6060 :                 if (mapping->id_prefix != 0) {
     496           0 :                         return WERR_INVALID_PARAMETER;
     497             :                 }
     498             : 
     499             :                 /* verify schemaInfo blob is valid one */
     500        6060 :                 blob = data_blob_const(mapping->oid.binary_oid, mapping->oid.length);
     501        6060 :                 if (!dsdb_schema_info_blob_is_valid(&blob)) {
     502           0 :                         return WERR_INVALID_PARAMETER;
     503             :                 }
     504             : 
     505             :                 /* get number of read mappings in the map */
     506        6060 :                 num_mappings--;
     507             :         }
     508             : 
     509             :         /* now, verify rest of entries for being at least not null */
     510     2103012 :         for (i = 0; i < num_mappings; i++) {
     511     2068136 :                 mapping = &ctr->mappings[i];
     512     2068136 :                 if (!mapping->oid.length) {
     513           0 :                         return WERR_INVALID_PARAMETER;
     514             :                 }
     515     2068136 :                 if (!mapping->oid.binary_oid) {
     516           0 :                         return WERR_INVALID_PARAMETER;
     517             :                 }
     518             :                 /* check it is not the special entry */
     519     2068136 :                 if (*mapping->oid.binary_oid == 0xFF) {
     520           0 :                         return WERR_INVALID_PARAMETER;
     521             :                 }
     522             :         }
     523             : 
     524       34876 :         return WERR_OK;
     525             : }
     526             : 
     527             : /**
     528             :  * Convert drsuapi_ prefix map to prefixMap internal presentation.
     529             :  *
     530             :  * \param ctr Pointer to drsuapi_DsReplicaOIDMapping_Ctr which represents drsuapi_ prefixMap
     531             :  * \param have_schema_info if drsuapi_prefixMap have schem_info in it or not
     532             :  * \param mem_ctx TALLOC_CTX to make allocations in
     533             :  * \param _pfm Out pointer to hold newly created prefixMap
     534             :  * \param _schema_info Out param to store schema_info to. If NULL, schema_info is not decoded
     535             :  */
     536       42073 : WERROR dsdb_schema_pfm_from_drsuapi_pfm(const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr,
     537             :                                         bool have_schema_info,
     538             :                                         TALLOC_CTX *mem_ctx,
     539             :                                         struct dsdb_schema_prefixmap **_pfm,
     540             :                                         struct dsdb_schema_info **_schema_info)
     541             : {
     542         365 :         WERROR werr;
     543         365 :         uint32_t i;
     544         365 :         DATA_BLOB blob;
     545         365 :         uint32_t num_mappings;
     546         365 :         struct dsdb_schema_prefixmap *pfm;
     547             : 
     548       42073 :         if (!_pfm) {
     549           0 :                 return WERR_INVALID_PARAMETER;
     550             :         }
     551             : 
     552             :         /*
     553             :          * error out if schema_info is requested
     554             :          * but it is not in the drsuapi_prefixMap
     555             :          */
     556       42073 :         if (_schema_info && !have_schema_info) {
     557           0 :                 return WERR_INVALID_PARAMETER;
     558             :         }
     559             : 
     560             :         /* verify drsuapi_pefixMap */
     561       42073 :         werr =_dsdb_drsuapi_pfm_verify(ctr, have_schema_info);
     562       42073 :         W_ERROR_NOT_OK_RETURN(werr);
     563             : 
     564             :         /* allocate mem for prefix map */
     565       34559 :         num_mappings = ctr->num_mappings;
     566       34559 :         if (have_schema_info) {
     567        5743 :                 num_mappings--;
     568             :         }
     569       34559 :         pfm = _dsdb_schema_prefixmap_talloc(mem_ctx, num_mappings);
     570       34559 :         W_ERROR_HAVE_NO_MEMORY(pfm);
     571             : 
     572             :         /* copy entries from drsuapi_prefixMap */
     573     2086921 :         for (i = 0; i < pfm->length; i++) {
     574     2052362 :                 blob = data_blob_talloc(pfm,
     575             :                                         ctr->mappings[i].oid.binary_oid,
     576             :                                         ctr->mappings[i].oid.length);
     577     2052362 :                 if (!blob.data) {
     578           0 :                         talloc_free(pfm);
     579           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     580             :                 }
     581     2052362 :                 pfm->prefixes[i].id = ctr->mappings[i].id_prefix;
     582     2052362 :                 pfm->prefixes[i].bin_oid = blob;
     583             :         }
     584             : 
     585             :         /* fetch schema_info if requested */
     586       34559 :         if (_schema_info) {
     587             :                 /* by this time, i should have this value,
     588             :                  *  but set it here for clarity */
     589          83 :                 i = ctr->num_mappings - 1;
     590             : 
     591          83 :                 blob = data_blob_const(ctr->mappings[i].oid.binary_oid,
     592          83 :                                        ctr->mappings[i].oid.length);
     593          83 :                 werr = dsdb_schema_info_from_blob(&blob, mem_ctx, _schema_info);
     594          83 :                 if (!W_ERROR_IS_OK(werr)) {
     595           0 :                         talloc_free(pfm);
     596           0 :                         return werr;
     597             :                 }
     598             :         }
     599             : 
     600             :         /* schema_prefixMap created successfully */
     601       34559 :         *_pfm = pfm;
     602             : 
     603       34559 :         return WERR_OK;
     604             : }
     605             : 
     606             : /**
     607             :  * Convert drsuapi_ prefix map to prefixMap internal presentation.
     608             :  *
     609             :  * \param pfm Schema prefixMap to be converted
     610             :  * \param schema_info schema_info string - if NULL, we don't need it
     611             :  * \param mem_ctx TALLOC_CTX to make allocations in
     612             :  * \param _ctr Out pointer to drsuapi_DsReplicaOIDMapping_Ctr prefix map structure
     613             :  */
     614       11187 : WERROR dsdb_drsuapi_pfm_from_schema_pfm(const struct dsdb_schema_prefixmap *pfm,
     615             :                                         const struct dsdb_schema_info *schema_info,
     616             :                                         TALLOC_CTX *mem_ctx,
     617             :                                         struct drsuapi_DsReplicaOIDMapping_Ctr **_ctr)
     618             : {
     619          29 :         uint32_t i;
     620          29 :         DATA_BLOB blob;
     621          29 :         struct drsuapi_DsReplicaOIDMapping_Ctr *ctr;
     622             : 
     623       11187 :         if (!_ctr) {
     624           0 :                 return WERR_INVALID_PARAMETER;
     625             :         }
     626       11187 :         if (!pfm) {
     627           0 :                 return WERR_INVALID_PARAMETER;
     628             :         }
     629       11187 :         if (pfm->length == 0) {
     630           0 :                 return WERR_INVALID_PARAMETER;
     631             :         }
     632             : 
     633             :         /* allocate memory for the structure */
     634       11187 :         ctr = talloc_zero(mem_ctx, struct drsuapi_DsReplicaOIDMapping_Ctr);
     635       11187 :         W_ERROR_HAVE_NO_MEMORY(ctr);
     636             : 
     637       11187 :         ctr->num_mappings = (schema_info ? pfm->length + 1 : pfm->length);
     638       11187 :         ctr->mappings = talloc_array(ctr, struct drsuapi_DsReplicaOIDMapping, ctr->num_mappings);
     639       11187 :         if (!ctr->mappings) {
     640           0 :                 talloc_free(ctr);
     641           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     642             :         }
     643             : 
     644             :         /* copy entries from schema_prefixMap */
     645      916551 :         for (i = 0; i < pfm->length; i++) {
     646      905364 :                 blob = data_blob_dup_talloc(ctr, pfm->prefixes[i].bin_oid);
     647      905364 :                 if (!blob.data) {
     648           0 :                         talloc_free(ctr);
     649           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     650             :                 }
     651      905364 :                 ctr->mappings[i].id_prefix = pfm->prefixes[i].id;
     652      905364 :                 ctr->mappings[i].oid.length = blob.length;
     653      905364 :                 ctr->mappings[i].oid.binary_oid = blob.data;
     654             :         }
     655             : 
     656             :         /* make schema_info entry if needed */
     657       11187 :         if (schema_info) {
     658           1 :                 WERROR werr;
     659             : 
     660             :                 /* by this time, i should have this value,
     661             :                  *  but set it here for clarity */
     662       10310 :                 i = ctr->num_mappings - 1;
     663             : 
     664       10310 :                 werr = dsdb_blob_from_schema_info(schema_info, ctr, &blob);
     665       10310 :                 if (!W_ERROR_IS_OK(werr)) {
     666           0 :                         talloc_free(ctr);
     667           0 :                         return werr;
     668             :                 }
     669             : 
     670       10310 :                 ctr->mappings[i].id_prefix = 0;
     671       10310 :                 ctr->mappings[i].oid.length = blob.length;
     672       10310 :                 ctr->mappings[i].oid.binary_oid = blob.data;
     673             :         }
     674             : 
     675             :         /* drsuapi_prefixMap constructed successfully */
     676       11187 :         *_ctr = ctr;
     677             : 
     678       11187 :         return WERR_OK;
     679             : }
     680             : 
     681             : /**
     682             :  * Verifies schema prefixMap and drsuapi prefixMap are same.
     683             :  * Note that we just need to verify pfm contains prefixes
     684             :  * from ctr, not that those prefixes has same id_prefix.
     685             :  */
     686         317 : WERROR dsdb_schema_pfm_contains_drsuapi_pfm(const struct dsdb_schema_prefixmap *pfm,
     687             :                                             const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)
     688             : {
     689           1 :         WERROR werr;
     690           1 :         uint32_t i;
     691           1 :         uint32_t idx;
     692           1 :         DATA_BLOB bin_oid;
     693             : 
     694             :         /* verify drsuapi_pefixMap */
     695         317 :         werr = _dsdb_drsuapi_pfm_verify(ctr, true);
     696         317 :         W_ERROR_NOT_OK_RETURN(werr);
     697             : 
     698             :         /* check pfm contains every entry from ctr, except the last one */
     699       16091 :         for (i = 0; i < ctr->num_mappings - 1; i++) {
     700       15774 :                 bin_oid.length = ctr->mappings[i].oid.length;
     701       15774 :                 bin_oid.data   = ctr->mappings[i].oid.binary_oid;
     702             : 
     703       15774 :                 werr = dsdb_schema_pfm_find_binary_oid(pfm, bin_oid, &idx);
     704       15774 :                 if (!W_ERROR_IS_OK(werr)) {
     705           0 :                         return WERR_DS_DRA_SCHEMA_MISMATCH;
     706             :                 }
     707             :         }
     708             : 
     709         317 :         return WERR_OK;
     710             : }

Generated by: LCOV version 1.14