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
2009-07-30 14:43:49 +04:00
Copyright ( C ) Matthias Dieter Wallnöfer 2009
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"
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
2004-08-17 15:04:12 +04:00
printf ( " Testing multiple binds on a single connnection 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 ;
}
2007-10-07 02:28:14 +04:00
static bool test_search_rootDSE ( struct ldap_connection * conn , char * * basedn )
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 ;
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
}
}
}
2005-06-16 09:39:40 +04:00
talloc_free ( req ) ;
2004-10-07 19:13:20 +04:00
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 ;
}
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 ;
2009-08-05 12:48:25 +04:00
printf ( " Testing error codes - to make this test pass against SAMBA 4 you have to specify the target! \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 ) ) {
printf ( " error in ldap addition 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 ) ;
2009-08-05 12:48:25 +04:00
if ( ! torture_setting_bool ( tctx , " samba4 " , false ) ) {
2009-07-30 14:43:49 +04:00
if ( ( ! W_ERROR_EQUAL ( err , WERR_DS_REFERRAL ) )
| | ( rep - > r . AddResponse . resultcode ! = 10 ) ) {
return false ;
}
} else {
2009-10-14 12:50:57 +04:00
if ( ( ! W_ERROR_EQUAL ( err , WERR_DS_OBJ_CLASS_VIOLATION ) )
| | ( rep - > r . AddResponse . resultcode ! = 65 ) ) {
2009-07-30 14:43:49 +04:00
return false ;
}
}
printf ( " Try a wrong modification \n " ) ;
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 ) ;
2009-08-05 12:48:25 +04:00
if ( ! torture_setting_bool ( tctx , " samba4 " , false ) ) {
2009-07-30 14:43:49 +04:00
if ( ( ! W_ERROR_EQUAL ( err , WERR_INVALID_PARAM ) )
| | ( rep - > r . ModifyResponse . resultcode ! = 53 ) ) {
return false ;
}
} else {
2009-10-14 12:50:57 +04:00
if ( ( ! W_ERROR_EQUAL ( err , WERR_DS_OPERATIONS_ERROR ) )
| | ( rep - > r . ModifyResponse . resultcode ! = 1 ) ) {
2009-07-30 14:43:49 +04:00
return false ;
}
}
printf ( " Try a wrong removal \n " ) ;
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 ) ;
2009-08-05 12:48:25 +04:00
if ( ! torture_setting_bool ( tctx , " samba4 " , false ) ) {
2009-07-30 14:43:49 +04:00
if ( ( ! W_ERROR_EQUAL ( err , WERR_DS_OBJ_NOT_FOUND ) )
| | ( rep - > r . DelResponse . resultcode ! = 32 ) ) {
return false ;
}
} else {
if ( ( ! W_ERROR_EQUAL ( err , WERR_DS_INVALID_DN_SYNTAX ) )
| | ( rep - > r . DelResponse . resultcode ! = 34 ) ) {
return false ;
}
}
return true ;
}
2005-06-16 09:39:40 +04: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 ) ;
2004-08-12 12:00:45 +04:00
char * url ;
2004-10-07 19:13:20 +04:00
char * basedn ;
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
}
2005-06-16 09:39:40 +04:00
if ( ! test_search_rootDSE ( conn , & basedn ) ) {
2007-10-07 02:28:14 +04:00
ret = false ;
2004-08-13 09:26:38 +04:00
}
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
}
2007-12-10 06:33:16 +03:00
if ( ! test_bind_sasl ( torture , conn , 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
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 ;
}
/* 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 ;
}