2004-08-13 11:10:46 +04:00
/*
Unix SMB / CIFS mplementation .
LDAP protocol helper functions for SAMBA
Copyright ( C ) Stefan Metzmacher 2004
Copyright ( C ) Simo Sorce 2004
2010-02-21 22:36:34 +03:00
Copyright ( C ) Matthias Dieter Wallnöfer 2009 - 2010
2004-08-13 11:10:46 +04:00
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 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2004-08-13 11:10:46 +04: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 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-08-13 11:10:46 +04:00
*/
2004-08-12 12:00:45 +04:00
# include "includes.h"
2010-02-21 22:36:34 +03:00
# include "ldb_wrap.h"
2005-06-16 09:39:40 +04:00
# include "libcli/ldap/ldap_client.h"
2005-03-22 00:22:07 +03:00
# include "lib/cmdline/popt_common.h"
2004-08-12 12:00:45 +04:00
2006-03-25 19:01:28 +03:00
# include "torture/torture.h"
2006-02-04 17:08:24 +03:00
# include "torture/ldap/proto.h"
2007-12-09 01:32:43 +03:00
2007-10-07 02:28:14 +04:00
static bool test_bind_simple ( struct ldap_connection * conn , const char * userdn , const char * password )
2004-08-13 02:25:01 +04:00
{
NTSTATUS status ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2004-08-13 02:25:01 +04:00
status = torture_ldap_bind ( conn , userdn , password ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-10-07 02:28:14 +04:00
ret = false ;
2004-08-13 02:25:01 +04:00
}
2004-08-13 09:26:38 +04:00
return ret ;
}
2007-12-10 06:33:16 +03:00
static bool test_bind_sasl ( struct torture_context * tctx ,
struct ldap_connection * conn , struct cli_credentials * creds )
2004-08-13 09:26:38 +04:00
{
NTSTATUS status ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2004-08-13 09:26:38 +04:00
2004-08-17 15:04:12 +04:00
printf ( " Testing sasl bind as user \n " ) ;
2007-12-10 06:33:16 +03:00
status = torture_ldap_bind_sasl ( conn , creds , tctx - > lp_ctx ) ;
2004-08-13 02:25:01 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-10-07 02:28:14 +04:00
ret = false ;
2004-08-13 09:26:38 +04:00
}
return ret ;
}
2007-10-07 02:28:14 +04:00
static bool test_multibind ( struct ldap_connection * conn , const char * userdn , const char * password )
2004-08-13 09:26:38 +04:00
{
2007-10-07 02:28:14 +04:00
bool ret = true ;
2004-08-13 09:26:38 +04:00
2011-03-01 00:04:29 +03:00
printf ( " Testing multiple binds on a single connection as anonymous and user \n " ) ;
2004-08-13 09:26:38 +04:00
ret = test_bind_simple ( conn , NULL , NULL ) ;
if ( ! ret ) {
printf ( " 1st bind as anonymous failed \n " ) ;
return ret ;
}
ret = test_bind_simple ( conn , userdn , password ) ;
if ( ! ret ) {
printf ( " 2nd bind as authenticated user failed \n " ) ;
2004-08-13 02:25:01 +04:00
}
return ret ;
}
2010-02-21 22:36:34 +03:00
static bool test_search_rootDSE ( struct ldap_connection * conn , const char * * basedn ,
const char * * * partitions )
2004-10-07 19:13:20 +04:00
{
2007-10-07 02:28:14 +04:00
bool ret = true ;
2004-10-07 19:13:20 +04:00
struct ldap_message * msg , * result ;
2005-06-16 09:39:40 +04:00
struct ldap_request * req ;
int i ;
struct ldap_SearchResEntry * r ;
NTSTATUS status ;
2004-10-07 19:13:20 +04:00
printf ( " Testing RootDSE Search \n " ) ;
* basedn = NULL ;
2010-02-21 22:36:34 +03:00
if ( partitions ! = NULL ) {
* partitions = const_str_list ( str_list_make_empty ( conn ) ) ;
}
2004-11-06 23:15:39 +03:00
msg = new_ldap_message ( conn ) ;
2004-10-07 19:13:20 +04:00
if ( ! msg ) {
2007-10-07 02:28:14 +04:00
return false ;
2004-10-07 19:13:20 +04:00
}
msg - > type = LDAP_TAG_SearchRequest ;
msg - > r . SearchRequest . basedn = " " ;
msg - > r . SearchRequest . scope = LDAP_SEARCH_SCOPE_BASE ;
msg - > r . SearchRequest . deref = LDAP_DEREFERENCE_NEVER ;
msg - > r . SearchRequest . timelimit = 0 ;
msg - > r . SearchRequest . sizelimit = 0 ;
2007-10-07 02:28:14 +04:00
msg - > r . SearchRequest . attributesonly = false ;
2005-06-15 04:27:51 +04:00
msg - > r . SearchRequest . tree = ldb_parse_tree ( msg , " (objectclass=*) " ) ;
2004-10-07 19:13:20 +04:00
msg - > r . SearchRequest . num_attributes = 0 ;
msg - > r . SearchRequest . attributes = NULL ;
2005-06-16 09:39:40 +04:00
req = ldap_request_send ( conn , msg ) ;
if ( req = = NULL ) {
printf ( " Could not setup ldap search \n " ) ;
2007-10-07 02:28:14 +04:00
return false ;
2005-06-16 09:39:40 +04:00
}
status = ldap_result_one ( req , & result , LDAP_TAG_SearchResultEntry ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " search failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2004-10-07 19:13:20 +04:00
}
2005-06-16 09:39:40 +04:00
printf ( " received %d replies \n " , req - > num_replies ) ;
r = & result - > r . SearchResultEntry ;
2004-10-07 19:13:20 +04:00
2005-06-16 09:39:40 +04:00
DEBUG ( 1 , ( " \t dn: %s \n " , r - > dn ) ) ;
for ( i = 0 ; i < r - > num_attributes ; i + + ) {
int j ;
for ( j = 0 ; j < r - > attributes [ i ] . num_values ; j + + ) {
DEBUG ( 1 , ( " \t %s: %d %.*s \n " , r - > attributes [ i ] . name ,
2005-07-17 13:20:52 +04:00
( int ) r - > attributes [ i ] . values [ j ] . length ,
( int ) r - > attributes [ i ] . values [ j ] . length ,
2005-06-16 09:39:40 +04:00
( char * ) r - > attributes [ i ] . values [ j ] . data ) ) ;
if ( ! ( * basedn ) & &
strcasecmp ( " defaultNamingContext " , r - > attributes [ i ] . name ) = = 0 ) {
* basedn = talloc_asprintf ( conn , " %.*s " ,
2005-07-17 13:20:52 +04:00
( int ) r - > attributes [ i ] . values [ j ] . length ,
2005-06-16 09:39:40 +04:00
( char * ) r - > attributes [ i ] . values [ j ] . data ) ;
2004-10-07 19:13:20 +04:00
}
2010-02-21 22:36:34 +03:00
if ( ( partitions ! = NULL ) & &
( strcasecmp ( " namingContexts " , r - > attributes [ i ] . name ) = = 0 ) ) {
char * entry = talloc_asprintf ( conn , " %.*s " ,
( int ) r - > attributes [ i ] . values [ j ] . length ,
( char * ) r - > attributes [ i ] . values [ j ] . data ) ;
* partitions = str_list_add ( * partitions , entry ) ;
}
2004-10-07 19:13:20 +04:00
}
}
return ret ;
}
2013-06-22 10:55:08 +04:00
static bool test_search_rootDSE_empty_substring ( struct ldap_connection * conn )
{
bool ret = true ;
struct ldap_message * msg , * result ;
struct ldap_request * req ;
NTSTATUS status ;
printf ( " Testing RootDSE Search with objectclass= substring filter \n " ) ;
msg = new_ldap_message ( conn ) ;
if ( ! msg ) {
return false ;
}
msg - > type = LDAP_TAG_SearchRequest ;
msg - > r . SearchRequest . basedn = " " ;
msg - > r . SearchRequest . scope = LDAP_SEARCH_SCOPE_BASE ;
msg - > r . SearchRequest . deref = LDAP_DEREFERENCE_NEVER ;
msg - > r . SearchRequest . timelimit = 0 ;
msg - > r . SearchRequest . sizelimit = 0 ;
msg - > r . SearchRequest . attributesonly = false ;
msg - > r . SearchRequest . tree = ldb_parse_tree ( msg , " (objectclass=*) " ) ;
msg - > r . SearchRequest . tree - > operation = LDB_OP_SUBSTRING ;
msg - > r . SearchRequest . tree - > u . substring . attr = " objectclass " ;
msg - > r . SearchRequest . tree - > u . substring . start_with_wildcard = 1 ;
msg - > r . SearchRequest . tree - > u . substring . end_with_wildcard = 1 ;
msg - > r . SearchRequest . tree - > u . substring . chunks = NULL ;
msg - > r . SearchRequest . num_attributes = 0 ;
msg - > r . SearchRequest . attributes = NULL ;
req = ldap_request_send ( conn , msg ) ;
if ( req = = NULL ) {
printf ( " Could not setup ldap search \n " ) ;
return false ;
}
status = ldap_result_one ( req , & result , LDAP_TAG_SearchResultEntry ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " looking for search result reply failed - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
printf ( " received %d replies \n " , req - > num_replies ) ;
return ret ;
}
static bool test_search_auth_empty_substring ( struct ldap_connection * conn , const char * basedn )
{
bool ret = true ;
struct ldap_message * msg , * result ;
struct ldap_request * req ;
NTSTATUS status ;
struct ldap_Result * r ;
printf ( " Testing authenticated base Search with objectclass= substring filter \n " ) ;
msg = new_ldap_message ( conn ) ;
if ( ! msg ) {
return false ;
}
msg - > type = LDAP_TAG_SearchRequest ;
msg - > r . SearchRequest . basedn = basedn ;
msg - > r . SearchRequest . scope = LDAP_SEARCH_SCOPE_BASE ;
msg - > r . SearchRequest . deref = LDAP_DEREFERENCE_NEVER ;
msg - > r . SearchRequest . timelimit = 0 ;
msg - > r . SearchRequest . sizelimit = 0 ;
msg - > r . SearchRequest . attributesonly = false ;
msg - > r . SearchRequest . tree = ldb_parse_tree ( msg , " (objectclass=*) " ) ;
msg - > r . SearchRequest . tree - > operation = LDB_OP_SUBSTRING ;
msg - > r . SearchRequest . tree - > u . substring . attr = " objectclass " ;
msg - > r . SearchRequest . tree - > u . substring . start_with_wildcard = 1 ;
msg - > r . SearchRequest . tree - > u . substring . end_with_wildcard = 1 ;
msg - > r . SearchRequest . tree - > u . substring . chunks = NULL ;
msg - > r . SearchRequest . num_attributes = 0 ;
msg - > r . SearchRequest . attributes = NULL ;
req = ldap_request_send ( conn , msg ) ;
if ( req = = NULL ) {
printf ( " Could not setup ldap search \n " ) ;
return false ;
}
status = ldap_result_one ( req , & result , LDAP_TAG_SearchResultDone ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " looking for search result done failed - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
printf ( " received %d replies \n " , req - > num_replies ) ;
r = & result - > r . SearchResultDone ;
if ( r - > resultcode ! = LDAP_SUCCESS ) {
printf ( " search result done gave error - %s \n " , ldb_strerror ( r - > resultcode ) ) ;
return false ;
}
return ret ;
}
2007-10-07 02:28:14 +04:00
static bool test_compare_sasl ( struct ldap_connection * conn , const char * basedn )
2004-10-07 19:13:20 +04:00
{
2005-06-16 09:39:40 +04:00
struct ldap_message * msg , * rep ;
struct ldap_request * req ;
2004-10-07 19:13:20 +04:00
const char * val ;
2005-06-16 09:39:40 +04:00
NTSTATUS status ;
2004-10-07 19:13:20 +04:00
printf ( " Testing SASL Compare: %s \n " , basedn ) ;
if ( ! basedn ) {
2007-10-07 02:28:14 +04:00
return false ;
2004-10-07 19:13:20 +04:00
}
2005-06-16 09:39:40 +04:00
msg = new_ldap_message ( conn ) ;
if ( ! msg ) {
2007-10-07 02:28:14 +04:00
return false ;
2004-10-07 19:13:20 +04:00
}
2005-06-16 09:39:40 +04:00
msg - > type = LDAP_TAG_CompareRequest ;
msg - > r . CompareRequest . dn = basedn ;
msg - > r . CompareRequest . attribute = talloc_strdup ( msg , " objectClass " ) ;
2004-10-07 19:13:20 +04:00
val = " domain " ;
2005-06-16 09:39:40 +04:00
msg - > r . CompareRequest . value = data_blob_talloc ( msg , val , strlen ( val ) ) ;
req = ldap_request_send ( conn , msg ) ;
if ( ! req ) {
2007-10-07 02:28:14 +04:00
return false ;
2005-06-16 09:39:40 +04:00
}
2004-10-07 19:13:20 +04:00
2005-06-16 09:39:40 +04:00
status = ldap_result_one ( req , & rep , LDAP_TAG_CompareResponse ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " error in ldap compare request - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2004-10-07 19:13:20 +04:00
}
DEBUG ( 5 , ( " Code: %d DN: [%s] ERROR:[%s] REFERRAL:[%s] \n " ,
2005-05-11 18:38:13 +04:00
rep - > r . CompareResponse . resultcode ,
rep - > r . CompareResponse . dn ,
rep - > r . CompareResponse . errormessage ,
rep - > r . CompareResponse . referral ) ) ;
2004-10-07 19:13:20 +04:00
2007-10-07 02:28:14 +04:00
return true ;
2004-10-07 19:13:20 +04:00
}
2009-07-30 14:43:49 +04:00
/*
* This takes an AD error message and splits it into the WERROR code
* ( WERR_DS_GENERIC if none found ) and the reason ( remaining string ) .
*/
static WERROR ad_error ( const char * err_msg , char * * reason )
{
WERROR err = W_ERROR ( strtol ( err_msg , reason , 16 ) ) ;
if ( ( reason ! = NULL ) & & ( * reason [ 0 ] ! = ' : ' ) ) {
return WERR_DS_GENERIC_ERROR ; /* not an AD std error message */
}
if ( reason ! = NULL ) {
* reason + = 2 ; /* skip ": " */
}
return err ;
}
2010-06-17 17:39:06 +04:00
/* This has to be done using the LDAP API since the LDB API does only transmit
* the error code and not the error message . */
2009-07-30 14:43:49 +04:00
static bool test_error_codes ( struct torture_context * tctx ,
struct ldap_connection * conn , const char * basedn )
{
struct ldap_message * msg , * rep ;
struct ldap_request * req ;
2009-10-14 12:50:57 +04:00
const char * err_code_str ;
char * endptr ;
2009-07-30 14:43:49 +04:00
WERROR err ;
NTSTATUS status ;
2010-06-17 17:39:06 +04:00
printf ( " Testing the most important error code -> error message conversions! \n " ) ;
2009-07-30 14:43:49 +04:00
if ( ! basedn ) {
return false ;
}
msg = new_ldap_message ( conn ) ;
if ( ! msg ) {
return false ;
}
printf ( " Try a wrong addition \n " ) ;
msg - > type = LDAP_TAG_AddRequest ;
msg - > r . AddRequest . dn = basedn ;
msg - > r . AddRequest . num_attributes = 0 ;
msg - > r . AddRequest . attributes = NULL ;
req = ldap_request_send ( conn , msg ) ;
if ( ! req ) {
return false ;
}
status = ldap_result_one ( req , & rep , LDAP_TAG_AddResponse ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-06-17 17:39:06 +04:00
printf ( " error in ldap add request - %s \n " , nt_errstr ( status ) ) ;
2009-07-30 14:43:49 +04:00
return false ;
}
if ( ( rep - > r . AddResponse . resultcode = = 0 )
| | ( rep - > r . AddResponse . errormessage = = NULL )
| | ( strtol ( rep - > r . AddResponse . errormessage , & endptr , 16 ) < = 0 )
| | ( * endptr ! = ' : ' ) ) {
printf ( " Invalid error message! \n " ) ;
return false ;
}
err = ad_error ( rep - > r . AddResponse . errormessage , & endptr ) ;
err_code_str = win_errstr ( err ) ;
printf ( " - Errorcode: %s; Reason: %s \n " , err_code_str , endptr ) ;
2010-06-17 17:39:06 +04:00
if ( ( ! W_ERROR_EQUAL ( err , WERR_DS_REFERRAL ) )
| | ( rep - > r . AddResponse . resultcode ! = LDAP_REFERRAL ) ) {
2009-07-30 14:43:49 +04:00
return false ;
2010-06-17 17:39:06 +04:00
}
if ( ( rep - > r . AddResponse . referral = = NULL )
| | ( strstr ( rep - > r . AddResponse . referral , basedn ) = = NULL ) ) {
2009-07-30 14:43:49 +04:00
return false ;
2010-06-17 17:39:06 +04:00
}
printf ( " Try another wrong addition \n " ) ;
msg - > type = LDAP_TAG_AddRequest ;
msg - > r . AddRequest . dn = " " ;
msg - > r . AddRequest . num_attributes = 0 ;
msg - > r . AddRequest . attributes = NULL ;
req = ldap_request_send ( conn , msg ) ;
if ( ! req ) {
return false ;
}
status = ldap_result_one ( req , & rep , LDAP_TAG_AddResponse ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " error in ldap add request - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
if ( ( rep - > r . AddResponse . resultcode = = 0 )
| | ( rep - > r . AddResponse . errormessage = = NULL )
| | ( strtol ( rep - > r . AddResponse . errormessage , & endptr , 16 ) < = 0 )
| | ( * endptr ! = ' : ' ) ) {
printf ( " Invalid error message! \n " ) ;
return false ;
}
err = ad_error ( rep - > r . AddResponse . errormessage , & endptr ) ;
err_code_str = win_errstr ( err ) ;
printf ( " - Errorcode: %s; Reason: %s \n " , err_code_str , endptr ) ;
if ( ( ! W_ERROR_EQUAL ( err , WERR_DS_ROOT_MUST_BE_NC ) & &
! W_ERROR_EQUAL ( err , WERR_DS_NAMING_VIOLATION ) )
| | ( rep - > r . AddResponse . resultcode ! = LDAP_NAMING_VIOLATION ) ) {
return false ;
2009-07-30 14:43:49 +04:00
}
printf ( " Try a wrong modification \n " ) ;
2010-06-17 17:39:06 +04:00
msg - > type = LDAP_TAG_ModifyRequest ;
msg - > r . ModifyRequest . dn = basedn ;
msg - > r . ModifyRequest . num_mods = 0 ;
msg - > r . ModifyRequest . mods = NULL ;
req = ldap_request_send ( conn , msg ) ;
if ( ! req ) {
return false ;
}
status = ldap_result_one ( req , & rep , LDAP_TAG_ModifyResponse ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " error in ldap modifification request - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
if ( ( rep - > r . ModifyResponse . resultcode = = 0 )
| | ( rep - > r . ModifyResponse . errormessage = = NULL )
| | ( strtol ( rep - > r . ModifyResponse . errormessage , & endptr , 16 ) < = 0 )
| | ( * endptr ! = ' : ' ) ) {
printf ( " Invalid error message! \n " ) ;
return false ;
}
err = ad_error ( rep - > r . ModifyResponse . errormessage , & endptr ) ;
err_code_str = win_errstr ( err ) ;
printf ( " - Errorcode: %s; Reason: %s \n " , err_code_str , endptr ) ;
2015-12-03 17:24:27 +03:00
if ( ( ! W_ERROR_EQUAL ( err , WERR_INVALID_PARAMETER ) & &
2010-06-17 17:39:06 +04:00
! W_ERROR_EQUAL ( err , WERR_DS_UNWILLING_TO_PERFORM ) )
| | ( rep - > r . ModifyResponse . resultcode ! = LDAP_UNWILLING_TO_PERFORM ) ) {
return false ;
}
printf ( " Try another wrong modification \n " ) ;
2009-07-30 14:43:49 +04:00
msg - > type = LDAP_TAG_ModifyRequest ;
msg - > r . ModifyRequest . dn = " " ;
msg - > r . ModifyRequest . num_mods = 0 ;
msg - > r . ModifyRequest . mods = NULL ;
req = ldap_request_send ( conn , msg ) ;
if ( ! req ) {
return false ;
}
status = ldap_result_one ( req , & rep , LDAP_TAG_ModifyResponse ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " error in ldap modifification request - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
if ( ( rep - > r . ModifyResponse . resultcode = = 0 )
| | ( rep - > r . ModifyResponse . errormessage = = NULL )
| | ( strtol ( rep - > r . ModifyResponse . errormessage , & endptr , 16 ) < = 0 )
| | ( * endptr ! = ' : ' ) ) {
printf ( " Invalid error message! \n " ) ;
return false ;
}
err = ad_error ( rep - > r . ModifyResponse . errormessage , & endptr ) ;
err_code_str = win_errstr ( err ) ;
printf ( " - Errorcode: %s; Reason: %s \n " , err_code_str , endptr ) ;
2015-12-03 17:24:27 +03:00
if ( ( ! W_ERROR_EQUAL ( err , WERR_INVALID_PARAMETER ) & &
2010-06-17 17:39:06 +04:00
! W_ERROR_EQUAL ( err , WERR_DS_UNWILLING_TO_PERFORM ) )
| | ( rep - > r . ModifyResponse . resultcode ! = LDAP_UNWILLING_TO_PERFORM ) ) {
return false ;
2009-07-30 14:43:49 +04:00
}
printf ( " Try a wrong removal \n " ) ;
2010-06-17 17:39:06 +04:00
msg - > type = LDAP_TAG_DelRequest ;
msg - > r . DelRequest . dn = basedn ;
req = ldap_request_send ( conn , msg ) ;
if ( ! req ) {
return false ;
}
status = ldap_result_one ( req , & rep , LDAP_TAG_DelResponse ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " error in ldap removal request - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
if ( ( rep - > r . DelResponse . resultcode = = 0 )
| | ( rep - > r . DelResponse . errormessage = = NULL )
| | ( strtol ( rep - > r . DelResponse . errormessage , & endptr , 16 ) < = 0 )
| | ( * endptr ! = ' : ' ) ) {
printf ( " Invalid error message! \n " ) ;
return false ;
}
err = ad_error ( rep - > r . DelResponse . errormessage , & endptr ) ;
err_code_str = win_errstr ( err ) ;
printf ( " - Errorcode: %s; Reason: %s \n " , err_code_str , endptr ) ;
if ( ( ! W_ERROR_EQUAL ( err , WERR_DS_CANT_DELETE ) & &
! W_ERROR_EQUAL ( err , WERR_DS_UNWILLING_TO_PERFORM ) )
| | ( rep - > r . DelResponse . resultcode ! = LDAP_UNWILLING_TO_PERFORM ) ) {
return false ;
}
printf ( " Try another wrong removal \n " ) ;
2009-07-30 14:43:49 +04:00
msg - > type = LDAP_TAG_DelRequest ;
msg - > r . DelRequest . dn = " " ;
req = ldap_request_send ( conn , msg ) ;
if ( ! req ) {
return false ;
}
status = ldap_result_one ( req , & rep , LDAP_TAG_DelResponse ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " error in ldap removal request - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
if ( ( rep - > r . DelResponse . resultcode = = 0 )
| | ( rep - > r . DelResponse . errormessage = = NULL )
| | ( strtol ( rep - > r . DelResponse . errormessage , & endptr , 16 ) < = 0 )
| | ( * endptr ! = ' : ' ) ) {
printf ( " Invalid error message! \n " ) ;
return false ;
}
err = ad_error ( rep - > r . DelResponse . errormessage , & endptr ) ;
err_code_str = win_errstr ( err ) ;
printf ( " - Errorcode: %s; Reason: %s \n " , err_code_str , endptr ) ;
2010-06-17 17:39:06 +04:00
if ( ( ! W_ERROR_EQUAL ( err , WERR_DS_OBJ_NOT_FOUND ) & &
! W_ERROR_EQUAL ( err , WERR_DS_NO_SUCH_OBJECT ) )
| | ( rep - > r . DelResponse . resultcode ! = LDAP_NO_SUCH_OBJECT ) ) {
return false ;
}
printf ( " Try a wrong rename \n " ) ;
msg - > type = LDAP_TAG_ModifyDNRequest ;
msg - > r . ModifyDNRequest . dn = basedn ;
msg - > r . ModifyDNRequest . newrdn = " dc=test " ;
msg - > r . ModifyDNRequest . deleteolddn = true ;
msg - > r . ModifyDNRequest . newsuperior = NULL ;
req = ldap_request_send ( conn , msg ) ;
if ( ! req ) {
return false ;
}
status = ldap_result_one ( req , & rep , LDAP_TAG_ModifyDNResponse ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " error in ldap rename request - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
if ( ( rep - > r . ModifyDNResponse . resultcode = = 0 )
| | ( rep - > r . ModifyDNResponse . errormessage = = NULL )
| | ( strtol ( rep - > r . ModifyDNResponse . errormessage , & endptr , 16 ) < = 0 )
| | ( * endptr ! = ' : ' ) ) {
printf ( " Invalid error message! \n " ) ;
return false ;
}
err = ad_error ( rep - > r . ModifyDNResponse . errormessage , & endptr ) ;
err_code_str = win_errstr ( err ) ;
printf ( " - Errorcode: %s; Reason: %s \n " , err_code_str , endptr ) ;
if ( ( ! W_ERROR_EQUAL ( err , WERR_DS_NO_PARENT_OBJECT ) & &
! W_ERROR_EQUAL ( err , WERR_DS_GENERIC_ERROR ) )
| | ( rep - > r . ModifyDNResponse . resultcode ! = LDAP_OTHER ) ) {
return false ;
}
printf ( " Try another wrong rename \n " ) ;
msg - > type = LDAP_TAG_ModifyDNRequest ;
msg - > r . ModifyDNRequest . dn = basedn ;
msg - > r . ModifyDNRequest . newrdn = basedn ;
msg - > r . ModifyDNRequest . deleteolddn = true ;
msg - > r . ModifyDNRequest . newsuperior = NULL ;
req = ldap_request_send ( conn , msg ) ;
if ( ! req ) {
return false ;
}
status = ldap_result_one ( req , & rep , LDAP_TAG_ModifyDNResponse ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " error in ldap rename request - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
if ( ( rep - > r . ModifyDNResponse . resultcode = = 0 )
| | ( rep - > r . ModifyDNResponse . errormessage = = NULL )
| | ( strtol ( rep - > r . ModifyDNResponse . errormessage , & endptr , 16 ) < = 0 )
| | ( * endptr ! = ' : ' ) ) {
printf ( " Invalid error message! \n " ) ;
return false ;
}
err = ad_error ( rep - > r . ModifyDNResponse . errormessage , & endptr ) ;
err_code_str = win_errstr ( err ) ;
printf ( " - Errorcode: %s; Reason: %s \n " , err_code_str , endptr ) ;
2015-12-03 17:24:27 +03:00
if ( ( ! W_ERROR_EQUAL ( err , WERR_INVALID_PARAMETER ) & &
2010-06-17 17:39:06 +04:00
! W_ERROR_EQUAL ( err , WERR_DS_NAMING_VIOLATION ) )
| | ( rep - > r . ModifyDNResponse . resultcode ! = LDAP_NAMING_VIOLATION ) ) {
return false ;
}
printf ( " Try another wrong rename \n " ) ;
msg - > type = LDAP_TAG_ModifyDNRequest ;
msg - > r . ModifyDNRequest . dn = basedn ;
msg - > r . ModifyDNRequest . newrdn = " " ;
msg - > r . ModifyDNRequest . deleteolddn = true ;
msg - > r . ModifyDNRequest . newsuperior = NULL ;
req = ldap_request_send ( conn , msg ) ;
if ( ! req ) {
return false ;
}
status = ldap_result_one ( req , & rep , LDAP_TAG_ModifyDNResponse ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " error in ldap rename request - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
if ( ( rep - > r . ModifyDNResponse . resultcode = = 0 )
| | ( rep - > r . ModifyDNResponse . errormessage = = NULL )
| | ( strtol ( rep - > r . ModifyDNResponse . errormessage , & endptr , 16 ) < = 0 )
| | ( * endptr ! = ' : ' ) ) {
printf ( " Invalid error message! \n " ) ;
return false ;
}
err = ad_error ( rep - > r . ModifyDNResponse . errormessage , & endptr ) ;
err_code_str = win_errstr ( err ) ;
printf ( " - Errorcode: %s; Reason: %s \n " , err_code_str , endptr ) ;
2015-12-03 17:24:27 +03:00
if ( ( ! W_ERROR_EQUAL ( err , WERR_INVALID_PARAMETER ) & &
2010-06-17 17:39:06 +04:00
! W_ERROR_EQUAL ( err , WERR_DS_PROTOCOL_ERROR ) )
| | ( rep - > r . ModifyDNResponse . resultcode ! = LDAP_PROTOCOL_ERROR ) ) {
return false ;
}
printf ( " Try another wrong rename \n " ) ;
msg - > type = LDAP_TAG_ModifyDNRequest ;
msg - > r . ModifyDNRequest . dn = " " ;
msg - > r . ModifyDNRequest . newrdn = " cn=temp " ;
msg - > r . ModifyDNRequest . deleteolddn = true ;
msg - > r . ModifyDNRequest . newsuperior = NULL ;
req = ldap_request_send ( conn , msg ) ;
if ( ! req ) {
return false ;
}
status = ldap_result_one ( req , & rep , LDAP_TAG_ModifyDNResponse ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " error in ldap rename request - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
if ( ( rep - > r . ModifyDNResponse . resultcode = = 0 )
| | ( rep - > r . ModifyDNResponse . errormessage = = NULL )
| | ( strtol ( rep - > r . ModifyDNResponse . errormessage , & endptr , 16 ) < = 0 )
| | ( * endptr ! = ' : ' ) ) {
printf ( " Invalid error message! \n " ) ;
return false ;
}
err = ad_error ( rep - > r . ModifyDNResponse . errormessage , & endptr ) ;
err_code_str = win_errstr ( err ) ;
printf ( " - Errorcode: %s; Reason: %s \n " , err_code_str , endptr ) ;
if ( ( ! W_ERROR_EQUAL ( err , WERR_DS_OBJ_NOT_FOUND ) & &
! W_ERROR_EQUAL ( err , WERR_DS_NO_SUCH_OBJECT ) )
| | ( rep - > r . ModifyDNResponse . resultcode ! = LDAP_NO_SUCH_OBJECT ) ) {
return false ;
2009-07-30 14:43:49 +04:00
}
return true ;
}
2005-06-16 09:39:40 +04:00
2010-02-21 22:36:34 +03:00
static bool test_referrals ( struct torture_context * tctx , TALLOC_CTX * mem_ctx ,
const char * url , const char * basedn , const char * * partitions )
{
struct ldb_context * ldb ;
struct ldb_result * res ;
const char * const * attrs = { NULL } ;
struct ldb_dn * dn1 , * dn2 ;
int ret ;
int i , j , k ;
char * tempstr ;
bool found , l_found ;
printf ( " Testing referrals \n " ) ;
if ( partitions [ 0 ] = = NULL ) {
printf ( " Partitions list empty! \n " ) ;
return false ;
}
if ( strcmp ( partitions [ 0 ] , basedn ) ! = 0 ) {
printf ( " The first (root) partition DN should be the base DN! \n " ) ;
return false ;
}
ldb = ldb_wrap_connect ( mem_ctx , tctx - > ev , tctx - > lp_ctx , url ,
2017-05-10 02:10:03 +03:00
NULL , popt_get_cmdline_credentials ( ) , 0 ) ;
2010-02-21 22:36:34 +03:00
/* "partitions[i]" are the partitions for which we search the parents */
for ( i = 1 ; partitions [ i ] ! = NULL ; i + + ) {
dn1 = ldb_dn_new ( mem_ctx , ldb , partitions [ i ] ) ;
if ( dn1 = = NULL ) {
printf ( " Out of memory \n " ) ;
talloc_free ( ldb ) ;
return false ;
}
/* search using base scope */
/* "partitions[j]" are the parent candidates */
for ( j = str_list_length ( partitions ) - 1 ; j > = 0 ; - - j ) {
dn2 = ldb_dn_new ( mem_ctx , ldb , partitions [ j ] ) ;
if ( dn2 = = NULL ) {
printf ( " Out of memory \n " ) ;
talloc_free ( ldb ) ;
return false ;
}
ret = ldb_search ( ldb , mem_ctx , & res , dn2 ,
LDB_SCOPE_BASE , attrs ,
" (foo=bar) " ) ;
if ( ret ! = LDB_SUCCESS ) {
printf ( " %s " , ldb_errstring ( ldb ) ) ;
talloc_free ( ldb ) ;
return false ;
}
if ( res - > refs ! = NULL ) {
printf ( " There shouldn't be generated any referrals in the base scope! \n " ) ;
talloc_free ( ldb ) ;
return false ;
}
talloc_free ( res ) ;
talloc_free ( dn2 ) ;
}
/* search using onelevel scope */
found = false ;
/* "partitions[j]" are the parent candidates */
for ( j = str_list_length ( partitions ) - 1 ; j > = 0 ; - - j ) {
dn2 = ldb_dn_new ( mem_ctx , ldb , partitions [ j ] ) ;
if ( dn2 = = NULL ) {
printf ( " Out of memory \n " ) ;
talloc_free ( ldb ) ;
return false ;
}
ret = ldb_search ( ldb , mem_ctx , & res , dn2 ,
LDB_SCOPE_ONELEVEL , attrs ,
" (foo=bar) " ) ;
if ( ret ! = LDB_SUCCESS ) {
printf ( " %s " , ldb_errstring ( ldb ) ) ;
talloc_free ( ldb ) ;
return false ;
}
tempstr = talloc_asprintf ( mem_ctx , " /%s??base " ,
partitions [ i ] ) ;
if ( tempstr = = NULL ) {
printf ( " Out of memory \n " ) ;
talloc_free ( ldb ) ;
return false ;
}
/* Try to find or find not a matching referral */
l_found = false ;
for ( k = 0 ; ( ! l_found ) & & ( res - > refs ! = NULL )
& & ( res - > refs [ k ] ! = NULL ) ; k + + ) {
if ( strstr ( res - > refs [ k ] , tempstr ) ! = NULL ) {
l_found = true ;
}
}
talloc_free ( tempstr ) ;
if ( ( ! found ) & & ( ldb_dn_compare_base ( dn2 , dn1 ) = = 0 )
& & ( ldb_dn_compare ( dn2 , dn1 ) ! = 0 ) ) {
/* This is a referral candidate */
if ( ! l_found ) {
printf ( " A required referral hasn't been found on onelevel scope (%s -> %s)! \n " , partitions [ j ] , partitions [ i ] ) ;
talloc_free ( ldb ) ;
return false ;
}
found = true ;
} else {
/* This isn't a referral candidate */
if ( l_found ) {
printf ( " A unrequired referral has been found on onelevel scope (%s -> %s)! \n " , partitions [ j ] , partitions [ i ] ) ;
talloc_free ( ldb ) ;
return false ;
}
}
talloc_free ( res ) ;
talloc_free ( dn2 ) ;
}
/* search using subtree scope */
found = false ;
/* "partitions[j]" are the parent candidates */
for ( j = str_list_length ( partitions ) - 1 ; j > = 0 ; - - j ) {
dn2 = ldb_dn_new ( mem_ctx , ldb , partitions [ j ] ) ;
if ( dn2 = = NULL ) {
printf ( " Out of memory \n " ) ;
talloc_free ( ldb ) ;
return false ;
}
ret = ldb_search ( ldb , mem_ctx , & res , dn2 ,
LDB_SCOPE_SUBTREE , attrs ,
" (foo=bar) " ) ;
if ( ret ! = LDB_SUCCESS ) {
printf ( " %s " , ldb_errstring ( ldb ) ) ;
talloc_free ( ldb ) ;
return false ;
}
tempstr = talloc_asprintf ( mem_ctx , " /%s " ,
partitions [ i ] ) ;
if ( tempstr = = NULL ) {
printf ( " Out of memory \n " ) ;
talloc_free ( ldb ) ;
return false ;
}
/* Try to find or find not a matching referral */
l_found = false ;
for ( k = 0 ; ( ! l_found ) & & ( res - > refs ! = NULL )
& & ( res - > refs [ k ] ! = NULL ) ; k + + ) {
if ( strstr ( res - > refs [ k ] , tempstr ) ! = NULL ) {
l_found = true ;
}
}
talloc_free ( tempstr ) ;
if ( ( ! found ) & & ( ldb_dn_compare_base ( dn2 , dn1 ) = = 0 )
& & ( ldb_dn_compare ( dn2 , dn1 ) ! = 0 ) ) {
/* This is a referral candidate */
if ( ! l_found ) {
printf ( " A required referral hasn't been found on subtree scope (%s -> %s)! \n " , partitions [ j ] , partitions [ i ] ) ;
talloc_free ( ldb ) ;
return false ;
}
found = true ;
} else {
/* This isn't a referral candidate */
if ( l_found ) {
printf ( " A unrequired referral has been found on subtree scope (%s -> %s)! \n " , partitions [ j ] , partitions [ i ] ) ;
talloc_free ( ldb ) ;
return false ;
}
}
talloc_free ( res ) ;
talloc_free ( dn2 ) ;
}
talloc_free ( dn1 ) ;
}
talloc_free ( ldb ) ;
return true ;
}
2011-10-22 14:34:42 +04:00
static bool test_abandon_request ( struct torture_context * tctx ,
2010-09-27 10:13:50 +04:00
struct ldap_connection * conn , const char * basedn )
{
struct ldap_message * msg ;
struct ldap_request * req ;
NTSTATUS status ;
printf ( " Testing the AbandonRequest with an old message id! \n " ) ;
if ( ! basedn ) {
return false ;
}
msg = new_ldap_message ( conn ) ;
if ( ! msg ) {
return false ;
}
printf ( " Try a AbandonRequest for an old message id \n " ) ;
msg - > type = LDAP_TAG_AbandonRequest ;
msg - > r . AbandonRequest . messageid = 1 ;
req = ldap_request_send ( conn , msg ) ;
if ( ! req ) {
return false ;
}
status = ldap_request_wait ( req ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " error in ldap abandon request - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
return true ;
}
2010-02-21 22:36:34 +03:00
2007-10-07 02:28:14 +04:00
bool torture_ldap_basic ( struct torture_context * torture )
2004-08-12 12:00:45 +04:00
{
NTSTATUS status ;
struct ldap_connection * conn ;
TALLOC_CTX * mem_ctx ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2006-10-18 18:23:19 +04:00
const char * host = torture_setting_string ( torture , " host " , NULL ) ;
const char * userdn = torture_setting_string ( torture , " ldap_userdn " , NULL ) ;
const char * secret = torture_setting_string ( torture , " ldap_secret " , NULL ) ;
2010-02-22 23:19:27 +03:00
const char * url ;
const char * basedn ;
2010-02-21 22:36:34 +03:00
const char * * partitions ;
2004-08-12 12:00:45 +04:00
mem_ctx = talloc_init ( " torture_ldap_basic " ) ;
url = talloc_asprintf ( mem_ctx , " ldap://%s/ " , host ) ;
2007-12-10 06:33:16 +03:00
status = torture_ldap_connection ( torture , & conn , url ) ;
2004-08-12 12:00:45 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-10-07 02:28:14 +04:00
return false ;
2004-08-12 12:00:45 +04:00
}
2010-02-21 22:36:34 +03:00
if ( ! test_search_rootDSE ( conn , & basedn , & partitions ) ) {
2007-10-07 02:28:14 +04:00
ret = false ;
2004-08-13 09:26:38 +04:00
}
2013-06-22 10:55:08 +04:00
if ( ! test_search_rootDSE_empty_substring ( conn ) ) {
ret = false ;
}
2009-07-30 14:43:49 +04:00
/* other bind tests here */
2005-06-16 09:39:40 +04:00
if ( ! test_multibind ( conn , userdn , secret ) ) {
2007-10-07 02:28:14 +04:00
ret = false ;
2004-10-07 19:13:20 +04:00
}
2017-05-10 02:10:03 +03:00
if ( ! test_bind_sasl ( torture , conn , popt_get_cmdline_credentials ( ) ) ) {
2007-10-07 02:28:14 +04:00
ret = false ;
2004-08-13 02:25:01 +04:00
}
2004-08-12 12:00:45 +04:00
2013-06-22 10:55:08 +04:00
if ( ! test_search_auth_empty_substring ( conn , basedn ) ) {
ret = false ;
}
2004-10-07 19:13:20 +04:00
if ( ! test_compare_sasl ( conn , basedn ) ) {
2007-10-07 02:28:14 +04:00
ret = false ;
2004-10-07 19:13:20 +04:00
}
2009-07-30 14:43:49 +04:00
/* error codes test here */
2004-08-12 12:00:45 +04:00
2009-07-30 14:43:49 +04:00
if ( ! test_error_codes ( torture , conn , basedn ) ) {
ret = false ;
}
2010-02-21 22:36:34 +03:00
/* referrals test here */
if ( ! test_referrals ( torture , mem_ctx , url , basedn , partitions ) ) {
ret = false ;
}
2011-10-22 14:34:42 +04:00
if ( ! test_abandon_request ( torture , conn , basedn ) ) {
2010-09-27 10:13:50 +04:00
ret = false ;
}
2009-07-30 14:43:49 +04:00
/* if there are no more tests we are closing */
torture_ldap_close ( conn ) ;
talloc_free ( mem_ctx ) ;
2004-08-12 12:00:45 +04:00
return ret ;
}