2009-10-06 09:40:15 +04:00
/*
Unix SMB / CIFS implementation .
DRSUAPI utility functions to be used in torture tests
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"
# include "torture/torture.h"
2010-08-07 13:52:07 +04:00
# include "dsdb/samdb/samdb.h"
2009-10-06 09:40:15 +04:00
# include "torture/rpc/drsuapi.h"
# include "../lib/util/asn1.h"
2011-03-19 02:45:16 +03:00
# include "torture/drs/proto.h"
2009-10-06 09:40:15 +04:00
/**
* Decode Attribute OID based on MS documentation
* See MS - DRSR . pdf - 5.16 .4
*
* On success returns decoded OID and
* corresponding prefix_map index ( if requested )
*/
bool drs_util_oid_from_attid ( struct torture_context * tctx ,
2009-11-11 11:27:30 +03:00
const struct drsuapi_DsReplicaOIDMapping_Ctr * prefix_map ,
2009-10-06 09:40:15 +04:00
uint32_t attid ,
const char * * _oid ,
int * map_idx )
{
int i ;
uint32_t hi_word , lo_word ;
DATA_BLOB bin_oid = { NULL , 0 } ;
2010-12-19 18:37:04 +03:00
char * oid ;
2009-10-06 09:40:15 +04:00
struct drsuapi_DsReplicaOIDMapping * map_entry = NULL ;
TALLOC_CTX * mem_ctx = talloc_named ( tctx , 0 , " util_drsuapi_oid_from_attid " ) ;
/* crack attid value */
hi_word = attid > > 16 ;
lo_word = attid & 0xFFFF ;
/* check last entry in the prefix map is the special one */
map_entry = & prefix_map - > mappings [ prefix_map - > num_mappings - 1 ] ;
torture_assert ( tctx ,
( map_entry - > id_prefix = = 0 )
& & ( * map_entry - > oid . binary_oid = = 0xFF ) ,
" Last entry in Prefix Map is not the special one! " ) ;
2009-10-18 22:28:55 +04:00
/* locate corresponding prefixMap entry */
2009-10-06 09:40:15 +04:00
map_entry = NULL ;
for ( i = 0 ; i < prefix_map - > num_mappings - 1 ; i + + ) {
if ( hi_word = = prefix_map - > mappings [ i ] . id_prefix ) {
map_entry = & prefix_map - > mappings [ i ] ;
if ( map_idx ) * map_idx = i ;
break ;
}
}
torture_assert ( tctx , map_entry , " Unable to locate corresponding Prefix Map entry " ) ;
/* copy partial oid making enough room */
bin_oid . length = map_entry - > oid . length + 2 ;
bin_oid . data = talloc_array ( mem_ctx , uint8_t , bin_oid . length ) ;
torture_assert ( tctx , bin_oid . data , " Not enough memory " ) ;
memcpy ( bin_oid . data , map_entry - > oid . binary_oid , map_entry - > oid . length ) ;
if ( lo_word < 128 ) {
bin_oid . length = bin_oid . length - 1 ;
bin_oid . data [ bin_oid . length - 1 ] = lo_word ;
}
else {
2009-10-18 22:28:28 +04:00
if ( lo_word > = 32768 ) {
2009-10-06 09:40:15 +04:00
lo_word - = 32768 ;
}
2011-10-08 09:22:39 +04:00
bin_oid . data [ bin_oid . length - 2 ] = ( ( lo_word / 128 ) % 128 ) + 128 ; /* (0x80 | ((lo_word>>7) & 0x7f)) */
bin_oid . data [ bin_oid . length - 1 ] = lo_word % 128 ; /* lo_word & 0x7f */
2009-10-06 09:40:15 +04:00
}
torture_assert ( tctx ,
2010-12-19 18:37:04 +03:00
ber_read_OID_String ( tctx , bin_oid , & oid ) ,
2009-10-06 09:40:15 +04:00
" Failed to decode binary OID " ) ;
talloc_free ( mem_ctx ) ;
2010-12-19 18:37:04 +03:00
* _oid = oid ;
2009-10-06 09:40:15 +04:00
return true ;
}
2009-10-06 12:38:42 +04:00
2010-08-07 13:52:07 +04:00
/**
* Loads dsdb_schema from ldb connection using remote prefixMap .
* Schema will be loaded only if :
* - ldb has no attached schema
* - reload_schema is true
*
* This function is to be used in tests that use GetNCChanges ( ) function
*/
bool drs_util_dsdb_schema_load_ldb ( struct torture_context * tctx ,
struct ldb_context * ldb ,
const struct drsuapi_DsReplicaOIDMapping_Ctr * mapping_ctr ,
bool reload_schema )
{
2011-08-25 05:39:03 +04:00
int ret ;
2010-08-07 13:52:07 +04:00
WERROR werr ;
2011-08-25 05:39:03 +04:00
char * err_msg ;
struct ldb_result * res ;
2010-08-07 13:52:07 +04:00
struct ldb_dn * schema_dn ;
struct dsdb_schema * ldap_schema ;
ldap_schema = dsdb_get_schema ( ldb , NULL ) ;
if ( ldap_schema & & ! reload_schema ) {
return true ;
}
schema_dn = ldb_get_schema_basedn ( ldb ) ;
torture_assert ( tctx , schema_dn ! = NULL ,
talloc_asprintf ( tctx , " ldb_get_schema_basedn() failed: %s " , ldb_errstring ( ldb ) ) ) ;
ldap_schema = dsdb_new_schema ( ldb ) ;
torture_assert ( tctx , ldap_schema ! = NULL , " dsdb_new_schema() failed! " ) ;
werr = dsdb_load_prefixmap_from_drsuapi ( ldap_schema , mapping_ctr ) ;
2010-08-10 02:08:19 +04:00
torture_assert_werr_ok ( tctx , werr ,
" Failed to construct prefixMap from drsuapi data " ) ;
2010-08-07 13:52:07 +04:00
/*
2011-08-25 05:39:03 +04:00
* load the attribute and objectClass definitions
2010-08-07 13:52:07 +04:00
*/
2011-08-25 05:39:03 +04:00
ret = ldb_search ( ldb , ldap_schema , & res ,
2010-08-07 13:52:07 +04:00
schema_dn , LDB_SCOPE_ONELEVEL , NULL ,
2011-08-25 05:39:03 +04:00
" (|(objectClass=attributeSchema)(objectClass=classSchema)) " ) ;
2010-08-07 13:52:07 +04:00
if ( ret ! = LDB_SUCCESS ) {
err_msg = talloc_asprintf ( tctx ,
2011-08-25 05:39:03 +04:00
" failed to search attributeSchema or classSchema objects: %s " ,
2010-08-07 13:52:07 +04:00
ldb_errstring ( ldb ) ) ;
torture_fail ( tctx , err_msg ) ;
}
2011-08-25 05:39:03 +04:00
ret = dsdb_load_ldb_results_into_schema ( tctx , ldb , ldap_schema , res , & err_msg ) ;
2010-08-07 13:52:07 +04:00
if ( ret ! = LDB_SUCCESS ) {
err_msg = talloc_asprintf ( tctx ,
2011-08-25 05:39:03 +04:00
" dsdb_load_ldb_results_into_schema failed: %s " ,
err_msg ) ;
2010-08-07 13:52:07 +04:00
torture_fail ( tctx , err_msg ) ;
}
2011-08-25 05:39:03 +04:00
talloc_free ( res ) ;
2010-08-07 13:52:07 +04:00
ret = dsdb_set_schema ( ldb , ldap_schema ) ;
if ( ret ! = LDB_SUCCESS ) {
torture_fail ( tctx ,
talloc_asprintf ( tctx , " dsdb_set_schema() failed: %s " , ldb_strerror ( ret ) ) ) ;
}
return true ;
}