2006-05-30 17:57:35 +00:00
/*
Unix SMB / CIFS mplementation .
LDAP schema tests
Copyright ( C ) Stefan Metzmacher 2006
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
2007-07-10 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2006-05-30 17:57:35 +00:00
( 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
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-05-30 17:57:35 +00:00
*/
# include "includes.h"
# include "libcli/ldap/ldap_client.h"
# include "lib/cmdline/popt_common.h"
2007-11-16 20:12:00 +01:00
# include "ldb_wrap.h"
2006-05-30 17:57:35 +00:00
# include "dsdb/samdb/samdb.h"
2008-10-11 21:31:42 +02:00
# include "../lib/util/dlinklist.h"
2006-05-30 17:57:35 +00:00
# include "torture/torture.h"
2014-02-27 09:08:17 +01:00
# include "torture/ldap/proto.h"
2006-05-30 17:57:35 +00:00
2007-10-01 18:52:55 +00:00
2006-05-30 17:57:35 +00:00
struct test_rootDSE {
const char * defaultdn ;
const char * rootdn ;
const char * configdn ;
const char * schemadn ;
} ;
2006-07-22 16:56:33 +00:00
struct test_schema_ctx {
2008-09-11 18:38:40 -04:00
struct ldb_context * ldb ;
2006-05-30 17:57:35 +00:00
struct ldb_paged_control * ctrl ;
uint32_t count ;
2007-10-06 22:28:14 +00:00
bool pending ;
2006-05-30 17:57:35 +00:00
int ( * callback ) ( void * , struct ldb_context * ldb , struct ldb_message * ) ;
void * private_data ;
} ;
2007-10-06 22:28:14 +00:00
static bool test_search_rootDSE ( struct ldb_context * ldb , struct test_rootDSE * root )
2006-05-30 17:57:35 +00:00
{
int ret ;
struct ldb_message * msg ;
struct ldb_result * r ;
d_printf ( " Testing RootDSE Search \n " ) ;
2008-09-23 14:30:06 -04:00
ret = ldb_search ( ldb , ldb , & r , ldb_dn_new ( ldb , ldb , NULL ) ,
LDB_SCOPE_BASE , NULL , NULL ) ;
2006-05-30 17:57:35 +00:00
if ( ret ! = LDB_SUCCESS ) {
2007-10-06 22:28:14 +00:00
return false ;
2006-05-30 17:57:35 +00:00
} else if ( r - > count ! = 1 ) {
2006-10-15 23:14:19 +00:00
talloc_free ( r ) ;
2007-10-06 22:28:14 +00:00
return false ;
2006-05-30 17:57:35 +00:00
}
msg = r - > msgs [ 0 ] ;
2006-08-13 08:00:36 +00:00
root - > defaultdn = ldb_msg_find_attr_as_string ( msg , " defaultNamingContext " , NULL ) ;
2006-05-30 17:57:35 +00:00
talloc_steal ( ldb , root - > defaultdn ) ;
2006-08-13 08:00:36 +00:00
root - > rootdn = ldb_msg_find_attr_as_string ( msg , " rootDomainNamingContext " , NULL ) ;
2006-05-30 17:57:35 +00:00
talloc_steal ( ldb , root - > rootdn ) ;
2006-08-13 08:00:36 +00:00
root - > configdn = ldb_msg_find_attr_as_string ( msg , " configurationNamingContext " , NULL ) ;
2006-05-30 17:57:35 +00:00
talloc_steal ( ldb , root - > configdn ) ;
2006-08-13 08:00:36 +00:00
root - > schemadn = ldb_msg_find_attr_as_string ( msg , " schemaNamingContext " , NULL ) ;
2006-05-30 17:57:35 +00:00
talloc_steal ( ldb , root - > schemadn ) ;
talloc_free ( r ) ;
2007-10-06 22:28:14 +00:00
return true ;
2006-05-30 17:57:35 +00:00
}
2008-09-11 18:38:40 -04:00
static int test_schema_search_callback ( struct ldb_request * req , struct ldb_reply * ares )
2006-05-30 17:57:35 +00:00
{
2008-09-11 18:38:40 -04:00
struct test_schema_ctx * actx ;
2006-05-30 17:57:35 +00:00
int ret = LDB_SUCCESS ;
2008-09-11 18:38:40 -04:00
actx = talloc_get_type ( req - > context , struct test_schema_ctx ) ;
if ( ! ares ) {
return ldb_request_done ( req , LDB_ERR_OPERATIONS_ERROR ) ;
}
if ( ares - > error ! = LDB_SUCCESS ) {
return ldb_request_done ( req , ares - > error ) ;
}
2006-05-30 17:57:35 +00:00
switch ( ares - > type ) {
case LDB_REPLY_ENTRY :
actx - > count + + ;
2008-09-11 18:38:40 -04:00
ret = actx - > callback ( actx - > private_data , actx - > ldb , ares - > message ) ;
2006-05-30 17:57:35 +00:00
break ;
case LDB_REPLY_REFERRAL :
break ;
case LDB_REPLY_DONE :
if ( ares - > controls ) {
struct ldb_paged_control * ctrl = NULL ;
int i ;
for ( i = 0 ; ares - > controls [ i ] ; i + + ) {
if ( strcmp ( LDB_CONTROL_PAGED_RESULTS_OID , ares - > controls [ i ] - > oid ) = = 0 ) {
ctrl = talloc_get_type ( ares - > controls [ i ] - > data , struct ldb_paged_control ) ;
break ;
}
}
if ( ! ctrl ) break ;
talloc_free ( actx - > ctrl - > cookie ) ;
actx - > ctrl - > cookie = talloc_steal ( actx - > ctrl - > cookie , ctrl - > cookie ) ;
actx - > ctrl - > cookie_len = ctrl - > cookie_len ;
if ( actx - > ctrl - > cookie_len > 0 ) {
2007-10-06 22:28:14 +00:00
actx - > pending = true ;
2006-05-30 17:57:35 +00:00
}
}
2008-09-11 18:38:40 -04:00
talloc_free ( ares ) ;
return ldb_request_done ( req , LDB_SUCCESS ) ;
2006-05-30 17:57:35 +00:00
default :
d_printf ( " %s: unknown Reply Type %u \n " , __location__ , ares - > type ) ;
2008-09-11 18:38:40 -04:00
return ldb_request_done ( req , LDB_ERR_OTHER ) ;
2006-05-30 17:57:35 +00:00
}
if ( talloc_free ( ares ) = = - 1 ) {
d_printf ( " talloc_free failed \n " ) ;
actx - > pending = 0 ;
2008-09-11 18:38:40 -04:00
return ldb_request_done ( req , LDB_ERR_OPERATIONS_ERROR ) ;
2006-05-30 17:57:35 +00:00
}
if ( ret ) {
2008-09-11 18:38:40 -04:00
return ldb_request_done ( req , LDB_ERR_OPERATIONS_ERROR ) ;
2006-05-30 17:57:35 +00:00
}
return LDB_SUCCESS ;
}
2007-10-06 22:28:14 +00:00
static bool test_create_schema_type ( struct ldb_context * ldb , struct test_rootDSE * root ,
2006-05-30 17:57:35 +00:00
const char * filter ,
int ( * callback ) ( void * , struct ldb_context * ldb , struct ldb_message * ) ,
void * private_data )
{
struct ldb_control * * ctrl ;
struct ldb_paged_control * control ;
struct ldb_request * req ;
int ret ;
2006-07-22 16:56:33 +00:00
struct test_schema_ctx * actx ;
2006-05-30 17:57:35 +00:00
2008-09-11 18:38:40 -04:00
actx = talloc ( ldb , struct test_schema_ctx ) ;
actx - > ldb = ldb ;
actx - > private_data = private_data ;
actx - > callback = callback ;
2006-05-30 17:57:35 +00:00
2008-09-11 18:38:40 -04:00
ctrl = talloc_array ( actx , struct ldb_control * , 2 ) ;
2006-05-30 17:57:35 +00:00
ctrl [ 0 ] = talloc ( ctrl , struct ldb_control ) ;
ctrl [ 0 ] - > oid = LDB_CONTROL_PAGED_RESULTS_OID ;
2007-10-06 22:28:14 +00:00
ctrl [ 0 ] - > critical = true ;
2006-05-30 17:57:35 +00:00
control = talloc ( ctrl [ 0 ] , struct ldb_paged_control ) ;
control - > size = 1000 ;
control - > cookie = NULL ;
control - > cookie_len = 0 ;
ctrl [ 0 ] - > data = control ;
ctrl [ 1 ] = NULL ;
2008-09-11 18:38:40 -04:00
ret = ldb_build_search_req ( & req , ldb , actx ,
ldb_dn_new ( actx , ldb , root - > schemadn ) ,
LDB_SCOPE_SUBTREE ,
filter , NULL ,
ctrl ,
actx , test_schema_search_callback ,
NULL ) ;
actx - > ctrl = control ;
actx - > count = 0 ;
2006-05-30 17:57:35 +00:00
again :
2007-10-06 22:28:14 +00:00
actx - > pending = false ;
2006-05-30 17:57:35 +00:00
ret = ldb_request ( ldb , req ) ;
if ( ret ! = LDB_SUCCESS ) {
d_printf ( " search failed - %s \n " , ldb_errstring ( ldb ) ) ;
2008-09-11 18:38:40 -04:00
talloc_free ( actx ) ;
2007-10-06 22:28:14 +00:00
return false ;
2006-05-30 17:57:35 +00:00
}
2006-07-22 17:21:59 +00:00
ret = ldb_wait ( req - > handle , LDB_WAIT_ALL ) ;
2006-05-30 17:57:35 +00:00
if ( ret ! = LDB_SUCCESS ) {
d_printf ( " search error - %s \n " , ldb_errstring ( ldb ) ) ;
2008-09-11 18:38:40 -04:00
talloc_free ( actx ) ;
2007-10-06 22:28:14 +00:00
return false ;
2006-05-30 17:57:35 +00:00
}
if ( actx - > pending )
goto again ;
d_printf ( " filter[%s] count[%u] \n " , filter , actx - > count ) ;
2008-09-11 18:38:40 -04:00
talloc_free ( actx ) ;
2007-10-06 22:28:14 +00:00
return true ;
2006-05-30 17:57:35 +00:00
}
static int test_add_attribute ( void * ptr , struct ldb_context * ldb , struct ldb_message * msg )
{
struct dsdb_schema * schema = talloc_get_type ( ptr , struct dsdb_schema ) ;
2006-12-17 02:19:56 +00:00
WERROR status ;
2006-05-30 17:57:35 +00:00
2012-04-15 14:50:20 -07:00
status = dsdb_set_attribute_from_ldb ( ldb , schema , msg ) ;
2006-12-17 02:19:56 +00:00
if ( ! W_ERROR_IS_OK ( status ) ) {
goto failed ;
}
2006-05-30 17:57:35 +00:00
return LDB_SUCCESS ;
failed :
return LDB_ERR_OTHER ;
}
static int test_add_class ( void * ptr , struct ldb_context * ldb , struct ldb_message * msg )
{
struct dsdb_schema * schema = talloc_get_type ( ptr , struct dsdb_schema ) ;
2006-12-17 02:19:56 +00:00
WERROR status ;
2006-05-30 17:57:35 +00:00
2012-04-15 14:50:20 -07:00
status = dsdb_set_class_from_ldb ( schema , msg ) ;
2006-12-17 02:19:56 +00:00
if ( ! W_ERROR_IS_OK ( status ) ) {
goto failed ;
}
2006-05-30 17:57:35 +00:00
return LDB_SUCCESS ;
failed :
return LDB_ERR_OTHER ;
}
2007-10-06 22:28:14 +00:00
static bool test_create_schema ( struct ldb_context * ldb , struct test_rootDSE * root , struct dsdb_schema * * _schema )
2006-05-30 17:57:35 +00:00
{
2007-10-06 22:28:14 +00:00
bool ret = true ;
2006-05-30 17:57:35 +00:00
struct dsdb_schema * schema ;
schema = talloc_zero ( ldb , struct dsdb_schema ) ;
d_printf ( " Fetching attributes... \n " ) ;
ret & = test_create_schema_type ( ldb , root , " (objectClass=attributeSchema) " ,
test_add_attribute , schema ) ;
d_printf ( " Fetching objectClasses... \n " ) ;
ret & = test_create_schema_type ( ldb , root , " (objectClass=classSchema) " ,
test_add_class , schema ) ;
2007-10-06 22:28:14 +00:00
if ( ret = = true ) {
2006-05-30 17:57:35 +00:00
* _schema = schema ;
}
return ret ;
}
2007-10-06 22:28:14 +00:00
static bool test_dump_not_replicated ( struct ldb_context * ldb , struct test_rootDSE * root , struct dsdb_schema * schema )
2006-05-30 17:57:35 +00:00
{
struct dsdb_attribute * a ;
uint32_t a_i = 1 ;
d_printf ( " Dumping not replicated attributes \n " ) ;
for ( a = schema - > attributes ; a ; a = a - > next ) {
if ( ! ( a - > systemFlags & 0x00000001 ) ) continue ;
d_printf ( " attr[%4u]: '%s' \n " , a_i + + ,
a - > lDAPDisplayName ) ;
}
2007-10-06 22:28:14 +00:00
return true ;
2006-05-30 17:57:35 +00:00
}
2007-10-06 22:28:14 +00:00
static bool test_dump_partial ( struct ldb_context * ldb , struct test_rootDSE * root , struct dsdb_schema * schema )
2006-05-30 17:57:35 +00:00
{
struct dsdb_attribute * a ;
uint32_t a_i = 1 ;
d_printf ( " Dumping attributes which are provided by the global catalog \n " ) ;
for ( a = schema - > attributes ; a ; a = a - > next ) {
if ( ! ( a - > systemFlags & 0x00000002 ) & & ! a - > isMemberOfPartialAttributeSet ) continue ;
d_printf ( " attr[%4u]: %u %u '%s' \n " , a_i + + ,
a - > systemFlags & 0x00000002 , a - > isMemberOfPartialAttributeSet ,
a - > lDAPDisplayName ) ;
}
2007-10-06 22:28:14 +00:00
return true ;
2006-05-30 17:57:35 +00:00
}
2007-10-06 22:28:14 +00:00
static bool test_dump_contructed ( struct ldb_context * ldb , struct test_rootDSE * root , struct dsdb_schema * schema )
2006-05-30 17:57:35 +00:00
{
struct dsdb_attribute * a ;
uint32_t a_i = 1 ;
d_printf ( " Dumping constructed attributes \n " ) ;
for ( a = schema - > attributes ; a ; a = a - > next ) {
if ( ! ( a - > systemFlags & 0x00000004 ) ) continue ;
d_printf ( " attr[%4u]: '%s' \n " , a_i + + ,
a - > lDAPDisplayName ) ;
}
2007-10-06 22:28:14 +00:00
return true ;
2006-05-30 17:57:35 +00:00
}
2007-10-06 22:28:14 +00:00
static bool test_dump_sorted_syntax ( struct ldb_context * ldb , struct test_rootDSE * root , struct dsdb_schema * schema )
2006-05-30 17:57:35 +00:00
{
struct dsdb_attribute * a ;
uint32_t a_i = 1 ;
uint32_t i ;
const char * syntaxes [ ] = {
" 2.5.5.0 " ,
" 2.5.5.1 " ,
" 2.5.5.2 " ,
" 2.5.5.3 " ,
" 2.5.5.4 " ,
" 2.5.5.5 " ,
" 2.5.5.6 " ,
" 2.5.5.7 " ,
" 2.5.5.8 " ,
" 2.5.5.9 " ,
" 2.5.5.10 " ,
" 2.5.5.11 " ,
" 2.5.5.12 " ,
" 2.5.5.13 " ,
" 2.5.5.14 " ,
" 2.5.5.15 " ,
" 2.5.5.16 " ,
" 2.5.5.17 "
} ;
2007-01-13 15:40:33 +00:00
d_printf ( " Dumping attribute syntaxes \n " ) ;
2006-05-30 17:57:35 +00:00
for ( i = 0 ; i < ARRAY_SIZE ( syntaxes ) ; i + + ) {
for ( a = schema - > attributes ; a ; a = a - > next ) {
2007-01-13 15:40:33 +00:00
char * om_hex ;
2006-12-17 02:19:56 +00:00
if ( strcmp ( syntaxes [ i ] , a - > attributeSyntax_oid ) ! = 0 ) continue ;
2007-01-13 15:40:33 +00:00
2009-11-04 17:42:53 +11:00
om_hex = data_blob_hex_string_upper ( ldb , & a - > oMObjectClass ) ;
2007-01-13 15:40:33 +00:00
if ( ! om_hex ) {
2007-10-06 22:28:14 +00:00
return false ;
2007-01-13 15:40:33 +00:00
}
d_printf ( " attr[%4u]: %s %u '%s' '%s' \n " , a_i + + ,
2006-12-17 02:19:56 +00:00
a - > attributeSyntax_oid , a - > oMSyntax ,
2007-01-13 15:40:33 +00:00
om_hex , a - > lDAPDisplayName ) ;
talloc_free ( om_hex ) ;
2006-05-30 17:57:35 +00:00
}
}
2007-10-06 22:28:14 +00:00
return true ;
2006-05-30 17:57:35 +00:00
}
2010-05-03 14:50:10 +02:00
static bool test_dump_not_in_filtered_replica ( struct ldb_context * ldb , struct test_rootDSE * root , struct dsdb_schema * schema )
{
struct dsdb_attribute * a ;
uint32_t a_i = 1 ;
d_printf ( " Dumping attributes not in filtered replica \n " ) ;
for ( a = schema - > attributes ; a ; a = a - > next ) {
if ( ! dsdb_attribute_is_attr_in_filtered_replica ( a ) ) {
d_printf ( " attr[%4u]: '%s' \n " , a_i + + ,
a - > lDAPDisplayName ) ;
}
}
return true ;
}
2007-10-06 22:28:14 +00:00
bool torture_ldap_schema ( struct torture_context * torture )
2006-05-30 17:57:35 +00:00
{
struct ldb_context * ldb ;
2007-10-06 22:28:14 +00:00
bool ret = true ;
2006-10-18 14:23:19 +00:00
const char * host = torture_setting_string ( torture , " host " , NULL ) ;
2006-05-30 17:57:35 +00:00
char * url ;
struct test_rootDSE rootDSE ;
struct dsdb_schema * schema = NULL ;
ZERO_STRUCT ( rootDSE ) ;
2006-12-17 02:19:56 +00:00
url = talloc_asprintf ( torture , " ldap://%s/ " , host ) ;
2006-05-30 17:57:35 +00:00
2008-04-17 12:23:44 +02:00
ldb = ldb_wrap_connect ( torture , torture - > ev , torture - > lp_ctx , url ,
2006-05-30 17:57:35 +00:00
NULL ,
cmdline_credentials ,
2009-10-23 14:27:00 +11:00
0 ) ;
2006-05-30 19:08:44 +00:00
if ( ! ldb ) goto failed ;
2006-05-30 17:57:35 +00:00
ret & = test_search_rootDSE ( ldb , & rootDSE ) ;
if ( ! ret ) goto failed ;
ret & = test_create_schema ( ldb , & rootDSE , & schema ) ;
if ( ! ret ) goto failed ;
ret & = test_dump_not_replicated ( ldb , & rootDSE , schema ) ;
ret & = test_dump_partial ( ldb , & rootDSE , schema ) ;
ret & = test_dump_contructed ( ldb , & rootDSE , schema ) ;
ret & = test_dump_sorted_syntax ( ldb , & rootDSE , schema ) ;
2010-05-03 14:50:10 +02:00
ret & = test_dump_not_in_filtered_replica ( ldb , & rootDSE , schema ) ;
2006-05-30 17:57:35 +00:00
failed :
return ret ;
}