2009-10-08 03:55:28 +04:00
/*
Unix SMB / CIFS implementation .
DRS : : prefixMap implementation
Copyright ( C ) Kamen Mazdrashki < kamen . mazdrashki @ postpath . com > 2009
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2009-10-18 22:34:21 +04:00
# include "dsdb/samdb/samdb.h"
# include "librpc/gen_ndr/ndr_drsuapi.h"
# include "librpc/gen_ndr/ndr_drsblobs.h"
# include "../lib/util/asn1.h"
2009-10-25 21:57:18 +03:00
2009-12-19 02:49:31 +03:00
/**
* Determine range type for supplied ATTID
*/
enum dsdb_attid_type dsdb_pfm_get_attid_type ( uint32_t attid )
{
if ( attid < = 0x7FFFFFFF ) {
2010-11-08 17:27:22 +03:00
return DSDB_ATTID_TYPE_PFM ;
2009-12-19 02:49:31 +03:00
}
else if ( attid < = 0xBFFFFFFF ) {
2010-11-08 17:27:22 +03:00
return DSDB_ATTID_TYPE_INTID ;
2009-12-19 02:49:31 +03:00
}
else if ( attid < = 0xFFFEFFFF ) {
2010-11-08 17:27:22 +03:00
return DSDB_ATTID_TYPE_RESERVED ;
2009-12-19 02:49:31 +03:00
}
else {
2010-11-08 17:27:22 +03:00
return DSDB_ATTID_TYPE_INTERNAL ;
2009-12-19 02:49:31 +03:00
}
}
2009-10-25 21:57:18 +03:00
/**
* Allocates schema_prefixMap object in supplied memory context
*/
static struct dsdb_schema_prefixmap * _dsdb_schema_prefixmap_talloc ( TALLOC_CTX * mem_ctx ,
uint32_t length )
{
struct dsdb_schema_prefixmap * pfm ;
pfm = talloc_zero ( mem_ctx , struct dsdb_schema_prefixmap ) ;
if ( ! pfm ) {
return NULL ;
}
pfm - > length = length ;
pfm - > prefixes = talloc_zero_array ( pfm , struct dsdb_schema_prefixmap_oid ,
pfm - > length ) ;
if ( ! pfm - > prefixes ) {
talloc_free ( pfm ) ;
return NULL ;
}
return pfm ;
}
2009-10-18 22:34:21 +04:00
/**
* Initial prefixMap creation according to :
* [ MS - DRSR ] section 5.12 .2
*/
2009-10-25 21:57:18 +03:00
WERROR dsdb_schema_pfm_new ( TALLOC_CTX * mem_ctx , struct dsdb_schema_prefixmap * * _pfm )
2009-10-18 22:34:21 +04:00
{
uint32_t i ;
struct dsdb_schema_prefixmap * pfm ;
const struct {
uint32_t id ;
const char * oid_prefix ;
} pfm_init_data [ ] = {
{ . id = 0x00000000 , . oid_prefix = " 2.5.4 " } ,
{ . id = 0x00000001 , . oid_prefix = " 2.5.6 " } ,
{ . id = 0x00000002 , . oid_prefix = " 1.2.840.113556.1.2 " } ,
{ . id = 0x00000003 , . oid_prefix = " 1.2.840.113556.1.3 " } ,
{ . id = 0x00000004 , . oid_prefix = " 2.16.840.1.101.2.2.1 " } ,
{ . id = 0x00000005 , . oid_prefix = " 2.16.840.1.101.2.2.3 " } ,
{ . id = 0x00000006 , . oid_prefix = " 2.16.840.1.101.2.1.5 " } ,
{ . id = 0x00000007 , . oid_prefix = " 2.16.840.1.101.2.1.4 " } ,
{ . id = 0x00000008 , . oid_prefix = " 2.5.5 " } ,
{ . id = 0x00000009 , . oid_prefix = " 1.2.840.113556.1.4 " } ,
{ . id = 0x0000000A , . oid_prefix = " 1.2.840.113556.1.5 " } ,
{ . id = 0x00000013 , . oid_prefix = " 0.9.2342.19200300.100 " } ,
{ . id = 0x00000014 , . oid_prefix = " 2.16.840.1.113730.3 " } ,
{ . id = 0x00000015 , . oid_prefix = " 0.9.2342.19200300.100.1 " } ,
{ . id = 0x00000016 , . oid_prefix = " 2.16.840.1.113730.3.1 " } ,
{ . id = 0x00000017 , . oid_prefix = " 1.2.840.113556.1.5.7000 " } ,
{ . id = 0x00000018 , . oid_prefix = " 2.5.21 " } ,
{ . id = 0x00000019 , . oid_prefix = " 2.5.18 " } ,
{ . id = 0x0000001A , . oid_prefix = " 2.5.20 " } ,
} ;
/* allocate mem for prefix map */
2009-10-25 21:57:18 +03:00
pfm = _dsdb_schema_prefixmap_talloc ( mem_ctx , ARRAY_SIZE ( pfm_init_data ) ) ;
2009-10-18 22:34:21 +04:00
W_ERROR_HAVE_NO_MEMORY ( pfm ) ;
/* build prefixes */
for ( i = 0 ; i < pfm - > length ; i + + ) {
if ( ! ber_write_partial_OID_String ( pfm , & pfm - > prefixes [ i ] . bin_oid , pfm_init_data [ i ] . oid_prefix ) ) {
talloc_free ( pfm ) ;
return WERR_INTERNAL_ERROR ;
}
pfm - > prefixes [ i ] . id = pfm_init_data [ i ] . id ;
}
2009-10-25 21:57:18 +03:00
* _pfm = pfm ;
2009-10-18 22:34:21 +04:00
return WERR_OK ;
}
2010-11-29 14:28:00 +03:00
struct dsdb_schema_prefixmap * dsdb_schema_pfm_copy_shallow ( TALLOC_CTX * mem_ctx ,
const struct dsdb_schema_prefixmap * pfm )
{
uint32_t i ;
struct dsdb_schema_prefixmap * pfm_copy ;
pfm_copy = _dsdb_schema_prefixmap_talloc ( mem_ctx , pfm - > length ) ;
if ( ! pfm_copy ) {
return NULL ;
}
for ( i = 0 ; i < pfm_copy - > length ; i + + ) {
pfm_copy - > prefixes [ i ] = pfm - > prefixes [ i ] ;
}
return pfm_copy ;
}
2009-10-18 22:34:21 +04:00
/**
* Adds oid to prefix map .
* On success returns ID for newly added index
* or ID of existing entry that matches oid
* Reference : [ MS - DRSR ] section 5.12 .2
*
* \ param pfm prefixMap
* \ param bin_oid OID prefix to be added to prefixMap
* \ param pfm_id Location where to store prefixMap entry ID
*/
2016-08-08 12:00:02 +03:00
WERROR dsdb_schema_pfm_add_entry ( struct dsdb_schema_prefixmap * pfm ,
DATA_BLOB bin_oid ,
const uint32_t * remote_id ,
uint32_t * _idx )
2009-10-18 22:34:21 +04:00
{
uint32_t i ;
struct dsdb_schema_prefixmap_oid * pfm_entry ;
struct dsdb_schema_prefixmap_oid * prefixes_new ;
/* dup memory for bin-oid prefix to be added */
2011-07-07 16:50:47 +04:00
bin_oid = data_blob_dup_talloc ( pfm , bin_oid ) ;
2009-10-29 19:18:54 +03:00
W_ERROR_HAVE_NO_MEMORY ( bin_oid . data ) ;
2009-10-18 22:34:21 +04:00
/* make room for new entry */
prefixes_new = talloc_realloc ( pfm , pfm - > prefixes , struct dsdb_schema_prefixmap_oid , pfm - > length + 1 ) ;
if ( ! prefixes_new ) {
talloc_free ( bin_oid . data ) ;
return WERR_NOMEM ;
}
pfm - > prefixes = prefixes_new ;
/* make new unique ID in prefixMap */
pfm_entry = & pfm - > prefixes [ pfm - > length ] ;
pfm_entry - > id = 0 ;
for ( i = 0 ; i < pfm - > length ; i + + ) {
2016-08-08 12:00:02 +03:00
if ( pfm_entry - > id < pfm - > prefixes [ i ] . id ) {
2009-10-18 22:34:21 +04:00
pfm_entry - > id = pfm - > prefixes [ i ] . id ;
2016-08-08 12:00:02 +03:00
}
if ( remote_id = = NULL ) {
continue ;
}
if ( pfm - > prefixes [ i ] . id = = * remote_id ) {
/*
* We can ' t use the remote id .
* it ' s already in use .
*/
remote_id = NULL ;
}
2009-10-18 22:34:21 +04:00
}
/* add new bin-oid prefix */
2016-08-08 12:00:02 +03:00
if ( remote_id ! = NULL ) {
pfm_entry - > id = * remote_id ;
} else {
pfm_entry - > id + + ;
}
2009-10-18 22:34:21 +04:00
pfm_entry - > bin_oid = bin_oid ;
2016-08-08 12:00:02 +03:00
if ( _idx ! = NULL ) {
* _idx = pfm - > length ;
}
2009-10-18 22:34:21 +04:00
pfm - > length + + ;
return WERR_OK ;
}
/**
2009-10-24 01:48:14 +04:00
* Make partial binary OID for supplied OID .
2009-10-18 22:34:21 +04:00
* Reference : [ MS - DRSR ] section 5.12 .2
*/
2009-10-24 01:48:14 +04:00
static WERROR _dsdb_pfm_make_binary_oid ( const char * full_oid , TALLOC_CTX * mem_ctx ,
DATA_BLOB * _bin_oid , uint32_t * _last_subid )
2009-10-18 22:34:21 +04:00
{
2009-10-24 01:48:14 +04:00
uint32_t last_subid ;
const char * oid_subid ;
2009-10-18 22:34:21 +04:00
/* make last sub-identifier value */
2009-10-24 01:48:14 +04:00
oid_subid = strrchr ( full_oid , ' . ' ) ;
if ( ! oid_subid ) {
2009-10-18 22:34:21 +04:00
return WERR_INVALID_PARAMETER ;
}
2009-10-24 01:48:14 +04:00
oid_subid + + ;
last_subid = strtoul ( oid_subid , NULL , 10 ) ;
2009-10-18 22:34:21 +04:00
/* encode oid in BER format */
2009-10-24 01:48:14 +04:00
if ( ! ber_write_OID_String ( mem_ctx , _bin_oid , full_oid ) ) {
2010-09-20 22:31:20 +04:00
DEBUG ( 0 , ( " ber_write_OID_String() failed for %s \n " , full_oid ) ) ;
2009-10-18 22:34:21 +04:00
return WERR_INTERNAL_ERROR ;
}
/* get the prefix of the OID */
2009-10-24 01:48:14 +04:00
if ( last_subid < 128 ) {
_bin_oid - > length - = 1 ;
2009-10-18 22:34:21 +04:00
} else {
2009-10-24 01:48:14 +04:00
_bin_oid - > length - = 2 ;
2009-10-18 22:34:21 +04:00
}
2009-10-24 01:48:14 +04:00
/* return last_value if requested */
if ( _last_subid ) {
* _last_subid = last_subid ;
}
return WERR_OK ;
}
2009-10-24 01:48:55 +04:00
/**
* Lookup partial - binary - oid in prefixMap
*/
2009-10-25 21:34:17 +03:00
WERROR dsdb_schema_pfm_find_binary_oid ( const struct dsdb_schema_prefixmap * pfm ,
2009-10-24 01:48:55 +04:00
DATA_BLOB bin_oid ,
uint32_t * _idx )
{
uint32_t i ;
for ( i = 0 ; i < pfm - > length ; i + + ) {
if ( pfm - > prefixes [ i ] . bin_oid . length ! = bin_oid . length ) {
continue ;
}
if ( memcmp ( pfm - > prefixes [ i ] . bin_oid . data , bin_oid . data , bin_oid . length ) = = 0 ) {
if ( _idx ) {
* _idx = i ;
}
return WERR_OK ;
}
}
2010-10-22 17:22:08 +04:00
return WERR_NOT_FOUND ;
2009-10-24 01:48:55 +04:00
}
2009-10-29 04:16:30 +03:00
/**
* Lookup full - oid in prefixMap
* Note : this may be slow .
*/
WERROR dsdb_schema_pfm_find_oid ( const struct dsdb_schema_prefixmap * pfm ,
const char * full_oid ,
uint32_t * _idx )
{
WERROR werr ;
DATA_BLOB bin_oid ;
ZERO_STRUCT ( bin_oid ) ;
/* make partial-binary-oid to look for */
werr = _dsdb_pfm_make_binary_oid ( full_oid , NULL , & bin_oid , NULL ) ;
W_ERROR_NOT_OK_RETURN ( werr ) ;
/* lookup the partial-oid */
werr = dsdb_schema_pfm_find_binary_oid ( pfm , bin_oid , _idx ) ;
data_blob_free ( & bin_oid ) ;
return werr ;
}
2009-10-24 01:48:14 +04:00
/**
* Make ATTID for given OID
2010-10-26 19:33:32 +04:00
* If OID is not in prefixMap , new prefix
* may be added depending on ' can_change_pfm ' flag
2009-10-24 01:48:14 +04:00
* Reference : [ MS - DRSR ] section 5.12 .2
*/
2010-10-26 19:33:32 +04:00
static WERROR dsdb_schema_pfm_make_attid_impl ( struct dsdb_schema_prefixmap * pfm ,
const char * oid ,
bool can_change_pfm ,
uint32_t * attid )
2009-10-24 01:48:14 +04:00
{
WERROR werr ;
2009-10-24 01:48:55 +04:00
uint32_t idx ;
2009-10-24 01:48:14 +04:00
uint32_t lo_word , hi_word ;
2009-10-24 01:48:55 +04:00
uint32_t last_subid ;
2009-10-24 01:48:14 +04:00
DATA_BLOB bin_oid ;
if ( ! pfm ) {
return WERR_INVALID_PARAMETER ;
}
if ( ! oid ) {
return WERR_INVALID_PARAMETER ;
}
2009-10-24 01:48:55 +04:00
werr = _dsdb_pfm_make_binary_oid ( oid , pfm , & bin_oid , & last_subid ) ;
2009-10-24 01:48:14 +04:00
W_ERROR_NOT_OK_RETURN ( werr ) ;
2009-10-18 22:34:21 +04:00
/* search the prefix in the prefix table, if none found, add
* one entry for new prefix .
*/
2009-10-24 01:48:55 +04:00
werr = dsdb_schema_pfm_find_binary_oid ( pfm , bin_oid , & idx ) ;
if ( W_ERROR_IS_OK ( werr ) ) {
2009-10-24 01:02:24 +04:00
/* free memory allocated for bin_oid */
data_blob_free ( & bin_oid ) ;
2009-10-24 01:48:55 +04:00
} else {
2010-10-26 19:33:32 +04:00
/* return error in read-only mode */
if ( ! can_change_pfm ) {
2013-04-02 08:36:47 +04:00
DEBUG ( 0 , ( " Unable to convert %s to an attid, and can_change_pfm=false! \n " , oid ) ) ;
2010-10-26 19:33:32 +04:00
return werr ;
}
2009-10-24 01:48:55 +04:00
/* entry does not exists, add it */
2016-08-08 12:00:02 +03:00
werr = dsdb_schema_pfm_add_entry ( pfm , bin_oid , NULL , & idx ) ;
2009-10-24 01:48:55 +04:00
W_ERROR_NOT_OK_RETURN ( werr ) ;
2009-10-18 22:34:21 +04:00
}
/* compose the attid */
2009-10-24 01:48:55 +04:00
lo_word = last_subid % 16384 ; /* actually get lower 14 bits: lo_word & 0x3FFF */
if ( last_subid > = 16384 ) {
2009-10-18 22:34:21 +04:00
/* mark it so that it is known to not be the whole lastValue
* This will raise 16 - th bit */
lo_word + = 32768 ;
}
2009-10-24 01:48:55 +04:00
hi_word = pfm - > prefixes [ idx ] . id ;
2009-10-18 22:34:21 +04:00
/* make ATTID:
* HIWORD is prefixMap id
* LOWORD is truncated binary - oid */
* attid = ( hi_word * 65536 ) + lo_word ;
return WERR_OK ;
}
2010-10-26 19:33:32 +04:00
/**
* Make ATTID for given OID
* Reference : [ MS - DRSR ] section 5.12 .2
*
* Note : This function may change prefixMap if prefix
* for supplied ' oid ' doesn ' t exists yet .
* It is recommended to be used mostly when caller
* want to add new prefixes .
* Otherwise dsdb_schema_pfm_attid_from_oid ( ) should be used .
*/
WERROR dsdb_schema_pfm_make_attid ( struct dsdb_schema_prefixmap * pfm ,
const char * oid ,
uint32_t * attid )
{
return dsdb_schema_pfm_make_attid_impl ( pfm , oid , true , attid ) ;
}
/**
* Make ATTID for given OID
* Reference : [ MS - DRSR ] section 5.12 .2
*/
WERROR dsdb_schema_pfm_attid_from_oid ( struct dsdb_schema_prefixmap * pfm ,
const char * oid ,
uint32_t * attid )
{
return dsdb_schema_pfm_make_attid_impl ( pfm , oid , false , attid ) ;
}
2009-10-18 22:34:21 +04:00
/**
* Make OID for given ATTID .
* Reference : [ MS - DRSR ] section 5.12 .2
*/
2010-11-09 05:36:24 +03:00
WERROR dsdb_schema_pfm_oid_from_attid ( const struct dsdb_schema_prefixmap * pfm ,
uint32_t attid ,
2009-10-18 22:34:21 +04:00
TALLOC_CTX * mem_ctx , const char * * _oid )
{
2009-11-06 22:14:41 +03:00
uint32_t i ;
2009-10-18 22:34:21 +04:00
uint32_t hi_word , lo_word ;
DATA_BLOB bin_oid = { NULL , 0 } ;
2010-12-19 18:37:04 +03:00
char * oid ;
2009-10-18 22:34:21 +04:00
struct dsdb_schema_prefixmap_oid * pfm_entry ;
WERROR werr = WERR_OK ;
2009-12-19 02:49:31 +03:00
/* sanity check for attid requested */
2010-11-08 17:27:22 +03:00
if ( dsdb_pfm_get_attid_type ( attid ) ! = DSDB_ATTID_TYPE_PFM ) {
2009-12-19 02:49:31 +03:00
return WERR_INVALID_PARAMETER ;
}
2009-10-18 22:34:21 +04:00
/* crack attid value */
hi_word = attid > > 16 ;
lo_word = attid & 0xFFFF ;
/* locate corRespoNding prefixMap entry */
pfm_entry = NULL ;
for ( i = 0 ; i < pfm - > length ; i + + ) {
if ( hi_word = = pfm - > prefixes [ i ] . id ) {
pfm_entry = & pfm - > prefixes [ i ] ;
break ;
}
}
if ( ! pfm_entry ) {
2010-09-20 22:31:20 +04:00
DEBUG ( 1 , ( " Failed to find prefixMap entry for ATTID = 0x%08X (%d) \n " ,
attid , attid ) ) ;
2010-09-20 21:52:48 +04:00
return WERR_DS_NO_ATTRIBUTE_OR_VALUE ;
2009-10-18 22:34:21 +04:00
}
/* copy oid prefix making enough room */
bin_oid . length = pfm_entry - > bin_oid . length + 2 ;
bin_oid . data = talloc_array ( mem_ctx , uint8_t , bin_oid . length ) ;
W_ERROR_HAVE_NO_MEMORY ( bin_oid . data ) ;
memcpy ( bin_oid . data , pfm_entry - > bin_oid . data , pfm_entry - > bin_oid . length ) ;
if ( lo_word < 128 ) {
bin_oid . length = bin_oid . length - 1 ;
bin_oid . data [ bin_oid . length - 1 ] = lo_word ;
}
else {
if ( lo_word > = 32768 ) {
lo_word - = 32768 ;
}
bin_oid . data [ bin_oid . length - 2 ] = ( 0x80 | ( ( lo_word > > 7 ) & 0x7f ) ) ;
bin_oid . data [ bin_oid . length - 1 ] = lo_word & 0x7f ;
}
2010-12-19 18:37:04 +03:00
if ( ! ber_read_OID_String ( mem_ctx , bin_oid , & oid ) ) {
2010-09-20 22:31:20 +04:00
DEBUG ( 0 , ( " ber_read_OID_String() failed for %s \n " ,
hex_encode_talloc ( bin_oid . data , bin_oid . data , bin_oid . length ) ) ) ;
2009-10-18 22:34:21 +04:00
werr = WERR_INTERNAL_ERROR ;
}
/* free locally allocated memory */
talloc_free ( bin_oid . data ) ;
2010-12-19 18:37:04 +03:00
* _oid = oid ;
2009-10-18 22:34:21 +04:00
return werr ;
}
2009-10-25 21:34:17 +03:00
/**
* Verifies drsuapi mappings .
*/
2009-11-03 09:49:36 +03:00
static WERROR _dsdb_drsuapi_pfm_verify ( const struct drsuapi_DsReplicaOIDMapping_Ctr * ctr ,
bool have_schema_info )
2009-10-25 21:34:17 +03:00
{
uint32_t i ;
2009-11-03 09:49:36 +03:00
uint32_t num_mappings ;
2009-10-25 21:34:17 +03:00
struct drsuapi_DsReplicaOIDMapping * mapping ;
/* check input params */
if ( ! ctr ) {
return WERR_INVALID_PARAMETER ;
}
if ( ! ctr - > mappings ) {
return WERR_INVALID_PARAMETER ;
}
2009-11-03 09:49:36 +03:00
num_mappings = ctr - > num_mappings ;
2009-10-25 21:34:17 +03:00
2009-11-03 09:49:36 +03:00
if ( have_schema_info ) {
2010-04-08 06:30:16 +04:00
DATA_BLOB blob ;
2009-11-03 09:49:36 +03:00
if ( ctr - > num_mappings < 2 ) {
return WERR_INVALID_PARAMETER ;
}
/* check last entry for being special */
mapping = & ctr - > mappings [ ctr - > num_mappings - 1 ] ;
if ( mapping - > id_prefix ! = 0 ) {
return WERR_INVALID_PARAMETER ;
}
2010-04-08 06:30:16 +04:00
2010-09-17 03:45:59 +04:00
/* verify schemaInfo blob is valid one */
2010-04-08 06:30:16 +04:00
blob = data_blob_const ( mapping - > oid . binary_oid , mapping - > oid . length ) ;
2010-09-17 03:45:59 +04:00
if ( ! dsdb_schema_info_blob_is_valid ( & blob ) ) {
2009-11-03 09:49:36 +03:00
return WERR_INVALID_PARAMETER ;
}
/* get number of read mappings in the map */
num_mappings - - ;
2009-10-25 21:34:17 +03:00
}
/* now, verify rest of entries for being at least not null */
2009-11-03 09:49:36 +03:00
for ( i = 0 ; i < num_mappings ; i + + ) {
2009-10-25 21:34:17 +03:00
mapping = & ctr - > mappings [ i ] ;
if ( ! mapping - > oid . length ) {
return WERR_INVALID_PARAMETER ;
}
if ( ! mapping - > oid . binary_oid ) {
return WERR_INVALID_PARAMETER ;
}
/* check it is not the special entry */
if ( * mapping - > oid . binary_oid = = 0xFF ) {
return WERR_INVALID_PARAMETER ;
}
}
return WERR_OK ;
}
/**
* Convert drsuapi_ prefix map to prefixMap internal presentation .
*
* \ param ctr Pointer to drsuapi_DsReplicaOIDMapping_Ctr which represents drsuapi_ prefixMap
2009-11-03 09:49:36 +03:00
* \ param have_schema_info if drsuapi_prefixMap have schem_info in it or not
2009-10-25 21:34:17 +03:00
* \ param mem_ctx TALLOC_CTX to make allocations in
* \ param _pfm Out pointer to hold newly created prefixMap
* \ param _schema_info Out param to store schema_info to . If NULL , schema_info is not decoded
*/
WERROR dsdb_schema_pfm_from_drsuapi_pfm ( const struct drsuapi_DsReplicaOIDMapping_Ctr * ctr ,
2009-11-03 09:49:36 +03:00
bool have_schema_info ,
2009-10-25 21:34:17 +03:00
TALLOC_CTX * mem_ctx ,
struct dsdb_schema_prefixmap * * _pfm ,
2016-08-04 11:03:14 +03:00
struct dsdb_schema_info * * _schema_info )
2009-10-25 21:34:17 +03:00
{
WERROR werr ;
uint32_t i ;
DATA_BLOB blob ;
2009-11-03 09:49:36 +03:00
uint32_t num_mappings ;
2009-10-25 21:34:17 +03:00
struct dsdb_schema_prefixmap * pfm ;
if ( ! _pfm ) {
return WERR_INVALID_PARAMETER ;
}
2009-11-03 09:49:36 +03:00
/*
* error out if schema_info is requested
* but it is not in the drsuapi_prefixMap
*/
if ( _schema_info & & ! have_schema_info ) {
return WERR_INVALID_PARAMETER ;
}
2009-10-25 21:34:17 +03:00
/* verify drsuapi_pefixMap */
2009-11-03 09:49:36 +03:00
werr = _dsdb_drsuapi_pfm_verify ( ctr , have_schema_info ) ;
2009-10-25 21:34:17 +03:00
W_ERROR_NOT_OK_RETURN ( werr ) ;
/* allocate mem for prefix map */
2009-11-03 09:49:36 +03:00
num_mappings = ctr - > num_mappings ;
if ( have_schema_info ) {
num_mappings - - ;
}
pfm = _dsdb_schema_prefixmap_talloc ( mem_ctx , num_mappings ) ;
2009-10-25 21:34:17 +03:00
W_ERROR_HAVE_NO_MEMORY ( pfm ) ;
/* copy entries from drsuapi_prefixMap */
for ( i = 0 ; i < pfm - > length ; i + + ) {
blob = data_blob_talloc ( pfm ,
ctr - > mappings [ i ] . oid . binary_oid ,
ctr - > mappings [ i ] . oid . length ) ;
if ( ! blob . data ) {
talloc_free ( pfm ) ;
return WERR_NOMEM ;
}
pfm - > prefixes [ i ] . id = ctr - > mappings [ i ] . id_prefix ;
pfm - > prefixes [ i ] . bin_oid = blob ;
}
/* fetch schema_info if requested */
if ( _schema_info ) {
/* by this time, i should have this value,
* but set it here for clarity */
i = ctr - > num_mappings - 1 ;
2016-08-04 11:03:14 +03:00
blob = data_blob_const ( ctr - > mappings [ i ] . oid . binary_oid ,
ctr - > mappings [ i ] . oid . length ) ;
werr = dsdb_schema_info_from_blob ( & blob , mem_ctx , _schema_info ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2009-10-25 21:34:17 +03:00
talloc_free ( pfm ) ;
2016-08-04 11:03:14 +03:00
return werr ;
2009-10-25 21:34:17 +03:00
}
}
/* schema_prefixMap created successfully */
* _pfm = pfm ;
return WERR_OK ;
}
/**
* Convert drsuapi_ prefix map to prefixMap internal presentation .
*
* \ param pfm Schema prefixMap to be converted
* \ param schema_info schema_info string - if NULL , we don ' t need it
* \ param mem_ctx TALLOC_CTX to make allocations in
* \ param _ctr Out pointer to drsuapi_DsReplicaOIDMapping_Ctr prefix map structure
*/
WERROR dsdb_drsuapi_pfm_from_schema_pfm ( const struct dsdb_schema_prefixmap * pfm ,
2016-08-04 11:03:14 +03:00
const struct dsdb_schema_info * schema_info ,
2009-10-25 21:34:17 +03:00
TALLOC_CTX * mem_ctx ,
struct drsuapi_DsReplicaOIDMapping_Ctr * * _ctr )
{
uint32_t i ;
DATA_BLOB blob ;
struct drsuapi_DsReplicaOIDMapping_Ctr * ctr ;
if ( ! _ctr ) {
return WERR_INVALID_PARAMETER ;
}
if ( ! pfm ) {
return WERR_INVALID_PARAMETER ;
}
if ( pfm - > length = = 0 ) {
return WERR_INVALID_PARAMETER ;
}
/* allocate memory for the structure */
ctr = talloc_zero ( mem_ctx , struct drsuapi_DsReplicaOIDMapping_Ctr ) ;
W_ERROR_HAVE_NO_MEMORY ( ctr ) ;
ctr - > num_mappings = ( schema_info ? pfm - > length + 1 : pfm - > length ) ;
ctr - > mappings = talloc_array ( ctr , struct drsuapi_DsReplicaOIDMapping , ctr - > num_mappings ) ;
if ( ! ctr - > mappings ) {
talloc_free ( ctr ) ;
return WERR_NOMEM ;
}
/* copy entries from schema_prefixMap */
for ( i = 0 ; i < pfm - > length ; i + + ) {
2011-07-07 16:50:47 +04:00
blob = data_blob_dup_talloc ( ctr , pfm - > prefixes [ i ] . bin_oid ) ;
2009-10-25 21:34:17 +03:00
if ( ! blob . data ) {
talloc_free ( ctr ) ;
return WERR_NOMEM ;
}
ctr - > mappings [ i ] . id_prefix = pfm - > prefixes [ i ] . id ;
ctr - > mappings [ i ] . oid . length = blob . length ;
ctr - > mappings [ i ] . oid . binary_oid = blob . data ;
}
/* make schema_info entry if needed */
if ( schema_info ) {
2016-08-04 11:03:14 +03:00
WERROR werr ;
2009-10-25 21:34:17 +03:00
/* by this time, i should have this value,
* but set it here for clarity */
i = ctr - > num_mappings - 1 ;
2016-08-04 11:03:14 +03:00
werr = dsdb_blob_from_schema_info ( schema_info , ctr , & blob ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2009-10-25 21:34:17 +03:00
talloc_free ( ctr ) ;
2016-08-04 11:03:14 +03:00
return werr ;
2009-10-25 21:34:17 +03:00
}
ctr - > mappings [ i ] . id_prefix = 0 ;
ctr - > mappings [ i ] . oid . length = blob . length ;
ctr - > mappings [ i ] . oid . binary_oid = blob . data ;
}
/* drsuapi_prefixMap constructed successfully */
* _ctr = ctr ;
return WERR_OK ;
}
/**
* Verifies schema prefixMap and drsuapi prefixMap are same .
* Note that we just need to verify pfm contains prefixes
* from ctr , not that those prefixes has same id_prefix .
*/
WERROR dsdb_schema_pfm_contains_drsuapi_pfm ( const struct dsdb_schema_prefixmap * pfm ,
const struct drsuapi_DsReplicaOIDMapping_Ctr * ctr )
{
WERROR werr ;
uint32_t i ;
uint32_t idx ;
DATA_BLOB bin_oid ;
/* verify drsuapi_pefixMap */
2009-11-03 09:49:36 +03:00
werr = _dsdb_drsuapi_pfm_verify ( ctr , true ) ;
2009-10-25 21:34:17 +03:00
W_ERROR_NOT_OK_RETURN ( werr ) ;
/* check pfm contains every entry from ctr, except the last one */
for ( i = 0 ; i < ctr - > num_mappings - 1 ; i + + ) {
bin_oid . length = ctr - > mappings [ i ] . oid . length ;
bin_oid . data = ctr - > mappings [ i ] . oid . binary_oid ;
werr = dsdb_schema_pfm_find_binary_oid ( pfm , bin_oid , & idx ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
return WERR_DS_DRA_SCHEMA_MISMATCH ;
}
}
return WERR_OK ;
}